752ceb1
From 51be3372ec8ba07ef68a409956ea0eefa89fe7c5 Mon Sep 17 00:00:00 2001
752ceb1
From: Nicholas Vinson <nvinson234@gmail.com>
752ceb1
Date: Mon, 16 Apr 2018 22:36:26 -0700
752ceb1
Subject: [PATCH] templates: Update grub script template files
752ceb1
752ceb1
Update grub-mkconfig.in and 10_linux.in to support grub-probe's new
752ceb1
partuuid target.  Update grub.texi documentation.  The following table
752ceb1
shows how GRUB_DISABLE_LINUX_UUID, GRUB_DISABLE_LINUX_PARTUUID, and
752ceb1
initramfs detection interact:
752ceb1
752ceb1
Initramfs  GRUB_DISABLE_LINUX_PARTUUID  GRUB_DISABLE_LINUX_UUID  Linux Root
752ceb1
detected   Set                          Set                      ID Method
752ceb1
752ceb1
false      false                        false                    part UUID
752ceb1
false      false                        true                     part UUID
752ceb1
false      true                         false                    dev name
752ceb1
false      true                         true                     dev name
752ceb1
true       false                        false                    fs UUID
752ceb1
true       false                        true                     part UUID
752ceb1
true       true                         false                    fs UUID
752ceb1
true       true                         true                     dev name
752ceb1
752ceb1
Note: GRUB_DISABLE_LINUX_PARTUUID and GRUB_DISABLE_LINUX_UUID equate to
752ceb1
      'false' when unset or set to any value other than 'true'.
752ceb1
      GRUB_DISABLE_LINUX_PARTUUID defaults to 'true'.
752ceb1
752ceb1
Signed-off-by: Nicholas Vinson <nvinson234@gmail.com>
752ceb1
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
752ceb1
---
752ceb1
 docs/grub.texi              | 67 ++++++++++++++++++++++++++++++++++++++++++---
752ceb1
 util/grub-mkconfig.in       |  3 ++
752ceb1
 util/grub.d/10_linux.in     | 22 +++++++++++++--
752ceb1
 util/grub.d/20_linux_xen.in | 22 +++++++++++++--
752ceb1
 4 files changed, 104 insertions(+), 10 deletions(-)
752ceb1
752ceb1
diff --git a/docs/grub.texi b/docs/grub.texi
752ceb1
index 0f2ab91fc69..2adfa97bee8 100644
752ceb1
--- a/docs/grub.texi
752ceb1
+++ b/docs/grub.texi
752ceb1
@@ -1214,10 +1214,11 @@ GRUB is configured using @file{grub.cfg}, usually located under
752ceb1
 need to write the whole thing by hand.
752ceb1
 
752ceb1
 @menu
752ceb1
-* Simple configuration::        Recommended for most users
752ceb1
-* Shell-like scripting::        For power users and developers
752ceb1
-* Multi-boot manual config::    For non-standard multi-OS scenarios
752ceb1
-* Embedded configuration::      Embedding a configuration file into GRUB
752ceb1
+* Simple configuration::            Recommended for most users
752ceb1
+* Root Identifcation Heuristics::   Summary on how the root file system is identified.
752ceb1
+* Shell-like scripting::            For power users and developers
752ceb1
+* Multi-boot manual config::        For non-standard multi-OS scenarios
752ceb1
+* Embedded configuration::          Embedding a configuration file into GRUB
752ceb1
 @end menu
752ceb1
 
752ceb1
 
752ceb1
@@ -1425,6 +1426,17 @@ the Linux kernel, using a @samp{root=UUID=...} kernel parameter.  This is
752ceb1
 usually more reliable, but in some cases it may not be appropriate.  To
752ceb1
 disable the use of UUIDs, set this option to @samp{true}.
752ceb1
 
752ceb1
+@item GRUB_DISABLE_LINUX_PARTUUID
752ceb1
+If @command{grub-mkconfig} cannot identify the root filesystem via its
752ceb1
+universally-unique indentifier (UUID), @command{grub-mkconfig} can use the UUID
752ceb1
+of the partition containing the filesystem to identify the root filesystem to
752ceb1
+the Linux kernel via a @samp{root=PARTUUID=...} kernel parameter.  This is not
752ceb1
+as reliable as using the filesystem UUID, but is more reliable than using the
752ceb1
+Linux device names. When @samp{GRUB_DISABLE_LINUX_PARTUUID} is set to
752ceb1
+@samp{false}, the Linux kernel version must be 2.6.37 (3.10 for systems using
752ceb1
+the MSDOS partition scheme) or newer.  This option defaults to @samp{true}.  To
752ceb1
+enable the use of partition UUIDs, set this option to @samp{false}.
752ceb1
+
752ceb1
 @item GRUB_DISABLE_RECOVERY
752ceb1
 If this option is set to @samp{true}, disable the generation of recovery
752ceb1
 mode menu entries.
