[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [GRUB PARTUUID PATCH 1/2] Add PARTUUID detection support to grub-pro
From: |
Andrei Borzenkov |
Subject: |
Re: [GRUB PARTUUID PATCH 1/2] Add PARTUUID detection support to grub-probe |
Date: |
Wed, 27 Jul 2016 07:43:55 +0300 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 |
20.06.2016 04:37, Nicholas Vinson пишет:
> Add PARTUUID detection to grub-probe. The grub-probe utility is used by
> grub-mkconfig to determine the filesystem [GU]UID, so updating it to be
> able to return partition [GU]UIDs seemed like the natural choice. The
> other obvious choice was to rely on Linux userland tools and /dev file
> structure which would added to the runtime dependencies of grub-probe.
>
> Signed-off-by: Nicholas Vinson <address@hidden>
> ---
> grub-core/partmap/gpt.c | 2 ++
> grub-core/partmap/msdos.c | 12 ++++++++--
> include/grub/partition.h | 9 +++++++-
> util/grub-probe.c | 58
> +++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 78 insertions(+), 3 deletions(-)
>
> diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c
> index 83bcba7..fd0bbef 100644
> --- a/grub-core/partmap/gpt.c
> +++ b/grub-core/partmap/gpt.c
> @@ -99,6 +99,8 @@ grub_gpt_partition_map_iterate (grub_disk_t disk,
> if (grub_memcmp (&grub_gpt_partition_type_empty, &entry.type,
> sizeof (grub_gpt_partition_type_empty)))
> {
> + grub_memcpy(part.guid.gpt, entry.guid, sizeof(part.guid.gpt));
> +
> /* Calculate the first block and the size of the partition. */
> part.start = grub_le_to_cpu64 (entry.start) << sector_log;
> part.len = (grub_le_to_cpu64 (entry.end)
> diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c
> index 6d4b455..79bb5b2 100644
> --- a/grub-core/partmap/msdos.c
> +++ b/grub-core/partmap/msdos.c
> @@ -169,6 +169,13 @@ grub_partition_msdos_iterate (grub_disk_t disk,
> if (mbr.entries[i].flag & 0x7f)
> return grub_error (GRUB_ERR_BAD_PART_TABLE, "bad boot flag");
>
> + /*
> + * Copy off the NT Disk signature. Linux uses this to compute the
> + * PARTUUID. The disk signature is 440 bytes in and 4 bytes long.
> + */
> + if (p.offset == 0)
> + grub_memcpy(p.guid.mbr, mbr.code + 440, sizeof(p.guid.mbr));
> +
> /* Analyze DOS partitions. */
> for (p.index = 0; p.index < 4; p.index++)
> {
> @@ -191,7 +198,7 @@ grub_partition_msdos_iterate (grub_disk_t disk,
> if (! grub_msdos_partition_is_empty (e->type)
> && ! grub_msdos_partition_is_extended (e->type))
> {
> - p.number++;
> + p.guid.mbr[4] = ++p.number;
>
> if (hook (disk, &p, hook_data))
> return grub_errno;
> @@ -199,7 +206,7 @@ grub_partition_msdos_iterate (grub_disk_t disk,
> else if (p.number < 3)
> /* If this partition is a logical one, shouldn't increase the
> partition number. */
> - p.number++;
> + p.guid.mbr[4] = ++p.number;
> }
>
> /* Find an extended partition. */
> @@ -209,6 +216,7 @@ grub_partition_msdos_iterate (grub_disk_t disk,
>
> if (grub_msdos_partition_is_extended (e->type))
> {
> + p.guid.mbr[4] = 4 + i; // logical partitions start with 4.
> p.offset = ext_offset
> + (grub_le_to_cpu32 (e->start)
> << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS));
> diff --git a/include/grub/partition.h b/include/grub/partition.h
> index 7adb7ec..4a80bf7 100644
> --- a/include/grub/partition.h
> +++ b/include/grub/partition.h
> @@ -66,6 +66,13 @@ struct grub_partition
> /* The partition number. */
> int number;
>
> + /* Unique partition GUID. */
> + union
> + {
> + grub_uint8_t gpt[16];
> + grub_uint8_t mbr[5];
> + } guid;
> +
> /* The start sector (relative to parent). */
> grub_disk_addr_t start;
>
> @@ -84,7 +91,7 @@ struct grub_partition
> /* The type partition map. */
> grub_partition_map_t partmap;
>
> - /* The type of partition whne it's on MSDOS.
> + /* The type of partition when it's on MSDOS.
> Used for embedding detection. */
> grub_uint8_t msdostype;
> };
As long as this is used by grub-probe only there is no need to bloat
boot time code.
> diff --git a/util/grub-probe.c b/util/grub-probe.c
> index 8ac527d..5ea9c4c 100644
> --- a/util/grub-probe.c
> +++ b/util/grub-probe.c
> @@ -62,6 +62,7 @@ enum {
> PRINT_DRIVE,
> PRINT_DEVICE,
> PRINT_PARTMAP,
> + PRINT_PARTUUID,
> PRINT_ABSTRACTION,
> PRINT_CRYPTODISK_UUID,
> PRINT_HINT_STR,
> @@ -85,6 +86,7 @@ static const char *targets[] =
> [PRINT_DRIVE] = "drive",
> [PRINT_DEVICE] = "device",
> [PRINT_PARTMAP] = "partmap",
> + [PRINT_PARTUUID] = "partuuid",
> [PRINT_ABSTRACTION] = "abstraction",
> [PRINT_CRYPTODISK_UUID] = "cryptodisk_uuid",
> [PRINT_HINT_STR] = "hints_string",
> @@ -617,6 +619,62 @@ probe (const char *path, char **device_names, char delim)
> else if (print == PRINT_CRYPTODISK_UUID)
> probe_cryptodisk_uuid (dev->disk, delim);
>
> + else if (print == PRINT_PARTUUID && dev->disk->partition)
> + {
> + grub_uint8_t be_guid[16];
> + int i;
> + int guid_len;
> + if (strcmp(dev->disk->partition->partmap->name, "gpt") == 0)
> + {
> + guid_len = sizeof(dev->disk->partition->guid.gpt);
> + /**
> + * The GUID disk format is LE(4) LE(2) LE(2) BE(8).
> + * where LE(n) means n-bytes little-endian formatted and
> + * BE(n) means n-bytes big-endian formatted.
> + */
> + for(i = 3; i >= 0; i--)
> + {
> + be_guid[3 - i] = dev->disk->partition->guid.gpt[i];
> + }
> + for (i = 1; i >= 0; i--)
> + {
> + be_guid[5 - i] = dev->disk->partition->guid.gpt[i + 4];
> + be_guid[7 - i] = dev->disk->partition->guid.gpt[i + 6];
> + }
> + for (i = 7; i >= 0; i--)
> + {
> + be_guid[i + 8] = dev->disk->partition->guid.gpt[i + 8];
> + }
> + }
> + else if (strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
> + {
> + guid_len = sizeof(dev->disk->partition->guid.mbr);
> + /*
> + * First 4 bytes are in LE order and need to be swapped them
> to BE
> + * order.
> + */
> + for(i = 3; i >= 0; i--)
> + {
> + be_guid[3 - i] = dev->disk->partition->guid.mbr[i];
> + }
> + /* Adjust the last number so that it is 1-indexed. */
> + be_guid[4] = dev->disk->partition->guid.mbr[4] + 1;
> + }
> + for (i = 0; i < guid_len; i++)
> + {
> + switch(i)
> + {
> + case 4:
> + case 6:
> + case 8:
> + case 10:
> + printf("-");
> + default:
> + printf("%02x", be_guid[i]);
> + }
> + }
> + putchar(delim);
> + }
> else if (print == PRINT_PARTMAP)
> /* Check if dev->disk itself is contained in a partmap. */
> probe_partmap (dev->disk, delim);
>
You can simply read partition table and build UUID in place. See
PRINT_GPT_PARTTYPE as example.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [GRUB PARTUUID PATCH 1/2] Add PARTUUID detection support to grub-probe,
Andrei Borzenkov <=