Commit 11b7e14a authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Cyrill Gorcunov

dump: Fix task freezing process

Currently we read the children tree of running processes.
This is deadly wrong. Stop task once we open it's proc dir
before descending to its kids.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 7e8eb76e
......@@ -760,6 +760,36 @@ err:
return NULL;
}
static const int state_sigs[] = {
[CR_TASK_STOP] = SIGSTOP,
[CR_TASK_RUN] = SIGCONT,
[CR_TASK_KILL] = SIGKILL,
};
static int ps_switch_state(int pid, enum cr_task_state state)
{
return kill(pid, state_sigs[state]);
}
static void pstree_switch_state(struct list_head *list,
enum cr_task_state state, int leader_only)
{
struct pstree_item *item;
/*
* Since ptrace-seize doesn't work on frozen tasks
* we stick with explicit tasks stopping via stop
* signal, but in future it's aimed to switch to
* kernel freezer.
*/
list_for_each_entry(item, list, list) {
kill(item->pid, state_sigs[state]);
if (leader_only)
break;
}
}
static int collect_pstree(pid_t pid, struct list_head *pstree_list)
{
struct pstree_item *item;
......@@ -771,6 +801,9 @@ static int collect_pstree(pid_t pid, struct list_head *pstree_list)
if (pid_dir < 0)
goto err;
if (ps_switch_state(pid, CR_TASK_STOP))
goto err;
item = add_pstree_entry(pid, pid_dir, pstree_list);
if (!item)
goto err;
......@@ -1103,31 +1136,6 @@ err:
return ret;
}
static void pstree_switch_state(struct list_head *list,
enum cr_task_state state, int leader_only)
{
static const int state_sigs[] = {
[CR_TASK_STOP] = SIGSTOP,
[CR_TASK_RUN] = SIGCONT,
[CR_TASK_KILL] = SIGKILL,
};
struct pstree_item *item;
/*
* Since ptrace-seize doesn't work on frozen tasks
* we stick with explicit tasks stopping via stop
* signal, but in future it's aimed to switch to
* kernel freezer.
*/
list_for_each_entry(item, list, list) {
kill(item->pid, state_sigs[state]);
if (leader_only)
break;
}
}
int cr_dump_tasks(pid_t pid, struct cr_options *opts)
{
LIST_HEAD(pstree_list);
......@@ -1155,8 +1163,6 @@ int cr_dump_tasks(pid_t pid, struct cr_options *opts)
collect_sockets();
pstree_switch_state(&pstree_list, CR_TASK_STOP, opts->leader_only);
list_for_each_entry(item, &pstree_list, list) {
if (item->pid == pid) {
cr_fdset = prep_cr_fdset_for_dump(item->pid, CR_FD_DESC_ALL);
......
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