This introduces a new type() function for partmaps modeled after the label() and uuid() functions for filesystems. A likely future extension will be support partition labels and uuids as well. This is in preparation for adding more functionality like a search.part_type command.
The msdos partition code is only partially converted for now, I'm not sure about the preferred way to do this. Re-reading a msdos partition table is not as easy as re-reading gpt is. One option would be to turn 'msdostype' into a union or data pointer that partmap modules can stash extra info in. That would also allow gpt to avoid re-reading. Being new to grub, are there memory usage concerns I should be aware of here? --- grub-core/disk/ldm.c | 17 ++---------- grub-core/kern/partition.c | 23 +++++++++++++++++ grub-core/partmap/gpt.c | 61 ++++++++++++++++++++++++++++++-------------- grub-core/partmap/msdos.c | 9 +++++++ include/grub/gpt_partition.h | 20 +++------------ include/grub/partition.h | 11 ++++++++ util/grub-install.c | 34 ++++-------------------- util/grub-probe.c | 54 +++++++++++++++------------------------ 8 files changed, 117 insertions(+), 112 deletions(-) diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c index 8075f2a..6dcfbc8 100644 --- a/grub-core/disk/ldm.c +++ b/grub-core/disk/ldm.c @@ -135,31 +135,18 @@ msdos_has_ldm_partition (grub_disk_t dsk) return has_ldm; } -static const grub_gpt_part_type_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM; - /* Helper for gpt_ldm_sector. */ static int gpt_ldm_sector_iter (grub_disk_t disk, const grub_partition_t p, void *data) { grub_disk_addr_t *sector = data; - struct grub_gpt_partentry gptdata; - grub_partition_t p2; - - p2 = disk->partition; - disk->partition = p->parent; - if (grub_disk_read (disk, p->offset, p->index, - sizeof (gptdata), &gptdata)) - { - disk->partition = p2; - return 0; - } - disk->partition = p2; - if (! grub_memcmp (&gptdata.type, &ldm_type, 16)) + if (grub_partition_is_type (disk, p, "gpt", GRUB_GPT_PARTITION_TYPE_LDM)) { *sector = p->start + p->len - 1; return 1; } + return 0; } diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c index e499147..f27a8bd 100644 --- a/grub-core/kern/partition.c +++ b/grub-core/kern/partition.c @@ -274,3 +274,26 @@ grub_partition_get_name (const grub_partition_t partition) grub_memmove (out, ptr + 1, out + needlen - ptr); return out; } + +int grub_partition_is_type (struct grub_disk *disk, + const grub_partition_t partition, + const char *partmap_name, + const char *partition_type) +{ + char *type; + int r; + + if (!disk || !partition || !partition->partmap->type) + return 0; + + if (grub_strcmp (partition->partmap->name, partmap_name) != 0) + return 0; + + if (partition->partmap->type(disk, partition, &type) != 0) + return 0; + + r = grub_strcmp (type, partition_type); + grub_free (type); + + return r == 0; +} diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index 38df7b3..6d6c13f 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -33,11 +33,10 @@ static grub_uint8_t grub_gpt_magic[8] = 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54 }; -static const grub_gpt_part_type_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY; - -#ifdef GRUB_UTIL -static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; -#endif +static const grub_gpt_part_type_t grub_gpt_partition_type_empty = + { 0x0, 0x0, 0x0, + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + }; /* 512 << 7 = 65536 byte sectors. */ #define MAX_SECTOR_LOG 7 @@ -128,6 +127,40 @@ grub_gpt_partition_map_iterate (grub_disk_t disk, return GRUB_ERR_NONE; } +static grub_err_t +grub_gpt_partition_type (grub_disk_t disk, const grub_partition_t partition, + char **type) +{ + struct grub_gpt_partentry gptentry; + grub_gpt_part_type_t gpttype; + grub_partition_t p2; + grub_err_t err; + + p2 = disk->partition; + disk->partition = partition->parent; + err = grub_disk_read (disk, partition->offset, partition->index, + sizeof (gptentry), &gptentry); + disk->partition = p2; + + if (err) + return err; + + gpttype.data1 = grub_le_to_cpu32 (gptentry.type.data1); + gpttype.data2 = grub_le_to_cpu16 (gptentry.type.data2); + gpttype.data3 = grub_le_to_cpu16 (gptentry.type.data3); + grub_memcpy (gpttype.data4, gptentry.type.data4, sizeof (gpttype.data4)); + + *type = grub_xasprintf ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + gpttype.data1, gpttype.data2, + gpttype.data3, gpttype.data4[0], + gpttype.data4[1], gpttype.data4[2], + gpttype.data4[3], gpttype.data4[4], + gpttype.data4[5], gpttype.data4[6], + gpttype.data4[7]); + + return GRUB_ERR_NONE; +} + #ifdef GRUB_UTIL /* Context for gpt_partition_map_embed. */ struct gpt_partition_map_embed_ctx @@ -137,25 +170,14 @@ struct gpt_partition_map_embed_ctx /* Helper for gpt_partition_map_embed. */ static int -find_usable_region (grub_disk_t disk __attribute__ ((unused)), +find_usable_region (grub_disk_t disk, const grub_partition_t p, void *data) { struct gpt_partition_map_embed_ctx *ctx = data; - struct grub_gpt_partentry gptdata; - grub_partition_t p2; - - p2 = disk->partition; - disk->partition = p->parent; - if (grub_disk_read (disk, p->offset, p->index, - sizeof (gptdata), &gptdata)) - { - disk->partition = p2; - return 0; - } - disk->partition = p2; /* If there's an embed region, it is in a dedicated partition. */ - if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) + if (grub_partition_is_type(disk, p, "gpt", + GRUB_GPT_PARTITION_TYPE_BIOS_BOOT)) { ctx->start = p->start; ctx->len = p->len; @@ -215,6 +237,7 @@ static struct grub_partition_map grub_gpt_partition_map = { .name = "gpt", .iterate = grub_gpt_partition_map_iterate, + .type = grub_gpt_partition_type, #ifdef GRUB_UTIL .embed = gpt_partition_map_embed #endif diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index 1d81a53..68140a7 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -228,6 +228,14 @@ grub_partition_msdos_iterate (grub_disk_t disk, return grub_errno; } +static grub_err_t +grub_partition_msdos_type (grub_disk_t disk __attribute__ ((unused)), + const grub_partition_t partition, char **type) +{ + *type = grub_xasprintf ("%02x", partition->msdostype); + return GRUB_ERR_NONE; +} + #ifdef GRUB_UTIL #pragma GCC diagnostic ignored "-Wformat-nonliteral" @@ -415,6 +423,7 @@ static struct grub_partition_map grub_msdos_partition_map = { .name = "msdos", .iterate = grub_partition_msdos_iterate, + .type = grub_partition_msdos_type, #ifdef GRUB_UTIL .embed = pc_partition_map_embed #endif diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h index 1b32f67..566334c 100644 --- a/include/grub/gpt_partition.h +++ b/include/grub/gpt_partition.h @@ -31,24 +31,12 @@ struct grub_gpt_part_type } __attribute__ ((aligned(8))); typedef struct grub_gpt_part_type grub_gpt_part_type_t; -#define GRUB_GPT_PARTITION_TYPE_EMPTY \ - { 0x0, 0x0, 0x0, \ - { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } \ - } - #define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \ - { grub_cpu_to_le32_compile_time (0x21686148), \ - grub_cpu_to_le16_compile_time (0x6449), \ - grub_cpu_to_le16_compile_time (0x6e6f), \ - { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } \ - } - + "21686148-6449-6e6f-744e-656564454649" #define GRUB_GPT_PARTITION_TYPE_LDM \ - { grub_cpu_to_le32_compile_time (0x5808C8AAU),\ - grub_cpu_to_le16_compile_time (0x7E8F), \ - grub_cpu_to_le16_compile_time (0x42E0), \ - { 0x85, 0xD2, 0xE1, 0xE9, 0x04, 0x34, 0xCF, 0xB3 } \ - } + "5808c8aa-7e8f-42e0-85d2-e1e90434cfb3" +#define GRUB_GPT_PARTITION_TYPE_PREP \ + "9e1a2d38-c612-4316-aa26-8b49521e5a8b" struct grub_gpt_header { diff --git a/include/grub/partition.h b/include/grub/partition.h index 7adb7ec..3dc46bf 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -50,6 +50,13 @@ struct grub_partition_map /* Call HOOK with each partition, until HOOK returns non-zero. */ grub_err_t (*iterate) (struct grub_disk *disk, grub_partition_iterate_hook_t hook, void *hook_data); + + /* Return the type of the partition PARTITION in TYPE. + The type is returned in a grub_malloc'ed buffer and should + be freed by the caller. */ + grub_err_t (*type) (struct grub_disk *disk, + const grub_partition_t partition, char **type); + #ifdef GRUB_UTIL /* Determine sectors available for embedding. */ grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors, @@ -95,6 +102,10 @@ int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk, grub_partition_iterate_hook_t hook, void *hook_data); char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition); +int EXPORT_FUNC(grub_partition_is_type) (struct grub_disk *disk, + const grub_partition_t partition, + const char *partmap_name, + const char *partition_type); extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list); diff --git a/util/grub-install.c b/util/grub-install.c index 7d61c32..ee98b70 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -696,36 +696,12 @@ write_to_disk (grub_device_t dev, const char *fn) static int is_prep_partition (grub_device_t dev) { - if (!dev->disk) - return 0; - if (!dev->disk->partition) - return 0; - if (strcmp(dev->disk->partition->partmap->name, "msdos") == 0) - return (dev->disk->partition->msdostype == 0x41); - - if (strcmp (dev->disk->partition->partmap->name, "gpt") == 0) - { - struct grub_gpt_partentry gptdata; - grub_partition_t p = dev->disk->partition; - int ret = 0; - dev->disk->partition = dev->disk->partition->parent; + if (grub_partition_is_type (dev->disk, dev->disk->partition, "msdos", "41")) + return 1; - if (grub_disk_read (dev->disk, p->offset, p->index, - sizeof (gptdata), &gptdata) == 0) - { - const grub_gpt_part_type_t template = { - grub_cpu_to_le32_compile_time (0x9e1a2d38), - grub_cpu_to_le16_compile_time (0xc612), - grub_cpu_to_le16_compile_time (0x4316), - { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b } - }; - - ret = grub_memcmp (&template, &gptdata.type, - sizeof (template)) == 0; - } - dev->disk->partition = p; - return ret; - } + if (grub_partition_is_type (dev->disk, dev->disk->partition, + "gpt", GRUB_GPT_PARTITION_TYPE_PREP)) + return 1; return 0; } diff --git a/util/grub-probe.c b/util/grub-probe.c index ecb7b6b..a2505f0 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -27,7 +27,6 @@ #include <grub/fs.h> #include <grub/partition.h> #include <grub/msdos_partition.h> -#include <grub/gpt_partition.h> #include <grub/emu/hostdisk.h> #include <grub/emu/getroot.h> #include <grub/term.h> @@ -253,6 +252,25 @@ probe_abstraction (grub_disk_t disk, char delim) } static void +probe_partition_type(grub_disk_t disk, const char *partmap, char delim) +{ + char *type; + + if (!disk->partition || !disk->partition->partmap->type || + strcmp(disk->partition->partmap->name, partmap) != 0) + { + putchar (delim); + return; + } + + if (disk->partition->partmap->type(disk, disk->partition, &type)) + grub_util_error ("%s", grub_errmsg); + + printf ("%s%c", type, delim); + free(type); +} + +static void probe (const char *path, char **device_names, char delim) { char **drives_names = NULL; @@ -653,44 +671,14 @@ probe (const char *path, char **device_names, char delim) if (print == PRINT_MSDOS_PARTTYPE) { - if (dev->disk->partition - && strcmp(dev->disk->partition->partmap->name, "msdos") == 0) - printf ("%02x", dev->disk->partition->msdostype); - - putchar (delim); + probe_partition_type(dev->disk, "msdos", delim); grub_device_close (dev); continue; } if (print == PRINT_GPT_PARTTYPE) { - if (dev->disk->partition - && strcmp (dev->disk->partition->partmap->name, "gpt") == 0) - { - struct grub_gpt_partentry gptdata; - grub_partition_t p = dev->disk->partition; - dev->disk->partition = dev->disk->partition->parent; - - if (grub_disk_read (dev->disk, p->offset, p->index, - sizeof (gptdata), &gptdata) == 0) - { - grub_gpt_part_type_t gpttype; - gpttype.data1 = grub_le_to_cpu32 (gptdata.type.data1); - gpttype.data2 = grub_le_to_cpu16 (gptdata.type.data2); - gpttype.data3 = grub_le_to_cpu16 (gptdata.type.data3); - grub_memcpy (gpttype.data4, gptdata.type.data4, 8); - - grub_printf ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - gpttype.data1, gpttype.data2, - gpttype.data3, gpttype.data4[0], - gpttype.data4[1], gpttype.data4[2], - gpttype.data4[3], gpttype.data4[4], - gpttype.data4[5], gpttype.data4[6], - gpttype.data4[7]); - } - dev->disk->partition = p; - } - putchar (delim); + probe_partition_type(dev->disk, "gpt", delim); grub_device_close (dev); continue; } -- 1.8.5.5 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel