This page is meant to serve as an introduction to boot environments, primarily architected as expected by bectl(8)/libbe(3). The target audience is generally system administrators with pre-existing setups that are not currently operable with bectl(8), but some details are mixed-in for audiences that perhaps don't have as much experience and wish to understand how boot environments work for further manipulation. beadm(1) will also work with such layouts, as the below generally reflects project defaults.
The bare minimum required for bectl(8) to operate on your pool is a common-root dataset that all root datasets will be grouped under, e.g.
zroot zroot/ROOT zroot/ROOT/default
The name of the organizational dataset ("BE root") doesn't matter; in this example, we're using "ROOT" to match the default layout created by the installer (hereby referred to as "the default layout"). zroot/ROOT/default is one boot environment (i.e. root dataset), and will show up in bectl list as default, based on the dataset name.
For boot environment dataset properties (i.e. zroot/ROOT/default properties in the above example), you should also make sure that canmount is set to noauto. It is also a good idea to set mountpoint to none, though this is not strictly required. canmount=noauto prevents BEs from getting auto-mounted if you're using the zfs rc script, and clobbering mountpoint is a good idea to ensure that you don't accidentally mount it over your current root filesystem.
While already restructuring your pool, consider what you expect to be included in a boot environment and make sure your layout's structured accordingly. The default layout will exclude these paths from the boot environment by default:
/tmp /usr/home /usr/ports /usr/src /var/audit /var/crash /var/log /var/mail /var/tmp
Any path not listed should be assumed to be under the influence of the boot environment. When examining datasets, note that any dataset with a mountpoint and canmount=off (as seen by zfs get) will be included in the parent dataset, or the BE if the entire path from the dataset in question up to the top-level zroot is set to canmount=off.
Setting Boot Dataset
In order for boot environments to be effective, you must let the bootfs zpool property control which dataset gets mounted as the root. Particularly, /etc/fstab must be purged of any / mount, and /boot/loader.conf must not be setting vfs.root.mountfrom directly.
$ zpool get bootfs zroot NAME PROPERTY VALUE SOURCE zroot bootfs zroot/ROOT/default local $ zfs get all zroot/ROOT/default | grep "local\|NAME" NAME PROPERTY VALUE SOURCE zroot/ROOT/default mountpoint / local zroot/ROOT/default readonly off local zroot/ROOT/default canmount noauto local $ bectl list BE Active Mountpoint Space Created default NR / 21.6G 2020-01-15 14:55 # bectl create test $ bectl list BE Active Mountpoint Space Created default NR / 21.6G 2020-01-15 14:55 test - - 8K 2020-01-21 22:19 # bectl activate test Successfully activated boot environment test $ bectl list BE Active Mountpoint Space Created default N / 1.27M 2020-01-15 14:55 test R - 21.6G 2020-01-21 22:19 # shutdown -r now $ bectl list BE Active Mountpoint Space Created default - - 1.27M 2020-01-15 14:55 test NR / 21.6G 2020-01-21 22:19
Restructuring your pool and moving to using the bootfs zpool property to let loader determine your root dataset can look/feel/seem/be a risky operation. Keep in mind the following, as you familiarize yourself with the process:
zpool checkpoint is your friend.
- It is always recommended to have rescue media on-hand in case of issues so that you can rollback to the aforementioned checkpoint.
If loader for some reason fails to determine the proper dataset to use as the root dataset, you should be able to drop to the loader prompt and set vfs.root.mountfrom to your root dataset (in the form zfs:zroot/ROOT/default) to get the system to userland for correction.