Commit c58abfd0 authored by Pavel Emelyanov's avatar Pavel Emelyanov

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 71cc2733
......@@ -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);
......
......@@ -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,
},
};
......
......@@ -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"
......
......@@ -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);
......
......@@ -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
......@@ -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__ */
......@@ -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_ */
......@@ -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);
......
......@@ -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;
......
......@@ -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;
}
......@@ -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");
......
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