Hello, all. Currently we use and recommend using the title for default variable. It has however following problems: 1) When device names change the title changes (because of the "(on $device)" part) 2) If user changes locale the part ", with" gets translated and again the title changes Attached patch changes it to the use of IDs specified by --id but keeps title possiblity for backward compatibility. Any comments?

--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko

=== modified file 'grub-core/commands/legacycfg.c'
--- grub-core/commands/legacycfg.c	2012-02-26 16:28:05 +0000
+++ grub-core/commands/legacycfg.c	2012-03-03 12:11:30 +0000
@@ -123,7 +123,7 @@
 		return grub_errno;
 	      }
 	    args[0] = oldname;
-	    grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL,
+	    grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, NULL,
 					entrysrc, 0);
 	    grub_free (args);
 	    entrysrc[0] = 0;
@@ -174,7 +174,8 @@
 	  return grub_errno;
 	}
       args[0] = entryname;
-      grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc, 0);
+      grub_normal_add_menu_entry (1, args, NULL, NULL, NULL,
+				  NULL, NULL, entrysrc, 0);
       grub_free (args);
     }
 

=== modified file 'grub-core/commands/menuentry.c'
--- grub-core/commands/menuentry.c	2012-02-26 16:28:05 +0000
+++ grub-core/commands/menuentry.c	2012-03-03 12:11:30 +0000
@@ -36,6 +36,8 @@
      N_("Keyboard key to quickly boot this entry."), N_("KEYBOARD_KEY"), ARG_TYPE_STRING},
     {"source", 4, 0,
      N_("Use STRING as menu entry body."), N_("STRING"), ARG_TYPE_STRING},
+    {"id", 1, GRUB_ARG_OPTION_REPEATABLE,
+     N_("Menu entry identifier."), N_("STRING"), ARG_TYPE_STRING},
     {0, 0, 0, 0, 0, 0}
   };
 
