grub-devel
[Top][All Lists]
Advanced

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

[PATCH vRESEND] Support openbsd disklabels embed in GPT


From: Vladimir Serbinenko
Subject: [PATCH vRESEND] Support openbsd disklabels embed in GPT
Date: Fri, 17 May 2024 10:40:05 +0300

Add support for bsdlabel as it's used by OpenBSD on GPT-partirioned hard drive.

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
---
 grub-core/partmap/bsdlabel.c | 80 +++++++++++++++++++++++++++++++-----
 include/grub/gpt_partition.h |  7 ++++
 2 files changed, 76 insertions(+), 11 deletions(-)

diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c
index 4e93faf1c..d966cd4e4 100644
--- a/grub-core/partmap/bsdlabel.c
+++ b/grub-core/partmap/bsdlabel.c
@@ -23,6 +23,7 @@
 #include <grub/mm.h>
 #include <grub/misc.h>
 #include <grub/dl.h>
+#include <grub/gpt_partition.h>
 #include <grub/msdos_partition.h>
 #include <grub/i18n.h>
 
@@ -32,6 +33,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
 #include <grub/emu/misc.h>
 #endif
 
+static const grub_guid_t openbsd_disklabel = 
GRUB_GPT_PARTITION_TYPE_OPENBSD_DISKLABEL;
+
 static struct grub_partition_map grub_bsdlabel_partition_map;
 static struct grub_partition_map grub_netbsdlabel_partition_map;
 static struct grub_partition_map grub_openbsdlabel_partition_map;
@@ -139,6 +142,23 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
          || disk->partition->partmap == &grub_openbsdlabel_partition_map))
       return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
 
+  if (disk->partition && grub_strcmp (disk->partition->partmap->name, "gpt") 
== 0)
+    {
+      struct grub_gpt_partentry entry;
+      int entry_valid = 1;
+      grub_partition_t part = disk->partition;
+      disk->partition = part->parent;
+      if (grub_disk_read (disk, part->offset, part->index,
+                         sizeof (entry), &entry))
+       {
+         grub_errno = GRUB_ERR_NONE;
+         entry_valid = 0;
+       }
+      disk->partition = part;
+      if (entry_valid && (grub_memcmp(&entry.type, &openbsd_disklabel, 
sizeof(openbsd_disklabel)) == 0))
+       return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
+  }
+
   return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0,
                       &grub_bsdlabel_partition_map, hook, hook_data);
 }
@@ -155,14 +175,10 @@ struct netopenbsdlabel_ctx
 
 /* Helper for netopenbsdlabel_partition_map_iterate.  */
 static int
-check_msdos (grub_disk_t dsk, const grub_partition_t partition, void *data)
+iterate_netopenbsd_subpart(grub_disk_t dsk, const grub_partition_t partition, 
struct netopenbsdlabel_ctx *ctx)
 {
-  struct netopenbsdlabel_ctx *ctx = data;
   grub_err_t err;
 
-  if (partition->msdostype != ctx->type)
-    return 0;
-
   err = iterate_real (dsk, partition->start
                      + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, ctx->pmap,
                      ctx->hook, ctx->hook_data);
@@ -180,6 +196,40 @@ check_msdos (grub_disk_t dsk, const grub_partition_t 
partition, void *data)
   return 0;
 }
 
+/* Helper for netopenbsdlabel_partition_map_iterate.  */
+static int
+check_msdos (grub_disk_t dsk, const grub_partition_t partition, void *data)
+{
+  struct netopenbsdlabel_ctx *ctx = data;
+
+  if (partition->msdostype != ctx->type)
+    return 0;
+
+  return iterate_netopenbsd_subpart(dsk, partition, ctx);
+}
+
+/* Helper for netopenbsdlabel_partition_map_iterate.  */
+static int
+check_gpt_openbsd (grub_disk_t dsk, const grub_partition_t partition, void 
*data)
+{
+  struct netopenbsdlabel_ctx *ctx = data;
+  struct grub_gpt_partentry entry;
+
+  if (grub_disk_read (dsk, partition->offset, partition->index,
+                     sizeof (entry), &entry))
+    {
+      grub_print_error();
+      return 0;
+    }
+
+  if (grub_memcmp(&entry.type, &openbsd_disklabel, sizeof(openbsd_disklabel)) 
!= 0)
+    {
+      return 0;
+    }
+
+  return iterate_netopenbsd_subpart(dsk, partition, ctx);
+}
+
 /* This is a total breakage. Even when net-/openbsd label is inside partition
    it actually describes the whole disk.
  */
@@ -189,8 +239,8 @@ netopenbsdlabel_partition_map_iterate (grub_disk_t disk, 
grub_uint8_t type,
                                       grub_partition_iterate_hook_t hook,
                                       void *hook_data)
 {
-  if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
-      == 0)
+  if (disk->partition &&
+      (grub_strcmp (disk->partition->partmap->name, "msdos") == 0 || 
grub_strcmp (disk->partition->partmap->name, "gpt") == 0))
     return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
 
   {
@@ -201,12 +251,20 @@ netopenbsdlabel_partition_map_iterate (grub_disk_t disk, 
grub_uint8_t type,
       .hook_data = hook_data,
       .count = 0
     };
-    grub_err_t err;
+    grub_err_t err_msdos;
 
-    err = grub_partition_msdos_iterate (disk, check_msdos, &ctx);
+    err_msdos = grub_partition_msdos_iterate (disk, check_msdos, &ctx);
+    if (err_msdos == GRUB_ERR_BAD_PART_TABLE && type == 
GRUB_PC_PARTITION_TYPE_OPENBSD)
+      {
+       grub_errno = GRUB_ERR_NONE;
+       if (grub_gpt_partition_map_iterate (disk, check_gpt_openbsd, &ctx))
+         return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found");
+      }
 
-    if (err)
-      return err;
+    if (err_msdos == GRUB_ERR_BAD_PART_TABLE)
+      grub_errno = GRUB_ERR_NONE;
+    else if (err_msdos)
+      return err_msdos;
     if (!ctx.count)
       return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found");
   }
diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h
index 292ea03f1..d199727b7 100644
--- a/include/grub/gpt_partition.h
+++ b/include/grub/gpt_partition.h
@@ -41,6 +41,13 @@
        { 0x85, 0xD2, 0xE1, 0xE9, 0x04, 0x34, 0xCF, 0xB3 }      \
   }
 
+#define GRUB_GPT_PARTITION_TYPE_OPENBSD_DISKLABEL \
+  { grub_cpu_to_le32_compile_time (0x824CC7A0U),\
+      grub_cpu_to_le16_compile_time (0x36A8), \
+      grub_cpu_to_le16_compile_time (0x11E3),         \
+       { 0x89, 0x0A, 0x95, 0x25, 0x19, 0xAD, 0x3F, 0x61 }      \
+  }
+
 struct grub_gpt_header
 {
   grub_uint8_t magic[8];
-- 
2.39.2




reply via email to

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