I'm attempting to recover as much data as possible from a failed 750 GB hard drive which is connected via a USB 3 drive enclosure.

The drive itself has over 1500 bad blocks, detected by badblocks on Linux.

It mounts perfectly on my computer (running macOS 10.12), but when data from a corrupt block is read, the drive idles for a few seconds, disappears from /dev, and then reappears — as if someone had unplugged the USB cable and then quickly plugged it back in again.

The first bad block occurs about 136 GiB from the start of the disk, however this is not the only one. This is evidenced by output from badblocks, along with when both dd and ddrescue fail.

dd and ddrescue both fail as soon as they read data from a bad block, since the drive then disappears from /dev:

dd if=/dev/rdisk3 of=image.img bs=16m:

enter image description here

ddrescue -v /dev/disk4 image.img logfile:

enter image description here

Rerunning ddrescue after the initial termination with the same log file results in it immediately terminating and not advancing further.

Since I am able to traverse the filesystem and access some files normally, I wrote a script to determine which files are accessible and which aren't, so I can copy the known good files from the disk. However, this is slow, and I'm worried that it may damage the disk further.

Is there any tool similar to dd or ddrescue which can recover data from this drive, which just waits for the drive to remount instead of automatically quitting upon reading a bad block?

I'm able to use both macOS as well as Linux (Ubuntu), so solutions for either platform would work for me.

  • 1
    By "unmounts" you mean "disappears from /dev", not the umount command, right? I'm asking to avoid terminology confusion. I think ddrescue is supposed to continue its interrupted run when you invoke it with the same logfile. Maybe you can write a simple script that runs ddrescue after a while again and again – and see if it advances your progress. Another approach is to fabricate the initial logfile (based on the badblocks result) so ddrescue never touches problematic sectors. There is ddrescuelog tool that may help. Just an idea, I have never done it myself. – Kamil Maciorowski Oct 22 '16 at 13:13
  • @KamilMaciorowski Yes, by unmount, I mean that it disappears from /dev (and is sometimes assigned a new identifier upon remount). Rerunning ddrescue again results in immediate termination, it never advances further. I'll experiment with manipulating the log file to see if that yields any results. – Jack Greenhill Oct 22 '16 at 13:17
  • But badblocks had no problems, right? Have you tried ddrescue --direct option? – Kamil Maciorowski Oct 22 '16 at 13:27
  • If the USB-SATA bridge causes the "unmount", one solution is to take the drive out of the enclosure and connect it directly via SATA. (All USB closures I've seen so far have SATA drives inside them). – dirkt Oct 22 '16 at 16:05
  • @Jack Greenhill: If my answer was helpful to you, then please consider marking it as the accepted answer so others may more easily find it in the future. This is also a polite way to thank the person answering your question for helping you out. – Andrea Lazzarotto Nov 10 '16 at 19:14

when data from a corrupt block is read, the drive idles for a few seconds, unmounts, and then remounts

I had the same problem with a drive that would "disappear" and then reappear later. It wasn't actually mounting either, but ddrescue was stopping when the device was disappearing. I was using it under Linux, but the situation is very similar.

I suggest you use a bit of simple shell programming and the fact that the drive actually eventually shows up again after a while. In other words, do:

while [ 1 ]; do
    ddrescue -v /dev/disk4 image.img logfile
    sleep 3

This works as follows:

  • ddrescue is started
  • if it stops running, the shell waits for 3 seconds then it starts it again
  • ddrescue is able to continue because you are making good use of its logging capabilities

After a number of attempts (I think the default is 3 but I may be wrong), ddrescue will mark sectors as definitely bad and it will go on reading other parts of the drive. After some hours you will see that ddrescue will be done and you can kill the loop with Ctrl+C.


From GNU ddrescue Manual:

Example 6: While rescuing a partition in /dev/sda1 to the file hdimage, /dev/sda1 disappears from /dev.

ddrescue -f -n /dev/sda1 hdimage mapfile     <-- /dev/sda1 fails here
  (restart /dev/sda or reboot computer and then repeat the above
   command as many times as needed until it succeeds)
ddrescue -d -f -r3 /dev/sda1 hdimage mapfile

Andrea Lazzarotto's answer covers the "repeat the above command" part. There is an additional step in the example that uses -d switch. The manual explains it a little:


Use direct disc access to read from infile, bypassing the kernel cache. (Opens the file with the O_DIRECT flag). Sector size must be correctly set for this to work. Not all systems support this.

It is advised to further read the proper section of the manual. From therein:

Try the --idirect option first. If direct disc access is not available in your system, try raw devices. Read your system documentation to find how to bind a raw device to a regular block device. Some OSs provide raw access through especial device names, like /dev/rdisk.

MacOS does provide /dev/rdisk names. In your question however you use rdisk with dd but disk with ddrescue, so it seems to me you may still benefit from the additional step.

Linux users will find raw command useful. They should refer to man raw and to Example 2: using a raw device in the already mentioned section of the GNU ddrescue Manual.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.