On Mon, Aug 3, 2009 at 12:17 AM, Robert Millan<r...@aybabtu.com> wrote: > On Fri, Jul 31, 2009 at 09:48:21PM +0200, Vladimir 'phcoder' Serbinenko wrote: >> >> The proble it doesn't solve is when 2 partition labels pretend to >> describe the same region. Solaris during install dd'es MBR to its >> partition that it subdivides in further paritions. This way the >> parition seems to have 2 valid subpartitioning tables. I think the >> most sane way to handle this is to introduce partition labels >> priority. > > Priority lists sound like an overkill solution. I'm not sure that you see the problem. Let's say we have a disk containing sun_pc label. sun_pc uses only sector number 1. So in sector 0 you can put a standard msdos. So the same area is described by 2 labels and grub has decide which to choose. If it was a purely theoretical situation I wouldn't care. Unfortunately it's the situation one encounters with opensolaris installer or if a bootsector contains a lookalike of msdos partition (64 bytes zeros plus a bootsector signature is a valid msdos label). You can look at the patch if you want (I wasn't going to submit it yet actually). It adds only 14 bytes to core size (first version added 6 but had a bug fixing which added another 8 bytes) > In practice, how many > times are we going to recurse at most? In practise we probably won't have more than 2 levels of partitions. But code for just 2 levels and for unlimited number of levels is of the same complexity. So I prefer to avoid artitficial limit. But AFAIK no OS is able to load from a 3-nested partition except perhaps using tricks like loopbacks. I'm aware of 4 situations when nested partitions are used BSDlabel inside msdos for *BSD sun_pc (patch ready but not submitted yet) inside msdos for OpenSolaris. msdos inside msdos for minix msdos inside GPT is described in GPT specification but I never saw it to be used I vaguely heard of sun partitions inside apple partitions and AROS mixing amiga and msdos
> > -- > Robert Millan > > The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and > how) you may access your data; but nobody's threatening your freedom: we > still allow you to remove your data and not access it at all." > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel > -- Regards Vladimir 'phcoder' Serbinenko Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
diff --git a/conf/common.rmk b/conf/common.rmk index dbbf38f..0c4873d 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -13,6 +13,7 @@ grub_probe_SOURCES = util/grub-probe.c \ util/hostdisk.c util/misc.c util/getroot.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ kern/parser.c kern/partition.c kern/file.c \ + kern/list.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index c213bfd..cfdc50f 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -100,6 +100,7 @@ grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ util/misc.c util/getroot.c kern/device.c kern/disk.c \ kern/err.c kern/misc.c kern/parser.c kern/partition.c \ kern/file.c kern/fs.c kern/env.c fs/fshelp.c \ + kern/list.c \ \ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ diff --git a/include/grub/partition.h b/include/grub/partition.h index 6c0939b..6e50661 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -28,16 +28,19 @@ typedef struct grub_partition *grub_partition_t; /* Partition map type. */ struct grub_partition_map { + /* The next partition map type. */ + struct grub_partition_map *next; + /* The name of the partition map type. */ const char *name; + /* Priority of this partition map. */ + int prio; + /* Call HOOK with each partition, until HOOK returns non-zero. */ grub_err_t (*iterate) (struct grub_disk *disk, int (*hook) (struct grub_disk *disk, const grub_partition_t partition)); - - /* The next partition map type. */ - struct grub_partition_map *next; }; typedef struct grub_partition_map *grub_partition_map_t; diff --git a/kern/partition.c b/kern/partition.c index aa7161f..415765a 100644 --- a/kern/partition.c +++ b/kern/partition.c @@ -20,39 +20,35 @@ #include <grub/mm.h> #include <grub/partition.h> #include <grub/disk.h> +#include <grub/list.h> static grub_partition_map_t grub_partition_map_list; +static int test (grub_partition_map_t new_item, grub_partition_map_t item) +{ + return new_item->prio > item->prio; +} + void grub_partition_map_register (grub_partition_map_t partmap) { - partmap->next = grub_partition_map_list; - grub_partition_map_list = partmap; + grub_list_insert (GRUB_AS_LIST_P (&grub_partition_map_list), + GRUB_AS_LIST (partmap), + (grub_list_test_t) test); } void grub_partition_map_unregister (grub_partition_map_t partmap) { - grub_partition_map_t *p, q; - - for (p = &grub_partition_map_list, q = *p; q; p = &(q->next), q = q->next) - if (q == partmap) - { - *p = q->next; - break; - } + grub_list_remove (GRUB_AS_LIST_P (&grub_partition_map_list), + GRUB_AS_LIST (partmap)); } int grub_partition_map_iterate (int (*hook) (const grub_partition_map_t partmap)) { - grub_partition_map_t p; - - for (p = grub_partition_map_list; p; p = p->next) - if (hook (p)) - return 1; - - return 0; + return grub_list_iterate (GRUB_AS_LIST (grub_partition_map_list), + (grub_list_hook_t) hook); } static grub_partition_t diff --git a/partmap/acorn.c b/partmap/acorn.c index 0318beb..9d4bdce 100644 --- a/partmap/acorn.c +++ b/partmap/acorn.c @@ -131,6 +131,7 @@ acorn_partition_map_iterate (grub_disk_t disk, static struct grub_partition_map grub_acorn_partition_map = { .name = "Linux/ADFS partition map", + .prio = 10, .iterate = acorn_partition_map_iterate, }; diff --git a/partmap/amiga.c b/partmap/amiga.c index 4f5c9dd..2cee986 100644 --- a/partmap/amiga.c +++ b/partmap/amiga.c @@ -136,6 +136,7 @@ amiga_partition_map_iterate (grub_disk_t disk, /* Partition map type. */ static struct grub_partition_map grub_amiga_partition_map = { + .prio = 10, .name = "amiga_partition_map", .iterate = amiga_partition_map_iterate, }; diff --git a/partmap/apple.c b/partmap/apple.c index 09259a1..3a67b78 100644 --- a/partmap/apple.c +++ b/partmap/apple.c @@ -172,6 +172,7 @@ apple_partition_map_iterate (grub_disk_t disk, /* Partition map type. */ static struct grub_partition_map grub_apple_partition_map = { + .prio = 5, .name = "apple_partition_map", .iterate = apple_partition_map_iterate, }; diff --git a/partmap/bsdlabel.c b/partmap/bsdlabel.c index f376dce..d007105 100644 --- a/partmap/bsdlabel.c +++ b/partmap/bsdlabel.c @@ -73,6 +73,7 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, static struct grub_partition_map grub_bsdlabel_partition_map = { .name = "bsdlabel_partition_map", + .prio = 5, .iterate = bsdlabel_partition_map_iterate, }; diff --git a/partmap/gpt.c b/partmap/gpt.c index e258297..d51c8b3 100644 --- a/partmap/gpt.c +++ b/partmap/gpt.c @@ -112,6 +112,7 @@ gpt_partition_map_iterate (grub_disk_t disk, /* Partition map type. */ static struct grub_partition_map grub_gpt_partition_map = { + .prio = 10, .name = "gpt_partition_map", .iterate = gpt_partition_map_iterate, }; diff --git a/partmap/pc.c b/partmap/pc.c index fd9dc09..d9d3e6a 100644 --- a/partmap/pc.c +++ b/partmap/pc.c @@ -120,6 +120,7 @@ pc_partition_map_iterate (grub_disk_t disk, static struct grub_partition_map grub_pc_partition_map = { .name = "pc_partition_map", + .prio = 1, .iterate = pc_partition_map_iterate, }; diff --git a/partmap/sun.c b/partmap/sun.c index 63ba6ae..2c6ee44 100644 --- a/partmap/sun.c +++ b/partmap/sun.c @@ -138,6 +138,7 @@ sun_partition_map_iterate (grub_disk_t disk, static struct grub_partition_map grub_sun_partition_map = { .name = "sun_partition_map", + .prio = 10, .iterate = sun_partition_map_iterate, };
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel