]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Fix menu title instability bug.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 4 Mar 2012 13:55:13 +0000 (14:55 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 4 Mar 2012 13:55:13 +0000 (14:55 +0100)
* grub-core/commands/menuentry.c (options): New option --id.
(grub_normal_add_menu_entry): New argument id. All users updated.
(grub_cmd_menuentry): Handle --id.
(grub_menu_init): Accept unknown arguments.
* grub-core/normal/main.c (features): Add feature_menuentry_id and
feature_menuentry_options.
* grub-core/normal/menu.c (grub_menu_execute_entry): Use id for
saved_entry.
(get_entry_number): Match with id as well.
* include/grub/menu.h (grub_menu_entry): New member id.
* util/grub-mkconfig_lib.in (grub_get_device_id): New function.
* util/grub.d/00_header.in: Define menuentry_id_option.
* util/grub.d/10_hurd.in: Define id.
* util/grub.d/10_illumos.in: Likewise.
* util/grub.d/10_kfreebsd.in: Likewise.
* util/grub.d/10_linux.in: Likewise.
* util/grub.d/10_netbsd.in: Likewise.
* util/grub.d/10_windows.in: Likewise.
* util/grub.d/20_linux_xen.in: Likewise.
* util/grub.d/30_os-prober.in: Likewise.

17 files changed:
ChangeLog
grub-core/commands/legacycfg.c
grub-core/commands/menuentry.c
grub-core/normal/main.c
grub-core/normal/menu.c
include/grub/menu.h
include/grub/normal.h
util/grub-mkconfig_lib.in
util/grub.d/00_header.in
util/grub.d/10_hurd.in
util/grub.d/10_illumos.in
util/grub.d/10_kfreebsd.in
util/grub.d/10_linux.in
util/grub.d/10_netbsd.in
util/grub.d/10_windows.in
util/grub.d/20_linux_xen.in
util/grub.d/30_os-prober.in

index 9fbad468c374af5f2d7b8f6e595578d87a75445b..7932efe8ffa2c02330b806d265993da78c332ec3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,29 @@
-2012-03-03  Vladimir Serbinenko  <phcoder@gmail.com>
+2012-03-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Fix menu title instability bug.
+
+       * grub-core/commands/menuentry.c (options): New option --id.
+       (grub_normal_add_menu_entry): New argument id. All users updated.
+       (grub_cmd_menuentry): Handle --id.
+       (grub_menu_init): Accept unknown arguments.
+       * grub-core/normal/main.c (features): Add feature_menuentry_id and
+       feature_menuentry_options.
+       * grub-core/normal/menu.c (grub_menu_execute_entry): Use id for
+       saved_entry.
+       (get_entry_number): Match with id as well.
+       * include/grub/menu.h (grub_menu_entry): New member id.
+       * util/grub-mkconfig_lib.in (grub_get_device_id): New function.
+       * util/grub.d/00_header.in: Define menuentry_id_option.
+       * util/grub.d/10_hurd.in: Define id.
+       * util/grub.d/10_illumos.in: Likewise.
+       * util/grub.d/10_kfreebsd.in: Likewise.
+       * util/grub.d/10_linux.in: Likewise.
+       * util/grub.d/10_netbsd.in: Likewise.
+       * util/grub.d/10_windows.in: Likewise.
+       * util/grub.d/20_linux_xen.in: Likewise.
+       * util/grub.d/30_os-prober.in: Likewise.
+
+2012-03-04  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/script/execute.c (grub_script_return): Replace ambiguous
        "scope" with "body".
index e8a58f75c9a22f8327959461de84ce17e6aaa0ed..aab0e632384c30f71411fa6a5a4b7e4b47a07f1d 100644 (file)
@@ -123,7 +123,7 @@ legacy_file (const char *filename)
                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 @@ legacy_file (const char *filename)
          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);
     }
 
index a607c101ef2aa74ad9f677e20d2e9afe218252b7..a4e498a95c334c8a92312155d3eb6f46465e4ee2 100644 (file)
@@ -36,6 +36,8 @@ static const struct grub_arg_option options[] =
      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 @@ static struct
    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 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
   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 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
   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 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
     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_normal_add_menu_entry (int argc, const char **args, char **classes,
 
   grub_free (menu_users);
   grub_free (menu_title);
+  grub_free (menu_id);
   return grub_errno;
 }
 
@@ -257,7 +267,9 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
   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 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
     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 @@ grub_menu_init (void)
 {
   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);
