;;; -*- 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 2MCR1n** (where 1n* is a digit), and partitions that hold saved images of Lisp worlds, conventionally named 2LOD1n**. 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* 301)** 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* 301)** Sets the current saved Lisp image partition to be 1partition-name*. If 1partition-name* is a number, the name 2LOD1n** 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* 301)** Sets the current microcode partition to be 1partition-name*. If 1partition-name* is a number, the name 2MCR1n** 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* 301)** 3si:current-microload* &optional 1(unit* 301)** 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 2LOD1n**, 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 2LOD1n** 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*.