Support some annoying BSD and Minix subpartitions.
* Makefile.util.def (libgrub.a): Add grub-core/partmap/bsdlabel.c. * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Properly handle concatenation. * grub-core/kern/device.c (grub_device_iterate): Likewise. * grub-core/normal/completion.c (iterate_partition): Likewise. * grub-core/kern/disk.c (grub_disk_open): Make disk->name not contain partition. All users updated. * grub-core/partmap/bsdlabel.c (grub_netbsdlabel_partition_map): New struct. (grub_openbsdlabel_partition_map): Likewise. (bsdlabel_partition_map_iterate): Rename to .. (iterate_real): ... this. New arguments sector, freebsd and pmap. (bsdlabel_partition_map_iterate): New function. (netopenbsdlabel_partition_map_iterate): Likewise. (netbsdlabel_partition_map_iterate): Likewise. (openbsdlabel_partition_map_iterate): Likewise. (GRUB_MOD_INIT): Register new partmaps. (GRUB_MOD_FINI): Unregister new partmaps. * grub-core/partmap/msdos.c (pc_partition_map_iterate): Rename to ... (grub_partition_msdos_iterate): ... this. All users updated. Don't support embedding other than in a minix partition. * include/grub/msdos_partition.h (grub_partition_msdos_iterate): New proto. * include/grub/partition.h (grub_partition): New field msdostype. * util/grub-install.in: Handle openbsd and netbsd types being in part_bsd module.
This commit is contained in:
commit
74342e312f
11 changed files with 225 additions and 57 deletions
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
|||
2010-09-20 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Support some annoying BSD and Minix subpartitions.
|
||||
|
||||
* Makefile.util.def (libgrub.a): Add grub-core/partmap/bsdlabel.c.
|
||||
* grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name):
|
||||
Properly handle concatenation.
|
||||
* grub-core/kern/device.c (grub_device_iterate): Likewise.
|
||||
* grub-core/normal/completion.c (iterate_partition): Likewise.
|
||||
* grub-core/kern/disk.c (grub_disk_open): Make disk->name not
|
||||
contain partition. All users updated.
|
||||
* grub-core/partmap/bsdlabel.c (grub_netbsdlabel_partition_map): New
|
||||
struct.
|
||||
(grub_openbsdlabel_partition_map): Likewise.
|
||||
(bsdlabel_partition_map_iterate): Rename to ..
|
||||
(iterate_real): ... this. New arguments sector, freebsd and pmap.
|
||||
(bsdlabel_partition_map_iterate): New function.
|
||||
(netopenbsdlabel_partition_map_iterate): Likewise.
|
||||
(netbsdlabel_partition_map_iterate): Likewise.
|
||||
(openbsdlabel_partition_map_iterate): Likewise.
|
||||
(GRUB_MOD_INIT): Register new partmaps.
|
||||
(GRUB_MOD_FINI): Unregister new partmaps.
|
||||
* grub-core/partmap/msdos.c (pc_partition_map_iterate): Rename to ...
|
||||
(grub_partition_msdos_iterate): ... this. All users updated.
|
||||
Don't support embedding other than in a minix partition.
|
||||
* include/grub/msdos_partition.h (grub_partition_msdos_iterate): New
|
||||
proto.
|
||||
* include/grub/partition.h (grub_partition): New field msdostype.
|
||||
* util/grub-install.in: Handle openbsd and netbsd types being in
|
||||
part_bsd module.
|
||||
|
||||
2010-09-20 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Split mdraid.mod into mdraid09.mod and mdraid1x.mod.
|
||||
|
|
|
@ -82,6 +82,7 @@ library = {
|
|||
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;
|
||||
|
|
|
@ -727,7 +727,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
|||
{
|
||||
/* 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;
|
||||
|
@ -766,7 +766,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -795,14 +795,17 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
|||
grub_memcpy (&hd, ldp, sizeof (hd));
|
||||
grub_partition_iterate (parent, find_partition);
|
||||
|
||||
if (! partition_name)
|
||||
if (! tpart)
|
||||
{
|
||||
grub_disk_close (parent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
char *partition_name = grub_partition_get_name (tpart);
|
||||
device_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
|
||||
grub_free (partition_name);
|
||||
}
|
||||
grub_disk_close (parent);
|
||||
|
||||
return device_name;
|
||||
|
|
|
@ -135,28 +135,28 @@ grub_device_iterate (int (*hook) (const char *name))
|
|||
|
||||
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;
|
||||
char *part_name;
|
||||
|
||||
p = grub_malloc (sizeof (*p));
|
||||
if (!p)
|
||||
{
|
||||
grub_free (partition_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
p->name = grub_xasprintf ("%s,%s", disk->name, partition_name);
|
||||
if (!p->name)
|
||||
part_name = grub_partition_get_name (partition);
|
||||
if (!part_name)
|
||||
{
|
||||
grub_free (p);
|
||||
return 1;
|
||||
}
|
||||
p->name = grub_xasprintf ("%s,%s", disk->name, part_name);
|
||||
grub_free (part_name);
|
||||
if (!p->name)
|
||||
{
|
||||
grub_free (partition_name);
|
||||
grub_free (p);
|
||||
return 1;
|
||||
}
|
||||
grub_free (partition_name);
|
||||
|
||||
p->next = ents;
|
||||
ents = p;
|
||||
|
|
|
@ -248,10 +248,6 @@ grub_disk_open (const char *name)
|
|||
if (! disk)
|
||||
return 0;
|
||||
|
||||
disk->name = grub_strdup (name);
|
||||
if (! disk->name)
|
||||
goto fail;
|
||||
|
||||
p = find_part_sep (name);
|
||||
if (p)
|
||||
{
|
||||
|
@ -263,7 +259,13 @@ grub_disk_open (const char *name)
|
|||
|
||||
grub_memcpy (raw, name, len);
|
||||
raw[len] = '\0';
|
||||
disk->name = grub_strdup (raw);
|
||||
}
|
||||
else
|
||||
disk->name = grub_strdup (name);
|
||||
if (! disk->name)
|
||||
goto fail;
|
||||
|
||||
|
||||
for (dev = grub_disk_dev_list; dev; dev = dev->next)
|
||||
{
|
||||
|
|
|
@ -100,15 +100,16 @@ static int
|
|||
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;
|
||||
char *part_name;
|
||||
|
||||
if (! partition_name)
|
||||
part_name = grub_partition_get_name (p);
|
||||
if (! part_name)
|
||||
return 1;
|
||||
|
||||
name = grub_xasprintf ("%s,%s", disk_name, partition_name);
|
||||
grub_free (partition_name);
|
||||
name = grub_xasprintf ("%s,%s", disk_name, part_name);
|
||||
grub_free (part_name);
|
||||
|
||||
if (! name)
|
||||
return 1;
|
||||
|
|
|
@ -23,16 +23,21 @@
|
|||
#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;
|
||||
|
||||
|
||||
|
||||
static grub_err_t
|
||||
bsdlabel_partition_map_iterate (grub_disk_t disk,
|
||||
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))
|
||||
{
|
||||
|
@ -42,8 +47,7 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
|
|||
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 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
|
|||
|
||||
/* 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 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
|
|||
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 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
|
|||
|
||||
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 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
|
|||
{
|
||||
#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,138 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
|
|||
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);
|
||||
}
|
||||
|
||||
/* This is a total breakage. Even when net-/openbsd label is inside partition
|
||||
it actually describes the whole disk.
|
||||
*/
|
||||
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))
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
auto int check_msdos (grub_disk_t dsk,
|
||||
const grub_partition_t partition);
|
||||
|
||||
int check_msdos (grub_disk_t dsk,
|
||||
const grub_partition_t partition)
|
||||
{
|
||||
grub_err_t err;
|
||||
|
||||
if (partition->msdostype != type)
|
||||
return 0;
|
||||
|
||||
err = iterate_real (dsk, partition->start
|
||||
+ GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, pmap, hook);
|
||||
if (err == GRUB_ERR_NONE)
|
||||
{
|
||||
count++;
|
||||
return 1;
|
||||
}
|
||||
if (err == GRUB_ERR_BAD_PART_TABLE)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
grub_print_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
|
||||
== 0)
|
||||
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
|
||||
|
||||
{
|
||||
grub_err_t err;
|
||||
err = grub_partition_msdos_iterate (disk, check_msdos);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
if (!count)
|
||||
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found");
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
static struct grub_partition_map grub_msdos_partition_map;
|
||||
|
||||
|
||||
static grub_err_t
|
||||
pc_partition_map_iterate (grub_disk_t disk,
|
||||
grub_err_t
|
||||
grub_partition_msdos_iterate (grub_disk_t disk,
|
||||
int (*hook) (grub_disk_t disk,
|
||||
const grub_partition_t partition))
|
||||
{
|
||||
|
@ -37,6 +37,15 @@ pc_partition_map_iterate (grub_disk_t disk,
|
|||
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->start;
|
||||
else
|
||||
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
|
||||
}
|
||||
|
||||
p.offset = 0;
|
||||
ext_offset = 0;
|
||||
|
@ -81,8 +90,9 @@ pc_partition_map_iterate (grub_disk_t disk,
|
|||
{
|
||||
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",
|
||||
|
@ -251,7 +261,7 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int nsectors,
|
|||
static struct grub_partition_map grub_msdos_partition_map =
|
||||
{
|
||||
.name = "msdos",
|
||||
.iterate = pc_partition_map_iterate,
|
||||
.iterate = grub_partition_msdos_iterate,
|
||||
#ifdef GRUB_UTIL
|
||||
.embed = pc_partition_map_embed
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include <grub/symbol.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
|
||||
/* The signature. */
|
||||
#define GRUB_PC_PARTITION_SIGNATURE 0xaa55
|
||||
|
@ -114,4 +116,9 @@ grub_msdos_partition_is_extended (int type)
|
|||
|| type == GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED);
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_partition_msdos_iterate (grub_disk_t disk,
|
||||
int (*hook) (grub_disk_t disk,
|
||||
const grub_partition_t partition));
|
||||
|
||||
#endif /* ! GRUB_PC_PARTITION_HEADER */
|
||||
|
|
|
@ -77,6 +77,10 @@ struct grub_partition
|
|||
|
||||
/* 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,
|
||||
|
|
|
@ -470,7 +470,12 @@ fi
|
|||
# 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).
|
||||
|
|
Loading…
Reference in a new issue