Source: grub2
Version: 2.02~beta2-18
Severity: wishlist

Dear Maintainer,

It would be good to have the option to other supported init system for linux
in the advanced option entry.

We should only list installed init systems that are not set as the default, as well as supporting various way of being set as default (either by GRUB variables
or with init symlinks).

Note that OS vendor may have a different supported init system (ubuntu
would only support, and thus list, upstart and systemd for instance)

Please find attached a patch supporting that. I used git-dpm to generate it, but not really familiar with this tool yet (seems that it's showing in the main branch after git-dpm dch as if it was inline and hides debian/patches/<patch_name>, so I hope this is all correct.


-- System Information:
Debian Release: jessie/sid
  APT prefers vivid-updates
APT policy: (500, 'vivid-updates'), (500, 'vivid-security'), (500, 'vivid'), (400, 'vivid-proposed')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.16.0-25-generic (SMP w/4 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

>From fcc1bd90d3ac427a7358cafa2a9ae0ecc5ba7fd7 Mon Sep 17 00:00:00 2001
From: Didier Roche <didro...@ubuntu.com>
Date: Mon, 15 Dec 2014 09:55:02 +0100
Subject: [PATCH] Generate alternatives init entries in advanced menu

For linux and linux-xen, enables generating alternatives init entries.
We generate those from a list of supported init alternatives, and if they
are installed, but not default (either pointed by init=/sbin/init or overidden
in GRUB_CMDLINE_LINUX_DEFAULT), add a corresponding entry to the advanced menu.
Add GRUB_DISABLE_OTHERINITS as an option to mask those generated entries.

Note that the list of init alternatives may be restricted by the OS vendor.

Patch-Name: add-other-inits.patch
---
 docs/grub.texi              | 19 +++++++++++++++----
 util/grub-mkconfig.in       |  6 +++++-
 util/grub.d/10_linux.in     | 24 ++++++++++++++++++++++++
 util/grub.d/20_linux_xen.in | 34 +++++++++++++++++++++++++++++-----
 4 files changed, 73 insertions(+), 10 deletions(-)

diff --git a/docs/grub.texi b/docs/grub.texi
index af020ec..cf30505 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -1374,11 +1374,13 @@ A command to configure the serial port when using the serial console.
 Command-line arguments to add to menu entries for the Linux kernel.
 
 @item GRUB_CMDLINE_LINUX_DEFAULT
-Unless @samp{GRUB_DISABLE_RECOVERY} is set to @samp{true}, two menu
+Unless @samp{GRUB_DISABLE_RECOVERY} is set to @samp{true}, at least two menu
 entries will be generated for each Linux kernel: one default entry and one
-entry for recovery mode.  This option lists command-line arguments to add
-only to the default menu entry, after those listed in
-@samp{GRUB_CMDLINE_LINUX}.
+entry for recovery mode. There will be additional entries if other init systems
+are installed unless @samp{GRUB_DISABLE_OTHERINITS} is set to @samp{true}.
+This option lists command-line arguments to add only to non recovery menu
+entry, after those listed in @samp{GRUB_CMDLINE_LINUX}. Any "init=" will be
+of course stripped for non default init system menu entry.
 
 @item GRUB_CMDLINE_NETBSD
 @itemx GRUB_CMDLINE_NETBSD_DEFAULT
@@ -1409,6 +1411,11 @@ disable the use of UUIDs, set this option to @samp{true}.
 If this option is set to @samp{true}, disable the generation of recovery
 mode menu entries.
 
+@item GRUB_DISABLE_OTHERINITS
+If this option is set to @samp{true}, disable the generation of additional
+menu entries for each non default installed init systems.
+Note that the list of init alternatives may be restricted by the OS vendor.
+
 @item GRUB_VIDEO_BACKEND
 If graphical video support is required, either because the @samp{gfxterm}
 graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set,
@@ -1504,6 +1511,10 @@ This option sets the English text of the string that will be displayed in
 parentheses to indicate that a boot option is provided to help users recover
 a broken system.  The default is "recovery mode".
 
+@item GRUB_OTHERINITS_TITLE
+This option sets the English text of the string that will be displayed in
+parentheses to indicate that a boot option is provided to help users booting
+with other installed init systems.  The default is "with <init_system_name>".
 @end table
 
 The following options are still accepted for compatibility with existing
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
index 4641563..fb43b4d 100644
--- a/util/grub-mkconfig.in
+++ b/util/grub-mkconfig.in
@@ -190,6 +190,9 @@ if [ "x${GRUB_RECOVERY_TITLE}" = "x" ]; then
   GRUB_RECOVERY_TITLE="recovery mode"
 fi
 
+if [ "x${GRUB_OTHERINITS_TITLE}" = "x" ]; then
+  GRUB_OTHERINITS_TITLE="with %s"
+fi
 
 # These are defined in this script, export them here so that user can
 # override them.
@@ -242,7 +245,8 @@ export GRUB_DEFAULT \
   GRUB_OS_PROBER_SKIP_LIST \
   GRUB_DISABLE_SUBMENU \
   GRUB_RECORDFAIL_TIMEOUT \
-  GRUB_RECOVERY_TITLE
+  GRUB_RECOVERY_TITLE \
+  GRUB_OTHERINITS_TITLE
 
 if test "x${grub_cfg}" != "x"; then
   rm -f "${grub_cfg}.new"
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index 86e35f2..6b53e38 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -32,6 +32,7 @@ export TEXTDOMAIN=@PACKAGE@
 export TEXTDOMAINDIR="@localedir@"
 
 CLASS="--class gnu-linux --class gnu --class os"
+SUPPORTED_INITS="/sbin/init /lib/systemd/systemd /sbin/upstart"
 
 if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
   OS=GNU/Linux
@@ -39,6 +40,7 @@ else
   case ${GRUB_DISTRIBUTOR} in
     Ubuntu|Kubuntu)
       OS="${GRUB_DISTRIBUTOR}"
+      SUPPORTED_INITS="/lib/systemd/systemd /sbin/upstart"
       ;;
     *)
       OS="${GRUB_DISTRIBUTOR} GNU/Linux"
