Skip to content

borg2 check: overview / tracking ticket #9998

Description

@ThomasWaldmann

This ticket collects all cmd: check tickets (especially the ones in the 2.0.0b23 milestone)
into one place: a summary of how borg2 check is supposed to work, plus a checkbox list of the
concrete work items. Ticked items are already in master (commit linked); unticked items are
still to do (open PR linked where one exists).

Tracked tickets: #9696 #9825 #9898 #9901 #9218 #9443 #8009 #7893 #2397 #8466 #8476 (b23),
#8478 (b24), #6584 (2.1), plus the already-closed #9897 #9411 #8518 #8517 #8559 #8297 #1931 #7062.

How borg2 check is supposed to work

What changed vs. borg 1.x

borg 1.x check had a repository part (crc32-check all segment entries, always rebuild the
repository index, run server-side for ssh repos) and an archives part (read all archives, check
chunk presence, optionally --verify-data). Much of that design no longer applies:

  • A borg2 repository is a borgstore store. There is no borg process on the server side
    (except for rest: served by borg serve --rest), so "run the check on the server" is
    replaced by something better: content-addressed verification.
  • Pack files (packs/<sha256>) and chunk index fragments (index/<sha256>) are named by the
    sha256 of their content (fd177535).
    So "is this object intact?" is simply Store.hash(name) == name. The REST backend computes
    the hash server-side, so a full repository check of a remote repo transfers no pack data.
  • The chunks index (chunk id → pack id, offset, size) lives in the repository and is the
    authoritative record of which chunks exist and where.
  • There is no chunks_healthy anymore (borg2: reconsider chunks_healthy approach #8559): an item's chunks list always holds the
    correct chunk ids, even when chunks are missing. Missing chunks are handled dynamically at
    read time (zeros or error), and if a later borg create re-produces a missing chunk, all
    old archives referencing it are healed instantly — no repeated check --repair runs.

Phase 1: repository check (cheap, read-only, no key needed)

  1. Verify all index/ fragments via Store.hash (small, always checked in full).
  2. If (and only if) the index is intact, verify all packs/ the same way.
  3. Partial checks (--max-duration) resume from a persisted set of checked packs
    (cache/checked-packs, borg2 check: move from marker to set-of-checked-packs #9897), with periodic checkpoints. Packs recorded as corrupt are
    always re-verified, never skipped.
  4. The read-only check never rebuilds the index: reading every pack is far too slow and
    expensive for a routine check. A corrupt index is reported and left for repair.

This phase is designed to be a routine, cron-able job: no key, no prompt, bounded time,
meaningful exit code. Its findings (corrupt pack ids) should be persisted so a later repair
can consume them instead of re-scanning everything (PR #9925).

Phase 2: archives check (client-side, needs the key)

  1. Ask for the passphrase up front, not hours into the run (ux: borg check asks for passphrase very late #1931).
  2. Check the manifest (rebuild if missing/corrupt), the archives directory, each selected
    archive's metadata object and item metadata stream (robust resync on damage), and each
    item's file-content chunk presence against the (verified) chunks index.
  3. --verify-data: additionally read, decrypt (AEAD-authenticate) and decompress every
    object — full cryptographic verification, detects malicious tampering too (for encrypted
    repos, against attackers without the key).
  4. --find-lost-archives: full scan of all objects for archive metadata without an archives
    directory entry; with --repair, recreate the entry (possible until borg compact removes
    the data).

A normal (non-repair) archives check trusts the hash-verified index and does not rebuild it
(#8476); only repair rebuilds from the actual packs.

Repair philosophy

Design goals

Work items

Repository check (read-only)

Archives check

Repair

Reporting & UX

Done / resolved by the borg2 design (no action needed)

Milestone view (2.0.0b23)

Ticket Topic State
#9696 check redesign umbrella read-only part done; repair part is the open core work
#8466 check --repair improvements open (index caching after repair)
#8476 avoid unnecessary index rebuild read-only part done; repair-index/-pack open
#9898 vanished packs open (PR #9925 related)
#9901 index rebuild trusts pack headers open
#9825 dealing with repo corruption open (docs + acknowledge mechanism)
#9218 missing-chunk reporting PR #9965 open
#2397 summarize findings/repairs PR #9891 open
#7893 Ctrl-C PR #9966 open
#9443 repo check progress done for read-only (27d693c2); repair progress open
#8009 progress counters borg1 wontfix; borg2 covered by #9443 items
#9897 set-of-checked-packs done (bc8b3c07)
#9411 check --format done (d7ffe748)

made by Claude Fable 5

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions