From: Daan De Meyer Date: Wed, 25 Mar 2026 09:22:30 +0000 (+0100) Subject: vmspawn: Create journal parent directories if needed X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f83371324d60e47998f5972590119aecfd11f9c8;p=thirdparty%2Fsystemd.git vmspawn: Create journal parent directories if needed --- diff --git a/src/test/test-chase.c b/src/test/test-chase.c index 129ea19b723..721f56a2506 100644 --- a/src/test/test-chase.c +++ b/src/test/test-chase.c @@ -620,6 +620,16 @@ TEST(chaseat) { assert_se(chaseat(tfd, "i/../p", CHASE_MKDIR_0755|CHASE_NONEXISTENT, NULL, NULL) == -ENOENT); + /* Test CHASE_MKDIR_0755|CHASE_PARENT — creates intermediate dirs but not the final component */ + + ASSERT_OK(chaseat(tfd, "mkp/a/r/e/n/t/file", CHASE_MKDIR_0755|CHASE_PARENT, &result, &fd)); + ASSERT_OK(faccessat(tfd, "mkp/a/r/e/n/t", F_OK, 0)); + assert_se(RET_NERRNO(faccessat(tfd, "mkp/a/r/e/n/t/file", F_OK, 0)) == -ENOENT); + ASSERT_OK(fd_verify_directory(fd)); + fd = safe_close(fd); + ASSERT_STREQ(result, "mkp/a/r/e/n/t/file"); + result = mfree(result); + /* Test CHASE_EXTRACT_FILENAME */ ASSERT_OK(chaseat(tfd, "chase/parent", CHASE_AT_RESOLVE_IN_ROOT|CHASE_PARENT|CHASE_NOFOLLOW|CHASE_EXTRACT_FILENAME, &result, &fd)); @@ -664,6 +674,23 @@ TEST(chaseat) { fd = safe_close(fd); result = mfree(result); + /* Test chase_and_openat() with CHASE_MKDIR_0755|CHASE_PARENT — opens parent dir */ + + fd = chase_and_openat(tfd, "mkopen/p/a/r/file.txt", CHASE_MKDIR_0755|CHASE_PARENT, O_RDONLY|O_CLOEXEC, NULL); + ASSERT_OK(fd); + ASSERT_OK(fd_verify_directory(fd)); + ASSERT_OK(faccessat(tfd, "mkopen/p/a/r", F_OK, 0)); + assert_se(RET_NERRNO(faccessat(tfd, "mkopen/p/a/r/file.txt", F_OK, 0)) == -ENOENT); + fd = safe_close(fd); + + /* Test chase_and_openat() with CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY + O_CREAT — creates and opens target dir */ + + fd = chase_and_openat(tfd, "mkopen/d/i/r/target", CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY, O_CREAT|O_RDONLY|O_CLOEXEC, NULL); + ASSERT_OK(fd); + ASSERT_OK(fd_verify_directory(fd)); + ASSERT_OK(faccessat(tfd, "mkopen/d/i/r/target", F_OK, 0)); + fd = safe_close(fd); + /* Test chase_and_openatdir() */ ASSERT_OK(chase_and_opendirat(tfd, "o/p/e/n/d/i", 0, &result, &dir)); diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index a197132c043..f730a756e28 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -26,6 +26,8 @@ #include "bus-locator.h" #include "bus-util.h" #include "capability-util.h" +#include "chase.h" +#include "chattr-util.h" #include "common-signal.h" #include "copy.h" #include "discover-image.h" @@ -2953,6 +2955,19 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { if (arg_forward_journal) { _cleanup_free_ char *listen_address = NULL; + ChaseFlags chase_flags = CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY; + if (endswith(arg_forward_journal, ".journal")) + chase_flags |= CHASE_PARENT; + + _cleanup_close_ int journal_fd = -EBADF; + r = chase(arg_forward_journal, /* root= */ NULL, chase_flags, /* ret_path= */ NULL, &journal_fd); + if (r < 0) + return log_error_errno(r, "Failed to create journal directory for '%s': %m", arg_forward_journal); + + r = chattr_fd(journal_fd, FS_NOCOW_FL, FS_NOCOW_FL); + if (r < 0) + log_debug_errno(r, "Failed to set NOCOW flag on journal directory for '%s', ignoring: %m", arg_forward_journal); + if (!GREEDY_REALLOC(children, n_children + 1)) return log_oom();