[CRIU] [PATCH v3 48/55] pid: Set pid_ns before we create a child
Kirill Tkhai
ktkhai at virtuozzo.com
Mon Apr 10 01:23:04 PDT 2017
Get pid_ns of the child and setns() it.
Of course, many optimizations are possible
here, but not for now.
v3: Save current pid_for_children ns to do not do excess setns()
when it's already set.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/cr-restore.c | 36 ++++++++++++++++++++++++++++++++++++
criu/include/pstree.h | 1 +
2 files changed, 37 insertions(+)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 6594399fe..780efed18 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -324,6 +324,38 @@ static void wait_pid_ns_helper_prepared(struct ns_id *pid_ns, struct pid *pid)
futex_wait_while_eq(&pid_ns->pid.helper_created, 0);
}
+static int set_pid_ns_for_children(struct ns_id *pid_ns, struct pid *pid)
+{
+ int fd, ret = 0;
+
+ if (!(root_ns_mask & CLONE_NEWPID))
+ return 0;
+
+ if (last_level_pid(pid) == INIT_PID)
+ return 0;
+
+ BUG_ON(!current);
+
+ if (current->pid_for_children_ns == pid_ns)
+ return 0;
+
+ fd = fdstore_get(pid_ns->pid.nsfd_id);
+ if (fd < 0) {
+ pr_err("Can't get pid_ns fd\n");
+ return -1;
+ }
+
+ if (setns(fd, CLONE_NEWPID) < 0) {
+ pr_perror("Can't set pid ns");
+ ret = -1;
+ } else {
+ current->pid_for_children_ns = pid_ns;
+ }
+
+ close(fd);
+ return ret;
+}
+
static rt_sigaction_t sigchld_act;
/*
* If parent's sigaction has blocked SIGKILL (which is non-sence),
@@ -1028,6 +1060,7 @@ static inline int fork_with_pid(struct pstree_item *item)
pid_ns = lookup_ns_by_id(item->ids->pid_ns_id, &pid_ns_desc);
BUG_ON(!pid_ns);
+ item->pid_for_children_ns = pid_ns;
if (item->pid->state != TASK_HELPER) {
if (open_core(pid, &ca.core))
@@ -1073,6 +1106,9 @@ static inline int fork_with_pid(struct pstree_item *item)
wait_pid_ns_helper_prepared(pid_ns, item->pid);
+ if (set_pid_ns_for_children(pid_ns, item->pid) < 0)
+ goto err_close;
+
if (flock(ca.fd, LOCK_EX)) {
pr_perror("%d: Can't lock %s", pid, LAST_PID_PATH);
goto err_close;
diff --git a/criu/include/pstree.h b/criu/include/pstree.h
index 05e5b1e8f..11ff58d33 100644
--- a/criu/include/pstree.h
+++ b/criu/include/pstree.h
@@ -30,6 +30,7 @@ struct pstree_item {
unsigned long task_st_le_bits;
};
struct ns_id *user_ns;
+ struct ns_id *pid_for_children_ns;
};
static inline pid_t vpid(const struct pstree_item *i)
More information about the CRIU
mailing list