From c58abfd03d8e5110d75841a241524c2e38cea8fd Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 27 Mar 2012 12:01:14 +0400 Subject: [PATCH] show: Introduce ->show callback for fdset Each fdset item now has the callback which will show a contents of a magic-described image file. Per-task and global show code is reworked to walk the respective fdsets and calling ->show on each file. Signed-off-by: Pavel Emelyanov --- cr-show.c | 136 +++++++++++++------------------------------ crtools.c | 21 +++++++ include/crtools.h | 12 ++++ include/ipc_ns.h | 9 +-- include/namespaces.h | 3 +- include/sockets.h | 7 ++- include/uts_ns.h | 3 +- ipc_ns.c | 8 +-- namespaces.c | 23 ++++---- sockets.c | 9 ++- uts_ns.c | 2 +- 11 files changed, 107 insertions(+), 126 deletions(-) diff --git a/cr-show.c b/cr-show.c index e9eb19461..84d965934 100644 --- a/cr-show.c +++ b/cr-show.c @@ -70,7 +70,7 @@ static char *fdtype2s(u8 type) return und; } -static void show_files(int fd_files) +void show_files(int fd_files, struct cr_options *o) { struct fdinfo_entry e; @@ -93,7 +93,7 @@ out: pr_img_tail(CR_FD_FDINFO); } -static void show_reg_files(int fd_reg_files) +void show_reg_files(int fd_reg_files, struct cr_options *o) { struct reg_file_entry rfe; @@ -125,7 +125,7 @@ out: pr_img_tail(CR_FD_REG_FILES); } -static void show_pipes(int fd_pipes) +void show_pipes(int fd_pipes, struct cr_options *o) { struct pipe_entry e; int ret; @@ -148,7 +148,7 @@ out: pr_img_tail(CR_FD_PIPES); } -static void show_vmas(int fd_vma) +void show_vmas(int fd_vma, struct cr_options *o) { struct vma_area vma_area = {}; struct vma_entry ve; @@ -193,11 +193,11 @@ void print_data(unsigned long addr, unsigned char *data, size_t size) } } -static void show_pages(int fd_pages, bool show_content) +void show_pages(int fd_pages, struct cr_options *o) { pr_img_head(CR_FD_PAGES); - if (show_content) { + if (o->show_pages_content) { while (1) { struct page_entry e; @@ -232,7 +232,7 @@ out: pr_img_tail(CR_FD_PAGES); } -static void show_sigacts(int fd_sigacts) +void show_sigacts(int fd_sigacts, struct cr_options *o) { struct sa_entry e; @@ -263,7 +263,7 @@ static void show_itimer(char *n, struct itimer_entry *ie) (unsigned long)ie->vsec, (unsigned long)ie->vusec); } -static void show_itimers(int fd) +void show_itimers(int fd, struct cr_options *o) { struct itimer_entry ie[3]; @@ -288,7 +288,7 @@ static void show_cap(char *name, u32 *v) pr_msg("\n"); } -static void show_creds(int fd) +void show_creds(int fd, struct cr_options *o) { struct creds_entry ce; @@ -311,7 +311,7 @@ out: pr_img_tail(CR_FD_CREDS); } -static int show_pstree(int fd_pstree, struct list_head *collect) +static int show_collect_pstree(int fd_pstree, struct list_head *collect) { struct pstree_entry e; @@ -377,6 +377,11 @@ out: return 0; } +void show_pstree(int fd_pstree, struct cr_options *o) +{ + show_collect_pstree(fd_pstree, NULL); +} + static void show_core_regs(int fd_core) { struct user_regs_entry regs; @@ -452,7 +457,7 @@ err: return; } -static void show_core(int fd_core, bool show_content) +void show_core(int fd_core, struct cr_options *o) { struct stat stat; bool is_thread; @@ -478,8 +483,7 @@ out: static int cr_parse_file(struct cr_options *opts) { u32 magic; - int fd = -1; - int ret = -1; + int fd = -1, ret = -1, i; fd = open(opts->show_dump_file, O_RDONLY); if (fd < 0) { @@ -490,67 +494,24 @@ static int cr_parse_file(struct cr_options *opts) if (read_img(fd, &magic) < 0) goto err; - switch (magic) { - case FDINFO_MAGIC: - show_files(fd); - break; - case PAGES_MAGIC: - show_pages(fd, opts->show_pages_content); - break; - case CORE_MAGIC: - show_core(fd, opts->show_pages_content); - break; - case VMAS_MAGIC: - show_vmas(fd); - break; - case PSTREE_MAGIC: - show_pstree(fd, NULL); - break; - case PIPES_MAGIC: - show_pipes(fd); - break; - case SIGACT_MAGIC: - show_sigacts(fd); - break; - case UNIXSK_MAGIC: - show_unixsk(fd); - break; - case INETSK_MAGIC: - show_inetsk(fd); - break; - case SK_QUEUES_MAGIC: - show_sk_queues(fd); - break; - case ITIMERS_MAGIC: - show_itimers(fd); - break; - case UTSNS_MAGIC: - show_utsns(fd); - break; - case CREDS_MAGIC: - show_creds(fd); - break; - case IPCNS_VAR_MAGIC: - show_ipc_var(fd); - break; - case IPCNS_SHM_MAGIC: - show_ipc_shm(fd); - break; - case IPCNS_MSG_MAGIC: - show_ipc_msg(fd); - break; - case IPCNS_SEM_MAGIC: - show_ipc_sem(fd); - break; - case REG_FILES_MAGIC: - show_reg_files(fd); - break; - default: - pr_err("Unknown magic %x on %s\n", magic, opts->show_dump_file); + for (i = 0; i < CR_FD_MAX; i++) + if (fdset_template[i].magic == magic) + break; + + if (i == CR_FD_MAX) { + pr_err("Unknown magic %x in %s\n", + magic, opts->show_dump_file); goto err; } - ret = 0; + if (!fdset_template[i].show) { + pr_err("No handler for %x/%s\n", + magic, opts->show_dump_file); + goto err; + } + + fdset_template[i].show(fd, opts); + ret = 0; err: close_safe(&fd); return ret; @@ -566,7 +527,7 @@ static int cr_show_all(struct cr_options *opts) if (fd < 0) goto out; - ret = show_pstree(fd, &pstree_list); + ret = show_collect_pstree(fd, &pstree_list); if (ret) goto out; @@ -576,14 +537,11 @@ static int cr_show_all(struct cr_options *opts) if (fd < 0) goto out; - ret = show_sk_queues(fd); - if (ret) - goto out; - + show_sk_queues(fd, opts); close(fd); pid = list_first_entry(&pstree_list, struct pstree_item, list)->pid; - ret = try_show_namespaces(pid); + ret = try_show_namespaces(pid, opts); if (ret) goto out; @@ -594,10 +552,10 @@ static int cr_show_all(struct cr_options *opts) if (!cr_fdset) goto out; - show_core(fdset_fd(cr_fdset, CR_FD_CORE), opts->show_pages_content); + show_core(fdset_fd(cr_fdset, CR_FD_CORE), opts); if (item->nr_threads > 1) { - int i, fd_th; + int fd_th; for (i = 0; i < item->nr_threads; i++) { @@ -612,28 +570,16 @@ static int cr_show_all(struct cr_options *opts) pr_msg("Thread: %d\n", item->threads[i]); pr_msg("----------------------------------------\n"); - show_core(fd_th, opts->show_pages_content); + show_core(fd_th, opts); pr_msg("----------------------------------------\n"); } } - show_vmas(fdset_fd(cr_fdset, CR_FD_VMAS)); - - show_pipes(fdset_fd(cr_fdset, CR_FD_PIPES)); - - show_files(fdset_fd(cr_fdset, CR_FD_FDINFO)); - - show_sigacts(fdset_fd(cr_fdset, CR_FD_SIGACT)); - - show_unixsk(fdset_fd(cr_fdset, CR_FD_UNIXSK)); - - show_inetsk(fdset_fd(cr_fdset, CR_FD_INETSK)); - - show_itimers(fdset_fd(cr_fdset, CR_FD_ITIMERS)); - - show_creds(fdset_fd(cr_fdset, CR_FD_CREDS)); + for (i = _CR_FD_TASK_FROM + 1; i < _CR_FD_TASK_TO; i++) + if (i != CR_FD_CORE && fdset_template[i].show) + fdset_template[i].show(fdset_fd(cr_fdset, i), opts); close_cr_fdset(&cr_fdset); diff --git a/crtools.c b/crtools.c index f3540b0a4..e3c27f627 100644 --- a/crtools.c +++ b/crtools.c @@ -20,6 +20,8 @@ #include "log.h" #include "sockets.h" #include "syscall.h" +#include "uts_ns.h" +#include "ipc_ns.h" static struct cr_options opts; struct page_entry zero_page_entry = {.va = ~0LL}; @@ -37,111 +39,130 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = { [CR_FD_FDINFO] = { .fmt = FMT_FNAME_FDINFO, .magic = FDINFO_MAGIC, + .show = show_files, }, /* private memory pages data */ [CR_FD_PAGES] = { .fmt = FMT_FNAME_PAGES, .magic = PAGES_MAGIC, + .show = show_pages, }, /* shared memory pages data */ [CR_FD_SHMEM_PAGES] = { .fmt = FMT_FNAME_SHMEM_PAGES, .magic = PAGES_MAGIC, + .show = show_pages, }, [CR_FD_REG_FILES] = { .fmt = FMT_FNAME_REG_FILES, .magic = REG_FILES_MAGIC, + .show = show_reg_files, }, /* core data, such as regs and vmas and such */ [CR_FD_CORE] = { .fmt = FMT_FNAME_CORE, .magic = CORE_MAGIC, + .show = show_core, }, [CR_FD_VMAS] = { .fmt = FMT_FNAME_VMAS, .magic = VMAS_MAGIC, + .show = show_vmas, }, /* info about pipes - fds, pipe id and pipe data */ [CR_FD_PIPES] = { .fmt = FMT_FNAME_PIPES, .magic = PIPES_MAGIC, + .show = show_pipes, }, /* info about process linkage */ [CR_FD_PSTREE] = { .fmt = FMT_FNAME_PSTREE, .magic = PSTREE_MAGIC, + .show = show_pstree, }, /* info about signal handlers */ [CR_FD_SIGACT] = { .fmt = FMT_FNAME_SIGACTS, .magic = SIGACT_MAGIC, + .show = show_sigacts, }, /* info about unix sockets */ [CR_FD_UNIXSK] = { .fmt = FMT_FNAME_UNIXSK, .magic = UNIXSK_MAGIC, + .show = show_unixsk, }, /* info about inet sockets */ [CR_FD_INETSK] = { .fmt = FMT_FNAME_INETSK, .magic = INETSK_MAGIC, + .show = show_inetsk, }, [CR_FD_SK_QUEUES] = { .fmt = FMT_FNAME_SK_QUEUES, .magic = SK_QUEUES_MAGIC, + .show = show_sk_queues, }, /* interval timers (itimers) */ [CR_FD_ITIMERS] = { .fmt = FMT_FNAME_ITIMERS, .magic = ITIMERS_MAGIC, + .show = show_itimers, }, /* creds */ [CR_FD_CREDS] = { .fmt = FMT_FNAME_CREDS, .magic = CREDS_MAGIC, + .show = show_creds, }, /* UTS namespace */ [CR_FD_UTSNS] = { .fmt = FMT_FNAME_UTSNS, .magic = UTSNS_MAGIC, + .show = show_utsns, }, /* IPC namespace variables */ [CR_FD_IPCNS_VAR] = { .fmt = FMT_FNAME_IPCNS_VAR, .magic = IPCNS_VAR_MAGIC, + .show = show_ipc_var, }, /* IPC namespace shared memory */ [CR_FD_IPCNS_SHM] = { .fmt = FMT_FNAME_IPCNS_SHM, .magic = IPCNS_SHM_MAGIC, + .show = show_ipc_shm, }, /* IPC namespace message queues */ [CR_FD_IPCNS_MSG] = { .fmt = FMT_FNAME_IPCNS_MSG, .magic = IPCNS_MSG_MAGIC, + .show = show_ipc_msg, }, /* IPC namespace semaphores sets */ [CR_FD_IPCNS_SEM] = { .fmt = FMT_FNAME_IPCNS_SEM, .magic = IPCNS_SEM_MAGIC, + .show = show_ipc_sem, }, }; diff --git a/include/crtools.h b/include/crtools.h index 92644fad1..6cc21462d 100644 --- a/include/crtools.h +++ b/include/crtools.h @@ -76,8 +76,20 @@ int get_service_fd(int type); struct cr_fd_desc_tmpl { const char *fmt; /* format for the name */ u32 magic; /* magic in the header */ + void (*show)(int fd, struct cr_options *o); }; +void show_files(int fd_files, struct cr_options *o); +void show_pages(int fd_pages, struct cr_options *o); +void show_reg_files(int fd_reg_files, struct cr_options *o); +void show_core(int fd_core, struct cr_options *o); +void show_vmas(int fd_vma, struct cr_options *o); +void show_pipes(int fd_pipes, struct cr_options *o); +void show_pstree(int fd_pstree, struct cr_options *o); +void show_sigacts(int fd_sigacts, struct cr_options *o); +void show_itimers(int fd, struct cr_options *o); +void show_creds(int fd, struct cr_options *o); + extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX]; #define FMT_FNAME_FDINFO "fdinfo-%d.img" diff --git a/include/ipc_ns.h b/include/ipc_ns.h index 41a7d9a39..e26d1753e 100644 --- a/include/ipc_ns.h +++ b/include/ipc_ns.h @@ -3,10 +3,11 @@ #include "crtools.h" -extern void show_ipc_var(int fd); -extern void show_ipc_shm(int fd); -extern void show_ipc_msg(int fd); -extern void show_ipc_sem(int fd); +struct cr_options; +extern void show_ipc_var(int fd, struct cr_options *); +extern void show_ipc_shm(int fd, struct cr_options *); +extern void show_ipc_msg(int fd, struct cr_options *); +extern void show_ipc_sem(int fd, struct cr_options *); extern int dump_ipc_ns(int ns_pid, struct cr_fdset *fdset); extern int prepare_ipc_ns(int pid); diff --git a/include/namespaces.h b/include/namespaces.h index 9e0c04f06..80c67af25 100644 --- a/include/namespaces.h +++ b/include/namespaces.h @@ -2,6 +2,7 @@ #define __CR_NS_H__ int dump_namespaces(int pid, unsigned int ns_flags); int prepare_namespace(int pid, unsigned long clone_flags); -int try_show_namespaces(int pid); +struct cr_options; +int try_show_namespaces(int pid, struct cr_options *); int switch_ns(int pid, int type, char *ns); #endif diff --git a/include/sockets.h b/include/sockets.h index 960b91840..204dbcb20 100644 --- a/include/sockets.h +++ b/include/sockets.h @@ -27,8 +27,9 @@ extern int try_dump_socket(pid_t pid, int fd, const struct cr_fdset *cr_fdset, extern int collect_sockets(void); extern int prepare_sockets(int pid); -extern void show_unixsk(int fd); -extern void show_inetsk(int fd); -extern int show_sk_queues(int fd); +struct cr_options; +extern void show_unixsk(int fd, struct cr_options *); +extern void show_inetsk(int fd, struct cr_options *); +extern void show_sk_queues(int fd, struct cr_options *); #endif /* CR_SOCKETS_H__ */ diff --git a/include/uts_ns.h b/include/uts_ns.h index 2e51ae1a1..6c47ffb04 100644 --- a/include/uts_ns.h +++ b/include/uts_ns.h @@ -4,7 +4,8 @@ #include "crtools.h" int dump_uts_ns(int ns_pid, struct cr_fdset *fdset); -void show_utsns(int fd); +struct cr_options; +void show_utsns(int fd, struct cr_options *); int prepare_utsns(int pid); #endif /* CR_UTS_NS_H_ */ diff --git a/ipc_ns.c b/ipc_ns.c index 704dd9c33..bdc3c3485 100644 --- a/ipc_ns.c +++ b/ipc_ns.c @@ -480,7 +480,7 @@ static void show_ipc_sem_entries(int fd) } } -void show_ipc_sem(int fd) +void show_ipc_sem(int fd, struct cr_options *o) { pr_img_head(CR_FD_IPCNS); show_ipc_sem_entries(fd); @@ -518,7 +518,7 @@ static void show_ipc_msg_entries(int fd) } } -void show_ipc_msg(int fd) +void show_ipc_msg(int fd, struct cr_options *o) { pr_img_head(CR_FD_IPCNS); show_ipc_msg_entries(fd); @@ -543,7 +543,7 @@ static void show_ipc_shm_entries(int fd) } } -void show_ipc_shm(int fd) +void show_ipc_shm(int fd, struct cr_options *o) { pr_img_head(CR_FD_IPCNS); show_ipc_shm_entries(fd); @@ -561,7 +561,7 @@ static void show_ipc_var_entry(int fd) ipc_sysctl_req(&var, CTL_SHOW); } -void show_ipc_var(int fd) +void show_ipc_var(int fd, struct cr_options *o) { pr_img_head(CR_FD_IPCNS); show_ipc_var_entry(fd); diff --git a/namespaces.c b/namespaces.c index 650e47217..4b4785ca9 100644 --- a/namespaces.c +++ b/namespaces.c @@ -114,28 +114,27 @@ int prepare_namespace(int pid, unsigned long clone_flags) return ret; } -int try_show_namespaces(int ns_pid) +int try_show_namespaces(int ns_pid, struct cr_options *o) { struct cr_fdset *fdset; + int i; fdset = cr_ns_fdset_open(ns_pid, O_SHOW); if (!fdset) return -1; - if (fdset_fd(fdset, CR_FD_UTSNS) != -1) - show_utsns(fdset_fd(fdset, CR_FD_UTSNS)); + for (i = _CR_FD_NS_FROM + 1; i < _CR_FD_NS_TO; i++) { + int fd; - if (fdset_fd(fdset, CR_FD_IPCNS_VAR) != -1) - show_ipc_var(fdset_fd(fdset, CR_FD_IPCNS_VAR)); + if (!fdset_template[i].show) + continue; - if (fdset_fd(fdset, CR_FD_IPCNS_SHM) != -1) - show_ipc_shm(fdset_fd(fdset, CR_FD_IPCNS_SHM)); + fd = fdset_fd(fdset, i); + if (fd == -1) + continue; - if (fdset_fd(fdset, CR_FD_IPCNS_MSG) != -1) - show_ipc_msg(fdset_fd(fdset, CR_FD_IPCNS_MSG)); - - if (fdset_fd(fdset, CR_FD_IPCNS_SEM) != -1) - show_ipc_sem(fdset_fd(fdset, CR_FD_IPCNS_SEM)); + fdset_template[i].show(fdset_fd(fdset, i), o); + } close_cr_fdset(&fdset); return 0; diff --git a/sockets.c b/sockets.c index 476688da1..4856f9ea2 100644 --- a/sockets.c +++ b/sockets.c @@ -1287,7 +1287,7 @@ int prepare_sockets(int pid) return prepare_inet_sockets(pid); } -void show_inetsk(int fd) +void show_inetsk(int fd, struct cr_options *o) { struct inet_sk_entry ie; int ret = 0; @@ -1325,7 +1325,7 @@ out: pr_img_tail(CR_FD_INETSK); } -void show_unixsk(int fd) +void show_unixsk(int fd, struct cr_options *o) { struct unix_sk_entry ue; int ret = 0; @@ -1361,7 +1361,7 @@ out: extern void print_data(unsigned long addr, unsigned char *data, size_t size); -int show_sk_queues(int fd) +void show_sk_queues(int fd, struct cr_options *o) { struct sk_packet_entry pe; int ret; @@ -1377,10 +1377,9 @@ int show_sk_queues(int fd) ret = read_img_buf(fd, (unsigned char *)buf, pe.length); if (ret < 0) - return ret; + break; print_data(0, (unsigned char *)buf, pe.length); } pr_img_tail(CR_FD_SK_QUEUES); - return ret; } diff --git a/uts_ns.c b/uts_ns.c index 8df32143c..a47d2765b 100644 --- a/uts_ns.c +++ b/uts_ns.c @@ -120,7 +120,7 @@ static void show_uts_string(int fd, char *n) } } -void show_utsns(int fd) +void show_utsns(int fd, struct cr_options *o) { pr_img_head(CR_FD_UTSNS); show_uts_string(fd, "hostname");