fsdb(1M)                                                              fsdb(1M)


NAME
     fsdb - filesystem debugger for EFS

SYNOPSIS
     fsdb [-?] [-o] [-p'string'] [-w] special

DESCRIPTION
     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
     through familiarity.

     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,

          > 2:inode

     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

          > 2000,400/X

     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

     or

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

     Note that:


          > 2:inode; :ls /

     or

          > 2:inode
          > :ls /

     is again synonymous.

EXPRESSIONS
     fsdb recognizes the following symbols.  There should be no white space
     between the symbols and the arguments.

     carriage return
              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
              or digit.

     =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
              next item).

     =[e]

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

COMMANDS
     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
     are available.

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

     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
                 quotes (").

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

     ! sh        Escape to shell.

INODE COMMANDS
     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,

          > :ln=+1

     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,


               > 1:db:block,20/X

          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,


               > 1:len/b

          displays the contents of the len field of extent number 1.

     mt   Modification time.

     md   Mode.

     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,


               > 7:dir:nm="foo"

          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,


               > 3:off,3/b

          displays the contents of the off field of extent number 3.

     sz   File size.

     uid  User ID.

FORMATTED OUTPUT
     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
     displaying:


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

EXAMPLES
     > :base         Display the current input/output base (hexadecimal by
                     default).

     > :base=0xa     Change the current input/output base to decimal.

     > 0t2000+(0t400%(0t20+0t20))=D
                     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).

     > 7:dir:nm="name"
                     Change the name field in the directory slot to name.

     > 2:db:block,*?d
                     Display the third block of the current inode as directory
                     entries.

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

     > 0x43b:block=0xdeadbeef
                     Set the contents of disk block number 0x43b to
                     0xdeadbeef.  0xdeadbeef may be truncated depending on the
                     current type.

     > 2050=0xffffffff
                     Set the contents of address 2050 to 0xffffffff.
                     0xffffffff may be truncated depending on the current
                     type.

     > 1c92434="this is some text"
                     Place the ASCII for the string at 1c92434.

     > 2:inode:0:db:block,*?d
                     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.

SEE ALSO
     fsck(1M), dir(4), efs(4), inode(4).


                                                                       Page 10