[CRIU] [PATCH cr 06/10] restore: restore sid of task which isn't
leaders and isn't a child of init (v2)
Andrey Vagin
avagin at openvz.org
Tue Jun 19 08:46:57 EDT 2012
It's sign, that a parent has been changed sid after forking a child.
We should know a sid with which a process was born, because in a processes
chain, more then one process might change SID.
v2: fix names of variables
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-restore.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++----
include/crtools.h | 5 +++-
2 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index 1f0e916..a1f634c 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -223,8 +223,26 @@ static int prepare_pstree_ids(void)
if (item->state == TASK_HELPER)
continue;
- if (item->sid != item->pid)
+ if (item->sid != item->pid) {
+ struct pstree_item *parent;
+
+ if (item->parent->sid == item->sid)
+ continue;
+
+ /* the task could fork a child before and after setsid() */
+ parent = item->parent;
+ while (parent && parent->pid != item->sid) {
+ parent->born_sid = item->sid;
+ pr_info("%d was born with sid %d\n", parent->pid, item->sid);
+ parent = parent->parent;
+ }
+
+ if (parent == NULL) {
+ pr_err("Can't find a session leader for %d\n", item->sid);
+ }
+
continue;
+ }
pr_info("Session leader %d\n", item->sid);
@@ -747,6 +765,16 @@ static void restore_pgid(void)
static char proc_mountpoint[PATH_MAX] = "/proc";
+static bool restore_before_setsid(struct pstree_item *child)
+{
+ int csid = child->born_sid == -1 ? child->sid : child->born_sid;
+
+ if (child->parent->born_sid == csid)
+ return true;
+
+ return false;
+}
+
static int restore_task_with_children(void *_arg)
{
struct cr_clone_arg *ca = _arg;
@@ -784,8 +812,6 @@ static int restore_task_with_children(void *_arg)
exit(-1);
}
- restore_sid();
-
/*
* The block mask will be restored in sigresturn.
*
@@ -801,13 +827,31 @@ static int restore_task_with_children(void *_arg)
pr_info("Restoring children:\n");
list_for_each_entry(child, &me->children, list) {
+ if (!restore_before_setsid(child))
+ continue;
+
+ BUG_ON(child->born_sid != -1 && getsid(getpid()) != child->born_sid);
+
ret = fork_with_pid(child, 0);
if (ret < 0)
exit(1);
}
- futex_dec_and_wake(&task_entries->nr_in_progress);
- futex_wait_while(&task_entries->start, CR_STATE_FORKING);
+ restore_sid();
+
+ pr_info("Restoring children:\n");
+ list_for_each_entry(child, &me->children, list) {
+ if (restore_before_setsid(child))
+ continue;
+ ret = fork_with_pid(child, 0);
+ if (ret < 0)
+ exit(1);
+ }
+
+ if (me->state != TASK_HELPER) {
+ futex_dec_and_wake(&task_entries->nr_in_progress);
+ futex_wait_while(&task_entries->start, CR_STATE_FORKING);
+ }
restore_pgid();
diff --git a/include/crtools.h b/include/crtools.h
index cb7dd3a..798d196 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -184,7 +184,10 @@ struct pid {
struct pstree_item {
struct list_head list;
u32 pid;
- u32 real_pid;
+ union {
+ u32 real_pid;
+ u32 born_sid;
+ };
struct pstree_item *parent;
struct list_head children; /* array of children */
pid_t pgid;
--
1.7.1
More information about the CRIU
mailing list