Relinking a deleted file
Awesome enough would be if you could "undo" the delete by running some magic option to ln that would let you re-link to the inode number (recovered through lsof).
This awesomeness was introduced to ln
in v8.0 (GNU/coreutils) with the -L|--logical
option which causes ln
to dereference a /proc/<pid>/fd/<handle>
first. So a simple
ln -L /proc/<pid>/fd/<handle> /path/to/deleted/file
is enough to relink a deleted file.
It sounds like you already understand a lot, so I won't go into excess detail. There's several methods to find the inode and you can usually cat and redirect STDOUT. You can use debugfs
. Run this command within:
ln <$INODE> FILENAME
Make sure you have backups of the filesystem. You'll probably need to run a fsck afterwards. I tested this successfully with an inode still being written to and it does work to create a new hard link to a dereferenced inode.
If the file is unlinked with an unopen file in ext3, the data is lost. I'm not sure how consistently true this is but most of my data recovery experience is with ext2. From the ext3 FAQ:
Q: How can I recover (undelete) deleted files from my ext3 partition? Actually, you can't! This is what one of the developers, Andreas Dilger, said about it:
In order to ensure that ext3 can safely resume an unlink after a crash, it actually zeros out the block pointers in the inode, whereas ext2 just marks these blocks as unused in the block bitmaps and marks the inode as "deleted" and leaves the block pointers alone.
Your only hope is to "grep" for parts of your files that have been deleted and hope for the best.
There's also relevant information in this question:
I overwrote a large file with a blank one on a linux server. Can I recover the existing file?
the debugfs way as you saw doesn't really work and at best your file will be deleted automatically (due to the journal) after reboot and at worst you can trash your filesystem resulting to "reboot cycle of death". The Right Solution (TM) is to perform the undelete in the VFS level (which also has the added benefit of working with practically all current Linux filesystems). The system call way (flink) has been shot down every time it appeared in LKML so the best way is through a module + ioctl.
A project that implements this approach and has reasonably small and clean code is fdlink (https://github.com/pkt/fdlink.git for a version tested with ubuntu maverick's kernel). With it, after you insert the module (sudo insmod flink_dev.ko) you can just do "./flinkapp /proc//fd/X /my/link/path" and it will do exactly what you want.
You can also use a forward-ported version of vfs-undelete.sourceforge.net that also works (and can also automatically relink to the original name), but fdlink's code is simpler and it works just as well, so it is my preference.
I don't know how to do exactly what you want, but what I would do is:
- Open the file RO from another process
- Wait for the original process to exit
- Copy the data from your open FD to a file
Not ideal, obviously, but possible. The other option is to play around with debugfs (using the link
command), but that's kind of scary on a production machine!