linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexey Dobriyan <adobriyan@gmail.com>
To: akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org,
	containers@lists.linux-foundation.org,
	torvalds@linux-foundation.org, xemul@parallels.com,
	orenl@cs.columbia.edu, serue@us.ibm.com, dave@linux.vnet.ibm.com,
	mingo@elte.hu, Alexey Dobriyan <adobriyan@gmail.com>
Subject: [PATCH 19/38] C/R: multiple tasks
Date: Fri, 22 May 2009 08:55:13 +0400	[thread overview]
Message-ID: <1242968132-1044-19-git-send-email-adobriyan@gmail.com> (raw)
In-Reply-To: <1242968132-1044-1-git-send-email-adobriyan@gmail.com>

Restore task hierarchy wrt ->real_parent.

First thing soon-to-be-restored task does after birth is to find
->real_parent and glue itself to parent lists.

For this parent is dumped first and restored first, so that at the time
child starts restoration, parent is already up and running as task_struct,
and we get cheap loop-prevention check.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/linux/kstate-image.h  |    2 +
 kernel/kstate/kstate-object.c |    3 +-
 kernel/kstate/kstate-task.c   |   53 +++++++++++++++++++++++++++++++++++-----
 3 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/include/linux/kstate-image.h b/include/linux/kstate-image.h
