Expand description
The Storage type holds references to three different types of
storage that together implement the unified storage model.
§Planned three-store architecture
The planned architecture for unified storage involves three content stores that share physical disk blocks on a reflink-capable filesystem (XFS, btrfs):
- bootc-owned containers-storage at
/sysroot/ostree/bootc/storage(overlay driver) — the image is accessible to podman and shares layers with Logically Bound Images. - composefs object store at
/sysroot/composefs/objects/(SHA-512 content-addressed) — used by composefs-boot to mount the rootfs as EROFS. Populated from containers-storage viaFICLONE(composefs_oci::pullwithZeroCopy). - ostree bare repo at
/sysroot/ostree/repo/objects/(SHA-256 content-addressed) — provides deployment, rollback, fsck, and delta updates. Populated from the composefs object store viaFICLONE(import_from_composefs_repo).
Each FICLONE ioctl lets the kernel mark source and destination extents as
copy-on-write siblings with no userspace data movement. On ext4 (no
reflinks), each step falls back to a byte copy.
§Implementation Plan
The containers-storage → composefs step (arrow 1) is already implemented
for the composefs boot backend in crates/lib/src/bootc_composefs/repo.rs
via pull_composefs_unified.
Wiring all three steps together for the ostree backend is the major planned work.
The composefs → ostree step (arrow 2) was proven by the composefs-to-ostree
spike branch. The planned implementation for the ostree backend will:
- Perform a lazy cached probe (
reflinks_supported) at install time. - Pull into containers-storage first (Stage 1).
- Use
composefs_oci::pullwithLocalFetchOpt::ZeroCopyto populate composefs (Stage 2). - Finally, synthesize the ostree commit by walking the composefs tree,
reading metadata, computing SELinux labels, computing the ostree checksum,
and
FICLONEing into the ostree bare repo (Stage 3).
§Long-term: Global composefs store
The ultimate planned state (the “composefs-as-storage” plan) is to have podman’s
composefs backend natively write objects to /sysroot/composefs directly, bypassing
even containers-storage. This would mean flatpak, podman, and bootc all share exactly
one global pool of content-addressed, deduplicated files.
§Why composefs in the middle
The old unified storage path (containers-storage → skopeo tar → ostree)
serialized layers twice. composefs-ctl’s ZeroCopy pull mode instead walks
the overlay diff/ directories and FICLONEs each file into the composefs
object store keyed by SHA-512 fsverity digest — no tar involved.
See container-libs#144.
§Why reflink and not hardlink between composefs and ostree
composefs is content-addressed by SHA-512 of raw bytes: two paths with
identical content share one composefs inode. ostree bare mode stores
uid/gid/mode/xattrs including security.selinux on each inode. Two files
with the same bytes but different SELinux labels produce different ostree
checksums but share one composefs object. One inode can hold only one
security.selinux value, so hardlinking would silently corrupt labels.
Reflink gives each ostree object its own inode while sharing disk extents.
§Reflink probe
The reflink probe is performed lazily and cached. It creates
two anonymous temporary files (via O_TMPFILE, no
cleanup needed), writes one byte to the source, and attempts
ioctl(FICLONE). Returns true on success, false on EOPNOTSUPP or
EXDEV. The probe directory is composefs/objects if it already exists,
otherwise the physical root itself.
§OSTree
The default backend for the bootable container store; this
lives in /ostree in the physical root.
§containers-storage:
Later, bootc gained support for Logically Bound Images.
On ostree systems this is a containers-storage: instance that
lives in /ostree/bootc/storage. On composefs systems the
physical location is /composefs/bootc/storage with a compat
symlink at ostree/bootc -> ../composefs/bootc.
§composefs
This lives in /composefs in the physical root.
Structs§
- Booted
Composefs - Represents a composefs-based boot environment
- Booted
Ostree - Represents an ostree-based boot environment
- Booted
Storage 🔒 - Storage accessor for a booted system.
- Cached
Image 🔒Status - Cached image status data used for optimization.
- Storage 🔒
- A reference to a physical filesystem root, plus accessors for the different types of container storage.
Enums§
- Booted
Storage 🔒Kind - A system can boot via either ostree or composefs; this enum allows code to handle both cases while maintaining type safety.
- Environment 🔒
- Discriminated union representing the boot storage backend.
Constants§
- BOOTC_
ROOT 🔒 - The path to the bootc root directory, relative to the physical
system root. On ostree systems this is a real directory; on composefs
systems it is a symlink to
../composefs/bootc(seeensure_composefs_bootc_link). - COMPOSEFS
- The toplevel composefs directory path
- COMPOSEFS_
BOOTC_ 🔒ROOT - The “real” bootc root for composefs-native systems, relative to the physical system root.
- COMPOSEFS_
MODE 🔒 - The mode for the composefs directory; this is intentionally restrictive to avoid leaking information.
- SYSROOT
- Path to the physical root
Functions§
- ensure_
composefs_ 🔒bootc_ link - On a composefs install the containers-storage lives under
composefs/bootc/storage. To keep the rest of the code (and the/usr/lib/bootc/storagesymlink which points throughostree/bootc) working, we create: - ensure_
composefs_ 🔒dir - Ensure the composefs directory exists in the given physical root with the correct permissions (mode 0700).
- get_
physical_ 🔒root_ and_ run - Open the physical root (/sysroot) and /run directories for a booted system.