On Mon, Feb 28, 2011 at 11:27:34PM -0500, Andrew Lutomirski wrote: > I'm playing around with rewriting efibootmgr, and I want it to use > libblkid to figure out how to label disks. Unfortunately, there's a > bit of byte order confusion. libblkid treats gpt guids like they're > big-endian, which seems to contradict the spec and all other software. .. because UUID is according to all standards 16 byte array, except Intel EFI standard... > This means that the the first three fields should be byte-swapped. > Wikipedia's page on GPT agrees. Yes, you're right. Good catch. > Should I submit a patch to fix up the byte order? I don't think that > fixing this will break anyone's boot since findfs and friends seem to > use UUID not PART_ENTRY_UUID. Fixed in master branch, see the patch below (it's based on GNU parted). Thanks! Karel >From c2ec2ff9a2e85c6146ab9253a61a158d8aee8edc Mon Sep 17 00:00:00 2001 From: Karel Zak <kzak@xxxxxxxxxx> Date: Tue, 1 Mar 2011 10:01:21 +0100 Subject: [PATCH] libblkid: fix EFI GPT uuid byte order Intel uses little-endians for UUID, the rest of the sane world uses 16 byte big-endian array... Reported-by: Andrew Lutomirski <luto@xxxxxxx> Signed-off-by: Karel Zak <kzak@xxxxxxxxxx> --- shlibs/blkid/src/partitions/gpt.c | 34 +++++++++++++++++++++++----------- 1 files changed, 23 insertions(+), 11 deletions(-) diff --git a/shlibs/blkid/src/partitions/gpt.c b/shlibs/blkid/src/partitions/gpt.c index 8259c2f..7df17bb 100644 --- a/shlibs/blkid/src/partitions/gpt.c +++ b/shlibs/blkid/src/partitions/gpt.c @@ -32,20 +32,18 @@ typedef uint16_t efi_char16_t; /* UUID */ typedef struct { - uint8_t b[16]; + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi; + uint8_t clock_seq_low; + uint8_t node[6]; } efi_guid_t; -#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) ((efi_guid_t) \ - {{ \ - (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ - (b) & 0xff, ((b) >> 8) & 0xff, \ - (c) & 0xff, ((c) >> 8) & 0xff, \ - (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) \ -}}) - -#define GPT_UNUSED_ENTRY_GUID EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) +#define GPT_UNUSED_ENTRY_GUID \ + ((efi_guid_t) { 0x00000000, 0x0000, 0x0000, 0x00, 0x00, \ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}) struct gpt_header { uint64_t signature; /* "EFI PART" */ uint32_t revision; @@ -120,6 +118,17 @@ static inline int guidcmp(efi_guid_t left, efi_guid_t right) return memcmp(&left, &right, sizeof (efi_guid_t)); } +/* + * UUID is traditionaly 16 byte big-endian array, except Intel EFI + * specification where the UUID is a structure of little-endian fields. + */ +static void swap_efi_guid(efi_guid_t *uid) +{ + uid->time_low = swab32(uid->time_low); + uid->time_mid = swab16(uid->time_mid); + uid->time_hi_and_version = swab16(uid->time_hi_and_version); +} + static int last_lba(blkid_probe pr, uint64_t *lba) { blkid_loff_t sz = blkid_probe_get_size(pr); @@ -352,6 +361,9 @@ static int probe_gpt_pt(blkid_probe pr, const struct blkid_idmag *mag) (unsigned char *) e->partition_name, sizeof(e->partition_name), BLKID_ENC_UTF16LE); + swap_efi_guid(&e->unique_partition_guid); + swap_efi_guid(&e->partition_type_guid); + blkid_partition_set_uuid(par, (const unsigned char *) &e->unique_partition_guid); -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe util-linux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html