Commit 5aa22f13 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

dump: Print error codes if dumper failed in parasite section

Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
parent 84e57b2a
......@@ -42,6 +42,9 @@ typedef struct {
struct vma_entry vma_entry;
unsigned long nrpages_dumped; /* how many pages are dumped */
unsigned long fd;
long ret;
long sys_ret;
long line;
unsigned long open_mode;
unsigned long open_flags;
char open_path[64];
......
......@@ -378,6 +378,45 @@ retry_signal:
pr_err("Can't get statistics (pid: %d)\n", ctl->pid);
goto err_restore;
}
/*
* Check if error happened during dumping.
*/
if (ptrace_peek_area((long)ctl->pid,
(void *)&parasite_dumppages.ret,
(void *)(ctl->addr_args +
offsetof(parasite_args_cmd_dumppages_t, ret)),
sizeof(parasite_dumppages.ret))) {
pr_err("Can't get dumper ret code (pid: %d)\n", ctl->pid);
goto err_restore;
}
if (parasite_dumppages.ret) {
if (ptrace_peek_area((long)ctl->pid,
(void *)&parasite_dumppages.sys_ret,
(void *)(ctl->addr_args +
offsetof(parasite_args_cmd_dumppages_t, sys_ret)),
sizeof(parasite_dumppages.sys_ret))) {
pr_err("Can't get dumper sys_ret code (pid: %d)\n", ctl->pid);
goto err_restore;
}
if (ptrace_peek_area((long)ctl->pid,
(void *)&parasite_dumppages.line,
(void *)(ctl->addr_args +
offsetof(parasite_args_cmd_dumppages_t, line)),
sizeof(parasite_dumppages.line))) {
pr_err("Can't get dumper ret line (pid: %d)\n", ctl->pid);
goto err_restore;
}
pr_panic("Dumping pages failed with %li (%li) at %li\n",
parasite_dumppages.ret,
parasite_dumppages.sys_ret,
parasite_dumppages.line);
goto err_restore;
}
pr_info(" (dumped: %16li pages)\n", parasite_dumppages.nrpages_dumped);
nrpages_dumped += parasite_dumppages.nrpages_dumped;
}
......
......@@ -97,6 +97,8 @@ static int dump_pages(parasite_args_cmd_dumppages_t *args)
if ((long)args->fd < 0) {
sys_write_msg("sys_open failed\n");
ret = PARASITE_ERR_OPEN;
args->sys_ret = args->fd;
args->ret = ret, args->line = __LINE__;
goto err;
}
}
......@@ -122,6 +124,8 @@ static int dump_pages(parasite_args_cmd_dumppages_t *args)
if ((long)map < 0) {
sys_write_msg("sys_mmap failed\n");
ret = PARASITE_ERR_MMAP;
args->sys_ret = (long)map;
args->ret = ret, args->line = __LINE__;
goto err;
}
}
......@@ -135,11 +139,14 @@ static int dump_pages(parasite_args_cmd_dumppages_t *args)
if (!(args->vma_entry.prot & PROT_READ)) {
prot_old = (unsigned long)args->vma_entry.prot;
prot_new = prot_old | PROT_READ;
if (sys_mprotect((unsigned long)args->vma_entry.start,
(unsigned long)vma_entry_len(&args->vma_entry),
prot_new)) {
ret = sys_mprotect((unsigned long)args->vma_entry.start,
(unsigned long)vma_entry_len(&args->vma_entry),
prot_new);
if (ret) {
sys_write_msg("sys_mprotect failed\n");
ret = PARASITE_ERR_MPROTECT;
args->sys_ret = ret;
args->ret = ret, args->line = __LINE__;
goto err_free;
}
}
......@@ -149,9 +156,12 @@ static int dump_pages(parasite_args_cmd_dumppages_t *args)
* so stick for mincore as a basis.
*/
if (sys_mincore((unsigned long)args->vma_entry.start, length, map)) {
ret = sys_mincore((unsigned long)args->vma_entry.start, length, map);
if (ret) {
sys_write_msg("sys_mincore failed\n");
args->sys_ret = ret;
ret = PARASITE_ERR_MINCORE;
args->ret = ret, args->line = __LINE__;
goto err_free;
}
......@@ -170,8 +180,10 @@ static int dump_pages(parasite_args_cmd_dumppages_t *args)
written += sys_write(args->fd, &vaddr, sizeof(vaddr));
written += sys_write(args->fd, (void *)vaddr, PAGE_SIZE);
if (written != sizeof(vaddr) + PAGE_SIZE) {
args->sys_ret = written; /* The caller are to decode value */
ret = PARASITE_ERR_WRITE;
sys_write_msg("sys_write on page failed\n");
args->ret = ret, args->line = __LINE__;
goto err_free;
}
......@@ -183,15 +195,21 @@ static int dump_pages(parasite_args_cmd_dumppages_t *args)
* Don't left pages readable if they were not.
*/
if (prot_old != prot_new) {
if (sys_mprotect((unsigned long)args->vma_entry.start,
(unsigned long)vma_entry_len(&args->vma_entry),
prot_old)) {
ret = sys_mprotect((unsigned long)args->vma_entry.start,
(unsigned long)vma_entry_len(&args->vma_entry),
prot_old);
if (ret) {
sys_write_msg("PANIC: Ouch! sys_mprotect failed on resore\n");
args->sys_ret = ret;
ret = PARASITE_ERR_MPROTECT;
args->ret = ret, args->line = __LINE__;
goto err_free;
}
}
/* on success ret = 0 */
args->ret = ret, args->line = __LINE__;
err_free:
if (map_brk)
brk_free(nrpages);
......
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