grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2] search: Support searching for GPT partition label


From: Daniel Wagenknecht
Subject: [PATCH v2] search: Support searching for GPT partition label
Date: Fri, 9 Sep 2022 11:49:13 +0200

GPT partitions have a name property that is useable for identifying the
partition in Linux via root=PARTLABEL=<partlabel> boot argument or via
/dev/disk/by-partlabel/<partlabel>. Add support for searching for it in
GRUB. Compared to the fs label, the partition label does not change when
reformatting a partition.

Signed-off-by: Daniel Wagenknecht <dwagenknecht@emlix.com>
---

This is a resend of a patch from 2020. Glenn Washburn suggested to rebase and
resend with Daniel Kiper explicitely added to the recipients.

The rebase required some changes to adapt to the changes in no_floppy search
flags but is otherwise unchanged.

Tested by manually searching for a partition by GPT partition label in grub in
qemu.

Cheers
Daniel Wagenknecht


 grub-core/Makefile.core.def           |  5 +++
 grub-core/commands/search.c           | 57 +++++++++++++++++++++++++++
 grub-core/commands/search_partlabel.c |  5 +++
 grub-core/commands/search_wrap.c      |  9 ++++-
 include/grub/search.h                 |  3 ++
 5 files changed, 77 insertions(+), 2 deletions(-)
 create mode 100644 grub-core/commands/search_partlabel.c

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 5212dfab1..d76c47113 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1084,6 +1084,11 @@ module = {
   common = commands/search_label.c;
 };
 
+module = {
+  name = search_part_label;
+  common = commands/search_partlabel.c;
+};
+
 module = {
   name = setpci;
   common = commands/setpci.c;
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 263f1501c..56aa97278 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -30,6 +30,8 @@
 #include <grub/i18n.h>
 #include <grub/disk.h>
 #include <grub/partition.h>
+#include <grub/gpt_partition.h>
+#include <grub/charset.h>
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -54,6 +56,29 @@ struct search_ctx
   int is_cache;
 };
 
+/* helper for grub_search_part_label */
+static char *
+get_utf8 (grub_uint8_t *in, grub_size_t len)
+{
+  grub_uint8_t *buf;
+  grub_uint16_t *tmp;
+  grub_size_t i;
+
+  buf = grub_malloc (len *  GRUB_MAX_UTF8_PER_UTF16 + 1);
+  tmp = grub_malloc (len * sizeof (tmp[0]));
+  if (!buf || !tmp)
+    {
+      grub_free (buf);
+      grub_free (tmp);
+      return NULL;
+    }
+  for (i = 0; i < len; i++)
+    tmp[i] = grub_le_to_cpu16 (grub_get_unaligned16 (in + 2 * i));
+  *grub_utf16_to_utf8 (buf, tmp, len) = '\0';
+  grub_free (tmp);
+  return (char *) buf;
+}
+
 /* Helper for FUNC_NAME.  */
 static int
 iterate_device (const char *name, void *data)
@@ -110,6 +135,34 @@ iterate_device (const char *name, void *data)
        }
       grub_free (buf);
     }
