;;; -*- Mode:gate; Fonts:(HL12 HL12I HL12B CPTFONTB HL12BI HL12B HL12I ) -*-


=Node: 4Dribble Files*

=Text:
3DRIBBLE FILES

dribble* &optional 1filename*                                                                                    
        With an argument, 2dribble* opens 1filename* as a `dribble file' (also known as a `wallpaper file')
        and then enters a Lisp listen loop in which 2*standard-input** and 2*standard-output** are
        rebound to direct all the output and echoing they do to the file as well as to the terminal.

        Dribble output can be sent to an editor buffer by using a suitable pathname; see
        4(FILENAMES-3)Editor Buffer Pathnames*.

        Calling 2dribble* with no arguments terminates dribbling; it throws to the original call to 2dribble*,
        which closes the file and returns.  

3dribble-all* &optional 1filename*                                                                              
        Like 2dribble* except that all input and output goes to the dribble file, including break loops,
        queries, warnings and sessions in the debugger.  This works by binding 2*terminal-io** instead
        of 2*standard-output** and 2*standard-input**.  

=Node: 4Version Information*

=Text:
3VERSION INFORMATION*

     Common Lisp defines several standard ways of inquiring about the identity and capabilities of
the Lisp system you are using.

3*features**                                                                                    1Variable*        
        A list of atoms which describe the software and hardware features of the Lisp implementation.
        By default, this is 

                3(:loop :defstruct :lispm :cadr :mit :chaos :sort :fasload :string*
                3 :newio :roman :trace :grindef :grind :common)*

        Most important is the symbol 2:lispm*; this indicates that the program is executing on the Lisp
        Machine.  2:cadr* indicates the type of hardware, 2:mit* which version of the Lisp Machine
        operating system, and 2:chaos* that the Chaosnet protocol is available.  2:common* indicates that
        Common Lisp is supported.

        Most of the other elements are for Maclisp compatibility.  Common Lisp defines the variable
        2*features** but does not define what should appear in the list.  The order of elements in the
        list has no significance.  Membership checks should use 2string-equal* so that packages are not
        significant

        The 3#+* and 3#-* read constructs () check for the presence of an element in this list.  Thus,
        3#+2lispm** when read by a Lisp Machine causes the following expression to be significant,
        because 2:lispm* is present in the features list.  

     The remaining standard means of inquiry are specified by Common Lisp to be functions rather
than variables, for reasons that seem poorly thought out.

3lisp-implementation-type*                                                                                 
        Returns a string saying what kind of Lisp implementation you are using.  On the Lisp Machine
        it is always 2"Zetalisp"*.  

3lisp-implementation-version*                                                                            
        Returns a string saying the version numbers of the Lisp implementation.  On the Lisp Machine
        it looks something like 

                2"System 98.3, CADR 3.0, ZMAIL 52.2"3.

machine-type**                                                                                                   
        Returns a string describing the kind of hardware in use.  It is 2"CADR"* or 2"LAMBDA"*.  

3machine-version*                                                                                              
        Returns a string describing the kind of hardware and microcode version.  It starts with the
        value of 2machine-type*.  It might be 2"CADR Microcode 309"*.  

3machine-instance*                                                                                             
        Returns a string giving the name of this machine.  Do not be confused; the value is a string,
        not an instance.  Example:  2"CADR-18"*.  

3software-type*                                                                                                 
        Returns a string describing the type of operating system software that Lisp is working with.
        On the Lisp Machine, it is always 2"Zetalisp"*, since the Lisp Machine Lisp software is the
        operating system.  

3software-version*                                                                                             
        Returns a string describing the version numbers of the operating system software in use.
        This is the same as 2lisp-implementation-version* on the Lisp Machine since the same software
        is being described.  

3short-site-name*                                                                                              
        Returns a string giving briefly the name of the site you are at.  A site is an institution which
        has a group of Lisp Machines.  The string you get is the value of the 2:short-site-name* site
        option as given in 2SYS:  SITE; SITE LISP*.  See 4(MISCELL-4)Site Options and Host Table* 
        for more information.  Example:  2"MIT AI Lab"*.  

