Friday, August 19, 2011

Finding the deleted node.

Today i found that some of the files are missing from my server, then i tried debugfs

# debugfs /dev/hda2

debugfs: lsdel


echo lsdel
debugfs /dev/hda1 > lsdel.out

debugfs has a stat command which prints details about an inode. Issue the command for each inode in your recovery list. For example, if you're interested in inode number 148003, try this:

debugfs: stat <148003>

If you have a lot of files to recover, you'll want to automate this. Assuming that your lsdel list of inodes to recover in is in lsdel.out, try this:

# cut -c1-6 lsdel.out
grep "[0-9]"
tr -d " " > inodes

This new file inodes contains just the numbers of the inodes to recover, one per line. We save it because it will very likely come in handy later on. Then you just say:

# sed 's/^.*$/stat <\0>/' inodes
debugfs /dev/hda1 > stats

and stats contains the output of all the stat commands.

If the file was no more than 12 blocks long, then the block numbers of all its data are stored in the inode: you can read them directly out of the stat output for the inode. Moreover, debugfs has a command which performs this task automatically. To take the example we had before, repeated here:

debugfs: stat <148003>

Inode: 148003 Type: regular Mode: 0644 Flags: 0x0 Version: 1

User: 503 Group: 100 Size: 6065

File ACL: 0 Directory ACL: 0

Links: 0 Blockcount: 12

Fragment: Address: 0 Number: 0 Size: 0

ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996

atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996

mtime: 0x313bf4d7 -- Tue Mar 5 08:01:27 1996

dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996


594810 594811 594814 594815 594816 594817


This file has six blocks. Since this is less than the limit of 12, we get debugfs to write the file into a new location, such as /mnt/recovered.000:

debugfs: dump <148003> /mnt/recovered.000

Of course, this can also be done with fsgrab; I'll present it here as an example of using it:

# fsgrab -c 2 -s 594810 /dev/hda1 > /mnt/recovered.000

# fsgrab -c 4 -s 594814 /dev/hda1 >> /mnt/recovered.000

With either debugfs or fsgrab, there will be some garbage at the end of /mnt/recovered.000, but that's fairly unimportant. If you want to get rid of it, the simplest method is to take the Size field from the inode, and plug it into the bs option in a dd command line:

# dd count=1 if=/mnt/recovered.000 of=/mnt/resized.000 bs=6065