752ceb1
@@ -1556,6 +1568,53 @@ edit the scripts in @file{/etc/grub.d} directly.
752ceb1
 menu entries; simply type the menu entries you want to add at the end of
752ceb1
 that file, making sure to leave at least the first two lines intact.
752ceb1
 
752ceb1
+@node Root Identifcation Heuristics
752ceb1
+@section Root Identifcation Heuristics
752ceb1
+If the target operating system uses the Linux kernel, @command{grub-mkconfig}
752ceb1
+attempts to identify the root file system via a heuristic algoirthm.  This
752ceb1
+algorithm selects the identification method of the root file system by
752ceb1
+considering three factors.  The first is if an initrd for the target operating
752ceb1
+system is also present.  The second is @samp{GRUB_DISABLE_LINUX_UUID} and if set
752ceb1
+to @samp{true}, prevents @command{grub-mkconfig} from identifying the root file
752ceb1
+system by its UUID.  The third is @samp{GRUB_DISABLE_LINUX_PARTUUID} and if set
752ceb1
+to @samp{true}, prevents @command{grub-mkconfig} from identifying the root file
752ceb1
+system via the UUID of its enclosing partition.  If the variables are assigned
752ceb1
+any other value, that value is considered equivalent to @samp{false}.  The
752ceb1
+variables are also considered to be set to @samp{false} if they are not set.
752ceb1
+
752ceb1
+When booting, the Linux kernel will delegate the task of mounting the root
752ceb1
+filesystem to the initrd.  Most initrd images determine the root file system by
752ceb1
+checking the Linux kernel's command-line for the @samp{root} key and use its
752ceb1
+value as the identification method of the root file system.  To improve the
752ceb1
+reliability of booting, most initrd images also allow the root file system to be
752ceb1
+identified by its UUID.  Because of this behavior, the @command{grub-mkconfig}
752ceb1
+command will set @samp{root} to @samp{root=UUID=...} to provide the initrd with
752ceb1
+the filesystem UUID of the root file system.
752ceb1
+
752ceb1
+If no initrd is detected or @samp{GRUB_DISABLE_LINUX_UUID} is set to @samp{true}
752ceb1
+then @command{grub-command} will identify the root filesystem by setting the
752ceb1
+kernel command-line variable @samp{root} to @samp{root=PARTUUID=...} unless
752ceb1
+@samp{GRUB_DISABLE_LINUX_PARTUUID} is also set to @samp{true}.  If
752ceb1
+@samp{GRUB_DISABLE_LINUX_PARTUUID} is also set to @samp{true},
752ceb1
+@command{grub-command} will identify by its Linux device name.
752ceb1
+
752ceb1
+The following table summarizes the behavior of the @command{grub-mkconfig}
752ceb1
+command.
752ceb1
+
752ceb1
+@multitable {detected} {GRUB_DISABLE_LINUX_PARTUUID} {GRUB_DISABLE_LINUX_UUID} {Linux Root}
752ceb1
+@headitem Initrd detected @tab GRUB_DISABLE_LINUX_PARTUUID Set To @tab GRUB_DISABLE_LINUX_UUID Set To @tab Linux Root ID Method
752ceb1
+@item false         @tab false                       @tab false                   @tab part UUID
752ceb1
+@item false         @tab false                       @tab true                    @tab part UUID
752ceb1
+@item false         @tab true                        @tab false                   @tab dev name
752ceb1
+@item false         @tab true                        @tab true                    @tab dev name
752ceb1
+@item true          @tab false                       @tab false                   @tab fs UUID
752ceb1
+@item true          @tab false                       @tab true                    @tab part UUID
752ceb1
+@item true          @tab true                        @tab false                   @tab fs UUID
752ceb1
+@item true          @tab true                        @tab true                    @tab dev name
752ceb1
+@end multitable
752ceb1
+
752ceb1
+Remember, @samp{GRUB_DISABLE_LINUX_PARTUUID} and @samp{GRUB_DISABLE_LINUX_UUID}
752ceb1
+are also considered to be set to @samp{false} when they are unset.
752ceb1
 
752ceb1
 @node Shell-like scripting
752ceb1
 @section Writing full configuration files directly
752ceb1
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
752ceb1
index 35ef583b05f..33332360eec 100644
752ceb1
--- a/util/grub-mkconfig.in
752ceb1
+++ b/util/grub-mkconfig.in
752ceb1
@@ -134,6 +134,7 @@ fi
752ceb1
 # Device containing our userland.  Typically used for root= parameter.
752ceb1
 GRUB_DEVICE="`${grub_probe} --target=device /`"
752ceb1
 GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true
752ceb1
+GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2> /dev/null`" || true
752ceb1
 
752ceb1
 # Device containing our /boot partition.  Usually the same as GRUB_DEVICE.
752ceb1
 GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`"
