-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
# Boot Environments and You: A Primer | ||
|
||
ZFSBootMenu adapts to a wide range of system configurations by making as few | ||
assumptions about filesystem layout as possible. When looking for Linux kernels | ||
to boot, the *only* requirements are that | ||
|
||
1. At least one ZFS pool be importable, | ||
|
||
2. At least one ZFS filesystem on any importable pool have *either* the | ||
properties | ||
|
||
- `mountpoint=/` and **not** `org.zfsbootmenu:active=off`, or | ||
- `mountpoint=legacy` and `org.zfsbootmenu:active=on` | ||
|
||
For filesystems with `mountpoint=/`, the property `org.zfsbootmenu:active` | ||
provides a means to opt **out** of scanning this filesystem for kernels. For | ||
filesystems with `mountpoint=legacy`, `org.zfsbootmenu:active` provides a | ||
means to opt **in** to scanning this filesystem for kernels. Filesystems | ||
that do not satisfy these conditions are *never* touched by ZFSBootMenu. | ||
|
||
3. At least one of the scanned ZFS filesystems contains a `/boot` subdirectory | ||
that contains at least one paired kernel and initramfs. | ||
|
||
ZFSBootMenu will present a list of all ZFS filesystems that satisfy these | ||
constraints. Additionally, if any filesystem provides more than one paired | ||
kernel and initramfs, it is possible to choose which kernel will be loaded | ||
should that filesystem be selected for booting. (It is, of course, possible to | ||
automate the selection of a filesystem and kernel so that ZFSBootMenu can boot | ||
a system without user intervention.) | ||
|
||
## Finding Kernels | ||
|
||
Although it may be possible to compile a kernel with built-in ZFS support that | ||
would be capable of booting from a ZFS root without an initramfs, this is not | ||
standard practice and would require considerable expertise. Consequently, | ||
ZFSBootMenu requires that a kernel be matched with an initramfs image before it | ||
will attempt to boot the kernel. ZFSBootMenu tries hard to identify matched | ||
pairs of kernels and initramfs images as installed by a wide range of Linux | ||
distributions. As noted above, kernel and initramfs pairs are required to | ||
reside in a `/boot` subdirectory of ZFS filesystem scanned by ZFSBootMenu. The | ||
kernel must begin with one of the following prefixes: | ||
|
||
- vmlinuz | ||
- vmlinux | ||
- linux | ||
- linuz | ||
- kernel | ||
|
||
After the prefix, the name of a kernel may be optionally followed by a hyphen | ||
(`-`) and an arbitrary string, which ZFSBootMenu considers a *version* | ||
identifier. | ||
|
||
ZFSBootMenu attempts to match one of several possible initramfs names for each | ||
kernel it identifies. Broadly, an initramfs is paired with a kernel when its | ||
name matches one of four forms: | ||
|
||
- `initramfs-${label}${extension}` | ||
- `initramfs${extension}-${label}` | ||
- `initrd-${label}${extension}` | ||
- `initrd${extension}-${label}` | ||
|
||
The value of `${extension}` may be empty or the text `.img` and may | ||
additionally be followed by one of several common compression suffixes: `gz`, | ||
`bz2`, `xz`, `lzma`, `lz4`, `lzo`, or `zstd`. The value of `${label}` is either | ||
|
||
- The full name of the kernel file with path components removed, *e.g.*, | ||
`vmlinuz-5.15.9_1` or `linux-lts`; or | ||
|
||
- The version part of a kernel file (if the kernel contains a version part): | ||
|
||
- For `vmlinuz-5.15.9_1`, this is `5.15.9_1`; | ||
- For `linux-lts`, this is `lts`. | ||
|
||
ZFSBootMenu prefers the more specific label (the full kernel name) when it | ||
exists. | ||
|
||
## Boot Environments | ||
|
||
Internally, ZFSBootMenu does not understand the concept of a boot environment. | ||
When it finds a suitable kernel and initramfs pair, it will load them and | ||
invoke `kexec` to jump into the chosen kernel. In fact, ZFSBootMenu doesn't | ||
even require that a "root" filesystem be the real root that a kernel and | ||
initramfs will mount. It would be possible, for example, to mount a ZFS | ||
filesystem at `/kernels` and install kernels and matching initramfs images to | ||
the `/kernels/boot` subdirectory. As long as the `/kernels` filesystem has a | ||
`mountpoint` property (along with `org.zfsbootmenu:active` if needed), | ||
ZFSBootMenu will identify the kernels even if the filesystem at `/kernels` | ||
contains nothing besides the `boot` subdirectory. | ||
|
||
Although ZFSBootMenu ensures maximum flexibility by imposing minimal | ||
assumptions on filesystem layout, not all layouts are equally sensible. For | ||
straightforward maintenance and administration, it is recommended that each | ||
Linux operating system that you wish to boot be stored as a self-contained boot | ||
environment. Conceptually, the ZFSBootMenu team recommends that a *boot | ||
environment* consist of a **single** ZFS filesystem that contains all of the | ||
*coupled* system state for that environment. Coupled system state embodies the | ||
executables, configuration and other files that are critical to proper system | ||
operation and must generally be kept consistent at all times. In most systems, | ||
coupled system state tends to be maintained by a package manager. The package | ||
manager might install programs in `/usr/bin`, configuration in `/etc` and other | ||
files throughout the filesystem. The package manager itself probably maintains | ||
a database of installed packages somewhere in `/var`. | ||
|
||
ZFSBootMenu is certainly capable of booting an environment that mounts separate | ||
filesystems at `/` and other paths like `/etc`, `/usr` or `/var`. ZFSBootMenu | ||
never needs to understand these details because either the initramfs or root | ||
filesystem will assume responsibility for mounting all filesystems it needs. | ||
However, a key benefit of boot environments is *atomicity*. In general, it is | ||
bad to allow the contents of `/usr` to become inconsistent with the package | ||
manager database on `/var`. Configuration files in `/etc` can often be tied to | ||
specific versions of software, so they should be kept consistent as well. When | ||
these directories live on different filesystems, ensuring consistency becomes | ||
much more challenging. | ||
|
||
For example, suppose that a software update has gone wrong and a program has | ||
been overwritten by a corrupt or buggy version. With ZFS snapshots, `zfs | ||
rollback` is sufficient to restore functionality. However, when `/usr` and | ||
`/var` reside on different filesystems, both must be rolled back to the same | ||
point in time. When the filesystems are on different snapshot schedules (or | ||
there is some delay between snapshotting one after the other), deciding which | ||
snapshots represent consistent state may not be a trivial task. | ||
|
||
To some extent, this could be remedied with a recursive snapshot scheme that | ||
provides uniform nomenclature for consistent snapshots across multiple | ||
filesystems. However, ZFSBootMenu strives to provide simple management and | ||
recovery interfaces for all boot environments on a disk, and | ||
|
||
1. Providing a convenient interface for rollback of a boot environment becomes | ||
substantially harder if ZFSBootMenu has to identify snapshots across | ||
multiple filesystems that might compose an environment, | ||
|
||
2. Even identifying which filesystems should be considered part of an | ||
environment is not always a trivial task, and | ||
|
||
3. The problem gets significantly more complex when a system holds multiple | ||
boot environments that might each have multiple sub-mounts. | ||
|
||
Keeping the entire operating system contents on a single filesystem avoids | ||
these issues entirely. For the purposes of rolling back snapshots or cloning | ||
one boot environment to another, ZFSBootMenu expects that the environment | ||
consists of exactly one filesystem, so that a snapshot of the filesystem always | ||
presents a consistent view of system state, and rollbacks or clones behave as | ||
expected without the need for manual correlation. If you wish to maintain more | ||
complicated setups, you can always manually manage snapshot rollbacks or clone | ||
operations from the recovery shell that ZFSBootMenu provides. | ||
|
||
Note that "coupled system state" does not include "user data" that should | ||
generally survive things like snapshot rollbacks. Recovering from a bad system | ||
update is generally not expected to discard user email or recent database | ||
transactions. For this reason, directories like `/home`, `/var/mail` and others | ||
that hold important data *not* managed by the system **should** reside on | ||
separate filesystems. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters