|
| 1 | +# Boot Environments and You: A Primer |
| 2 | + |
| 3 | +ZFSBootMenu adapts to a wide range of system configurations by making as few |
| 4 | +assumptions about filesystem layout as possible. When looking for Linux kernels |
| 5 | +to boot, the *only* requirements are that |
| 6 | + |
| 7 | +1. At least one ZFS pool be importable, |
| 8 | + |
| 9 | +2. At least one ZFS filesystem on any importable pool have *either* the |
| 10 | + properties |
| 11 | + |
| 12 | + - `mountpoint=/` and **not** `org.zfsbootmenu:active=off`, or |
| 13 | + - `mountpoint=legacy` and `org.zfsbootmenu:active=on` |
| 14 | + |
| 15 | + For filesystems with `mountpoint=/`, the property `org.zfsbootmenu:active` |
| 16 | + provides a means to opt **out** of scanning this filesystem for kernels. For |
| 17 | + filesystems with `mountpoint=legacy`, `org.zfsbootmenu:active` provides a |
| 18 | + means to opt **in** to scanning this filesystem for kernels. Filesystems |
| 19 | + that do not satisfy these conditions are *never* touched by ZFSBootMenu. |
| 20 | + |
| 21 | +3. At least one of the scanned ZFS filesystems contains a `/boot` subdirectory |
| 22 | + that contains at least one paired kernel and initramfs. |
| 23 | + |
| 24 | +ZFSBootMenu will present a list of all ZFS filesystems that satisfy these |
| 25 | +constraints. Additionally, if any filesystem provides more than one paired |
| 26 | +kernel and initramfs, it is possible to choose which kernel will be loaded |
| 27 | +should that filesystem be selected for booting. (It is, of course, possible to |
| 28 | +automate the selection of a filesystem and kernel so that ZFSBootMenu can boot |
| 29 | +a system without user intervention.) |
| 30 | + |
| 31 | +## Finding Kernels |
| 32 | + |
| 33 | +Although it may be possible to compile a kernel with built-in ZFS support that |
| 34 | +would be capable of booting from a ZFS root without an initramfs, this is not |
| 35 | +standard practice and would require considerable expertise. Consequently, |
| 36 | +ZFSBootMenu requires that a kernel be matched with an initramfs image before it |
| 37 | +will attempt to boot the kernel. ZFSBootMenu tries hard to identify matched |
| 38 | +pairs of kernels and initramfs images as installed by a wide range of Linux |
| 39 | +distributions. As noted above, kernel and initramfs pairs are required to |
| 40 | +reside in a `/boot` subdirectory of ZFS filesystem scanned by ZFSBootMenu. The |
| 41 | +kernel must begin with one of the following prefixes: |
| 42 | + |
| 43 | +- vmlinuz |
| 44 | +- vmlinux |
| 45 | +- linux |
| 46 | +- linuz |
| 47 | +- kernel |
| 48 | + |
| 49 | +After the prefix, the name of a kernel may be optionally followed by a hyphen |
| 50 | +(`-`) and an arbitrary string, which ZFSBootMenu considers a *version* |
| 51 | +identifier. |
| 52 | + |
| 53 | +ZFSBootMenu attempts to match one of several possible initramfs names for each |
| 54 | +kernel it identifies. Broadly, an initramfs is paired with a kernel when its |
| 55 | +name matches one of four forms: |
| 56 | + |
| 57 | +- `initramfs-${label}${extension}` |
| 58 | +- `initramfs${extension}-${label}` |
| 59 | +- `initrd-${label}${extension}` |
| 60 | +- `initrd${extension}-${label}` |
| 61 | + |
| 62 | +The value of `${extension}` may be empty or the text `.img` and may |
| 63 | +additionally be followed by one of several common compression suffixes: `gz`, |
| 64 | +`bz2`, `xz`, `lzma`, `lz4`, `lzo`, or `zstd`. The value of `${label}` is either |
| 65 | + |
| 66 | +- The full name of the kernel file with path components removed, *e.g.*, |
| 67 | + `vmlinuz-5.15.9_1` or `linux-lts`; or |
| 68 | + |
| 69 | +- The version part of a kernel file (if the kernel contains a version part): |
| 70 | + |
| 71 | + - For `vmlinuz-5.15.9_1`, this is `5.15.9_1`; |
| 72 | + - For `linux-lts`, this is `lts`. |
| 73 | + |
| 74 | +ZFSBootMenu prefers the more specific label (the full kernel name) when it |
| 75 | +exists. |
| 76 | + |
| 77 | +## Boot Environments |
| 78 | + |
| 79 | +Internally, ZFSBootMenu does not understand the concept of a boot environment. |
| 80 | +When it finds a suitable kernel and initramfs pair, it will load them and |
| 81 | +invoke `kexec` to jump into the chosen kernel. In fact, ZFSBootMenu doesn't |
| 82 | +even require that a "root" filesystem be the real root that a kernel and |
| 83 | +initramfs will mount. It would be possible, for example, to mount a ZFS |
| 84 | +filesystem at `/kernels` and install kernels and matching initramfs images to |
| 85 | +the `/kernels/boot` subdirectory. As long as the `/kernels` filesystem has a |
| 86 | +`mountpoint` property (along with `org.zfsbootmenu:active` if needed), |
| 87 | +ZFSBootMenu will identify the kernels even if the filesystem at `/kernels` |
| 88 | +contains nothing besides the `boot` subdirectory. |
| 89 | + |
| 90 | +Although ZFSBootMenu ensures maximum flexibility by imposing minimal |
| 91 | +assumptions on filesystem layout, not all layouts are equally sensible. For |
| 92 | +straightforward maintenance and administration, it is recommended that each |
| 93 | +Linux operating system that you wish to boot be stored as a self-contained boot |
| 94 | +environment. Conceptually, the ZFSBootMenu team recommends that a *boot |
| 95 | +environment* consist of a **single** ZFS filesystem that contains all of the |
| 96 | +*coupled* system state for that environment. Coupled system state embodies the |
| 97 | +executables, configuration and other files that are critical to proper system |
| 98 | +operation and must generally be kept consistent at all times. In most systems, |
| 99 | +coupled system state tends to be maintained by a package manager. The package |
| 100 | +manager might install programs in `/usr/bin`, configuration in `/etc` and other |
| 101 | +files throughout the filesystem. The package manager itself probably maintains |
| 102 | +a database of installed packages somewhere in `/var`. |
| 103 | + |
| 104 | +ZFSBootMenu is certainly capable of booting an environment that mounts separate |
| 105 | +filesystems at `/` and other paths like `/etc`, `/usr` or `/var`. ZFSBootMenu |
| 106 | +never needs to understand these details because either the initramfs or root |
| 107 | +filesystem will assume responsibility for mounting all filesystems it needs. |
| 108 | +However, a key benefit of boot environments is *atomicity*. In general, it is |
| 109 | +bad to allow the contents of `/usr` to become inconsistent with the package |
| 110 | +manager database on `/var`. Configuration files in `/etc` can often be tied to |
| 111 | +specific versions of software, so they should be kept consistent as well. When |
| 112 | +these directories live on different filesystems, ensuring consistency becomes |
| 113 | +much more challenging. |
| 114 | + |
| 115 | +For example, suppose that a software update has gone wrong and a program has |
| 116 | +been overwritten by a corrupt or buggy version. With ZFS snapshots, `zfs |
| 117 | +rollback` is sufficient to restore functionality. However, when `/usr` and |
| 118 | +`/var` reside on different filesystems, both must be rolled back to the same |
| 119 | +point in time. When the filesystems are on different snapshot schedules (or |
| 120 | +there is some delay between snapshotting one after the other), deciding which |
| 121 | +snapshots represent consistent state may not be a trivial task. |
| 122 | + |
| 123 | +To some extent, this could be remedied with a recursive snapshot scheme that |
| 124 | +provides uniform nomenclature for consistent snapshots across multiple |
| 125 | +filesystems. However, ZFSBootMenu strives to provide simple management and |
| 126 | +recovery interfaces for all boot environments on a disk, and |
| 127 | + |
| 128 | +1. Providing a convenient interface for rollback of a boot environment becomes |
| 129 | + substantially harder if ZFSBootMenu has to identify snapshots across |
| 130 | + multiple filesystems that might compose an environment, |
| 131 | + |
| 132 | +2. Even identifying which filesystems should be considered part of an |
| 133 | + environment is not always a trivial task, and |
| 134 | + |
| 135 | +3. The problem gets significantly more complex when a system holds multiple |
| 136 | + boot environments that might each have multiple sub-mounts. |
| 137 | + |
| 138 | +Keeping the entire operating system contents on a single filesystem avoids |
| 139 | +these issues entirely. For the purposes of rolling back snapshots or cloning |
| 140 | +one boot environment to another, ZFSBootMenu expects that the environment |
| 141 | +consists of exactly one filesystem, so that a snapshot of the filesystem always |
| 142 | +presents a consistent view of system state, and rollbacks or clones behave as |
| 143 | +expected without the need for manual correlation. If you wish to maintain more |
| 144 | +complicated setups, you can always manually manage snapshot rollbacks or clone |
| 145 | +operations from the recovery shell that ZFSBootMenu provides. |
| 146 | + |
| 147 | +Note that "coupled system state" does not include "user data" that should |
| 148 | +generally survive things like snapshot rollbacks. Recovering from a bad system |
| 149 | +update is generally not expected to discard user email or recent database |
| 150 | +transactions. For this reason, directories like `/home`, `/var/mail` and others |
| 151 | +that hold important data *not* managed by the system **should** reside on |
| 152 | +separate filesystems. |
0 commit comments