IFS Scavenger Operation
Page Numbers: Yes X: 527 Y: 10.5"
Copyright Xerox Corporation 1981
Inter-Office Memorandum
ToIFS ProjectDateJanuary 7, 1981
FromDavid BoggsLocationPARC/CSL
SubjectIFS Scavenger OperationFile[Maxc1]<IFS>IfsScavOp.bravo
This memo describes the operation of the Interim File System Scavenger. The design is outlined in a separate memo. The scavenger reads every page in the file system, makes sure that every file is well-formed, and checks for consistency between files and directories. Since an Interim file system is (nearly) a superset of an Alto file system, this scavenger can also repair non-IFS Trident file systems.
When to run the scavenger
File system problems can be divided into two classes: 1) minor inconsistancies in file system structures, and 2) massive losses of data. The scavenger is intended to avoid the time-consuming process of reloading the file system from backup when the problems are minor. If a drive cuts loose and obliterates a large part of a pack, then you will be better off reloading from backup.
The most common causes of damage to an IFS are software bugs and hardware glitches which cause the system to stop in an unclean way. There is only one safe way to stop IFS: log in and issue the privledged HALT command. Any other method (including <Ctrl-K> from Swat and <Shift-Swat>) can potentially damage the file system. There are consistancy checks scattered throughout the system which should detect problems and call Swat before extensive damage is done. If this happens, or you are just suspicious and have some time on your hands, then run the scavenger.
Calling the scavenger
The scavenger is invoked by the command
where the switches control the operation of the system in various ways. Switches defined at present are:
/DDebug mode. Various non-fatal errors call Swat rather than just continuing on. More error and warning messages are generated.
/AAllocator debug. Every call to the storage allocator causes a very thorough consistency check to be invoked. This slows down operation of the system considerably.
/UUcode runtime. Enable the microcode version of the Bcpl runtime.
/FFile map. Each occurance of this switch increases the size of directory B-tree file maps by 100 words.
/XExtended memory. Attempt to load the overlays into extended memory and swap them from there rather than from disk.
/SSpy buffer. Allocate a Swat spy buffer for performance tuning purposes.
Unknown switches are ignored; in normal operation no switches should be used.
The scavenger announces itself along with its release date and the date on which it was started, and then waits for commands. The herald is an asterisk. The standard editing characters, command recognition features and help facility (via "?") are available.
Normal operation
The scavenger scans each pack in the file system and then goes back and works some more on the pack containing logical unit 0. Although the order of scanning is unimportant, if logical unit 0 is still spinning when all of the packs have been scanned, you will not have to remount it, so I recommend that you scan it last if you have to cycle packs through a limited number of drives.
If you have enough drives that you can leave all primary packs spinning, then the scavenger can collect their names all at once, and you won’t have to keep coming back every half hour or so to type something.
In the example below, what you type is underlined.
Are all of the packs spinning? [Confirm] Yes.
How many packs are there? n
Scan pack on drive: TPn (0<n<7)
. . .
Scan pack on drive: TPm (n times)
Return to Exec if all goes well? [Confirm] Yes.
Scratch disk: DPm or TPm (see below)
When it is done with that pack, if it is not sure which pack to scan next it asks:
Scan pack on drive TPn
When it has scanned all of the packs, if it is not sure which drive has logical unit 0 it asks:
Which drive has logical unit 0? TPn
Finally, it says:
Pass 2 complete
Print IfsScavenger.log (see below), restart IFS, restore damaged files from backup, and notify owners of lost files not protected by backup.
You can get IFS to restart automatically after scavenging by typing ahead to the Alto Exec:
and answering yes to the question "Return to Exec if all goes well?".
If only the directory B-tree is damaged
The most common reason for running the scavenger is to repair damage to the internal structure of the directory B-tree. If this is all that is wrong then most of pass 1 can be skipped at a considerable savings in time. Before issuing the Scavenge command, type ’justFixDir’. This toggles a flag by the same name, and the scavenger should respond ’yes’.
Scratch disks
The scavenger builds some large data structures which it must keep on some disk. It can use a Diablo or a Trident. The scavenger runs about twice as fast using a Trident, and the size of file system that can be scanned with a Diablo scratch disk is limited.
If you have only one Trident drive, then you must use the Diablo for the scratch disk. This disk should be very empty. The number of free pages required is a function of the size of the largest disk and the number of files in the IFS. The table below estimates the minimum number of free Diablo pages needed to scavenge representative configurations.
largest disk1000 files5000 files10000 files25000 files

I recommend that you keep a disk with just the following files:
If you have more than one Trident drive, I recommend that you use one of them for the scratch disk. The scavenger only needs one IFS pack spinning at a time, so you can do this even if you use all of the drives when running the file system (of course this means that you aren’t doing backup and should have your head examined). Depending on the size of the IFS, the scavenger will need between a few hundred and a few thousand pages on the scratch disk (divide the numbers in the table above by 4 for a Trident).
Any Trident disk with enough pages will do, but things will go faster if the pages can be allocated contiguously. Therefore I recommend using a freshly erased scratch pack (do this by ’TFU Drive n | Erase’). Of course, the pack should have been previously certified (tested and bad spots logged) (do this by ’TFU Drive n | Certify’). See the TFU documentation for more on preparing a scratch pack.
Scavenger log
The scavenger appends display output to a typescript file (IfsScavenger.log) on the Diablo disk. You can use this information to notify the owners of files to which the scavenger does something drastic.
During normal operation, the scavenger will display some messages telling what it is doing and summarizing statistics about the file system. A section at the end of this memo explains the messages.
Pass 2 can potentially generate a lot of log output which might run DP0 out of space. If this happens, the log file is closed and a message to that effect is displayed on the CRT.
Other commands
There are a number of commands in addition to Scavenge; most have to do with debugging the scavenger.
Returns control to the Alto Executive.
Scans a pack and makes it into a well-formed Trident file system. The dialog goes as follows:

Scratch disk TPm
Scan pack on drive TPn
Is this an IFS pack? [Confirm] Yes
. . .
May I alter your disk? [Confirm] Yes

Alert readers will have noticed the similarity between this dialog and that for the Scavenge command. The Scavenge command is implemented by repeatedly calling Pass1 until all of the packs in the IFS have been scanned and then calling Pass2. The Scavenge command tells Pass1 that it is working on an IFS, that it’s OK to make changes, and that if it is a T-300 then there are two logical file systems on the pack.
Verifies the health of the directory B-Tree, and then verifies that all of the files discovered during the previous scans are listed in it, and no others. If Pass2 is invoked without previously running Pass1, it assumes that you ran Pass1 during a previous invocation of the scavenger. In this case it asks you which disk to use for scratch, and assumes that the proper scratch files are out there.
Prompts you for the name of the scratch disk. Diablo disks are called DP0 and DP1. Trident disks are called TPn, where n is the physical unit number in the right byte, and the logical file system in the left byte, so, e.g., TP401 is the second (middle) file system on drive 1, a T300.
This command turns on debug mode. More debugging information is output to the display, including some non-fatal error messages such as soft disk errors. The scavenger will pause after each phase has been swapped in so that breakpoints can be set. Typing any character proceeds it.
Invokes a simple disk editor with a DDT-style command syntax. The editor is described in more detail below.
Dumps (converts to text format) the contents of the leader page table (one of the scratch files) into a file on DP0. The dialog goes as follows:

Scratch disk: TPn (see below)
What shall I call the output file on DP0? foo
Do you want just page usage info? [Confirm] No

