diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2022-09-04 18:53:25 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-09-05 16:19:41 +0200 |
commit | 11749b6108a942f8c301cb7718fa30436a55f923 (patch) | |
tree | 73fa6f560cae11c9df2031bd60279f0dfff6c84f | |
parent | Merge pull request #24561 from yuwata/loop-util-follow-ups (diff) | |
download | systemd-11749b6108a942f8c301cb7718fa30436a55f923.tar.xz systemd-11749b6108a942f8c301cb7718fa30436a55f923.zip |
repart: Add support for setting a partition's UUID to zero
This is useful when we need to fill in the UUID later, such as when
using verity partitions.
-rw-r--r-- | man/repart.d.xml | 4 | ||||
-rw-r--r-- | src/partition/repart.c | 56 | ||||
-rwxr-xr-x | test/units/testsuite-58.sh | 29 |
3 files changed, 79 insertions, 10 deletions
diff --git a/man/repart.d.xml b/man/repart.d.xml index d9ec521160..6a0a6b32b2 100644 --- a/man/repart.d.xml +++ b/man/repart.d.xml @@ -358,8 +358,8 @@ <listitem><para>The UUID to assign to the partition if none is assigned yet. Note that this setting is not used for matching. It is also not used when a UUID is already set for an existing partition. It is thus only used when a partition is newly created or when an existing one had a - all-zero UUID set. If not specified a UUID derived from the partition type is automatically - used.</para></listitem> + all-zero UUID set. If set to <literal>null</literal>, the UUID is set to all zeroes. If not specified + a UUID derived from the partition type is automatically used.</para></listitem> </varlistentry> <varlistentry> diff --git a/src/partition/repart.c b/src/partition/repart.c index 1d949696a4..ea8468dc29 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -138,6 +138,7 @@ struct Partition { sd_id128_t type_uuid; sd_id128_t current_uuid, new_uuid; + bool new_uuid_is_set; char *current_label, *new_label; bool dropped; @@ -1313,12 +1314,50 @@ static int config_parse_gpt_flags( return 0; } +static int config_parse_uuid( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Partition *partition = ASSERT_PTR(data); + int r; + + if (isempty(rvalue)) { + partition->new_uuid = SD_ID128_NULL; + partition->new_uuid_is_set = false; + return 0; + } + + if (streq(rvalue, "null")) { + partition->new_uuid = SD_ID128_NULL; + partition->new_uuid_is_set = true; + return 0; + } + + r = sd_id128_from_string(rvalue, &partition->new_uuid); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse 128bit ID/UUID, ignoring: %s", rvalue); + return 0; + } + + partition->new_uuid_is_set = true; + + return 0; +} + static int partition_read_definition(Partition *p, const char *path, const char *const *conf_file_dirs) { ConfigTableItem table[] = { { "Partition", "Type", config_parse_type, 0, &p->type_uuid }, { "Partition", "Label", config_parse_label, 0, &p->new_label }, - { "Partition", "UUID", config_parse_id128, 0, &p->new_uuid }, + { "Partition", "UUID", config_parse_uuid, 0, p }, { "Partition", "Priority", config_parse_int32, 0, &p->priority }, { "Partition", "Weight", config_parse_weight, 0, &p->weight }, { "Partition", "PaddingWeight", config_parse_weight, 0, &p->padding_weight }, @@ -2066,7 +2105,7 @@ static int context_dump_partitions(Context *context, const char *node) { t, TABLE_STRING, gpt_partition_type_uuid_to_string_harder(p->type_uuid, uuid_buffer), TABLE_STRING, empty_to_null(label) ?: "-", TABLE_SET_COLOR, empty_to_null(label) ? NULL : ansi_grey(), - TABLE_UUID, sd_id128_is_null(p->new_uuid) ? p->current_uuid : p->new_uuid, + TABLE_UUID, p->new_uuid_is_set ? p->new_uuid : p->current_uuid, TABLE_STRING, p->definition_path ? basename(p->definition_path) : "-", TABLE_SET_COLOR, p->definition_path ? NULL : ansi_grey(), TABLE_STRING, partname ?: "-", TABLE_SET_COLOR, partname ? NULL : ansi_highlight(), TABLE_UINT64, p->offset, @@ -2184,7 +2223,7 @@ static int partition_hint(const Partition *p, const char *node, char **ret) { goto done; } - if (!sd_id128_is_null(p->new_uuid)) + if (p->new_uuid_is_set) id = p->new_uuid; else if (!sd_id128_is_null(p->current_uuid)) id = p->current_uuid; @@ -3249,11 +3288,13 @@ static int context_acquire_partition_uuids_and_labels(Context *context) { if (!sd_id128_is_null(p->current_uuid)) p->new_uuid = p->current_uuid; /* Never change initialized UUIDs */ - else if (sd_id128_is_null(p->new_uuid)) { + else if (!p->new_uuid_is_set) { /* Not explicitly set by user! */ r = partition_acquire_uuid(context, p, &p->new_uuid); if (r < 0) return r; + + p->new_uuid_is_set = true; } if (!isempty(p->current_label)) { @@ -3369,8 +3410,6 @@ static int context_mangle_partitions(Context *context) { } if (!sd_id128_equal(p->new_uuid, p->current_uuid)) { - assert(!sd_id128_is_null(p->new_uuid)); - r = fdisk_partition_set_uuid(p->current_partition, SD_ID128_TO_UUID_STRING(p->new_uuid)); if (r < 0) return log_error_errno(r, "Failed to set partition UUID: %m"); @@ -3402,7 +3441,6 @@ static int context_mangle_partitions(Context *context) { assert(!p->new_partition); assert(p->offset % context->sector_size == 0); assert(p->new_size % context->sector_size == 0); - assert(!sd_id128_is_null(p->new_uuid)); assert(p->new_label); t = fdisk_new_parttype(); @@ -4042,8 +4080,10 @@ static int context_open_copy_block_paths( free_and_replace(p->copy_blocks_path, opened); /* When copying from an existing partition copy that partitions UUID if none is configured explicitly */ - if (sd_id128_is_null(p->new_uuid) && !sd_id128_is_null(uuid)) + if (!p->new_uuid_is_set && !sd_id128_is_null(uuid)) { p->new_uuid = uuid; + p->new_uuid_is_set = true; + } } return 0; diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh index 3c826b0829..fddcda3872 100755 --- a/test/units/testsuite-58.sh +++ b/test/units/testsuite-58.sh @@ -570,6 +570,34 @@ EOF assert_in "$imgs/21817.img2 : start= 104448, size= (100319| 98304)," "$output" } +test_zero_uuid() { + local defs imgs output + + defs="$(mktemp --directory "/tmp/test-repart.XXXXXXXXXX")" + imgs="$(mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")" + # shellcheck disable=SC2064 + trap "rm -rf '$defs' '$imgs'" RETURN + + # Test image with zero UUID. + + cat >"$defs/root.conf" <<EOF +[Partition] +Type=root-${architecture} +UUID=null +EOF + + systemd-repart --definitions="$defs" \ + --seed="$seed" \ + --dry-run=no \ + --empty=create \ + --size=auto \ + "$imgs/zero" + + output=$(sfdisk --dump "$imgs/zero") + + assert_in "$imgs/zero1 : start= 2048, size= 20480, type=${root_guid}, uuid=00000000-0000-0000-0000-000000000000" "$output" +} + test_sector() { local defs imgs output loop local start size ratio @@ -635,6 +663,7 @@ test_multiple_definitions test_copy_blocks test_unaligned_partition test_issue_21817 +test_zero_uuid # Valid block sizes on the Linux block layer are >= 512 and <= PAGE_SIZE, and # must be powers of 2. Which leaves exactly four different ones to test on |