+#elif defined (DO_SEARCH_PART_LABEL)
+    {
+      grub_device_t dev;
+      char *buf;
+
+      dev = grub_device_open (name);
+      if (dev && dev->disk && dev->disk->partition)
+       {
+         grub_partition_t p = dev->disk->partition;
+         grub_disk_t disk = grub_disk_open(dev->disk->name);
+
+         if (!disk)
+           return 1;
+         if (grub_strcmp (p->partmap->name, "gpt") == 0)
+           {
+             struct grub_gpt_partentry gptdata;
+
+             if (grub_disk_read (disk, p->offset, p->index, sizeof (gptdata), 
&gptdata))
+               return 1;
+             buf = get_utf8(gptdata.name, 36);
+             if (compare_fn (buf, ctx->key) == 0)
+               found = 1;
+             grub_free (buf);
+           }
+         grub_disk_close(disk);
+         grub_device_close (dev);
+       }
+    }
 #else
     {
       /* SEARCH_FS_UUID or SEARCH_LABEL */
@@ -333,6 +386,8 @@ static grub_command_t cmd;
 
 #ifdef DO_SEARCH_FILE
 GRUB_MOD_INIT(search_fs_file)
+#elif defined (DO_SEARCH_PART_LABEL)
+GRUB_MOD_INIT(search_part_label)
 #elif defined (DO_SEARCH_FS_UUID)
 GRUB_MOD_INIT(search_fs_uuid)
 #else
@@ -347,6 +402,8 @@ GRUB_MOD_INIT(search_label)
 
 #ifdef DO_SEARCH_FILE
 GRUB_MOD_FINI(search_fs_file)
+#elif defined (DO_SEARCH_PART_LABEL)
+GRUB_MOD_FINI(search_part_label)
 #elif defined (DO_SEARCH_FS_UUID)
 GRUB_MOD_FINI(search_fs_uuid)
 #else
diff --git a/grub-core/commands/search_partlabel.c 
b/grub-core/commands/search_partlabel.c
new file mode 100644
index 000000000..8784d909e
--- /dev/null
+++ b/grub-core/commands/search_partlabel.c
@@ -0,0 +1,5 @@
+#define DO_SEARCH_PART_LABEL 1
+#define FUNC_NAME grub_search_part_label
+#define COMMAND_NAME "search.part_label"
+#define HELP_MESSAGE N_("Search devices by GPT partition label. If VARIABLE is 
specified, the first device found is set to a variable.")
+#include "search.c"
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
index 318581f3b..6d1935bed 100644
--- a/grub-core/commands/search_wrap.c
+++ b/grub-core/commands/search_wrap.c
@@ -34,6 +34,8 @@ static const struct grub_arg_option options[] =
     {"file",           'f', 0, N_("Search devices by a file."), 0, 0},
     {"label",          'l', 0, N_("Search devices by a filesystem label."),
      0, 0},
+    {"part-label",     0,   0, N_("Search devices by a GPT partition label."),
+     0, 0},
     {"fs-uuid",                'u', 0, N_("Search devices by a filesystem 
UUID."),
      0, 0},
     {"set",            's', GRUB_ARG_OPTION_OPTIONAL,
@@ -71,6 +73,7 @@ enum options
   {
     SEARCH_FILE,
     SEARCH_LABEL,
+    SEARCH_PART_LABEL,
     SEARCH_FS_UUID,
     SEARCH_SET,
     SEARCH_NO_FLOPPY,
@@ -191,6 +194,8 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char 
**args)
 
   if (state[SEARCH_LABEL].set)
     grub_search_label (id, var, flags, hints, nhints);
+  else if (state[SEARCH_PART_LABEL].set)
+    grub_search_part_label (id, var, flags, hints, nhints);
   else if (state[SEARCH_FS_UUID].set)
     grub_search_fs_uuid (id, var, flags, hints, nhints);
   else if (state[SEARCH_FILE].set)
@@ -212,8 +217,8 @@ GRUB_MOD_INIT(search)
                          GRUB_COMMAND_FLAG_EXTRACTOR | 
GRUB_COMMAND_ACCEPT_DASH,
                          N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
                             " NAME"),
-                         N_("Search devices by file, filesystem label"
-                            " or filesystem UUID."
+                         N_("Search devices by file, filesystem label,"
+                            " GPT partition label or filesystem UUID."
                             " If --set is specified, the first device found is"
                             " set to a variable. If no variable name is"
                             " specified, `root' is used."),
diff --git a/include/grub/search.h b/include/grub/search.h
index ffd2411ca..ce61078a0 100644
--- a/include/grub/search.h
+++ b/include/grub/search.h
@@ -35,5 +35,8 @@ void grub_search_fs_uuid (const char *key, const char *var,
 void grub_search_label (const char *key, const char *var,
                        enum search_flags flags,
                        char **hints, unsigned nhints);
+void grub_search_part_label (const char *key, const char *var,
+                       enum search_flags flags,
+                       char **hints, unsigned nhints);
 
 #endif
-- 
2.36.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]