Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/configuration-directory.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ passwd:

Elemental does not enforce or prefer any specific Butane variant.

Check [Filesystem Modes](./filesystem-modes.md) for more information on the filesystem layout and which paths are writable.
Check [Filesystem Modes](filesystem.md/#filesystem-modes) for more information on the filesystem layout and which paths are writable.

Check [Elemental and Ignition Integration](./ignition-integration.md) for further details about Ignition being used in the scope of Elemental.

Expand Down Expand Up @@ -355,6 +355,6 @@ Finally, if any of the provided scripts or files is needed beyond the firstboot
* `files` - If present, all the files, directories, and subdirectories in this directory will be available at firstboot on the booted system.

Note that attempting to write to read-only directories (e.g., `/usr`) from a custom script will fail.
Check [Filesystem Modes](./filesystem-modes.md) for more information on the filesystem layout and which paths are writable.
Check [Filesystem Modes](filesystem.md#filesystem-modes) for more information on the filesystem layout and which paths are writable.

It is crucial to perform cleanup (unmounting) in every script that involves mounting a specific path.
17 changes: 0 additions & 17 deletions docs/filesystem-modes.md

This file was deleted.

142 changes: 142 additions & 0 deletions docs/filesystem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Filesystem Layout and Data Persistence

This document explains how the filesystem and partition layout works in Elemental 3 systems and how data persists across
updates.

## Filesystem Modes

| Path | Initramfs | Booted System |
|--------------|-----------|---------------|
| `/etc` | RW | RW |
| `/var` | RW | RW |
| `/root` | RW | RW |
| `/run` | RW | RW |
| `/tmp` | RW | RW |
| `/home` | RO | RW |
| `/opt` | RO | RW |
| `/srv` | RO | RW |
| `/usr` | RO* | RO |
| `/usr/local` | RO | RW |

\* The `/usr` filesystem is permanently mounted as Read-Only (RO) by design. All other filesystems listed as RO are
unavailable during initramfs and can be optionally mounted as RW, if necessary, for Ignition (via Butane syntax) or for
custom scripts execution on firstboot.

## Partition Layout

The default deployment creates the following partition structure:

| Partition | Label | Filesystem | Mount Point | Size | Required | Purpose |
|-----------|------------|------------|-------------|---------------|----------|--------------------------------|
| EFI | `EFI` | vfat | `/boot/efi` | Fixed | Yes | Bootloader |
| Recovery | `RECOVERY` | ext4 | N / A | Fixed | Yes | Install and restore operations |
| System | `SYSTEM` | btrfs | `/` | All remaining | Yes | System and user data |
| Config | `CONFIG` | ext4 | N / A | Variable | No | Firstboot configuration |

## Btrfs Subvolume Layout

The system partition uses btrfs with the following subvolume structure:

- **Root**: Mounted read-only (`ro=vfs`), contains the immutable OS image
- **RW Volumes**: Separate btrfs subvolumes for mutable data

| Path | Snapshotted | NoCopyOnWrite | Mounted in Initramfs |
|--------------|-------------|---------------|----------------------|
| `/etc` | Yes | No | Yes |
| `/var` | No | Yes | Yes |
| `/root` | No | No | Yes |
| `/home` | No | No | No |
| `/opt` | No | No | No |
| `/srv` | No | No | No |
| `/usr/local` | No | No | No |

### Subvolume Properties

- **Snapshotted** (`/etc`): This subvolume is included in btrfs snapshots, allowing configuration to be versioned
alongside the OS.
- **NoCopyOnWrite** (`/var`): Disables copy-on-write for this subvolume, which is recommended for directories containing
databases, logs, and container storage.
- **Mounted in Initramfs** (`x-initrd.mount`): These subvolumes are mounted early in the boot process.

## How Upgrades Work

OS upgrades use a btrfs snapper snapshots layout:

1. The root filesystem is an immutable snapshot
2. `/etc` is a nested and snapshotted subvolume
3. Mutable parts of the system (`/var`, `/root`, `/home`, `/opt`, `/srv`, `/usr/local`) are shared btrfs subvolumes
4. A new boot entry is generated for each snapshot
5. Bootloader, kernel, and initrd are installed to the ESP

### Upgrade Process

During an upgrade:

1. A new transaction (snapshot) is initialized
2. The new OS image content is synced to the transaction
3. RW volumes are merged into the new snapshot
4. The fstab is updated for the new snapshot
5. The snapshot is locked (made immutable)
6. A new boot entry is created pointing to the new snapshot
7. The transaction is committed

If an upgrade fails at any point, the transaction is rolled back and the system remains on the previous snapshot.

## Data Persistence Across Updates

Because RW volumes are **shared btrfs subvolumes** (not part of the root snapshot), data in these locations persists
across updates:

| Directory | Persists Across Updates | Notes |
|--------------|-------------------------|---------------------------------------------|
| `/etc` | Yes (merged) | Snapshotted; changes merged to new snapshot |
| `/var` | Yes | Shared subvolume; not affected by updates |
| `/root` | Yes | Shared subvolume; not affected by updates |
| `/home` | Yes | Shared subvolume; not affected by updates |
| `/opt` | Yes | Shared subvolume; not affected by updates |
| `/srv` | Yes | Shared subvolume; not affected by updates |
| `/usr/local` | Yes | Shared subvolume; not affected by updates |
| `/usr` | No | Part of immutable root; replaced on update |

### Example: `/var/lib/rancher`

Container and Kubernetes data stored in `/var/lib/rancher` persists because `/var` is a shared btrfs subvolume with
copy-on-write disabled. When an upgrade occurs:

1. A new root snapshot is created from the new OS image
2. The existing `/var` subvolume (containing `/var/lib/rancher`) is mounted into the new snapshot
3. After reboot, the same `/var` data is accessible from the new OS

## The `/etc` Directory

The `/etc` directory is handled specially:

- It is a **nested subvolume** within the root
- It is **snapshotted** along with the root filesystem
- During upgrades, changes are **merged** into the new snapshot

This means:

- System configuration is versioned with OS snapshots
- Local configuration changes persist across updates via the merge process
- Rolling back the OS also rolls back `/etc` to match that OS version

## Configuring Additional Disks and Partitions

Since Elemental 3 supports Butane input, additional disks and partitions can be configured via Ignition on firstboot.
This allows you to:

- Add additional data disks
- Create custom partitions for specific workloads
- Configure filesystems and mount points beyond the default layout

This configuration is processed during the firstboot phase before the system becomes operational.

## Rollback

Because each upgrade creates a new btrfs snapshot with its own boot entry:

- Previous system states remain available
- The bootloader can boot any available snapshot
- Rolling back means selecting a previous snapshot to boot
- Shared subvolumes (`/var`, `/home`, etc.) are **not** rolled back—they always contain the latest data