752ceb1
@@ -188,6 +189,7 @@ if [ "x${GRUB_ACTUAL_DEFAULT}" = "xsaved" ] ; then GRUB_ACTUAL_DEFAULT="`"${grub
752ceb1
 # override them.
752ceb1
 export GRUB_DEVICE \
752ceb1
   GRUB_DEVICE_UUID \
752ceb1
+  GRUB_DEVICE_PARTUUID \
752ceb1
   GRUB_DEVICE_BOOT \
752ceb1
   GRUB_DEVICE_BOOT_UUID \
752ceb1
   GRUB_FS \
752ceb1
@@ -223,6 +225,7 @@ export GRUB_DEFAULT \
752ceb1
   GRUB_TERMINAL_OUTPUT \
752ceb1
   GRUB_SERIAL_COMMAND \
752ceb1
   GRUB_DISABLE_LINUX_UUID \
752ceb1
+  GRUB_DISABLE_LINUX_PARTUUID \
752ceb1
   GRUB_DISABLE_RECOVERY \
752ceb1
   GRUB_VIDEO_BACKEND \
752ceb1
   GRUB_GFXMODE \
752ceb1
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
752ceb1
index faedf74e14e..146499f22fd 100644
752ceb1
--- a/util/grub.d/10_linux.in
752ceb1
+++ b/util/grub.d/10_linux.in
752ceb1
@@ -43,12 +43,22 @@ case ${GRUB_DEVICE} in
752ceb1
   ;;
752ceb1
 esac
752ceb1
 
752ceb1
+# Default to disabling partition uuid support to maintian compatibility with
752ceb1
+# older kernels.
752ceb1
+GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}
752ceb1
+
752ceb1
 # btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
752ceb1
 # and mounting btrfs requires user space scanning, so force UUID in this case.
752ceb1
-if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
752ceb1
-    || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
752ceb1
+if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ) \
752ceb1
+    || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
752ceb1
+	&& [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
752ceb1
+    || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
752ceb1
+	&& ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
752ceb1
     || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
752ceb1
   LINUX_ROOT_DEVICE=${GRUB_DEVICE}
752ceb1
+elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
752ceb1
+    || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
752ceb1
+  LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
752ceb1
 else
752ceb1
   LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
752ceb1
 fi
752ceb1
@@ -242,7 +252,13 @@ while [ "x$list" != "x" ] ; do
752ceb1
   if test -z "${initramfs}" && test -z "${initrd_real}" ; then
752ceb1
     # "UUID=" and "ZFS=" magic is parsed by initrd or initramfs.  Since there's
752ceb1
     # no initrd or builtin initramfs, it can't work here.
752ceb1
-    linux_root_device_thisversion=${GRUB_DEVICE}
752ceb1
+    if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \
752ceb1
+	|| [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then
752ceb1
+
752ceb1
+	linux_root_device_thisversion=${GRUB_DEVICE}
752ceb1
+    else
752ceb1
+	linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID}
752ceb1
+    fi
752ceb1
   fi
752ceb1
 
752ceb1
   if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
752ceb1
diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in
752ceb1
index 0cb0f4e49b9..e8143b079dc 100644
752ceb1
--- a/util/grub.d/20_linux_xen.in
752ceb1
+++ b/util/grub.d/20_linux_xen.in
752ceb1
@@ -43,12 +43,22 @@ case ${GRUB_DEVICE} in
752ceb1
   ;;
752ceb1
 esac
752ceb1
 
752ceb1
+# Default to disabling partition uuid support to maintian compatibility with
752ceb1
+# older kernels.
752ceb1
+GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}
752ceb1
+
752ceb1
 # btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
752ceb1
 # and mounting btrfs requires user space scanning, so force UUID in this case.
752ceb1
-if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
752ceb1
-    || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
752ceb1
+if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
752ceb1
+    || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
752ceb1
+	&& [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
752ceb1
+    || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
752ceb1
+	&& ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
752ceb1
     || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
752ceb1
   LINUX_ROOT_DEVICE=${GRUB_DEVICE}
752ceb1
+elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
752ceb1
+    || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
752ceb1
+  LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
752ceb1
 else
752ceb1
   LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
752ceb1
 fi
752ceb1
@@ -246,7 +256,13 @@ while [ "x${xen_list}" != "x" ] ; do
752ceb1
 	    gettext_printf "Found initrd image: %s\n" "${dirname}/${initrd}" >&2
752ceb1
 	else
752ceb1
     # "UUID=" magic is parsed by initrds.  Since there's no initrd, it can't work here.
752ceb1
-	    linux_root_device_thisversion=${GRUB_DEVICE}
752ceb1
+	    if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \
752ceb1
+		|| [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then
752ceb1
+
752ceb1
+		linux_root_device_thisversion=${GRUB_DEVICE}
752ceb1
+	    else
752ceb1
+		linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID}
752ceb1
+	    fi
752ceb1
 	fi
752ceb1
 
752ceb1
 	if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then