Commit a9fdf386 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Cyrill Gorcunov

crtools: Collect dumping fd parameters into one place

Introduce the fd_parms structure, that contains all we need to describe
open fd during dump -- its name (int), pos, flags and id. The read_fd_parms
routing fills one once and passes along the stack. This reduces the amount
of arguments significantly.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 1b247eb6
...@@ -92,9 +92,15 @@ err_bogus_mapping: ...@@ -92,9 +92,15 @@ err_bogus_mapping:
goto err; goto err;
} }
static int dump_one_reg_file(int type, unsigned long fd_name, int lfd, struct fd_parms {
bool do_close, unsigned long pos, unsigned int flags, unsigned long fd_name;
char *id, struct cr_fdset *cr_fdset) 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; struct fdinfo_entry e;
char fd_str[128]; char fd_str[128];
...@@ -110,23 +116,23 @@ static int dump_one_reg_file(int type, unsigned long fd_name, int lfd, ...@@ -110,23 +116,23 @@ static int dump_one_reg_file(int type, unsigned long fd_name, int lfd,
big_buffer[len] = '\0'; big_buffer[len] = '\0';
pr_info("Dumping path for %lx fd via self %d [%s]\n", 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) if (do_close)
close(lfd); close(lfd);
e.type = type; e.type = type;
e.len = len; e.len = len;
e.flags = flags; e.flags = p->flags;
e.pos = pos; e.pos = p->pos;
e.addr = fd_name; e.addr = p->fd_name;
if (id) if (p->id)
memcpy(e.id, id, FD_ID_SIZE); memcpy(e.id, p->id, FD_ID_SIZE);
else else
memzero(e.id, FD_ID_SIZE); memzero(e.id, FD_ID_SIZE);
pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8x addr: %16lx\n", 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_ptr_safe(cr_fdset->fds[CR_FD_FDINFO], &e, err);
write_safe(cr_fdset->fds[CR_FD_FDINFO], big_buffer, e.len, 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) ...@@ -140,6 +146,12 @@ static int dump_cwd(char *path, struct cr_fdset *cr_fdset)
{ {
int ret = -1; int ret = -1;
int fd; int fd;
struct fd_parms p = {
.fd_name = ~0L,
.pos = 0,
.flags = 0,
.id = NULL,
};
fd = open(path, O_RDONLY | O_DIRECTORY); fd = open(path, O_RDONLY | O_DIRECTORY);
if (fd < 0) { if (fd < 0) {
...@@ -147,7 +159,7 @@ static int dump_cwd(char *path, struct cr_fdset *cr_fdset) ...@@ -147,7 +159,7 @@ static int dump_cwd(char *path, struct cr_fdset *cr_fdset)
return -1; 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: ...@@ -205,19 +217,19 @@ err:
return ret; return ret;
} }
static int dump_one_pipe(int fd, int lfd, unsigned int id, unsigned int flags, static int dump_one_pipe(struct fd_parms *p, unsigned int id, int lfd,
struct cr_fdset *cr_fdset) struct cr_fdset *cr_fdset)
{ {
struct pipe_entry e; struct pipe_entry e;
int ret = -1; 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.pipeid = id;
e.flags = flags; e.flags = p->flags;
if (flags & O_WRONLY) { if (p->flags & O_WRONLY) {
e.bytes = 0; e.bytes = 0;
write_ptr_safe(cr_fdset->fds[CR_FD_PIPES], &e, err); write_ptr_safe(cr_fdset->fds[CR_FD_PIPES], &e, err);
ret = 0; ret = 0;
...@@ -229,29 +241,29 @@ err: ...@@ -229,29 +241,29 @@ err:
pr_info("Dumped pipe: fd: %8lx pipeid: %8lx flags: %8lx bytes: %8lx\n", pr_info("Dumped pipe: fd: %8lx pipeid: %8lx flags: %8lx bytes: %8lx\n",
e.fd, e.pipeid, e.flags, e.bytes); e.fd, e.pipeid, e.flags, e.bytes);
else 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; return ret;
} }
static int dump_one_fd(char *pid_fd_dir, int lfd, int fd, unsigned long pos, static int dump_one_fd(char *pid_fd_dir, int lfd,
unsigned int flags, char *id, struct cr_fdset *cr_fdset) struct fd_parms *p, struct cr_fdset *cr_fdset)
{ {
struct statfs stfs_buf; struct statfs stfs_buf;
struct stat st_buf; struct stat st_buf;
int err = -1; int err = -1;
if (lfd < 0) { if (lfd < 0) {
err = try_dump_socket(pid_fd_dir, fd, cr_fdset); err = try_dump_socket(pid_fd_dir, p->fd_name, cr_fdset);
if (err != 1) if (err != 1)
return err; return err;
pr_perror("Failed to openat %s/%d\n", pid_fd_dir, fd); pr_perror("Failed to open %s/%d\n", pid_fd_dir, p->fd_name);
return -1; return -1;
} }
if (fstat(lfd, &st_buf) < 0) { if (fstat(lfd, &st_buf) < 0) {
pr_perror("Can't get stat on %d\n", fd); pr_perror("Can't get stat on %d\n", p->fd_name);
goto out_close; goto out_close;
} }
...@@ -259,9 +271,9 @@ static int dump_one_fd(char *pid_fd_dir, int lfd, int fd, unsigned long pos, ...@@ -259,9 +271,9 @@ static int dump_one_fd(char *pid_fd_dir, int lfd, int fd, unsigned long pos,
(major(st_buf.st_rdev) == TTY_MAJOR || (major(st_buf.st_rdev) == TTY_MAJOR ||
major(st_buf.st_rdev) == UNIX98_PTY_SLAVE_MAJOR)) { major(st_buf.st_rdev) == UNIX98_PTY_SLAVE_MAJOR)) {
/* skip only standard destriptors */ /* skip only standard destriptors */
if (fd < 3) { if (p->fd_name < 3) {
err = 0; err = 0;
pr_info("... Skipping tty ... %s/%d\n", pid_fd_dir, fd); pr_info("... Skipping tty ... %s/%d\n", pid_fd_dir, p->fd_name);
goto out_close; goto out_close;
} }
goto err; goto err;
...@@ -270,30 +282,27 @@ static int dump_one_fd(char *pid_fd_dir, int lfd, int fd, unsigned long pos, ...@@ -270,30 +282,27 @@ static int dump_one_fd(char *pid_fd_dir, int lfd, int fd, unsigned long pos,
if (S_ISREG(st_buf.st_mode) || if (S_ISREG(st_buf.st_mode) ||
S_ISDIR(st_buf.st_mode) || S_ISDIR(st_buf.st_mode) ||
(S_ISCHR(st_buf.st_mode) && major(st_buf.st_rdev) == MEM_MAJOR)) (S_ISCHR(st_buf.st_mode) && major(st_buf.st_rdev) == MEM_MAJOR))
return dump_one_reg_file(FDINFO_FD, fd, return dump_one_reg_file(FDINFO_FD, p, lfd, cr_fdset, 1);
lfd, 1, pos, flags, id, cr_fdset);
if (S_ISFIFO(st_buf.st_mode)) { if (S_ISFIFO(st_buf.st_mode)) {
if (fstatfs(lfd, &stfs_buf) < 0) { if (fstatfs(lfd, &stfs_buf) < 0) {
pr_perror("Can't fstatfs on %d\n", fd); pr_perror("Can't fstatfs on %d\n", p->fd_name);
return -1; return -1;
} }
if (stfs_buf.f_type == PIPEFS_MAGIC) if (stfs_buf.f_type == PIPEFS_MAGIC)
return dump_one_pipe(fd, lfd, return dump_one_pipe(p, st_buf.st_ino, lfd, cr_fdset);
st_buf.st_ino, flags, cr_fdset);
} }
err: err:
pr_err("Can't dump file %d of that type [%x]\n", fd, 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: out_close:
close_safe(&lfd); close_safe(&lfd);
return err; return err;
} }
static int read_fd_params(pid_t pid, char *fd, unsigned long *pos, static int read_fd_params(pid_t pid, char *fd, struct fd_parms *p)
unsigned int *flags, char *id)
{ {
FILE *file; FILE *file;
unsigned int f; unsigned int f;
...@@ -304,11 +313,12 @@ static int read_fd_params(pid_t pid, char *fd, unsigned long *pos, ...@@ -304,11 +313,12 @@ static int read_fd_params(pid_t pid, char *fd, unsigned long *pos,
return -1; 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); fclose(file);
pr_info("%d fdinfo %s: pos: %16lx flags: %16o id %s\n", 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; return 0;
} }
...@@ -319,7 +329,6 @@ static int dump_task_files(pid_t pid, struct cr_fdset *cr_fdset) ...@@ -319,7 +329,6 @@ static int dump_task_files(pid_t pid, struct cr_fdset *cr_fdset)
struct dirent *de; struct dirent *de;
unsigned long pos; unsigned long pos;
unsigned int flags; unsigned int flags;
char id[FD_ID_SIZE];
DIR *fd_dir; DIR *fd_dir;
pr_info("\n"); pr_info("\n");
...@@ -340,16 +349,17 @@ static int dump_task_files(pid_t pid, struct cr_fdset *cr_fdset) ...@@ -340,16 +349,17 @@ static int dump_task_files(pid_t pid, struct cr_fdset *cr_fdset)
} }
while ((de = readdir(fd_dir))) { while ((de = readdir(fd_dir))) {
char id[FD_ID_SIZE];
struct fd_parms p = { .id = id };
int lfd; int lfd;
if (de->d_name[0] == '.') if (de->d_name[0] == '.')
continue; continue;
if (read_fd_params(pid, de->d_name, &pos, &flags, id)) if (read_fd_params(pid, de->d_name, &p))
return -1; return -1;
lfd = openat(dirfd(fd_dir), de->d_name, O_RDONLY); lfd = openat(dirfd(fd_dir), de->d_name, O_RDONLY);
if (dump_one_fd(pid_fd_dir, lfd, atoi(de->d_name), if (dump_one_fd(pid_fd_dir, lfd, &p, cr_fdset))
pos, flags, id, cr_fdset))
return -1; return -1;
} }
...@@ -392,20 +402,19 @@ static int dump_task_mappings(pid_t pid, struct list_head *vma_area_list, struct ...@@ -392,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); write_ptr_safe(cr_fdset->fds[CR_FD_SHMEM], &e, err);
} else if (vma_entry_is(vma, VMA_FILE_PRIVATE) || } else if (vma_entry_is(vma, VMA_FILE_PRIVATE) ||
vma_entry_is(vma, VMA_FILE_SHARED)) { vma_entry_is(vma, VMA_FILE_SHARED)) {
struct fd_parms p = {
unsigned int flags; .fd_name = vma->start,
.pos = 0,
.id = NULL,
};
if (vma->prot & PROT_WRITE && if (vma->prot & PROT_WRITE &&
vma_entry_is(vma, VMA_FILE_SHARED)) vma_entry_is(vma, VMA_FILE_SHARED))
flags = O_RDWR; p.flags = O_RDWR;
else else
flags = O_RDONLY; p.flags = O_RDONLY;
ret = dump_one_reg_file(FDINFO_MAP, ret = dump_one_reg_file(FDINFO_MAP, &p, vma_area->vm_file_fd, cr_fdset, 0);
vma->start,
vma_area->vm_file_fd,
0, 0, flags, NULL,
cr_fdset);
if (ret) if (ret)
goto err; goto err;
} }
......
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