Skip to content

Commit

Permalink
Prefer ZFS property org.zfsbootmenu:commandline for command-line args
Browse files Browse the repository at this point in the history
  • Loading branch information
ahesford committed May 11, 2020
1 parent 49e4dab commit eb2c00f
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
25 changes: 16 additions & 9 deletions 90zfsbootmenu/zfsbootmenu-lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}"

Expand Down Expand Up @@ -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
Expand Down
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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.
4 changes: 2 additions & 2 deletions void-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down

0 comments on commit eb2c00f

Please sign in to comment.