diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile index 9c9947eda..7817e00d3 100644 --- a/test/zdtm/static/Makefile +++ b/test/zdtm/static/Makefile @@ -225,6 +225,7 @@ TST_DIR = \ mntns_shared_bind02 \ mntns_root_bind \ mntns_root_bind02 \ + mntns_shared_vs_private \ mnt_ext_auto \ mnt_ext_master \ mntns_deleted \ diff --git a/test/zdtm/static/mntns_shared_vs_private.c b/test/zdtm/static/mntns_shared_vs_private.c new file mode 100644 index 000000000..204ac1139 --- /dev/null +++ b/test/zdtm/static/mntns_shared_vs_private.c @@ -0,0 +1,118 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zdtmtst.h" + +#ifndef CLONE_NEWNS +#define CLONE_NEWNS 0x00020000 +#endif + +const char *test_doc = "Check a private mount in a shared mount"; +const char *test_author = "Andrew Vagin "; + +char *dirname; +TEST_OPTION(dirname, string, "directory name", 1); + + +int main(int argc, char **argv) +{ + char path[PATH_MAX]; + pid_t pid; + int status, i; + task_waiter_t t; + + test_init(argc, argv); + + task_waiter_init(&t); + + snprintf(path, sizeof(path), "%s/fs", dirname); + if (mkdir(dirname, 0700)) { + pr_perror("mkdir"); + return 1; + } + + if (mount(NULL, "/", NULL, MS_SHARED, NULL)) { + pr_perror("mount"); + return 1; + } + + if (mount("zdtm_fs", dirname, "tmpfs", 0, NULL)) { + pr_perror("mount"); + return 1; + } + + if (mount(NULL, dirname, NULL, MS_PRIVATE, NULL)) { + pr_perror("mount"); + return 1; + } + + if (mkdir(path, 0700)) { + pr_perror("mkdir"); + return 1; + } + + if (mount("zdtm_fs", path, "tmpfs", 0, NULL)) { + pr_perror("mount"); + return 1; + } + + for (i = 0; i < 2; i++) { + pid = fork(); + if (pid < 0) { + pr_perror("fork"); + return 1; + } + if (pid == 0) { + unshare(CLONE_NEWNS); + + task_waiter_complete(&t, 1); + task_waiter_wait4(&t, 2); + + return 0; + } + } + + for (i = 0; i < 2; i++) + task_waiter_wait4(&t, 1); + + test_daemon(); + test_waitsig(); + + if (umount(path)) { + pr_perror("Unable to umount %s\n", path); + return 1; + } + if (umount(dirname)) { + pr_perror("Unable to umount %s\n", dirname); + return 1; + } + + for (i = 0; i < 2; i++) { + task_waiter_complete(&t, 2); + + if (waitpid(-1, &status, 0) < 0) { + pr_perror("waitpid %d", pid); + return 1; + } + + if (status) { + pr_perror("%d/%d/%d/%d", WIFEXITED(status), WEXITSTATUS(status), WIFSIGNALED(status), WTERMSIG(status)); + return 1; + } + } + + pass(); + + return 0; +} diff --git a/test/zdtm/static/mntns_shared_vs_private.desc b/test/zdtm/static/mntns_shared_vs_private.desc new file mode 100644 index 000000000..a8849e097 --- /dev/null +++ b/test/zdtm/static/mntns_shared_vs_private.desc @@ -0,0 +1 @@ +{'flavor': 'ns uns', 'flags': 'suid', 'feature': 'mnt_id'}