Commit 9b3b059b authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

crtools: add "pid" to the --namespaces cmdline option arguments (v3)

to require dumping pid namespace. Dump and restore will be failed if
a tress doesn't contain a process init.

pid namespace will be created implicitly if a process init in the tree.

v2: fix comments from Pavel
v3: Restore of pidns should be approved by user
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 57b1e945
...@@ -1197,12 +1197,9 @@ static int collect_pstree(pid_t pid, const struct cr_options *opts) ...@@ -1197,12 +1197,9 @@ static int collect_pstree(pid_t pid, const struct cr_options *opts)
* Some tasks could have been reparented to * Some tasks could have been reparented to
* namespaces' reaper. Check this. * namespaces' reaper. Check this.
*/ */
if (opts->namespaces_flags & CLONE_NEWPID) { if (opts->namespaces_flags & CLONE_NEWPID)
BUG_ON(root_item->pid.real_pid != 1);
if (check_subtree(root_item)) if (check_subtree(root_item))
goto try_again; goto try_again;
}
break; break;
} }
......
...@@ -711,17 +711,24 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts) ...@@ -711,17 +711,24 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
*/ */
if (init->pid.pid == 1) { if (init->pid.pid == 1) {
if (!(opts->namespaces_flags & CLONE_NEWPID)) {
pr_err("This process tree can be restored in a new pid namespace.\n");
pr_err("crtools should be re-executed with --namespace pid\n");
return -1;
}
snprintf(proc_mountpoint, sizeof(proc_mountpoint), "/tmp/crtools-proc.XXXXXX"); snprintf(proc_mountpoint, sizeof(proc_mountpoint), "/tmp/crtools-proc.XXXXXX");
if (mkdtemp(proc_mountpoint) == NULL) { if (mkdtemp(proc_mountpoint) == NULL) {
pr_err("mkdtemp failed %m"); pr_err("mkdtemp failed %m");
return -1; return -1;
} }
/* A process with pid = 1 is "init".
* It should be restore in new pid ns. } else if (opts->namespaces_flags & CLONE_NEWPID) {
* The first process in pid ns gets pid = 1 automaticaly. */ pr_err("Can't restore pid namespace without the process init\n");
opts->namespaces_flags |= CLONE_NEWPID; return -1;
} }
ret = fork_with_pid(init, opts->namespaces_flags); ret = fork_with_pid(init, opts->namespaces_flags);
if (ret < 0) if (ret < 0)
return -1; return -1;
......
...@@ -187,6 +187,8 @@ static int parse_ns_string(const char *ptr) ...@@ -187,6 +187,8 @@ static int parse_ns_string(const char *ptr)
opts.namespaces_flags |= CLONE_NEWIPC; opts.namespaces_flags |= CLONE_NEWIPC;
else if (!strncmp(ptr, "mnt", 3)) else if (!strncmp(ptr, "mnt", 3))
opts.namespaces_flags |= CLONE_NEWNS; opts.namespaces_flags |= CLONE_NEWNS;
else if (!strncmp(ptr, "pid", 3))
opts.namespaces_flags |= CLONE_NEWPID;
else else
goto bad_ns; goto bad_ns;
ptr += 4; ptr += 4;
...@@ -392,7 +394,7 @@ usage: ...@@ -392,7 +394,7 @@ usage:
pr_msg("\n* Special resources support:\n"); pr_msg("\n* Special resources support:\n");
pr_msg(" -n|--namespaces checkpoint/restore namespaces - values must be separated by comma\n"); pr_msg(" -n|--namespaces checkpoint/restore namespaces - values must be separated by comma\n");
pr_msg(" supported: uts, ipc\n"); pr_msg(" supported: uts, ipc, pid\n");
pr_msg(" -x|--ext-unix-sk allow external unix connections\n"); pr_msg(" -x|--ext-unix-sk allow external unix connections\n");
pr_msg(" --%s checkpoint/restore established TCP connections\n", SK_EST_PARAM); pr_msg(" --%s checkpoint/restore established TCP connections\n", SK_EST_PARAM);
......
...@@ -82,6 +82,11 @@ int dump_namespaces(struct pid *ns_pid, unsigned int ns_flags) ...@@ -82,6 +82,11 @@ int dump_namespaces(struct pid *ns_pid, unsigned int ns_flags)
pr_info("Dumping %d(%d)'s namespaces\n", ns_pid->pid, ns_pid->real_pid); pr_info("Dumping %d(%d)'s namespaces\n", ns_pid->pid, ns_pid->real_pid);
if ((opts.namespaces_flags & CLONE_NEWPID) && ns_pid->pid != 1) {
pr_err("Can't dump a pid namespace without the process init\n");
return -1;
}
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
pr_perror("Can't fork ns dumper"); pr_perror("Can't fork ns dumper");
......
...@@ -152,6 +152,10 @@ run_test() ...@@ -152,6 +152,10 @@ run_test()
ddump=dump/$tname/$PID ddump=dump/$tname/$PID
DUMP_PATH=`pwd`/$ddump DUMP_PATH=`pwd`/$ddump
if [ -n "$PIDNS" ]; then
args="--namespace pid $args"
fi
echo Dump $PID echo Dump $PID
mkdir -p $ddump mkdir -p $ddump
save_fds $PID $ddump/dump.fd save_fds $PID $ddump/dump.fd
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment