6

I have two ddrescue images created from contiguous recovery attempts of the same media. The two images are the same size but have complementary data:

$ od part-one/ddrescue_image --skip-bytes 227966006774 --read-bytes 32
3242365232766 113056 016517 102014 074371 144073 000000 000000 000000
3242365233006 000000 000000 000000 000000 000000 000000 000000 000000
3242365233026
$ od part-two/ddrescue_image --skip-bytes 227966006774 --read-bytes 32
3242365232766 000000 000000 000000 000000 000000 124616 163450 064251
3242365233006 074567 134433 012742 022160 044301 054235 140604 020633
3242365233026

How can I merge them into a single, complete image?

Details

  • The second image is simply a continuation of the first recovery attempt, à la:

    $ ddrescue corrupt-partition part-one/ddrescue_image part-one/ddrescue_log
    $ mkdir part-two; cp part-one/ddrescue_log part-two/ddrescue_log
    $ ddrescue corrupt-partition part-two/ddrescue_image part-two/ddrescue_log
    
  • The second image is almost entirely zeros, but contains 18 KB of recovered data spread across 1847 isolated regions.

  • I tried using the technique mentioned on this mailing list,

    $ ddrescue --domain-logfile=part-two/ddrescue_log part-two/ddrescue_image part-one/ddrescue_image part-one/ddrescue_log
    
    
    GNU ddrescue 1.16
    Press Ctrl-C to interrupt
    Initial status (read from logfile)
    rescued:   937286 MB,  errsize:   62976 B,  errors:     122
    Current status
    rescued:   937286 MB,  errsize:   62976 B,  current rate:        0 B/s
       ipos:         0 B,   errors:     122,    average rate:        0 B/s
       opos:         0 B,     time since last successful read:       0 s
    Finished
    

    but it doesn't appear to have changed anything.

4

If you know exactly which region of data you want to copy, you can use dd:

dd conv=notrunc if=input of=output seek=123456 skip=123456 bs=4k count=128

That would copy 128 4k blocks from input to output starting at 123456.

It would be prudent to backup the blocks you are about to overwrite first:

dd if=output skip=123456 bs=4k count=128 of=output-backup-bs4k-pos123456

If you do NOT know which region of data to copy or are unsure about it, GNU dd happens to know sparse.

dd conv=notrunc,sparse if=input of=output bs=4k

That would copy every non-zero 4k input block to output. Use bs=512 if your blocks are smaller!

Note that there isn't a backup with this method, so you better copy the file if it's important.

1

Try something like this?

dd if=part-one/ddrescue_image bs=1 count=227966006784 >result
dd if=part-two/ddrescue_image bs=1 seek=227966006785 >>result

The small block size will make this very slow; if you can refactor to use a bigger block size and still land at the correct offset, that should make it a lot faster.

If you can't do that, splitting the operation into more dd invocations is probably a goid idea -- read with a large block size such as 65536 to the nearest 64K boundary, then take it slow from there (maybe stepping down to a 1K block size to the nearest 1K boundary before going all the way to individual bytes), then go faster again once you are done with the fine-grained manipulation.

  • With the updated information about the scattered regions, this still holds as a proof of concept. Loop across a list of offsets, switching to the second image at the offsets where it contains data you want. – tripleee Jul 14 '13 at 8:17

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.