| jul92.tar |
The UNIX File System Debugger -- FSDB
Chris Hare Of the many different debuggers available under UNIX -- such as the C language debuggers adb and sdb, dbx, and CodeView -- one of the least commonly used is fsdb, the file system debugger. The reasons for fsdb's unpopularity are several: it is difficult to use; it does not guard for user errors; and it has no "undo" facility. Despite these shortcomings, however, fsdb offers some powerful capabilities not available elsewhere. fsdb can be used to resolve file system inconsistencies which fsck might consider fatal. One such example is the "ROOT INODE NOT DIRECTORY" error. When fsck sees this condition, it aborts; with fsdb the root inode can be restored, but other problems are likely to occur. fsdb is typically used for correcting filenames that were created with invalid or embedded control characters. ( A program solely for this purpose was written by Rebecca Thomas and published in UNIX World, February 1991.) Starting fsdb fsdb can be started with either the block or the character device name of the file system on which the work needs to be performed, as it will work equally well with either device. The syntax is as follows:
# fsdb /dev/fd148ds9
Once started, fsdb reports on the size of the file system being examined. It also performs some simple bounds checking on startup. For example, if the size of the ILIST is larger than the size of the file system, then the superblock is corrupt. Unlike fsck, fsdb allows you to operate on MOUNTED file systems. This is because fsdb assumes that you know what you are doing and will do whatever you ask of it. The only command line option for fsdb is "-", which instructs fsdb to disable the bounds checking it performs on startup. The bounds checking can also be disabled after fsdb has started by using the O command. fsdb is not for the faint of heart. It is not user friendly, and it doesn't provide many of the expected user amenities: prompts, detailed error messages, etc. To top it all off, many of the commands mean one thing when used one way, and something completely different when used another. fsdb commands operate on the information at an address. If the address to be worked on is not specified in the command, then the current address is used. The address in use may be a disk block, a byte address, or an inode. It should be stressed that the current address may have changed depending upon the last command issued. If a read was issued, then the address may have changed once the read was completed. (For an overview of fsdb commands, including its print facility commands, see Table 1). Viewing Inodes To see the information on a particular inode, use the i command, preceded by the number of the inode. Listing 1 shows how to view the root inode. Using the mnemonic followed by an equal sign (as in ln=), you can change anything in the inode with the exception of the ct value (altering the ct value is considered a security breach. However, you can still change anything, including the deletion of the file, by changing the link count to zero. (For a list of the mnemonics used in an fsdb display, see Figure 1.) Altering Values As mentioned earlier, fsdb can be used to correct, or at least attempt to correct, problems in inodes. The degree of success depends on the severity of the problem. For example, if fsck reports that the root inode is not of directory type, you can use fsdb's md (or mode) mnemonic to set the mode to type directory. The legal file modes for System V UNIX are shown in Figure 2. The "XXX" in each of the modes are the permission positions. Listing 2 shows how to set the damaged root inode back to type directory. Note that fsdb responds with the address being changed, and the octal and decimal values it has been changed to. This operation is perhaps a desperate measure, especially for the root inode, as it is highly likely that there will be many other problems as well. Displaying Directories Displaying directories involves a little more than displaying inodes. First, make sure that you know the inode number of the directory you want to view (from having tried it, I can assure you that traversing the directory structure using fsdb can be an exercise in frustration. Remember where file names are, and what you see in inodes? You would have to read the name list for every directory to see where you were.) To find the inode number of the directory, use the ls -id command. This command lists the inode number only for the directory, not for all of the files in the directory as ls -i would. The command
# ls -id /u/chris
results in the display
3392 /u/chris
To display the directory, use the command shown in Listing 3. In this command line, 3392i instructs fsdb to use the inode number, 3392, as the address, f tells it to print file contents; and d requests fsdb to print the contents as directory entries. Notice that fsdb lists a total of 64 slots, whether or not all 64 are used. This is because a directory entry under System V is 16 bytes long, and 64 entries can fit into one 1024-byte block. The print facilities can be terminated at any time by typing the INTERRUPT character. If there are more entries -- that is, if the address of the second block (a1) is not zero -- you can use wither of two commands to display them. The first is the f1d command, which instructs the file print facility to print the next block. This command works because after part of a file has been printed, the current location in the file is where the print terminated. You can also use the example from the fsdb manual pages: a1bp0d. This command says that the block address of the current inode (a1b) should be printed (p) listing all (0) entries in directory format (d). Changing Other Inode Values The most common use for fsdb is to fix corrupted file names: that is, names that cannot be read because they contain illegal characters or embedded control codes. Before changing anything, however, you must display the contents of the directory file. fsdb provides two mnemonics for the items in a directory entry: the first, dN (where N is the entry number) refers to the slot in the directory. Changing the value of the directory slot assigns the specified inode number to the entry. To assign a new inode to slot 2, you would use
d2=13
where 13 is the inode to which this directory entry should point. The second mnemonic allows you to change the name associated with a particular entry:
dNnm="string"
where N is the entry number and nm indicates that the name portion of the entry is to be modified. Note from the mnemonics list that =" is used to assign a string value. The string is the new file name. fsdb will know that the value is a string if the first character is alphabetic, but if you must use numbers or a period to start the file name, you will have to use the quotes. |