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