SHA256
1
0
Fork
You've already forked resumedd
0
Tool to help with resuming aborted dd operations on block devices.
  • Rust 100%
Find a file
2026年01月10日 04:16:05 +01:00
src fix: update to new err format 2026年01月10日 04:15:05 +01:00
.gitignore feat: initial commit 2026年01月10日 03:33:20 +01:00
Cargo.lock feat: initial commit 2026年01月10日 03:33:20 +01:00
Cargo.toml feat: initial commit 2026年01月10日 03:33:20 +01:00
PERFORMANCE chore: formatting 2026年01月10日 04:16:05 +01:00
README chore: formatting 2026年01月10日 04:16:05 +01:00
rustfmt.toml feat: initial commit 2026年01月10日 03:33:20 +01:00

resumedd
A tool for diffing block devices and finding roughly where they differ, built
to resume cancelled/aborted long-standing dd operations without wearing out
the disks re-writing all of the parts that were already written.
Skips n random blocks between sectors read, so only use this on disks where
it's highly unlikely that blocks will randomly be the same (a freshly
initialized LUKS for example, should be fine), as to prevent it skipping
over a mismatch randomly.
Running multiple (2-3) times or changing the `MAX_SEEK` value may also help.
-----------
Assumptions
-----------
We assume a block size of 4096 bytes. This can be changed in src/main.rs.
If your block size is smaller, this should really be changed. In theory you can
also divide by 4096 and then multiply by your block size to get a skip/seek
value that's realistic for your use-case.
We also assume blocks within MAX_SEEK (defaults to 32768 as of writing) will
never differ until every block differs. In the case of partial mismatches, ie
in the case of partial corruption with only small mismatches, we are unlikely
to detect anything.
------------------
Operating the tool
------------------
Assuming the output
❯ doas resumedd /dev/mapper/a /dev/mapper/b
doas (lain@navi) password: 
i 0 incr's, at block 0, byte 0
i 512 incr's, at block 8607700, byte 35257139200
i 1024 incr's, at block 17084095, byte 69976453120
i 1536 incr's, at block 25305405, byte 103650938880
i 2048 incr's, at block 33535047, byte 137359552512
i 2560 incr's, at block 41874242, byte 171516895232
[snip]
i 8704 incr's, at block 142808786, byte 584944787456
i 9216 incr's, at block 151258805, byte 619556065280
i 9728 incr's, at block 159772808, byte 654429421568
i 10240 incr's, at block 168129008, byte 688656416768
i 10752 incr's, at block 176359900, byte 722370150400
E ERR within 4926 blocks of 181337629
E ERR within 2875 blocks of 181342555
E ERR within 17973 blocks of 181345430
E ERR within 23168 blocks of 181363403
[snip]
E ERR within 9000 blocks of 182333443
E ERR within 11329 blocks of 182342443
E ERR within 20670 blocks of 182353772
E ERR within 25212 blocks of 182374442
F Maximum Error Count Reached! (64 of 64 errors)
F First error around block 181337629, byte 742758928384.
F Exiting...
You can be relatively confident that `dd` with
`bs=4k skip=181337629 seek=181337629` should resume it.
Note that the informational lines `i [...] incr's, at block [...], byte [...]`
are just progress logs.
-----------
Performance
-----------
See ./PERFORMANCE