I have seen several posts about recovering deleted files, but this situation is different. My wife had a file called Journal.odt in which she kept a lot of important personal information such as special memories about our kids. The other day when she tried to open it in OpenOffice it complained about the format. I had her hit cancel and back out. When I cat
the file it is completely empty. ls
says the file is 0 bytes.
Had she accidentally selected all of the text in the file, hit backspace and saved it there would still be the OpenOffice meta information in the file.
I immediately shut her laptop down to prevent making any more changes to disk until I can think of something to do.
I have done some complicated things in the past such as using dd
to recover raw text off the disk but I have no idea what to do here. Since odt files aren't flat text I can't just pipe the whole disk through grep.
Any suggestions would be greatly appreciated.
Also if anyone has any insight as to what might have gone wrong I would love to hear it.
Thanks
Best Answer
If you are using ext3 file system try following Carlo Wood's HOWTO
In few words,
ext3grep $IMAGE --ls --inode 2 | grep your_file
to find the file you are looking for (where$IMAGE
is your partition, for example/dev/sda2
; you'll needext3grep
)dd
.cat
the file wherever you wantFrom the source:
"The chapter Manual recovery example
In the following example we will manually recover a small file. Only partial output is given in order to save space and to make the example more readable.
Using ext3grep $IMAGE --ls --inode we find the name of the file that we want to recover:
Obviously, inode 309631 is erased and we have no block numbers for this file:
Therefore, we will try to look for an older copy of it in the journal. First, we find the file system block that contains this inode:
$ ext3grep $IMAGE --inode-to-block 309631 | grep resides Inode 309631 resides in block 622598 at offset 0xf00.
Then we find all journal descriptors referencing block 622598:
This means that the transaction with sequence number 4381294 has a copy of block 622598 in block 26582, and so on. The largest sequence number, at the bottom, should be the last data written to disk and thus block 8931 should be the same as the current block 622598. In order to find the last non-deleted copy, one should start at the bottom and work upwards.
If you try to print such a block, ext3grep recognizes that it's a block from an inode table and will print the contents of all 32 inodes in it. We only wish to see inode 309631 however; so we use a smart grep:
Direct Blocks:
This is indeed the same as we saw in block 622598. Next we look at smaller sequence numbers until we find one with a 0 Deletion time. The first one that we find (bottom up) is block 6073:
The above is automated and can be done much faster with the command line option --show-journal-inodes. This option will find the block that the inode belongs to, then finds all copies of that block in the journal, and subsequently prints only the requested inode from each of these block (each of which contains 32 inodes, as you know), eliminating duplicates:
The file is indeed small: only one block. We copy this block with dd as shown before:
and then edit the file to delete the trailing zeroes, or copy the first 40 bytes (the given size of the file):
Recovered!"