Skip to content

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

@cgwalters

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions