Skip to content

Unified storage: Tracker for ostree <-> composefs reflinking #2247

Description

@cgwalters

We were having a chat about large PRs (esp LLM generated), and after some (internal team) discussion I think a general best practice should really be for us to have a tracker issue where we come to consensus on design first.

Here's one for #2205 that proposes the rough shape.

Related: #20, #1190,
containers/container-libs#144.

Core idea: On filesystems with reflinks, we can share disk extents between
disparate storage systems easily.

Goal 1: set-unified composefs (ostree systems only)

On ostree-backed systems, replace the pull pipeline with one that pulls into
composefs, and from there into ostree via reflinks:

composefs OCI repo  →(FICLONE)→  ostree bare repo

The actual "fetch from registry" code still goes through containers-image-proxy.
bootc upgrade triggers the re-pull; a reboot activates it. Until then
bootc status shows Storage: ostree-composefs-bound.

On a native composefs system set-unified composefs is a no-op with an
explanatory message — the composefs↔ostree binding is intrinsic there.

Goal 2: set-unified full (both system types)

Uses podman pull to write directly into containers-storage, then reflinks from
there into composefs. On ostree systems a further reflink goes into the ostree repo:

containers-storage  →(FICLONE)→  composefs OCI repo  →(FICLONE)→  ostree bare repo

This makes the booted image immediately visible to podman run and backfills
rollback and staged images. The unified flag is written only after everything
succeeds, so a failure leaves the system unmarked rather than half-migrated.

Supporting interface

bootc internals fsck images [--repair]

Checks that every composefs-tagged image is present in containers-storage and referenced
by a live bootloader entry, emitting a structured report (human or --json). --repair
fixes gaps by re-importing from the composefs repo. This covers the "make it right" case
too; bootc image sync duplicates this and will be removed.

Install config: [install.storage] unified

[install.storage]
unified = "enabled-with-copy"   # recommended: byte-copy fallback on ext4
# unified = "enabled"           # hard-fail if no reflinks
# unified = "disabled"          # default

Lets a bootc image opt in at build time without CLI flags.

bootc status storage field

Storage    unified (enabled-with-copy)   # fully active (both system types)
Storage    ostree-composefs-bound        # ostree only: binding set, upgrade+reboot needed

Native composefs systems show no Storage: line until set-unified full completes.

Longer-term

Once stable, the next step is to have podman's composefs backend write directly into
/sysroot/composefs, eliminating containers-storage as a separate pool and giving
flatpak, podman, and bootc a single global deduplicated object store. Out of scope here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions