Tuesday 12 November 2013

Using DD to copy a failing drive

I have posted before about copying a hard disk using DD.

This post expands on that concept a bit for situations where you need to do an emergency copy of a failing hard disk.

The scenario:

You boot up your system only to receive a SMART warning that one of  your hard disks is failing and should be replaced.

I currently have such a situation.

The drive in question has a bootable Windows partition as well as non-bootable ext4 partition.

Fortunately, I boot my Ubuntu system from a seperate SSD but if you don't have that option then a LiveCD is your best option. 

So, now I have purchased a replacement hard disk and I'm wanting to copy the old drive over to the new drive to save having to do all the re-installing of Windows/Steam.

I am aware of the potential for file corruption and if I see evidence that corruption has adversely affected things I will go to PLAN B, a complete Windows re-install. I hope I won't have to go that route.

So, I plug the new disk into my system and determine that the failing disk is /dev/sdb and the replacement is /dev/sdc

To copy the disk over I want to use the 'dd' command

dd if=/dev/sdb of=/dev/sdc

This works, but after a bit I hit a bad sector, at which point dd stops copying data. This is not what I want.

To make dd ignore errors and re-sync it's position on the target device once it resumes we can expand on our dd command like this:

dd if=/dev/sdb of=/dev/sdc conv=noerror,sync

That's great. Don't you love Unix?

Anyway, after a while of dd chugging along I decide to check on progress. I open another terminal (you can also background the process and use the same terminal) and enter:

kill -SIGUSR1 `pidof dd`

This produces the following output in the terminal window that dd is executing in:

7382+0 records in
7381+0 records out
56787277824 bytes (57 GB) copied, 1369.35 s, 4.1 MB/s

Good lord. At 4.1MB/s this 1TB drive will take an estimated 2 days to complete!

This is obviously unacceptable.

The problem is that dd uses a default block size that is quite tiny. Of course, this being Unix we can control that.

I stop the dd process and re-issue the command, this time specifying a 4M block size:

dd if=/dev/sdb of=/dev/sdc conv=noerror,sync bs=4M

Now, when I check the progress I see a much more satisfying result:

37382+0 records in
37381+0 records out
156787277824 bytes (157 GB) copied, 1369.35 s, 114 MB/s

144 MB/s, that's more like what I want. The re-image should now take a matter of hours rather than days.




No comments: