All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFT] nested partition issues
@ 2010-09-04  0:07 Vladimir 'φ-coder/phcoder' Serbinenko
  2010-11-02  0:31 ` Grégoire Sutre
  0 siblings, 1 reply; 7+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-09-04  0:07 UTC (permalink / raw)
  To: The development of GRUB 2; +Cc: Fam Zheng, Grégoire Sutre


[-- Attachment #1.1: Type: text/plain, Size: 201 bytes --]

Hello. It was reported to me about several issues with nested
partitions. Please try attached patch and report  back any remaining
problems

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


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: nested.diff --]
[-- Type: text/x-diff; name="nested.diff", Size: 12216 bytes --]

=== modified file 'Makefile.util.def'
--- Makefile.util.def	2010-08-31 23:09:00 +0000
+++ Makefile.util.def	2010-09-03 23:04:39 +0000
@@ -89,6 +89,7 @@
   common = grub-core/partmap/msdos.c;
   common = grub-core/partmap/sun.c;
   common = grub-core/partmap/sunpc.c;
+  common = grub-core/partmap/bsdlabel.c;
   common = grub-core/script/function.c;
   common = grub-core/script/lexer.c;
   common = grub-core/script/main.c;

=== modified file 'grub-core/disk/efi/efidisk.c'
--- grub-core/disk/efi/efidisk.c	2010-02-16 12:13:02 +0000
+++ grub-core/disk/efi/efidisk.c	2010-09-03 23:29:51 +0000
@@ -731,7 +731,7 @@
     {
       /* This is a hard disk partition.  */
       grub_disk_t parent = 0;
-      char *partition_name = 0;
+      const grub_partition_t tpart = NULL;
       char *device_name;
       grub_efi_device_path_t *dup_dp, *dup_ldp;
       grub_efi_hard_drive_device_path_t hd;
@@ -770,7 +770,7 @@
 	  if (grub_partition_get_start (part) == hd.partition_start
 	      && grub_partition_get_len (part) == hd.partition_size)
 	    {
-	      partition_name = grub_partition_get_name (part);
+	      tpart = part;
 	      return 1;
 	    }
 
@@ -799,13 +799,15 @@
       grub_memcpy (&hd, ldp, sizeof (hd));
       grub_partition_iterate (parent, find_partition);
 
-      if (! partition_name)
+      if (! tpart)
 	{
 	  grub_disk_close (parent);
 	  return 0;
 	}
 
-      device_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
+      device_name = grub_xasprintf ("%s,%s%d", parent->name,
+				    tpart->partmap->name,
+				    tpart->number + 1);
       grub_free (partition_name);
       grub_disk_close (parent);
 

=== modified file 'grub-core/kern/device.c'
--- grub-core/kern/device.c	2010-03-31 20:03:48 +0000
+++ grub-core/kern/device.c	2010-09-03 23:29:23 +0000
@@ -135,28 +135,22 @@
 
   int iterate_partition (grub_disk_t disk, const grub_partition_t partition)
     {
-      char *partition_name;
       struct part_ent *p;
 
-      partition_name = grub_partition_get_name (partition);
-      if (! partition_name)
-	return 1;
 
       p = grub_malloc (sizeof (*p));
       if (!p)
 	{
-	  grub_free (partition_name);
 	  return 1;
 	}
 
-      p->name = grub_xasprintf ("%s,%s", disk->name, partition_name);
+      p->name = grub_xasprintf ("%s,%s%d", disk->name, partition->partmap->name,
+				partition->number + 1);
       if (!p->name)
 	{
-	  grub_free (partition_name);
 	  grub_free (p);
 	  return 1;
 	}
-      grub_free (partition_name);
 
       p->next = ents;
       ents = p;

=== modified file 'grub-core/normal/completion.c'
--- grub-core/normal/completion.c	2010-08-28 13:31:21 +0000
+++ grub-core/normal/completion.c	2010-09-03 23:29:36 +0000
@@ -100,15 +100,10 @@
 iterate_partition (grub_disk_t disk, const grub_partition_t p)
 {
   const char *disk_name = disk->name;
-  char *partition_name = grub_partition_get_name (p);
   char *name;
   int ret;
 
-  if (! partition_name)
-    return 1;
-
-  name = grub_xasprintf ("%s,%s", disk_name, partition_name);
-  grub_free (partition_name);
+  name = grub_xasprintf ("%s,%s%d", disk_name, p->partmap->name, p->number + 1);
 
   if (! name)
     return 1;

=== modified file 'grub-core/partmap/bsdlabel.c'
--- grub-core/partmap/bsdlabel.c	2010-07-16 23:57:48 +0000
+++ grub-core/partmap/bsdlabel.c	2010-09-03 23:13:07 +0000
@@ -23,18 +23,23 @@
 #include <grub/mm.h>
 #include <grub/misc.h>
 #include <grub/dl.h>
+#include <grub/msdos_partition.h>
 
 #ifdef GRUB_UTIL
 #include <grub/util/misc.h>
 #endif
 
 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;
+
 \f
 
 static grub_err_t
-bsdlabel_partition_map_iterate (grub_disk_t disk,
-				int (*hook) (grub_disk_t disk,
-					     const grub_partition_t partition))
+iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
+	      struct grub_partition_map *pmap,
+	      int (*hook) (grub_disk_t disk,
+			   const grub_partition_t partition))
 {
   struct grub_partition_bsd_disk_label label;
   struct grub_partition p;
@@ -42,8 +47,7 @@
   unsigned pos;
 
   /* Read the BSD label.  */
-  if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR,
-		      0, sizeof (label), &label))
+  if (grub_disk_read (disk, sector, 0, sizeof (label), &label))
     return grub_errno;
 
   /* Check if it is valid.  */
@@ -52,12 +56,12 @@
 
   /* A kludge to determine a base of be.offset.  */
   if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION
-      < grub_cpu_to_le16 (label.num_partitions))
+      < grub_cpu_to_le16 (label.num_partitions) && freebsd)
     {
       struct grub_partition_bsd_entry whole_disk_be;
 
-      pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
-	* GRUB_DISK_SECTOR_SIZE + sizeof (struct grub_partition_bsd_entry)
+      pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE
+	+ sizeof (struct grub_partition_bsd_entry)
 	* GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION;
 
       if (grub_disk_read (disk, pos / GRUB_DISK_SECTOR_SIZE,
@@ -68,8 +72,7 @@
       delta = grub_le_to_cpu32 (whole_disk_be.offset);
     }
 
-  pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
-    * GRUB_DISK_SECTOR_SIZE;
+  pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE;
 
   for (p.number = 0;
        p.number < grub_cpu_to_le16 (label.num_partitions);
@@ -88,13 +91,7 @@
 
       p.start = grub_le_to_cpu32 (be.offset);
       p.len = grub_le_to_cpu32 (be.size);
-      p.partmap = &grub_bsdlabel_partition_map;
-
-      grub_dprintf ("partition",
-		    "partition %d: type 0x%x, start 0x%llx, len 0x%llx\n",
-		    p.number, be.fs_type,
-		    (unsigned long long) p.start,
-		    (unsigned long long) p.len);
+      p.partmap = pmap;
 
       if (p.len == 0)
 	continue;
@@ -103,13 +100,6 @@
 	{
 #ifdef GRUB_UTIL
 	  char *partname;
-#endif
-	  grub_dprintf ("partition",
-			"partition %d: invalid start (found 0x%llx, wanted >= 0x%llx)\n",
-			p.number,
-			(unsigned long long) p.start,
-			(unsigned long long) delta);
-#ifdef GRUB_UTIL
 	  /* disk->partition != NULL as 0 < delta */
 	  partname = grub_partition_get_name (disk->partition);
 	  grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)",
@@ -124,24 +114,118 @@
       if (hook (disk, &p))
 	return grub_errno;
     }
-
   return GRUB_ERR_NONE;
 }
 
-\f
-/* Partition map type.  */
+static grub_err_t
+bsdlabel_partition_map_iterate (grub_disk_t disk,
+				int (*hook) (grub_disk_t disk,
+					     const grub_partition_t partition))
+{
+
+  if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
+      == 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD)
+    return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1,
+			 &grub_bsdlabel_partition_map, hook);
+
+  if (disk->partition 
+      && (grub_strcmp (disk->partition->partmap->name, "msdos") == 0
+	  || disk->partition->partmap == &grub_bsdlabel_partition_map
+	  || disk->partition->partmap == &grub_netbsdlabel_partition_map
+	  || disk->partition->partmap == &grub_openbsdlabel_partition_map))
+      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);
+}
+
+static grub_err_t
+netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type,
+				       struct grub_partition_map *pmap,
+				       int (*hook) (grub_disk_t disk,
+						    const grub_partition_t partition))
+{
+  grub_err_t err;
+
+  if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
+      == 0)
+    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
+
+  {
+    struct grub_msdos_partition_mbr mbr;
+    unsigned i;
+
+    err = grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr);
+    if (err)
+      return err;
+
+    for (i = 0; i < ARRAY_SIZE (mbr.entries); i++)
+      if (mbr.entries[i].type == type)
+	{
+	  err = iterate_real (disk, mbr.entries[i].start
+			      + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, pmap,
+			      hook);
+	  if (err != GRUB_ERR_BAD_PART_TABLE)
+	    return err;
+	}
+  }
+
+  return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found");
+}
+
+static grub_err_t
+netbsdlabel_partition_map_iterate (grub_disk_t disk,
+				   int (*hook) (grub_disk_t disk,
+						const grub_partition_t partition))
+{
+  return netopenbsdlabel_partition_map_iterate (disk,
+						GRUB_PC_PARTITION_TYPE_NETBSD,
+						&grub_netbsdlabel_partition_map,
+						hook);
+}
+
+static grub_err_t
+openbsdlabel_partition_map_iterate (grub_disk_t disk,
+				   int (*hook) (grub_disk_t disk,
+						const grub_partition_t partition))
+{
+  return netopenbsdlabel_partition_map_iterate (disk,
+						GRUB_PC_PARTITION_TYPE_OPENBSD,
+						&grub_openbsdlabel_partition_map,
+						hook);
+}
+
+
 static struct grub_partition_map grub_bsdlabel_partition_map =
   {
     .name = "bsd",
     .iterate = bsdlabel_partition_map_iterate,
   };
 
+static struct grub_partition_map grub_openbsdlabel_partition_map =
+  {
+    .name = "openbsd",
+    .iterate = openbsdlabel_partition_map_iterate,
+  };
+
+static struct grub_partition_map grub_netbsdlabel_partition_map =
+  {
+    .name = "netbsd",
+    .iterate = netbsdlabel_partition_map_iterate,
+  };
+
+\f
+
 GRUB_MOD_INIT(part_bsd)
 {
   grub_partition_map_register (&grub_bsdlabel_partition_map);
+  grub_partition_map_register (&grub_netbsdlabel_partition_map);
+  grub_partition_map_register (&grub_openbsdlabel_partition_map);
 }
 
 GRUB_MOD_FINI(part_bsd)
 {
   grub_partition_map_unregister (&grub_bsdlabel_partition_map);
+  grub_partition_map_unregister (&grub_netbsdlabel_partition_map);
+  grub_partition_map_unregister (&grub_openbsdlabel_partition_map);
 }

=== modified file 'grub-core/partmap/msdos.c'
--- grub-core/partmap/msdos.c	2010-03-26 14:44:13 +0000
+++ grub-core/partmap/msdos.c	2010-09-03 22:48:07 +0000
@@ -37,6 +37,15 @@
   int labeln = 0;
   grub_disk_addr_t lastaddr;
   grub_disk_addr_t ext_offset;
+  grub_disk_addr_t delta = 0;
+
+  if (disk->partition && disk->partition->partmap == &grub_msdos_partition_map)
+    {
+      if (disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_LINUX_MINIX)
+	delta = disk->partition->offset;
+      else
+	return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
+    }
 
   p.offset = 0;
   ext_offset = 0;
@@ -81,8 +90,9 @@
 	{
 	  e = mbr.entries + p.index;
 
-	  p.start = p.offset + grub_le_to_cpu32 (e->start);
+	  p.start = p.offset + grub_le_to_cpu32 (e->start) - delta;
 	  p.len = grub_le_to_cpu32 (e->length);
+	  p.msdostype = e->type;
 
 	  grub_dprintf ("partition",
 			"partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",

=== modified file 'include/grub/partition.h'
--- include/grub/partition.h	2010-07-14 09:26:17 +0000
+++ include/grub/partition.h	2010-09-03 22:48:07 +0000
@@ -65,6 +65,10 @@
 
   /* The type partition map.  */
   grub_partition_map_t partmap;
+
+  /* The type of partition whne it's on MSDOS.
+     Used for embedding detection.  */
+  grub_uint8_t msdostype;
 };
 
 grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk,

=== modified file 'util/grub-install.in'
--- util/grub-install.in	2010-08-30 18:23:04 +0000
+++ util/grub-install.in	2010-09-03 23:18:51 +0000
@@ -332,7 +332,12 @@
 # filesystem will be accessible).
 partmap_module=
 for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do
-   partmap_module="$partmap_module part_$x";
+   case "$x" in
+       netbsd | openbsd) 
+	   partmap_module="$partmap_module part_bsd";;
+       *)
+	   partmap_module="$partmap_module part_$x";;
+   esac
 done
 
 # Device abstraction module, if any (lvm, raid).


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-01-07 10:32 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-04  0:07 [RFT] nested partition issues Vladimir 'φ-coder/phcoder' Serbinenko
2010-11-02  0:31 ` Grégoire Sutre
2010-11-02  9:25   ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-11-02 15:58     ` Grégoire Sutre
2010-11-14 22:31       ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-01-05 10:50       ` [RFT] NetBSD embedding regression fix Vladimir 'φ-coder/phcoder' Serbinenko
2011-01-07 10:32         ` Grégoire Sutre

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.