Skip to content

Commit

Permalink
Extend capabilities of zbm.prefer
Browse files Browse the repository at this point in the history
Under certain circumstances, it might be preferable to ensure
ZFSBootMenu only ever interacts with a specific zpool.
Historical/default behavior has every pool being imported each boot,
with optional preference being given to one specific pool.

A new modifier to `zbm.prefer`, `!!` has been added. When this is
appended to the name of a pool, that pool is imported exclusive of all
others on the system. If the pool can't be imported, a retry/recovery
shell loop is initiated.
  • Loading branch information
zdykstra committed Oct 27, 2022
1 parent af1c74b commit 57b46a2
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 28 deletions.
18 changes: 17 additions & 1 deletion docs/pod/zfsbootmenu.7.pod
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,25 @@ These options are set on the kernel command line when booting the initramfs or U

When creating an initramfs or UEFI bundle, the I</etc/hostid> from the system is copied into the target. If this image will be used on another system with a different hostid, replace B<E<lt>hostidE<gt>> with the desired hostid, as an eight-digit hexadecimal number, to override the value contained within the image.

=item B<zbm.prefer>

ZFSBootMenu will attempt to import as many pools as possible to identify boot environments and will, by default, look for the I<bootfs> property on the first imported pool (sorted alphabetically) to select the default boot environment. This option controls this behavior.

=over 2

=item B<zbm.prefer=E<lt>poolE<gt>>

ZFSBootMenu will attempt to import as many pools as possible to identify boot environments and will, by default, look for the I<bootfs> property on the first imported pool (sorted alphabetically) to select the default boot environment. If you have multiple pools, replace B<E<lt>poolE<gt>> with the name of your preferred pool to override the default. If B<E<lt>poolE<gt>> is the name of a pool followed by a literal I<!> character, ZFSBootMenu will insist on successfully importing the named pool before attempting to import any others.
The simplest form attempts to import B<E<lt>poolE<gt>> before any other pool. The I<bootfs> value from this pool will control the default boot environment.

=item B<zbm.prefer=E<lt>poolE<gt>I<!>>

If a literal I<!> has been appended to the pool name, ZFSBootMenu will insist on successfully importing the named pool before attempting to import any others.

=item B<zbm.prefer=E<lt>poolE<gt>I<!!>>

If a literal I<!!> has been appended to the pool name, ZFSBootMenu will insist on successfully importing the named pool and no others.

=back

=item B<zbm.import_delay=E<lt>timeE<gt>>

Expand Down
19 changes: 15 additions & 4 deletions zfsbootmenu/help-files/132/zfsbootmenu.7.pod
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,22 @@ general systems to boot without setting any values.
on another system with a different hostid, replace <hostid> with the desired hostid, as an eight-digit hexadecimal number, to
override the value contained within the image.

zbm.prefer=<pool>
zbm.prefer
ZFSBootMenu will attempt to import as many pools as possible to identify boot environments and will, by default, look for the
bootfs property on the first imported pool (sorted alphabetically) to select the default boot environment. If you have multiple
pools, replace <pool> with the name of your preferred pool to override the default. If <pool> is the name of a pool followed by
a literal ! character, ZFSBootMenu will insist on successfully importing the named pool before attempting to import any others.
bootfs property on the first imported pool (sorted alphabetically) to select the default boot environment. This option controls
this behavior.

zbm.prefer=<pool>
The simplest form attempts to import <pool> before any other pool. The bootfs value from this pool will control the default
boot environment.

zbm.prefer=<pool>!
If a literal ! has been appended to the pool name, ZFSBootMenu will insist on successfully importing the named pool before
attempting to import any others.

zbm.prefer=<pool>!!
If a literal !! has been appended to the pool name, ZFSBootMenu will insist on successfully importing the named pool and no
others.

zbm.import_delay=<time>
Should ZFSBootMenu fail to successfully import any pool, it will repeat import attempts indefinitely until at least one pool can
Expand Down
27 changes: 19 additions & 8 deletions zfsbootmenu/help-files/52/zfsbootmenu.7.pod
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,30 @@ without setting any values.
hexadecimal number, to override the value
contained within the image.