3long-site-name*                                                                                                
        Returns a string giving a verbose name for the site you are at.  This string is specified by the
        site option 2:long-site-name*.  Example:  2"Massachusetts Institute of Technology, Artificial*
        2Intelligence Laboratory"*.  

=Node: 4Booting and Disk Partitions*

=Text:
3BOOTING AND DISK PARTITIONS*

     A Lisp Machine disk is divided into several named 1partitions* (also called 1bands* sometimes).
Partitions can be used for many things.  Every disk has a partition named 2PAGE*, which is used to
implement the virtual memory of the Lisp Machine.  When you run Lisp, this is where the Lisp world
actually resides.  There are also partitions that hold saved images of the Lisp Machine microcode,
conventionally named 2MCR1n** (where 1n* is a digit), and partitions that hold saved images of Lisp worlds,
conventionally named 2LOD1n**.  A saved image of a Lisp world is also called a 1virtual memory load* or
1system load*.  The microcode and system load are stored separately so that the microcode can be
changed without going through the time-consuming process of generating a new system load.

     The directory of partitions is in a special block on the disk called the label.  The label names one
of the partitions as the current microcode and one as the current system load.  When you cold-boot,
the contents of the current microcode band are loaded into the microcode memory, and then the
contents of the current saved image of the Lisp world is copied into the 2PAGE* partition.  Then Lisp
starts running.  When you warm-boot, the contents of the current microcode band are loaded, but
Lisp starts running using the data already in the 2PAGE* partition.

     For each partition, the directory of partitions contains a brief textual description of the contents
of the partition.  For microcode partitions, a typical description might be 2"UCADR 310"*; this means
that version 2310* of the microcode is in the partition.  For saved Lisp images, it is a little more
complicated.  Ideally, the description would say which versions of which systems are loaded into the
band.  Unfortunately, there isn't enough room for that in most cases.  A typical description is 2"99.4
Daed 5.1"*, meaning that this band contains version 299.4* of 2System* and version 25.1* of 2Daedalus*.
The description is created when a Lisp world is saved away by 2disk-save* (see below).

=Node: 4Manipulating the Label*

=Text:
3MANIPULATING THE LABEL

