diff options
author | Luca Boccassi <bluca@debian.org> | 2022-02-02 11:03:04 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-02 11:03:04 +0000 |
commit | b0c7e3d0e1e61f06881aaea8820d773e855a46d6 (patch) | |
tree | 52cb746f591d8c95697fe07db5d7d3cda2db17bb | |
parent | 891c9b36cf339176e6f58935c9e15db006cedda8 (diff) | |
parent | 6f6b017b9bc69df3f3e308c36c95597002ce6e29 (diff) | |
download | systemd-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.c | 4 | ||||
-rw-r--r-- | src/core/mount.c | 4 | ||||
-rw-r--r-- | src/test/meson.build | 2 | ||||
-rw-r--r-- | src/test/test-mkdir.c | 30 |
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); |