Commit a2eaa5cf authored by Andrew Vagin's avatar Andrew Vagin Committed by Pavel Emelyanov

ptrace: the task state is restored automatically

It's a feature of PTRACE_SEIZE.  So we need to do something, only
if we want to change the state.

[xemul: If task _was_ in stopped state before dump and we want them
 to stay alive after dump, the existing code queues one more STOP
 to it. This affects subsequent dump, as we seize a stopped task
 with STOP in queue.

 One more item in TODO list -- support stopped tasks with STOP in
 queue :)
]
Signed-off-by: 's avatarAndrew Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 805e25ef
......@@ -808,10 +808,7 @@ static void unseize_task_and_threads(const struct pstree_item *item, int st)
* the item->state is the state task was in when we seized one.
*/
if (st == TASK_ALIVE)
unseize_task(item->pid.real, item->state);
else
unseize_task(item->pid.real, st); /* item->pid will be here */
unseize_task(item->pid.real, item->state, st);
for (i = 1; i < item->nr_threads; i++)
ptrace(PTRACE_DETACH, item->threads[i].real, NULL, NULL);
......
......@@ -153,7 +153,7 @@ int cr_exec(int pid, char **opt)
parasite_cure_seized(ctl);
out_unseize:
unseize_task(pid, prev_state);
unseize_task(pid, prev_state, prev_state);
out:
return ret;
}
......@@ -56,7 +56,7 @@ struct ptrace_peeksiginfo_args {
#define SI_EVENT(_si_code) (((_si_code) & 0xFFFF) >> 8)
extern int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid);
extern int unseize_task(pid_t pid, int state);
extern int unseize_task(pid_t pid, int orig_state, int state);
extern int ptrace_peek_area(pid_t pid, void *dst, void *addr, long bytes);
extern int ptrace_poke_area(pid_t pid, void *src, void *addr, long bytes);
extern int ptrace_swap_area(pid_t pid, void *dst, void *src, long bytes);
......
......@@ -19,13 +19,13 @@
#include "ptrace.h"
#include "proc_parse.h"
int unseize_task(pid_t pid, int st)
int unseize_task(pid_t pid, int orig_st, int st)
{
pr_debug("\tUnseizing %d into %d\n", pid, st);
if (st == TASK_DEAD)
kill(pid, SIGKILL);
else if (st == TASK_STOPPED)
else if (st == TASK_STOPPED && orig_st == TASK_ALIVE)
kill(pid, SIGSTOP);
else if (st == TASK_ALIVE)
/* do nothing */ ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment