Filesystem Layout

cache22 follows the bootc / ostree filesystem layout with a few cache22-specific additions.

Top-level mounts

After boot, the visible mounts include:

Mount Source Purpose
/ The booted deploy directory (read-only btrfs). The OS image.
/sysroot The btrfs root subvolume containing /ostree. The physical root partition.
/etc Writable: a persistent overlay (composefs) or bind-on-self (legacy) over the per-deploy etc. Per-machine configuration.
/var Per-stateroot /sysroot/ostree/deploy/<state>/var (read-write). Persistent runtime state.
/home btrfs subvolume /home (read-write). User home directories.
/boot UEFI: same partition as /, mounted separately. BIOS: dedicated cache22-boot ext4 partition. BLS entries and kernel/initramfs files (GRUB modules + grub.cfg on BIOS).
/efi The ESP (FAT32). UEFI only. sd-boot, UKIs, EFI variables.

The root mount is read-only by design. Writes to /usr are blocked unless bootc usroverlay is active (see usroverlay).

/etc handling

/etc is writable and persistent. Its content is the result of an ostree 3-way merge performed at deploy time, combining:

  1. The previous deploy’s /usr/etc (image defaults at last upgrade time).
  2. The current /etc (user state including their changes).
  3. The new deploy’s /usr/etc (image defaults in the new image).

User changes carry forward. Image-shipped changes apply where the user has not customized. Conflicting changes typically prefer the user’s version.

This merge happens at bootc upgrade time, not at boot time. At boot, /etc exposes the merged result.

How it is mounted depends on the backend. Under composefs, ostree-prepare-root sets /etc up as a writable overlay (lower = the image /usr/etc defaults, upper = the per-deploy etc). Under the legacy backend it is a writable bind-mount; the 50-cache22-etc-rw.conf drop-in re-establishes it via ensure-etc-writable as a safety net if the bind is missing.

/var per stateroot

/var lives at /sysroot/ostree/deploy/<state>/var. It is per-stateroot, not per-deploy. All deploys in the same stateroot share the same /var.

cache22 uses a single stateroot named default. All cache22 deploys (current, staged, rollback) share /var.

Several top-level paths are symlinks into /var:

Symlink Target
/home /var/home
/root /var/roothome
/srv /var/srv
/usr/local /var/usrlocal
/opt /var/opt

This is the Fedora atomic pattern. User-installed binaries in /usr/local/bin, third-party app installers writing to /opt, etc., all persist across upgrades because they live under /var.

ESP layout

/efi/
  EFI/
    BOOT/
      BOOTX64.EFI               # Fallback bootloader (signed sd-boot copy).
    systemd/
      systemd-bootx64.efi       # Primary bootloader (signed by per-machine SB key).
    Linux/
      cache22-<csum>.efi        # Per-deploy signed UKI.
      cache22-<csum>.efi        # ...
  loader/
    loader.conf                 # sd-boot config.
    keys/
      auto/
        PK.auth                 # PK auto-enroll file.
        KEK.auth                # KEK auto-enroll file.
        db.auth                 # db auto-enroll file.
        microsoft-uefi-ca.auth  # Microsoft DB key auto-enroll file.

The Microsoft DB keys are bundled at install time so dual-boot Windows and signed-shim distros continue to work.

Per-machine state

Files in /var/lib/cache22/:

Path Content
/var/lib/cache22/sbkey/keys/PK/PK.{key,pem,der} Platform Key.
/var/lib/cache22/sbkey/keys/KEK/KEK.{key,pem,der} Key Exchange Key.
/var/lib/cache22/sbkey/keys/db/db.{key,pem,der} Secure Boot signing key.
/var/lib/cache22/sbkey/tpm-pcr11.{key,pub} TPM PCR-policy key.
/var/lib/cache22/sbkey/backup-<timestamp>/ Backup of previous keys after rotate-keys.
/var/lib/cache22/healthcheck/fail-counter Consecutive failed-boot counter (single integer).

All under /var/lib/cache22/ is mode 0700 root, and its contents are mode 0600 root. The directory is on the encrypted root, so at-rest the keys are protected by LUKS.

Files in /etc/cache22/:

Path Content
/etc/cache22/extra-cmdline Per-machine kargs baked into UKIs.
/etc/cache22/reboot.conf cache22-reboot preferences (KERNEL_CHANGE_STRATEGY).
/etc/cache22/autoupdate.conf cache22-autoupdate config (APP_UPDATES).
/etc/cache22/autoreboot.conf cache22-autoreboot config (WINDOW, ALLOW_ACTIVE_SESSIONS).
/etc/cache22/healthcheck.d/required.d/* User-defined health-check scripts.

These are managed by their respective cache22-* tools, but can be edited manually.

/sysroot

/sysroot is the btrfs root subvolume. It contains:

/sysroot/
  ostree/
    repo/                                # Object store (deduplicated content).
    deploy/
      default/                           # Stateroot.
        deploy/
          <csum>.0/                      # A deploy directory (booted, staged, or rollback).
            usr/                         # The image's /usr.
            etc/                         # The merged etc.
            ...
          <csum>.1/                      # Another deploy.
        var/                             # Per-stateroot var (shared by all deploys).
    boot.0/                              # BLS-related symlinks.
    boot.1/
    ...
  boot/                                  # /boot bind source.
  home/                                  # /home subvolume.

/sysroot is normally mounted read-only. To inspect deploys directly, read from /sysroot/ostree/deploy/... (root permissions required).

Mount options

The btrfs root mount uses these options:

noatime,compress=zstd:1,discard=async,space_cache=v2,subvolid=<id>,subvol=/root

compress=zstd:1 provides ~30% compression with negligible CPU cost. discard=async issues TRIM commands without blocking writes. These options are baked into /etc/cache22/extra-cmdline as rootflags=....

To change mount options, edit /etc/cache22/extra-cmdline and let the path watcher trigger a UKI rebuild. The new options take effect on next boot.

See also