core/namespace: split out bind mount retry helper

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.
This commit is contained in:
dongshengyuan
2026-07-26 19:57:43 +09:00
committed by Yu Watanabe
parent c8f0be5e34
commit 86168be51a
+51 -31
View 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));