@@ -67,7 +69,8 @@
    variable data slot `menu').  As the configuration file is read, the script
    parser calls this when a menu entry is to be created.  */
 grub_err_t
-grub_normal_add_menu_entry (int argc, const char **args, char **classes,
+grub_normal_add_menu_entry (int argc, const char **args,
+			    char **classes, const char *id,
 			    const char *users, const char *hotkey,
 			    const char *prefix, const char *sourcecode,
 			    int submenu)
@@ -77,6 +80,7 @@
   char *menu_users = NULL;
   char *menu_title = NULL;
   char *menu_sourcecode = NULL;
+  char *menu_id = NULL;
   struct grub_menu_entry_class *menu_classes = NULL;
 
   grub_menu_t menu;
@@ -139,6 +143,10 @@
   if (! menu_title)
     goto fail;
 
+  menu_id = grub_strdup (id ? : menu_title);
+  if (! menu_id)
+    goto fail;
+
   /* Save argc, args to pass as parameters to block arg later. */
   menu_args = grub_malloc (sizeof (char*) * (argc + 1));
   if (! menu_args)
@@ -164,6 +172,7 @@
     goto fail;
 
   (*last)->title = menu_title;
+  (*last)->id = menu_id;
   (*last)->hotkey = menu_hotkey;
   (*last)->classes = menu_classes;
   if (menu_users)
@@ -196,6 +205,7 @@
 
   grub_free (menu_users);
   grub_free (menu_title);
+  grub_free (menu_id);
   return grub_errno;
 }
 
@@ -257,7 +267,9 @@
   if (! ctxt->script)
     return grub_normal_add_menu_entry (argc, (const char **) args,
 				       (ctxt->state[0].set ? ctxt->state[0].args
-					: NULL), ctxt->state[1].arg,
+					: NULL),
+				       ctxt->state[4].arg,
+				       ctxt->state[1].arg,
 				       ctxt->state[2].arg, 0,
 				       ctxt->state[3].arg,
 				       ctxt->extcmd->cmd->name[0] == 's');
@@ -274,7 +286,8 @@
     return grub_errno;
 
   r = grub_normal_add_menu_entry (argc - 1, (const char **) args,
-				  ctxt->state[0].args, ctxt->state[1].arg,
+				  ctxt->state[0].args, ctxt->state[4].arg,
+				  ctxt->state[1].arg,
 				  ctxt->state[2].arg, prefix, src + 1,
 				  ctxt->extcmd->cmd->name[0] == 's');
 
@@ -291,10 +304,12 @@
 {
   cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry,
 			      GRUB_COMMAND_FLAG_BLOCKS
+			      | GRUB_COMMAND_ACCEPT_DASH
 			      | GRUB_COMMAND_FLAG_EXTRACTOR,
 			      N_("BLOCK"), N_("Define a menu entry."), options);
   cmd_sub = grub_register_extcmd ("submenu", grub_cmd_menuentry,
 				  GRUB_COMMAND_FLAG_BLOCKS
+				  | GRUB_COMMAND_ACCEPT_DASH
 				  | GRUB_COMMAND_FLAG_EXTRACTOR,
 				  N_("BLOCK"), N_("Define a submenu."),
 				  options);

=== modified file 'grub-core/normal/main.c'
--- grub-core/normal/main.c	2012-02-26 17:09:07 +0000
+++ grub-core/normal/main.c	2012-03-03 12:11:30 +0000
@@ -475,7 +475,8 @@
 static void (*grub_xputs_saved) (const char *str);
 static const char *features[] = {
   "feature_chainloader_bpb", "feature_ntldr", "feature_platform_search_hint",
-  "feature_default_font_path", "feature_all_video_module"
+  "feature_default_font_path", "feature_all_video_module",
+  "feature_menuentry_id", "feature_menuentry_options"
 };
 
 GRUB_MOD_INIT(normal)

=== modified file 'grub-core/normal/menu.c'
--- grub-core/normal/menu.c	2012-03-03 12:05:08 +0000
+++ grub-core/normal/menu.c	2012-03-03 12:11:30 +0000
@@ -188,7 +188,7 @@
 	grub_env_set ("timeout", "0");
     }
 
-  for (ptr = entry->title; *ptr; ptr++)
+  for (ptr = entry->id; *ptr; ptr++)
     sz += (*ptr == '>') ? 2 : 1;
   if (chosen)
     {
@@ -217,7 +217,7 @@
 	  optr = grub_stpcpy (optr, chosen);
 	  *optr++ = '>';
 	}
-      for (ptr = entry->title; *ptr; ptr++)
+      for (ptr = entry->id; *ptr; ptr++)
 	{
 	  if (*ptr == '>')
 	    *optr++ = '>';
@@ -411,10 +411,10 @@
 }
 
 static int
-menuentry_eq (const char *title, const char *spec)
+menuentry_eq (const char *id, const char *spec)
 {
   const char *ptr1, *ptr2;
-  ptr1 = title;
+  ptr1 = id;
   ptr2 = spec;
   while (1)
     {
@@ -459,7 +459,8 @@
 
       for (i = 0; e; i++)
 	{
-	  if (menuentry_eq (e->title, val))
+	  if (menuentry_eq (e->title, val)
+	      || menuentry_eq (e->id, val))
 	    {
 	      entry = i;
 	      break;

=== modified file 'include/grub/menu.h'
--- include/grub/menu.h	2011-01-10 22:27:58 +0000
+++ include/grub/menu.h	2012-03-03 12:11:30 +0000
@@ -32,6 +32,9 @@
   /* The title name.  */
   const char *title;
 
+  /* The identifier.  */
+  const char *id;
+
   /* If set means not everybody is allowed to boot this entry.  */
   int restricted;
 

=== modified file 'include/grub/normal.h'
--- include/grub/normal.h	2012-02-09 13:38:34 +0000
+++ include/grub/normal.h	2012-03-03 12:11:30 +0000
@@ -120,6 +120,7 @@
 
 grub_err_t
 grub_normal_add_menu_entry (int argc, const char **args, char **classes,
+			    const char *id,
 			    const char *users, const char *hotkey,
 			    const char *prefix, const char *sourcecode,
 			    int submenu);

=== modified file 'util/grub-mkconfig_lib.in'
--- util/grub-mkconfig_lib.in	2012-02-27 10:04:50 +0000
+++ util/grub-mkconfig_lib.in	2012-03-03 12:11:30 +0000
@@ -162,6 +162,16 @@
   fi
 }
 
+grub_get_device_id ()
+{
+  device="$1"
+  if fs_uuid="`"${grub_probe}" --device "${device}" --target=fs_uuid 2> /dev/null`" ; then
+    echo "$fs_uuid";
+  else
+    echo "$device"
+  fi
+}
+
 grub_file_is_not_garbage ()
 {
   if test -f "$1" ; then

=== modified file 'util/grub.d/00_header.in'
--- util/grub.d/00_header.in	2012-02-29 23:40:02 +0000
+++ util/grub.d/00_header.in	2012-03-03 12:11:30 +0000
@@ -63,6 +63,13 @@
 EOF
 fi
 cat <<EOF
+
+if [ x"\${feature_menuentry_id}" = xy ]; then
+  menuentry_id_option="--id"
+else
+  menuentry_id_option=""
+fi
+
 if [ "\${prev_saved_entry}" ]; then
   set saved_entry="\${prev_saved_entry}"
   save_env saved_entry

=== modified file 'util/grub.d/10_hurd.in'
--- util/grub.d/10_hurd.in	2012-02-29 23:40:02 +0000
+++ util/grub.d/10_hurd.in	2012-03-03 12:11:30 +0000
@@ -85,9 +85,9 @@
   KERNEL="using ${kernel_base}"
 
   cat << EOF
-menuentry "${OS} ${KERNEL}" ${CLASS} {
+menuentry "${OS} ${KERNEL}" ${CLASS} \$menuentry_id_option 'gnuhurd-$kernel-false-$(grub_get_device_id "${GRUB_DEVICE_BOOT}")' {
 EOF
-  prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
+  prepare_grub_to_access_device "${GRUB_DEVICE_BOOT}" | sed -e "s/^/\t/"
   message="$(gettext_printf "Loading GNU Mach ...")"
   cat << EOF
 	echo		'$message'

=== modified file 'util/grub.d/10_illumos.in'
--- util/grub.d/10_illumos.in	2012-01-24 12:17:36 +0000
+++ util/grub.d/10_illumos.in	2012-03-03 12:11:30 +0000
@@ -34,9 +34,9 @@
   ;;
 esac
 
-echo "menuentry '${OS}' ${CLASS} {"
+echo "menuentry '${OS}' ${CLASS} \$menuentry_id_option 'illumos-$(grub_get_device_id "${GRUB_DEVICE_BOOT}")' {"
 save_default_entry | sed -e "s/^/\t/"
-prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
+prepare_grub_to_access_device "${GRUB_DEVICE_BOOT}" | sed -e "s/^/\t/"
 message="$(gettext_printf "Loading kernel of Illumos ...")"
   cat << EOF
 	insmod gzio

=== modified file 'util/grub.d/10_kfreebsd.in'
--- util/grub.d/10_kfreebsd.in	2012-02-03 10:42:22 +0000
+++ util/grub.d/10_kfreebsd.in	2012-03-03 12:11:30 +0000
@@ -74,7 +74,10 @@
   else
     title="$(gettext_quoted "%s, with kFreeBSD %s")"
   fi
-  printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}"
+  if [ -z "$boot_device_id" ]; then
+      boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
+  fi
+  printf "menuentry '${title}' ${CLASS} \$menuentry_id_option 'kfreebsd-$version-$recovery-$boot_device_id' {\n" "${os}" "${version}"
   if ! ${recovery} ; then
       save_default_entry | sed -e "s/^/\t/"
   fi
@@ -132,6 +135,7 @@
         if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
       done`
 prepare_boot_cache=
