summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shared/gpt.h22
-rw-r--r--src/udev/udev-builtin-blkid.c90
2 files changed, 107 insertions, 5 deletions
diff --git a/src/shared/gpt.h b/src/shared/gpt.h
index 2956377b48..e23073e1f9 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 23a24da907..a49dd31b8b 100644
--- a/src/udev/udev-builtin-blkid.c
+++ b/src/udev/udev-builtin-blkid.c
@@ -29,6 +29,9 @@
#include <sys/stat.h>
#include <blkid/blkid.h>
+#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)