]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect: also parse out the top-level GPT table uuid and expose this as image UUID
authorLennart Poettering <lennart@poettering.net>
Thu, 20 Oct 2022 21:14:28 +0000 (23:14 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 10 Nov 2022 15:00:59 +0000 (16:00 +0100)
systemd-repart generates this in a suitably stable fashion, hence let's
actually use it as an identifier for the image. As a first step parse
it, and show it.

src/dissect/dissect.c
src/shared/dissect-image.c
src/shared/dissect-image.h

index 81764690e9975c53fe3f476e8f4c2a5c61bc8ccd..2512cd0f0b934d142d9d99f711221bbaea9c5745 100644 (file)
@@ -594,6 +594,9 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
         else if (arg_json_format_flags & JSON_FORMAT_OFF) {
                 _cleanup_strv_free_ char **sysext_scopes = NULL;
 
+                if (!sd_id128_is_null(m->image_uuid))
+                        printf("Image UUID: %s\n", SD_ID128_TO_UUID_STRING(m->image_uuid));
+
                 if (m->hostname)
                         printf("  Hostname: %s\n", m->hostname);
 
@@ -673,6 +676,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
 
                 r = json_build(&v, JSON_BUILD_OBJECT(
                                                JSON_BUILD_PAIR("name", JSON_BUILD_STRING(bn)),
+                                               JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->image_uuid), "imageUuid", JSON_BUILD_UUID(m->image_uuid)),
                                                JSON_BUILD_PAIR("size", JSON_BUILD_INTEGER(size)),
                                                JSON_BUILD_PAIR_CONDITION(m->hostname, "hostname", JSON_BUILD_STRING(m->hostname)),
                                                JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->machine_id), "machineId", JSON_BUILD_ID128(m->machine_id)),
index 2f1903121636aca5b88fd68e43b5055a38e5ab96..1d338fe3521c62753bb222997506a313c0ea0169 100644 (file)
@@ -349,7 +349,7 @@ static int dissect_image(
         _cleanup_(blkid_free_probep) blkid_probe b = NULL;
         _cleanup_free_ char *generic_node = NULL;
         sd_id128_t generic_uuid = SD_ID128_NULL;
-        const char *pttype = NULL;
+        const char *pttype = NULL, *sptuuid = NULL;
         blkid_partlist pl;
         int r, generic_nr = -1, n_partitions;
 
@@ -410,7 +410,7 @@ static int dissect_image(
         if ((flags & DISSECT_IMAGE_GPT_ONLY) == 0) {
                 /* Look for file system superblocks, unless we only shall look for GPT partition tables */
                 blkid_probe_enable_superblocks(b, 1);
-                blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE|BLKID_SUBLKS_USAGE);
+                blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE|BLKID_SUBLKS_USAGE|BLKID_SUBLKS_UUID);
         }
 
         blkid_probe_enable_partitions(b, 1);
@@ -433,8 +433,9 @@ static int dissect_image(
                 (void) blkid_probe_lookup_value(b, "USAGE", &usage, NULL);
                 if (STRPTR_IN_SET(usage, "filesystem", "crypto")) {
                         _cleanup_free_ char *t = NULL, *n = NULL, *o = NULL;
-                        const char *fstype = NULL, *options = NULL;
+                        const char *fstype = NULL, *options = NULL, *suuid = NULL;
                         _cleanup_close_ int mount_node_fd = -1;
+                        sd_id128_t uuid = SD_ID128_NULL;
 
                         if (FLAGS_SET(flags, DISSECT_IMAGE_OPEN_PARTITION_DEVICES)) {
                                 mount_node_fd = open_partition(devname, /* is_partition = */ false, m->loop);
@@ -444,6 +445,7 @@ static int dissect_image(
 
                         /* OK, we have found a file system, that's our root partition then. */
                         (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
+                        (void) blkid_probe_lookup_value(b, "UUID", &suuid, NULL);
 
                         if (fstype) {
                                 t = strdup(fstype);
@@ -451,6 +453,15 @@ static int dissect_image(
                                         return -ENOMEM;
                         }
 
+                        if (suuid) {
+                                /* blkid will return FAT's serial number as UUID, hence it is quite possible
+                                 * that parsing this will fail. We'll ignore the ID, since it's just too
+                                 * short to be useful as tru identifier. */
+                                r = sd_id128_from_string(suuid, &uuid);
+                                if (r < 0)
+                                        log_debug_errno(r, "Failed to parse file system UUID '%s', ignoring: %m", suuid);
+                        }
+
                         n = strdup(devname);
                         if (!n)
                                 return -ENOMEM;
@@ -467,6 +478,8 @@ static int dissect_image(
                         m->verity_sig_ready = m->verity_ready &&
                                 verity->root_hash_sig;
 
+                        m->image_uuid = uuid;
+
                         options = mount_options_from_designator(mount_options, PARTITION_ROOT);
                         if (options) {
                                 o = strdup(options);
@@ -515,6 +528,13 @@ static int dissect_image(
                         return -EPROTONOSUPPORT;
         }
 
+        (void) blkid_probe_lookup_value(b, "PTUUID", &sptuuid, NULL);
+        if (sptuuid) {
+                r = sd_id128_from_string(sptuuid, &m->image_uuid);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to parse partition table UUID '%s', ignoring: %m", sptuuid);
+        }
+
         errno = 0;
         pl = blkid_probe_get_partitions(b);
         if (!pl)
index 46675d22ab3a981f47ee810241560d4b095700b6..ccdc4d6f3520be9b3d08647cfcb0f0e272144975 100644 (file)
@@ -229,6 +229,7 @@ struct DissectedImage {
 
         /* Meta information extracted from /etc/os-release and similar */
         char *image_name;
+        sd_id128_t image_uuid;
         char *hostname;
         sd_id128_t machine_id;
         char **machine_info;