fsdb - filesystem debugger for EFS
fsdb [-?] [-o] [-p'string'] [-w] special
fsdb is applicable only to EFS filesystems.
fsdb can be used to patch up a damaged filesystem after a crash. It has
conversions to translate block and i-numbers into their corresponding
disk addresses. Also included are mnemonic offsets to access different
parts of an inode. These greatly simplify the process of correcting
control block entries or descending the filesystem tree.
Because fsdb reads the disk raw, it is able to circumvent normal
filesystem security. It also bypasses the buffer cache mechanism.
Hence, it is not advisable to use fsdb to write to a mounted filesystem.
The options available to fsdb are:
-? Display usage.
-o Override some error conditions.
-p'string' Set prompt to string.
-w Open for write.
fsdb contains several error-checking routines to verify inode and block
addresses. These can be disabled if necessary by invoking fsdb with the
-o option or by the use of the o command.
special is the name of a character device file. fsdb searches /etc/fstab
for the raw character device filename, if given the name of a filesystem.
A buffer management routine is used to retain commonly used blocks of
data in order to reduce the number of read system calls. All assignment
operations result in an immediate write-through of the corresponding
block. Since fsdb opens the raw device file, any write-throughs bypass
the filesystem buffer cache, resulting in a potential mismatch between
on-disk and buffer cache data structures. Hence, it is recommended that
fsdb not be used to write to a mounted filesystem. Note that in order to
modify any portion of the disk, fsdb must be invoked with the -w option.
Wherever possible, adb-like syntax was adopted to promote the use of fsdb
Numbers are considered hexadecimal by default. However, the user has
control over how data are to be displayed or accepted. The base command
displays or sets the input/output base. Once set, all input defaults to
this base and all output is shown in this base. The base can be
overridden temporarily for input by preceding hexadecimal numbers with
0x, decimal numbers with 0t, or octal numbers with 0. Hexadecimal
numbers beginning with a-f or A-F must be preceded with 0x to distinguish
them from commands.
Disk addressing by fsdb is at the byte level. However, fsdb offers many
commands to convert a desired inode, directory entry, block, superblock,
and so forth to a byte address. Once the address has been calculated,
fsdb records the result in dot.
Several global values are maintained by fsdb: the current base (referred
to as base), the current address (referred to as dot), the current inode
(referred to as inode), the current count (referred to as count), and the
current type (referred to as type). Most commands use the preset value
of dot in their execution. For example,
first sets the value of dot to 2, : alerts the start of a command, and
the inode command sets inode to 2. A count is specified after a ,. Once
set, count remains at this value until a new command is encountered,
which resets the value back to 1 (the default). So, if
is typed, 400 hexadecimal longs are listed from 2000, and when completed
the value of dot is 2000 + 400 * sizeof (long). If a carriage return is
then typed, the output routine uses the current values of dot, count, and
type and displays 400 more hexadecimal longs. An * causes the entire
block to be displayed.
End of block and file are maintained by fsdb. When displaying data as
blocks, an error message is displayed when the end of the block is
reached. When displaying data using the db, directory, or file commands,
an error message is displayed if the end of file is reached. This is
needed primarily to avoid passing the end of a directory or file and
getting unknown and unwanted results.
Examples showing several commands and the use of carriage return are:
> 2:ino; 0:dir?d
> 2:ino; 0:db:block?d
The two examples are synonymous for getting to the first directory entry
of the root of the filesystem. Once there, subsequent carriage returns
(or + or -) advance to subsequent entries.
> 2:inode; :ls /
> :ls /
is again synonymous.
fsdb recognizes the following symbols. There should be no white space
between the symbols and the arguments.
Update the value of dot by the current value of type and display
using the current value of count.
# Numeric expressions can be composed of +, -, *, and % operators
(evaluated left to right) and can use parentheses. Once
evaluated, the value of dot is updated.
,count Count indicator. The global value of count is updated to count.
The value of count remains until a new command is run. A count
specifier of * attempts to show a block's worth of information.
The default for count is 1.
?f Display in structured style with format specifier f (see
FORMATTED OUTPUT section).
/f Display in unstructured style with format specifier f (see
FORMATTED OUTPUT section).
. The value of dot.
+e Increment the value of dot by the expression e. The amount
actually incremented is dependent on the size of type:
dot = dot + e * sizeof (type)
The default for e is 1.
-e Decrement the value of dot by the expression e (see +).
*e Multiply the value of dot by the expression e. Multiplication
and division do not use type. In the above calculation of dot,
consider the sizeof ( type) to be 1.
%e Divide the value of dot by the expression e (see *).
<name Restore an address saved in register name. name must be a
single letter or digit.
>name Save an address in register name. name must be a single letter
=f Display indicator. If f is a legitimate format specifier (see
FORMATTED OUTPUT section), then the value of dot is displayed
using format specifier f. Otherwise, assignment is assumed (see
=[s] Assignment indicator. The address pointed to by dot has its
contents changed to the value of the expression e or to the
ASCII representation of the quoted (") string s. This may be
useful for changing directory names or ASCII file information.
=+e Incremental assignment. The address pointed to by dot has its
contents incremented by expression e.
=-e Decremental assignment. The address pointed to by dot has its
contents decremented by expression e.
A command must be prefixed by a : character. Only enough letters of the
command to uniquely distinguish it are needed. Multiple commands can be
entered on one line by separating them by a space, tab, or ;.
In order to view a potentially unmounted disk in a reasonable manner,
fsdb offers the cd, pwd, ls, and find commands. The functionality of
these commands substantially matches those of its IRIX counterparts (see
individual commands for details). The *, ?, and [-] wildcard characters
base=b Display or set base. As stated above, all input and output
is governed by the current base. If the =b is left off, the
current base is displayed. Otherwise, the current base is
set to b. Note that this is interpreted using the old value
of base. To ensure correctness, use the 0, 0t, or 0x prefix
when changing the base. The default for base is hexadecimal.
block Convert the value of dot to a block address.
cd dir Change the current directory to directory dir. The current
values of inode and dot are also updated. If no dir is
specified, then change directories to inode 2 (/).
cg Convert the value of dot to a cylinder group.
directory If the current inode is a directory, then the value of dot is
converted to a directory slot offset in that directory. dot
now points to this entry.
file The value of dot is taken as a relative block count from the
beginning of the file. The value of dot is updated to the
first byte of this block.
find dir [-name n] [-inum i]
Find files by name or i-number. find recursively searches
directory dir and below for filenames whose i-number matches
i or whose name matches pattern n. Note that only one of the
two options (-name or -inum) can be used at one time. Also,
the -print is not needed or accepted.
fill=p Fill an area of disk with pattern p. The area of disk is
delimited by dot and count.
inode Convert the value of dot to an inode address. If successful,
the current value of inode is updated as well as the value of
dot. As a convenient shorthand, if :inode appears at the
beginning of the line, the value of dot is set to the current
inode and that inode is displayed in inode format.
ls [-R] [-l] pat1 pat2 ...
List directories or files. If no file is specified, the
current directory is assumed. Either or both of the options
can be used (but, if used, must be specified before the
filename specifiers). Also, as stated above, wildcard
characters are available and multiple arguments can be given.
The long listing shows only the i-number and the name; use
the inode command with ?i to get more information. The
output is sorted in alphabetical order. If either the -R or
the -l options is used, then the files can have a character
following the filename, indicating the type of the file.
Directories have a /, symbolic links have a @, AF_UNIX
address family sockets have a = and fifos have an f. Regular
files and block and character device files have an * if they
are executable. If the file type is unknown, then a ? is
override Toggle the value of override. Some error conditions can be
overridden if override is toggled on.
prompt p Change the fsdb prompt to p. p must be surrounded by double
pwd Display the current working directory.
quit Quit fsdb.
sb The value of dot is taken as the basic block number and then
converted to the address of the superblock in that cylinder
group. As a shorthand, :sb at the beginning of a line sets
the value of dot to the superblock and displays it in
! sh Escape to shell.
In addition to the above commands, there are several commands that deal
with inode fields and operate directly on the current inode (they still
require the :). They can be used to display more easily or change the
particular fields. The value of dot is only used by the :db, :len, and
:off commands. Upon completion of the command, the value of dot is
changed to point to that particular field. For example,
increments the link count of the current inode and set the value of dot
to the address of the link count field. It is important to know the
format of the disk inode structure and the size and alignment of the
respective fields; otherwise the output of these commands is not
coherent. The disk inode structure is available in <sys/fs/efs_ino.h>.
at Access time.
ct Creation time.
db Use the current value of dot as an index into the list of extents
stored in the disk inode to get the starting disk block number
associated with the corresponding extent. Extents number from 0 to
11. In order to display the block itself, you need to pipe this
result into the block command. For example,
gets the contents of disk block number field of extent number 1 from
the inode and converts it to a block address. Twenty longs are then
displayed in hexadecimal (see the FORMATTED OUTPUT section).
gen Inode generation number.
gid Group ID.
ln Link count.
len Use the current value of dot as an index into the list of extents
stored in the disk inode to get the length associated with the
corresponding extent. Extents number from 0 to 11. This field is
one byte long. For example,
displays the contents of the len field of extent number 1.
mt Modification time.
maj Major device number.
min Minor device number.
nex Number of extents.
nm Although listed here, this command actually operates on the
directory name field. Once poised at the desired directory entry
(using the directory command), this command allows you to change or
display the directory name. For example,
gets the seventh directory entry of the current inode and changes
its name to foo. Names have to be the same size as the original
name. If the new name is smaller, it is padded with #. If it is
larger, the string is truncated to fit and a warning message to this
effect is displayed.
off Use the current value of dot as an index into the list of extents
stored in the disk inode to get the logical block offset associated
with the corresponding extent. Extents number from 0 to 11. This
field is three bytes long. For example,
displays the contents of the off field of extent number 3.
sz File size.
uid User ID.
There are two styles and many format types. The two styles are
structured and unstructured. Structured output is used to display
inodes, directories, superblocks, and the like. Unstructured output only
displays raw data. The following table shows the different ways of
c Display as cylinder groups
i Display as inodes
I Display as inodes (all direct extents)
d Display as directories
s Display as superblocks
e Display as extents
b Display as bytes
c Display as characters
o O Display as octal shorts or longs
d D Display as decimal shorts or longs
x X Display as hexadecimal shorts or longs
The format specifier immediately follows the / or ? character. The
values displayed by /b and all ? formats are displayed in the current
base. Also, type is appropriately updated upon completion.
> :base Display the current input/output base (hexadecimal by
> :base=0xa Change the current input/output base to decimal.
Display 2010 in decimal (use of fsdb as a calculator for
complex arithmetic). The 0t indicates that the numbers
are to be interpreted as decimal numbers and are
necessary only if the current base is not decimal.
Brackets should be used to force ordering since fsdb does
not force the normal ordering of operators. Note that %
is the division symbol.
> 386:ino?i Display i-number 386 in an inode format. This now
becomes the current inode.
> :ln=4 Change the link count for the current inode to 4.
> :ln/x Display the link count as a hexadecimal short.
> :ln=+1 Increment the link count by 1.
> :sz/D Display the size field as a decimal long.
> :sz/X Display the size field as a hexadecimal long.
> :ct=X Display the creation time as a hexadecimal long.
> :mt=t Display the modification time in time format.
> 0:db,3/b Display the block number of the first extent as 3 bytes.
The block number has to be printed out as bytes, because
of alignment considerations.
> 0:file/c Display, in ASCII, block zero of the file associated with
the current inode.
> 5:dir:inode; 0:file,*/c
Change the current inode to that associated with the
fifth directory entry (numbered from zero) of the current
inode. The first logical block of the file is then
displayed in ASCII.
> :sb Display the superblock of this filesystem.
> 0:cg?c Display cylinder group information and summary for the
first cylinder group (cg number 0).
Change the name field in the directory slot to name.
Display the third block of the current inode as directory
> 0:db=0x43b Change the disk block number associated with extent 0 of
the inode to 0x43b.
> 0:len=0x4 Change the length of extent 0 to 4.
> 1:off=0xa Change the logical block offset of extent 1 to 4.
> 0x43b:block/X Display the first four bytes of the contents of block
Set the contents of disk block number 0x43b to
0xdeadbeef. 0xdeadbeef may be truncated depending on the
Set the contents of address 2050 to 0xffffffff.
0xffffffff may be truncated depending on the current
> 1c92434="this is some text"
Place the ASCII for the string at 1c92434.
Change the current inode to 2. Take the first block
associated with this (root) inode and display its
contents as directory entries. It stops prematurely if
the EOF is reached.
fsck(1M), dir(4), efs(4), inode(4).
PPPPaaaaggggeeee 11110000 [ Back ]