mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-03 15:55:53 +00:00
Merge branch '@xemul' into dev
* @xemul:
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-dump.c
include/sockets.h
sockets.c
The conflicts are mostly because of commit
995ef5eca3
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
This commit is contained in:
129
cr-dump.c
129
cr-dump.c
@@ -92,10 +92,16 @@ 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_lfd, unsigned long pos,
|
unsigned long fd_name;
|
||||||
unsigned int flags, char *id,
|
unsigned long pos;
|
||||||
struct cr_fdset *cr_fdset)
|
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_lfd)
|
||||||
{
|
{
|
||||||
struct fdinfo_entry e;
|
struct fdinfo_entry e;
|
||||||
char fd_str[128];
|
char fd_str[128];
|
||||||
@@ -111,23 +117,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_lfd)
|
if (do_close_lfd)
|
||||||
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);
|
||||||
@@ -141,6 +147,12 @@ static int dump_cwd(int pid_dir, 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_proc(pid_dir, "cwd");
|
fd = open_proc(pid_dir, "cwd");
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@@ -148,7 +160,7 @@ static int dump_cwd(int pid_dir, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -206,19 +218,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;
|
||||||
@@ -230,31 +242,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(pid_t pid, int pid_dir, char *fd_name, unsigned long pos,
|
static int dump_one_fd(pid_t pid, int 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;
|
||||||
int fd = -1;
|
|
||||||
|
|
||||||
fd = open_proc(pid_dir, "fd/%s", fd_name);
|
if (lfd < 0) {
|
||||||
if (fd < 0) {
|
err = try_dump_socket(pid_fd_dir, p->fd_name, cr_fdset);
|
||||||
err = try_dump_socket(pid, fd_name, cr_fdset);
|
|
||||||
if (err != 1)
|
if (err != 1)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
pr_perror("Failed to openat %d/fd/%s\n", pid, fd_name);
|
pr_perror("Failed to open %s/%d\n", pid_fd_dir, p->fd_name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat(fd, &st_buf) < 0) {
|
if (fstat(lfd, &st_buf) < 0) {
|
||||||
pr_perror("Can't get stat on %d/fd/%s\n", pid, fd_name);
|
pr_perror("Can't get stat on %d\n", p->fd_name);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,9 +272,10 @@ static int dump_one_fd(pid_t pid, int pid_dir, char *fd_name, 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 (atoi(fd_name) < 3) {
|
if (p->fd_name < 3) {
|
||||||
err = 0;
|
err = 0;
|
||||||
pr_info("... Skipping tty ... %d/fd/%s\n", pid, fd_name);
|
pr_info("... Skipping tty ... %s/%d\n",
|
||||||
|
pid_fd_dir, p->fd_name);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
goto err;
|
goto err;
|
||||||
@@ -273,31 +284,27 @@ static int dump_one_fd(pid_t pid, int pid_dir, char *fd_name, 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, atol(fd_name),
|
return dump_one_reg_file(FDINFO_FD, p, lfd, cr_fdset, 1);
|
||||||
fd, 1, pos, flags, id, cr_fdset);
|
|
||||||
|
|
||||||
if (S_ISFIFO(st_buf.st_mode)) {
|
if (S_ISFIFO(st_buf.st_mode)) {
|
||||||
if (fstatfs(fd, &stfs_buf) < 0) {
|
if (fstatfs(lfd, &stfs_buf) < 0) {
|
||||||
pr_perror("Can't fstatfs on %s\n", fd_name);
|
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(atol(fd_name), fd,
|
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 %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:
|
out_close:
|
||||||
close_safe(&fd);
|
close_safe(&lfd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_fd_params(pid_t pid, int pid_dir, char *fd,
|
static int read_fd_params(pid_t pid, int pid_dir, char *fd, struct fd_parms *p)
|
||||||
unsigned long *pos, unsigned int *flags,
|
|
||||||
char *id)
|
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
unsigned int f;
|
unsigned int f;
|
||||||
@@ -308,11 +315,12 @@ static int read_fd_params(pid_t pid, int pid_dir, char *fd,
|
|||||||
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 %20s\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;
|
||||||
}
|
}
|
||||||
@@ -322,7 +330,6 @@ static int dump_task_files(pid_t pid, int pid_dir, 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");
|
||||||
@@ -341,11 +348,17 @@ static int dump_task_files(pid_t pid, int pid_dir, 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;
|
||||||
|
|
||||||
if (de->d_name[0] == '.')
|
if (de->d_name[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
if (read_fd_params(pid, pid_dir, de->d_name, &pos, &flags, id))
|
if (read_fd_params(pid, pid_dir, de->d_name, &p))
|
||||||
return -1;
|
return -1;
|
||||||
if (dump_one_fd(pid, pid_dir, de->d_name, pos, flags, id, cr_fdset))
|
|
||||||
|
lfd = openat(dirfd(fd_dir), de->d_name, O_RDONLY);
|
||||||
|
if (dump_one_fd(pid, dirfd(fd_dir), lfd, &p, cr_fdset))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,20 +401,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;
|
||||||
}
|
}
|
||||||
@@ -795,7 +807,7 @@ err:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pstree_item *find_pstree_entry(pid_t pid, int pid_dir)
|
static struct pstree_item *add_pstree_entry(pid_t pid, int pid_dir, struct list_head *list)
|
||||||
{
|
{
|
||||||
struct pstree_item *item;
|
struct pstree_item *item;
|
||||||
|
|
||||||
@@ -810,6 +822,7 @@ static struct pstree_item *find_pstree_entry(pid_t pid, int pid_dir)
|
|||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
||||||
item->pid = pid;
|
item->pid = pid;
|
||||||
|
list_add_tail(&item->list, list);
|
||||||
return item;
|
return item;
|
||||||
|
|
||||||
err_free:
|
err_free:
|
||||||
@@ -831,12 +844,10 @@ static int collect_pstree(pid_t pid, struct list_head *pstree_list)
|
|||||||
if (pid_dir < 0)
|
if (pid_dir < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
item = find_pstree_entry(pid, pid_dir);
|
item = add_pstree_entry(pid, pid_dir, pstree_list);
|
||||||
if (!item)
|
if (!item)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
list_add_tail(&item->list, pstree_list);
|
|
||||||
|
|
||||||
for (i = 0; i < item->nr_children; i++) {
|
for (i = 0; i < item->nr_children; i++) {
|
||||||
ret = collect_pstree(item->children[i], pstree_list);
|
ret = collect_pstree(item->children[i], pstree_list);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
106
cr-show.c
106
cr-show.c
@@ -78,6 +78,10 @@ static void show_files(int fd_files)
|
|||||||
int ret = read_ptr_safe_eof(fd_files, &e, out);
|
int ret = read_ptr_safe_eof(fd_files, &e, out);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
goto out;
|
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) {
|
if (e.len) {
|
||||||
int ret = read(fd_files, local_buf, e.len);
|
int ret = read(fd_files, local_buf, e.len);
|
||||||
if (ret != e.len) {
|
if (ret != e.len) {
|
||||||
@@ -85,11 +89,10 @@ static void show_files(int fd_files)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
local_buf[e.len] = 0;
|
local_buf[e.len] = 0;
|
||||||
pr_info("type: %02x len: %02x flags: %4x pos: %8x addr: %16lx --> %s\n",
|
pr_info(" --> %s", local_buf);
|
||||||
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",
|
pr_info("\n");
|
||||||
e.type, e.len, e.flags, e.pos, e.addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -215,7 +218,7 @@ out:
|
|||||||
pr_img_tail(CR_FD_SIGACT);
|
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;
|
struct pstree_entry e;
|
||||||
|
|
||||||
@@ -224,6 +227,7 @@ static void show_pstree(int fd_pstree)
|
|||||||
while (1) {
|
while (1) {
|
||||||
u32 pid;
|
u32 pid;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct pstree_item *item = NULL;
|
||||||
|
|
||||||
ret = read_ptr_safe_eof(fd_pstree, &e, out);
|
ret = read_ptr_safe_eof(fd_pstree, &e, out);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
@@ -231,6 +235,22 @@ static void show_pstree(int fd_pstree)
|
|||||||
pr_info("pid: %8d nr_children: %8d nr_threads: %8d\n",
|
pr_info("pid: %8d nr_children: %8d nr_threads: %8d\n",
|
||||||
e.pid, e.nr_children, e.nr_threads);
|
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) {
|
if (e.nr_children) {
|
||||||
pr_info("\\\n");
|
pr_info("\\\n");
|
||||||
pr_info(" +--- children: ");
|
pr_info(" +--- children: ");
|
||||||
@@ -251,6 +271,8 @@ static void show_pstree(int fd_pstree)
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
goto out;
|
goto out;
|
||||||
pr_info(" %6d", pid);
|
pr_info(" %6d", pid);
|
||||||
|
if (item)
|
||||||
|
item->threads[e.nr_threads] = pid;
|
||||||
}
|
}
|
||||||
pr_info("\n");
|
pr_info("\n");
|
||||||
}
|
}
|
||||||
@@ -259,6 +281,7 @@ static void show_pstree(int fd_pstree)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
pr_img_tail(CR_FD_PSTREE);
|
pr_img_tail(CR_FD_PSTREE);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_core_regs(int fd_core)
|
static void show_core_regs(int fd_core)
|
||||||
@@ -403,7 +426,7 @@ static int cr_parse_file(struct cr_options *opts)
|
|||||||
show_shmem(fd);
|
show_shmem(fd);
|
||||||
break;
|
break;
|
||||||
case PSTREE_MAGIC:
|
case PSTREE_MAGIC:
|
||||||
show_pstree(fd);
|
show_pstree(fd, NULL);
|
||||||
break;
|
break;
|
||||||
case PIPES_MAGIC:
|
case PIPES_MAGIC:
|
||||||
show_pipes(fd);
|
show_pipes(fd);
|
||||||
@@ -425,71 +448,6 @@ err:
|
|||||||
return ret;
|
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)
|
static int cr_show_all(unsigned long pid, struct cr_options *opts)
|
||||||
{
|
{
|
||||||
struct cr_fdset *cr_fdset = NULL;
|
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)
|
if (!cr_fdset)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = collect_pstree(&pstree_list, pid, cr_fdset);
|
ret = show_pstree(cr_fdset->fds[CR_FD_PSTREE], &pstree_list);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -520,7 +478,6 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts)
|
|||||||
if (!cr_fdset)
|
if (!cr_fdset)
|
||||||
goto out;
|
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);
|
show_core(cr_fdset->fds[CR_FD_CORE], opts->show_pages_content);
|
||||||
|
|
||||||
if (item->nr_threads > 1) {
|
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("Thread: %d\n", item->threads[i]);
|
||||||
pr_info("----------------------------------------\n");
|
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);
|
show_core(cr_fdset_th->fds[CR_FD_CORE], opts->show_pages_content);
|
||||||
|
|
||||||
pr_info("----------------------------------------\n");
|
pr_info("----------------------------------------\n");
|
||||||
|
@@ -43,9 +43,6 @@ struct pstree_entry {
|
|||||||
u32 pid;
|
u32 pid;
|
||||||
u32 nr_children;
|
u32 nr_children;
|
||||||
u32 nr_threads;
|
u32 nr_threads;
|
||||||
|
|
||||||
u32 children[0];
|
|
||||||
u32 threads[0];
|
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct pipe_entry {
|
struct pipe_entry {
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct cr_fdset;
|
struct cr_fdset;
|
||||||
extern int try_dump_socket(pid_t pid, char *fd_name, struct cr_fdset *cr_fdset);
|
extern int try_dump_socket(pid_t pid, int fd, struct cr_fdset *cr_fdset);
|
||||||
|
|
||||||
extern int collect_sockets(void);
|
extern int collect_sockets(void);
|
||||||
extern int prepare_sockets(int pid);
|
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(p) memset(p, 0, sizeof(*p))
|
||||||
#define memzero(p, size) memset(p, 0, size)
|
#define memzero(p, size) memset(p, 0, size)
|
||||||
|
|
||||||
extern void printk_registers(user_regs_struct_t *regs);
|
|
||||||
extern void printk_siginfo(siginfo_t *siginfo);
|
extern void printk_siginfo(siginfo_t *siginfo);
|
||||||
|
|
||||||
struct vma_area;
|
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_vma(vma_area) printk_vma(vma_area)
|
||||||
#define pr_info_registers(regs) printk_registers(regs)
|
|
||||||
#define pr_info_siginfo(siginfo) printk_siginfo(siginfo)
|
#define pr_info_siginfo(siginfo) printk_siginfo(siginfo)
|
||||||
|
|
||||||
extern int move_img_fd(int *img_fd, int want_fd);
|
extern int move_img_fd(int *img_fd, int want_fd);
|
||||||
|
@@ -144,7 +144,7 @@ static int can_dump_unix_sk(struct unix_sk_desc *sk)
|
|||||||
return 1;
|
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_desc *sk = (struct unix_sk_desc *)_sk;
|
||||||
struct unix_sk_entry ue;
|
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))
|
if (!can_dump_unix_sk(sk))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ue.fd = atoi(fd);
|
ue.fd = fd;
|
||||||
ue.id = sk->sd.ino;
|
ue.id = sk->sd.ino;
|
||||||
ue.type = sk->type;
|
ue.type = sk->type;
|
||||||
ue.state = sk->state;
|
ue.state = sk->state;
|
||||||
@@ -175,7 +175,7 @@ err:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int try_dump_socket(pid_t pid, char *fd, struct cr_fdset *cr_fdset)
|
int try_dump_socket(pid_t pid, int fd, struct cr_fdset *cr_fdset)
|
||||||
{
|
{
|
||||||
struct socket_desc *sk;
|
struct socket_desc *sk;
|
||||||
struct statfs fst;
|
struct statfs fst;
|
||||||
@@ -186,7 +186,7 @@ int try_dump_socket(pid_t pid, char *fd, struct cr_fdset *cr_fdset)
|
|||||||
* Sockets are tricky, we can't open it but can
|
* Sockets are tricky, we can't open it but can
|
||||||
* do stats over and check for sokets magic.
|
* do stats over and check for sokets magic.
|
||||||
*/
|
*/
|
||||||
snprintf(buf, sizeof(buf), "/proc/%d/fd/%s", pid, fd);
|
snprintf(buf, sizeof(buf), "/proc/%d/fd/%d", pid, fd);
|
||||||
if (statfs(buf, &fst)) {
|
if (statfs(buf, &fst)) {
|
||||||
pr_err("Can't statfs %s\n", buf);
|
pr_err("Can't statfs %s\n", buf);
|
||||||
return -1;
|
return -1;
|
||||||
|
22
util.c
22
util.c
@@ -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)
|
void printk_siginfo(siginfo_t *siginfo)
|
||||||
{
|
{
|
||||||
printk("si_signo %d si_errno %d si_code %d\n",
|
printk("si_signo %d si_errno %d si_code %d\n",
|
||||||
|
Reference in New Issue
Block a user