Cover V01, I02
Article
Figure 1
Figure 2
Figure 3
Figure 4
Listing 1
Listing 2
Listing 3
Listing 4
Listing 5
Listing 6
Listing 7
Table 1
Table 2

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.

Figure 3 shows two files, test, and testx. In Using fsdb to Read the Superblock

Listings 4, 5, and 6 demonstrate the commands used to read the superblock and show how to interpret the output using the file system structure as defined in /usr/include/sys/filesys.h.

The output of fsdb as shown in Listing 4 is exactly what the user would see when using fsdb. The superblock is from a 386 AT-based system, using SCO XENIX 2.3.4.

To verify the information, and perhaps save yourself some difficulty, you may want to use the sb.c program in Listing 5, or the PERL version, sb.pl, in Listing 6, both of which will dump the contents of the superblock from the filesystem specified. Listing 7 shows the file system structures translation for this Perl program, sb.pl.

Table 2 shows command examples from various manuals. It is included to give you a sense of the strange variations into which the command can be cast into.

Bibliography

Thomas, Rebecca, and Farrow, Rik. UNIX Administration Guide for System V. New Jersey: Prentice-Hall, 1989.

Ritchie, D.M., and Thompson, K. "The UNIX Time-Sharing System," in UNIX System Readings and Applications, Volume 1. New Jersey: Prentice-Hall, 1987.

Thompson, K. "UNIX Implementation," in UNIX System Readings and Applications, Volume 1. New Jersey: Prentice-Hall, 1987.

Santa Cruz Operation. SCO XENIX Installation and Maintenance Guide. Santa Cruz: SCO, 1989.

AT&T. UNIX System V/386 Release 3.2 System Administrator's Reference Manual. New Jersey: Prentice-Hall, 1989.

Bach, Maurice. The Design of the UNIX Operating System. New Jersey: Prentice Hall, 1986.

Kernighan, Brian W., and Pike, Rob. The UNIX Programming Environment. New Jersey: Prentice Hall, 1984.

Fiedler, David and Hunter, Bruce. UNIX System Administration. Indiana: Hayden Books, 1986.

About the Author

Chris Hare is Ottawa Technical Services Manager for Choreo Systems, Inc. He has worked in the UNIX environment since 1986 and in 1988 became one the first SCO authorized instructors in Canada. He teaches UNIX introductory, system administration, and programming classes. His current focus is on networking, Perl, and X.