Log in

No account? Create an account

Previous Entry | Next Entry

That sinking feeling

I've been working for a few weeks on writing some scripts and such to do nice things like generate G-code to control my CNC mill in making gears, and preview tool paths, and bug fixing the DXF file to g-code post-processor I found. I'm getting some nominally useful things in this 'cnc' directory. I was getting a lot of files in there, many of them temporary test files, so I finally went to clean them out.

You know, there's a world of difference between 'rm testfile*' and 'rm testfile.g *'

The sinking feeling hits about then. I'd just deleted all the files in the directory. Including the three weeks of scripting work. Oops. The 'rm' command doesn't have a nice undo feature like dragging a file to the trashcan in OS X does. The files were toast.

Or were they?

I knew the data still had to be on disk, now marked as free space. I'd just find an undelete program to recover them. So I immediately did what any sane geek would do. I deliberately rm'ed a few hundred megs of .CR2 image files I was never going to get around to processing, to make sure that free space for my scripts was less likely to get overwritten immediately. Just in case.

I searched the net for undelete tools for OS X and the HFS+ file system it uses. I did find a few, but I then realized that they only undelete files whose type they recognize while scanning free space. 70-odd file types recognized, none of them .py or .tcl. Dead end.

Well, I've manually hex-edited file systems before to undelete files. Except I don't know the HFS+ file-system format. And a quick net search didn't pop up anything for me immediately.

So I fell back to the basics.

I searched the whole hard disk for strings I knew were in the files I wanted back.
$ sudo grep -ba 'proc read_gcode' /dev/disk0

Five dozen or so variations on the next line appeared.
98326763874: proc read_gcode {token stream} {

After futzing about for a while, I figured out that it had most every version of the files I had ever saved. I figured out the last one was maybe not coincidentally the most recent one. I took it's offset into the disk, and copied that section of disk to a file.
$ sudo tail -c 98326760000 /dev/disk0 | head -1000 > cnc.tcl
$ vim cnc.tcl

I then edited out extra cruft from beginning and end of file.

Actually, it turned out I couldn't use the tail command like that, because for some bizarre reason on OS X, it started eating up massive amounts of RAM and CPU. I actually ended up writing my own short 'skip' C program that seeks directly to the file position given, then starts spewing out the contents of the file given. In this case, the file is the raw disk device itself.

Ta-da! File recovery, the hard way.

For those less technically inclined, this is somewhat like saving Timmy from the well by convincing the local moles that there's some nice tasty veggies to be had if only they would burrow you a tunnel down to the side of the well.



( 7 comments — Leave a comment )
Nov. 18th, 2005 07:14 pm (UTC)
And then...
convincing them that letting you have Timmy is a good idea.

What's that Lassie? We're mired in a war in Asia AGAIN?
Nov. 18th, 2005 07:42 pm (UTC)
"I know the data's still on the disk. If I can figure out which sectors it's in, the rest's just a lot of cut-and-paste." :)
Nov. 18th, 2005 08:14 pm (UTC)
Not even much cut and paste. OS X's HFS+ filesystem tends to avoid fragmentation for files smaller than 20 megs. In point of fact, each of the five files I recovered were contiguous and the data in the correct order. Once I trimmed the beginning and end of extra data and zeros, the scripts ran flawlessly without any data re-ordering.
Nov. 18th, 2005 08:52 pm (UTC)
Whoops! Glad you were able to recover it... Yikes indeed.
Nov. 18th, 2005 09:06 pm (UTC)
Been there done that.

Or my more common mistake with tab completion:

gcc foo.c -o foo.c



I've also done a similar recovery, except I did it from my computer's RAM instead of a drive.
(Deleted comment)
Nov. 19th, 2005 12:06 pm (UTC)
D'oh! I know and use dd for various other things. I don't know why I didn't think of it!
Nov. 20th, 2005 02:24 am (UTC)
I am somewhat scared that I even understood the basis behind what you are saying.
You need your own brand name cereal. It can be like alphabets, only with numerics in there too. Throw in a few symbols, and I can have inspiration for my coder's block on my spoon.
( 7 comments — Leave a comment )