| 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.  
 
 
 |