]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
repart: avoid label string clashes between LUKS superblocks and the filesystems on...
authorLennart Poettering <lennart@poettering.net>
Thu, 13 Nov 2025 09:09:50 +0000 (10:09 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 17 Nov 2025 14:37:14 +0000 (15:37 +0100)
Let's make sure that by default /dev/disk/by-label/ symlinks avoid
ambiguities, and the LUKS volume carries a different one than the file
system inside it.

Alternative-to: #39536
man/repart.d.xml
src/repart/repart.c

index 486fea96b9019e75706c056bcd5e0c31026c3bc0..22d50e2c636cfdbb003c820f1fa901bc588c30b2 100644 (file)
         <xi:include href="version-info.xml" xpointer="v245"/></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>VolumeLabel=</varname></term>
+
+        <listitem><para>The textual label to assign to the LUKS superblock if applicable. If not specified
+        defaults to the same string as the partition label (see <varname>Label=</varname> above), however
+        prefixed with <literal>luks-</literal>. This setting has no effect if encryption is not enabled for
+        this partition.</para>
+
+        <xi:include href="version-info.xml" xpointer="v259"/></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>UUID=</varname></term>
 
index d0087771d49dbbb20a26ba7b99472daeaee0f6c8..46ab02162526363f61870948470fc0604bb313cc 100644 (file)
@@ -398,7 +398,8 @@ typedef struct Partition {
         GptPartitionType type;
         sd_id128_t current_uuid, new_uuid;
         bool new_uuid_is_set;
-        char *current_label, *new_label;
+        char *current_label, *new_label;      /* Used for the GPT partition label + fs superblock label */
+        char *new_volume_label;               /* used for LUKS superblock */
         sd_id128_t fs_uuid, luks_uuid, verity_uuid;
         uint8_t verity_salt[SHA256_DIGEST_SIZE];
 
@@ -714,6 +715,7 @@ static Partition* partition_free(Partition *p) {
 
         free(p->current_label);
         free(p->new_label);
+        free(p->new_volume_label);
         free(p->definition_path);
         strv_free(p->drop_in_files);
 
@@ -2750,6 +2752,7 @@ static int partition_read_definition(
         ConfigTableItem table[] = {
                 { "Partition", "Type",                     config_parse_type,              0,                                  &p->type                    },
                 { "Partition", "Label",                    config_parse_label,             0,                                  &p->new_label               },
+                { "Partition", "VolumeLabel",              config_parse_label,             0,                                  &p->new_volume_label        },
                 { "Partition", "UUID",                     config_parse_uuid,              0,                                  p                           },
                 { "Partition", "Priority",                 config_parse_int32,             0,                                  &p->priority                },
                 { "Partition", "Weight",                   config_parse_weight,            0,                                  &p->weight                  },
@@ -3976,6 +3979,27 @@ static const char *partition_label(const Partition *p) {
         return gpt_partition_type_uuid_to_string(p->type.uuid);
 }
 
+static int volume_label(const Partition *p, char **ret) {
+        assert(p);
+        assert(ret);
+
+        if (p->new_volume_label)
+                return strdup_to(ret, p->new_volume_label);
+
+        const char *e = partition_label(p);
+        if (!e)
+                return -ENODATA;
+
+        /* Let's prefix "luks-" for the label string used for LUKS superblocks. We do this so that the
+         * /dev/disk/by-label/ symlink to the LUKS volume and the file system inside it do not clash */
+        char *j = strjoin("luks-", e);
+        if (!j)
+                return -ENOMEM;
+
+        *ret = j;
+        return 0;
+}
+
 static int context_dump_partitions(Context *context) {
         _cleanup_(table_unrefp) Table *t = NULL;
         uint64_t sum_padding = 0, sum_size = 0;
@@ -4966,21 +4990,6 @@ static int partition_target_sync(Context *context, Partition *p, PartitionTarget
 
 static int partition_encrypt(Context *context, Partition *p, PartitionTarget *target, bool offline) {
 #if HAVE_LIBCRYPTSETUP
-        const char *node = partition_target_path(target);
-        struct crypt_params_luks2 luks_params = {
-                .label = strempty(ASSERT_PTR(p)->new_label),
-                .sector_size = partition_fs_sector_size(context, p),
-                .data_device = offline ? node : NULL,
-        };
-        struct crypt_params_reencrypt reencrypt_params = {
-                .mode = CRYPT_REENCRYPT_ENCRYPT,
-                .direction = CRYPT_REENCRYPT_BACKWARD,
-                .resilience = "datashift",
-                .data_shift = LUKS2_METADATA_SIZE / 512,
-                .luks2 = &luks_params,
-                .flags = CRYPT_REENCRYPT_INITIALIZE_ONLY|CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT,
-        };
-        _cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
 #if HAVE_TPM2
         _cleanup_(erase_and_freep) char *base64_encoded = NULL;
 #endif
@@ -5001,6 +5010,26 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta
 
         log_info("Encrypting future partition %" PRIu64 "...", p->partno);
 
+        _cleanup_free_ char *vl = NULL;
+        r = volume_label(p, &vl);
+        if (r < 0)
+                return log_error_errno(r, "Failed to generate volume label: %m");
+
+        const char *node = partition_target_path(target);
+        struct crypt_params_luks2 luks_params = {
+                .label = vl,
+                .sector_size = partition_fs_sector_size(context, p),
+                .data_device = offline ? node : NULL,
+        };
+        struct crypt_params_reencrypt reencrypt_params = {
+                .mode = CRYPT_REENCRYPT_ENCRYPT,
+                .direction = CRYPT_REENCRYPT_BACKWARD,
+                .resilience = "datashift",
+                .data_shift = LUKS2_METADATA_SIZE / 512,
+                .luks2 = &luks_params,
+                .flags = CRYPT_REENCRYPT_INITIALIZE_ONLY|CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT,
+        };
+
         if (offline) {
                 r = var_tmp_dir(&vt);
                 if (r < 0)
@@ -5023,6 +5052,7 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta
                         return log_oom();
         }
 
+        _cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
         r = sym_crypt_init(&cd, offline ? hp : node);
         if (r < 0)
                 return log_error_errno(r, "Failed to allocate libcryptsetup context for %s: %m", hp);