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