@@ -47,6 +49,14 @@ else
   CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
 fi
 
+INIT_PATH="/sbin/init"
+# override with potentially manually set init
+INIT_IN_CMDLINE=`echo "${GRUB_CMDLINE_LINUX_DEFAULT}" | grep -cs "init=" || true`
+if [ ${INIT_IN_CMDLINE} -ne 0 ]; then
+    INIT_PATH=`echo ${GRUB_CMDLINE_LINUX_DEFAULT} | sed 's,.*init=\([^ ]*\).*,\1,'`
+fi
+DEFAULT_INIT_PATH=`readlink -f ${INIT_PATH}`
+
 # loop-AES arranges things so that /dev/loop/X can be our root device, but
 # the initrds that Linux uses don't like that.
 case ${GRUB_DEVICE} in
@@ -113,6 +122,9 @@ linux_entry ()
   fi
   if [ x$type != xsimple ] ; then
       case $type in
+	  init-*)
+	      initname=${type#init-}
+	      title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "$(gettext_printf "${GRUB_OTHERINITS_TITLE}" "${initname}")")" ;;
 	  recovery)
 	      title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" ;;
 	  *)
@@ -344,6 +356,18 @@ while [ "x$list" != "x" ] ; do
     linux_entry "${OS}" "${version}" recovery \
                 "${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}"
   fi
+  if [ "x${GRUB_DISABLE_OTHERINITS}" != "xtrue" ]; then
+    GRUB_CMDLINE_WITHOUTINIT_DEFAULT=`echo ${GRUB_CMDLINE_LINUX_DEFAULT} | sed 's,init=[^ ]*\b,,g'`
+    for init_path in ${SUPPORTED_INITS}; do
+      if [ "${init_path}" = "/sbin/init" ] && [ -h "${init_path}" ]; then
+        continue
+      fi
+      if [ "${DEFAULT_INIT_PATH}" != "${init_path}" ] && [ -x "${init_path}" ]; then
+        linux_entry "${OS}" "${version}" init-`basename ${init_path}` \
+                    "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_WITHOUTINIT_DEFAULT} init=${init_path}"
+    fi
+    done
+  fi
 
   list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
 done
diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in
index a5e5e50..c116ba9 100644
--- a/util/grub.d/20_linux_xen.in
+++ b/util/grub.d/20_linux_xen.in
@@ -27,6 +27,7 @@ export TEXTDOMAIN=@PACKAGE@
 export TEXTDOMAINDIR="@localedir@"
 
 CLASS="--class gnu-linux --class gnu --class os --class xen"
+SUPPORTED_INITS="/sbin/init /lib/systemd/systemd /sbin/upstart"
 
 if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
   OS=GNU/Linux
@@ -35,6 +36,14 @@ else
   CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
 fi
 
+INIT_PATH="/sbin/init"
+# override with potentially manually set init
+INIT_IN_CMDLINE=`echo "${GRUB_CMDLINE_LINUX_DEFAULT}" | grep -cs "init=" || true`
+if [ ${INIT_IN_CMDLINE} -ne 0 ]; then
+    INIT_PATH=`echo ${GRUB_CMDLINE_LINUX_DEFAULT} | sed 's,.*init=\([^ ]*\).*,\1,'`
+fi
+DEFAULT_INIT_PATH=`readlink -f ${INIT_PATH}`
+
 # loop-AES arranges things so that /dev/loop/X can be our root device, but
 # the initrds that Linux uses don't like that.
 case ${GRUB_DEVICE} in
@@ -92,11 +100,15 @@ linux_entry ()
       boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
   fi
   if [ x$type != xsimple ] ; then
-      if [ x$type = xrecovery ] ; then
-	  title="$(gettext_printf "%s, with Xen %s and Linux %s (%s)" "${os}" "${xen_version}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
-      else
-	  title="$(gettext_printf "%s, with Xen %s and Linux %s" "${os}" "${xen_version}" "${version}")"
-      fi
+      case $type in
+	     init-*)
+	         initname=${type#init-}
+	         title="$(gettext_printf "%s, with Xen %s and Linux %s (%s)" "${os}" "${xen_version}" "${version}" "$(gettext_printf "${GRUB_OTHERINITS_TITLE}" "${initname}")")" ;;
+	     recovery)
+	         title="$(gettext_printf "%s, with Xen %s and Linux %s (%s)" "${os}" "${xen_version}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" ;;
+	     *)
+	         title="$(gettext_printf "%s, with Xen %s and Linux %s" "${os}" "${xen_version}" "${version}")" ;;
+      esac
       replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
       if [ x"Xen ${xen_version}>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
          quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
@@ -259,6 +271,18 @@ while [ "x${xen_list}" != "x" ] ; do
 	    linux_entry "${OS}" "${version}" "${xen_version}" recovery \
 		"single ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}"
 	fi
+	if [ "x${GRUB_DISABLE_OTHERINITS}" != "xtrue" ]; then
+	    GRUB_CMDLINE_WITHOUTINIT_DEFAULT=`echo ${GRUB_CMDLINE_LINUX_DEFAULT} | sed 's,init=[^ ]*\b,,g'`
+	    for init_path in ${SUPPORTED_INITS}; do
+	      if [ "${init_path}" = "/sbin/init" ] && [ -h "${init_path}" ]; then
+	        continue
+	      fi
+	      if [ "${DEFAULT_INIT_PATH}" != "${init_path}" ] && [ -x "${init_path}" ]; then
+	        linux_entry "${OS}" "${version}" init-`basename ${init_path}` \
+	                    "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_WITHOUTINIT_DEFAULT} init=${init_path}"
+	      fi
+	    done
+	fi
 
 	list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
     done
-- 
2.1.3

Reply via email to