+boot_device_id=
 
 while [ "x$list" != "x" ] ; do
   kfreebsd=`version_find_latest $list`

=== modified file 'util/grub.d/10_linux.in'
--- util/grub.d/10_linux.in	2012-02-27 18:07:09 +0000
+++ util/grub.d/10_linux.in	2012-03-03 12:11:30 +0000
@@ -77,7 +77,10 @@
   else
     title="$(gettext_quoted "%s, with Linux %s")"
   fi
-  printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}"
+  if [ -z "$boot_device_id" ]; then
+      boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
+  fi
+  printf "menuentry '${title}' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$recovery-$boot_device_id' {\n" "${os}" "${version}"
   if ! ${recovery} ; then
       save_default_entry | sed -e "s/^/\t/"
   fi
@@ -151,6 +154,7 @@
 
 prepare_boot_cache=
 prepare_root_cache=
+boot_device_id=
 
 while [ "x$list" != "x" ] ; do
   linux=`version_find_latest $list`

=== modified file 'util/grub.d/10_netbsd.in'
--- util/grub.d/10_netbsd.in	2012-02-03 10:42:22 +0000
+++ util/grub.d/10_netbsd.in	2012-03-03 12:11:30 +0000
@@ -99,7 +99,10 @@
     title="$(gettext_quoted "%s, with kernel %s (via %s)")"
   fi
 
