From d789af72801f6c24c63b62e1dd44b0896e5def9d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 1 Jul 2026 16:04:43 +0200 Subject: [PATCH] mkfs-util: deal with mmd name clashes gracefully In various cases we'll touch the same directories multiple times with mtools: for example the /loader/ dir itself. Unfortunately mtools' mmd does not implement a graceful "-p" switch like mkdir, but will do some interactive name clash thing instead. We can turn this off via "-Ds -DS", so let's do that. But that's not enough since the tool will still fail with a non-explanatory exit status of 1. This hence ignores that failure and proceeds anyway, under the assumption that failures to create a directory will sooner or later be detected anyway once the directory is to be populated and turns out not be existing because the creation failed. This makes some integration test/mkosi invocations work non-interactively again. Follow-up for f191ca982ce9eac85207807a65489909308f7d8f --- src/shared/mkfs-util.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index 33415e972bf..f4aaa46ee8a 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -149,7 +149,7 @@ static int mangle_fat_label(const char *s, char **ret) { return 0; } -static int mtools_exec(char *const *argv) { +static int mtools_exec(char *const *argv, ForkFlags extra_fork_flags) { int r; assert(argv); @@ -162,7 +162,7 @@ static int mtools_exec(char *const *argv) { r = pidref_safe_fork( "(mtools)", - FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS, + FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS|extra_fork_flags, /* ret= */ NULL); if (r < 0) return r; @@ -175,7 +175,7 @@ static int mtools_exec(char *const *argv) { "TZ=UTC", strv_find_prefix(environ, "SOURCE_DATE_EPOCH="))); - log_error_errno(errno, "Failed to execute %s: %m", argv[0]); + log_full_errno(FLAGS_SET(extra_fork_flags, FORK_LOG) ? LOG_ERR : LOG_DEBUG, errno, "Failed to execute %s: %m", argv[0]); _exit(EXIT_FAILURE); } @@ -216,7 +216,7 @@ static int mcopy_flush_files( if (strv_extend(&argv, dest) < 0) return log_oom(); - return mtools_exec(argv); + return mtools_exec(argv, FORK_LOG); } static int do_mcopy_recurse( @@ -276,13 +276,18 @@ static int do_mcopy_recurse( return log_oom(); /* Note: mmd accepts only -D and -i; there is no -Q quiet flag like mcopy has. */ - _cleanup_strv_free_ char **argv = strv_new(mmd_bin, "-i", node, dst); + _cleanup_strv_free_ char **argv = strv_new(mmd_bin, "-Ds", "-DS", "-i", node, dst); if (!argv) return log_oom(); - r = mtools_exec(argv); + /* If a directory already exists mmd will skip the entry (because we pass -Ds/-DS above), but + * it ultimately still fails. That sucks, and there's no way we can turn this off. Let's + * ignore the return value here (i.e. we do not pass FORK_LOG here, and eat up the error), + * under the assumption that any serious failure is noticed later either way, once we + * populate the directory, and it turns out to be missing. */ + r = mtools_exec(argv, /* extra_fork_flags= */ 0); if (r < 0) - return r; + log_debug_errno(r, "mtools mmd operation failed, assuming because directory already existed, ignoring: %m"); _cleanup_free_ char *child_rel = strjoin(dest_rel, "/", ent->d_name); if (!child_rel) -- 2.47.3