From: Andrey Mirkin <major@openvz.org>
To: containers@lists.linux-foundation.org, linux-kernel@vger.kernel.org
Cc: Pavel Emelyanov <xemul@openvz.org>, Andrey Mirkin <major@openvz.org>
Subject: [PATCH 10/10] Add support for multiple processes
Date: Sat, 18 Oct 2008 03:11:38 +0400 [thread overview]
Message-ID: <1224285098-573-11-git-send-email-major@openvz.org> (raw)
In-Reply-To: <1224285098-573-10-git-send-email-major@openvz.org>
The whole tree of processes can be checkpointed and restarted now.
Shared objects are not supported yet.
Signed-off-by: Andrey Mirkin <major@openvz.org>
---
checkpoint/cpt_image.h | 2 +
checkpoint/cpt_process.c | 24 +++++++++++++
checkpoint/rst_process.c | 85 +++++++++++++++++++++++++++-------------------
3 files changed, 76 insertions(+), 35 deletions(-)
diff --git a/checkpoint/cpt_image.h b/checkpoint/cpt_image.h
index e1fb483..f370df2 100644
--- a/checkpoint/cpt_image.h
+++ b/checkpoint/cpt_image.h
@@ -128,6 +128,8 @@ struct cpt_task_image {
__u64 cpt_nivcsw;
__u64 cpt_min_flt;
__u64 cpt_maj_flt;
+ __u32 cpt_children_num;
+ __u32 cpt_pad;
} __attribute__ ((aligned (8)));
struct cpt_mm_image {
diff --git a/checkpoint/cpt_process.c b/checkpoint/cpt_process.c
index 1f7a54b..d73ec3c 100644
--- a/checkpoint/cpt_process.c
+++ b/checkpoint/cpt_process.c
@@ -40,6 +40,19 @@ static unsigned int encode_task_flags(unsigned int task_flags)
}
+static int cpt_count_children(struct task_struct *tsk, struct cpt_context *ctx)
+{
+ int num = 0;
+ struct task_struct *child;
+
+ list_for_each_entry(child, &tsk->children, sibling) {
+ if (child->parent != tsk)
+ continue;
+ num++;
+ }
+ return num;
+}
+
int cpt_dump_task_struct(struct task_struct *tsk, struct cpt_context *ctx)
{
struct cpt_task_image *t;
@@ -102,6 +115,7 @@ int cpt_dump_task_struct(struct task_struct *tsk, struct cpt_context *ctx)
t->cpt_egid = tsk->egid;
t->cpt_sgid = tsk->sgid;
t->cpt_fsgid = tsk->fsgid;
+ t->cpt_children_num = cpt_count_children(tsk, ctx);
err = ctx->write(t, sizeof(*t), ctx);
@@ -231,6 +245,16 @@ int cpt_dump_task(struct task_struct *tsk, struct cpt_context *ctx)
err = cpt_dump_fpustate(tsk, ctx);
if (!err)
err = cpt_dump_registers(tsk, ctx);
+ if (!err) {
+ struct task_struct *child;
+ list_for_each_entry(child, &tsk->children, sibling) {
+ if (child->parent != tsk)
+ continue;
+ err = cpt_dump_task(child, ctx);
+ if (err)
+ break;
+ }
+ }
return err;
}
diff --git a/checkpoint/rst_process.c b/checkpoint/rst_process.c
index 9e448b2..c088833 100644
--- a/checkpoint/rst_process.c
+++ b/checkpoint/rst_process.c
@@ -25,7 +25,7 @@ struct thr_context {
struct completion complete;
int error;
struct cpt_context *ctx;
- struct task_struct *tsk;
+ struct cpt_task_image *ti;
};
int local_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags, pid_t pid)
@@ -199,17 +199,14 @@ static int restart_thread(void *arg)
struct cpt_context *ctx;
struct cpt_task_image *ti;
int err;
+ int i;
current->state = TASK_UNINTERRUPTIBLE;
ctx = thr_ctx->ctx;
- ti = kmalloc(sizeof(*ti), GFP_KERNEL);
- if (!ti)
- return -ENOMEM;
+ ti = thr_ctx->ti;
- err = rst_get_object(CPT_OBJ_TASK, ti, sizeof(*ti), ctx);
- if (!err)
- err = rst_restore_task_struct(current, ti, ctx);
+ err = rst_restore_task_struct(current, ti, ctx);
if (!err)
err = rst_restore_mm(ctx);
if (!err)
@@ -217,6 +214,12 @@ static int restart_thread(void *arg)
if (!err)
err = rst_restore_registers(current, ctx);
+ for (i = 0; i < ti->cpt_children_num; i++) {
+ err = rst_restart_process(ctx);
+ if (err)
+ break;
+ }
+
thr_ctx->error = err;
complete(&thr_ctx->complete);
@@ -226,7 +229,6 @@ static int restart_thread(void *arg)
__set_current_state(TASK_UNINTERRUPTIBLE);
}
- kfree(ti);
schedule();
eprintk("leaked %d/%d %p\n", task_pid_nr(current), task_pid_vnr(current), current->mm);
@@ -235,44 +237,57 @@ static int restart_thread(void *arg)
complete_and_exit(NULL, 0);
return 0;
}
-static int create_root_task(struct cpt_context *ctx,
- struct thr_context *thr_ctx)
+
+int rst_restart_process(struct cpt_context *ctx)
{
+ struct thr_context thr_ctx;
struct task_struct *tsk;
+ struct cpt_task_image *ti;
int pid;
+ int err;
- thr_ctx->ctx = ctx;
- thr_ctx->error = 0;
- init_completion(&thr_ctx->complete);
+ thr_ctx.ctx = ctx;
+ thr_ctx.error = 0;
+ init_completion(&thr_ctx.complete);
- /* We should also create container here */
- pid = local_kernel_thread(restart_thread, thr_ctx,
- CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
- CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET, 0);
- if (pid < 0)
- return pid;
+ ti = kmalloc(sizeof(*ti), GFP_KERNEL);
+ if (!ti)
+ return -ENOMEM;
+
+ err = rst_get_object(CPT_OBJ_TASK, ti, sizeof(*ti), ctx);
+ if (err)
+ goto err_free;
+ thr_ctx.ti = ti;
+
+ if (ti->cpt_pid == 1) {
+ /* We should also create container here */
+ pid = local_kernel_thread(restart_thread, &thr_ctx,
+ CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
+ CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET, 0);
+ } else {
+ /* We should fork here a child with the same pid and
+ correct flags */
+ pid = local_kernel_thread(restart_thread, &thr_ctx, 0, 0);
+ }
+ if (pid < 0) {
+ err = pid;
+ goto err_free;
+ }
read_lock(&tasklist_lock);
tsk = find_task_by_vpid(pid);
if (tsk)
get_task_struct(tsk);
read_unlock(&tasklist_lock);
- if (tsk == NULL)
- return -ESRCH;
- thr_ctx->tsk = tsk;
- return 0;
-}
-
-int rst_restart_process(struct cpt_context *ctx)
-{
- struct thr_context thr_ctx_root;
- int err;
-
- err = create_root_task(ctx, &thr_ctx_root);
- if (err)
- return err;
+ if (tsk == NULL) {
+ err = -ESRCH;
+ goto err_free;
+ }
- wait_for_completion(&thr_ctx_root.complete);
- wait_task_inactive(thr_ctx_root.tsk, 0);
+ wait_for_completion(&thr_ctx.complete);
+ wait_task_inactive(tsk, 0);
+ err = thr_ctx.error;
+err_free:
+ kfree(ti);
return err;
}
--
1.5.6
next prev parent reply other threads:[~2008-10-17 23:15 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-17 23:11 [PATCH 0/10] OpenVZ kernel based checkpointing/restart (v2) Andrey Mirkin
2008-10-17 23:11 ` [PATCH 01/10] Introduce trivial sys_checkpoint and sys_restore system calls Andrey Mirkin
2008-10-17 23:11 ` [PATCH 02/10] Make checkpoint/restart functionality modular Andrey Mirkin
2008-10-17 23:11 ` [PATCH 03/10] Introduce context structure needed during checkpointing/restart Andrey Mirkin
2008-10-17 23:11 ` [PATCH 04/10] Introduce container dump function Andrey Mirkin
2008-10-17 23:11 ` [PATCH 05/10] Introduce function to dump process Andrey Mirkin
2008-10-17 23:11 ` [PATCH 06/10] Introduce functions to dump mm Andrey Mirkin
2008-10-17 23:11 ` [PATCH 07/10] Introduce function for restarting a container Andrey Mirkin
2008-10-17 23:11 ` [PATCH 08/10] Introduce functions to restart a process Andrey Mirkin
2008-10-17 23:11 ` [PATCH 09/10] Introduce functions to restore mm Andrey Mirkin
2008-10-17 23:11 ` Andrey Mirkin [this message]
2008-10-27 15:58 ` [PATCH 10/10] Add support for multiple processes Oren Laadan
2008-10-30 4:55 ` [Devel] " Andrey Mirkin
2008-10-20 9:23 ` [PATCH 08/10] Introduce functions to restart a process Cedric Le Goater
2008-10-22 8:49 ` [Devel] " Andrey Mirkin
2008-10-22 9:25 ` Louis Rilling
2008-10-22 10:06 ` Greg Kurz
2008-10-22 10:44 ` Louis Rilling
2008-10-22 12:44 ` Greg Kurz
2008-10-22 10:12 ` Andrey Mirkin
2008-10-22 10:46 ` Louis Rilling
2008-10-23 8:53 ` Andrey Mirkin
2008-10-22 15:25 ` Oren Laadan
2008-10-23 9:00 ` Andrey Mirkin
2008-10-23 13:57 ` Dave Hansen
2008-10-24 3:57 ` Andrey Mirkin
2008-10-25 21:10 ` Oren Laadan
2008-10-29 14:52 ` Andrey Mirkin
2008-10-30 15:59 ` Oren Laadan
2008-10-22 12:47 ` Cedric Le Goater
2008-10-23 9:54 ` Andrey Mirkin
2008-10-23 13:49 ` Dave Hansen
2008-10-24 4:04 ` Andrey Mirkin
2008-10-20 13:25 ` Louis Rilling
2008-10-23 10:56 ` [Devel] " Andrey Mirkin
2008-10-20 12:25 ` [PATCH 06/10] Introduce functions to dump mm Louis Rilling
2008-10-22 8:58 ` [Devel] " Andrey Mirkin
2008-10-20 17:21 ` Dave Hansen
2008-10-23 8:43 ` [Devel] " Andrey Mirkin
2008-10-23 13:51 ` Dave Hansen
2008-10-24 4:07 ` Andrey Mirkin
2008-10-20 11:02 ` [PATCH 05/10] Introduce function to dump process Louis Rilling
2008-10-24 4:15 ` [Devel] " Andrey Mirkin
2008-10-20 17:48 ` Serge E. Hallyn
2008-10-24 4:40 ` [Devel] " Andrey Mirkin
2008-10-20 17:02 ` [PATCH 03/10] Introduce context structure needed during checkpointing/restart Dave Hansen
2008-10-29 15:30 ` [Devel] " Andrey Mirkin
2008-10-20 16:51 ` [PATCH 02/10] Make checkpoint/restart functionality modular Dave Hansen
2008-10-20 16:59 ` Serge E. Hallyn
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=1224285098-573-11-git-send-email-major@openvz.org \
--to=major@openvz.org \
--cc=containers@lists.linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=xemul@openvz.org \
/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).