From: Zbigniew Jędrzejewski-Szmek Date: Wed, 27 May 2026 15:10:26 +0000 (+0200) Subject: repart: perform an early check for missing mkfs or fs contents X-Git-Tag: v261-rc3~8^2~1 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=230a38ea52d321a301e84739f627f1408967e7e2;p=thirdparty%2Fsystemd.git repart: perform an early check for missing mkfs or fs contents I was running repart in a VM, and if failed because mkfs.vfat was not available. But if fails quite late in the process, possibly wasting quite a bit of work. So add a check that catches some obvious cases where repart would fail. The condition of whether we have the root directory is complex, determined in part by partition_target_prepare(). I didn't think it was worth it to recreate the full logic in the check, so in some cases it'll not miss cases. But that's still better than having no check ;) --- diff --git a/src/repart/repart.c b/src/repart/repart.c index 3f2b6a081d5..6b0422dd6cc 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -7364,6 +7364,42 @@ static void context_btrfs_replace_back(Context *context) { } } +static int check_mkfs(const Context *context) { + int r; + + assert(context); + + LIST_FOREACH(partitions, p, context->partitions) { + if (p->dropped) + continue; + + if (PARTITION_EXISTS(p)) /* Never format existing partitions */ + continue; + + if (!p->format) + continue; + + if (partition_defer(context, p)) + continue; + + /* For offline signing case */ + if (!set_isempty(arg_verity_settings) && partition_designator_is_verity_sig(p->type.designator)) + continue; + + /* Minimized partitions will use the copy blocks logic so skip those here. */ + if (p->copy_blocks_fd >= 0) + continue; + + /* We don't yet quite know if have_root= will be true, so just pass -1 which + * means "not sure". */ + r = mkfs_find_or_warn(p->format, /* have_root= */ -1, /* ret= */ NULL); + if (r < 0) + return r; + } + + return 0; +} + static int context_mkfs(Context *context) { int r; @@ -11674,6 +11710,10 @@ static int run(int argc, char *argv[]) { return r; context->from_scratch = r > 0; /* Starting from scratch */ + r = check_mkfs(context); + if (r < 0) + return r; + if (arg_can_factory_reset) { r = context_can_factory_reset(context); if (r < 0) diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index 29caaacac6f..126f5705275 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -39,18 +39,18 @@ int mkfs_exists(const char *fstype) { return true; } -static int mkfs_find_or_warn(const char *fstype, bool have_root, char **ret) { +int mkfs_find_or_warn(const char *fstype, int have_root, char **ret) { int r; assert(fstype); - if (fstype_is_ro(fstype) && !have_root) + if (fstype_is_ro(fstype) && have_root == 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot generate read-only filesystem %s without a source tree.", fstype); const char *bin = NULL; if (streq(fstype, "swap")) { - if (have_root) + if (have_root > 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "A swap filesystem can't be populated, refusing"); bin = "mkswap"; @@ -70,7 +70,7 @@ static int mkfs_find_or_warn(const char *fstype, bool have_root, char **ret) { return 0; } - if (have_root && !mkfs_supports_root_option(fstype)) + if (have_root > 0 && !mkfs_supports_root_option(fstype)) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Populating with source tree is not supported for %s", fstype); r = mkfs_exists(fstype); diff --git a/src/shared/mkfs-util.h b/src/shared/mkfs-util.h index 7ab78be98a6..b23f0cf7457 100644 --- a/src/shared/mkfs-util.h +++ b/src/shared/mkfs-util.h @@ -12,6 +12,7 @@ typedef enum MakeFilesystemFlags { } MakeFileSystemFlags; int mkfs_exists(const char *fstype); +int mkfs_find_or_warn(const char *fstype, int have_root, char **ret); int mkfs_supports_root_option(const char *fstype);