Recovering a deleted file

Sometimes you have a file which is held open by a running process (probably being written to) but the filename itself has been deleted. The file contents exist as long as the process is running, but when it terminates, the file will disappear and become pretty much unrecoverable.

How can you get at the contents of the file, when the filename has been deleted?

It turns out to be remarkably simple:

  1. Use lsof to get details of the file in question
  2. Create a new file (quite possibly with the same name as the original, or something else if you prefer) and copy the content of the deleted file into it

You then have a copy of the data (up to that point in time) which will not disappear when the process holding the file open terminates.

It's all based around inodes, which are pointers to the location on disk of the contents of a file, whereas the filename is just an entry in a special file which is normally called a directory, and points to the inode. Deleting the filename from the directory does not affect the inode, it simply removes the usual way of referencing it.

Example:

# ps ax | grep pcap
25028 ?        S      0:00 /usr/sbin/tcpdump -w /var/log/smpp.pcap -i any port 2775

# ls -l /var/log/smpp.pcap
ls: cannot access '/var/log/smpp.pcap': No such file or directory

# lsof | grep /var/log/smpp.pcap
tcpdump 25028 root    4w   REG  254,2 36995072 527356 /var/log/smpp.pcap (deleted)

The output of lsof has the following meaning:

tcpdump is the name of the process which has the file open
25028 is the Process ID (PID) of the process which has the file open
root is the username the process is running under
4 is the File Descriptor (FD) being used to reference that file by the process
w means that the file is open for writing
REG means this is a regular file (not a pipe, socket or similar)
254 is the major device number of the disk the file is stored on
2 is the minor device number of the disk the file is stored on
36995072 is the current size of the file in bytes
527356 is the inode where the file is stored on disk
/var/log/smpp.pcap is the name the file had when it was opened
(deleted) means the name has been deleted since the process started writing to the file

To recover the file you simply use the PID and the FD, together with the magic of the proc file system:

# cat /proc/25028/fd/4 >/var/log/smpp.pcap

# ls -l /var/log/smpp.pcap
-rw-r--r-- 1 root root 36995072 May 22 13:06 /var/log/smpp.pcap

You then have a copy of the file with its content at the time you do the copy. Any data which gets written to the file later will only be in the original (deleted) file; you would need to copy it again later if you want to get that content as well.


Go up
Return to main index.