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 --]
next 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).