The arrow of time

Ivan Voras' blog

Undelete files on FreeBSD?

The short answer is: you can't. The long answer is that it might be possible to recover some lost data, with quite good chances, but absolutely no guarantees. See the rest of the post for details.

I've set up a 8-CURRENT machine in VirtualBox and when I needed a 8-CURRENT system to start working on pkg_trans, I was too lazy to set up another one and started using the VirtualBox VM. As I don't quite trust VirtualBox yet (one thing that's very annoying is that the host bluescreens if suspended and resumed while any VMs running in VirtualBox, even if they are themselves suspended (paused)), I've occasionally made backups to another machine. I didn't bother setting up a VCS since, well, with the backups, what can go wrong, right? Well, wrong. Yesterday, instead of doing "tar czf" I did "tar xzf" and overwritten two days of work with the last backup.

As is well known, file systems commonly used don't really erase data, just remove pointers to the files in the appropriate metadata tables, so in theory, the data is still there and is recoverable. The problem is that since the metadata doesn't point to the file, it's tough to get at the data. UFS2 is not popular enough to have specialized undelete programs. The Coroner's toolkit which is often mentioned for this purpose is old and supports only UFS1. With ZFS, the situation is probably worse.

The only solution always available is to inspect the raw contents of the drive for data. This is tedious at best and requires prior knowledge of what is beeing searched for. For example, I'm searching for source code (i.e. text files) and I remember the names of a couple of functions I wrote so I used that. Searching for binary data would be much harder.

In steps, here's what I did:

  1. Mounted a external computer's drive to store indermediate data over NFS (Samba works also) to /mt
  2. Run strings /dev/ad0s1a > /mt/strings.txt. This step is crucial and it's actually where most improvement can be done. For one thing, strings tends not to look at lines such as "{\n" as being printable characters so it ignores them :( The best that can be done is to use -t switch to manually extract useful offsets.
  3. Wrote a simple python script to search the strings.txt (on the other machine!) for my function name and extract a thousand lines around it.

The result still needed manual patching into the proper source tree with vim, but it's better than nothing.

Post your comment here!

Your name:
Comment title:
Text:
Type "xxx" here: