summaryrefslogtreecommitdiff
path: root/src/udev
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-03-07 02:35:19 +0100
committerLennart Poettering <lennart@poettering.net>2014-03-07 02:40:24 +0100
commitcbd353ce7787ab11a9aa193f35abb97548b3fcf2 (patch)
treee40e8acea16f120656268367ee82791eab086df1 /src/udev
parentd13394a88334441bf3092cf93804ba0f9c56d8e0 (diff)
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.
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)