From: Valentin David Date: Thu, 12 Mar 2026 22:14:39 +0000 (+0100) Subject: repart: Rescan disk on failure if we create blkpg partitions on the fly X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d0d00297a43e7d824fb68f2cad702ba366abeb59;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/repart/repart.c b/src/repart/repart.c index 854ca644f75..0e5ba58af2a 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -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) - 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); + if (r < 0) { + r = log_error_errno(r, "Failed to write partition table: %m"); + goto error; + } - 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."); + r = context_partscan(context); + if (r < 0) + 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) {