fsdb(ADM)
fsdb --
filesystem debugger
Syntax
/etc/fsdb special [ - ]
Description
A system administrator can use fsdb to examine and
change a filesystem. This may be necessary to repair a damaged
filesystem after a crash. For example, in some circumstances
such as the superblock being corrupted,
fsck(ADM)
may not be able to correct the damage. In such cases, an
experienced system administrator may choose to use fsdb.
(Note that fsdb is powerful, but you can damage your
filesystem irrevocably if you are not familiar with the details
of filesystem structure. Use it with caution.)
If the system cannot be rebooted, fsdb cannot
be used. If the system refuses to reboot from the hard disk, try
booting from a boot diskette instead.
Once you have repaired a filesystem using fsdb, you
should run fsck (using the -ofull option for
AFS, EAFS and HTFS filesystem types)
on it as a final check.
The argument special is the raw or block device of the
filesystem to be examined.
fsdb takes only one optional argument:
--
Disable error-checking routines that verify inode and block
addresses. This may be necessary because fsdb reads
the inode table size (ISIZE) and the filesystem size
(FSIZE) from the filesystem superblock
as the basis for these checks; if the superblock has been
corrupted, these entries may be incorrect. (Error-checking can
also be turned on or off using the O command.)
Once fsdb has been invoked, it
reports the logical block size of the filesystem and the values
of ISIZE and FSIZE in logical blocks.
fsdb commands
fsdb's command language manipulates the
contents of a UNIX® filesystem. A command sets
the current working address in the filesystem; the contents of
the filesystem at this address may be acted on by the next command.
In this way you can build complex command sequences from the command
primitives. The section ``Examples'' shows how you can create a
filesystem on a floppy disk to practice using fsdb.
The same section also demonstrates how you can build
complex command sequences.
On entering fsdb, you are positioned at the first byte of
the filesystem. You move around the filesystem by specifying
absolute or relative addresses.
You can also specify offsets into directory entries and inode
structures using the mnemonic offset commands provided (see
``Directory offsets'' and ``Inode offsets'').
fsdb can calculate a new working address in the
filesystem given a logical disk block number (from an inode
entry) or an inode number (from a directory entry).
For example, the d command returns an inode
number within a directory entry.
The i command converts an inode number into a disk address,
sets a new current working address, and displays the inode structure.
The a command converts disk block
numbers referenced by an inode to disk addresses, allowing
you to examine or change file data.
Each command displays the data at the current working address in
an appropriate format. This output is suppressed if the
command is immediately followed by another command on the same line.
fsdb outputs an error message
if the structure of the filesystem at the current address is such that
a command cannot be executed or would yield an invalid new address.
The current working address is left unchanged.
fsdb also complains if invalid block or inode numbers are given.
General commands
.-
A do-nothing delimiter; used to break command sequences into
readable units. Any white-space character (tab or space) can
also be used.
!command-
Execute a system command in a sub-shell. You are
returned to fsdb when the shell exits.
O-
Toggle error checking on or off. The new mode is displayed.
q-
Quit from fsdb.
Address offset commands
Numeric values entered are considered to be decimal by default.
You may specify octal values by prefixing them with a ``0''.
<Enter>-
Increment the current address by the size of the data type last
printed (byte, word, long word, directory slot entry or inode).
This allows you to step through part of the filesystem.
+[number]-
Increment the current working address by
number of current units (default is 1).
-[number]-
Decrement the current working address by
number of current units (default is 1).
>-
Save the current working address.
<-
Restore a previous working address saved using >.
number[mode]-
Set the current working address to the absolute address given by
number.
The units of the address may be specified by
appending an address mode (b or i,
for blocks or inodes).
If no mode is given, the address is assumed to be in bytes from
the start of the filesystem.
fsdb outputs the absolute
address followed by the octal and decimal values of the data at
the address in the form:
octal_address[.B
|.D
]: octal_value (decimal_value)
The default is to interpret data as short words (two bytes at a time).
You may also select to display data interpreted as one byte or one long word
(four bytes); the data display mode is indicated by .B
or
.D
respectively. The data display modes are set using
the following commands:
B-
Selects byte mode; data at the current working address is displayed
as an unsigned single byte value.
D-
Selects long (double) word mode; data at the current working address is
interpreted as an unsigned long integer.
W-
Selects short word mode; data at the current working address is
interpreted as an unsigned short integer. This is the default mode.
For example, B512 displays the byte value at address 512,
W512 the short word, and D512 the long word
value at the same address.
b-
Convert a logical block number into a disk address. This is used to access
the data referenced by the a# fields of the inode structure.
For example, 23i.a5b changes the working address to the
address of the sixth direct disk block referenced by inode 23.
i-
Convert an inode number into the disk address of the inode table
entry referenced by the inode number.
For example, 23i sets the working address to the disk
address of the inode table entry for inode 23.
(Note that 2 is always the inode number for the root of a UNIX filesystem.)
Directory offsets
d#-
For AFS, EAFS and S51K filesystems,
index the directory slot entry # in the current disk
block; # is in the range 0 to 63. For HTFS filesystems,
# is in the range 0 to 512. Also, for HTFS, #
is a byte offset
from the beginning of the disk block rather than a slot entry.
This command is also the name of the directory slot displayed
using the d print format (see the section ``Print commands'').
This command returns the inode value referenced by the slot entry;
if followed by the i command, it can be used to change
address to the indexed inode. The inode referenced may be changed using an
assignment expression (see ``Assignment expressions'').
For example, 2i.a1b.d19 would set the working address
to the twentieth entry of the second direct disk block referenced by the
root directory (inode 2). You can display the inode number and
filename stored in the entry using p1d.
Since the directory entry holds an inode number, you can use
this to access the inode table entry. For example,
2i.a1b.d19i would access the inode entry from the
previous example.
nm-
The name of a file in a directory entry; limited to 14 characters
in length (except for HTFS which is 255). The name held
in the directory slot may
be changed using an assignment expression; 2i.a1b.d19.nm="foo"
would change the filename from the previous example.
(Note that long filenames in EAFS filesystems are spread over
several directory slots.)
Inode offsets
These commands are also the name of the inode fields
displayed using the i print format
(see the section ``Print commands''). Any field except
ct may be modified using an assignment expression (see
``Assignment expressions''):
md-
The file mode. This is displayed as a symbolic string (in the style
of ls -l), but it may only be assigned an absolute
numeric value.
ln-
The number of links to a file (link count).
uid-
The user ID of the file.
gid-
The group ID of the file.
sz-
The size of the file in bytes. This is always zero for device
special files; for symbolic links in EAFS filesystems,
it is the length of the pathname string to which the link evaluates.
a#-
The logical disk block numbers of the file: a0 to
a9 are direct block numbers, a10 is a
single indirect block, a11 is a double indirect block,
and a12 is a triple indirect block.
major-
The major number of a device special file.
minor-
The minor number of a device special file.
at-
File access time.
mt-
File modification time.
ct-
Inode change time. fsdb prevents you modifying this
field directly; if necessary, you can change it using the
offset mt+1.
The time fields at, mt, and ct are
stored internally as the number of seconds
since 00:00:00 GMT on January 1 1970; times are converted to your
local time zone before being displayed. You can use
convertclock(TCL)
to find the integer clock value corresponding to a date string,
or getclock to find the current value.
Print commands
The print commands generate various styles of formatted output.
fsdb adjusts the current address to the previous appropriate
boundary before output begins. The current address advances with the
printing, and is left at the end address of the last item
displayed. You can interrupt the output at any time by pressing
the interrupt key (usually <Del> or <Ctrl>C.
fsdb has the following print commands:
p[#][format]-
The general print command displays #
entries (default is 1). The remainder of the current block is
printed if # is 0.
format sets the current display style.
f[#][format]-
Output data for disk block number #
(default is the first block, referenced by a0)
associated with the current inode.
This command is equivalent to the command sequence:
a#b.p0format.
The following print formats are available:
b-
Print as octal bytes.
c-
Print as characters.
d-
Print a directory.
The mnemonics used for the slot entries are described in the
section ``Directory offsets''.
Each slot entry consists of the directory offset followed by the
decimal inode number and the name of the directory entry. For
example, the command 2i.a0b.p8d prints the first eight
directory slot entries for the root directory:
d0: 2 .
d1: 2 ..
d2: 3 dev
d3: 10 bin
d4: 34 etc
d5: 69 shlib
d6: 63 usr
d7: 95 u
d7 and subsequent directory slot entries may be output by pressing
<Enter>.
Filenames longer than 14 characters in EAFS filesystems
are displayed as shown by this example command
2i.a0b.d12.p4d:
d12: 65535 Filename_more_
d13: 65535 than_fourteen_
d14: 103 chars_long
d15: 103 Short_name_one
The filename Filename_more_than_fourteen_chars_long
occupies three directory slots (d12-d14);
only the final slot stores the actual inode number.
The entry Short_name_one refers
to the same inode but occupies only one slot (d15).
e-
Print as decimal short words.
i-
Print an inode showing its number and all members of its structure.
The first field (i#) is the inode number.
The mnemonics of the remaining fields are described in the
section ``Inode offsets''.
This is an example of the output for the root directory inode
using the command 2i:
i#: 2 md:d---rwxr-xr-x ln: 17 uid: 0 gid: 0 sz: 432
a0: 861 a1: 0 a2: 0 a3: 0 a4: 0 a5: 0 a6: 0
a7: 0 a8: 0 a9: 0 a10: 0 a11: 0 a12: 0
at: Fri 15 Jan 12:33:05 1993
mt: Fri 15 Jan 12:33:05 1993
ct: Fri 15 Jan 12:33:05 1993
For symbolic links (EAFS filesystems only), the
sz field shows the length of
the pathname string stored in the disk block referenced by
a0.
For HTFS, if the symbolic link target filename is
less than 53 characters
long, then the name is displayed instead of the block numbers because short
symbolic links are stored directly in the inode.
For the display of special device inodes, the format is changed
to show the major and minor device numbers:
i#: 100 md:c---rwxr-xr-x ln: 1 uid: 0 gid: 0 sz: 0
maj: 004 min: 002 at: Fri 15 Jan 12:33:05 1993
mt: Fri 15 Jan 12:33:05 1993
ct: Fri 15 Jan 12:33:05 1993
o-
Print as octal short words.
x-
Print as hexadecimal short words.
Assignment expressions
=string-
Assign a string. This is used to enter a new filename into a
directory entry slot, for example:
2i.a0b.d12.nm="New_name"
The quotes are optional if the string begins with an alphabetic
character. The string must not be more than fourteen characters long
(for AFS, EAFS and S51K filesystems only).
Numeric assignments are used to change inode numbers in directory
slots, file modes, link counts, user and group IDs, file
sizes, disk block numbers, and times.
The value entered is assumed to be decimal by default; octal values may
be entered if prefixed with a leading 0.
fsdb prevents data from overflowing the current block.
=number-
Assign a number.
=+number-
Increment by a number.
=-number-
Decrement by a number.
Examples
The following example demonstrates the creation of
a filesystem on a diskette. This can then be used to gain
experience of navigating a filesystem with fsdb:
-
Make an EAFS filesystem on a formatted 3.5" high
density floppy disk:
/etc/mkfs -f EAFS /dev/fd0 2880
-
Mount the floppy disk and write some files to it:
/etc/mount /dev/fd0 /mnt
cp files /mnt
-
Unmount the filesystem and run fsdb on it:
/etc/umount /dev/fd0
/etc/fsdb /dev/fd0
Examples of fsdb commands
512B.p0x-
Print the superblock of the filesystem as hexadecimal byte values.
512 sets the working address to 512 from the start of
the filesystem. B selects byte mode; values will be
converted and displayed a byte at a time. p0x prints
the remainder of the logical disk block (bytes 512 to 1023) as
hexadecimal values.
(Note that the superblock in UNIX System V is located in
the second half
of the first block of the filesystem; that is from byte 512 to 1023.
A XENIX® filesystem has its superblock in the second block of the
filesystem; from byte 1024 to 2047.)
W-
Select short word display mode; values will be converted and
displayed two bytes at a time. If you press <Enter>, you
will advance through the filesystem in two byte steps.
2i-
Display the root directory inode.
2i.a0b.p3d-
Print the first 3 entries in the root directory. This example also shows
how several operations can be combined on one command line.
2i selects inode 2. a0 is the offset to the inode
field indexing the first disk block of the inode. b
converts the disk block number to a disk address. p3d
prints the first three directory entries from the address.
The current working address is left at the third entry.
<Enter>-
Display the fourth root directory entry.
<Enter>-
Display the fifth root directory entry.
2i.md=040770-
Set the permissions on the root directory to
``d---rwxrwx---'' (in symbolic form). See
chmod(C)
for a description of the flags.
386i-
Print inode number 386 in an inode format.
This now becomes the current working inode.
=0100600-
Set the permissions on inode 386 to ``f---rw-------''.
Note that the md offset is not necessary because the mode is at
zero offset into the inode structure.
ln=4-
Set the link count for the working inode to 4.
ln=+1-
Increment the link count by 1.
fc-
a0b.p1024c-
a0b.p0c-
Any of these command sequences prints block zero of the file associated
with the working inode in ASCII.
2i.fd-
2i.a0b.p64d-
Print the first 64 directory entries
for the root inode of this filesystem.
If you want to display 12 directory entries at a time use the
command sequence 2i.a0b.p12d followed by instances of
p12d to page through the directory. For HTFS,
it may be more or less than 64 entries.
d5i.fc-
d5i.a0b.p0c-
Change the current inode to that associated with the sixth directory entry
found from the previous command and print the first block of the
file.
Entries are numbered from zero, so the sixth entry is at offset
d5. i converts the inode number in the sixth
slot to a disk address; this becomes the current working inode.
a0 selects the first disk block number referenced by
the new inode. b converts the disk block number to a
disk address. p0c prints the first logical block of the
file in ASCII.
2i.a0b.d7=3-
Change the inode number for the eighth directory slot in the root
directory to 3. 2i.a0b sets the working address to the
first disk block of the directory entries. d7 offsets the
working address to the eighth entry. =3 sets the value
of the inode number held in the slot to 3.
d7.nm=name-
Change the filename field in the same directory slot to name.
d7.nm offsets the working address to the filename field of the
eighth slot. ="name" assigns a new value to the field.
Quotes are optional if the first character is alphabetic.
486i.a10b+12b.fc-
Access and output a single indirect disk block of inode 486.
486i selects inode 486. a10b sets the working
address to the disk address of the indirect block referenced by
a10. +12 advances the current address by 24
bytes. This is the seventh disk block referenced as a single
indirection (indirect disk block numbers are stored 256 to a
logical block as 4-byte long words). b
converts the seventh block number to a disk address. fc
outputs the file data at this address as ASCII
characters.
486i.a11b+16b+4b.fc-
Access and output a double indirect disk block.
This example is similar to the previous one except that one more
level of indirection is used to store the file data.
+16b accesses the ninth single indirect block
referenced by a11 of inode 486. This block stores
the disk block numbers of actual file data; +4b.fc
outputs the third of these blocks.
Warning
fsdb is intended for use by experienced system
administrators who are familiar with the details of filesystem
structure. You are cautioned that you may irrevocably damage the
contents of a filesystem if you do not use fsdb with
care.
If for any reason you change a filename on the root
filesystem with fsdb, you must reboot the system immediately
after exiting fsdb. This will avoid any potential
name-to-inode
look-up problems which could lead to opening a file with the
wrong contents.
Limitations
fsdb should only be used on an unmounted filesystem.
fsdb cannot be used with DOS, HS, or
Rock Ridge filesystems.
Files
/etc/fscmd.d/fstyp-
directory containing programs
for each filesystem type; each of these programs applies
some appropriate heuristic to determine
whether the supplied special file is of the type for which it checks.
See also
chmod(C),
dir(FP),
filesystem(FP),
fsck(ADM),
fstyp(ADM),
mkfs(ADM),
mount(ADM),
convertclock(TCL)
``Troubleshooting system-level problems'' in the SCO OpenServer Handbook
Standards conformance
fsdb is conformant with
AT&T SVID Issue 2.
© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003