summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-05-03 17:17:35 +0200
committerLuca Boccassi <luca.boccassi@gmail.com>2023-05-03 20:52:19 +0100
commitea0f3289a288affd5f13c83849b984c8fad63e90 (patch)
treef8e8d64a945e5525053e4fc650b91310f4ab6c72 /src/test
parent64ff6ad494477e4ad87fb02335db5ff17bd21d07 (diff)
downloadsystemd-ea0f3289a288affd5f13c83849b984c8fad63e90.tar.gz
mount-util: simplify mount_switch_root() a bit
There's no need to fchdir() out of the rootfs and back into it around the umount2(), hence don't. This brings the logic closer to what the pivot_root() man page suggests. While we are at it, always operate based on fds, once we opened the original dir, and pass the path string along only for generating messages (i.e. as "decoration"). Add tests for both code paths: the pivot_root() one and the MS_MOUNT.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/test-mount-util.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/test/test-mount-util.c b/src/test/test-mount-util.c
index 405cdf557a..a395f0cc6d 100644
--- a/src/test/test-mount-util.c
+++ b/src/test/test-mount-util.c
@@ -16,6 +16,7 @@
#include "namespace-util.h"
#include "path-util.h"
#include "process-util.h"
+#include "random-util.h"
#include "rm-rf.h"
#include "stat-util.h"
#include "string-util.h"
@@ -388,6 +389,48 @@ TEST(make_mount_point_inode) {
assert_se(!(S_IXOTH & st.st_mode));
}
+TEST(make_mount_switch_root) {
+ _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
+ _cleanup_free_ char *s = NULL;
+ int r;
+
+ if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
+ (void) log_tests_skipped("not running privileged");
+ return;
+ }
+
+ assert_se(mkdtemp_malloc(NULL, &t) >= 0);
+
+ assert_se(asprintf(&s, "%s/somerandomname%" PRIu64, t, random_u64()) >= 0);
+ assert_se(s);
+ assert_se(touch(s) >= 0);
+
+ for (int force_ms_move = 0; force_ms_move < 2; force_ms_move++) {
+ r = safe_fork("(switch-root",
+ FORK_RESET_SIGNALS |
+ FORK_CLOSE_ALL_FDS |
+ FORK_DEATHSIG |
+ FORK_WAIT |
+ FORK_REOPEN_LOG |
+ FORK_LOG |
+ FORK_NEW_MOUNTNS |
+ FORK_MOUNTNS_SLAVE,
+ NULL);
+ assert_se(r >= 0);
+
+ if (r == 0) {
+ assert_se(make_mount_point(t) >= 0);
+ assert_se(mount_switch_root_full(t, /* mount_propagation_flag= */ 0, force_ms_move) >= 0);
+
+ assert_se(access(ASSERT_PTR(strrchr(s, '/')), F_OK) >= 0); /* absolute */
+ assert_se(access(ASSERT_PTR(strrchr(s, '/')) + 1, F_OK) >= 0); /* relative */
+ assert_se(access(s, F_OK) < 0 && errno == ENOENT); /* doesn't exist in our new environment */
+
+ _exit(EXIT_SUCCESS);
+ }
+ }
+}
+
static int intro(void) {
/* Create a dummy network interface for testing remount_sysfs(). */
(void) system("ip link add dummy-test-mnt type dummy");