sd_id128_t type_uuid;
sd_id128_t current_uuid, new_uuid;
+ bool new_uuid_is_set;
char *current_label, *new_label;
bool dropped;
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 },
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,
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;
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)) {
}
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");
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();
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;
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
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