]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/test/test-mount-util.c
mount-util: simplify mount_switch_root() a bit
[thirdparty/systemd.git] / src / test / test-mount-util.c
index 405cdf557a821ed362f5c29258b8645b815a6066..a395f0cc6d084072470b1b92f0e926f269aea677 100644 (file)
@@ -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");