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 originalfstool createflow, 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.tarfalls through to theImagepath (the regular tar reader sits on top of acrate::block::BlockDevice). - An existing image (
Source::Image) — a raw or qcow2 file, optionally with a:Npartition selector. Walks the source FS throughAnyFsand 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
Filesystemthrough 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
enterbefore driving the copy path and tears it down withleaveafterward; the inner copy code callsnotefor each entry it processes. - Repack
Meta - Per-entry metadata carried through
RepackSink. A superset of bothFileMetaandTarEntryMeta. - TarStream
Sink - 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§
- Repack
Sink - 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_innerfor the binary crate’sbuild_ext_plan. Walks the source through thecrate::fs::Filesystemtrait, no AnyFs match. - enter
- Install
pas the active progress sink for this thread. Inner copy code callsnotewithout 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
BuildPlansized for the source. Walks the source once and feeds entry counts + byte totals into the plan; the resultingto_format_opts()is ready to driveExt::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
enterwasn’t called. - note
- Record one processed entry at
path. No-op when no sink is active. - note_
bytes - Record
nbytes 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
pathas a forward-only byte stream —make_readerdecompresses 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 ofsource. The destination is assumed to already exist. - populate_
fat32_ from_ source - Populate
dst(a freshly formatted FAT32) with the contents ofsource. 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::Filesystemfromsource, dispatching through the trait for every entry create. Works for HFS+, NTFS, F2FS, SquashFS, XFS — whatever implements the trait — though ext/FAT32 callers should preferpopulate_ext_from_source/populate_fat32_from_sourcewhich 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::AnyFsdispatch helpers) that have a&mut dyn Filesystemrather 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
sinkwith 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 Filesystemsource, emitting each entry intosink— the trait-driven twin ofwalk_anyfs. Used to repack an in-memorycrate::fs::ramfs::Ramfs(or any otherFilesystem) into a fresh image without routing throughcrate::inspect::AnyFs. Same cycle/depth guards and(inode, nlink)hard-link de-duplication. Does not callsink.finish()— the caller does. - walk_
source_ into_ sink - Walk
sourceand replay every entry intosink. This is the single repack copy path: there is no per-(source,dest) branching —sinkdecides whether the output is a streaming tar or a block-device FS. The caller is responsible forsink.finish()(or, for an FS sink, flushing the destination) afterwards. - walk_
tar_ stream - Stream a (decompressed) tar
readerstraight intosink— the non-random-access counterpart towalk_anyfs. Drivestar::stream::TarStreamReader, which resolves PAX / GNU long-name + long-link overrides and exposes each entry’s body as aRead. 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 viaRepackSink::materialise_copy.