1. Pure Rust, #![forbid(unsafe_code)], zero system dependencies —
reading AND writing the default format needs no C++ toolchain,
no vcpkg, no cmake
2. Build wall-clock: limnifs-core compiles everywhere Rust compiles,
semver-pinned from crates.io — the dwarfs-t vcpkg ports were the
CI cost driver (per-target C++ cross-compilation)
3. Content-addressed: every drop is BLAKE3(plaintext) — image-internal
integrity and dedup come from the format, not bolted-on machinery
4. Read efficiency: on-demand per-class decompression; inline drops
serve small files straight from the metadata blob, no slab access
5. Unambiguous detection: the strong LMFS magic is disjoint from
every existing probe arm
6. Nothing else changes: existing dwarfs packages, runtimes, and
payload artifacts are untouched; dwarfs stays a first-class
explicit --format dwarfs opt-in and a supported read backend
forever
ARCHITECTURE · 15
Image formats.
Every payload image is a file. Its format answers exactly one question, how to read these bytes, and nothing else; what a payload is, whether it is a runtime, and where its entrypoint lives are manifest semantics that never touch the format id.
|
Note
|
Six in-tree formats are shipped, with LimniFS the default write format since v0.2.0 and magic detection authoritative. The pure-Rust runtime line (backend-limnifs only) is a recorded goal on its own release line, and it is planned. |
The format_id axis
The format_id is a 32-bit field in each trailer slot record, and it is a
hint. Magic detection on the actual bytes is authoritative; a slot stamped 5
whose bytes do not open with LMFS mounts as what the magic says. Ids ≥ 6
are unallocated.
| ID | FORMAT | READER | TOOLCHAIN | STATUS |
|---|---|---|---|---|
0 |
|
Magic detection decides. |
— |
It is the hint value that defers to the bytes. |
1 |
|
dwarfs-t (FlatBuffers metadata) |
C++ (vcpkg/cmake) |
It is a first-class read backend, with an explicit --format dwarfs write opt-in. |
2 |
|
squashfs-tools-ng |
C (POSIX-only today) |
It is a read backend. |
3 |
|
pure Rust |
none |
It is a read backend. |
4 |
|
It is never mounted. |
— |
It is a legacy runtime-role wart: never reused and never given new meaning. |
5 |
|
limnifs-core, #![forbid(unsafe_code)] |
pure Rust, zero system deps |
It is the default write format, and it reads everywhere. |
Id 4 is the v1 wart: a runtime role smuggled into the format field so that v1 loaders skip handing the runtime slot over as a mount. It is kept for backward compatibility and never reused; roles live in manifests, and new semantics are never again smuggled into the format axis. The documented deviation is locked: the reference C99 reader keeps its bound at 4 and rejects a format-5 slot with its named invalid error, which is fail-closed and correct, since a v1-era reader cannot read limnifs bytes.
Detection: strong magic first, weak heuristics last
Detection uses one 512-byte sniff window and one locked probe order. Every mount, a host file, memory, a file-region (offset+length), or a VFS-file-region (an image addressed by a path inside an existing mount, read through the owning mount’s pread), serves one byte-slice core.
| # | MAGIC | FORMAT |
|---|---|---|
1 |
|
zip |
2 |
|
dwarfs |
3 |
|
squashfs |
4 |
|
limnifs — disjoint 4-byte prefix against every arm above |
5 |
|
tar envelopes (gzip, zstd) |
6 |
|
tar — always LAST (weak) |
7 |
|
Unknown magic answers EINVAL at mount. |
Compile separation: a build ships exactly the formats it must read
Backends compile in per cargo feature. The enc transform feature is
orthogonal, and it stacks over any backend.
| FEATURE | BACKEND | TOOLCHAIN |
|---|---|---|
|
dwarfs-t (FlatBuffers) |
C++ (vcpkg/cmake via dwarfs-t-rs) |
|
squashfs |
C (squashfs-tools-ng; POSIX-only today) |
|
zip |
pure Rust |
|
tar (+ gz/zst envelopes) |
pure Rust |
|
limnifs |
pure Rust, #![forbid(unsafe_code)], no system deps |
The per-product defaults are the following: the packager and human tools
(tebako-cli, tfs-cli, tebako-pkg) ship all backends; the driver inside every
runtime exe and the preload shim ship all backends, so any package runs on
any runtime; and the bootstrap ships no backend, ever, because it never
mounts, stays format-agnostic, and stays inside its size gate. The
compiled-out rule is locked: a mount whose detected format has no
compiled-in backend fails with the named ENOTSUP, naming the format, and
there is never a silent re-route, a partial read, or a crash.
Why LimniFS is the default
The default is the format every payload takes when the operator says nothing, so it must be the one with the least toolchain exposure, the least build cost, and no loss of capability.
Both writer entry points, tfs mkimage and tebako press, default to
limnifs and work fully in-process, with no limni or mkdwarfs binary, no
PATH lookup, and no shell-out. While the published runtime fleet’s readers
span pre-fix limnifs lines, the writers pin a floor-safe recipe (no
shared-inline dedup, lz4-HC metadata, lz4-or-store content drops), and every
constraint names its lift condition, a factory runtime cut whose link unit
carries limnifs-core ≥ 0.2.53. A payload written outside the constraints is
not rejected; it is simply below the floor’s guarantee, so it may mount on
newer readers and fail closed, by name, on older ones.
Read-only at runtime, forever
The transforms law binds every backend: no format backend learns to write,
creation-time writers are the only write path, and COW and ENC stack above
as transforms. Writes to a read-only mount fail EROFS at the mode gate,
above the backend, and TEBAKO_MOUNT_RW stays ENOTSUP in-tree. LimniFS’s
own AEAD-sealed images are an image-format concern; a mount of one without
key support fails ENOTSUP by name, and tebako-side encryption stays the
stacking transform. The in-image manifest never names a format: payload
artifacts stay .tfs-named and byte-identical with the registry artifact
whatever the backend.
See also: The virtual filesystem · Declarative overlays · How a Tebako package works.