Let’s say you have a hard drive whose media is failing but whose controller card is still functional. Let’s further say you have a desire to pull a partition off that drive and see what’s still salvageable. And let’s further say you have a computer you’re okay with leaving on for a month or so to do it. All of these things were true about a hard drive that Glendon Mellow, The Flying Trilobite, sent along to me to try to recover — there were some family photos and tax returns that he hadn’t had backed up anyplace when the drive started failing. Being the samaritan that I am, I took the project on as a way to hone my own skills. I also had a feeling I could write a blog post afterward so others might benefit.
This isn’t a 101 level course. Hell, it’s not even a 201, as it assumes you know enough to use Linux’s terminal (no GUIs in this post!), and how to connect your hard drive through a USB adapter or directly. It also assumes the hard drive is in a specific state that it might still be readable even if Windows itself can’t get at the data. This last one is a fairly big assumption, and I trust you’re going to be able to identify when that’s the case.
The first thing you’re going to need to know in this procedure is that everything you do on a hard drive with failing media could provoke the media to fail further, so you definitely want to be careful not to do any writing to the drive you’re trying to recover. The second thing you need to know is that everything you do could take an absurd amount of time. Patience and caution are the watchwords here.
Connect the hard drive to your Linux box by whatever means necessary. We’ll be doing most of our work from the console; feel free to use whatever console terminal you want, and whatever shell, but my personal preference is to use a tabbed terminal like Guake, and
bash as my shell of choice.
If you’re using a USB adapter (like this kind for instance) and can plug it in live while your computer is turned on,
dmesg will show you what drive you’ve just plugged in, usually in square brackets like [sdb].
So, now that we know that Linux can see the controller, we need to find out the parameters of the drive. I assume you know something about the partition structure of the drive, and therefore what partition is the target. In your terminal, use:
sudo parted /dev/sdb
We’ll want to use sector units for our next part, so first type “unit s”, then “p” to print the stats on the device. Again, this might take a very long time, and might even fail. If it doesn’t, you should see something like:
(parted) unit s
Model: ATA TOSHIBA MK1665GS (scsi)
Disk /dev/sdb: 312581808s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 2048s 27265023s 27262976s primary ntfs diag
2 27265024s 27469823s 204800s primary ntfs boot
3 27469824s 97733495s 70263672s primary ntfs
4 97734654s 312580095s 214845442s extended
5 97734656s 136800255s 39065600s logical ext4
6 136802304s 287389695s 150587392s logical ext4
7 287391744s 312580095s 25188352s logical linux-swap(v1)
Let’s imagine, in our hypothetical, that partition 3 — the largest NTFS drive — is the one we’re looking to recover. It’s the one I store my Windows-side Home drive, so it’s a good example. It’s up to you to decide what partition you want to recover, or you could simply do every one of these partitions one at a time if you really aren’t sure.
So, the next thing we need to do is ensure we have a place we can put a drive dump of that partition that has sufficient space. Assuming your block size is 512 like mine, cd to that location, then do the following:
sudo dd bs=512 if=/dev/sdb of=./drivedump-sdb3.dmp conv=noerror,sync iflag=direct skip=27469824 count=70263672
bs is the Block Size listed above.
if is the Input File (in this case the whole sdb drive).
conv set to noerror,sync sets the dd command to plow through any drive errors it finds and replace them with zeroes, rather than aborting the copy.
iflag sets the input method to “direct”, or a raw drive copy.
skip tells dd where to start the copy from — specifically, at the start of the third partition as listed by parted above.
count tells dd how many blocks to copy, as derived by the length of the third partition listed by parted above.
And then you wait. However long it takes. In my case, with Glendon’s drive, my netbook chunked away at the 26 gig partition for over a month. But, when it was done, I had a full drive dump that I could mount as a drive and explore locally.
If you want to watch to see how big the drive dump is getting, you can do something fairly simple in a new shell tab:
watch -n1 ls -la ./drivedump-sdb3.dmp
This runs the ls command every second and refreshes the output. That way you aren’t going and checking manually every time you decide to go look to see how far along it’s gotten.
To mount the drive once it’s done, do the following:
sudo mount -o loop -t ntfs ./drivedump-sdb3.dmp temp
Of course, if the partition was a type other than ntfs, feel free to change the -t parameter to the filesystem you were recovering. Now the temp folder should have all the contents of the drive you’ve copied. Grab them and restore them however you please.
If there were a lot of errors during the copy, many files may not be fully intact, but they’re at least browsable and you can see what you can salvage this way. Imagine each media error that dd encountered as a bullet hole somewhere on your hard drive. If the bullet hit a file, that file might be badly damaged and unreadable, or simply missing a few letters, depending on what kind of file it is. A text document, for instance, is more resilient than a jpeg image, and an image is more resilient than a zip file or Word document.
If you have any other tips and tricks, feel free to throw them together here. And if you have any questions, don’t hesitate to ask. I’d be glad to impart my vast (snicker) wisdom.