====== Boot Environments ======
===== Introduction =====
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. [[https://www.freshports.org/sysutils/beadm|beadm(1)]] will also work with such layouts, as the below generally reflects project defaults.
===== Pool Layout/Design =====
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
===== Recovery =====
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.
===== See Also =====
* [[https://www.freshports.org/sysutils/beadm|sysutils/beadm]]
* [[https://is.gd/BECTL|ZFS Boot Environments Reloaded]]
* [[https://man.freebsd.org/cgi/man.cgi?query=bectl&sektion=8&manpath=freebsd-release|bectl(8) manpage]]
----
{{tag>Zfs}}