safecopy

There are some predefined settings:

  • stage1: Preset to rescue most of the data fast, using no retries and avoiding bad areas. Skip 10% of size when bad block found. 1 read attempt.
  • stage2: Preset to rescue more data, using no retries but searching for exact ends of bad areas. Skip 128 blocks when bad block found. 1 read attempt.
  • stage3: Preset to rescue everything that can be rescued using maximum retries, head realignment tricks and low level access. Skip 1 block if bad block found. 4 read attempts.
-f -r -R -Z -L -I -o
stage skip resolution reads move head low level increm. mode bad block out file other
stage1 10% 10% 1 0 2 stage1.badblocks
stage2 128* 1* 1 0 2 stage1.badblocks stage2.badblocks
stage3 1* 1* 4 1 2 stage2.badblocks stage3.badblocks

Every stage preset parameter can be overridden. E.g. for stage 3 is not needed to give additional stress to device with -R 4 and -Z 1, and better is to use:

safecopy --forceopen -L 0 --stage3 -c 151275030 -Z 0 -R 1 /dev/sdb /dev/sdc


Note: -c parameter is used to continue previous safecopy interrupted by CTRL+C.
Note:
With -f parameter other than 1* you can miss good areas in between two bad ones.

stage#.badblocks files

In current working directory, safecopy will create files with badblocks map: stage#.badblocks, which are used in next stages.

Make sure stage#.badblocks files are sorted are unique before moving to next stage. In other case following error will shown:

..................Parse error in badblocks file stage1.badblocks: not sorted correctly!

Aborted because of error!
Recovered bad blocks: 0
Unrecoverable bad blocks (bytes): 60 (18100224)
Blocks (bytes) copied: 151299151 (619721322496) 

Number of lines in each stage#.badblocks file shows how each stage works:

# cat stage1.badblocks | sort | uniq | wc -l
51200
# cat stage2.badblocks | sort | uniq | wc -l
4720
# cat stage3.badblocks | sort | uniq | wc -l
1477

Usage example

Typical usage is:

safecopy --stage1 /dev/source output.img
mv stage1.badblocks stage1.badblocks.bak
cat stage1.badblocks.bak | sort | uniq > stage1.badblocks
 
safecopy --stage2 /dev/source output.img
mv stage2.badblocks stage2.badblocks.bak
cat stage2.badblocks.bak | sort | uniq > stage2.badblocks
 
safecopy --stage3 /dev/source output.img

Output

......................................... [244042830]
......................................... [244084814]
......................................... [244126798]
......................................... [244168782]
.....................  100%
Done!
Recovered bad blocks: 0
Unrecoverable bad blocks (bytes): 2 (209715200)
Blocks (bytes) copied: 244190646 (1000204886016)
# safecopy --forceopen -L 0 --stage2 /dev/sdb /dev/sdc

Low level device calls enabled mode: 0
Forced reopening of source file even if device is temporarily gone.
Reported hw blocksize: 4096
Filesize not reported by stat(), trying seek().
File size: 1000204886016
Blocksize: 4096
Fault skip blocksize: 524288
Resolution: 4096
Min read attempts: 1
Head moves on read error: 0
Incremental mode file: stage1.badblocks
Incremental mode blocksize: 4096
Badblocks output: stage2.badblocks
Starting block: 0
Source: /dev/sdb
Destination: /dev/sdc
Destination filesize not reported by stat(), trying seek().
Current destination size: 1000204886016
[1124830](+4607303680){X<<<<<<<}[1124831](+4096)
.........................[151273551](+615009157120){X [151273679]
<<<<<<<}[151273655](+425984)
.[151273690](+143360){XXXXX<<<<<<<}[151274319](+2576384)
.[151274323](+16384){XXX<<<<<<<}[151274620](+1216512)
.[151274700](+327680){X<<<<<<<}[151274788](+360448)
.[151275798](+20480){XXX<<<<<<<}[151276078](+1146880)
.[151276107](+118784){X<<<<<<<}[151276110](+12288)
.[151276125](+61440){XX<<<<<<<}[151276262](+561152)
.[151276326](+262144){X<<<<<<<}[151276345](+77824)
.[151276347](+8192){X<<<<<<<}[151276412](+266240)
.[151276511](+405504){X<<<<<<<}[151276512](+4096)
..[151278398](+7725056){XXXX<<<<<<<}[151278843](+1822720)
.[151278847](+16384){XX<<<<<<<}[151279033](+761856)
.[151279172](+8192){X<<<<<<<}[151279173](+4096)
.[151279178](+20480){X<<<<<<<}[151279179](+4096)
.[151279274](+389120){X<<<<<<<}[151279287](+53248)
.[151279318](+126976){XX<<<<<<<}[151279501](+749568)
.[151279567](+270336){X<<<<<<<}[151279640](+299008)
.[151279646](+24576){X<<<<<<<}[151279684](+155648)
.[151279685](+4096){XXX<<<<<<<}[151280013](+1343488)
.[151280572](+413696){X<<<<<<<}[151280636](+262144)
.[151280638](+8192){XX<<<<<<<}[151280812](+712704)
..................  100%
Done!
Recovered bad blocks: 0
Unrecoverable bad blocks (bytes): 60 (18206720)
Blocks (bytes) copied: 244190646 (1000204886016)

Continue interrupted copy

......................................... [175312976]
..^C:-) 71%
Aborted by user request!
Recovered bad blocks: 0
Unrecoverable bad blocks (bytes): 2 (209715200)
Blocks (bytes) copied: 175316045 (718094520320)

With -I parameter safecopy works in incremental mode. Position is detemined from dest file size. If dest is a block device parameter -c needs to be used:

safecopy --stage1 -c 175316045 -I my/previous/stage1.badblocks -L 0 --forceopen /dev/sdi /dev/sdd

Working with USB or erroneous drives

To disable SATA low level operations:

safecopy --forceopen -L 0 --stage1 /dev/source /dev/destination