65 Commits
Author SHA1 Message Date
Thomas WaldmannandClaude Fable 5.1 1110bcddba repository: single config/config text object replaces readme, version, id and manifest (repo version 5)
Opening a repository loaded four store objects: config/readme (sanity check),
config/version, config/id and config/manifest (only read for its key type
byte since the manifest lost all other content). Now there is one plain text
INI object, config/config, e.g.:

    # This is a Borg Backup repository.
    # See https://borgbackup.readthedocs.io/

    [repository]
    version = 5
    id = <64 hex digits>
    encryption = aes256-ocb
    id_hash = sha256

The crypto suite of the key is recorded by the --encryption / --id-hash
names, so key_factory() selects the key class from the config without
reading any repository object. Both names are recorded or none; a config
with one but not the other is invalid, an unsupported suite raises
InvalidRepositoryConfig. The repository version is 5; only version 5 is
accepted, there is no code to read the old layout and no migration (betas
are for new repositories only).

The manifest object is gone for borg 2 repositories: Manifest is now only
the in-memory container for key, repo_objs, repository and archives; its
write() and all callers, get_manifest()/put_manifest(), the manifest checks
and rebuild in "borg check", "borg debug dump-manifest", the key type
detection from stored objects (key_from_repository) and the ROBJ_MANIFEST
type are removed. borg 1.x repositories are still read via their manifest
(legacy_key_factory), as it holds their archives list. NoManifestError is
kept (never raised) so that rc 26 stays reserved.

Repository.create() creates all namespace directories in advance
(store.create_levels()) and writes the config (version, id, no key info)
right away, so a repository created via the Python API is an openable
key/value store. "borg repo-create" alone defers the config write
(create_config=False) until after the key was created, so nothing that
looks like a repository exists until repo-create succeeds: any failure or
interruption before that destroys the store (and the keyfile, in keyfile
mode), and a failure inside create() destroys the store as well.

