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
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@virtuozzo.com>2017-02-22 09:39:45 +0300
committerAndrei Vagin <avagin@virtuozzo.com>2017-03-02 00:19:02 +0300
commitb6f7577109d1e940f9f3dc64539803d1eb2ca411 (patch)
tree97b242b72cb2225b186452f8bfe1d10cd08aea7c
parentf830e0ff3491c49dc6fc24c24e35cc7934e5fded (diff)
mount: restore mounts in the root mount namespace
Currently all mounts are restored in a one mount namespace, then this namespace is cloned to restore other mount namespaces and we need another copy of this namespace to clean link remap files. Let's define terms: A - the root mount namespace B - the mount namespace where link remap files are destroyed Currently we restore all mounts in the B namespace and then clone it into the A namespace. But it doesn't work in a case, when we have to open file descriptores to restore mounts (e g to restore bind-mount pty slaves), because a file descriptor has to be opened from a specified mount (which is one of restore mount namespaces). This patch reworks code so, that all mounts is restored in the A mount namespace and then the B mount namespace is created. In this case we can open files from the root mount namespace (A). $ ./zdtm.py run -t zdtm/static/pty-console --iter 5 ====================== Run zdtm/static/pty-console in ns ======================= Start test Test is SUID ./pty-console --pidfile=pty-console.pid --outfile=pty-console.out Run criu dump Run criu restore Run criu dump =[log]=> dump/zdtm/static/pty-console/36/2/dump.log ------------------------ grep Error ------------------------ (00.106521) Error (criu/files-reg.c:1132): Can't lookup mount=563 for fd=4 path=/ptmx (00.106585) Error (criu/cr-dump.c:1325): Dump files (pid: 70) failed with -1 (00.129041) Error (criu/cr-dump.c:1674): Dumping FAILED. ------------------------ ERROR OVER ------------------------ Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
-rw-r--r--criu/cr-restore.c21
-rw-r--r--criu/include/restorer.h5
-rw-r--r--criu/mount.c32
3 files changed, 49 insertions, 9 deletions
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 0c216566c..0712b4695 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -1319,6 +1319,9 @@ static int restore_task_with_children(void *_arg)
if (prepare_namespace(current, ca->clone_flags))
goto err;
+ if (restore_finish_stage(task_entries, CR_STATE_POST_RESTORE_NS) < 0)
+ goto err;
+
if (root_prepare_shared())
goto err;
@@ -1382,6 +1385,7 @@ static inline int stage_participants(int next_stage)
case CR_STATE_FAIL:
return 0;
case CR_STATE_RESTORE_NS:
+ case CR_STATE_POST_RESTORE_NS:
case CR_STATE_RESTORE_SHARED:
return 1;
case CR_STATE_FORKING:
@@ -1737,16 +1741,25 @@ static int restore_root_task(struct pstree_item *init)
if (ret)
goto out_kill;
+ ret = run_scripts(ACT_SETUP_NS);
+ if (ret)
+ goto out_kill;
+
+ ret = restore_switch_stage(CR_STATE_POST_RESTORE_NS);
+ if (ret < 0)
+ goto out_kill;
+
+ pr_info("Wait until namespaces are created\n");
+ ret = restore_wait_inprogress_tasks();
+ if (ret)
+ goto out_kill;
+
if (root_ns_mask & CLONE_NEWNS) {
mnt_ns_fd = open_proc(init->pid->real, "ns/mnt");
if (mnt_ns_fd < 0)
goto out_kill;
}
- ret = run_scripts(ACT_SETUP_NS);
- if (ret)
- goto out_kill;
-
if (opts.empty_ns & CLONE_NEWNET) {
/*
* Local TCP connections were locked by network_lock_internal()
diff --git a/criu/include/restorer.h b/criu/include/restorer.h
index cb2221671..60246eff1 100644
--- a/criu/include/restorer.h
+++ b/criu/include/restorer.h
@@ -198,6 +198,11 @@ static inline unsigned long restorer_stack(struct restore_mem_zone *mz)
enum {
CR_STATE_FAIL = -1,
CR_STATE_RESTORE_NS = 0, /* is used for executing "setup-namespace" scripts */
+ /*
+ * Need to wait a mount namespace which
+ * will be used to clean up remap files.
+ */
+ CR_STATE_POST_RESTORE_NS,
CR_STATE_RESTORE_SHARED,
CR_STATE_FORKING,
CR_STATE_RESTORE,
diff --git a/criu/mount.c b/criu/mount.c
index 8f66b4e09..013b17e2f 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -2948,17 +2948,39 @@ int prepare_mnt_ns(void)
goto err;
}
+ if (nsid->type == NS_ROOT) {
+ int fd;
+
+ /*
+ * We need to create a mount namespace which will be
+ * used to clean up remap files
+ * (depopulate_roots_yard). The namespace where mounts
+ * was restored has to be restored as a root mount
+ * namespace, because there are file descriptors
+ * linked with it (e.g. to bind-mount slave pty-s).
+ */
+ fd = open_proc(PROC_SELF, "ns/mnt");
+ if (fd < 0)
+ goto err;
+ if (setns(rst, CLONE_NEWNS)) {
+ pr_perror("Can't restore mntns back");
+ goto err;
+ }
+ nsid->mnt.ns_fd = rst;
+ rst = fd;
+ } else {
+ /* Pin one with a file descriptor */
+ nsid->mnt.ns_fd = open_proc(PROC_SELF, "ns/mnt");
+ if (nsid->mnt.ns_fd < 0)
+ goto err;
+ }
+
/* Set its root */
path[0] = '/';
print_ns_root(nsid, 0, path + 1, sizeof(path) - 1);
if (cr_pivot_root(path))
goto err;
- /* Pin one with a file descriptor */
- nsid->mnt.ns_fd = open_proc(PROC_SELF, "ns/mnt");
- if (nsid->mnt.ns_fd < 0)
- goto err;
-
/* root_fd is used to restore file mappings */
nsid->mnt.root_fd = open_proc(PROC_SELF, "root");
if (nsid->mnt.root_fd < 0)