Commit 73d7e283 authored by Pavel Emelyanov's avatar Pavel Emelyanov

show: Filter -D output with --pid option

Show only image info relevant to given pid. Also reuse
the introduced --pid argument for exec action.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 6241a057
...@@ -261,11 +261,28 @@ void show_creds(int fd, struct cr_options *o) ...@@ -261,11 +261,28 @@ void show_creds(int fd, struct cr_options *o)
pb_show_vertical(fd, PB_CREDS); pb_show_vertical(fd, PB_CREDS);
} }
static int pstree_item_from_pb(PstreeEntry *e, struct pstree_item *item)
{
int i;
item->pid.virt = e->pid;
item->nr_threads = e->n_threads;
item->threads = xzalloc(sizeof(struct pid) * e->n_threads);
if (!item->threads) {
xfree(item);
return -1;
}
for (i = 0; i < item->nr_threads; i++)
item->threads[i].virt = e->threads[i];
return 0;
}
static void pstree_handler(int fd, void *obj, int collect) static void pstree_handler(int fd, void *obj, int collect)
{ {
PstreeEntry *e = obj; PstreeEntry *e = obj;
struct pstree_item *item = NULL; struct pstree_item *item = NULL;
int i;
if (!collect) if (!collect)
return; return;
...@@ -274,17 +291,11 @@ static void pstree_handler(int fd, void *obj, int collect) ...@@ -274,17 +291,11 @@ static void pstree_handler(int fd, void *obj, int collect)
if (!item) if (!item)
return; return;
item->pid.virt = e->pid; if (pstree_item_from_pb(e, item)) {
item->nr_threads = e->n_threads;
item->threads = xzalloc(sizeof(struct pid) * e->n_threads);
if (!item->threads) {
xfree(item); xfree(item);
return; return;
} }
for (i = 0; i < item->nr_threads; i++)
item->threads[i].virt = e->threads[i];
list_add_tail(&item->sibling, &pstree_list); list_add_tail(&item->sibling, &pstree_list);
} }
...@@ -428,30 +439,9 @@ err: ...@@ -428,30 +439,9 @@ err:
return ret; return ret;
} }
static int cr_show_all(struct cr_options *opts) static int cr_show_pstree_item(struct cr_options *opts, struct pstree_item *item)
{ {
struct pstree_item *item = NULL, *tmp; int ret = -1, i;
int i, ret = -1, fd, pid;
fd = open_image_ro(CR_FD_PSTREE);
if (fd < 0)
goto out;
show_collect_pstree(fd, 1);
close(fd);
fd = open_image_ro(CR_FD_SK_QUEUES);
if (fd < 0)
goto out;
show_sk_queues(fd, opts);
close(fd);
pid = list_first_entry(&pstree_list, struct pstree_item, sibling)->pid.virt;
ret = try_show_namespaces(pid, opts);
if (ret)
goto out;
list_for_each_entry(item, &pstree_list, sibling) {
struct cr_fdset *cr_fdset = NULL; struct cr_fdset *cr_fdset = NULL;
cr_fdset = cr_task_fdset_open(item->pid.virt, O_SHOW); cr_fdset = cr_task_fdset_open(item->pid.virt, O_SHOW);
...@@ -473,7 +463,7 @@ static int cr_show_all(struct cr_options *opts) ...@@ -473,7 +463,7 @@ static int cr_show_all(struct cr_options *opts)
fd_th = open_image_ro(CR_FD_CORE, item->threads[i].virt); fd_th = open_image_ro(CR_FD_CORE, item->threads[i].virt);
if (fd_th < 0) if (fd_th < 0)
goto out; goto outc;
pr_msg("Thread %d.%d:\n", item->pid.virt, item->threads[i].virt); pr_msg("Thread %d.%d:\n", item->pid.virt, item->threads[i].virt);
pr_msg("----------------------------------------\n"); pr_msg("----------------------------------------\n");
...@@ -494,9 +484,70 @@ static int cr_show_all(struct cr_options *opts) ...@@ -494,9 +484,70 @@ static int cr_show_all(struct cr_options *opts)
} }
pr_msg("---[ end of task %d ]---\n", item->pid.virt); pr_msg("---[ end of task %d ]---\n", item->pid.virt);
ret = 0;
outc:
close_cr_fdset(&cr_fdset); close_cr_fdset(&cr_fdset);
out:
return ret;
}
static int cr_show_pid(struct cr_options *opts, int pid)
{
int fd, ret;
struct pstree_item item;
fd = open_image_ro(CR_FD_PSTREE);
if (fd < 0)
return -1;
while (1) {
PstreeEntry *pe;
ret = pb_read_one_eof(fd, &pe, PB_PSTREE);
if (ret <= 0)
return ret;
if (pe->pid == pid) {
pstree_item_from_pb(pe, &item);
pstree_entry__free_unpacked(pe, NULL);
break;
} }
pstree_entry__free_unpacked(pe, NULL);
}
close(fd);
return cr_show_pstree_item(opts, &item);
}
static int cr_show_all(struct cr_options *opts)
{
struct pstree_item *item = NULL, *tmp;
int ret = -1, fd, pid;
fd = open_image_ro(CR_FD_PSTREE);
if (fd < 0)
goto out;
show_collect_pstree(fd, 1);
close(fd);
fd = open_image_ro(CR_FD_SK_QUEUES);
if (fd < 0)
goto out;
show_sk_queues(fd, opts);
close(fd);
pid = list_first_entry(&pstree_list, struct pstree_item, sibling)->pid.virt;
ret = try_show_namespaces(pid, opts);
if (ret)
goto out;
list_for_each_entry(item, &pstree_list, sibling)
if (cr_show_pstree_item(opts, item))
break;
out: out:
list_for_each_entry_safe(item, tmp, &pstree_list, sibling) { list_for_each_entry_safe(item, tmp, &pstree_list, sibling) {
list_del(&item->sibling); list_del(&item->sibling);
...@@ -506,10 +557,13 @@ out: ...@@ -506,10 +557,13 @@ out:
return ret; return ret;
} }
int cr_show(struct cr_options *opts) int cr_show(struct cr_options *opts, int pid)
{ {
if (opts->show_dump_file) if (opts->show_dump_file)
return cr_parse_file(opts); return cr_parse_file(opts);
if (pid)
return cr_show_pid(opts, pid);
return cr_show_all(opts); return cr_show_all(opts);
} }
...@@ -62,13 +62,13 @@ bad_ns: ...@@ -62,13 +62,13 @@ bad_ns:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
pid_t pid = 0; pid_t pid = 0, tree_id = 0;
int ret = -1; int ret = -1;
int opt, idx; int opt, idx;
int log_inited = 0; int log_inited = 0;
int log_level = 0; int log_level = 0;
static const char short_opts[] = "dsf:t:hcD:o:n:vxVr:jl"; static const char short_opts[] = "dsf:t:p:hcD:o:n:vxVr:jl";
BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE); BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE);
...@@ -88,6 +88,7 @@ int main(int argc, char *argv[]) ...@@ -88,6 +88,7 @@ int main(int argc, char *argv[])
while (1) { while (1) {
static struct option long_opts[] = { static struct option long_opts[] = {
{ "tree", required_argument, 0, 't' }, { "tree", required_argument, 0, 't' },
{ "pid", required_argument, 0, 'p' },
{ "leave-stopped", no_argument, 0, 's' }, { "leave-stopped", no_argument, 0, 's' },
{ "restore-detached", no_argument, 0, 'd' }, { "restore-detached", no_argument, 0, 'd' },
{ "contents", no_argument, 0, 'c' }, { "contents", no_argument, 0, 'c' },
...@@ -126,9 +127,12 @@ int main(int argc, char *argv[]) ...@@ -126,9 +127,12 @@ int main(int argc, char *argv[])
case 'x': case 'x':
opts.ext_unix_sk = true; opts.ext_unix_sk = true;
break; break;
case 't': case 'p':
pid = atoi(optarg); pid = atoi(optarg);
break; break;
case 't':
tree_id = atoi(optarg);
break;
case 'c': case 'c':
opts.show_pages_content = true; opts.show_pages_content = true;
break; break;
...@@ -292,22 +296,24 @@ int main(int argc, char *argv[]) ...@@ -292,22 +296,24 @@ int main(int argc, char *argv[])
switch (argv[optind][0]) { switch (argv[optind][0]) {
case 'd': case 'd':
if (!pid) if (!tree_id)
goto opt_pid_missing; goto opt_pid_missing;
ret = cr_dump_tasks(pid, &opts); ret = cr_dump_tasks(tree_id, &opts);
break; break;
case 'r': case 'r':
if (!pid) if (!tree_id)
goto opt_pid_missing; goto opt_pid_missing;
ret = cr_restore_tasks(pid, &opts); ret = cr_restore_tasks(tree_id, &opts);
break; break;
case 's': case 's':
ret = cr_show(&opts); ret = cr_show(&opts, pid);
break; break;
case 'c': case 'c':
ret = cr_check(); ret = cr_check();
break; break;
case 'e': case 'e':
if (!pid)
pid = tree_id; /* old usage */
if (!pid) if (!pid)
goto opt_pid_missing; goto opt_pid_missing;
ret = cr_exec(pid, argv + optind + 1); ret = cr_exec(pid, argv + optind + 1);
...@@ -328,7 +334,7 @@ usage: ...@@ -328,7 +334,7 @@ usage:
pr_msg(" %s restore -t pid [<options>]\n", argv[0]); pr_msg(" %s restore -t pid [<options>]\n", argv[0]);
pr_msg(" %s show (-D dir)|(-f file) [<options>]\n", argv[0]); pr_msg(" %s show (-D dir)|(-f file) [<options>]\n", argv[0]);
pr_msg(" %s check\n", argv[0]); pr_msg(" %s check\n", argv[0]);
pr_msg(" %s exec -t pid <syscall-string>\n", argv[0]); pr_msg(" %s exec -p pid <syscall-string>\n", argv[0]);
pr_msg("\nCommands:\n"); pr_msg("\nCommands:\n");
pr_msg(" dump checkpoint a process/tree identified by pid\n"); pr_msg(" dump checkpoint a process/tree identified by pid\n");
...@@ -390,6 +396,7 @@ usage: ...@@ -390,6 +396,7 @@ usage:
pr_msg(" -f|--file show contents of a checkpoint file\n"); pr_msg(" -f|--file show contents of a checkpoint file\n");
pr_msg(" -D|--images-dir directory where to get images from\n"); pr_msg(" -D|--images-dir directory where to get images from\n");
pr_msg(" -c|--contents show contents of pages dumped in hexdump format\n"); pr_msg(" -c|--contents show contents of pages dumped in hexdump format\n");
pr_msg(" -p|--pid <pid> show files relevant to pid (filter -D flood)\n");
pr_msg("\nOther options:\n"); pr_msg("\nOther options:\n");
pr_msg(" -h|--help show this text\n"); pr_msg(" -h|--help show this text\n");
......
...@@ -217,7 +217,7 @@ extern struct cr_options opts; ...@@ -217,7 +217,7 @@ extern struct cr_options opts;
int cr_dump_tasks(pid_t pid, const struct cr_options *opts); int cr_dump_tasks(pid_t pid, const struct cr_options *opts);
int cr_restore_tasks(pid_t pid, struct cr_options *opts); int cr_restore_tasks(pid_t pid, struct cr_options *opts);
int cr_show(struct cr_options *opts); int cr_show(struct cr_options *opts, int pid);
int convert_to_elf(char *elf_path, int fd_core); int convert_to_elf(char *elf_path, int fd_core);
int cr_check(void); int cr_check(void);
int cr_exec(int pid, char **opts); int cr_exec(int pid, char **opts);
......
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