From b387778c5b8a1e0d1b3f957f0c5866defbfbe4d4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Oct 2022 23:14:28 +0200 Subject: [PATCH] dissect: also parse out the top-level GPT table uuid and expose this as image UUID 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 | 4 ++++ src/shared/dissect-image.c | 26 +++++++++++++++++++++++--- src/shared/dissect-image.h | 1 + 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 81764690e99..2512cd0f0b9 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -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)), diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 2f190312163..1d338fe3521 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -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) diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 46675d22ab3..ccdc4d6f352 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -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;