-  printf "menuentry \"${title}\" {\n" \
+  if [ -z "$boot_device_id" ]; then
+      boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
+  fi
+  printf "menuentry \"${title}\" \$menuentry_id_option 'netbsd-$kernel-$recovery-$boot_device_id' {\n" \
     "${OS}" "$(echo ${kernel} | sed -e 's,^.*/,,')" "${loader}"
   printf "%s\n" "${prepare_boot_cache}"
   case "${loader}" in
@@ -119,6 +122,7 @@
 }
 
 prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e 's,^,	,')"
+boot_device_id=
 
 # We look for NetBSD kernels in / but not in subdirectories.  We simply
 # pick all statically linked ELF executable files (or links) in / with a

=== modified file 'util/grub.d/10_windows.in'
--- util/grub.d/10_windows.in	2012-02-29 23:40:02 +0000
+++ util/grub.d/10_windows.in	2012-03-03 12:11:30 +0000
@@ -63,14 +63,16 @@
   test -n "$dir" || continue
 
   needmap=
+  osid=
 
   # Check for Vista bootmgr.
   if [ -f "$dir"/bootmgr -a -f "$dir"/boot/bcd ] ; then
     OS="$(gettext_quoted "Windows Vista/7 (loader)")"
-
+    osid=bootmgr
   # Check for NTLDR.
   elif [ -f "$dir"/ntldr -a -f "$dir"/ntdetect.com -a -f "$dir"/boot.ini ] ; then
     OS=`get_os_name_from_boot_ini "$dir"/boot.ini` || OS="$(gettext_quoted "Windows NT/2000/XP (loader)")"
+    osid=ntldr
     needmap=t
 
   else
@@ -82,7 +84,7 @@
 
   gettext_printf "Found %s on %s (%s)\n" "$OS" "$drv" "$dev" >&2
   cat << EOF