index ac3c81d..348f59f 100644
--- a/include/linux/kstate-image.h
+++ b/include/linux/kstate-image.h
@@ -60,6 +60,8 @@ struct kstate_object_header {
 struct kstate_image_task_struct {
 	struct kstate_object_header hdr;
 
+	kstate_ref_t	ref_real_parent;
+
 	kstate_ref_t	ref_mm;
 
 	__u8		comm[16];
diff --git a/kernel/kstate/kstate-object.c b/kernel/kstate/kstate-object.c
index f9f2f33..60ba70d 100644
--- a/kernel/kstate/kstate-object.c
+++ b/kernel/kstate/kstate-object.c
@@ -25,7 +25,8 @@ int kstate_collect_object(struct kstate_context *ctx, void *p, enum kstate_conte
 	obj->o_ref.pos = 0;	/* not yet dumped */
 	obj->o_ref.id = 0;	/* not yet assigned */
 	obj->o_obj = p;
-	list_add(&obj->o_list, &ctx->obj[type]);
+	/* task_struct collecting relies on "_tail" part. */
+	list_add_tail(&obj->o_list, &ctx->obj[type]);
 
 	switch (type) {
 	case KSTATE_CTX_FILE:
diff --git a/kernel/kstate/kstate-task.c b/kernel/kstate/kstate-task.c
index aec97c2..4f48c32 100644
--- a/kernel/kstate/kstate-task.c
+++ b/kernel/kstate/kstate-task.c
@@ -11,11 +11,6 @@
 static int check_task_struct(struct task_struct *tsk)
 {
 	read_lock_irq(&tasklist_lock);
-	if (!list_empty(&tsk->children)) {
-		read_unlock_irq(&tasklist_lock);
-		WARN_ON(1);
-		return -EINVAL;
-	}
 	if (!list_empty(&tsk->thread_group)) {
 		read_unlock_irq(&tasklist_lock);
 		WARN_ON(1);
@@ -74,8 +69,32 @@ static int collect_task_struct(struct kstate_context *ctx, struct task_struct *t
 
 int kstate_collect_all_task_struct(struct kstate_context *ctx)
 {
+	struct kstate_object *obj;
+	int rv;
+
 	/* Seed task list. */
-	return collect_task_struct(ctx, ctx->init_tsk);
+	rv = collect_task_struct(ctx, ctx->init_tsk);
+	if (rv < 0)
+		return rv;
+	/*
+	 * Children are added after parent as iteration goes on:
+	 * - parent is dumped before child, child knows position of parent's
+	 *   image and can reference it,
+	 * - task_struct restore is done in the same order: parent first.
+	 *   This is cheap loop prevention wrt "->real_parent": if real_parent
+	 *   reference can't be resolved at the time ->real_parent rewrite is
+	 *   done, image is malformed.
+	 */
+	for_each_kstate_object(ctx, obj, KSTATE_CTX_TASK_STRUCT) {
+		struct task_struct *tsk = obj->o_obj, *child;
+
+		list_for_each_entry(child, &tsk->children, sibling) {
+			rv = collect_task_struct(ctx, child);
+			if (rv < 0)
+				return rv;
+		}
+	}
+	return 0;
 }
 
 static int dump_task_struct(struct kstate_context *ctx, struct kstate_object *obj)
@@ -91,6 +110,13 @@ static int dump_task_struct(struct kstate_context *ctx, struct kstate_object *ob
 	if (!i)
 		return -ENOMEM;
 
+	tmp = find_kstate_obj_by_ptr(ctx, tsk->real_parent, KSTATE_CTX_TASK_STRUCT);
+	if (tmp)
+		i->ref_real_parent = tmp->o_ref;
+	else
+		/* Root of hierarchy to be checkpointed. */
+		i->ref_real_parent = KSTATE_REF_UNDEF;
+
 	tmp = find_kstate_obj_by_ptr(ctx, tsk->mm, KSTATE_CTX_MM_STRUCT);
 	i->ref_mm = tmp->o_ref;
 
@@ -206,7 +232,20 @@ static int task_struct_restorer(void *_tsk_ctx)
 	pr_debug("%s: ENTER tsk %p/%s\n", __func__, tsk, tsk->comm);
 
 	write_lock_irq(&tasklist_lock);
-	real_parent = ctx->init_tsk->nsproxy->pid_ns->child_reaper;
+	if (kstate_ref_undefined(&i->ref_real_parent))
+		real_parent = ctx->init_tsk->nsproxy->pid_ns->child_reaper;
+	else {
+		struct kstate_object *tmp;
+
+		/* Parent as task_struct should be restored already. */
+		tmp = find_kstate_obj_by_ref(ctx, &i->ref_real_parent, KSTATE_CTX_TASK_STRUCT);
+		if (!tmp) {
+			write_unlock_irq(&tasklist_lock);
+			rv = -EINVAL;
+			goto out;
+		}
+		real_parent = tmp->o_obj;
+	}
 	tsk->real_parent = tsk->parent = real_parent;
 	list_move_tail(&tsk->sibling, &tsk->real_parent->sibling);
 	write_unlock_irq(&tasklist_lock);
-- 
1.5.6.5


  parent reply	other threads:[~2009-05-22  5:00 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-22  4:54 [PATCH 01/38] cred: #include init.h in cred.h Alexey Dobriyan
2009-05-22  4:54 ` [PATCH 02/38] utsns: extract create_uts_ns() Alexey Dobriyan
2009-05-24 22:37   ` Serge E. Hallyn
2009-05-22  4:54 ` [PATCH 03/38] ipcns 1/4: remove useless get/put while CLONE_NEWIPC Alexey Dobriyan
2009-05-22  9:00   ` Amerigo Wang
2009-05-22  4:54 ` [PATCH 04/38] ipcns 2/4: extract create_ipc_ns() Alexey Dobriyan
2009-05-22  8:59   ` Amerigo Wang
2009-05-22  4:54 ` [PATCH 05/38] ipcns 3/4: make free_ipc_ns() static Alexey Dobriyan
2009-05-24 22:40   ` Serge E. Hallyn
2009-05-22  4:55 ` [PATCH 06/38] ipcns 4/2: move free_ipcs() proto Alexey Dobriyan
2009-05-24 22:49   ` Serge E. Hallyn
2009-05-22  4:55 ` [PATCH 07/38] pidns 1/2: make create_pid_namespace() accept parent pidns Alexey Dobriyan
2009-05-22  9:20   ` Amerigo Wang
2009-05-24 22:44   ` Serge E. Hallyn
2009-06-04  0:20   ` Sukadev Bhattiprolu
2009-05-22  4:55 ` [PATCH 08/38] pidns 2/2: rewrite copy_pid_ns() Alexey Dobriyan
2009-05-22  9:14   ` Amerigo Wang
2009-05-24 22:45   ` Serge E. Hallyn
2009-06-04  0:17   ` Sukadev Bhattiprolu
2009-05-22  4:55 ` [PATCH 09/38] netns 1/2: don't get/put old netns on CLONE_NEWNET Alexey Dobriyan
2009-05-22  6:30   ` David Miller
2009-05-22  4:55 ` [PATCH 10/38] netns 2/2: extract net_create() Alexey Dobriyan
2009-05-22  6:30   ` David Miller
2009-05-22  4:55 ` [PATCH 11/38] nsproxy: extract create_nsproxy() Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 12/38] i386: ifdef out struct thread_struct::fs Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 13/38] x86_64: ifdef out struct thread_struct::ip Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 14/38] Remove struct mm_struct::exe_file et al Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 15/38] dcache: extract and use d_unlinked() Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 16/38] x86: ptrace debugreg checks rewrite Alexey Dobriyan
2009-05-26 23:25   ` Andrew Morton
2009-05-22  4:55 ` [PATCH 17/38] groups: move code to kernel/groups.c Alexey Dobriyan
2009-05-25  0:53   ` Serge E. Hallyn
2009-05-26 14:48   ` Serge E. Hallyn
2009-05-26 18:34     ` Alexey Dobriyan
2009-05-26 23:25       ` Serge E. Hallyn
2009-05-22  4:55 ` [PATCH 18/38] C/R: core stuff Alexey Dobriyan
2009-05-26 13:16   ` Serge E. Hallyn
2009-05-26 19:35     ` Alexey Dobriyan
2009-05-26 23:14       ` Serge E. Hallyn
2009-05-26 23:44       ` Serge E. Hallyn
2009-05-28 15:38         ` Alexey Dobriyan
2009-05-28 18:17           ` Serge E. Hallyn
2009-05-28 22:42           ` Oren Laadan
2009-05-27 18:52       ` Dave Hansen
2009-05-27 20:56       ` Oren Laadan
2009-05-27 22:17         ` Alexey Dobriyan
2009-05-27 22:40           ` Andrew Morton
2009-05-27 22:45           ` Oren Laadan
2009-05-28 15:33             ` Alexey Dobriyan
2009-05-28 22:20               ` Oren Laadan
2009-05-28 22:33                 ` Matt Helsley
2009-05-29  6:01                 ` Alexey Dobriyan
2009-05-29 17:26                   ` Dave Hansen
2009-05-27 22:25         ` Alexey Dobriyan
2009-05-27 16:28   ` Alexey Dobriyan
2009-05-22  4:55 ` Alexey Dobriyan [this message]
2009-05-22  4:55 ` [PATCH 20/38] C/R: i386 support Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 21/38] C/R: i386 debug registers Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 22/38] C/R: i386 xstate Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 23/38] C/R: x86_64 support Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 24/38] C/R: x86_64 debug registers Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 25/38] C/R: x86_64 xstate Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 26/38] C/R: nsproxy Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 27/38] C/R: checkpoint/restore struct uts_namespace Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 28/38] C/R: formally checkpoint/restore struct ipc_namespace Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 29/38] C/R: formally checkpoint/restore struct mnt_namespace Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 30/38] C/R: checkpoint/restore struct pid_namespace Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 31/38] C/R: formally checkpoint/restore struct net_namespace Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 32/38] C/R: checkpoint/restore struct cred Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 33/38] C/R: checkpoint/restore aux groups (structy group_info) Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 34/38] C/R: checkpoint/restore struct user Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 35/38] C/R: checkpoint/restore struct user_namespace Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 36/38] C/R: checkpoint/restore struct pid Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 37/38] C/R: checkpoint/restore opened files Alexey Dobriyan
2009-05-22  4:55 ` [PATCH 38/38] C/R: checkpoint/restart struct sighand_struct Alexey Dobriyan
2009-05-22  5:02 ` [PATCH 01/38] cred: #include init.h in cred.h Alexey Dobriyan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1242968132-1044-19-git-send-email-adobriyan@gmail.com \
    --to=adobriyan@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=containers@lists.linux-foundation.org \
    --cc=dave@linux.vnet.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=orenl@cs.columbia.edu \
    --cc=serue@us.ibm.com \
    --cc=torvalds@linux-foundation.org \
    --cc=xemul@parallels.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).