grub-devel
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]