repart: Rescan disk on failure if we create blkpg partitions on the fly

Since we did not write the partition table, then the created partitions
should get removed on error.
This commit is contained in:
Valentin David
2026-05-12 18:31:23 +02:00
parent 0ef0824201
commit d0d00297a4
+47 -21
View File
@@ -568,6 +568,8 @@ struct Context {
bool defer_partitions_factory_reset;
sd_varlink *link; /* If 'more' is used on the Varlink call, we'll send progress info over this link */
bool needs_rescan;
};
static const char *empty_mode_table[_EMPTY_MODE_MAX] = {
@@ -5132,6 +5134,8 @@ static int partition_target_prepare(
if (r < 0)
return log_error_errno(r, "Failed to create new partition '%s': %m", part_node);
context->needs_rescan = true;
dev_fd = open(part_node, O_RDWR|O_CLOEXEC|O_NOCTTY);
if (dev_fd < 0) {
r = -errno;
@@ -8244,9 +8248,34 @@ static int context_find_esp_offset(Context *context, uint64_t *ret) {
return 0;
}
static int context_partscan(Context *context) {
int capable, r;
assert(context);
context->needs_rescan = false;
capable = blockdev_partscan_enabled_fd(sym_fdisk_get_devfd(context->fdisk_context));
if (capable == -ENOTBLK)
log_debug("Not telling kernel to reread partition table, since we are not operating on a block device.");
else if (capable < 0)
return log_error_errno(capable, "Failed to check if block device supports partition scanning: %m");
else if (capable > 0) {
log_info("Informing kernel about changed partitions...");
(void) context_notify(context, PROGRESS_REREADING_TABLE, /* object= */ NULL, UINT_MAX);
r = reread_partition_table_fd(sym_fdisk_get_devfd(context->fdisk_context), /* flags= */ 0);
if (r < 0)
return log_error_errno(r, "Failed to reread partition table: %m");
} else
log_notice("Not telling kernel to reread partition table, because selected image does not support kernel partition block devices.");
return 0;
}
static int context_write_partition_table(Context *context) {
_cleanup_(fdisk_unref_tablep) struct fdisk_table *original_table = NULL;
int capable, r;
int r;
assert(context);
@@ -8292,46 +8321,43 @@ static int context_write_partition_table(Context *context) {
* gaps between partitions, just to be sure. */
r = context_wipe_and_discard(context);
if (r < 0)
return r;
goto error;
r = context_copy_blocks(context);
if (r < 0)
return r;
goto error;
r = context_mkfs(context);
if (r < 0)
return r;
goto error;
r = context_mangle_partitions(context);
if (r < 0)
return r;
goto error;
log_info("Writing new partition table.");
(void) context_notify(context, PROGRESS_WRITING_TABLE, /* object= */ NULL, UINT_MAX);
r = sym_fdisk_write_disklabel(context->fdisk_context);
if (r < 0) {
r = log_error_errno(r, "Failed to write partition table: %m");
goto error;
}
r = context_partscan(context);
if (r < 0)
return log_error_errno(r, "Failed to write partition table: %m");
capable = blockdev_partscan_enabled_fd(sym_fdisk_get_devfd(context->fdisk_context));
if (capable == -ENOTBLK)
log_debug("Not telling kernel to reread partition table, since we are not operating on a block device.");
else if (capable < 0)
return log_error_errno(capable, "Failed to check if block device supports partition scanning: %m");
else if (capable > 0) {
log_info("Informing kernel about changed partitions...");
(void) context_notify(context, PROGRESS_REREADING_TABLE, /* object= */ NULL, UINT_MAX);
r = reread_partition_table_fd(sym_fdisk_get_devfd(context->fdisk_context), /* flags= */ 0);
if (r < 0)
return log_error_errno(r, "Failed to reread partition table: %m");
} else
log_notice("Not telling kernel to reread partition table, because selected image does not support kernel partition block devices.");
return r;
log_info("Partition table written.");
return 0;
error:
if (context->needs_rescan)
(void) context_partscan(context);
return r;
}
static int context_write_eltorito(Context *context) {