Objective: A file has been accidentally deleted on Linux but another process still has the file open. Restore or recover the file using /proc
filesystem.
On Linux, files are links to an inode that contains all of the file’s properties, such as permissions and ownership, as well as the addresses of the data blocks where the file’s content is stored on disk. When a file is removed from the filesystem, only the link that points to its inode is removed and not the inode itself. In other words, the contents of the inode is not removed but merely marked as free.
Even if a file has been deleted, other processes might still have that file open. Only when all of these processes have closed the file descriptors and all links are removed that an inode and the data blocks (belonging to the deleted file) are marked as available for writing.
So, even if a file has been deleted but if a process still has the file open, the file can still be recovered using the /proc
filesystem.
Let’s now go through an example. Assume that you are working on a file called “mitm.flows”.
1 |
$ cat mitm.flows | base64 | less |
On another terminal, delete the file using rm
.
1 2 3 4 5 6 7 8 9 10 |
$ stat mitm.flows File: 'mitm.flows' Size: 47623305 Blocks: 93016 IO Block: 4096 regular file Device: 801h/2049d Inode: 553990 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 1000/ ibrahim) Gid: ( 50/ staff) Access: 2015-07-19 16:21:20.365416347 +0800 Modify: 2015-07-19 16:21:18.180314515 +0800 Change: 2015-07-19 16:21:18.180314515 +0800 Birth: - $ rm mitm.flows |
Now, the cat
command still has the file opened. Get the process ID of the cat
command by either using ps
or lsof
commands. Note that if the cat
command has closed the file, then we will not be able to recover the file anymore.
1 2 |
$ lsof | grep mitm.flows cat 3215 ibrahim 3r REG 8,1 47623305 553990 /home/ibrahim/mitm.flows (deleted) |
1 2 |
$ ps -ef | grep mitm.flows ibrahim 3215 2815 0 16:21 pts/0 00:00:00 cat mitm.flows |
The process ID of the cat
command is 3215. To prevent the cat
process from running and closing the file, you can send a STOP signal to the cat process. This is optional.
1 |
$ kill -STOP 3215 |
The above command will suspend the cat process and put it as a background job. The background job can be checked in the shell where the cat command was executed.
Now, check the file descriptors for this process in the /proc
directory.
1 2 3 4 5 6 |
$ ls -l /proc/3215/fd total 0 lrwx------ 1 ibrahim staff 64 Jul 19 16:21 0 -> /dev/pts/0 l-wx------ 1 ibrahim staff 64 Jul 19 16:21 1 -> pipe:[19845] lrwx------ 1 ibrahim staff 64 Jul 19 16:21 2 -> /dev/pts/0 lr-x------ 1 ibrahim staff 64 Jul 19 16:21 3 -> /home/ibrahim/mitm.flows (deleted) |
We can see that file descriptor (fd) 3 is pointing to the deleted file. To recover the file, use the following cp
command.
1 |
$ cp /proc/3215/fd/3 /new/path/to/mitm.flows |
The file will now be recovered in the directory specified in the destination.