2
0
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:
Pavel Emelyanov
2012-01-11 13:29:35 +04:00
committed by Cyrill Gorcunov
parent 7fde5f061b
commit 0ca9ccc3e4
5 changed files with 37 additions and 37 deletions

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
};

View 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)))

View File

@@ -61,7 +61,7 @@ err:
return ret;
err_cont:
continue_task(pid);
kill(pid, SIGCONT);
goto err;
}