From: Lennart Poettering Date: Fri, 7 Mar 2014 01:35:19 +0000 (+0100) Subject: udev-builtin-blkid: when we find a GPT partition marked as root disk on the same... X-Git-Tag: v211~83 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=cbd353ce7787ab11a9aa193f35abb97548b3fcf2 udev-builtin-blkid: when we find a GPT partition marked as root disk on the same disk as the ESP, expose a property on the udev device This is preparation for a logic to automatically discover the root partition to boot from if no partition has been configured explicitly. This makes use of our newly defined GPT type GUIDs for our root disks: #define GPT_ROOT_X86 SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a) #define GPT_ROOT_X86_64 SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09) We define differen GUIDs for different architectures to allow images which finde the right root partition for the appropriate arch. --- diff --git a/src/shared/gpt.h b/src/shared/gpt.h index 2956377b4..e23073e1f 100644 --- a/src/shared/gpt.h +++ b/src/shared/gpt.h @@ -21,8 +21,20 @@ #include "sd-id128.h" -#define GPT_ESP SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b) -#define GPT_ROOT SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09) -#define GPT_SWAP SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f) -#define GPT_HOME SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15) -#define GPT_SRV SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8) +/* We only support root disk discovery for x86 and x86-64 for now, + * since EFI for anything else doesn't really exist, and we only care + * for root partitions on the same disk as the EFI ESP. */ + +#define GPT_ROOT_X86 SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a) +#define GPT_ROOT_X86_64 SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09) + +#define GPT_ESP SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b) +#define GPT_SWAP SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f) +#define GPT_HOME SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15) +#define GPT_SRV SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8) + +#if defined(__x86_64__) +# define GPT_ROOT_NATIVE GPT_ROOT_X86_64 +#elif defined(__i386__) +# define GPT_ROOT_NATIVE GPT_ROOT_X86 +#endif diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c index 23a24da90..a49dd31b8 100644 --- a/src/udev/udev-builtin-blkid.c +++ b/src/udev/udev-builtin-blkid.c @@ -29,6 +29,9 @@ #include #include +#include "sd-id128.h" +#include "gpt.h" +#include "efivars.h" #include "udev.h" static void print_property(struct udev_device *dev, bool test, const char *name, const char *value) @@ -100,6 +103,85 @@ static void print_property(struct udev_device *dev, bool test, const char *name, } } +static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool test) { + +#if defined(GPT_ROOT_NATIVE) && defined(ENABLE_EFI) + + _cleanup_free_ char *root_id = NULL; + bool found_esp = false; + blkid_partlist pl; + int i, nvals, r; + + assert(pr); + + /* Iterate through the partitions on this disk, and see if the + * EFI ESP we booted from is on it. If so, find the first root + * disk, and add a property indicating its partition UUID. */ + + errno = 0; + pl = blkid_probe_get_partitions(pr); + if (!pl) + return errno ? -errno : -ENOMEM; + + nvals = blkid_partlist_numof_partitions(pl); + for (i = 0; i < nvals; i++) { + blkid_partition pp; + const char *stype, *sid; + sd_id128_t type; + + pp = blkid_partlist_get_partition(pl, i); + if (!pp) + continue; + + sid = blkid_partition_get_uuid(pp); + if (!sid) + continue; + + stype = blkid_partition_get_type_string(pp); + if (!stype) + continue; + + if (sd_id128_from_string(stype, &type) < 0) + continue; + + if (sd_id128_equal(type, GPT_ESP)) { + sd_id128_t id, esp; + + /* We found an ESP, let's see if it matches + * the ESP we booted from. */ + + if (sd_id128_from_string(sid, &id) < 0) + continue; + + r = efi_loader_get_device_part_uuid(&esp); + if (r < 0) + return r; + + if (sd_id128_equal(id, esp)) + found_esp = true; + + } else if (sd_id128_equal(type, GPT_ROOT_NATIVE)) { + + /* We found a suitable root partition, let's + * remember the first one. */ + + if (!root_id) { + root_id = strdup(sid); + if (!root_id) + return -ENOMEM; + } + } + } + + /* We found the ESP on this disk, and also found a root + * partition, nice! Let's export its UUID*/ + if (found_esp && root_id) + udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT", root_id); +#endif + + return 0; +} + static int probe_superblocks(blkid_probe pr) { struct stat st; @@ -145,6 +227,7 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t int i; size_t len; int err = 0; + bool is_gpt = false; static const struct option options[] = { { "offset", optional_argument, NULL, 'o' }, @@ -203,10 +286,17 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t for (i = 0; i < nvals; i++) { if (blkid_probe_get_value(pr, i, &name, &data, &len)) continue; + len = strnlen((char *) data, len); print_property(dev, test, name, (char *) data); + + if (streq(name, "PTTYPE") && streq(data, "gpt")) + is_gpt = true; } + if (is_gpt) + find_gpt_root(dev, pr, test); + blkid_free_probe(pr); out: if (err < 0)