This manual is for GNU ddrescue (version 1.28, 22 January 2024).
Copyright © 2004-2024 Antonio Diaz Diaz.
This manual is free documentation: you have unlimited permission to copy, distribute, and modify it.
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.
The basic operation of ddrescue is fully automatic. That is, you don't have to wait for an error, stop the program, restart it from a new position, etc.
If you use the mapfile feature of ddrescue, the data are rescued very efficiently, (only the blocks needed are read). Also you may interrupt the rescue at any time and resume it later at the same point. The mapfile is an essential part of ddrescue's effectiveness. Use it unless you know what you are doing.
Ddrescue does not write zeros to the output when it finds bad sectors in the input, and does not truncate the output file if not asked to. So, every time you run it on the same output file, it tries to fill in the gaps without wiping out the data already rescued.
Automatic merging of backups: If you have two or more damaged copies of a file, cdrom, etc, and run ddrescue on all of them, one at a time, with the same output file, you will probably obtain a complete and error-free file. This is so because the probability of having the same area damaged in all copies is low (if the errors are randomly located). Using the mapfile, only the blocks needed are read from the second and successive copies.
Ddrescue recommends lzip for compression of backups because the lzip format is designed for long-term archiving and provides data recovery capabilities which nicely complement those of ddrescue. (Ddrescue fills unreadable sectors with data from other copies, while lziprecover corrects corrupt sectors with data from other copies). If the cause of file corruption is a damaged medium, the combination ddrescue + lziprecover is the best option for recovering data from multiple damaged copies. See lziprecover-example.
Because ddrescue needs to read and write at random places, it only works on seekable (random access) input and output files. Therefore, the only way of creating a compressed image with ddrescue is to create a normal (uncompressed) image first, and then compress that image.
If your system supports it, ddrescue can use direct disc access to read the input file, bypassing the kernel cache.
One of the strengths of ddrescue is that it is interface-agnostic, and so can be used for any kind of device supported by your kernel (ATA, SATA, SCSI, old MFM drives, floppy discs, or even flash media cards like SD).
Ddrescue also features a 'fill mode' able to selectively overwrite parts of the output file, which has a number of interesting uses like wiping data, marking bad areas, or even, in some cases, "repair" damaged sectors.
Ddrescue never tries to read any data outside the rescue domain except when unaligned direct disc access is requested (see Direct disc access). If it does, please, report it as a bug.
The data shown by ddrescue (amount of data rescued, number of bad areas,
etc) may vary or even become zero if you limit the rescue domain. Don't
worry, they have not disappeared; they are simply out of the rescue domain
specified.
Ddrescue is like any other power tool. You need to understand what it does, and you need to understand some things about the machines it does those things to, in order to use it safely.
Never try to rescue a r/w mounted partition. The resulting copy may be useless. It is best that the device or partition to be rescued is not mounted at all, not even read-only.
Never try to repair a file system on a drive with I/O errors; you will probably lose even more data.
If you use a device or a partition as destination, any data stored there will be overwritten.
Some systems may change device names on reboot (for example, udev enabled systems). If you reboot such a system, pass the option --ask to ddrescue and check that the device names match the model and serial number of the input and output devices before allowing ddrescue to proceed. You may also check the devices with commands like 'hdparm -I /dev/sda' or 'smartctl -i /dev/sda'.
If you interrupt the rescue and then reboot, any partially copied partitions should be hidden before allowing them to be touched by any operating system that tries to mount and "fix" the partitions it sees.
When using a (graphical) frontend, be careful to not insert or remove any devices to avoid changes in the mapping of devices to device names between the moment the devices are selected in the frontend and the call to ddrescue. Be careful even if the frontend passes --ask to ddrescue, because outfile may be changed between user confirmation and actual opening.
GNU ddrescue is not a derivative of dd, nor is related to dd in any way except in that both can be used for copying data from one device to another. The key difference is that ddrescue uses a sophisticated algorithm to copy data from failing drives causing them as little additional damage as possible.
Versions of ddrescue prior to 1.19 used a divide-and-conquer strategy to rescue the difficult parts of the drive. But that caused a lot of head movement, which is bad for the drive. Therefore, newer versions try to minimize head movement to minimize drive damage.
Ddrescue manages efficiently the status of the rescue in progress and tries to rescue the good parts first, scheduling reads inside bad (or slow) areas for later. This maximizes the amount of data that can be finally recovered from a failing drive.
The standard dd utility can be used to save data from a failing drive, but it reads the data sequentially, which may wear out the drive without rescuing anything if the errors are at the beginning of the drive.
Other programs read the data sequentially but switch to small size reads when they find errors. This is a bad idea because it means spending more time at error areas, damaging the surface, the heads, and the drive mechanics, instead of getting out of them as fast as possible. This behavior reduces the chances of rescuing the remaining good data.
The algorithm of ddrescue is divided in four phases: copying, trimming, scraping, and retrying. Each phase is described below. Disc sectors are marked successively as non-tried, non-trimmed, non-scraped, and bad-sector until they are successfully read and marked as finished. The user may interrupt the process at any point, but a bad drive can block ddrescue for a long time until the kernel gives up.
The amount of work remaining for a given phase can be calculated by comparing the current size of the corresponding areas with their size at the end of the previous pass. Namely the size of non-tried while copying, the size of non-trimmed while trimming, the size of non-scraped while scraping, and the size of bad-sector while retrying. See Output.
The steps of the algorithm are:
1) Optionally read a mapfile describing the status of a multi-part or previously interrupted rescue. If no mapfile is specified, or is empty, or does not exist, mark all the rescue domain as non-tried.
2) (First phase; Copying) Copying is done in up to five passes. The first pass reads the non-tried parts of the input file, marking the failed blocks as non-trimmed and skipping beyond them. The second pass runs in the opposite direction as the first pass and delimits the blocks skipped by the first pass. The first two passes also skip beyond slow areas. The areas skipped are tried later in one or three additional passes (before trimming). The copying direction is reversed after each pass until all the rescue domain is tried.
The third and fourth passes read the blocks skipped due to slow areas (if any) by the first two passes, in the same direction that each block was skipped. For each block, passes 2 to 4 skip the rest of the block after finding the first error in the block. The last pass is a sweeping pass, with skipping disabled. The purpose of the multiple passes is to delimit large bad areas fast, recover the most promising areas first, keep the mapfile small, and produce good starting points for trimming.
Only non-tried areas are read in large blocks. Trimming, scraping, and retrying are done sector by sector. Each sector is tried at most two times: the first in the copying phase as part of a large block read, the second in one of the phases below as a single sector read.
3) (Second phase; Trimming) Trimming retries sector by sector the edges of the large block reads failed during the copying phase. Trimming is done in one pass as follows. For each non-trimmed block, read forwards one sector at a time from the leading edge of the block until a bad sector is found. Then read backwards one sector at a time from the trailing edge of the block until a bad sector is found. Then mark the bad sectors found (if any) as bad-sector, and mark the rest of the block as non-scraped without trying to read it. If any edge is already adjacent to a bad sector, it is considered as already trimmed and is not trimmed again.
4) (Third phase; Scraping) Scrape together, sector by sector, the data not recovered by the copying or trimming phases. Scraping is done in one pass. Each non-scraped block is read forwards, one sector at a time. Any bad sectors found are marked as bad-sector.
5) (Fourth phase; Retrying) Optionally try to read again the bad sectors until the number of retry passes specified is reached. The direction is reversed after each pass. Every bad sector is tried only once in each pass. Ddrescue can't know if a bad sector is unrecoverable or if it will be eventually read after some retries.
6) Optionally write a mapfile for later use.
When ddrescue finishes the steps above, any areas marked as bad-sector will remain untouched in the output file. If the output file is a regular file created by ddrescue, the areas marked as bad-sector will contain zeros. If it is a device or a previously existing file, the areas marked as bad-sector will still contain the data previously present there.
The mapfile is periodically saved to disc, as well as when ddrescue finishes or is interrupted. A backup copy of the mapfile with the extension '.bak' is also periodically created (if possible). So in case of a crash you can resume the rescue with little recopying. The default interval between saves varies from 30 seconds to 5 minutes depending on mapfile size (larger mapfiles are saved at longer intervals), but may be overriden. See --mapfile-interval.
The same mapfile can be used for multiple commands that copy different areas of the input file, and for multiple recovery attempts over different subsets. See this example:
Rescue the most important part of the disc first.
ddrescue -i0 -s50MiB /dev/sdc hdimage mapfile ddrescue -i0 -s1MiB -d -r3 /dev/sdc hdimage mapfile
Then rescue some key disc areas.
ddrescue -i30GiB -s10GiB /dev/sdc hdimage mapfile ddrescue -i230GiB -s5GiB /dev/sdc hdimage mapfile
Now rescue the rest (does not recopy what is already done).
ddrescue /dev/sdc hdimage mapfile ddrescue -d -r3 /dev/sdc hdimage mapfile
The output of ddrescue looks like this:
GNU ddrescue 1.28 Press Ctrl-C to interrupt Initial status (read from mapfile) rescued: 1665 MB, tried: 0 B, bad-sector: 0 B, bad areas: 0 Current status ipos: 2874 MB, non-trimmed: 0 B, current rate: 21479 kB/s opos: 2874 MB, non-scraped: 0 B, average rate: 21023 kB/s non-tried: 13603 MB, bad-sector: 0 B, error rate: 0 B/s rescued: 2401 MB, bad areas: 0, run time: 35s pct rescued: 15.00%, read errors: 0, remaining time: 10m slow reads: 5, time since last successful read: 0s Copying non-tried blocks... Pass 1 (forwards)
Ddrescue scrolls forward after each pass. This keeps on the screen the final status of the previous pass, making it easier to estimate the amount of work done by the current pass.
The meaning of each field is as follows:
ipos
opos
non-tried
rescued
pct rescued
slow reads
tried
non-trimmed
non-scraped
bad-sector
bad areas
read errors
current rate
average rate
error rate
run time
remaining time
time since last successful read
The format for running ddrescue is:
ddrescue [options] infile outfile [mapfile]
infile and outfile may be files, devices, or partitions. mapfile is a regular file and must be placed in an existing directory. If mapfile does not exist, ddrescue creates it. Be careful to not specify by mistake an old mapfile from an unrelated rescue.
Ddrescue tries to create a backup copy of the mapfile, with the name mapfile.bak, every time it is going to overwrite a fsynced mapfile. See --mapfile-interval.
Always use a mapfile unless you know you won't need it. Without a mapfile, ddrescue can't resume a rescue, only reinitiate it.
ddrescue supports the following options:
-h
--help
-V
--version
-a
bytes--min-read-rate=
bytesIf bytes is 0 (auto), the minimum read rate is recalculated every
second as (average_rate / 10).
-A
--try-again
-b
bytes--sector-size=
bytesIn rescue mode, any non-finished subsector that is found during the initial
read of the mapfile is joined to its corresponding sector (if it is also not
finished), marking the whole sector with the less processed state, so as to
make sure that sub-sector data is not discarded from a successful read
during the rescue. (A subsector is a block smaller than sector size).
Subsector joining is performed in all the mapfile, not only in the rescue
domain.
-B
--binary-prefixes
-c
sectors--cluster-size=
sectors-C
--complete-only
-d
--idirect
If your system does not support direct disc access, ddrescue warns you. If
the sector size is not correctly set, an unaligned read error may happen, in
which case ddrescue exits with error status 1.
-D
--odirect
If your system does not support direct disc access, ddrescue warns you. If the sector size is not correctly set, a write error is reported and no data is rescued. Some OSs have a bug that prevents them from detecting write errors properly (or at all) on some devices if direct disc access is not used for outfile.
-e [+]
n--max-bad-areas=[+]
n-E
bytes--max-error-rate=
bytes-f
--force
-F
types--fill-mode=
types-G
--generate-mode
-H
file--test-mode=
file-i
bytes--input-position=
bytes-I
--check-input-size
-J
--check-on-error
This option performs one extra read after each error, wearing the drive
faster. Use it only on drives that stop responding or return garbage data
after finding errors. You may need to power cycle the drive before
restarting ddrescue.
-K [
initial][,
max]
--skip-size=[
initial][,
max]
If ddrescue is having difficulties skipping away from a large area with scattered errors, or if the device has large bad areas at regular intervals, you may increase the initial skip size with this option. Inversely, if ddrescue is skipping too much, leaving large non-tried areas behind each error (which will be read later in the usually slower backwards direction), you may reduce the maximum skip size, or disable skipping.
--skip-size is independent from --cluster-size. The size
to skip is calculated from the end of the block that just failed.
-L
--loose-domain
-m
file--domain-mapfile=
file-M
--retrim
-n
--no-scrape
-N
--no-trim
-o
bytes--output-position=
bytes-O
--reopen-on-error
-p
--preallocate
-P[
lines]
--data-preview[=
lines]
-q
--quiet
-r
n--retry-passes=
nA command like 'ddrescue -f -r-1 /dev/sdcard /dev/null mapfile' can
be used to read repeatedly until the device controller succeeds and remaps
the bad sectors internally.
-R
--reverse
-s
bytes--size=
bytesddrescue -i 100 -s 200 infile outfile mapfile
-S
--sparse
-t
--truncate
-T
interval--timeout=
interval-u
--unidirectional
-v
--verbose
-w
--ignore-write-errors
Note that in rescue mode a write error is fatal, which means that the rescue
needs to be repeated or else outfile needs to be copied to a third
drive using mapfile as domain (see --domain-mapfile).
-W
--compare-before-write
-x
bytes--extend-outfile=
bytes-X
n--max-read-errors=
n--max-read-errors=0 is also similar but different to
--max-bad-areas=+0, which exits when a new bad area is found. If
the read errors are adjacent to existing bad areas, no new bad areas are
produced (just enlarged), and --max-bad-areas=+0 does not make
ddrescue to exit.
-y
--synchronous
-Z
bytes--max-read-rate=
bytes--ask
If they can be obtained, ddrescue shows the model and serial number of the
input and output devices. Ddrescue also shows the size in bytes of the
corresponding file or device if it exists. The format used is
[model::serial_number] (size)
--command-mode
--cpass=
rangeExamples of range | Passes run
|
1 | 1
|
1,2,3 | 1, 2, 3
|
2-4 | 2, 3, 4
|
1,3-5 | 1, 3, 4, 5
|
1-3,5 | 1, 2, 3, 5
|
--delay-slow=
interval--log-events=
file--log-rates=
file--log-reads=
file--mapfile-interval=[
save_interval][,
sync_interval]
In practice, fsyncs are a subset of saves. I.e., some of the times when the
mapfile is saved, it is also fsync'ed. Therefore,
--mapfile-interval=30,45 is really --mapfile-interval=30,60.
The time needed to write the mapfile is excluded from the mapfile save
and sync intervals. (Some mapfiles may take several seconds to write).
--max-slow-reads=
n--pause-on-error=
interval--pause-on-pass=
interval--reset-slow
--same-file
Numbers given as arguments to options (positions, sizes, rates, etc) may be expressed as decimal, hexadecimal, or octal values (using the same syntax as integer constants in C++), and may be followed by a multiplier and an optional 'B' for "byte". The 's' multiplier may be appended to any of the other multipliers. For example, 'ks' means kilosectors (1000 * sector_size), and 'Kis' means kibisectors (1024 * sector_size).
Table of SI and binary prefixes (unit multipliers):
Prefix | Value | | | Prefix | Value
|
s | sectors | | |
| |
k | kilobyte (10^3 = 1000) | | | Ki | kibibyte (2^10 = 1024)
|
M | megabyte (10^6) | | | Mi | mebibyte (2^20)
|
G | gigabyte (10^9) | | | Gi | gibibyte (2^30)
|
T | terabyte (10^12) | | | Ti | tebibyte (2^40)
|
P | petabyte (10^15) | | | Pi | pebibyte (2^50)
|
E | exabyte (10^18) | | | Ei | exbibyte (2^60)
|
Z | zettabyte (10^21) | | | Zi | zebibyte (2^70)
|
Y | yottabyte (10^24) | | | Yi | yobibyte (2^80)
|
R | ronnabyte (10^27) | | | Ri | robibyte (2^90)
|
Q | quettabyte (10^30) | | | Qi | quebibyte (2^100)
|
Exit status: 0 for a normal exit, 1 for environmental problems (file not found, invalid command-line options, I/O errors, etc), 2 to indicate a corrupt or invalid input file, 3 for an internal consistency error (e.g., bug) which caused ddrescue to panic.
If ddrescue is interrupted by a signal, it updates mapfile and then terminates by raising the signal received.
NOTE: In versions of ddrescue prior to 1.20 the mapfile was called 'logfile'. The format is the same; only the name has changed.
The mapfile is a text file easy to read and edit. It is formed by three parts, the heading comments, the status line, and the list of data blocks. The character '#' at begin of line or after whitespace starts a comment that extends to the end of the line.
The heading comments contain the version of ddrescue or ddrescuelog that created the mapfile, the command line used, and the time when the program started. If the mapfile was created by ddrescue it also contains the current time when the mapfile was saved and a copy of the status message from the screen describing the operation being performed (copying, trimming, finished, etc). They are intended as information for the user.
The first non-comment line is the status line. It contains a non-negative integer, a status character, and a positive decimal integer. The first integer is the position being tried in the input file. (The beginning of the block being tried in a forward pass or the end of the block in a backward pass). The status character is one of these:
Character | Meaning
|
'?' | copying non-tried blocks
|
'*' | trimming non-trimmed blocks
|
'/' | scraping non-scraped blocks
|
'-' | retrying bad sectors
|
'F' | filling the blocks specified
|
'G' | generating approximate mapfile
|
'+' | finished
|
Finally, the last integer is the number of the current pass in the current phase. The status line allows ddrescue to resume the copying phase instead of restarting it from pass 1. It also allows the retrying phase to resume in the same direction it was interrupted.
The blocks in the list of data blocks must be contiguous and non-overlapping.
Every line in the list of data blocks describes a block of data. It contains 2 non-negative integers and a status character. The first integer is the starting position of the block in the input file, the second integer is the size (in bytes) of the block. The status character is one of these:
Character | Meaning
|
'?' | non-tried block
|
'*' | failed block non-trimmed
|
'/' | failed block non-scraped
|
'-' | failed block bad-sector(s)
|
'+' | finished block
|
And here is an example mapfile:
# Mapfile. Created by GNU ddrescue version 1.28 # Command line: ddrescue -d -c18 /dev/fd0 fdimage mapfile # Start time: 2015-07-21 09:37:44 # Current time: 2015-07-21 09:38:19 # Copying non-tried blocks... Pass 1 (forwards) # current_pos current_status current_pass 0x00120000 ? 1 # pos size status 0x00000000 0x00117000 + 0x00117000 0x00000200 - 0x00117200 0x00001000 / 0x00118200 0x00007E00 * 0x00120000 0x00048000 ?
If you edit the file, you may use decimal, hexadecimal, or octal values, using the same syntax as integer constants in C++, except for current_pass, which must be a decimal integer.
The mapfile is an essential part of ddrescue's effectiveness. Without a mapfile, ddrescue can't resume a rescue, only reinitiate it. Given that a difficult rescue may take days to complete, it would be a serious drawback if the mapfile were lost because of a solvable problem like a lack of space on the device the mapfile is written to.
In case of trouble writing the mapfile, ddrescue prints a message like this:
Error writing mapfile 'mapfile': No space left on device Fix the problem and press ENTER to retry, or E+ENTER for an emergency save and exit, or Q+ENTER to abort.
You may try to fix the problem, for example deleting some files to make room for the mapfile, and press <Return> to retry.
If the problem can't be fixed, you may press <e> followed by <Return> to try an emergency save and exit. Ddrescue tries to write the mapfile to the file ddrescue.map in the current directory or, if this fails, to $HOME/ddrescue.map. If the mapfile is written successfully, ddrescue exits with status 1. Else it prints the above message again.
Or you may press <q> followed by <Return> to quit and exit with status 1. In this case the content of the mapfile is lost.
Ddrescue may be better than dd for copying recordable CD-ROMs because the two lead out sectors at the end of some of them may cause a read error that prevents the whole last record from being copied by dd, potentially losing data. Also dd may create an image larger than the original if the 'sync' conversion and a block size larger than the sector size are specified.
In the special case of reading CD-ROMs (but not DVDs), the specialized tool dvdisaster may be a better option than ddrescue for recovering data because dvdisaster can read and analyze raw CD sectors, which ddrescue can't.
Recordable CD and DVD media keep their data only for a finite time (typically for some years). After that time, data loss develops slowly with read errors growing from the outer region towards the inside. It is a good idea to make two (or more) copies of every important CD-ROM/DVD you burn so that you can later recover them with ddrescue.
If you have only one copy of a CD-ROM or DVD that fails when being copied, and if you have access to multiple optical media drives, you have a better chance of recovering the bad sectors since one drive may fail to read a particular sector, but another drive might be able to squeeze the data out of it, depending on the laser frequency and the sensitivity of the laser-sensor that reads the reflected laser light.
Example 1: Rescue a CD-ROM in /dev/cdrom.
ddrescue -n -b2048 /dev/cdrom cdimage mapfile ddrescue -d -r1 -b2048 /dev/cdrom cdimage mapfile (if bad-sector size is zero, cdimage now contains a complete image of the CD-ROM and you can write it to a blank CD-ROM)
Example 2: Rescue a CD-ROM in /dev/cdrom from two copies.
ddrescue -n -b2048 /dev/cdrom cdimage mapfile ddrescue -d -b2048 /dev/cdrom cdimage mapfile (insert second copy in the CD drive) ddrescue -d -r1 -b2048 /dev/cdrom cdimage mapfile (if bad-sector size is zero, cdimage now contains a complete image of the CD-ROM and you can write it to a blank CD-ROM)
Example 3: Rescue a CD-ROM in /dev/cdrom using two CD drives from two different computers, writing the image into an USB drive mounted on /mnt/mem.
ddrescue -n -b2048 /dev/cdrom /mnt/mem/cdimage /mnt/mem/mapfile ddrescue -d -r1 -b2048 /dev/cdrom /mnt/mem/cdimage /mnt/mem/mapfile (umount the USB drive and move both USB drive and CD-ROM to second computer) ddrescue -d -r1 -b2048 /dev/cdrom /mnt/mem/cdimage /mnt/mem/mapfile (if bad-sector size is zero, /mnt/mem/cdimage now contains a complete image of the CD-ROM and you can write it to a blank CD-ROM)
Example 4: Merge the partially recovered images of 3 identical DVDs using their mapfiles as domain mapfiles.
ddrescue -m mapfile1 dvdimage1 dvdimage mapfile ddrescue -m mapfile2 dvdimage2 dvdimage mapfile ddrescue -m mapfile3 dvdimage3 dvdimage mapfile (if bad-sector size is zero, dvdimage now contains a complete image of the DVD and you can write it to a blank DVD)
Example 5: Rescue a lzip compressed backup from two copies on CD-ROM with error-checked merging of copies. See the lziprecover manual for details about lziprecover.
ddrescue -d -r1 -b2048 /dev/cdrom cdimage1 mapfile1 mount -t iso9660 -o loop,ro cdimage1 /mnt/cdimage cp /mnt/cdimage/backup.tar.lz rescued1.tar.lz umount /mnt/cdimage (insert second copy in the CD drive) ddrescue -d -r1 -b2048 /dev/cdrom cdimage2 mapfile2 mount -t iso9660 -o loop,ro cdimage2 /mnt/cdimage cp /mnt/cdimage/backup.tar.lz rescued2.tar.lz umount /mnt/cdimage lziprecover -m -v -o backup.tar.lz rescued1.tar.lz rescued2.tar.lz Input files merged successfully. lziprecover -tv backup.tar.lz backup.tar.lz: ok
This tutorial is for those already able to use the dd command. If you don't know what dd is, better search the net for some introductory material about dd and GNU ddrescue first.
A failing drive tends to develop more and more errors as time passes. Because of this, you should rescue the data from a drive as soon as you notice the first error. Be diligent because every time a physically damaged drive powers up and is able to output some data, it may be the very last time that it ever will.
You should make a copy of the failing drive with ddrescue, and then try to repair the copy. If your data are really important, use the first copy as a master for a second copy, and try to repair the second copy. If something goes wrong, you have the master intact to try again.
If you are trying to rescue a whole partition, first repair the copy with e2fsck or some other tool appropriate for the type of partition you are trying to rescue, then mount the repaired copy somewhere and try to recover the files in it.
If the drive is so damaged that the file system in the rescued partition can't be repaired or mounted, you will have to browse the rescued data with an hex editor and extract the desired parts by hand, or use a file recovery tool like photorec.
If the partition table is damaged, you may try to rescue the whole disc, then try to repair the partition table and the partitions on the copy.
If the damaged drive is not listed in /dev, then you cannot rescue it. At least not with ddrescue.
See Optical media, for rescue examples of CD-ROMs and DVDs.
Example 1: Fully automatic rescue of a whole disc with two ext2 partitions in /dev/sda to /dev/sdb.
ddrescue -f -r3 /dev/sda /dev/sdb mapfile fdisk /dev/sdb e2fsck -v -f /dev/sdb1 e2fsck -v -f /dev/sdb2
Example 2: Rescue an ext2 partition in /dev/sda2 to /dev/sdb2.
ddrescue -f -n /dev/sda2 /dev/sdb2 mapfile ddrescue -d -f -r3 /dev/sda2 /dev/sdb2 mapfile e2fsck -v -f /dev/sdb2 mount -t ext2 -o ro /dev/sdb2 /mnt (read rescued files from /mnt)
Example 3: While rescuing the whole drive /dev/sda to /dev/sdb, /dev/sda freezes up at position 12345678.
ddrescue -f /dev/sda /dev/sdb mapfile # /dev/sda freezes here (restart /dev/sda or reboot computer) (restart copy at a safe distance from the troubled sector) ddrescue -f -i 12350000 /dev/sda /dev/sdb mapfile (then copy backwards down to the troubled sector) ddrescue -f -R /dev/sda /dev/sdb mapfile
Example 4: While rescuing the whole drive /dev/sda to /dev/sdb, /dev/sdb fails and you have to rescue the data to a third drive, /dev/sdc.
ddrescue -f -n /dev/sda /dev/sdb mapfile1 # /dev/sdb fails here ddrescue -f -m mapfile1 /dev/sdb /dev/sdc mapfile2 ddrescue -f -n /dev/sda /dev/sdc mapfile2 ddrescue -d -f -r3 /dev/sda /dev/sdc mapfile2
Example 5: While rescuing a partition in /dev/sda1 to the file hdimage, /dev/sda1 stops responding and begins returning read errors, causing ddrescue to mark the rest of the partition as non-scraped.
ddrescue -n /dev/sda1 hdimage mapfile # /dev/sda1 fails here (restart /dev/sda or reboot computer) ddrescue -n -A -i<pos> -O /dev/sda1 hdimage mapfile (if /dev/sda1 fails again, restart /dev/sda or reboot computer and then repeat the above command as many times as needed until it succeeds. <pos> is the position where the drive stopped responding) ddrescue -d -r3 /dev/sda1 hdimage mapfile
Example 6: While rescuing a partition in /dev/sda1 to the file hdimage, sda1 disappears from /dev.
ddrescue -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 -r3 /dev/sda1 hdimage mapfile
Example 7: While rescuing a partition in /dev/sda1 to the file hdimage, the partition table of /dev/sda becomes unreadable and the OS no longer shows sda1 in /dev. The solution is to shift the mapfile and read the rest of the partition sda1 from /dev/sda.
ddrescue /dev/sda1 hdimage mapfile # partition table fails here ddrescuelog --shift -o<offset> mapfile > shifted_mapfile ddrescue -i<offset> -o0 -s<size> /dev/sda hdimage shifted_mapfile
Example 8: After rescuing a partition in /dev/sda1 to the file hdimage, expand hdimage to copy the whole drive in /dev/sda without recopying the already copied partition /dev/sda1. The solution is to shift the mapfile, move the data of sda1 to its final position in hdimage, and then read the rest of the data from /dev/sda.
ddrescue /dev/sda1 hdimage mapfile # rescue partition ddrescuelog --shift -o<offset> mapfile > shifted_mapfile ddrescue --same-file -o<offset> -s<size> --reverse hdimage hdimage ddrescue /dev/sda hdimage shifted_mapfile # rescue rest of drive
If you notice that the positions and sizes in mapfile are always multiples of the sector size, maybe your kernel is caching the disc accesses and grouping them. In this case you may want to use direct disc access for infile, or read from a raw device, to bypass the kernel cache and rescue more of your data.
NOTE! Sector size must be correctly set with the option --sector-size for direct disc access to work.
NOTE: Direct disc access can copy arbitrary domains by reading whole sectors and then writing only the requested part. This is the only case where ddrescue tries to read data outside the rescue domain.
Try the option --idirect 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.
Ddrescue aligns its I/O buffer to the sector size so that it can be used for direct disc access or to read from raw devices. For efficiency reasons, also aligns it to the memory page size if page size is a multiple of sector size. On some systems, ddrescue can't determine the size of a raw device, so an explicit --size or --complete-only option may be needed.
Using direct disc access, or reading from a raw device, may be slower or faster than normal cached reading depending on your OS and hardware. In case it is slower you may want to make a first pass using normal cached reads and use direct disc access, or a raw device, only to recover the good sectors inside the failed blocks.
Example 1: using direct disc access.
ddrescue -f -n /dev/sdb1 /dev/sdc1 mapfile ddrescue -d -f -r3 /dev/sdb1 /dev/sdc1 mapfile e2fsck -v -f /dev/sdc1 mount -t ext2 -o ro /dev/sdc1 /mnt
Example 2: using a raw device.
raw /dev/raw/raw1 /dev/sdb1 ddrescue -f -n /dev/sdb1 /dev/sdc1 mapfile ddrescue -C -f -r3 /dev/raw/raw1 /dev/sdc1 mapfile raw /dev/raw/raw1 0 0 e2fsck -v -f /dev/sdc1 mount -t ext2 -o ro /dev/sdc1 /mnt
The command mode of ddrescue implements a scripting interface similar to the one of ed. In this mode commands are read from the standard input and executed to copy parts of the input file to the output file, retrieve information from the mapfile, or write the mapfile to disc. Ddrescue's responses are written to standard output. "done\n" for a successfully executed command, "error\n" for a failed command (for example because of wrong arguments), and "error: error message\n" for serious or fatal errors like write errors.
If end-of-file is detected on standard input, ddrescue discards any partial command being read and executes the 'f' (finish) command.
All ddrescue commands are single characters, though some require additonal parameters separated by spaces. Only one command is allowed per line. Ddrescue recognizes the following commands:
c
pos sizef
q
s
pos sizeu
When ddrescue is invoked with the option --fill-mode it operates in "fill mode", which is different from the default "rescue mode". That is, in "fill mode" ddrescue does not rescue anything. It only fills with data read from infile the blocks of outfile whose status character from mapfile coincides with one of the type characters specified in the argument to --fill-mode.
If the argument to --fill-mode contains an 'l', ddrescue writes location data (position, sector number, and status) into each sector filled. With bad sectors filled in this way, it should be possible to retry the recovery of important files, as the location of the error is known by looking into the unfinished copy of the file.
In fill mode infile does not need to be seekable and it may be of any size. If it is too small, the data is duplicated as many times as necessary to fill the input buffer. If it is too big, only the data needed to fill the input buffer is read. Then the same data is written to every cluster or sector to be filled.
Note that in fill mode infile is always read from position 0. If you specify a --input-position, it refers to the original infile from which mapfile was built, and is only used to calculate the offset between input and output positions.
Note also that when filling the infile of the original rescue run you should not set --output-position, whereas when filling the outfile of the original rescue run you should keep the original offset between --input-position and --output-position.
The option --fill-mode implies --complete-only.
In fill mode mapfile is updated to allow resumability when interrupted or in case of a crash, but as nothing is being rescued mapfile is not destroyed. The status line is the only part of mapfile that is modified.
The fill mode has a number of uses. See the following examples:
Example 1: Mark parts of the rescued copy to allow finding them when examined in an hex editor. For example, the following command line fills all blocks marked as '-' (bad-sector) with copies of the string 'BAD-SECTOR ':
ddrescue --fill-mode=- <(printf "BAD-SECTOR ") outfile mapfile
And the following command line fills all the non-finished areas in the destination file with copies of the string 'NON-RESCUED-SECTOR ':
ddrescue --fill-mode='?*/-' <(printf "NON-RESCUED-SECTOR ") outfile mapfile
Example 2: Wipe only the good sectors, leaving the bad sectors alone. This way, the drive will still test bad (i.e., with unreadable sectors). This is the fastest way of wiping a failing drive, and is especially useful when sending the drive back to the manufacturer for warranty replacement.
ddrescue --fill-mode=+ --force /dev/zero bad_drive mapfile
Example 3: Force the drive to remap the bad sectors, making it usable again. If the drive has only a few bad sectors, and they are not caused by drive age, you can probably just rewrite those sectors, and the drive will reallocate them automatically to new "spare" sectors that it keeps for just this purpose. WARNING! This may not work on your drive.
ddrescue --fill-mode=- -f --synchronous /dev/zero bad_drive mapfile
Fill mode can also help you to figure out, independently of the file system used, what files are partially or entirely in the bad areas of the disc. Just follow these steps:
1) Copy the damaged drive with ddrescue until finished. Don't use sparse writes. This yields a mapfile containing only finished ('+') and bad-sector ('-') blocks.
2) Fill the bad-sector blocks of the copied drive or image file with a string not present in any file, for example "DEADBEEF". Use --fill-mode=l- if you want location data.
3) Mount the copied drive (or the image file, via loopback device) read-only.
4) Grep for the fill string in all the files. Those files containing the string reside (at least partially) in damaged disc areas. Note that if all the damaged areas are in unused space, grep will not find the string in any file, which means that no files are damaged.
5) Take note of the location data of any important files that you want to retry.
6) Unmount the copied drive or image file.
7) Retry the sectors belonging to the important files until they are rescued or until it is clear that they can't be rescued.
8) Optionally fill the bad-sector blocks of the copied drive or image file with zeros to restore the disc image.
Example 4: Figure out what files are in the bad areas of the disc.
ddrescue -b2048 /dev/cdrom cdimage mapfile printf "DEADBEEF" > tmpfile ddrescue --fill-mode=l- tmpfile cdimage mapfile rm tmpfile mount -t iso9660 -o loop,ro cdimage /mnt/cdimage find /mnt/cdimage -type f -exec grep -l "DEADBEEF" '{}' ';' (note that my_thesis.txt has a bad sector at pos 0x12345000) umount /mnt/cdimage ddrescue -b2048 -i0x12345000 -s2048 -dr9 /dev/cdrom cdimage mapfile ddrescue --fill-mode=- /dev/zero cdimage mapfile mount -t iso9660 -o loop,ro cdimage /mnt/cdimage cp -a /mnt/cdimage/my_thesis.txt /safe/place/my_thesis.txt
When ddrescue is invoked with the option --generate-mode it operates in "generate mode", which is different from the default "rescue mode". That is, in "generate mode" ddrescue does not rescue anything. It only tries to generate a mapfile for later use.
So you didn't read the manual and started ddrescue without a mapfile. Now, two days later, your computer crashed and you can't know how much data ddrescue managed to save. And even worse, you can't resume the rescue; you have to restart it from the very beginning.
Or maybe you started copying a drive with 'dd conv=noerror,sync' and are now in the same situation described above. In this case, note that you can't use a copy made by dd unless it was invoked with the 'sync' conversion argument.
Don't despair (yet). Ddrescue can in some cases generate an approximate mapfile, from infile and the (partial) copy in outfile, that is almost as good as an exact mapfile. It makes this by simply assuming that sectors containing all zeros were not rescued.
However, if the destination of the copy was a drive or a partition, (or an existing regular file and truncation was not requested), most probably you will need to restart ddrescue from the very beginning. (This time with a mapfile, of course). The reason is that old data may be present in the drive that have not been overwritten yet, and may be thus non-tried but non-zero.
For example, if you first tried one of these commands:
ddrescue infile outfile or dd if=infile of=outfile conv=noerror,sync
then you can generate an approximate mapfile with this command:
ddrescue --generate-mode infile outfile mapfile
Note that you must keep the original offset between --input-position and --output-position of the original rescue run.
Ddrescuelog is a tool that manipulates ddrescue mapfiles, shows mapfile contents, converts mapfiles to/from other formats, compares mapfiles, tests rescue status, and can delete a mapfile if the rescue is done. Ddrescuelog operations can be restricted to one or several parts of the mapfile if the domain setting options are used.
When performing logic operations (AND, OR, XOR) on mapfiles of different extension, only the blocks present in both files are processed. Other blocks are left untouched.
Here are some examples of how to use ddrescuelog, alone or in combination with other tools.
Example 1: Delete the mapfile if the rescue is finished (all data have been recovered without errors left).
ddrescue -f /dev/sda /dev/sdb mapfile ddrescuelog -d mapfile
Example 2: Rescue two ext2 partitions in /dev/sda to /dev/sdb and repair the file systems using badblock lists generated with ddrescuelog. File system block size is 4096.
fdisk /dev/sdb # partition /dev/sdb ddrescue -f /dev/sda1 /dev/sdb1 mapfile1 ddrescue -f /dev/sda2 /dev/sdb2 mapfile2 ddrescuelog -l- -b4096 mapfile1 > badblocks1 ddrescuelog -l- -b4096 mapfile2 > badblocks2 e2fsck -v -f -L badblocks1 /dev/sdb1 e2fsck -v -f -L badblocks2 /dev/sdb2
Example 3: Rescue a whole disc with two ext2 partitions in /dev/sda to /dev/sdb and repair the file systems using badblock lists generated with ddrescuelog. Disc sector size is 512, file system block size is 4096. Arguments to options -i and -s are the starting positions and sizes of the partitions being rescued.
ddrescue -f /dev/sda /dev/sdb mapfile fdisk /dev/sdb # get partition sizes ddrescuelog -l- -b512 -i63s -o0 -s767457s -b4096 mapfile > badblocks1 ddrescuelog -l- -b512 -i767520s -o0 -s96520s -b4096 mapfile > badblocks2 e2fsck -v -f -L badblocks1 /dev/sdb1 e2fsck -v -f -L badblocks2 /dev/sdb2
The format for running ddrescuelog is:
ddrescuelog [options] mapfile
Use a hyphen '-' as mapfile to read the mapfile from standard input (also in the options taking a mapfile argument) or to write the mapfile created by --create-mapfile to standard output.
Ddrescuelog supports the following options:
-h
--help
-V
--version
-a
old_types,
new_types--change-types=
old_types,
new_types-A
--annotate-mapfile
-b
bytes--block-size=
bytes--sector-size=
bytes-B
--binary-prefixes
-c[
type1type2]
--create-mapfile[=
type1type2]
type1 and type2 are block status characters as defined in the
chapter Mapfile structure (see Mapfile structure). type1 sets the
type for blocks included in the list, while type2 sets the type for
the rest of mapfile. If not specified, type1 defaults to
'+' and type2 defaults to '-'.
-C[
type]
--complete-mapfile[=
type]
-d
--delete-if-done
-D
--done-status
-f
--force
-F
name--format=
name-i
bytes--input-position=
bytes-l
types--list-blocks=
typesIf a bitmap --format is specified, write to standard output a bitmap of the endianness chosen, with ones for the sectors specified and zeros for sectors from other block types. The bits set to 1 in the bitmap should be equivalent to the list of blocks.
types contains one or more of the block status characters defined in the chapter Mapfile structure (see Mapfile structure). If the output numbers or bits are being created displaced from their position in the input domain, the offset between -i and -o must be a multiple of the block size. In this case, remember to specify -o because it defaults to the same value given to -i, producing a default offset of 0.
A sector is listed (or set to 1 in bitmap output) if selected, even
partially. (The positions and sizes of the mapfile blocks are not required
to be multiples of the sector size).
-L
--loose-domain
-m
file--domain-mapfile=
file-n
--invert-mapfile
-o
bytes--output-position=
bytes-p
file--compare-mapfile=
file-P
file--compare-as-domain=
file-q
--quiet
-s
bytes--size=
bytes-t
--show-status
-v
--verbose
-x
file--xor-mapfile=
file-y
file--and-mapfile=
file-z
file--or-mapfile=
file--shift
Exit status: 0 for a normal exit, 1 for environmental problems (file not found, invalid command-line options, I/O errors, etc), 2 to indicate a corrupt or invalid input file, 3 for an internal consistency error (e.g., bug) which caused ddrescuelog to panic.
There are probably bugs in ddrescue. There are certainly errors and omissions in this manual. If you report them, they will get fixed. If you don't, no one will ever know about them and they will remain unfixed for all eternity, if not longer.
If you find a bug in GNU ddrescue, please send electronic mail to [email protected]. Include the version number, which you can find by running 'ddrescue --version'.