GNU ddrescue is a data recovery tool. It copies data from one file or block device (hard disc, cdrom, etc) to another, trying to rescue the good parts first in case of read errors. You can use ddrescue to recover data from a damaged drive volume or from CDs, DVDs or other media.
If you have multiple, identical copies, you can combine partial recoveries to hopefully make one completely recovered image. See the ddrescue documentation for full usage notes as this app can do so much more, but for this example we are going to attempt recovery from two identical DVDs, both of which are damaged. The hope is that between the them a single, whole image can be reconstructed.
ddrescue for OSX is easiest to install via MacPorts, which requires Xcode and the Xcode command line tools. See the MacPorts install page. After you have MacPorts installed, you can install ddrescue form the command line:
sudo port install ddrescue
This installs ddrescue at: /opt/local/bin/ddrescue , and should be in your search path.
Determining the device path of the volume to recover
Since ddrescue operates at the command line, you have to provide the path to the device which you are attempting to recover. Insert one of the DVDs, wait for it to mount or otherwise become available, then:
provides a list of volumes and their paths similar to this:
Hungry-Calliope-2:~ cgray$ diskutil list
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *500.1 GB disk0
1: EFI EFI 209.7 MB disk0s1
2: Apple_HFS Macintosh HD 499.2 GB disk0s2
3: Apple_Boot Recovery HD 650.0 MB disk0s3
#: TYPE NAME SIZE IDENTIFIER
0: MY_DVD1 *4.5 GB disk6
so in this example the device path is: /dev/disk6
Create a working directory
Create a directory somewhere where you have plenty of disk space. This is where you will save the partially recovered images and log files. ddrescue log files contain information about which parts of the disc were read un/successfully, so you can interrupt the recovery process and continue where you left off trying to scrape off every bit of readable data.
Recover from the first disc
In Terminal, cd to the local working directory. This sets the path for ddrescue to that directory.
ddrescue -v -n -b2048 /dev/disk6 image1.dmg logfile1
- -v : verbose mode
- -n : disable the scrape mode, which takes a very long time to perform
- -b : sets the sector size
- 512 for hard discs and 3.5" floppies,
- 1024 for 5.25" floppies
- 2048 for cdroms, DVS
- (Defaults to 512)
- /dev/disk6 : the device path
- image1.dmg : the disk image file where recovered data will go
- logfile1: the log file for this copy of the DVD
The recovery process can take a very long time.
If you get an error "ddrescue: Can't open input file: Resource busy", unmount the DVD (not eject):
diskutil unmount /dev/disk6
Recover from the second disc
Mostly a repeat of what we have already done. Eject the first disc and set it aside (be sure to label it!).
diskutil eject /dev/disk6
If you are having trouble ejecting with error "device is busy", you might have to quit Terminal and re-launch to get it to eject.
Insert the second disc. Check that the device path remains the same, unmount the volume if it mounted, and increment the disk image name and the logfile name as in the command below:
ddrescue -v -n -b2048 /dev/disk6 image2.dmg logfile2
Merge the partial recovered images
We now have two disk images and two log files, and both had errors during recovery. Now let's merge the partial recovered images into a single (and hopefully complete) image:
ddrescue -m logfile1 image1.dmg image_combined.dmg logfile
ddrescue -m logfile2 image2.dmg image_combined.dmg logfile
If the if errsize is zero, combined.dmg now contains a complete image of the DVD and you can write it to a blank DVD.
How can I see the number of errors on any recovered disc image?
ddrescuelog --show-status logfile
which will show you something like this:
Hungry-Calliope-2:2 cgray$ ddrescuelog --show-status logfile
current pos: 3871 MB, current status: finished
logfile extent: 4521 MB, in 27 area(s)
rescued: 4520 MB, in 14 area(s) ( 99.98%)
non-tried: 851968 B, in 13 area(s) ( 0.01%)
errsize: 0 B, errors: 0 ( 0%)
non-trimmed: 0 B, in 0 area(s) ( 0%)
non-scraped: 0 B, in 0 area(s) ( 0%)
bad-sector: 0 B, in 0 area(s) ( 0%)
You can see all was recovered except for about 832K. So my work is not yet done...
What can I do if there are still errors?
Repeat the recovery steps above but omit the -n flag. This enables the scrape mode, which takes a lot of time but may be able to eventually recover more of the missing bits. You don't have to start over with the merge, just merge to the combined image again with whichever recovery image has eventual success.
Perhaps there is a 3rd copy of the disc you can try to recover from...
Also, review the ddrescue documentation. ddrescue is very powerful and you can perform advanced surgery on the volume, such as filling bad blocks with data you specify, which depending on where they occur and the data types in question may allow proper usage anyway.