Skip to content

Commit 04f5b87

Browse files
committed
Allow references to parent properties in org.zfsbootmenu:commandline
Any reference to "%{parent}" in org.zfsbootmenu:commandline will be replaced with the value of the same property on the parent filesystem (with parent references above recursively expanded), allowing easy specification of common options at a mutual parent of two BEs and overrides or additions of individual options per-BE. The value of %{parent} is always an empty string on a root filesystem. This is not intended to be sophisticated, and %{parent} appearing within other words will be replaced regardless. The assumption is that %{parent} is unique enough and will not conflict with real KCL options, so dumb global replacement is sufficient.
1 parent 8886db3 commit 04f5b87

File tree

1 file changed

+66
-7
lines changed

1 file changed

+66
-7
lines changed

90zfsbootmenu/zfsbootmenu-lib.sh

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,68 @@ find_root_prefix() {
11481148
echo "root=zfs:"
11491149
}
11501150

1151+
# arg1: ZFS filesystem
1152+
# prints: value of org.zfsbootmenu:commandline, with %{parent} recursively expanded
1153+
# returns: 0 on success
1154+
1155+
read_kcl_prop() {
1156+
local zfsbe args parfs par_args inherited
1157+
1158+
zfsbe="${1}"
1159+
if [ -z "${zfsbe}" ]; then
1160+
zerror "zfsbe is undefined"
1161+
return 1
1162+
fi
1163+
1164+
if ! args="$( zfs get -H -o value org.zfsbootmenu:commandline "${zfsbe}" )"; then
1165+
zerror "unable to read org.zfsbootmenu:commandline on ${zfsbe}"
1166+
return 1
1167+
fi
1168+
1169+
# KCL is empty, nothing to see
1170+
if [ "${args}" = "-" ]; then
1171+
zdebug "org.zfsbootmenu:commandline on ${zfsbe} has no value"
1172+
echo ""
1173+
return 0
1174+
fi
1175+
1176+
# KCL does not specify parent inheritance, just return the args
1177+
if ! [[ "${args}" =~ "%{parent}" ]]; then
1178+
zdebug "no parent reference in org.zfsbootmenu:commandline on ${zfsbe}"
1179+
echo "${args}"
1180+
return 0
1181+
fi
1182+
1183+
# Need to recursively expand "%{parent}"
1184+
1185+
parfs="${zfsbe%/*}"
1186+
if [ -z "${parfs}" ] || [ "${parfs}" = "${zfsbe}" ]; then
1187+
# There is no parent, par_args is empty
1188+
par_args=""
1189+
else
1190+
# Query the parent for kcl properties
1191+
if ! par_args="$( read_kcl_prop "${parfs}" )"; then
1192+
zwarn "failed to invoke read_kcl_prop on parent ${parfs}"
1193+
par_args=""
1194+
fi
1195+
1196+
# When the KCL property is inherited, recursive expansion fully populates
1197+
# the KCL at the level of the ancestor that actually defines the property.
1198+
if inherited="$( zfs get -H -o source -s inherited org.zfsbootmenu:commandline "${zfsbe}" 2>/dev/null )"; then
1199+
# Inherited property have a source of "inherited from <ancestor>";
1200+
# non-inherited properties will not be printed with `-s inherited`
1201+
if [ -n "${inherited}" ]; then
1202+
zdebug "org.zfsbootmenu:commandline on ${zfsbe} is inherited, using parent expansion verbatim"
1203+
echo "${par_args}"
1204+
return 0
1205+
fi
1206+
fi
1207+
fi
1208+
1209+
echo "${args//%\{parent\}/${par_args}}"
1210+
return 0
1211+
}
1212+
11511213
# arg1: ZFS filesystem
11521214
# arg2: path for a mounted filesystem
11531215
# prints: nothing
@@ -1172,13 +1234,10 @@ preload_be_cmdline() {
11721234

11731235
args_file="${BASE}/${zfsbe_fs}/cmdline"
11741236

1175-
if [ -n "${zfsbe_fs}" ]; then
1176-
zfsbe_args="$( zfs get -H -o value org.zfsbootmenu:commandline "${zfsbe_fs}" )"
1177-
if [ "${zfsbe_args}" != "-" ]; then
1178-
zdebug "using org.zfsbootmenu:commandline"
1179-
echo "${zfsbe_args}" > "${args_file}"
1180-
return
1181-
fi
1237+
if zfsbe_args="$( read_kcl_prop "${zfsbe_fs}" )" && [ -n "${zfsbe_args}" ]; then
1238+
zdebug "using org.zfsbootmenu:commandline"
1239+
echo "${zfsbe_args}" > "${args_file}"
1240+
return
11821241
fi
11831242

11841243
if [ -n "${zfsbe_mnt}" ] && [ -r "${zfsbe_mnt}/etc/default/zfsbootmenu" ]; then

0 commit comments

Comments
 (0)