zbm.prefer=<pool>
zbm.prefer
ZFSBootMenu will attempt to import as many pools
as possible to identify boot environments and
will, by default, look for the bootfs property
on the first imported pool (sorted
alphabetically) to select the default boot
environment. If you have multiple pools, replace
<pool> with the name of your preferred pool to
override the default. If <pool> is the name of a
pool followed by a literal ! character,
ZFSBootMenu will insist on successfully
importing the named pool before attempting to
import any others.
environment. This option controls this behavior.

zbm.prefer=<pool>
The simplest form attempts to import <pool>
before any other pool. The bootfs value from
this pool will control the default boot
environment.

zbm.prefer=<pool>!
If a literal ! has been appended to the pool
name, ZFSBootMenu will insist on successfully
importing the named pool before attempting to
import any others.

zbm.prefer=<pool>!!
If a literal !! has been appended to the pool
name, ZFSBootMenu will insist on successfully
importing the named pool and no others.

zbm.import_delay=<time>
Should ZFSBootMenu fail to successfully import
Expand Down
21 changes: 15 additions & 6 deletions zfsbootmenu/help-files/92/zfsbootmenu.7.pod
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,23 @@ Default options were chosen to allow general systems to boot without setting any
replace <hostid> with the desired hostid, as an eight-digit hexadecimal number, to
override the value contained within the image.

zbm.prefer=<pool>
zbm.prefer
ZFSBootMenu will attempt to import as many pools as possible to identify boot
environments and will, by default, look for the bootfs property on the first imported
pool (sorted alphabetically) to select the default boot environment. If you have
multiple pools, replace <pool> with the name of your preferred pool to override the
default. If <pool> is the name of a pool followed by a literal ! character, ZFSBootMenu
will insist on successfully importing the named pool before attempting to import any
others.
pool (sorted alphabetically) to select the default boot environment. This option
controls this behavior.

zbm.prefer=<pool>
The simplest form attempts to import <pool> before any other pool. The bootfs value
from this pool will control the default boot environment.

zbm.prefer=<pool>!
If a literal ! has been appended to the pool name, ZFSBootMenu will insist on
successfully importing the named pool before attempting to import any others.

zbm.prefer=<pool>!!
If a literal !! has been appended to the pool name, ZFSBootMenu will insist on
successfully importing the named pool and no others.

zbm.import_delay=<time>
Should ZFSBootMenu fail to successfully import any pool, it will repeat import attempts
Expand Down
24 changes: 17 additions & 7 deletions zfsbootmenu/hook/zfsbootmenu-parse-commandline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,23 @@ case "${root}" in
;;
esac

# Pool preference ending in ! indicates a hard requirement
bpool="${root%\!}"
if [ "${bpool}" != "${root}" ]; then
# shellcheck disable=SC2034
zbm_require_bpool=1
root="${bpool}"
fi
# pool! : this pool must be imported before all others
# pool!!: this pool, and no others, must be imported

# shellcheck disable=SC2034
case "${root}" in
*!!)
zbm_require_bpool="only"
root="${root%!!}"
;;
*!)
zbm_require_bpool="yes"
root="${root%!}"
;;
*)
zbm_require_bpool=""
;;
esac

# Make sure Dracut is happy that we have a root
if [ ${wait_for_zfs} -eq 1 ]; then
Expand Down
7 changes: 5 additions & 2 deletions zfsbootmenu/libexec/zfsbootmenu-init
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ while true; do

# shellcheck disable=SC2154
if check_for_pools; then
if [ -n "${try_pool}" ]; then
if [ "${zbm_require_bpool}" = "only" ]; then
zdebug "only importing ${try_pool}"
break
elif [ -n "${try_pool}" ]; then
# If a single pool was requested and imported, try importing others
try_pool=""
continue
Expand All @@ -127,7 +130,7 @@ while true; do
# allow another pass to pick up others with the same hostid
try_pool=""
continue
elif [ -n "${try_pool}" ] && [ "${zbm_require_bpool:-0}" -ne 1 ]; then
elif [ -n "${try_pool}" ] && [ -z "${zbm_require_bpool}" ]; then
# If a specific pool was tried unsuccessfully but is not a requirement,
# allow another pass to try any other importable pools
try_pool=""
Expand Down

0 comments on commit 57b46a2

Please sign in to comment.