print-disk-label* &optional 1(unit* 301)** 1(stream* 3*standard-output*1)**                            
        Prints a description of the label of the disk specified by 1unit* onto 1stream*.  The description
        starts with the name of the disk pack, various information about the disk that is generally
        uninteresting, and the names of the two current load partitions (microcode and saved Lisp
        image).  This is followed by one line of description for each partition.  Each one has a name,
        disk address, size, and textual comment.  The current microcode partition and the current
        system load partition are marked with asterisks, each at the beginning of the line.

        1unit* may be the unit number of the disk (most Lisp machines just have one unit, number 0), or
        the host name of another Lisp Machine on the Chaosnet, as a string (in which case the label
        of unit 20* on that machine is printed, and the user of that machine is notified that you are
        looking at his label), or, for CADRs only, the string 2"CC"* (which prints the label of unit 0 of
        the machine connected to this machine's debugging hardware).

        Use of 2"CC"* as the 1unit* is the way to examine or fix up the label of a machine which cannot
        work because of problems with the label.  On a Lambda, this must be done through the SDU.  

3set-current-band* 1partition-name* &optional 1(unit* 301)**                                                
        Sets the current saved Lisp image partition to be 1partition-name*.  If 1partition-name* is a
        number, the name 2LOD1n** is used.

        1unit* can be a disk drive number, the host name of another Lisp Machine, or the string 2"CC"*.
        See the comments under 2print-disk-label*, above.

        If the partition you specify goes with a version of microcode different from the one that is
        current, this function offers to select the an appropriate microcode partition as well.  Normally
        you should answer 2Y*.  

3set-current-microload* 1partition-name* &optional 1(unit* 301)**                                         
        Sets the current microcode partition to be 1partition-name*.  If 1partition-name* is a number, the
        name 2MCR1n** is used.

        1unit* can be a disk drive number, the host name of another Lisp Machine, or the string 2"CC"*.
        See the comments under 2print-disk-label*, above.  

3si:current-band* &optional 1(unit* 301)**                                                                    
3si:current-microload* &optional 1(unit* 301)**                                                            
        Return, respectively, the name of the current band and the current microload on the specified
        unit.  

     When using the functions to set the current load partitions, be extra sure that you are specifying
the correct partition.  Having done it, cold-booting the machine will reload from those partitions.
Some versions of the microcode will not work with some versions of the Lisp system, and if you set
the two current partitions incompatibly, cold-booting the machine will fail.  To fix this, on a CADR,
use another CADR's debugging hardware, running 2print-disk-label* and 2set-current-band* on the other
CADR and giving 2"CC"* as the 1unit* argument.  On a Lambda, this is done via the SDU.

3si:edit-disk-label* 1unit* &optional 1init-p*                                                                 
        Runs an interactive label editor on the specified unit.  This editor allows you to change any
        field in the label.  The 2Help* key documents the commands.  You have to be an expert to need
        this and to understand what it does, so the commands are not documented here.  Ask
        someone if you need help.  You can screw yourself very badly with this function.  

3disk-restore* &optional 1partition*                                                                            
        Allows booting from a band other than the current one.  1partition* may be the name or the
        number of a disk partition containing a virtual-memory load, or 2nil* or omitted, meaning to use
        the current partition.  The specified partition is copied into the paging area of the disk and
        then started.

        Although you can use this to boot a different Lisp image than the installed one, this does not
        provide a way to boot a different microcode image.  2disk-restore* brings up the new band with
        the currently running microcode.

        2disk-restore* asks the user for confirmation before doing it.  

3describe-partition* 1partition* &optional 1unit*                                                              
        Tells you various useful things about a partition; including where on disk the partition begins,
        and how long it is.

        If you specify a saved Lisp system partition, such as 2LOD3*, it also tells you important
        information about the contents of the partition:  the microcode version which the partition
        goes with, the size of the data in the partition and the highest virtual address used.  The size
        of the partition tells how large a partition you need to make a copy of this one, and the
        highest virtual address used (which is measured in units of disk blocks) tells you how large a
        2PAGE* partition you need in order to run this partition.  

=Node: 4Updating Software*

=Text:
3UPDATING SOFTWARE*

     Of all the procedures described in this section, the most common one is to take a partition
containing a Lisp image, update it to have all the latest patches (see
4(SYSTEMS-2)The Patch Facility*), and save it away in a disk partition.  The function
2load-and-save-patches* does it all conveniently for you.

3load-and-save-patches*                                                                                     
        Loads patches and saves a band, with a simple user interface.  Run this function immediately
        after cold booting, without logging in first; it logs in automatically as 2LISPM* (or whatever is
        specified in the site files).  The first thing it does is print the list of disk partitions and ask
        you which one to save in.  Answer 2LOD1n**, using the name of a partition from the printed list.
        You must then confirm.  Then the patches are loaded and the resulting world is saved with no
        further user interaction, as long as no problem arises.

        It is convenient to use this function just before you depart, allowing it to finish unattended.  

     If you wish to do something other than loading all and only the latest patches, you must perform
the steps by hand.  Start by cold-booting the machine, to get a fresh, empty system.  Next, you
must log in as something whose INIT file does not affect the Lisp world noticably (so that when you
save away the Lisp image, the side-effects of the INIT file won't get saved too); on MIT-OZ, for
example, you can log in as 2LISPM* with password 2LISPM*.  Now you can load in any new software you
want; usually you should also do 2(load-patches)* for good measure.  You may also want to call
2si:set-system-status* to change the release status of the system.

     When you're done loading everything, do 2(print-disk-label)* to find a band in which to save your
new Lisp world.  It is best not to reuse the current band, since if something goes wrong during the
saving of the partition, while you have written, say, half of the band that is current, it may be
impossible to cold-boot the machine.  Once you have found the partition, you use the 2disk-save*
function to save everything into that partition.

3disk-save* 1partition-name* &optional 1no-query* 1incremental*                                                
        Saves the current Lisp world in the designated partition.  1partition-name* may be a partition
        name (a string), or it may be a number in which case the name 2LOD1n** is used.

        The user is first asked for yes-or-no confirmation that he really wants to reuse the named
        partition.  A non-2nil* value for 1no-query* prevents this question.  This is only for callers that
        have already asked.

        Next it is necessary to figure out what to put into the textual description of the band, for the
        disk label.  This starts with the brief version of 2si:system-version-info* (see
        4(SYSTEMS-2)The Patch Facility*).  Then comes a string of additional information; if 
        1no-query* is 2nil*, the user is offered the chance to provide a new string.  The current value 
        of this string is returned by 2si:system-version-info* and printed by booting.  The version info 
        and the string both go in the comment field of the disk label for this band.  If they don't 
        together fit into the fixed size available, the user is asked to retype the whole thing (the 
        version info as well as your comment) in a compressed form that does fit.

        The Lisp environment is then saved away into the designated partition, and then the
        equivalent of a cold-boot from that partition is done.  

     Once the patched system has been successfully saved and the system comes back up, you can
make it current with 2set-current-band*.

     When you do a 2disk-save*, it may tell you that the band you wish to save in is not big enough
to hold all the data in your current world.  It may be possible for you to reduce the size of the data
so that it will fit in that band, by garbage collecting.  Simply do 2(si:full-gc)*.

     Try to avoid saving patched systems after running the editor or the compiler.  This works, but it
makes the saved system a lot bigger.  In order to produce a clean saved environment, you should
try to do as little as possible between the time you cold-boot and the time you save the partition.

3si:login-history*                                                                           1Variable*        
        The value of 2si:login-history* is a list of entries, one for each person who has logged into this
        world since it was created.  This makes it possible to tell who 2disk-saved* a band with
        something broken in it.  Each entry is a list of the user ID, the host logged into, the Lisp
        Machine on which the world was being executed, and the date and time.  

=Node: 4Saving Personal Software*

=Text:
3SAVING PERSONAL SOFTWARE*

     If you have a large application system which takes a while to load, you may wish to save a
band containing it.

     To do this, boot a fresh band, log in without running your init file, do 2make-system* to load the
application system, and then invoke 2disk-save*.  When 2disk-save* asks for an additional comment,
give your name or the name of the application system you loaded, and a date.  This will tell other
people who to ask whether the band is still in use if they would like to save other things.

     You can greatly reduce the amount of disk space needed for the saved band by making it an
1incremental* band; that is, a band which contains the differences between the Lisp world you want to
save and the system band you originally loaded.  Since all the pages of the system which your
application program did not change do not have to be saved, an incremental band is generally much
smaller--perhaps by a factor of ten.

     To make an incremental band, give a non-2nil* third argument to 2disk-save*, as in 

        3(disk-save "lod4" nil t)*

     Figuring out which pages need to be saved in the incremental band takes a couple of extra
minutes.

     You can restore the incremental band with 2disk-restore* or boot it like any other band.  This
works by first booting the original band and then copying in the differences that the incremental band
records.  It takes only a little longer than booting the original system band.

     The original band to which an incremental band refers must be a complete load.  When you
update a standard system band (loading patches, for instance) you should always make a complete
load, so that the previous system band is not needed for the new one to function.

     The incremental band records the partition name of the original system band.  That original band
must still exist, with the same contents, in order for the incremental band to work properly.  The
incremental band contains some error check data which is used to verify this.  The error checking is
done by the microcode when the incremental band is booted, but it is also done by
2set-current-band*, so that you are not permitted to select an incremental band if it is not going to
work.

     When using incremental bands, it is important to preserve the system bands that they depend on.
Therefore, system bands should not be updated too frequently.  2describe-partition* on an incremental
band says which full band it depends on; you can use this to determine which bands should be kept
for the sake of incremental bands that depend on them.

     In order to realize the maximum savings in disk space possible because of incremental bands,
you must make the partition you saved in smaller once the save is finished and you know how much
space was actually used.  This is done with 2si:edit-disk-label*.  The excess space at the end of the
partition can be used to make another partition which is used for the next incremental band saved.
Eventually when some of the incremental bands are no longer needed the rest must be shuffled so
that the free space can be put together into larger partitions.  This can be done with
2si:copy-disk-partition*.

     An easier technique is to divide a couple of the initial partitions into several equal-sized
partitions of about 4000 pages, and use these for all incremental saving.  You can easily provide
room for 12 incremental bands this way in addition to a few system bands and file system.

     You must not do a garbage collection to reduce the size of the world before you make an an
incremental band.  This is because garbage collection alters so many pages that an incremental band
would be as big as a complete band.

=Node: 4Copying Bands*

=Text:
3COPYING BANDS*

     The normal way to install new software on a machine is to copy the microcode and world load
bands from another machine.

     The first step is to find a machine that is not in use and has the desired system.  Let us call
this the source machine.  The machine where the new system is to be installed is the target machine.
You can use 2finger* to see which machines are free, and use 2print-disk-label* with an argument to
examine the label of that machine's disk and see if it has the system you want.

     Then you should do a 2(print-disk-label)* to find suitable partitions to copy them into.  It is
advisable not to copy them into the selected partitions; if you did that, and the machine crashed in
the middle, you would be unable to boot it.

     Before copying a band from another machine, double-check the partition names by printing the
labels of both machines, and make sure no one is using the other machine.  Also double-check with
2describe-partition* that the world load and microcode go together.  Then use this function:

3si:receive-band* 1source-host* 1source-band* 1target-band* &optional 1subset-start* 1subset-size*        
        Copies the partition on 1source-host*'s partition named 1source-band* onto the local machine's
        partition named 1target-band*.  This takes about ten minutes.  It types out the size of the
        partition in pages, and types a number every 100 pages telling how far it has gotten.  It
        displays an entry in the who line on the remote machine saying what's going on.

        The 1subset-start* and 1subset-size* arguments can be used to transfer only part of a partition.
        They are measured in blocks.  The default for the first is zero, and the default for the second
        is to continue to the end of the data in the band.  These arguments are useful for restarting a
        transfer that was aborted due to network problems or a crash, based on the count of
        hundreds of blocks that was printed out before the crash.  

     To go the other direction, use 2si:transmit-band*.

3si:transmit-band* 1source-band* 1target-host* 1target-band* &optional 1subset-start* 1subset-size*       
        This is just like 2si:receive-band*, except you use it on the source machine instead of the
        target machine.  It copies the local machine's partition named 1source-band* onto
        1target-machine*'s partition named 1target-band*.

        It is preferable to use 2si:receive-band* so that you are present at the machine being written
        on.  

     After transferring the band, it is good practice to make sure that it really was copied
successfully by comparing the original and the copy.  All of the known reasons for errors during
band transfer have (of course) been corrected, but peace of mind is valuable.  If the copy was not
perfectly faithful, you might not find out about it until a long time later, when you use whatever part
of the system that had not been copied properly.

3si:compare-band* 1source-host* 1source-band* 1target-band* &optional 1subset-start* 1subset-size*        
        This is like 2si:receive-band*, except that it does not change anything.  It compares the two
        bands and complains about any differences.  

     Having gotten the current microcode load and system load copied into partitions on your
machine, you can make them current for booting using 2set-current-band*.

