Prefer ZFS property org.zfsbootmenu:commandline for command-line args

This commit is contained in:
Andrew J. Hesford 2020-05-11 10:21:36 -04:00
parent 49e4dabffe
commit eb2c00ff5c
3 changed files with 23 additions and 17 deletions

View File

@ -105,7 +105,7 @@ kexec_kernel() {
emergency_shell "unable to mount ${fs}"
fi
cli_args="$( find_kernel_args "${mnt}" )"
cli_args="$( find_kernel_args "${fs}" "${mnt}" )"
# restore kernel log level just before we kexec
echo "${printk}" > /proc/sys/kernel/printk
@ -246,7 +246,7 @@ find_be_kernels() {
def_kernel_file="${mnt/mnt/default_kernel}"
echo "${def_version}" > "${def_kernel_file}"
def_args="$( find_kernel_args "${mnt}" )"
def_args="$( find_kernel_args "${fs}" "${mnt}" )"
def_args_file="${mnt/mnt/default_args}"
echo "${def_args}" > "${def_args_file}"
@ -283,19 +283,26 @@ select_kernel() {
}
find_kernel_args() {
local zfsbe
zfsbe="${1}"
local selected_args
local zfsbe_mnt zfsbe_fs zfsbe_args
zfsbe_fs="${1}"
zfsbe_mnt="${2}"
if [ -f "${BASE}/default_args" ]
then
if [ -f "${BASE}/default_args" ]; then
cat "${BASE}/default_args"
return
fi
if [ -f "${zfsbe}/etc/default/grub" ]; then
if [ -n "${zfsbe_fs}" ]; then
zfsbe_args="$( zfs get -H -o value org.zfsbootmenu:commandline "${zfsbe_fs}" )"
if [ "${zfsbe_args}" != "-" ]; then
echo "${zfsbe_args}"
return
fi
fi
if [ -n "${zfsbe_mnt}" -a -f "${zfsbe_mnt}/etc/default/grub" ]; then
echo "$(
. "${zfsbe}/etc/default/grub" ;
. "${zfsbe_mnt}/etc/default/grub" ;
echo "${GRUB_CMDLINE_LINUX_DEFAULT}"
)"
return

View File

@ -16,7 +16,7 @@ zfsbootmenu is implemented as a Dracut module to provide an experience similar t
* If needed, prompt for encryption passphrases
* Once the count down has been reached for the bootfs-selected environment, prompt for the encryption passphrase if needed
* Mount the filesystem and find the highest-numbered kernel in /boot in the boot environment.
* Load the kernel, initramfs and the kernel command line defined in `/etc/default/grub` into memory via kexec
* Load the kernel, initramfs and the kernel command line defined in the `org.zfsbootmenu:commandline` property (or, as a fallback, `/etc/default/grub`) into memory via kexec
* Unmount all ZFS filesystems
* Boot the final kernel and initramfs
@ -54,14 +54,15 @@ On start, ZFS Boot Menu will find the highest versioned kernel in `zroot/ROOT/vo
# Installation
In the boot environment, the file `/etc/default/grub` will need to be created with the variable `GRUB_CMDLINE_LINUX_DEFAULT` defined. These are the kernel arguments passed to the kernel in your boot environment. Do not set any `root=` or any other pool-related options here. This value will be filled in when a boot environment is selected.
Kernel command-line arguments should be set by setting the ZFS property `org.zfsbootmenu:commandline` on each boot environment. If the property is not defined for a boot environment or its parents, command-line arguments will be taken from the `GRUB_CMDLINE_LINUX_DEFAULT` variable in the file `/etc/default/grub` of the boot environment if the file exist and the variable is defined. Do not set any `root=` or any other pool-related options in the kernel command line; these will be filled in automatically when a boot environment is selected.
For example, I have the following set:
For example, I have the following command-line arguments set on my boot environment:
```
GRUB_CMDLINE_LINUX_DEFAULT="zfs.zfs_arc_max=8589934592 elevator=noop"
zfs.zfs_arc_max=8589934592 elevator=noop
```
Because ZFS properties are inherited by default, it is possible to set the `org.zfsbootmenu:commandline` property on a common parent to apply the same arguments to multiple environments. Setting the property locally on individual boot environments will override the common defaults.
## EFI
@ -237,8 +238,6 @@ It's critical that you do not put this key file into the ZFS Boot Menu initramfs
# Limitations
Currently, the kernel command line for the boot environment is read from `/etc/default/grub`. I'd like to support multiple locations determined by probing the OS installed in the boot environment.
When building a kernel command line to pass to the kexec'd kernel, the command line generated is always created for Dracut's ZFS module. Again, this will need to be modified based on the detected OS in the boot environment.
Both of the above issues are readily resolved by hopefully reading /etc/os-release from the boot environment and acting based on that.

View File

@ -128,9 +128,9 @@ xbps-reconfigure -f linux5.4
```
# Install and configure ZFSBootMenu
* Create /etc/default/grub . This is read by `ZFSBootMenu` to know what kernel command line arguments are needed to boot the final kernel.
* Assign command-line arguments to be used when booting the final kernel. Because ZFS properties are inherited, assign the common properties to the `ROOT` dataset so all children will inherit common arguments by default.
```
echo "GRUB_CMDLINE_LINUX_DEFAULT=\"spl_hostid=$( hostid ) ro quiet\"" > /etc/default/grub
zfs set org.zfsbootmenu:commandline="spl_hostid=$( hostid ) ro quiet" zpool/ROOT
```
* Create an EFI partition on `/dev/sdb`