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.
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.