A store without repository config is reported as not a valid repository
(InvalidRepository; DoesNotExist is only for a missing store backend, the
rest:// case from #10365). repo-create on it raises IncompleteRepository
(rc 11, "has no repository config"), as the store backend refuses any
non-empty directory. "borg repo-delete --force" destroys such a store, so
that ssh/rest/s3 users can remove it without other access to the storage,
but only if it has the packs, archives, index and config namespaces every
store borg created has: a data directory, a home directory or a borg 1.x
repository is never destroyed by borg. key_factory() on a config without
key info raises RepositoryKeyInfoMissing (rc 54).

The cache config's [cache]/[integrity] cross-check (manifest id) could
never detect anything and is dropped.

Docs: new "Repository config" section replaces the manifest section
(including how to recreate a lost config by hand, as check --repair can
not), the layout list, packs and security internals (where the protection
against a swapped crypto suite lives), repo-info example, error list and the
remaining manifest mentions are updated.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-18 00:28:33 +02:00
Thomas WaldmannandClaude Fable 5 8550349a77 docs: update internals/data-structures.rst to the current formats
The document still described borg 1.x in many places. All claims were
re-verified against the code (and a live scratch repository):

- repository layout: borgstore namespaces (archives/ cache/ config/
  index/ keys/ locks/ packs/) instead of the borg1 nested data/ tree;
  document the index/ namespace and the cache/ objects.
- repo objects: the 49-byte header (magic, version, chunk id, meta and
  data sizes) and storage inside packs; container details deferred to
  the packs document.
- manifest: version 2, archives always empty, item_keys inside config.
- archives directory: entries keyed by archive ID with empty content;
  no duplicate-name counters; soft-delete via the .del suffix.
- archive timestamps: time/start/end (time_end is borg1-only).
- item fields synced with item.pyx (target, bsdflags, size, inode,
  ACL keys; legacy read-only keys noted).
- files cache: document the digests field and the actual location.
- argon2 salt is 128 bits, not 256.
- key envelope: repository_id refers to the config/id store object;
  optional label field added.
- locking: drop the borg1 fslocking cache-lock section; storelocking
  is the only locking borg2 does.
- cache config: actual keys + [integrity] section; a corrupt files
  cache is discarded and rebuilt, not fatal.
- compaction: describe the current index-driven algorithm; drop the
  "reappeared IDs" claim.
- id-hash modes: --id-hash for encrypted modes vs the fixed
  authenticated-*/none-* modes.
- default chunker examples use fastcdc; fix the broken "cache" link.
- internals.rst: mention the rabin-aes/toeplitz-aes/goldilocks-aes
  chunkers; compression is done by RepoObj, not the key object.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-28 12:41:20 +02:00
Thomas WaldmannandClaude Fable 5 ea9e1eb55d docs: add chunker guide (user-level and cryptographic)
New docs/internals/chunker.rst documenting all supported chunkers twice:

- a plain-language section for users: what the chunker choice affects,
  the chunk-size fingerprinting threat model, an at-a-glance comparison
  table, and concrete recommendations per use case (borg 1.x dedup
  compat, speed, untrusted repository storage, disk images);
- a technical section for readers with a crypto background: the FSWC
  model, why direct-decision keyed rolling hashes are broken (key
  recovery from observed boundaries), the UHF-then-PRF construction and
  its epsilon-AU requirement, the three universal hashes with their
  collision bounds (rabin-aes ~2^-55 probabilistic, goldilocks-aes
  ~2^-58, toeplitz-aes exactly 2^-64 unconditional), why the fixed
  64-byte window is essential (including the rotation/cancellation
  algebra that also explains the classic 4095-vs-4096 buzhash window),
  rejected alternatives, measured performance, proof-bound limits and
  the wider-digest upgrade path, plus references.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-04 15:56:38 +02:00
Thomas Waldmann 61b1b83059 make fastcdc the default chunker, fixes #9957
fastcdc is ~1.3x faster than buzhash/buzhash64 at the same deduplication
and (with normalized chunking) a tighter chunk size distribution.

It is also the better choice security-wise: its Gear table is derived
from secret key material, while the "buzhash" chunker only XORs a 32bit
seed into its table - so chunk cut points are much harder to predict
without the key (resistance against chunk-size fingerprinting attacks).

Both places using a chunker are switched:

- CHUNKER_PARAMS (file content data): fastcdc,19,23,21,2
- ITEMS_CHUNKER_PARAMS (item metadata stream): fastcdc,15,19,17,2

The metadata stream chunker was still using the 32bit seeded buzhash, so
this also closes that gap.

Also rename CHUNKER64_PARAMS -> BUZHASH64_PARAMS and add BUZHASH_PARAMS,
so the per-algorithm defaults are named consistently and CHUNKER_PARAMS
unambiguously means "the default chunker".

This is intentionally done during the beta phase so it gets plenty of
practical testing before borg2 is released for production.
2026-08-02 00:40:58 +02:00
Thomas Waldmann 6854dca403 fix #9884: chunks index terminology update
Rename chunks cache / cached chunks index to chunks index or index, renaming parameters/variables where appropriate to avoid 'cache' terminology for index.
2026-07-08 22:47:33 +02:00
Thomas Waldmann 48308f1969 misc docs updates 2026-06-16 15:21:57 +02:00
Mrityunjay Raj 5d6cafe4b8 docs: add pack file format design and internals documentation, refs #8572 2026-05-27 13:26:18 +05:30
Thomas Waldmann 3120f9cd1c fixed typos and grammar (AI)
this was done by Junie AI.
2025-09-23 14:56:23 +02:00
Thomas Waldmann d23704e112 buzhash64: docs 2025-06-10 23:42:22 +02:00
Paul D 253d8e8d4e Docs grammar fixes
joined split infinitives, and relocated adverbs appropriately.
2022-12-29 22:26:54 +00:00
Thomas Waldmann 7f46eb99aa update docs about fixed chunker and chunker algo spec needed 2019-02-13 06:30:13 +01:00
Marian Beermann d495b0fe75 docs: move introduction sentence 2017-06-19 10:01:55 +02:00
Marian Beermann fec0958b7f docs: internals: columnize rather long ToC 2017-06-05 15:41:42 +02:00
Marian Beermann e80c0f7c5e docs: fix way too small figures in pdf 2017-06-05 01:01:27 +02:00
Marian Beermann f1709df8a9 docs/internals: layers image + description 2017-06-04 22:13:55 +02:00
Marian Beermann 9ed8e4b7a9 document JSON 2017-02-26 17:01:06 +01:00
Marian Beermann 19d50cff76 docs: internals: move toctree to after the introduction text
this only changes the location on the page, nothing about how the TOC
is arranged.
2017-02-22 15:56:27 +01:00
Marian Beermann 1652525858 docs: clarify metadata kind, manifest ops 2017-02-22 15:29:33 +01:00
Marian Beermann e5bbba573a docs: make internals.rst an index page
Subsections:

- Security
- Data structures and file formats
2017-02-22 00:21:14 +01:00
Marian Beermann 63f17087c8 docs: edited internals section a bit 2017-02-22 00:13:46 +01:00
Marian Beermann 8e8d9d3f48 docs: add edited "Cryptography in Borg" and "Remote RPC protocol security" sections
The former section is a bit older (Nov 2016) and has been the piece
responsible for finding CVE-2016-10099, since while writing it I
wondered how the manifest was authenticated to actually
*be* the manifest. Well. There it is ;)