The text file produced by this command lists each file, its fp and selected information from the DIFRec if present. If you answer ’yes’ to the last question, then only the number of pages used and the page usage limit for each directory is output. The LPT is deleted by pass2 unless the debug flag is set.
Dumps (converting to text format) the contents of the IFS directory B-Tree into a file on DP0. The dialog is very similar to DumpLPT, and the description for that command applies here too.
Toggles a flag which allows you to edit the information in Ifs.Home when it comes under scrutiny during Pass1.
Toggles a flag which controls whether or not the scavenger recreates the directory B-tree from scratch during pass 2. This takes much longer.
Toggles a flag which controls whether the scavenger appends to an existing leader page table scratch file or resets it to empty. If the scavenger is quit between packs during pass 1, the scavenge can be continued by setting this flag false.
Scavenging non-IFS trident packs
To scavenge a non-IFS Trident pack (Spruce, Press, AIS, etc.), just run Pass1 on it and reply ’No’ when it asks if it is an IFS pack.
Hard disk errors
The scavenger does not try to diagnose an unreadable sector, it merely adds it to the bad page list and truncates the file that includes it. Often the sector is not really a bad spot (an imperfection in the recording media), and all that is wrong is that the controller glitched while writing, causing a bad checksum or some other minor problem. However, to firmly establish the soundness of a sector requires extensive and subtle testing. This is done by the ’certify’ command of TFU, not by the scavenger. Over time, a file system will accumulate ’crud’. Eventually, an opportunity will present itself (usually unanticipated and damned inconvenient) to reload the file system: the packs can be re-certified, the true bad spots identifed, and the falsely accused returned to service.
A common failure mode is to wipe out an entire track. This often results from a power failure or other sudden interruption such as tripping over a disk cable and yanking it out of the back of the Alto. Track zero, in particular virtual disk address one, must be readable by the scavenger. If it is not, you should use TriEx to rewrite the header, label, and data records. This will turn them into free pages, which reduces the damage to a problem which the scavenger knows how to solve.
Duplicate Files
Duplicate files are files with exactly the same IFS file name. They are caused when a files’s directory entry falls out of the B-tree, usually because it has just been inserted, and the dirty pages have not been flushed to the disk when the system crashes. The scavenger enters one of the duplicates under its proclaimed name, and enters the other copies under aliases. The names in the leader pages of these duplicates won’t match their directory entries, so the file system is in a slightly inconsistant state and requires some manual repair by a system administrator after the system is restarted. If things aren’t cleaned up, the scavenger will complain about the inconsistancies the next time it is run.
A Duplicate file name is generated by a mechanical process, and has the form "<System>Duplicate>SNxxx-Dir-SubDir-Name.ext!vers". It is inserted in <System>Duplicate> so that all duplicates are in one place where it is easy for an administrator to work on them. The serial number is included to increase the probability that the resulting name is unique. The directory punctutation (">" and "<") in the original name is neutralized by converting it into dashes.
When duplicate files crop up, you should process them at your earliest convenience, not only because until you does they will continue to reappear each time the file system is scavenged, but also because a bogus file by the same name may be lurking in some unsuspecting user’s directory. Consult with the owner of the files to decide which ones to keep. Usually one of the files is ’good’ (the file creation date is a good hint--the most recently created file is usually the ’good’ one) and all the others can probably be deleted. If a ’bad’ one is in <System>Duplicate>, then simply delete it; if a ’bad’ one is in the user’s directory, delete it and move the ’good’ one from <System>Duplicate> to the user’s directory by renaming it. Deleting a duplicate file obviously cures the inconsistancy in the file system structure; renaming a file rewrites the name in the leader page also repairing it.
Duplicate directory information files (DIFs) require special treatment. If the ’bad’ DIF is in <System>Duplicate>, then simply delete it (since it is a ’permanent’ file, you must be enabled and give an extra confirmation). If the ’bad’ file is in the user’s directory, you must not delete it, but instead overwrite it with the ’good’ copy. This can’t be done with a Telnet command, you must use Ftp. Retrieve the ’good’ DIF from <System>Duplicate> and store it as "<Directory>!1", where Direcory is the directory name. Then delete the copy on <System>Duplicate>.
Disk editor
The scavenger contains a simple disk editor with a DDT-style command syntax. I wrote it so that I could damage a file system in controlled ways and test the scavenger’s ability to fix the damage. It has turned out to be a useful tool in its own right. To start the disk editor type:
What disk would you like to edit? TPn
When the editor is running, the normal small display is replaced with a large one. The top level commands are (all numbers are octal):
close the current page and open the page whose virtual disk address (vda) is equal to <number>. If no <number> is typed, the number last printed is used. The display looks like:

1/ Fid 200000144;1 pn 0 nc 4000 prev 177777 next 2

1/ means vda 1 is open.
fid 200000144;1 is the serial number;version number.
pn 0 means page number 0 of the file.
nc 4000 means this page contains 4000 bytes (it’s full).
prev 177777 means the back link is EOF.
next 2 means the next page is 2.

Typing just ’/’ follows the forward link in the currently open page.
close the currently open page and open the page pointed to by its back pointer. A number before the ’\’ is illegal, as is typing ’\’ when no page is open.
close the currently open page and open the one with the next higher vda. This sweeps the disk in ascending virtual disk address order (until your finger gets tired).

close the currently open page and open the one with the next lower vda. This sweeps the disk in descending virtual disk address order.
close the currently open page.
quit the disk editor (after confirming) and return to the scavenger’s top level command scanner.
enter an editor for the Label record of the currently open page.
enter an editor for the Data record of the currently open page.
When editing a Label or Data record, the following commands are available:
close the currently open cell and open cell <number> in the record. If no number was typed, the last number displayed is used. The display looks like:

1 = SN1/
40502(if it is a label) or
1/ 40502
101 102AB(if it is a data record).

1/40502 means cell 1 of the record is open and contains 40502.
101 102 is 40502 displayed as bytes.
AB is 101 102 displayed as ascii characters.

Typing just ’/’ now would try to open cell 40502 which is out of range, so the screen would flash.
If <number> was typed, store it in the currently open cell. Close the currently open cell.
If <number> was typed, store it in the currently open cell. Close the currently open cell and open the next cell.
If <number> was typed, store it in the currently open cell. Close the currently open cell and open the cell before it.
return control to the page editor. If you changed the record, you will be asked to confirm rewriting the changed record back onto the disk. If the record is rewritten, the page is closed.
Reporting scavenger bugs
Assuming that the hardware is in good health, the scavenger should be bullet-proof: no matter how badly mangled the file system is, the scavenger should not go into Swat. If it does, or you believe that the scavenger did the wrong thing, please take the following steps:
1) If you landed in Swat, make a sysout file (type <Ctrl-L> and supply a descriptive filename such as 30Dec79Scav.Swatee), and then type <Ctrl-K>; if you end up in swat again boot.
2) Save IfsScavenger.log.
3) Get in touch with me.
The scavenger is an unfinishable program. As long as IFS is under active development, the details of its structures will change, and the scavenger must change too. Also, the more effort expended on the scavenger, the more weird cases it can repair, and the less often it will be necessary to reload from backup.
An annotated type script
What follows is the typescript from scavenging an IFS that was in good health. Commentary is in a small font to distinguish it from the typescript; what I typed is underlined. The numbers in square brackets tell what module is generating the message. The format is [Pass-Phase]. Places where the scavenger would have paused if the debug flag was set are marked with an asterisk.
Ifs Scavenger, version of November 15, 1980
Started at 16-Nov-80 19:23:47 PST
Are all of the packs spinning? [Confirm]
How many packs are there?
Scan pack on drive
tp1A single-pack IFS, mounted on drive 1 (a T-80).
Scratch disk:
tp0Use the freshly erased pack on drive 0 for scratch.
*Reads each page on the disk and builds the page link map (PLM) and
[1-1] Time = 3:13
the leader page table (LPT). File name syntax is checked.
[1-1] Files = 1038The disk has this many pages which look like leader pages.
*The forward link in each leader page is followed checking the file structure.
[1-2] Time = 0:26Every page which is part of a file is marked accessible.
[1-2] 11678 pages used out of 36674
Last page FA hints are checked.
[1-3] PLM & BT
The PLM is enumerated and all inaccessible pages are made free.
[1-3] Time = 0:30
A bit map is built. Damaged files are repaired or deleted.
[1-3] BPL
The list of incorrigible pages is updated.
[1-3] LPT
Leader pages which need work are rewritten.
[1-3] Time = 0:02
[1-4] SysDir
SysDir is rebuilt from scratch.
[1-4] Time = 0:02
[1-4] DiskDescriptor
DiskDescriptor is rebuilt from scratch, using the bit table from [1-3].
[1-5] File system type: PrimaryIfs.home is verified.
[1-5] File system ID: Primary
If the EditHome flag is set,
[1-5] File system name: Test
you would be able to edit these 5 items.
[1-5] Number of units: 1
[1-5] Created 22-Dec-79 22:19:37 PST
[1-5] Logical unit number: 0
[1-5] LPT
The LPT is scanned looking for special system files
[1-5] Time = 0:10
which are listed in the Special File Table, SFT.
[1-5] SFT
If any files in the SFT were not found, they are created.
Pass1 complete

