repart: report the actual block device size in currentSizeBytes

The io.systemd.Repart interface documents the currentSizeBytes field as
the size of the selected block device, both in the Run() method's
dry-run reply and in the InsufficientFreeSpace and DiskTooSmall errors.
The implementation however filled it in from the "current size"
computed by determine_auto_size(), which means something else entirely:
the size of the image as it currently exists, i.e. the GPT metadata
overhead plus the sizes of all existing partitions — a metric designed
for growing image files with --size=auto. For a disk that is being
partitioned from scratch (i.e. carries no partition table yet) that
value is 0.

As a result, when systemd-sysinstall was pointed at a blank 2G disk
that is too small for the OS installation, it reported:

    The selected disk is not large enough for an OS installation.
    The size of the selected disk is 0B, but a minimal size of 15.7G is required.

Report context->total instead, i.e. the actual size of the block
device, which is also the value the DiskTooSmall check compares the
required size against. Do this in all three places that send
currentSizeBytes, matching the documented semantics of the field.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-07-16 13:58:55 +02:00
parent 5a12005c83
commit 588275f426
+5 -5
View File
@@ -11582,7 +11582,7 @@ static int vl_method_run(
return sd_varlink_errorbo(
link,
"io.systemd.Repart.DiskTooSmall",
SD_JSON_BUILD_PAIR_UNSIGNED("currentSizeBytes", current_size),
SD_JSON_BUILD_PAIR_UNSIGNED("currentSizeBytes", context->total),
SD_JSON_BUILD_PAIR_UNSIGNED("minimalSizeBytes", minimal_size));
/* Or if the disk would fit, but theres's not enough unallocated space */
@@ -11590,7 +11590,7 @@ static int vl_method_run(
return sd_varlink_errorbo(
link,
"io.systemd.Repart.InsufficientFreeSpace",
SD_JSON_BUILD_PAIR_UNSIGNED("currentSizeBytes", current_size),
SD_JSON_BUILD_PAIR_UNSIGNED("currentSizeBytes", context->total),
JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("needFreeBytes", need_free),
SD_JSON_BUILD_PAIR_UNSIGNED("minimalSizeBytes", minimal_size));
}
@@ -11598,17 +11598,17 @@ static int vl_method_run(
return r;
if (p.dry_run) {
uint64_t current_size, minimal_size;
uint64_t minimal_size;
/* If we are doing a dry-run, report the minimal size. */
r = determine_auto_size(context, LOG_DEBUG, &current_size, /* ret_foreign_size= */ NULL, &minimal_size);
r = determine_auto_size(context, LOG_DEBUG, /* ret_current_size= */ NULL, /* ret_foreign_size= */ NULL, &minimal_size);
if (r < 0)
return r;
return sd_varlink_replybo(
link,
SD_JSON_BUILD_PAIR_UNSIGNED("minimalSizeBytes", minimal_size),
SD_JSON_BUILD_PAIR_UNSIGNED("currentSizeBytes", current_size));
SD_JSON_BUILD_PAIR_UNSIGNED("currentSizeBytes", context->total));
}
r = context_write_partition_table(context);