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:
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,29 +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 lfd, int fd, 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;
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)
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;
}
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;
}
......@@ -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) == UNIX98_PTY_SLAVE_MAJOR)) {
/* skip only standard destriptors */
if (fd < 3) {
if (p->fd_name < 3) {
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 err;
......@@ -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) ||
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, fd,
lfd, 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(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;
}
if (stfs_buf.f_type == PIPEFS_MAGIC)
return dump_one_pipe(fd, lfd,
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 %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:
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;
......@@ -304,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;
}
......@@ -319,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");
......@@ -340,16 +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;
lfd = openat(dirfd(fd_dir), de->d_name, O_RDONLY);
if (dump_one_fd(pid_fd_dir, lfd, atoi(de->d_name),
pos, flags, id, cr_fdset))
if (dump_one_fd(pid_fd_dir, lfd, &p, cr_fdset))
return -1;
}
......@@ -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);
} 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;
}
......
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