docs(cpu-software): add Flipper OS storage architecture RFC#361
docs(cpu-software): add Flipper OS storage architecture RFC#361xbizzybone wants to merge 6 commits into
Conversation
This RFC outlines a proposed storage architecture for Flipper OS, focusing on atomic A/B updates, cloneable profiles, and a Debian-based userland. It details the system's state classes, partition layout, atomic update mechanisms, and configuration discipline to ensure integrity and usability.
|
I built a working Phase-0 reference implementation of this RFC and put it up as a public lab, so the storage model isn't just on paper: → https://github.com/xbizzybone/flipper-os-lab It reproduces the whole Phase-0 storage stack on loop-backed disk images on any Linux host (no RK3576 board, no QEMU) — every mechanism is the genuine kernel feature, just on files instead of eMMC:
CI proof: GitHub Actions runs the full 8-step demo on Scope is honest about phase boundaries: A/B + RAUC + MCU watchdog (Phases 1–2) are referenced, not implemented yet — that's the roadmap. Two minor deltas vs. the RFC: the lab's Happy to evolve this toward Phase 1 (QEMU aarch64 + U-Boot A/B slot selection + RAUC bootcount rollback) if useful for the discussion. |
|
We’ve been thinking along similar lines, but without squashfs, which is rather limiting in our context, as it forces a single base image and precludes storage-level data deduplication if more than one are used. Right now we are experimenting with a stack fully based around Btrfs snapshots, which allows multiple base profiles to coexist space-efficiently, with instantaneous cloning/branching via native CoW functionality. We haven’t yet considered the introduction of verity into the chain though (or discussed if it’s vital for our envisaged usage scenarios and target audience) |
|
Really nice work! A couple of things I keep wondering about:
Mainly trying to get my head around the day-2 side: updates, rollback, recovery, not just the layout. |
…ntegrity axis Respond to PR flipperdevices#361 review feedback (alchark, Flipper team): - Add Alternative D (all-Btrfs base with reflink-sharing base subvolumes), crediting the review. It answers Option B's storage-scaling objection via native multi-base CoW dedup/coexistence, at the cost of whole-device verity. - Reframe base integrity as an explicit pluggable axis (dm-verity / fs-verity / Btrfs checksums / signed-update-only) selected by threat model, rather than a fixed squashfs+dm-verity mandate. dm-verity remains the default. - Clarify that RAUC signing (authenticity at update time) is independent of continuous at-rest tamper-evidence (verity's distinct role). - Add unresolved question flipperdevices#4: is whole-device verity vital for the target audience, or does fs-verity/signed-update suffice (squashfs vs all-Btrfs base)? Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@alchark you're right on the substance, and I want to concede it cleanly: a squashfs base is an opaque compressed blob, so it forces a single active base per slot and can't extent-share with a second base — there's no storage-level dedup across bases. The PoC shows exactly that shape: one I'll also own a gap in the RFC's framing. We listed "three options" and rejected full-image-per-profile on storage-scaling grounds ("N × image × 2"), but we never evaluated your design — multiple coexisting Btrfs base subvolumes that reflink-share. That's a distinct fourth point in the space, it answers the same scaling objection without giving up apt or waiting on deb-ostree, and it deserved an explicit weighing rather than silence. So I've gone ahead and added it: the latest revision on this PR now has Alternative D — All-Btrfs base (multiple reflink-sharing base subvolumes), credited to this review. Worth being clear about what we already share: profiles are Btrfs subvolumes today, and the PoC demonstrates the CoW snapshot clone/branch/reset you describe ( The crux is verity, and it's genuinely a fork rather than a disagreement. Classic whole-device dm-verity needs a static read-only hash-tree device and is mutually exclusive with a writable Btrfs-snapshot base — that's exactly why the RFC pushed the base onto squashfs (it also keeps RAUC's A/B slots and the MCU/U-Boot early-boot path simple). What the PoC actually proves here is narrow but concrete: a byte-flipped base image is rejected against its sealed dm-verity root hash in CI. I don't want to overstate it — that's offline image verification, and RAUC signature verification / fs-verity / Btrfs-checksum integrity are not built yet. You're asking the right question — is verity vital for your audience? For a tool whose owner deliberately runs untrusted code with physical access, base verity buys a narrow thing: continuous at-rest tamper-evidence (rootkit persistence, bad flash, bit-rot) plus a hash-pinned rollback target. It's an anti-persistence story, not load-bearing for the profile/clone/reset UX. So in the same revision I also reframed base integrity as an explicit pluggable axis — dm-verity / fs-verity / Btrfs-checksums / none-plus-signed-update — selected by threat model, rather than baking squashfs+dm-verity into the partition layout. dm-verity stays the default; choosing fs-verity or signed-update-only is precisely what unlocks Alternative D. Net: if verity is a hard requirement, squashfs buys it cheaply at the cost of multi-base dedup. If it isn't, your all-Btrfs multi-base stack wins on storage and coexisting-bases UX essentially by construction. I'd love to chase a hybrid — sealed read-only Btrfs base snapshots + fs-verity — so we keep native CoW/branching and an integrity story. To write Alternative D up fairly I'd rather use your real numbers than assume: if you can share the multi-base layout you're experimenting with, and how you're handling atomic A/B update + rollback on a single Btrfs pool (RAUC's discrete-slot model doesn't map cleanly onto one shared pool — I'd expect snapshot-swap orchestration instead), I'll flesh it out with actual tradeoffs. |
|
@Yury-MonZon thanks — these are exactly the day-2 issues the layout has to earn, so let me be precise about what's designed vs. what actually runs today. base_min_version mismatch after a base swap → refused, not migrated or reset. The manifest's Packages per profile & dedup → shared base + deltas, never a full userland per profile. Userland is served read-only from the single immutable base (squashfs + dm-verity) as the OverlayFS lower; each profile's Btrfs subvolume is just the upper, holding only its delta — drop-in config, packages baked at profile build time (the On dedup, to be precise rather than overclaim: there's dedup in exactly one place today — profiles live in a Btrfs pool, so Backup / export → honest split. Profile export is on the roadmap but undesigned — Day-2 overall (updates / rollback / recovery) → designed, not yet demonstrated. Rollback is a U-Boot boot-counter plus a |
Sibling of lab.sh implementing RFC Alternative D (the direction the Flipper team is exploring in flipperdevices/flipperone-docs#361): an immutable base as a Btrfs subvolume sealed with fs-verity instead of squashfs + dm-verity. - altd.sh: base build/derive/list/verify, profile clone/reset, overlay boot with a real ">=" base_min_version guard, anti-drift lint carried over. - Proves multi-base coexistence + CoW dedup (btrfs filesystem du + qgroups): a derived base references the full size but exclusively owns ~the delta — exactly what a single squashfs base cannot do. - Integrity via fs-verity (per-file): sealed files reject in-place writes; base verify re-measures vs sealed digests + offline tamper check. - NOFSV=1 fallback for kernels without CONFIG_FS_VERITY. - CI: .github/workflows/altd.yml runs the full demo on ubuntu-24.04. - README: lab.sh (Option A) vs altd.sh (Alternative D) section. Locally validated end-to-end in Docker (lab.sh with real dm-verity; altd.sh Btrfs dedup/swap/guard/lint with NOFSV=1); fs-verity seal is exercised in CI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
What
Adds a design RFC for Flipper OS storage as a new page under
🐧 Linux (CPU Software).
Why
The Flipper OS notes state the architecture isn't pinned down yet.
This RFC proposes a concrete answer to the core open question: how do
profile overlays stay valid when the A/B base is atomically replaced
underneath them?
Summary of the proposal
per-profile Btrfs overlay (reflink clone/reset), and a separate
/data partition that survives both profile resets and base updates.
rollback backstop.
forbids profiles from shadowing base files (eliminates /etc drift).
Interconnect via a small CRC-checked message.
Includes RFC-2119 wording, prior art (OpenWrt, Android A/B, RAUC,
ostree/Silverblue), drawbacks, unresolved questions, and a phased
implementation plan.
This is a proposal for discussion — feedback and pushback welcome.
The nav entry is registered in archbee.json.