Skip to download

Recovery provenance / constructed software experiments

ddrescue image provenance: twelve controlled cases

Complete maps, stale output bytes, approximate map reconstruction and identical images with different acquisition histories.

Download CSV12 cases / 9 columns

Metadata and hashes / Original observations / Replay / Interpretation

Method

Eight rescue/resume cases, three approximate-map cases and one post-copy modification on a known 4096-byte fixture. Read errors are simulated with --test-mode. Source sectors are A, zero, C, D, E, F, G and H; letters denote 512 repetitions of that ASCII byte. Reused destinations start filled with Z. Copy buffers are one sector. GNU ddrescue 1.30 was built from the pinned official archive. These are selected counterexamples, not recovery-rate estimates.

Source extent: 4,096 bytes. Status 0 means the indicated command succeeded, not necessarily a correct image.
CaseFinished bytesMatching bytesFull-domain statusFirst-sector status
fresh-bad-data3584358410
reused-bad-data3584358410
fresh-bad-zero3584409610
fresh-healthy4096409600
sparse-fresh-healthy4096409600
sparse-reused-healthy4096358400
sparse-reused-bad-data3584307210
resume-sparse-reused4096358400
generated-fresh-bad-data3072358410
generated-reused-bad-data3584358410
generated-sparse-reused-bad-data4096307200
modified-after-completion4096358400

What the columns establish

The mapfile provides interval states; the known source provides a separate byte oracle. Every mismatch fills an entire sector in these fixtures. Counting matching sectors therefore gives the matching-byte total here, but is not a generic byte-difference counter. Generate-mode rows inspect output and do not copy source bytes. The modification row records a fixture edit, not a ddrescue invocation.

Sparse writes into nonzero output intentionally violate the manual's precondition. The resume disables sparse writes and read-error simulation while keeping that image/map pair: 4,096 finished bytes, 3,584 matching bytes. Fresh-output controls distinguish the misuse from ordinary sparse-file behavior.

Reproduce

Build upstream 1.30 from the release archive with ./configure, make and make check. Its hash and inspected files are in the source ledger. No upstream executable or source is redistributed.

Place the harness, tests and results.json together. Python 3 is required. The harness uses disposable regular files only, bounds subprocess runtime and refuses to replace an existing receipt.

python3 observe.py --ddrescue /path/to/ddrescue \
  --ddrescuelog /path/to/ddrescuelog --output fresh-results.json
DDRESCUE_BIN=/path/to/ddrescue DDRESCUELOG_BIN=/path/to/ddrescuelog \
  python3 -B -m unittest -v test_observe

For a CSV/metadata rebuild, put all files named in metadata's sha256 object together, including the generator, publication tests, replay, claims and license. Run python3 -B build_publication.py --dev-root ./rebuilt. Outputs appear below rebuilt/sites/hesela-dev/public/. Run python3 -B -OO -m unittest test_publication to check mutation rejection, replay equivalence and file hashes.

Environments and replay

Original: Linux 6.18.55, x86_64, Python 3.12.14; generated 2026-10-18T05:23:15.836662+00:00. Replay: Linux 6.8.0-146-generic, x86_64, Python 3.12.3; generated 2026-10-18T09:23:46.198610+00:00. All twelve stable outcomes matched.

Comparison excludes timestamps and map comments, but retains image hashes, sector comparisons, ranges and exit statuses. Both raw receipts retain original timestamps and executable hashes. HTTPS and hash pinning were used without detached-signature verification. This is software repeatability evidence, not a hardware study.

Limits

Column definitions

case
Stable scenario ID, not an independent fleet observation.
mode
Rescue, resume, approximate map generation or post-copy modification.
source_bytes
Known fixture extent in bytes.
finished_bytes
Bytes in map ranges marked +, not independently verified image bytes.
matching_source_bytes
Bytes equal to the fixture; differences in these cases occupy whole sectors.
operation_status
Operation exit status; modification is a fixture action, not ddrescue.
done_status
ddrescuelog --done-status over the full map domain.
first_sector_done_status
The same check restricted to the first 512 bytes.
image_sha256
Output digest, not source authentication or acquisition history.

Sources and reuse

Hesela-authored code, observations and derived CSV: MIT. GNU source and documentation retain their licenses and are not redistributed.

  1. GNU ddrescue 1.30 manual: sparse output, generate mode and ddrescuelog
  2. GNU ddrescue 1.30 source release: rescuebook.cc and genbook.cc

Related: sparse file, checksum, backup verification.

Published by Hesela team

Report a correction · Editorial standards · Reuse guidance

Cite this page
Hesela team. ddrescue image provenance: twelve controlled cases. Hesela. https://hesela.dev/datasets/ddrescue-image-provenance/