zdtm: add new mnt_ext_root test

This test simply creates a) root external mount and b) "deeper"
bindmount for it (deeper in terms of mnt_depth). Our mount restore code
tries to mount (b) first and fails (without previous patch ordering
external mounts before their binds).

Cherry-picked from Virtuozzo criu:
https://src.openvz.org/projects/OVZ/repos/criu/commits/d31954669

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This commit is contained in:
Pavel Tikhomirov 2020-02-18 13:41:18 +03:00 committed by Andrei Vagin
parent 4f94149346
commit 007501f985
4 changed files with 106 additions and 0 deletions

View file

@ -399,6 +399,7 @@ TST_DIR = \
mnt_ext_auto \
mnt_ext_master \
mnt_ext_dev \
mnt_ext_root \
mnt_tracefs \
mntns_deleted \
unlink_regular00 \

View file

@ -0,0 +1,88 @@
#include <sched.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <linux/limits.h>
#include "zdtmtst.h"
const char *test_doc = "Check root external mount with \"deepper\" bind";
const char *test_author = "Pavel Tikhomirov <ptikhomirov@virtuozzo.com>";
char *source = "zdtm_ext_root";
char *dirname = "mnt_ext_root.test";
TEST_OPTION(dirname, string, "directory name", 1);
#define BUF_SIZE 4096
int main(int argc, char **argv)
{
char *root, testdir[PATH_MAX];
char dst[PATH_MAX], deep_bind[PATH_MAX];
char *tmp = "/tmp/zdtm_ext_root.tmp";
char *zdtm_newns = getenv("ZDTM_NEWNS");
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(dst, "%s/%s/dst", root, dirname);
mkdir(dst, 0755);
sprintf(deep_bind, "%s/%s/deep", root, dirname);
mkdir(deep_bind, 0755);
sprintf(deep_bind, "%s/%s/deep/bind", root, dirname);
mkdir(deep_bind, 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 to the tests mntns root mounts
*/
if (mount(tmp, dst, NULL, MS_BIND, NULL)) {
pr_perror("bind");
return 1;
}
if (mount(tmp, deep_bind, NULL, MS_BIND, NULL)) {
pr_perror("bind");
return 1;
}
test:
test_init(argc, argv);
test_daemon();
test_waitsig();
pass();
return 0;
}

View file

@ -0,0 +1,5 @@
{ 'dopts': '--external mnt[/mnt_ext_root.test/dst]:ZDTM',
'feature': 'mnt_id',
'flavor': 'ns uns',
'flags': 'suid',
'ropts': '--external mnt[ZDTM]:/tmp/zdtm_ext_root.tmp'}

View file

@ -0,0 +1,12 @@
#!/bin/bash
[ "$1" == "--clean" ] || exit 0
TMP="/tmp/zdtm_ext_root.tmp"
echo "Cleanup mnt_ext_sharing"
umount "$TMP"
rm -rf $TMP
rm -rf "mnt_ext_root.test"
exit 0