It has been edited to final form only recently and should now be ready
for review.

The latter section is new.
2017-02-16 20:27:16 +01:00
Thomas Waldmann 76c5f1a258 add more details about resource usage 2016-11-26 04:34:01 +01:00
Thomas Waldmann c8b58e0fd8 improve cache / index docs, esp. files cache docs, fixes #1825 2016-11-24 01:53:23 +01:00
Carlo Teubner 1c666222a7 internals.rst: fix typos 2016-08-21 00:15:56 +02:00
Thomas Waldmann c834b2969c document archive limitation, #1452 2016-08-12 17:54:15 +02:00
Lee Bousfield 0a4a95eb17 Remove trailing whitespace 2016-07-27 10:05:51 -04:00
Thomas Waldmann cf4d761042 docs: fix the highlighting
default is "python", that's why some help fragments and bash scripts looked strange.
2016-07-11 23:16:53 +02:00
Marian Beermann 7ed425dae0 Repository: cleanup on ENOSPC 2016-07-05 20:33:07 +02:00
Thomas Waldmann 435d30d61b docs: updates and fixes 2016-02-01 03:22:02 +01:00
Thomas Waldmann e06b7162c2 update docs / docstring about new key location 2016-01-28 23:15:49 +01:00
Thomas Waldmann 1fc99ec9cd update docs, remove references to passphrase mode 2016-01-24 16:04:00 +01:00
Thomas Waldmann 169634f2ca change the builtin default for --chunker-params, create 2MiB chunks, fixes #343
one of the biggest issues with borg < 1.0 was that it had a default target chunk
size of 64kiB, thus it created a lot of chunks, a huge chunk management overhead
(high RAM and disk usage).
2016-01-24 15:44:09 +01:00
Robin Schneider 32900c8679 Mi does stand for a IEC binary prefix e.g. 2^20. 2016-01-18 10:38:55 +01:00
Robin Schneider 1f49d16a71 Fixed my changes. Thanks to @ThomasWaldmann for the review! 2016-01-18 09:00:07 +01:00
Robin Schneider 8b9ae0ae92 More – → -- (CLI) fixes. Fixed spelling. AES-256 is used.
* According to the comment in `borg/key.py`.
2016-01-17 23:49:54 +01:00
Robin Schneider 19eb8e2d3b Use `--option` in RST to not render "--" as "–". 2016-01-17 20:12:23 +01:00
Thomas Waldmann 888e078382 use finer chunker granularity for items metadata stream, fixes #547, fixes #487
the items metadata stream is usually not that big (compared to the file content data) -
it is just file and dir names and other metadata.

if we use too rough granularity there (and big minimum chunk size), we usually will get no deduplication.
2016-01-15 20:56:21 +01:00
Thomas Waldmann 393e36b6da updated internals docs: hash table max. load factor is 0.75 now 2015-12-13 19:58:32 +01:00
Thomas Waldmann 734dae80ef improve chunker params docs, fixes #362 2015-11-02 19:47:09 +01:00
Thomas Waldmann 1a949eab3e docs: internals: improve structure and formatting 2015-08-29 04:23:57 +02:00
Thomas Waldmann 1e11e24fc4 document locking system 2015-08-20 22:37:38 +02:00
Thomas Waldmann 1d16e7a37c compression: update / refine docs 2015-08-15 15:45:15 +02:00
Thomas Waldmann 8b1d46caa4 docs: more about compression 2015-08-10 20:36:21 +02:00
Thomas Waldmann b5bdb52b6a update internals doc about chunker params, memory usage and compression 2015-07-14 00:43:35 +02:00
Thomas Waldmann b2f460d591 fix filenames used for locking, update docs about locking 2015-07-13 23:20:46 +02:00
Jan Bader 8de8073345 Improve wording 2015-07-02 23:23:45 +02:00
Jan Bader 028e12473d Update internals to reflect new --compression argument 2015-07-02 23:21:28 +02:00
Thomas Waldmann 83f520cfbe improve internals docs 2015-06-07 02:15:13 +02:00
Thomas Waldmann cb5c9b63b3 fork: s/attic/borg/g, fix URLs, add new section to AUTHORS
use borg instead attic except at the places where it was used:
- as toplevel package name, directory name, file name
- to refer to original attic

remove sphinx upload make command, will be replaced by github.io site later

remove references to binary downloads and linux packages for now

remove some software name references, fix grammar

use borgbackup rather than borg-backup (or borg) in URLs,
less name collision issues, better search results, no validity issues with "-"
2015-05-13 15:02:33 +02:00
anarcat ecee5a0b51 PDKF is a key derivation function
do not use the word "encryption", as it is actually closer to "hashing" anyways.
2015-03-05 09:00:06 -05:00