* [PATCH-user-cr] restart: handle dead/dummy tasks like ghosts
@ 2009-10-01 1:36 Oren Laadan
[not found] ` <1254360988-29553-1-git-send-email-orenl-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Oren Laadan @ 2009-10-01 1:36 UTC (permalink / raw)
To: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In "subtree" restart (restarting not inside a container), 'restart'
uses prctl(PR_DEATH_SIGNAL,...) to ensure proper cleanup should the
restart fail prematurely. The death_signal is sent, recursively, to
all the descendants of root to force-kill them.
However, dead (dummy) tasks, marked with TASK_DEAD, used to exit
during the creation of the task tree. Since the task is not within
sys_restart it does not have the PF_RESTARTING, and therefore will
send the death_signal its children as it exits.
To fix it, we observe that dead tasks are much like ghost tasks:
they are expected to terminate from within sys_restart, and before
the other tasks may resume execution. So we now treat dead (dummy)
tasks similarly to ghost tasks.
Signed-off-by: Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
---
restart.c | 27 ++++++++-------------------
1 files changed, 8 insertions(+), 19 deletions(-)
diff --git a/restart.c b/restart.c
index 07ffdc3..b810ca9 100644
--- a/restart.c
+++ b/restart.c
@@ -1485,10 +1485,12 @@ static int ckpt_propagate_session(struct ckpt_ctx *ctx, struct task *task)
* needed. In the second pass the task forks the remainder of the
* children. In both passes, a child that is marked TASK_THREAD is
* created as a thread and a child that is marked TASK_SIBLING is
- * created with parent inheritance. In the third pass, terminated
- * tasks and temporary placeholders are cleaned up. Finally, the task
- * either terminates if it is marked TASK_DEAD or calls sys_restart()
- * which does not return.
+ * created with parent inheritance. Finally, the task will invoke
+ * sys_restart() which does not return (if successful).
+ *
+ * Tasks marked TASK_DEAD or TASK_GHOST are both destined to terminate
+ * anyway; both use flag RESTART_GHOST for sys_restart(), which will
+ * result in a call to do_exit().
*/
static int ckpt_make_tree(struct ckpt_ctx *ctx, struct task *task)
{
@@ -1534,17 +1536,6 @@ static int ckpt_make_tree(struct ckpt_ctx *ctx, struct task *task)
}
}
- /* 3rd pass: bring out your deads ... */
- for (child = task->children; child; child = child->next_sib) {
- if (child->flags & TASK_DEAD) {
- ret = waitpid(child->rpid, NULL, 0);
- if (ret < 0) {
- perror("waitpid");
- return -1;
- }
- }
- }
-
/* are we supposed to exit now ? */
if (task->flags & TASK_DEAD) {
ckpt_dbg("pid %d: task dead ... exiting\n", task->pid);
@@ -1587,7 +1578,7 @@ static int ckpt_make_tree(struct ckpt_ctx *ctx, struct task *task)
* then exit (more precisely, killed). The RESTART_GHOST flag
* tells the kernel that they are not to be restored.
*/
- if (task->flags & TASK_GHOST)
+ if (task->flags & (TASK_GHOST | TASK_DEAD))
flags |= RESTART_GHOST;
/* on success this doesn't return */
@@ -1907,9 +1898,7 @@ static int ckpt_adjust_pids(struct ckpt_ctx *ctx)
/* read in 'pid_swap' data and adjust ctx->pids_arr */
for (n = 0; n < ctx->tasks_nr; n++) {
- /* don't expect data from dead tasks */
- if (ctx->tasks_arr[n].flags & TASK_DEAD)
- continue;
+ /* get pid info from next task */
ret = read(ctx->pipe_in, &swap, sizeof(swap));
if (ret < 0)
ckpt_abort(ctx, "read pipe");
--
1.6.0.4
^ permalink raw reply related [flat|nested] 3+ messages in thread[parent not found: <1254360988-29553-1-git-send-email-orenl-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org>]
* Re: [PATCH-user-cr] restart: handle dead/dummy tasks like ghosts [not found] ` <1254360988-29553-1-git-send-email-orenl-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org> @ 2009-10-01 3:26 ` Serge E. Hallyn [not found] ` <20091001032650.GA9491-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> 0 siblings, 1 reply; 3+ messages in thread From: Serge E. Hallyn @ 2009-10-01 3:26 UTC (permalink / raw) To: Oren Laadan; +Cc: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA Quoting Oren Laadan (orenl-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org): > In "subtree" restart (restarting not inside a container), 'restart' > uses prctl(PR_DEATH_SIGNAL,...) to ensure proper cleanup should the > restart fail prematurely. The death_signal is sent, recursively, to > all the descendants of root to force-kill them. > > However, dead (dummy) tasks, marked with TASK_DEAD, used to exit > during the creation of the task tree. Since the task is not within > sys_restart it does not have the PF_RESTARTING, and therefore will > send the death_signal its children as it exits. > > To fix it, we observe that dead tasks are much like ghost tasks: > they are expected to terminate from within sys_restart, and before > the other tasks may resume execution. So we now treat dead (dummy) > tasks similarly to ghost tasks. > > Signed-off-by: Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org> Hmm? But at line 1540 you are still doing do_exit if it's TASK_DEAD :) > --- > restart.c | 27 ++++++++------------------- > 1 files changed, 8 insertions(+), 19 deletions(-) > > diff --git a/restart.c b/restart.c > index 07ffdc3..b810ca9 100644 > --- a/restart.c > +++ b/restart.c > @@ -1485,10 +1485,12 @@ static int ckpt_propagate_session(struct ckpt_ctx *ctx, struct task *task) > * needed. In the second pass the task forks the remainder of the > * children. In both passes, a child that is marked TASK_THREAD is > * created as a thread and a child that is marked TASK_SIBLING is > - * created with parent inheritance. In the third pass, terminated > - * tasks and temporary placeholders are cleaned up. Finally, the task > - * either terminates if it is marked TASK_DEAD or calls sys_restart() > - * which does not return. > + * created with parent inheritance. Finally, the task will invoke > + * sys_restart() which does not return (if successful). > + * > + * Tasks marked TASK_DEAD or TASK_GHOST are both destined to terminate > + * anyway; both use flag RESTART_GHOST for sys_restart(), which will > + * result in a call to do_exit(). > */ > static int ckpt_make_tree(struct ckpt_ctx *ctx, struct task *task) > { > @@ -1534,17 +1536,6 @@ static int ckpt_make_tree(struct ckpt_ctx *ctx, struct task *task) > } > } > > - /* 3rd pass: bring out your deads ... */ > - for (child = task->children; child; child = child->next_sib) { > - if (child->flags & TASK_DEAD) { > - ret = waitpid(child->rpid, NULL, 0); > - if (ret < 0) { > - perror("waitpid"); > - return -1; > - } > - } > - } > - > /* are we supposed to exit now ? */ > if (task->flags & TASK_DEAD) { > ckpt_dbg("pid %d: task dead ... exiting\n", task->pid); > @@ -1587,7 +1578,7 @@ static int ckpt_make_tree(struct ckpt_ctx *ctx, struct task *task) > * then exit (more precisely, killed). The RESTART_GHOST flag > * tells the kernel that they are not to be restored. > */ > - if (task->flags & TASK_GHOST) > + if (task->flags & (TASK_GHOST | TASK_DEAD)) > flags |= RESTART_GHOST; > > /* on success this doesn't return */ > @@ -1907,9 +1898,7 @@ static int ckpt_adjust_pids(struct ckpt_ctx *ctx) > > /* read in 'pid_swap' data and adjust ctx->pids_arr */ > for (n = 0; n < ctx->tasks_nr; n++) { > - /* don't expect data from dead tasks */ > - if (ctx->tasks_arr[n].flags & TASK_DEAD) > - continue; > + /* get pid info from next task */ > ret = read(ctx->pipe_in, &swap, sizeof(swap)); > if (ret < 0) > ckpt_abort(ctx, "read pipe"); > -- > 1.6.0.4 > > _______________________________________________ > Containers mailing list > Containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org > https://lists.linux-foundation.org/mailman/listinfo/containers ^ permalink raw reply [flat|nested] 3+ messages in thread
[parent not found: <20091001032650.GA9491-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH-user-cr] restart: handle dead/dummy tasks like ghosts [not found] ` <20091001032650.GA9491-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> @ 2009-10-01 14:59 ` Oren Laadan 0 siblings, 0 replies; 3+ messages in thread From: Oren Laadan @ 2009-10-01 14:59 UTC (permalink / raw) To: Serge E. Hallyn; +Cc: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA Serge E. Hallyn wrote: > Quoting Oren Laadan (orenl-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org): >> In "subtree" restart (restarting not inside a container), 'restart' >> uses prctl(PR_DEATH_SIGNAL,...) to ensure proper cleanup should the >> restart fail prematurely. The death_signal is sent, recursively, to >> all the descendants of root to force-kill them. >> >> However, dead (dummy) tasks, marked with TASK_DEAD, used to exit >> during the creation of the task tree. Since the task is not within >> sys_restart it does not have the PF_RESTARTING, and therefore will >> send the death_signal its children as it exits. >> >> To fix it, we observe that dead tasks are much like ghost tasks: >> they are expected to terminate from within sys_restart, and before >> the other tasks may resume execution. So we now treat dead (dummy) >> tasks similarly to ghost tasks. >> >> Signed-off-by: Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org> > > Hmm? But at line 1540 you are still doing do_exit if it's > TASK_DEAD :) Oops... I thought I removed it... will do. Oren. ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-10-01 14:59 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-01 1:36 [PATCH-user-cr] restart: handle dead/dummy tasks like ghosts Oren Laadan
[not found] ` <1254360988-29553-1-git-send-email-orenl-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org>
2009-10-01 3:26 ` Serge E. Hallyn
[not found] ` <20091001032650.GA9491-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-10-01 14:59 ` Oren Laadan
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.