[CRIU] [PATCH cr 05/10] restore: restore sids of tasks,
which have been reparented to init (v2)
Andrey Vagin
avagin at openvz.org
Tue Jun 19 08:46:56 EDT 2012
v2: fix variables names and check errors
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-restore.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 84 insertions(+), 0 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index 9ba4d4d..1f0e916 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -172,6 +172,87 @@ static int prepare_pstree(void)
return ret;
}
+static int prepare_pstree_ids(void)
+{
+ struct pstree_item *item, *child, *helper, *tmp;
+ LIST_HEAD(helpers);
+
+ /* Some task can be reparented to init. A helper task should be added
+ * for restoring sid of such tasks. The helper tasks will be exited
+ * immediately after forking children and all children will be
+ * reparented to init. */
+ list_for_each_entry(item, &root_item->children, list) {
+ if (item->sid == root_item->sid || item->sid == item->pid)
+ continue;
+
+ helper = alloc_pstree_item();
+ if (helper == NULL)
+ return -1;
+ helper->sid = item->sid;
+ helper->pgid = item->sid;
+ helper->pid = item->sid;
+ helper->state = TASK_HELPER;
+ helper->parent = root_item;
+ list_add_tail(&helper->list, &helpers);
+
+ pr_info("Add a helper %d for restoring SID %d\n",
+ helper->pid, helper->sid);
+
+ child = list_entry(item->list.prev, struct pstree_item, list);
+ item = child;
+
+ list_for_each_entry_safe_continue(child, tmp, &root_item->children, list) {
+ if (child->sid != helper->sid)
+ continue;
+ if (child->sid == child->pid)
+ continue;
+
+ pr_info("Attach %d to the temporary task %d\n",
+ child->pid, helper->pid);
+
+ child->parent = helper;
+ list_move(&child->list, &helper->children);
+ }
+ }
+
+ for_each_pstree_item(item) {
+ if (!item->parent) /* skip the root task */
+ continue;
+
+ /* Try to find a session leader */
+ if (item->state == TASK_HELPER)
+ continue;
+
+ if (item->sid != item->pid)
+ continue;
+
+ pr_info("Session leader %d\n", item->sid);
+
+ /* Try to find helpers, who should be connected to the leader */
+ list_for_each_entry(child, &helpers, list) {
+ if (child->state != TASK_HELPER)
+ continue;
+
+ if (child->sid != item->sid)
+ continue;
+
+ child->pgid = item->pgid;
+ child->pid = ++max_pid;
+ child->parent = item;
+ list_move(&child->list, &item->children);
+
+ pr_info("Attach %d to the task %d\n",
+ child->pid, item->pid);
+
+ break;
+ }
+ }
+
+ list_splice(&helpers, &root_item->children);
+
+ return 0;
+}
+
static int prepare_shared(void)
{
int ret = 0;
@@ -842,6 +923,9 @@ static int restore_all_tasks(pid_t pid, struct cr_options *opts)
if (prepare_shared() < 0)
return -1;
+ if (prepare_pstree_ids() < 0)
+ return -1;
+
return restore_root_task(root_item, opts);
}
--
1.7.1
More information about the CRIU
mailing list