[2-1] Time = 0:35
The LPT is sorted in directory order.
[2-1] Number of files = 1038
[2-1] SortZone size = 19456 words
[2-2] PostOrder
The directory B-Tree is traversed checking its structure.
[2-2] Time = 0:04
[2-2] 2 levels, 41 pages allocated, 22 used, 19 free.
*The LPT and the Tree are enumerated in parallel.
[2-3] Time = 2:51
The Tree is made to agree with the LPT.
Pass2 complete

Error and warning messages
This section lists all of the error and warning messages generated by the scavenger, along with a brief description of each.
[1-1] Initializing the bad page list
Either the page containing the bad page list (real disk address zero) is unreadable, or the seal which certifies the bad page list data structure is wrong. The scavenger creates a new, empty bad page list.
[1-1] The bad page list overflowed.
[1-1] An entry for cyl xxx hd yy sec z was discarded
The bad page list can hold 511 entries. If it overflows, many pages are unreadable and it is time to recertify the pack. Discarding an entry is harmless, it just means that it will become free the next time the pack is erased. If the sector really is bad, then it will eventually give a hard error again. On the other hand, sectors listed in the bad page list are automatically marked as in use when a pack is erased, meaning that they will never again cause trouble.
[1-1] Soft read error at vda nnn
The trident routines reported a soft read error at virtual disk address ’nnn’. This message is only displayed if debugFlag is true, since 30 or 40 soft errors are normal while scanning a pack. They are usually read data lates causes by leaving the display on during this phase, and are harmless.
[1-*] Hard disk error at vda nnn (cyl xxx hd yy sec z)
[1-*] <action> <record> status: <status>
A disk error has happened which was not fixable by retrying, recalibrating, applying the error correction code if appropriate, and generally doing everything possible. ’nnn’ is the virtual disk address (remember that this is relative to a logical file system); the real disk address is also displayed for convenience when using TriEx. The second line is printed three times, once each for the header, label, and data records. ’action’ is what the controller did during that record: read, write, check, reset, or restore. This error message can be generated from many places during pass 1.
[1-1] Incorrigable page at vda nnn
Virtual disk address ’nnn’ either contains a label with the special ’incorrigable’ seal (it was unreadable to someone in the past), or the sector was unreadable to us (in which case a hard read error will have just been announced).
[1-1] VDA nnn has an illegal <back|next> link of cyl xxx hd yy sec z
The label of the page at virtual disk address nnn contains a pointer (cyl xxx hd yy sec z) to a page which is not a legal real disk address.
[1-1] "oldName" is not a legal IFS name. I renamed it "newName".
A leader page was encountered which contained an illegal IFS name. The ParseFD directory function is used so that the scavenger’s notion of a legal name is identical with the file system’s. The illegal name is replaced by "<System>Anonymous>SNxxx.scavenger!1", where xxx is the file’s serial number. Thus, a file whose name has been trashed will materialize in the Anonymous subdirectory of the system directory. The leader page will be rewritten with the new name during [1-3].
[1-1] "oldName" is not a legal TFS name. I renamed it "newName".
A leader page was encountered which contained an illegal TFS name. The illegal name is replaced by "SNxxx.scavenger", where xxx is the file’s serial number. The leader page will be rewritten with the new name during [1-3].
During [1-2], an error message triggers the display of some background information on the file and page which is causing the trouble. The first complaint about a file prints:
[1-2] FID sn;vn, IFS name "ifsName", TFS name "tfsName"
This information is from the leader page of the file in question. Most user files in IFS don’t have TFS names so no characters will appear between the quotes.
The first complaint about a page prints:
[1-2] FID sn;vn, page number pp, num chars cc
[1-2] vda xxx, previous vda yyy, next vda zzz
This information is from the label of the page in question. Often the bogosity of one of these items is what is being complained about.
[1-2] This is a <free|bad|incorrigable> page!
Starting from a leader page, following a chain of pages, a page of an unexpected type was encountered. This usually means that the next pointer of the previous page is wrong.
[1-2] back pointer is wrong
The back pointer in the current page does not point at the page we just came from.
[1-2] file ID is wrong
The file identifier of the current page is not equal to the file being worked on.
[1-2] setting FID to sn;vn
The scavenger has concluded that the page does in fact belong to the current file, but its file ID is wrong. The label will be rewritten with this new value during [1-3].
[1-2] setting back pointer to nnn
The scavenger has concluded that the page does in fact belong to the current file, but its back pointer is wrong. The label will be rewritten with this new value during [1-3].
[1-2] backing up to vda nnn and truncating
The file has irreparable damage and can only be saved by truncating at the last good page, virtual disk address nnn. This may orphan some pages which will show up as ’inaccessible pages’ during [1-3]. Truncation is accomplished by rewriting the forward link in the label during [1-3].
[1-2] setting page number to nnn
The page number is not the last page number plus one The label will be rewritten with this new value during [1-3].
[1-2] setting numChars to nnn
The number of bytes in the file is wrong. The last page of a file must not be full and all other pages must be. The label will be rewritten with this new value during [1-3].
[1-2] deleted this file - just a leader page
A prospective file turned out to consist of just a leader page, probably due to previous drastic actons by the scavenger, so the leader page will be deleted during [1-3].
[1-2] setting last fa hint: vda xx, page number yy, num chars zz
The last file address hint in the leader page is wrong. The page will be rewritten with this new value during [1-3].
[1-3] inaccessible page:
[1-3] FID sn;vn page number nn, numChars cc
[1-3] current vda xxx, previous vda yyy, next vda zzz
This page is not free or incorrigable, and it is not part of any legal file. It is made free.
[1-4] Moving page at VDA 1
The page at virtual disk address 1 must be the leader page of SysDir. If it isn’t, the current contents are moved elsewhere and page 1 is made free.
[1-4] Creating SysDir
Virtual disk address one is a free page. A file with SysDir’s attributes is created at this address.
[1-4] Creating DiskDescriptor
DiskDescriptor contains the file system’s state, including the page allocation bit table. This file could not be found. One was created.
[1-4] Deleting "name"
This file has some of the characteristics of SysDir, but not enough to believe. It is deleted to avoid further confusion. The scavenger always rebuilds SysDir from whole cloth, so this isn’t as drastic a move as it sounds.
[1-5] Creating Ifs.home
Ifs.home contains configuration information about the pack’s role in a (potentially multi-pack) file system. This file could not be found. One was created.
[1-5] Malformed home block
The contents of Ifs.home is malformed. This will always be the case if it was just created. If this is the first home block encountered, the user is asked to enter reasonable values for each of the entries; otherwise it is initialized from the information in the home blocks of other packs in the file system.
[1-5] File system type: <primary|backup>
[1-5] File system ID: <string>
[1-5] File system name: <string>
[1-5] Number of Units: <decimal number>
[1-5] Created <date>
[1-5] Logical Unit number: <decimal number>
These are the fields of a home block. All but the logical unit number are displayed only for the first home block processed. These fields can be altered if the editHome flag is true or if the first home block encounted is malformed.
[1-5] Are you sure this pack belongs to the same file system as the last pack?
The home block of this pack looks plausible, but is wildly different from the home blocks of previously scavenged packs. Often this is caused by operator error, for example mounting a backup pack by mistake. Replying ’no’ will cause the scavenger to forget about this pack and ask for another one to scan.
[1-5] Creating special file "fileName"
The named file is a special system-related file which must exist. The scavenger couldn’t find it, so it is creating it. All packs must contain "SysDir", "DiskDescriptor" and "Ifs.home". If these don’t exist by now, the scavenger swats, because they should by now, if only because the scavenger would have created them if they didn’t. Logical unit zero must also contain "Ifs.Swap", "Ifs.Dir", "Ifs.Syms" and "Ifs.Errors".
[1-5] Deleting malformed DIF "name"
The named file appears to be a directory information file (e.g., "<Boggs>!1", the place where user information is kept). However, it is obviously damaged, and so it is deleted. [2-3] will discover that it is missing and recreate it.
[2-1] LPT is already sorted
The leader page table, the Scavenger’s version of the file system directory, appears to be sorted already, so it wasn’t sorted again. This can happen if pass two is restarted.
[2-2] Record counts disagree
The actual number of directory entries in IFS.Dir disagrees with the count maintained in the B-tree state page. The state page information is corrected.
[2-2] Tree is not of uniform depth
While traversing the tree, we touched bottom at a different depth than last time. This particular brand of B-tree should have a uniform depth, so this is an indication of serious damage. The tree is initialized to empty.
[2-2] Pointer gr TREE.GreatestPage
A pointer in a B-tree page points to a page which is greater than the greatest page claimed to be in use in the tree’s state page. The tree is initialized to empty.
[2-2] Two pointers to same B-tree page
Two B-tree pages point to the same page. The tree is initialized to empty.
[2-2] Free page encounted
The pointer in a B-tree page points to a free B-tree page. The tree is initialized to empty.
[2-2] Page is <1/3 full
The particular B-tree implementation should make this a very rare case; though it is harmless. This message is only displayed in debug mode.
[2-2] BTP.Freewords > maxFreeWords
The B-tree page claims to have more free space than a page can possibly have. The tree is initialized to empty.
[2-2] Malformed dr
The directory record in a B-tree entry is malformed. The tree is initialized to empty.
[2-2] Records out of order
The directory records are not in proper order (to take an extreme example, "<Boggs>foo!1" appears after "<Taft>bar!1"). The tree is initialized to empty.
[2-2] BTE overflow
The end of the last record on a B-tree page does not fall where the page’s header predicts it should. The tree is initialized to empty.
[2-2] Page has < 4 records
The particular B-tree implementation should make this a very rare case; though it is harmless. This message is only displayed in debug mode.
[2-3] Deleting tree entry "name"
A directory entry for ’name’ appears in the tree, but no file by that name was found by the scavenger.
[2-3] Updating tree entry "name"
The file pointer in the entry for ’name’ is incorrect. It is fixed.
[2-3] Inserting tree entry for "name"
The directory does not list file ’name’, but it is present on the disk. An entry is added to the tree.
[2-3] Duplicate file "<System>Duplicate>SNxxx-Directory-name"
Two files with exactly the same name exist. The second one is given a new unique name and added to the tree. The first part of the name is "<System>Duplicate>", so these files will materialize in the system directory after a scavenge. The next component is the file’s serial number, which guarantees uniqueness of the fabricated name. The remaining characters are the original file name with the directory punctuation, "<" and ">", replaced with dashes.
[2-3] Creating "<xxx>!1"
A group of files was encountered without a corresponding directory information file. A DIF with vanilla attributes is created by the scavenger. A system administrator should adjust them after IFS is restarted.
Revision history
October 1977
First release.
November 1977
Added the abiltiy to scavenge multiple Alto file systems on a single T-300.
February 1980
Many bugs fixed; extensive internal work. InitLPT and Scratch commands added.
November 1980
The scavenge command now collects all of the packs to be scanned before starting. If pass 2 is restarted on an old, sorted LPT, it is no longer resorted. Running out of disk space in the log file is handled gracefully. A new command, JustFixDir, assumes the only damage is to the structure of the directory B-tree, and omits most of pass 1, speeding things up. All records of an incorrigable page are rewritten. The file map for the directory B-tree is always rebuilt.