Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorPavel Tikhomirov <ptikhomirov@virtuozzo.com>2022-01-12 16:00:56 +0300
committerAndrei Vagin <avagin@gmail.com>2022-04-29 03:53:52 +0300
commite50abbd3b38539c1dc72b67940e5fd5604934199 (patch)
tree108f138a3d444593cdc03dc0ba257f0aa066ddad /test
parenta963ceb7702466f068c808fabc4741068ce20704 (diff)
zdtm: add mnt_ext_collision test
This test creates two mount namespaces, one "root" with external mount at /mnt_ext_collision.test/dst and one "nested" with different internal mount at /mnt_ext_collision.test/dst instead. This case is important for nested containers, if we dump a container with some external mount in /mnt we should not also replace mounts in /mnt for nested containers with the external one. (One example is docker containers inside Virtuozzo containers.) Without previous patch which restricts external mounts resolution to only root mntns of container this test fails as internal mount is replaced by external one after migration. Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Diffstat (limited to 'test')
-rw-r--r--test/zdtm/static/Makefile1
-rw-r--r--test/zdtm/static/mnt_ext_collision.c194
-rw-r--r--test/zdtm/static/mnt_ext_collision.desc5
-rwxr-xr-xtest/zdtm/static/mnt_ext_collision.hook12
4 files changed, 212 insertions, 0 deletions
diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile
index a64c51cd0..565b32400 100644
--- a/test/zdtm/static/Makefile
+++ b/test/zdtm/static/Makefile
@@ -400,6 +400,7 @@ TST_DIR = \
mnt_ext_master \
mnt_ext_dev \
mnt_ext_root \
+ mnt_ext_collision \
mnt_tracefs \
mntns_deleted \
unlink_regular00 \
diff --git a/test/zdtm/static/mnt_ext_collision.c b/test/zdtm/static/mnt_ext_collision.c
new file mode 100644
index 000000000..324a3484c
--- /dev/null
+++ b/test/zdtm/static/mnt_ext_collision.c
@@ -0,0 +1,194 @@
+#include <sched.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <linux/limits.h>
+
+#include "zdtmtst.h"
+#include "lock.h"
+
+const char *test_doc = "Check external mount mountpoint collide with different mount in nested mntns";
+const char *test_author = "Pavel Tikhomirov <ptikhomirov@virtuozzo.com>";
+
+char *dirname = "mnt_ext_collision.test";
+TEST_OPTION(dirname, string, "directory name", 1);
+
+char *source = "zdtm_ext_collision";
+char *source2 = "zdtm_ext_collision_2";
+
+enum {
+ TEST_INIT = 0,
+ TEST_CHILD,
+ TEST_CHECK,
+ TEST_EXIT,
+ EMERGENCY_ABORT,
+};
+
+futex_t *futex;
+
+#define BUF_SIZE 4096
+
+static int child(void)
+{
+ char dst[PATH_MAX], dst_file[PATH_MAX];
+ int fd;
+
+ if (unshare(CLONE_NEWNS)) {
+ pr_perror("unshare");
+ goto err;
+ }
+
+ /*
+ * Umount external mount copy
+ */
+ sprintf(dst, "/%s/dst", dirname);
+ if (umount(dst)) {
+ pr_perror("umount");
+ goto err;
+ }
+
+ /*
+ * Mount tmpfs in its place
+ */
+ if (mount(source2, dst, "tmpfs", 0, NULL)) {
+ pr_perror("mount tmpfs");
+ goto err;
+ }
+
+ sprintf(dst_file, "/%s/dst/file", dirname);
+ fd = open(dst_file, O_RDWR | O_CREAT | O_EXCL, 0666);
+ if (fd < 0) {
+ pr_perror("open");
+ goto err;
+ }
+ close(fd);
+
+ futex_set_and_wake(futex, TEST_CHILD);
+ futex_wait_while_lt(futex, TEST_CHECK);
+
+ if (access(dst_file, F_OK)) {
+ pr_perror("access");
+ goto err;
+ }
+
+ futex_set_and_wake(futex, TEST_EXIT);
+ return 0;
+err:
+ futex_set_and_wake(futex, EMERGENCY_ABORT);
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ char *root, testdir[PATH_MAX];
+ char lckd[PATH_MAX], dst[PATH_MAX];
+ char *tmp = "/tmp/zdtm_ext_collision.tmp";
+ char *zdtm_newns = getenv("ZDTM_NEWNS");
+ int pid;
+
+ root = getenv("ZDTM_ROOT");
+ if (root == NULL) {
+ pr_perror("root");
+ return 1;
+ }
+
+ if (!zdtm_newns) {
+ pr_perror("ZDTM_NEWNS is not set");
+ return 1;
+ } else if (strcmp(zdtm_newns, "1")) {
+ goto test;
+ }
+
+ /* Prepare directories in test root */
+ sprintf(testdir, "%s/%s", root, dirname);
+ mkdir(testdir, 0755);
+
+ sprintf(lckd, "%s/%s/lckd", root, dirname);
+ mkdir(lckd, 0755);
+ sprintf(dst, "%s/%s/dst", root, dirname);
+ mkdir(dst, 0755);
+
+ /* Prepare mount in criu root */
+ mkdir(tmp, 0755);
+ if (mount(source, tmp, "tmpfs", 0, NULL)) {
+ pr_perror("mount tmpfs");
+ return 1;
+ }
+ if (mount(NULL, tmp, NULL, MS_PRIVATE, NULL)) {
+ pr_perror("make private");
+ return 1;
+ }
+
+ /*
+ * Create temporary mntns, next mounts will not show up in criu mntns
+ */
+ if (unshare(CLONE_NEWNS)) {
+ pr_perror("unshare");
+ return 1;
+ }
+
+ /*
+ * Populate external mount to the tests mntns root
+ * (in uns flavour this would become locked)
+ */
+ if (mount(tmp, lckd, NULL, MS_BIND, NULL)) {
+ pr_perror("bind");
+ return 1;
+ }
+test:
+ test_init(argc, argv);
+
+ /*
+ * Hack to create unlocked external mount without pivot_root+bind thing
+ */
+ sprintf(lckd, "/%s/lckd", dirname);
+ sprintf(dst, "/%s/dst", dirname);
+ if (mount(lckd, dst, NULL, MS_BIND, NULL)) {
+ pr_perror("bind");
+ return 1;
+ }
+
+ /*
+ * Setup futex for processes syncronization
+ */
+ futex = mmap(NULL, sizeof(futex), PROT_WRITE | PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ if (futex == MAP_FAILED) {
+ pr_perror("mmap");
+ return 1;
+ }
+ futex_init(futex);
+
+ /*
+ * Fork child which would have nested mntns
+ */
+ pid = fork();
+ if (pid < 0) {
+ pr_perror("fork");
+ return 1;
+ } else if (pid == 0) {
+ exit(child());
+ }
+
+ futex_wait_while_lt(futex, TEST_CHILD);
+ if (futex_get(futex) == EMERGENCY_ABORT) {
+ pr_err("Fail in child\n");
+ return 1;
+ }
+
+ test_daemon();
+ test_waitsig();
+
+ futex_set_and_wake(futex, TEST_CHECK);
+ futex_wait_while_lt(futex, TEST_EXIT);
+ if (futex_get(futex) == EMERGENCY_ABORT) {
+ fail("Fail in child on check stage");
+ return 1;
+ }
+
+ waitpid(pid, NULL, 0);
+ pass();
+ return 0;
+}
diff --git a/test/zdtm/static/mnt_ext_collision.desc b/test/zdtm/static/mnt_ext_collision.desc
new file mode 100644
index 000000000..9b68a4ae0
--- /dev/null
+++ b/test/zdtm/static/mnt_ext_collision.desc
@@ -0,0 +1,5 @@
+{ 'dopts': '--external mnt[/mnt_ext_collision.test/dst]:ZDTM',
+ 'feature': 'mnt_id',
+ 'flavor': 'ns uns',
+ 'flags': 'suid',
+ 'ropts': '--external mnt[ZDTM]:/tmp/zdtm_ext_collision.tmp'}
diff --git a/test/zdtm/static/mnt_ext_collision.hook b/test/zdtm/static/mnt_ext_collision.hook
new file mode 100755
index 000000000..31c908d67
--- /dev/null
+++ b/test/zdtm/static/mnt_ext_collision.hook
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+[ "$1" == "--clean" ] || exit 0
+
+TMP="/tmp/zdtm_ext_collision.tmp"
+echo "Cleanup mnt_ext_collision"
+umount "$TMP"
+rm -rf $TMP
+
+rm -rf "mnt_ext_collision.test"
+
+exit 0