summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2022-02-02 11:03:04 +0000
committerGitHub <noreply@github.com>2022-02-02 11:03:04 +0000
commitb0c7e3d0e1e61f06881aaea8820d773e855a46d6 (patch)
tree52cb746f591d8c95697fe07db5d7d3cda2db17bb
parent891c9b36cf339176e6f58935c9e15db006cedda8 (diff)
parent6f6b017b9bc69df3f3e308c36c95597002ce6e29 (diff)
downloadsystemd-b0c7e3d0e1e61f06881aaea8820d773e855a46d6.tar.gz
Merge pull request #22359 from yuwata/mkdir-fix
mkdir: allow to create directory whose path contains symlink
-rw-r--r--src/basic/mkdir.c4
-rw-r--r--src/core/mount.c4
-rw-r--r--src/test/meson.build2
-rw-r--r--src/test/test-mkdir.c30
4 files changed, 37 insertions, 3 deletions
diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c
index 6e2b94d024..51a0d74e87 100644
--- a/src/basic/mkdir.c
+++ b/src/basic/mkdir.c
@@ -42,7 +42,7 @@ int mkdir_safe_internal(
if ((flags & MKDIR_FOLLOW_SYMLINK) && S_ISLNK(st.st_mode)) {
_cleanup_free_ char *p = NULL;
- r = chase_symlinks_and_stat(path, NULL, CHASE_NONEXISTENT, &p, &st, NULL);
+ r = chase_symlinks_and_stat(path, NULL, 0, &p, &st, NULL);
if (r < 0)
return r;
if (r == 0)
@@ -162,7 +162,7 @@ int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, uid_t ui
assert(_mkdirat != mkdirat);
- r = mkdir_parents_internal(prefix, path, mode, uid, gid, flags, _mkdirat);
+ r = mkdir_parents_internal(prefix, path, mode, uid, gid, flags | MKDIR_FOLLOW_SYMLINK, _mkdirat);
if (r < 0)
return r;
diff --git a/src/core/mount.c b/src/core/mount.c
index 0170406351..c650b5abe2 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1027,8 +1027,10 @@ static void mount_enter_mounting(Mount *m) {
r = mkdir_p_label(p->what, m->directory_mode);
/* mkdir_p_label() can return -EEXIST if the target path exists and is not a directory - which is
* totally OK, in case the user wants us to overmount a non-directory inode. */
- if (r < 0 && r != -EEXIST)
+ if (r < 0 && r != -EEXIST) {
log_unit_error_errno(UNIT(m), r, "Failed to make bind mount source '%s': %m", p->what);
+ goto fail;
+ }
}
if (p) {
diff --git a/src/test/meson.build b/src/test/meson.build
index e245e0b7b2..88164f1262 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -193,6 +193,8 @@ tests += [
[files('test-macro.c')],
+ [files('test-mkdir.c')],
+
[files('test-json.c')],
[files('test-modhex.c')],
diff --git a/src/test/test-mkdir.c b/src/test/test-mkdir.c
new file mode 100644
index 0000000000..c715d5f096
--- /dev/null
+++ b/src/test/test-mkdir.c
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <unistd.h>
+
+#include "mkdir.h"
+#include "path-util.h"
+#include "rm-rf.h"
+#include "tests.h"
+#include "tmpfile-util.h"
+
+TEST(mkdir_p) {
+ _cleanup_(rm_rf_physical_and_freep) char *tmp = NULL;
+ _cleanup_free_ char *p = NULL;
+
+ assert_se(mkdtemp_malloc("/tmp/test-mkdir-XXXXXX", &tmp) >= 0);
+
+ assert_se(p = path_join(tmp, "run"));
+ assert_se(mkdir_p(p, 0755) >= 0);
+
+ p = mfree(p);
+ assert_se(p = path_join(tmp, "var/run"));
+ assert_se(mkdir_parents(p, 0755) >= 0);
+ assert_se(symlink("../run", p) >= 0);
+
+ p = mfree(p);
+ assert_se(p = path_join(tmp, "var/run/hoge/foo/baz"));
+ assert_se(mkdir_p(p, 0755) >= 0);
+}
+
+DEFINE_TEST_MAIN(LOG_DEBUG);