All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Cc: "Fam Zheng" <famcool@gmail.com>,
	"Grégoire Sutre" <gregoire.sutre@gmail.com>
Subject: [RFT] nested partition issues
Date: Sat, 04 Sep 2010 02:07:24 +0200	[thread overview]
Message-ID: <4C818DBC.10002@gmail.com> (raw)


[-- 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 --]

             reply	other threads:[~2010-09-04  0:07 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-04  0:07 Vladimir 'φ-coder/phcoder' Serbinenko [this message]
2010-11-02  0:31 ` [RFT] nested partition issues 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C818DBC.10002@gmail.com \
    --to=phcoder@gmail.com \
    --cc=famcool@gmail.com \
    --cc=gregoire.sutre@gmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.