zfsbootmenu/docs/guides/general/bootenvs-and-you.rst

123 lines
8.0 KiB
ReStructuredText

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.