]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/namespace: split out bind mount retry helper
authordongshengyuan <545258830@qq.com>
Sun, 26 Jul 2026 04:49:42 +0000 (12:49 +0800)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 26 Jul 2026 10:57:43 +0000 (19:57 +0900)
Move the bind mount retry path into a small helper so
apply_one_mount() no longer carries destination creation and
retry state inline.

Report destination creation and retry failures at debug level,
then return the error to apply_mounts(). The caller still reports
the final mount namespace failure with the cleaned-up mount path.

src/core/namespace.c

index d5f78595877e0d47d06cb802169786d883a3cd8f..1a15e799017248e309b305103b0d6214f9c999e2 100644 (file)
@@ -1847,6 +1847,54 @@ static int follow_symlink(
         return 0;
 }
 
+static int mount_bind(
+                const MountEntry *m,
+                const char *what,
+                bool recursive,
+                bool make) {
+
+        int r;
+
+        assert(m);
+        assert(what);
+
+        r = mount_nofollow_verbose(
+                        LOG_DEBUG,
+                        what,
+                        mount_entry_path(m),
+                        NULL,
+                        MS_BIND|(recursive ? MS_REC : 0),
+                        NULL);
+        if (r >= 0)
+                return 0;
+        if (r != -ENOENT || !make)
+                return log_debug_errno(r, "Failed to mount %s to %s: %m", what, mount_entry_path(m));
+
+        /* Either the source or the destination is missing. Create the destination and try again. */
+        r = mkdir_parents(mount_entry_path(m), 0755);
+        if (r < 0 && r != -EEXIST)
+                return log_debug_errno(r,
+                                       "Failed to create parent directories of destination mount point node '%s': %m",
+                                       mount_entry_path(m));
+
+        r = make_mount_point_inode_from_path(what, mount_entry_path(m), 0755);
+        if (r < 0 && r != -EEXIST)
+                return log_debug_errno(r, "Failed to create destination mount point node '%s': %m",
+                                       mount_entry_path(m));
+
+        r = mount_nofollow_verbose(
+                        LOG_DEBUG,
+                        what,
+                        mount_entry_path(m),
+                        NULL,
+                        MS_BIND|(recursive ? MS_REC : 0),
+                        NULL);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to mount %s to %s: %m", what, mount_entry_path(m));
+
+        return 0;
+}
+
 static int apply_one_mount(
                 const char *root_directory,
                 MountEntry *m,
@@ -2099,37 +2147,9 @@ static int apply_one_mount(
 
         assert(what);
 
-        r = mount_nofollow_verbose(LOG_DEBUG, what, mount_entry_path(m), NULL, MS_BIND|(rbind ? MS_REC : 0), NULL);
-        if (r < 0) {
-                bool try_again = false;
-
-                if (r == -ENOENT && make) {
-                        int q;
-
-                        /* Hmm, either the source or the destination are missing. Let's see if we can create
-                           the destination, then try again. */
-
-                        q = mkdir_parents(mount_entry_path(m), 0755);
-                        if (q < 0 && q != -EEXIST)
-                                // FIXME: this shouldn't be logged at LOG_WARNING, but be bubbled up, and logged there to avoid duplicate logging
-                                log_warning_errno(q, "Failed to create parent directories of destination mount point node '%s', ignoring: %m",
-                                                  mount_entry_path(m));
-                        else {
-                                q = make_mount_point_inode_from_path(what, mount_entry_path(m), 0755);
-                                if (q < 0 && q != -EEXIST)
-                                        // FIXME: this shouldn't be logged at LOG_WARNING, but be bubbled up, and logged there to avoid duplicate logging
-                                        log_warning_errno(q, "Failed to create destination mount point node '%s', ignoring: %m",
-                                                          mount_entry_path(m));
-                                else
-                                        try_again = true;
-                        }
-                }
-
-                if (try_again)
-                        r = mount_nofollow_verbose(LOG_DEBUG, what, mount_entry_path(m), NULL, MS_BIND|(rbind ? MS_REC : 0), NULL);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to mount %s to %s: %m", what, mount_entry_path(m)); // FIXME: this should not be logged here, but be bubbled up, to avoid duplicate logging
-        }
+        r = mount_bind(m, what, rbind, make);
+        if (r < 0)
+                return r;
 
         log_debug("Successfully mounted %s to %s", what, mount_entry_path(m));