=== 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 #include #include +#include #ifdef GRUB_UTIL #include #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; + 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; } - -/* 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, + }; + + + 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).