fsdb -- filesystem debugger


/etc/fsdb special [ - ]


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(TM) 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.

Execute a system command in a sub-shell. You are returned to fsdb when the shell exits.

Toggle error checking on or off. The new mode is displayed.

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

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.

Increment the current working address by number of current units (default is 1).

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

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:

Selects byte mode; data at the current working address is displayed as an unsigned single byte value.

Selects long (double) word mode; data at the current working address is interpreted as an unsigned long integer.

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.

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.

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

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.

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''):

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.

The number of links to a file (link count).

The user ID of the file.

The group ID of the file.

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.

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.

The major number of a device special file.

The minor number of a device special file.

File access time.

File modification time.

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:

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.

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:

Print as octal bytes.

Print as characters.

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

Print as decimal short words.

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

Print as octal short words.

Print as hexadecimal short words.

Assignment expressions

Assign a string. This is used to enter a new filename into a directory entry slot, for example:
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.

Assign a number.

Increment by a number.

Decrement by a number.


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:

Examples of fsdb commands

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

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.

Display the root directory inode.

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.

Display the fourth root directory entry.

Display the fifth root directory entry.
Set the permissions on the root directory to ``d---rwxrwx---'' (in symbolic form). See chmod(C) for a description of the flags.

Print inode number 386 in an inode format. This now becomes the current working inode.

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.

Set the link count for the working inode to 4.

Increment the link count by 1.



Any of these command sequences prints block zero of the file associated with the working inode in ASCII.


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.


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.

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.

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.

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.

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.


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.


fsdb should only be used on an unmounted filesystem.

fsdb cannot be used with DOS, HS, or Rock Ridge filesystems.


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