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