index 50c314dfa358b2d69d427a2e9fe1b13bc37b899e..be5d6b5bfd0143bad67399c592ac855146b1e78d 100644 (file)
@@ -475,7 +475,8 @@ static grub_command_t cmd_clear;
 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)
index b511d4c48af7fb7f73365e863f26e206eece4188..a0ab2297d304066b00aca1a5fc0c1671187726f5 100644 (file)
@@ -188,7 +188,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
        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 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
          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 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer)
 }
 
 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 @@ get_entry_number (grub_menu_t menu, const char *name)
 
       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;
index 1f23a23636e36265b2ea0396853ed4e06189bf18..ee2b5e910457806da0a105141b74b21200197886 100644 (file)
@@ -32,6 +32,9 @@ struct grub_menu_entry
   /* The title name.  */
   const char *title;
 
+  /* The identifier.  */
+  const char *id;
+
   /* If set means not everybody is allowed to boot this entry.  */
   int restricted;
 
index b6b7d288d940ed14d52312ec32a2815a28874e76..00f8f1b7d494b347cfe44ae01213be078d170121 100644 (file)
@@ -120,6 +120,7 @@ extern int grub_extractor_level;
 
 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);
index e776ef07b6f34351493e0aec48a2be873095d2a7..ab3b934e0e7254466cd19eef93ce6d69621b6a9e 100644 (file)
@@ -162,6 +162,16 @@ prepare_grub_to_access_device ()
   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
index 217067c17ac7a51c02f24ebebbd5b14595cecdda..765bfdcd30e30c2d038dc37d97d3ddc7c573d950 100644 (file)
@@ -63,6 +63,15 @@ set default="${GRUB_DEFAULT}"
 EOF
 fi
 cat <<EOF
+
+if [ x"\${feature_menuentry_id}" = xy ]; then
+  menuentry_id_option="--id"
+else
+  menuentry_id_option=""
+fi
+
+export menuentry_id_option
+
 if [ "\${prev_saved_entry}" ]; then
   set saved_entry="\${prev_saved_entry}"
   save_env saved_entry
index d9c2db12aff9149c46c90acf16c95ffff21ea491..4f77a8d3f0749dcf06c2bbf3fa59204e47fb995c 100644 (file)
@@ -85,9 +85,9 @@ do
   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'
index a4be7ba14abd3a944e9f488d962c08de16b37a3e..e9bdf0872d476ea8d97cc3472c8b6953576c698e 100644 (file)
@@ -34,9 +34,9 @@ case "${GRUB_DISTRIBUTOR}" in
   ;;
 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
index c315512062666cd305d46b2dde89fa20a14a3790..a7294724fa43f8985cfe4579624e6e665b0af747 100644 (file)
@@ -74,7 +74,10 @@ kfreebsd_entry ()
   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 @@ list=`for i in /boot/kfreebsd-* /boot/kernel/kernel ; do
         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`
index 3791dec9d13526c16971e57f891e7844e538eabe..db1e81455cfda7f91d143ac1da335bb2e39ff5fd 100644 (file)
@@ -77,7 +77,10 @@ linux_entry ()
   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 @@ esac
 
 prepare_boot_cache=
 prepare_root_cache=
+boot_device_id=
 
 while [ "x$list" != "x" ] ; do
   linux=`version_find_latest $list`
index 236842da1cb9c0e4db77046b2816cf73c9cb67f2..3f03a380b9e73d13fbf3f17529da177e130a63ee 100644 (file)
@@ -99,7 +99,10 @@ netbsd_entry ()
     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 @@ netbsd_entry ()
 }
 
 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
index 623b8c61557ed6550e7311463b11ecc0c19ac1f0..63b748d0f7baf3474ff9d10210128c6d18ab858a 100644 (file)
@@ -63,14 +63,16 @@ for drv in $drives ; do
   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 @@ for drv in $drives ; do
 
   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,'
index 09ba2f0f1524be5140c8a5c80fc518b0b023d7a2..1fc34377c188e81e9d205022baee74c84968d24c 100644 (file)
@@ -87,7 +87,10 @@ linux_entry ()
   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 @@ xen_list=`for i in /boot/xen*; do
         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 @@ while [ "x${xen_list}" != "x" ] ; do
     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
index 4be888866a9bdf4fbdf8e332a58f37dafa464aa3..6ef4027e5e6b158599f8c92889d3edbdbb16cf5b 100644 (file)
@@ -52,7 +52,7 @@ osx_entry() {
     # 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
 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 @@ for OS in ${OSPROBED} ; do
 
          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 @@ EOF
     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 @@ EOF
        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 @@ EOF
     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/"