Oops - Undeleting a file on Freebsd

A perfect storm of filename completion and inattention resulted in the deletion of a C source code file yesterday (.core starts with .c). As a result I had to find a way to “undelete” a file from a FreeBSD system.
Unfortunately, FreeBSD does not have an undelete facility. A bit of simple filesystem forensics was required to access the contents of the file. This only works because the default FreeBSD filesystem tends to cluster the bits of a file close together and it overwrites existing sectors when modifying a file.

The process is fairly simple:
  1. stop doing anything to the filesystem with the file to be undeleted immediately
  2. dd the whole filesystem slice to another disk to create an image file
  3. use grep to find the byte offset of a string in the file in the image
  4. use dd to roughly extract deleted file contents
  5. trim

In my case the series of commands looked like:

dd if=/dev/ad4s1f of=ad4s1f.dd bs=4K
grep -b --binary-files=text dump_stream_info ad4s1f.dd

The string was found at offset 47035498575

dd if=/data/ad4s1f.dd of=/tmp/a.c bs=1000 skip=47035498 count=100

and trimmed the file a.c to remove extraneous bytes.