mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 14:25:49 +00:00
crtools: Sanitize the tasklist states switch
Introduce a helper for walking the list and sending signals. Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
This commit is contained in:
committed by
Cyrill Gorcunov
parent
7fde5f061b
commit
0ca9ccc3e4
56
cr-dump.c
56
cr-dump.c
@@ -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)))
|
||||
|
||||
|
Reference in New Issue
Block a user