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