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 ;)
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-06-03 16:02:58 +02:00
parent bf4388ab31
commit 230a38ea52
3 changed files with 45 additions and 4 deletions
+40
View File
@@ -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)
+4 -4
View File
@@ -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);
+1
View File
@@ -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);