8

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.

2 Answers 2

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.

2
  • 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, 2013 at 8:17
  • If you use iflag=count_bytes oflag=seek_bytes, then you should be able to set the block size to whatever you want.
    – mwfearnley
    Jun 16, 2020 at 12:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .