Commit d7121ede authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

Merge branch '@xemul-mails' into @xemul

* @xemul-mails:
  crtools: Collect dumping fd parameters into one place
  crtools: Toss dump_one_fd args around
  crtools: Rename fd to lfd in dump_one_fd
  crtools: Sanitize pstree construction
  crtools: Remove unused printk_registers and co
  crtools: Deduplicate file info showing code
  crtools: Merge pstree collecting into showing
  crtools: Remove unused and wrong arrays from pstree image
  crtools: Remove lseeks after prep_cr_ calls
  crtools: Cleanup collect_pstree in cr-show

Conflicts:
	cr-show.c
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parents 9360a73c a9fdf386
......@@ -92,9 +92,15 @@ err_bogus_mapping:
goto err;
}
static int dump_one_reg_file(int type, unsigned long fd_name, int lfd,
bool do_close, unsigned long pos, unsigned int flags,
char *id, struct cr_fdset *cr_fdset)
struct fd_parms {
unsigned long fd_name;
unsigned long pos;
unsigned int flags;
char *id;
};
static int dump_one_reg_file(int type, struct fd_parms *p, int lfd,
struct cr_fdset *cr_fdset, bool do_close)
{
struct fdinfo_entry e;
char fd_str[128];
......@@ -110,23 +116,23 @@ static int dump_one_reg_file(int type, unsigned long fd_name, int lfd,
big_buffer[len] = '\0';
pr_info("Dumping path for %lx fd via self %d [%s]\n",
fd_name, lfd, big_buffer);
p->fd_name, lfd, big_buffer);
if (do_close)
close(lfd);
e.type = type;
e.len = len;
e.flags = flags;
e.pos = pos;
e.addr = fd_name;
if (id)
memcpy(e.id, id, FD_ID_SIZE);
e.flags = p->flags;
e.pos = p->pos;
e.addr = p->fd_name;
if (p->id)
memcpy(e.id, p->id, FD_ID_SIZE);
else
memzero(e.id, FD_ID_SIZE);
pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8x addr: %16lx\n",
type, len, flags, pos, fd_name);
type, len, p->flags, p->pos, p->fd_name);
write_ptr_safe(cr_fdset->fds[CR_FD_FDINFO], &e, err);
write_safe(cr_fdset->fds[CR_FD_FDINFO], big_buffer, e.len, err);
......@@ -140,6 +146,12 @@ static int dump_cwd(char *path, struct cr_fdset *cr_fdset)
{
int ret = -1;
int fd;
struct fd_parms p = {
.fd_name = ~0L,
.pos = 0,
.flags = 0,
.id = NULL,
};
fd = open(path, O_RDONLY | O_DIRECTORY);
if (fd < 0) {
......@@ -147,7 +159,7 @@ static int dump_cwd(char *path, struct cr_fdset *cr_fdset)
return -1;
}
return dump_one_reg_file(FDINFO_FD, ~0L, fd, 1, 0, 0, NULL, cr_fdset);
return dump_one_reg_file(FDINFO_FD, &p, fd, cr_fdset, 1);
}
......@@ -205,19 +217,19 @@ err:
return ret;
}
static int dump_one_pipe(int fd, int lfd, unsigned int id, unsigned int flags,
struct cr_fdset *cr_fdset)
static int dump_one_pipe(struct fd_parms *p, unsigned int id, int lfd,
struct cr_fdset *cr_fdset)
{
struct pipe_entry e;
int ret = -1;
pr_info("Dumping pipe %d/%x flags %x\n", fd, id, flags);
pr_info("Dumping pipe %d/%x flags %x\n", p->fd_name, id, p->flags);
e.fd = fd;
e.fd = p->fd_name;
e.pipeid = id;
e.flags = flags;
e.flags = p->flags;
if (flags & O_WRONLY) {
if (p->flags & O_WRONLY) {
e.bytes = 0;
write_ptr_safe(cr_fdset->fds[CR_FD_PIPES], &e, err);
ret = 0;
......@@ -229,31 +241,29 @@ err:
pr_info("Dumped pipe: fd: %8lx pipeid: %8lx flags: %8lx bytes: %8lx\n",
e.fd, e.pipeid, e.flags, e.bytes);
else
pr_err("Dumping pipe %d/%x flags %x\n", fd, id, flags);
pr_err("Dumping pipe %d/%x flags %x\n", p->fd_name, id, p->flags);
return ret;
}
static int dump_one_fd(char *pid_fd_dir, int dir, char *fd_name, unsigned long pos,
unsigned int flags, char *id, struct cr_fdset *cr_fdset)
static int dump_one_fd(char *pid_fd_dir, int lfd,
struct fd_parms *p, struct cr_fdset *cr_fdset)
{
struct statfs stfs_buf;
struct stat st_buf;
int err = -1;
int fd = -1;
fd = openat(dir, fd_name, O_RDONLY);
if (fd < 0) {
err = try_dump_socket(pid_fd_dir, fd_name, cr_fdset);
if (lfd < 0) {
err = try_dump_socket(pid_fd_dir, p->fd_name, cr_fdset);
if (err != 1)
return err;
pr_perror("Failed to openat %s/%d %s\n", pid_fd_dir, dir, fd_name);
pr_perror("Failed to open %s/%d\n", pid_fd_dir, p->fd_name);
return -1;
}
if (fstat(fd, &st_buf) < 0) {
pr_perror("Can't get stat on %s\n", fd_name);
if (fstat(lfd, &st_buf) < 0) {
pr_perror("Can't get stat on %d\n", p->fd_name);
goto out_close;
}
......@@ -261,9 +271,9 @@ static int dump_one_fd(char *pid_fd_dir, int dir, char *fd_name, unsigned long p
(major(st_buf.st_rdev) == TTY_MAJOR ||
major(st_buf.st_rdev) == UNIX98_PTY_SLAVE_MAJOR)) {
/* skip only standard destriptors */
if (atoi(fd_name) < 3) {
if (p->fd_name < 3) {
err = 0;
pr_info("... Skipping tty ... %s/%s\n", pid_fd_dir, fd_name);
pr_info("... Skipping tty ... %s/%d\n", pid_fd_dir, p->fd_name);
goto out_close;
}
goto err;
......@@ -272,30 +282,27 @@ static int dump_one_fd(char *pid_fd_dir, int dir, char *fd_name, unsigned long p
if (S_ISREG(st_buf.st_mode) ||
S_ISDIR(st_buf.st_mode) ||
(S_ISCHR(st_buf.st_mode) && major(st_buf.st_rdev) == MEM_MAJOR))
return dump_one_reg_file(FDINFO_FD, atol(fd_name),
fd, 1, pos, flags, id, cr_fdset);
return dump_one_reg_file(FDINFO_FD, p, lfd, cr_fdset, 1);
if (S_ISFIFO(st_buf.st_mode)) {
if (fstatfs(fd, &stfs_buf) < 0) {
pr_perror("Can't fstatfs on %s\n", fd_name);
if (fstatfs(lfd, &stfs_buf) < 0) {
pr_perror("Can't fstatfs on %d\n", p->fd_name);
return -1;
}
if (stfs_buf.f_type == PIPEFS_MAGIC)
return dump_one_pipe(atol(fd_name), fd,
st_buf.st_ino, flags, cr_fdset);
return dump_one_pipe(p, st_buf.st_ino, lfd, cr_fdset);
}
err:
pr_err("Can't dump file %s of that type [%x]\n", fd_name, st_buf.st_mode);
pr_err("Can't dump file %d of that type [%x]\n", p->fd_name, st_buf.st_mode);
out_close:
close_safe(&fd);
close_safe(&lfd);
return err;
}
static int read_fd_params(pid_t pid, char *fd, unsigned long *pos,
unsigned int *flags, char *id)
static int read_fd_params(pid_t pid, char *fd, struct fd_parms *p)
{
FILE *file;
unsigned int f;
......@@ -306,11 +313,12 @@ static int read_fd_params(pid_t pid, char *fd, unsigned long *pos,
return -1;
}
fscanf(file, "pos:\t%li\nflags:\t%o\nid:\t%s\n", pos, flags, id);
p->fd_name = atoi(fd);
fscanf(file, "pos:\t%li\nflags:\t%o\nid:\t%s\n", &p->pos, &p->flags, p->id);
fclose(file);
pr_info("%d fdinfo %s: pos: %16lx flags: %16o id %s\n",
pid, fd, *pos, *flags, id);
pid, fd, p->pos, p->flags, p->id);
return 0;
}
......@@ -321,7 +329,6 @@ static int dump_task_files(pid_t pid, struct cr_fdset *cr_fdset)
struct dirent *de;
unsigned long pos;
unsigned int flags;
char id[FD_ID_SIZE];
DIR *fd_dir;
pr_info("\n");
......@@ -342,12 +349,17 @@ static int dump_task_files(pid_t pid, struct cr_fdset *cr_fdset)
}
while ((de = readdir(fd_dir))) {
char id[FD_ID_SIZE];
struct fd_parms p = { .id = id };
int lfd;
if (de->d_name[0] == '.')
continue;
if (read_fd_params(pid, de->d_name, &pos, &flags, id))
if (read_fd_params(pid, de->d_name, &p))
return -1;
if (dump_one_fd(pid_fd_dir, dirfd(fd_dir), de->d_name,
pos, flags, id, cr_fdset))
lfd = openat(dirfd(fd_dir), de->d_name, O_RDONLY);
if (dump_one_fd(pid_fd_dir, lfd, &p, cr_fdset))
return -1;
}
......@@ -390,20 +402,19 @@ static int dump_task_mappings(pid_t pid, struct list_head *vma_area_list, struct
write_ptr_safe(cr_fdset->fds[CR_FD_SHMEM], &e, err);
} else if (vma_entry_is(vma, VMA_FILE_PRIVATE) ||
vma_entry_is(vma, VMA_FILE_SHARED)) {
unsigned int flags;
struct fd_parms p = {
.fd_name = vma->start,
.pos = 0,
.id = NULL,
};
if (vma->prot & PROT_WRITE &&
vma_entry_is(vma, VMA_FILE_SHARED))
flags = O_RDWR;
p.flags = O_RDWR;
else
flags = O_RDONLY;
p.flags = O_RDONLY;
ret = dump_one_reg_file(FDINFO_MAP,
vma->start,
vma_area->vm_file_fd,
0, 0, flags, NULL,
cr_fdset);
ret = dump_one_reg_file(FDINFO_MAP, &p, vma_area->vm_file_fd, cr_fdset, 0);
if (ret)
goto err;
}
......@@ -798,7 +809,7 @@ err:
return -1;
}
static struct pstree_item *find_pstree_entry(pid_t pid)
static struct pstree_item *add_pstree_entry(pid_t pid, struct list_head *list)
{
struct pstree_item *item;
......@@ -813,6 +824,7 @@ static struct pstree_item *find_pstree_entry(pid_t pid)
goto err_free;
item->pid = pid;
list_add_tail(&item->list, list);
return item;
err_free:
......@@ -829,12 +841,10 @@ static int collect_pstree(pid_t pid, struct list_head *pstree_list)
unsigned long i;
int ret = -1;
item = find_pstree_entry(pid);
item = add_pstree_entry(pid, pstree_list);
if (!item)
goto err;
list_add_tail(&item->list, pstree_list);
for (i = 0; i < item->nr_children; i++) {
ret = collect_pstree(item->children[i], pstree_list);
if (ret)
......
......@@ -78,6 +78,10 @@ static void show_files(int fd_files)
int ret = read_ptr_safe_eof(fd_files, &e, out);
if (!ret)
goto out;
pr_info("type: %02x len: %02x flags: %4x pos: %8x addr: %16lx",
e.type, e.len, e.flags, e.pos, e.addr);
if (e.len) {
int ret = read(fd_files, local_buf, e.len);
if (ret != e.len) {
......@@ -85,11 +89,10 @@ static void show_files(int fd_files)
goto out;
}
local_buf[e.len] = 0;
pr_info("type: %02x len: %02x flags: %4x pos: %8x addr: %16lx --> %s\n",
e.type, e.len, e.flags, e.pos, e.addr, local_buf);
} else
pr_info("type: %02x len: %02x flags: %4x pos: %8x addr: %16lx\n",
e.type, e.len, e.flags, e.pos, e.addr);
pr_info(" --> %s", local_buf);
}
pr_info("\n");
}
out:
......@@ -215,7 +218,7 @@ out:
pr_img_tail(CR_FD_SIGACT);
}
static void show_pstree(int fd_pstree)
static int show_pstree(int fd_pstree, struct list_head *collect)
{
struct pstree_entry e;
......@@ -224,6 +227,7 @@ static void show_pstree(int fd_pstree)
while (1) {
u32 pid;
int ret;
struct pstree_item *item = NULL;
ret = read_ptr_safe_eof(fd_pstree, &e, out);
if (!ret)
......@@ -231,6 +235,22 @@ static void show_pstree(int fd_pstree)
pr_info("pid: %8d nr_children: %8d nr_threads: %8d\n",
e.pid, e.nr_children, e.nr_threads);
if (collect) {
item = xzalloc(sizeof(struct pstree_item));
if (!item)
return -1;
item->pid = e.pid;
item->nr_threads = e.nr_threads;
item->threads = xzalloc(sizeof(u32) * e.nr_threads);
if (!item->threads) {
xfree(item);
return -1;
}
list_add_tail(&item->list, collect);
}
if (e.nr_children) {
pr_info("\\\n");
pr_info(" +--- children: ");
......@@ -251,6 +271,8 @@ static void show_pstree(int fd_pstree)
if (!ret)
goto out;
pr_info(" %6d", pid);
if (item)
item->threads[e.nr_threads] = pid;
}
pr_info("\n");
}
......@@ -259,6 +281,7 @@ static void show_pstree(int fd_pstree)
out:
pr_img_tail(CR_FD_PSTREE);
return 0;
}
static void show_core_regs(int fd_core)
......@@ -403,7 +426,7 @@ static int cr_parse_file(struct cr_options *opts)
show_shmem(fd);
break;
case PSTREE_MAGIC:
show_pstree(fd);
show_pstree(fd, NULL);
break;
case PIPES_MAGIC:
show_pipes(fd);
......@@ -425,71 +448,6 @@ err:
return ret;
}
static int collect_pstree(struct list_head *head, pid_t pid, struct cr_fdset *cr_fdset)
{
int fd = cr_fdset->fds[CR_FD_PSTREE];
struct pstree_item *item = NULL;
struct pstree_entry e;
int ret = -1;
for (;;) {
size_t size_children, size_threads;
ret = read(fd, &e, sizeof(e));
if (ret && ret != sizeof(e)) {
pr_perror("Wrong pstree entry\n");
goto err;
}
if (!ret)
break;
item = xzalloc(sizeof(*item));
if (!item)
goto err;
size_children = sizeof(u32) * e.nr_children;
size_threads = sizeof(u32) * e.nr_threads;
item->pid = e.pid;
item->nr_children = e.nr_children;
item->nr_threads = e.nr_threads;
item->children = xmalloc(size_children);
item->threads = xmalloc(size_threads);
if (!item->children || !item->threads) {
pr_err("No memory for children/thread pids\n");
goto err;
}
ret = read(fd, item->children, size_children);
if (ret != size_children) {
pr_err("An error in reading children pids\n");
goto err;
}
ret = read(fd, item->threads, size_threads);
if (ret != size_threads) {
pr_err("An error in reading threads pids\n");
goto err;
}
list_add_tail(&item->list, head);
}
item = NULL;
ret = 0;
err:
if (item) {
xfree(item->children);
xfree(item->threads);
}
xfree(item);
return ret;
}
static int cr_show_all(unsigned long pid, struct cr_options *opts)
{
struct cr_fdset *cr_fdset = NULL;
......@@ -501,7 +459,7 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts)
if (!cr_fdset)
goto out;
ret = collect_pstree(&pstree_list, pid, cr_fdset);
ret = show_pstree(cr_fdset->fds[CR_FD_PSTREE], &pstree_list);
if (ret)
goto out;
......@@ -520,7 +478,6 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts)
if (!cr_fdset)
goto out;
lseek(cr_fdset->fds[CR_FD_CORE], MAGIC_OFFSET, SEEK_SET);
show_core(cr_fdset->fds[CR_FD_CORE], opts->show_pages_content);
if (item->nr_threads > 1) {
......@@ -540,7 +497,6 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts)
pr_info("Thread: %d\n", item->threads[i]);
pr_info("----------------------------------------\n");
lseek(cr_fdset_th->fds[CR_FD_CORE], MAGIC_OFFSET, SEEK_SET);
show_core(cr_fdset_th->fds[CR_FD_CORE], opts->show_pages_content);
pr_info("----------------------------------------\n");
......
......@@ -43,9 +43,6 @@ struct pstree_entry {
u32 pid;
u32 nr_children;
u32 nr_threads;
u32 children[0];
u32 threads[0];
} __packed;
struct pipe_entry {
......
......@@ -4,7 +4,7 @@
#include <stdbool.h>
struct cr_fdset;
extern int try_dump_socket(char *dir_name, char *fd_name, struct cr_fdset *cr_fdset);
extern int try_dump_socket(char *dir_name, int fd, struct cr_fdset *cr_fdset);
extern int collect_sockets(void);
extern int prepare_sockets(int pid);
......
......@@ -133,7 +133,6 @@ extern void printk(const char *format, ...);
#define memzero_p(p) memset(p, 0, sizeof(*p))
#define memzero(p, size) memset(p, 0, size)
extern void printk_registers(user_regs_struct_t *regs);
extern void printk_siginfo(siginfo_t *siginfo);
struct vma_area;
......@@ -161,7 +160,6 @@ extern void printk_vma(struct vma_area *vma_area);
})
#define pr_info_vma(vma_area) printk_vma(vma_area)
#define pr_info_registers(regs) printk_registers(regs)
#define pr_info_siginfo(siginfo) printk_siginfo(siginfo)
extern int reopen_fd_as(int new_fd, int old_fd);
......
......@@ -144,7 +144,7 @@ static int can_dump_unix_sk(struct unix_sk_desc *sk)
return 1;
}
static int dump_one_unix(struct socket_desc *_sk, char *fd, struct cr_fdset *cr_fdset)
static int dump_one_unix(struct socket_desc *_sk, int fd, struct cr_fdset *cr_fdset)
{
struct unix_sk_desc *sk = (struct unix_sk_desc *)_sk;
struct unix_sk_entry ue;
......@@ -152,7 +152,7 @@ static int dump_one_unix(struct socket_desc *_sk, char *fd, struct cr_fdset *cr_
if (!can_dump_unix_sk(sk))
goto err;
ue.fd = atoi(fd);
ue.fd = fd;
ue.id = sk->sd.ino;
ue.type = sk->type;
ue.state = sk->state;
......@@ -175,13 +175,13 @@ err:
return -1;
}
int try_dump_socket(char *dir, char *fd, struct cr_fdset *cr_fdset)
int try_dump_socket(char *dir, int fd, struct cr_fdset *cr_fdset)
{
struct socket_desc *sk;
struct statfs fst;
struct stat st;
snprintf(buf, sizeof(buf), "%s/%s", dir, fd);
snprintf(buf, sizeof(buf), "%s/%d", dir, fd);
if (statfs(buf, &fst)) {
pr_err("Can't statfs %s\n", buf);
return -1;
......
......@@ -61,28 +61,6 @@ void hex_dump(void *addr, unsigned long len)
}
}
void printk_registers(user_regs_struct_t *regs)
{
printk("ip : %16lx cs : %16lx ds : %16lx\n"
"es : %16lx fs : %16lx gs : %16lx\n"
"sp : %16lx ss : %16lx flags : %16lx\n"
"ax : %16lx cx : %16lx dx : %16lx\n"
"si : %16lx di : %16lx bp : %16lx\n"
"bx : %16lx r8 : %16lx r9 : %16lx\n"
"r10 : %16lx r11 : %16lx r12 : %16lx\n"
"r13 : %16lx r14 : %16lx r15 : %16lx\n"
"orig_ax: %16lx fs_base: %16lx gs_base: %16lx\n\n",
regs->ip, regs->cs, regs->ds,
regs->es, regs->fs, regs->gs,
regs->sp, regs->ss, regs->flags,
regs->ax, regs->cx, regs->dx,
regs->si, regs->di, regs->bp,
regs->bx, regs->r8, regs->r9,
regs->r10, regs->r11, regs->r12,
regs->r13, regs->r14, regs->r15,
regs->orig_ax, regs->fs_base, regs->gs_base);
}
void printk_siginfo(siginfo_t *siginfo)
{
printk("si_signo %d si_errno %d si_code %d\n",
......
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