-menuentry "$OS" {
+menuentry "$OS" \$menuentry_id_option '$osid-$(grub_get_device_id "${dev}")' {
 EOF
 
   save_default_entry | sed -e 's,^,\t,'

=== modified file 'util/grub.d/20_linux_xen.in'
--- util/grub.d/20_linux_xen.in	2012-02-27 18:07:09 +0000
+++ util/grub.d/20_linux_xen.in	2012-03-03 12:11:30 +0000
@@ -87,7 +87,10 @@
   else
     title="$(gettext_quoted "%s, with Xen %s and Linux %s")"
   fi
-  printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${xen_version}" "${version}"
+  if [ -z "$boot_device_id" ]; then
+      boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
+  fi
+  printf "menuentry '${title}' ${CLASS} \$menuentry_id_option 'xen-gnulinux-$version-$recovery-$boot_device_id' {\n" "${os}" "${xen_version}" "${version}"
   if ! ${recovery} ; then
       save_default_entry | sed -e "s/^/\t/"
   fi
@@ -139,6 +142,7 @@
         if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
       done`
 prepare_boot_cache=
+boot_device_id=
 
 while [ "x${xen_list}" != "x" ] ; do
     list="${linux_list}"
@@ -147,7 +151,10 @@
     xen_dirname=`dirname ${current_xen}`
     rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname`
     xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"`
-    echo "submenu \"Xen ${xen_version}\" {"
+    if [ -z "$boot_device_id" ]; then
+	boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
+    fi
+    echo "submenu \"Xen ${xen_version}\" \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {"
     while [ "x$list" != "x" ] ; do
 	linux=`version_find_latest $list`
 	gettext_printf "Found linux image: %s\n" "$linux" >&2

=== modified file 'util/grub.d/30_os-prober.in'
--- util/grub.d/30_os-prober.in	2012-03-02 14:09:10 +0000
+++ util/grub.d/30_os-prober.in	2012-03-03 12:11:30 +0000
@@ -52,7 +52,7 @@
     # TRANSLATORS: it refers on the OS residing on device %s
     onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
         cat << EOF
-menuentry "${LONGNAME} $bitstr $onstr" --class osx --class darwin --class os {
+menuentry "${LONGNAME} $bitstr $onstr" --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")'  {
 EOF
 	save_default_entry | sed -e "s/^/\t/"
 	prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
@@ -104,6 +104,8 @@
 EOF
 }
 
+used_osprober_linux_ids=
+
 for OS in ${OSPROBED} ; do
   DEVICE="`echo ${OS} | cut -d ':' -f 1`"
   LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`"
@@ -121,7 +123,7 @@
 
 	  onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
       cat << EOF
-menuentry "${LONGNAME} $onstr" --class windows --class os {
+menuentry "${LONGNAME} $onstr" --class windows --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' {
 EOF
       save_default_entry | sed -e "s/^/\t/"
       prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
@@ -144,6 +146,7 @@
     linux)
       LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`"
       prepare_boot_cache=
+      boot_device_id=
 
       for LINUX in ${LINUXPROBED} ; do
         LROOT="`echo ${LINUX} | cut -d ':' -f 1`"
@@ -163,8 +166,17 @@
 	fi
 
 	onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
+	recovery_params="$(echo "${LPARAMS}" | grep single)"
+	counter=1
+	while echo "$used_osprober_linux_ids" | grep 'osprober-gnulinux-$LKERNEL-${recovery_params}-$counter-$boot_device_id' > /dev/null; do
+	    counter=$((counter+1));
+	done
+	if [ -z "$boot_device_id" ]; then
+	    boot_device_id="$(grub_get_device_id "${DEVICE}")"
+	fi
+	used_osprober_linux_ids="$used_osprober_linux_ids 'osprober-gnulinux-$LKERNEL-${recovery_params}-$counter-$boot_device_id'"
         cat << EOF
-menuentry "${LLABEL} $onstr" --class gnu-linux --class gnu --class os {
+menuentry "${LLABEL} $onstr" --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-$LKERNEL-${recovery_params}-$boot_device_id' {
 EOF
 	save_default_entry | sed -e "s/^/\t/"
 	if [ -z "${prepare_boot_cache}" ]; then
@@ -192,7 +204,7 @@
     hurd)
       onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
       cat << EOF
-menuentry "${LONGNAME} $onstr" --class hurd --class gnu --class os {
+menuentry "${LONGNAME} $onstr" --class hurd --class gnu --class os \$menuentry_id_option 'osprober-gnuhurd-/boot/gnumach.gz-false-$(grub_get_device_id "${DEVICE}")' {
 EOF
       save_default_entry | sed -e "s/^/\t/"
       prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to