Commit 609e4313 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

Add cr_options structure

We will need more options since the
tool should support both cgroups freezer
and a regular task stop/dump/restore/continue
transition.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
parent 374ec760
...@@ -948,13 +948,13 @@ err: ...@@ -948,13 +948,13 @@ err:
return ret; return ret;
} }
int cr_dump_tasks(pid_t pid, bool leader_only, int leave_stopped) int cr_dump_tasks(pid_t pid, struct cr_options *opts)
{ {
struct cr_fdset *cr_fdset = NULL; struct cr_fdset *cr_fdset = NULL;
struct pstree_item *item; struct pstree_item *item;
int ret = -1; int ret = -1;
if (!leader_only) { if (!opts->leader_only) {
pr_info("========================================\n"); pr_info("========================================\n");
pr_info("Dumping process group (pid: %d)\n", pid); pr_info("Dumping process group (pid: %d)\n", pid);
pr_info("========================================\n"); pr_info("========================================\n");
...@@ -965,7 +965,7 @@ int cr_dump_tasks(pid_t pid, bool leader_only, int leave_stopped) ...@@ -965,7 +965,7 @@ int cr_dump_tasks(pid_t pid, bool leader_only, int leave_stopped)
list_for_each_entry(item, &pstree_list, list) { list_for_each_entry(item, &pstree_list, list) {
stop_task(item->pid); stop_task(item->pid);
if (leader_only) if (opts->leader_only)
break; break;
} }
...@@ -997,16 +997,16 @@ int cr_dump_tasks(pid_t pid, bool leader_only, int leave_stopped) ...@@ -997,16 +997,16 @@ int cr_dump_tasks(pid_t pid, bool leader_only, int leave_stopped)
close_cr_fdset(cr_fdset); close_cr_fdset(cr_fdset);
free_cr_fdset(&cr_fdset); free_cr_fdset(&cr_fdset);
if (leader_only) if (opts->leader_only)
break; break;
} }
ret = 0; ret = 0;
err: err:
if (!leave_stopped) { if (!opts->final_state != CR_TASK_LEAVE_STOPPED) {
list_for_each_entry(item, &pstree_list, list) { list_for_each_entry(item, &pstree_list, list) {
continue_task(item->pid); continue_task(item->pid);
if (leader_only) if (opts->leader_only)
break; break;
} }
} }
......
...@@ -1219,9 +1219,9 @@ static int restore_all_tasks(pid_t pid) ...@@ -1219,9 +1219,9 @@ static int restore_all_tasks(pid_t pid)
return restore_root_task(path, pstree_fd); return restore_root_task(path, pstree_fd);
} }
int cr_restore_tasks(pid_t pid, bool leader_only, int leave_stopped) int cr_restore_tasks(pid_t pid, struct cr_options *opts)
{ {
if (leader_only) if (opts->leader_only)
return restore_one_task(pid); return restore_one_task(pid);
return restore_all_tasks(pid); return restore_all_tasks(pid);
} }
...@@ -363,7 +363,7 @@ err: ...@@ -363,7 +363,7 @@ err:
return ret; return ret;
} }
int cr_show(unsigned long pid, bool leader_only) int cr_show(unsigned long pid, struct cr_options *opts)
{ {
struct cr_fdset *cr_fdset; struct cr_fdset *cr_fdset;
struct pstree_item *item; struct pstree_item *item;
...@@ -400,7 +400,7 @@ int cr_show(unsigned long pid, bool leader_only) ...@@ -400,7 +400,7 @@ int cr_show(unsigned long pid, bool leader_only)
show_pipes(cr_fdset); show_pipes(cr_fdset);
show_files(cr_fdset); show_files(cr_fdset);
if (leader_only) if (opts->leader_only)
break; break;
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "crtools.h" #include "crtools.h"
#include "util.h" #include "util.h"
static struct cr_options opts;
struct page_entry zero_page_entry; struct page_entry zero_page_entry;
static struct cr_fd_desc_tmpl template[CR_FD_MAX] = { static struct cr_fd_desc_tmpl template[CR_FD_MAX] = {
...@@ -214,60 +215,25 @@ int main(int argc, char *argv[]) ...@@ -214,60 +215,25 @@ int main(int argc, char *argv[])
memset(&zero_page_entry, 0, sizeof(zero_page_entry)); memset(&zero_page_entry, 0, sizeof(zero_page_entry));
if (!strcmp(argv[1], "dump")) { switch (argv[2][1]) {
bool leader_only; case 'p':
pid = atol(argv[3]);
switch (argv[2][1]) { opts.leader_only = true;
case 'p': break;
pid = atol(argv[3]); case 't':
leader_only = true; pid = atol(argv[3]);
break; opts.leader_only = false;
case 't': break;
pid = atol(argv[3]); default:
leader_only = false; goto usage;
break; }
default:
goto usage;
}
ret = cr_dump_tasks(pid, leader_only, 1);
if (!strcmp(argv[1], "dump")) {
ret = cr_dump_tasks(pid, &opts);
} else if (!strcmp(argv[1], "restore")) { } else if (!strcmp(argv[1], "restore")) {
bool leader_only; ret = cr_restore_tasks(pid, &opts);
switch (argv[2][1]) {
case 'p':
pid = atol(argv[3]);
leader_only = true;
break;
case 't':
pid = atol(argv[3]);
leader_only = false;
break;
default:
goto usage;
}
ret = cr_restore_tasks(pid, leader_only, 1);
} else if (!strcmp(argv[1], "show")) { } else if (!strcmp(argv[1], "show")) {
bool leader_only = true; ret = cr_show(pid, &opts);
switch (argv[2][1]) {
case 'p':
leader_only = true;
pid = atol(argv[3]);
break;
case 't':
leader_only = false;
pid = atol(argv[3]);
break;
default:
goto usage;
}
ret = cr_show(pid, leader_only);
} else } else
goto usage; goto usage;
......
...@@ -10,11 +10,6 @@ ...@@ -10,11 +10,6 @@
extern struct page_entry zero_page_entry; extern struct page_entry zero_page_entry;
int cr_dump_tasks(pid_t pid, bool leader_only, int leave_stopped);
int cr_restore_tasks(pid_t pid, bool leader_only, int leave_stopped);
int cr_show(unsigned long pid, bool leader_only);
int convert_to_elf(char *elf_path, int fd_core);
#define CR_FD_PERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) #define CR_FD_PERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)
#define CR_FD_PERM_DUMP (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) #define CR_FD_PERM_DUMP (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
...@@ -30,6 +25,17 @@ enum { ...@@ -30,6 +25,17 @@ enum {
CR_FD_MAX 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 */
};
struct cr_options {
bool leader_only;
enum cr_task_final_state final_state;
};
/* file descriptors template */ /* file descriptors template */
struct cr_fd_desc_tmpl { struct cr_fd_desc_tmpl {
const char *fmt; /* format for the name */ const char *fmt; /* format for the name */
...@@ -56,6 +62,10 @@ struct cr_fdset { ...@@ -56,6 +62,10 @@ struct cr_fdset {
#define CR_FD_DESC_NOPSTREE (CR_FD_DESC_ALL & ~(CR_FD_DESC_USE(CR_FD_PSTREE))) #define CR_FD_DESC_NOPSTREE (CR_FD_DESC_ALL & ~(CR_FD_DESC_USE(CR_FD_PSTREE)))
#define CR_FD_DESC_NONE (0) #define CR_FD_DESC_NONE (0)
int cr_dump_tasks(pid_t pid, struct cr_options *opts);
int cr_restore_tasks(pid_t pid, struct cr_options *opts);
int cr_show(unsigned long pid, struct cr_options *opts);
int convert_to_elf(char *elf_path, int fd_core);
struct cr_fdset *alloc_cr_fdset(pid_t pid); struct cr_fdset *alloc_cr_fdset(pid_t pid);
int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset, int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset,
......
...@@ -239,10 +239,13 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a ...@@ -239,10 +239,13 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
if (path_len > sizeof(parasite_dumppages.open_path)) { if (path_len > sizeof(parasite_dumppages.open_path)) {
pr_panic("Dumping pages path is too long (%d while %d allowed)\n", pr_panic("Dumping pages path is too long (%d while %d allowed)\n",
path_len, sizeof(parasite_dumppages.open_path)); path_len, sizeof(parasite_dumppages.open_path));
goto err; goto chmod_err;
} }
jerr(fchmod(cr_fdset->desc[fd_type].fd, CR_FD_PERM_DUMP), chmod_err); if (fchmod(cr_fdset->desc[fd_type].fd, CR_FD_PERM_DUMP)) {
pr_perror("Can't change permissions on pages file\n");
goto chmod_err;
}
jerr(ptrace(PTRACE_GETREGS, ctl->pid, NULL, &regs_orig), err); jerr(ptrace(PTRACE_GETREGS, ctl->pid, NULL, &regs_orig), 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