Commit 0ca9ccc3 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Cyrill Gorcunov

crtools: Sanitize the tasklist states switch

Introduce a helper for walking the list and sending signals.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 7fde5f06
......@@ -1166,6 +1166,31 @@ 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);
......@@ -1187,17 +1212,7 @@ int cr_dump_tasks(pid_t pid, struct cr_options *opts)
if (collect_sockets())
goto err;
/*
* 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, &pstree_list, list) {
stop_task(item->pid);
if (opts->leader_only)
break;
}
pstree_switch_state(&pstree_list, CR_TASK_STOP, opts->leader_only);
list_for_each_entry(item, &pstree_list, list) {
......@@ -1254,22 +1269,11 @@ int cr_dump_tasks(pid_t pid, struct cr_options *opts)
err:
switch (opts->final_state) {
case CR_TASK_LEAVE_RUNNING:
list_for_each_entry(item, &pstree_list, list) {
continue_task(item->pid);
if (opts->leader_only)
break;
}
break;
case CR_TASK_RUN:
case CR_TASK_KILL:
list_for_each_entry(item, &pstree_list, list) {
kill_task(item->pid);
if (opts->leader_only)
break;
}
break;
case CR_TASK_LEAVE_STOPPED:
default:
pstree_switch_state(&pstree_list,
opts->final_state, opts->leader_only);
case CR_TASK_STOP: /* they are already stopped */
break;
}
......
......@@ -296,7 +296,7 @@ int main(int argc, char *argv[])
break;
case 'c':
opts.show_pages_content = true;
opts.final_state = CR_TASK_LEAVE_RUNNING;
opts.final_state = CR_TASK_RUN;
break;
case 'f':
opts.show_dump_file = optarg;
......
......@@ -28,15 +28,15 @@ enum {
CR_FD_MAX
};
enum cr_task_final_state {
CR_TASK_LEAVE_STOPPED, /* leave tasks stopped after dump/restore */
CR_TASK_LEAVE_RUNNING, /* leave tasks running after dump/restore */
CR_TASK_KILL, /* kill tasks after dump */
enum cr_task_state {
CR_TASK_RUN,
CR_TASK_STOP,
CR_TASK_KILL,
};
struct cr_options {
bool leader_only;
enum cr_task_final_state final_state;
enum cr_task_state final_state;
bool show_pages_content;
char *show_dump_file;
};
......
......@@ -98,10 +98,6 @@ extern void printk(const char *format, ...);
#define BUG_ON(condition) BUG_ON_HANDLER((condition))
#define stop_task(pid) kill(pid, SIGSTOP)
#define kill_task(pid) kill(pid, SIGKILL)
#define continue_task(pid) kill(pid, SIGCONT)
#define write_ptr(fd, ptr) \
write(fd, (ptr), sizeof(*(ptr)))
......
......@@ -61,7 +61,7 @@ err:
return ret;
err_cont:
continue_task(pid);
kill(pid, SIGCONT);
goto err;
}
......
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