summaryrefslogtreecommitdiff
path: root/src/udev
diff options
context:
space:
mode:
Diffstat (limited to 'src/udev')
-rw-r--r--src/udev/udev-builtin-blkid.c90
1 files changed, 90 insertions, 0 deletions
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)