On Fri, 15 Sep 2017 at 00:57:39AM +0100, Colin Watson wrote:
> A reasonable solution to this kind of thing is to set
> PATH="$PATH:/sbin:/usr/sbin" to ensure that utilities there are
> available.
I edited the patch and tested it. Now everywhere where I use the zpool or
zfs commands I temporarily extend $PATH with PATH="$PATH:/sbin:/usr/sbin".
Signed-off-by: Paul Lagerweij <[email protected]>
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index de9044c..8be0acb 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -20,6 +20,7 @@ set -e
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
+zfs_be="0"
. "$pkgdatadir/grub-mkconfig_lib"
@@ -62,9 +63,18 @@ case x"$GRUB_FS" in
fi;;
xzfs)
rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
- bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
- LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs}"
- ;;
+ old_path="$PATH"
+ PATH="$PATH:/sbin:/usr/sbin"
+ zfs_active_bootfs="`zpool list -H -o bootfs ${rpool} || true`"
+ PATH="$old_path"
+ if [ -n "${zfs_active_bootfs}" ] && [ "${zfs_active_bootfs}" != "-" ] && \
+ [ `echo ${zfs_active_bootfs} | grep -o '/' | wc -l` -gt 1 ]; then
+ zfs_be="1"
+ LINUX_ROOT_DEVICE="ZFS=${zfs_active_bootfs}"
+ else
+ bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
+ LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs}"
+ fi;;
esac
title_correction_code=
@@ -177,6 +187,19 @@ title_correction_code=
# yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
submenu_indentation=""
+if [ "${zfs_be}" = 1 ]; then
+ old_path="$PATH"
+ PATH="$PATH:/sbin:/usr/sbin"
+ while read ZFS_BE_NAME ZFS_ORIGIN; do
+ if [ "${ZFS_ORIGIN}" != "-" ]; then
+ zfs_be_list="${zfs_be_list} ${ZFS_BE_NAME}"
+ fi
+ done << EOF
+`zfs list -H -t filesystem -S creation -o name,origin -d 1 ${zfs_active_bootfs%/*} || true`
+EOF
+ PATH="$old_path"
+fi
+
is_top_level=true
while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`
@@ -184,6 +207,10 @@ while [ "x$list" != "x" ] ; do
basename=`basename $linux`
dirname=`dirname $linux`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
+ # If ZFS BE support and /boot is in ZFS.
+ if [ "${zfs_be}" = 1 ] && [ -n "${rel_dirname}" ]; then
+ rel_dirname="/""${zfs_active_bootfs#*/}""@/boot"
+ fi
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
@@ -238,12 +265,56 @@ while [ "x$list" != "x" ] ; do
is_top_level=false
fi
- linux_entry "${OS}" "${version}" advanced \
- "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
- if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
- linux_entry "${OS}" "${version}" recovery \
- "single ${GRUB_CMDLINE_LINUX}"
- fi
+ for menu_entries_group in default ${zfs_be_list}; do
+ found_entry="0"
+ if [ "${menu_entries_group}" = "default" ]; then
+ found_entry="1"
+ os_title="${OS}"
+ else
+ found_zfs_be="0"
+ zfs_be_name=${menu_entries_group}
+ # If /boot is not in ZFS.
+ if [ -z "${rel_dirname}" ]; then
+ found_zfs_be="1"
+ else
+ old_path="$PATH"
+ PATH="$PATH:/sbin:/usr/sbin"
+ zfs_be_mounted="`zfs list -H -o mounted ${zfs_be_name}`"
+ if [ "${zfs_be_mounted}" = "yes" ]; then
+ ZFSMNT=`mount | grep -m 1 "^${zfs_be_name} " | cut -d' ' -f3)`
+ else
+ ZFSMNT=`mktemp -d "/tmp/$(echo ${zfs_be_name} | sed 's^/^-^g').XXX" || true`
+ zfs set mountpoint=legacy ${zfs_be_name} || true
+ mount -t zfs -o ro ${zfs_be_name} ${ZFSMNT} || true
+ fi
+ if [ -n "${ZFSMNT}" ] && [ -f "${ZFSMNT}/boot/vmlinuz-${version}" ]; then
+ found_zfs_be="1"
+ rel_dirname="/""${zfs_be_name#*/}""@/boot"
+ fi
+ if [ "${zfs_be_mounted}" != "yes" ]; then
+ umount ${ZFSMNT} && rm -rf ${ZFSMNT} || true
+ zfs set mountpoint=/ ${zfs_be_name} || true
+ fi
+ PATH="$old_path"
+ fi
+
+ if [ "${found_zfs_be}" = 1 ]; then
+ found_entry="1"
+ os_title="${OS} (${zfs_be_name##*/} BE)"
+ gettext_printf "Found ZFS boot environment: (%s BE) %s\n" "${zfs_be_name##*/}" "$linux" >&2
+ linux_root_device_thisversion="ZFS=${zfs_be_name}"
+ fi
+ fi
+
+ if [ "${found_entry}" = 1 ]; then
+ linux_entry "${os_title}" "${version}" advanced \
+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
+ if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
+ linux_entry "${os_title}" "${version}" recovery \
+ "single ${GRUB_CMDLINE_LINUX}"
+ fi
+ fi
+ done
list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
done
_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel