Skip to main content

Module repack

Module repack 

Source
Expand description

Repack — copy file trees from one source into a freshly-formatted destination filesystem.

Three kinds of sources, exposed as Source:

  • A host directory (Source::HostDir) — the original fstool create flow, walks a directory tree.
  • A tar archive on disk (Source::TarArchive), with optional compression codec. Compressed archives go through a two-pass stream-index → replay flow; plain .tar falls through to the Image path (the regular tar reader sits on top of a crate::block::BlockDevice).
  • An existing image (Source::Image) — a raw or qcow2 file, optionally with a :N partition selector. Walks the source FS through AnyFs and copies entries straight through without host-filesystem intermediation.

The two main entry points — populate_ext_from_source and populate_fat32_from_source — take an already-formatted destination filesystem and stream the chosen source’s contents into it. Auto-sizing helpers (ext_build_plan_for_source, fat32_min_bytes_for_source) let callers right-size the destination geometry up-front.

Used by both the fstool repack CLI command and by the spec layer when a TOML source = "..." value points at a tar / image instead of a directory.

Structs§

FsSink
Sink that writes into any block-device-backed Filesystem through the trait. lossy (set for FAT/exFAT) drops symlinks / devices / xattrs the destination can’t represent instead of erroring.
Progress
Progress reporter for a running repack. The CLI installs one with enter before driving the copy path and tears it down with leave afterward; the inner copy code calls note for each entry it processes.
RepackMeta
Per-entry metadata carried through RepackSink. A superset of both FileMeta and TarEntryMeta.
TarStreamSink
Sink that streams a tar archive (optionally codec-wrapped) to a Write. Hard links are materialised (tar copies the body).

Enums§

Source
Where to draw a filesystem’s contents from when building or populating it. See module docs.

Traits§

RepackSink
The destination side of a repack. A source walk drives exactly one of these; the two implementations are an FS-backed sink (FsSink) and a streaming-tar sink (TarStreamSink).

Functions§

build_ext_plan_through_trait
Public counterpart of build_ext_plan_inner for the binary crate’s build_ext_plan. Walks the source through the crate::fs::Filesystem trait, no AnyFs match.
enter
Install p as the active progress sink for this thread. Inner copy code calls note without knowing whether progress is wired up; the sink is per-thread so different concurrent repacks don’t trample each other.
ext_build_plan_for_source
Build a BuildPlan sized for the source. Walks the source once and feeds entry counts + byte totals into the plan; the resulting to_format_opts() is ready to drive Ext::format_with.
fat32_min_bytes_for_source
Compute the minimum FAT32 byte capacity needed to fit source. Bumps to the FAT32 cluster-count minimum + rounds up to a 512-byte sector boundary.
leave
Tear down the active progress sink, emitting its final summary. No-op if enter wasn’t called.
note
Record one processed entry at path. No-op when no sink is active.
note_bytes
Record n bytes of file body written. Used by the streaming walkers to drive the progress bar’s byte fraction. No-op when no sink is active.
open_tar_stream
Open a (possibly compressed) tar at path as a forward-only byte stream — make_reader decompresses on the fly, so no tempfile is ever written. Each call re-opens from byte 0; callers that need a sizing pre-pass simply call this twice (the “read twice” the streaming repack trades for not staging to disk).
open_tar_stream_index
Open the tar source (optionally codec-wrapped) and build a random-access index over it. Shared entry point for the streaming-tar inspector commands.
phase
Announce a coarse phase boundary (e.g. “decompressing …”, “scanning source …”, “formatting … destination”). Prints on its own line in both TTY and pipe/log modes and resets the running file counter — every emitted phase is the start of a new pass, so the user-visible “repack: N files” reflects the current phase rather than summing across passes (without this a two-pass build double- counts every entry, since both the analyze pass and the copy pass walk the source). No-op when no sink is active.
populate_ext_from_source
Populate dst (a freshly formatted ext{2,3,4}) with the contents of source. The destination is assumed to already exist.
populate_fat32_from_source
Populate dst (a freshly formatted FAT32) with the contents of source. The destination is assumed to already exist. FAT can’t hold symlinks / device nodes / POSIX metadata, so the sink runs in lossy mode (drop-with-warning).
populate_fs_from_source
Populate any crate::fs::Filesystem from source, dispatching through the trait for every entry create. Works for HFS+, NTFS, F2FS, SquashFS, XFS — whatever implements the trait — though ext/FAT32 callers should prefer populate_ext_from_source / populate_fat32_from_source which preserve xattrs and use the per-FS fast paths.
populate_fs_from_source_dyn
Trait-object form of populate_fs_from_source. Used by code paths (e.g. crate::inspect::AnyFs dispatch helpers) that have a &mut dyn Filesystem rather than a known concrete type.
set_total
Tell the active progress sink the totals for the current phase so it can render a percentage / bar. Call this after phase("…") (which clears any previous totals) and before the copy walk starts. The numbers come from the analyze pass: files = directory entries to emit (regular + dir + symlink + device), bytes = total regular-file body bytes. No-op when no sink is active.
walk_anyfs
DFS over an opened source filesystem, emitting each entry into sink with full metadata (getattr), xattrs (list_xattrs), symlink targets, and device numbers. Hard links are de-duplicated by (inode, nlink); if the sink can’t represent a link it materialises the body.
walk_filesystem
DFS over any &mut dyn Filesystem source, emitting each entry into sink — the trait-driven twin of walk_anyfs. Used to repack an in-memory crate::fs::ramfs::Ramfs (or any other Filesystem) into a fresh image without routing through crate::inspect::AnyFs. Same cycle/depth guards and (inode, nlink) hard-link de-duplication. Does not call sink.finish() — the caller does.
walk_source_into_sink
Walk source and replay every entry into sink. This is the single repack copy path: there is no per-(source,dest) branching — sink decides whether the output is a streaming tar or a block-device FS. The caller is responsible for sink.finish() (or, for an FS sink, flushing the destination) afterwards.
walk_tar_stream
Stream a (decompressed) tar reader straight into sink — the non-random-access counterpart to walk_anyfs. Drives tar::stream::TarStreamReader, which resolves PAX / GNU long-name + long-link overrides and exposes each entry’s body as a Read. Bodies are streamed (never fully resident); parent directories are created on demand; hard links the destination can’t represent fall back to a destination-sourced copy via RepackSink::materialise_copy.