]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
repart: perform an early check for missing mkfs or fs contents
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Wed, 27 May 2026 15:10:26 +0000 (17:10 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Wed, 3 Jun 2026 14:02:58 +0000 (16:02 +0200)
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 ;)

src/repart/repart.c
src/shared/mkfs-util.c
src/shared/mkfs-util.h

index 3f2b6a081d532c87df5fb095b0faa638cebcacca..6b0422dd6ccaaa4bdc7f3b05d307c89b6b725f1e 100644 (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)
index 29caaacac6f13cecb781f19e1235d314ef6d3b80..126f5705275e4311dbc8a84dac05e935a93a99c1 100644 (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);
index 7ab78be98a62c104094d2279df8e23d7aedc153c..b23f0cf74575c2247c1ecc8859750827c31f413a 100644 (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);