diff --git a/cr-dump.c b/cr-dump.c index 7216d7903..a908d3292 100644 --- a/cr-dump.c +++ b/cr-dump.c @@ -128,8 +128,8 @@ static int dump_one_reg_file(int type, unsigned long fd_name, int lfd, pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8x addr: %16lx\n", type, len, flags, pos, fd_name); - write_ptr_safe(cr_fdset->desc[CR_FD_FDINFO].fd, &e, err); - write_safe(cr_fdset->desc[CR_FD_FDINFO].fd, big_buffer, e.len, 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); ret = 0; err: @@ -160,7 +160,7 @@ static int dump_pipe_and_data(int lfd, struct pipe_entry *e, int has_bytes; int ret = -1; - fd_pipes = cr_fdset->desc[CR_FD_PIPES].fd; + fd_pipes = cr_fdset->fds[CR_FD_PIPES]; pr_info("Dumping data from pipe %x\n", e->pipeid); if (pipe(steal_pipe) < 0) { @@ -219,7 +219,7 @@ static int dump_one_pipe(int fd, int lfd, unsigned int id, unsigned int flags, if (flags & O_WRONLY) { e.bytes = 0; - write_ptr_safe(cr_fdset->desc[CR_FD_PIPES].fd, &e, err); + write_ptr_safe(cr_fdset->fds[CR_FD_PIPES], &e, err); ret = 0; } else ret = dump_pipe_and_data(lfd, &e, cr_fdset); @@ -387,7 +387,7 @@ static int dump_task_mappings(pid_t pid, struct list_head *vma_area_list, struct pr_info("shmem: s: %16lx e: %16lx shmid: %16lx\n", e.start, e.end, e.shmid); - write_ptr_safe(cr_fdset->desc[CR_FD_SHMEM].fd, &e, err); + 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)) { @@ -651,7 +651,7 @@ err: static int dump_task_core_seized(pid_t pid, struct cr_fdset *cr_fdset) { struct core_entry *core = xzalloc(sizeof(*core)); - int fd_core = cr_fdset->desc[CR_FD_CORE].fd; + int fd_core = cr_fdset->fds[CR_FD_CORE]; int ret = -1; unsigned long brk; @@ -866,12 +866,12 @@ static int dump_pstree(pid_t pid, struct list_head *pstree_list, struct cr_fdset e.nr_children = item->nr_children; e.nr_threads = item->nr_threads; - write_ptr_safe(cr_fdset->desc[CR_FD_PSTREE].fd, &e, err); + write_ptr_safe(cr_fdset->fds[CR_FD_PSTREE], &e, err); pr_info("Children:"); for (i = 0; i < item->nr_children; i++) { pr_info(" %d", item->children[i]); - write_ptr_safe(cr_fdset->desc[CR_FD_PSTREE].fd, + write_ptr_safe(cr_fdset->fds[CR_FD_PSTREE], &item->children[i], err); } pr_info("\n"); @@ -879,7 +879,7 @@ static int dump_pstree(pid_t pid, struct list_head *pstree_list, struct cr_fdset pr_info("Threads:\n"); for (i = 0; i < item->nr_threads; i++) { pr_info(" %d", item->threads[i]); - write_ptr_safe(cr_fdset->desc[CR_FD_PSTREE].fd, + write_ptr_safe(cr_fdset->fds[CR_FD_PSTREE], &item->threads[i], err); } pr_info("\n"); @@ -906,8 +906,8 @@ static struct vma_area *find_vma_by_addr(struct list_head *vma_area_list, unsign static int append_thread_core(struct cr_fdset *dst, struct cr_fdset *src) { const int size = sizeof(struct core_entry); - int fd_core_dst = dst->desc[CR_FD_CORE].fd; - int fd_code_src = src->desc[CR_FD_CORE].fd; + int fd_core_dst = dst->fds[CR_FD_CORE]; + int fd_code_src = src->fds[CR_FD_CORE]; int ret = -1; lseek(fd_core_dst, 0, SEEK_END); @@ -937,9 +937,9 @@ static int finalize_core(pid_t pid, struct list_head *vma_area_list, struct cr_f pr_info("Finalizing core (pid: %d)\n", pid); pr_info("----------------------------------------\n"); - fd_core = cr_fdset->desc[CR_FD_CORE].fd; - fd_pages = cr_fdset->desc[CR_FD_PAGES].fd; - fd_pages_shmem = cr_fdset->desc[CR_FD_PAGES_SHMEM].fd; + fd_core = cr_fdset->fds[CR_FD_CORE]; + fd_pages = cr_fdset->fds[CR_FD_PAGES]; + fd_pages_shmem = cr_fdset->fds[CR_FD_PAGES_SHMEM]; lseek(fd_core, GET_FILE_OFF_AFTER(struct core_entry), SEEK_SET); lseek(fd_pages, MAGIC_OFFSET, SEEK_SET); @@ -1043,7 +1043,7 @@ err_strno: static int dump_task_thread(pid_t pid, struct cr_fdset *cr_fdset) { struct core_entry *core = xzalloc(sizeof(*core)); - int fd_core = cr_fdset->desc[CR_FD_CORE].fd; + int fd_core = cr_fdset->fds[CR_FD_CORE]; int ret = -1; pr_info("\n"); @@ -1224,17 +1224,17 @@ int cr_dump_tasks(pid_t pid, struct cr_options *opts) list_for_each_entry(item, &pstree_list, list) { - cr_fdset = alloc_cr_fdset(item->pid); + cr_fdset = alloc_cr_fdset(); if (!cr_fdset) goto err; if (item->pid == pid) { - if (prep_cr_fdset_for_dump(cr_fdset, CR_FD_DESC_ALL)) + if (prep_cr_fdset_for_dump(cr_fdset, item->pid, CR_FD_DESC_ALL)) goto err; if (dump_pstree(pid, &pstree_list, cr_fdset)) goto err; } else { - if (prep_cr_fdset_for_dump(cr_fdset, CR_FD_DESC_NOPSTREE)) + if (prep_cr_fdset_for_dump(cr_fdset, item->pid, CR_FD_DESC_NOPSTREE)) goto err; } @@ -1249,11 +1249,12 @@ int cr_dump_tasks(pid_t pid, struct cr_options *opts) if (item->pid == item->threads[i]) continue; - cr_fdset_thread = alloc_cr_fdset(item->threads[i]); + cr_fdset_thread = alloc_cr_fdset(); if (!cr_fdset_thread) goto err; - if (prep_cr_fdset_for_dump(cr_fdset_thread, CR_FD_DESC_CORE)) + if (prep_cr_fdset_for_dump(cr_fdset_thread, + item->threads[i], CR_FD_DESC_CORE)) goto err; if (dump_task_thread(item->threads[i], cr_fdset_thread)) diff --git a/cr-show.c b/cr-show.c index 4e25b8a56..8b24f5bf2 100644 --- a/cr-show.c +++ b/cr-show.c @@ -427,7 +427,7 @@ err: static int collect_pstree(struct list_head *head, pid_t pid, struct cr_fdset *cr_fdset) { - int fd = cr_fdset->desc[CR_FD_PSTREE].fd; + int fd = cr_fdset->fds[CR_FD_PSTREE]; struct pstree_item *item = NULL; struct pstree_entry e; int ret = -1; @@ -497,11 +497,11 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts) LIST_HEAD(pstree_list); int i, ret = -1; - cr_fdset = alloc_cr_fdset(pid); + cr_fdset = alloc_cr_fdset(); if (!cr_fdset) goto out; - ret = prep_cr_fdset_for_restore(cr_fdset, + ret = prep_cr_fdset_for_restore(cr_fdset, pid, CR_FD_DESC_USE(CR_FD_PSTREE)); if (ret) goto out; @@ -514,24 +514,24 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts) * Yeah, I know we read the same file for second * time here, but this saves us from code duplication. */ - lseek(cr_fdset->desc[CR_FD_PSTREE].fd, MAGIC_OFFSET, SEEK_SET); - show_pstree(cr_fdset->desc[CR_FD_PSTREE].fd); + lseek(cr_fdset->fds[CR_FD_PSTREE], MAGIC_OFFSET, SEEK_SET); + show_pstree(cr_fdset->fds[CR_FD_PSTREE]); close_cr_fdset(cr_fdset); free_cr_fdset(&cr_fdset); list_for_each_entry(item, &pstree_list, list) { - cr_fdset = alloc_cr_fdset(item->pid); + cr_fdset = alloc_cr_fdset(); if (!cr_fdset) goto out; - ret = prep_cr_fdset_for_restore(cr_fdset, CR_FD_DESC_NOPSTREE); + ret = prep_cr_fdset_for_restore(cr_fdset, item->pid, CR_FD_DESC_NOPSTREE); if (ret) goto out; - lseek(cr_fdset->desc[CR_FD_CORE].fd, MAGIC_OFFSET, SEEK_SET); - show_core(cr_fdset->desc[CR_FD_CORE].fd, opts->show_pages_content); + 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) { struct cr_fdset *cr_fdset_th; @@ -542,11 +542,12 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts) if (item->threads[i] == item->pid) continue; - cr_fdset_th = alloc_cr_fdset(item->threads[i]); + cr_fdset_th = alloc_cr_fdset(); if (!cr_fdset) goto out; - ret = prep_cr_fdset_for_restore(cr_fdset_th, CR_FD_DESC_CORE); + ret = prep_cr_fdset_for_restore(cr_fdset_th, + item->threads[i], CR_FD_DESC_CORE); if (ret) goto out; @@ -554,8 +555,8 @@ 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->desc[CR_FD_CORE].fd, MAGIC_OFFSET, SEEK_SET); - show_core(cr_fdset_th->desc[CR_FD_CORE].fd, opts->show_pages_content); + 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"); @@ -564,15 +565,15 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts) } } - show_pipes(cr_fdset->desc[CR_FD_PIPES].fd); + show_pipes(cr_fdset->fds[CR_FD_PIPES]); - show_files(cr_fdset->desc[CR_FD_FDINFO].fd); + show_files(cr_fdset->fds[CR_FD_FDINFO]); - show_shmem(cr_fdset->desc[CR_FD_SHMEM].fd); + show_shmem(cr_fdset->fds[CR_FD_SHMEM]); - show_sigacts(cr_fdset->desc[CR_FD_SIGACT].fd); + show_sigacts(cr_fdset->fds[CR_FD_SIGACT]); - show_unixsk(cr_fdset->desc[CR_FD_UNIXSK].fd); + show_unixsk(cr_fdset->fds[CR_FD_UNIXSK]); close_cr_fdset(cr_fdset); free_cr_fdset(&cr_fdset); diff --git a/crtools.c b/crtools.c index 17050d21c..f9418ff63 100644 --- a/crtools.c +++ b/crtools.c @@ -87,36 +87,24 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = { }, }; -struct cr_fdset *alloc_cr_fdset(pid_t pid) +struct cr_fdset *alloc_cr_fdset(void) { struct cr_fdset *cr_fdset; unsigned int i; - int ret; - cr_fdset = xzalloc(sizeof(*cr_fdset)); - if (!cr_fdset) - goto err; - - for (i = 0; i < CR_FD_MAX; i++) { - ret = get_image_path(cr_fdset->desc[i].path, - sizeof(cr_fdset->desc[i].path), - fdset_template[i].fmt, pid); - if (ret) { - xfree(cr_fdset); - return NULL; - } - cr_fdset->desc[i].fd = -1; - } - -err: + cr_fdset = xmalloc(sizeof(*cr_fdset)); + if (cr_fdset) + for (i = 0; i < CR_FD_MAX; i++) + cr_fdset->fds[i] = -1; return cr_fdset; } -int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset, +int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset, int pid, unsigned long use_mask) { unsigned int i; int ret = -1; + char path[PATH_MAX]; if (!cr_fdset) goto err; @@ -125,40 +113,39 @@ int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset, if (!(use_mask & CR_FD_DESC_USE(i))) continue; - ret = unlink(cr_fdset->desc[i].path); - if (ret && errno != ENOENT) { - pr_perror("Unable to unlink %s (%s)\n", - cr_fdset->desc[i].path, - strerror(errno)); + ret = get_image_path(path, sizeof(path), + fdset_template[i].fmt, pid); + if (ret) goto err; - } else - ret = -1; - cr_fdset->desc[i].fd = open(cr_fdset->desc[i].path, - O_RDWR | O_CREAT | O_EXCL, - CR_FD_PERM); - if (cr_fdset->desc[i].fd < 0) { - pr_perror("Unable to open %s (%s)\n", - cr_fdset->desc[i].path, - strerror(errno)); + + ret = unlink(path); + if (ret && errno != ENOENT) { + pr_perror("Unable to unlink %s (%s)\n", path, strerror(errno)); + goto err; + } + + ret = open(path, O_RDWR | O_CREAT | O_EXCL, CR_FD_PERM); + if (ret < 0) { + pr_perror("Unable to open %s (%s)\n", path, strerror(errno)); goto err; } - pr_debug("Opened %s with %d\n", - cr_fdset->desc[i].path, - cr_fdset->desc[i].fd); - - write_ptr_safe(cr_fdset->desc[i].fd, &fdset_template[i].magic, err); + pr_debug("Opened %s with %d\n", path, ret); + write_ptr_safe(ret, &fdset_template[i].magic, err); + cr_fdset->fds[i] = ret; } + ret = 0; err: return ret; } -int prep_cr_fdset_for_restore(struct cr_fdset *cr_fdset, +int prep_cr_fdset_for_restore(struct cr_fdset *cr_fdset, int pid, unsigned long use_mask) { unsigned int i; int ret = -1; + char path[PATH_MAX]; u32 magic; if (!cr_fdset) @@ -168,27 +155,28 @@ int prep_cr_fdset_for_restore(struct cr_fdset *cr_fdset, if (!(use_mask & CR_FD_DESC_USE(i))) continue; - cr_fdset->desc[i].fd = open(cr_fdset->desc[i].path, - O_RDWR, CR_FD_PERM); - if (cr_fdset->desc[i].fd < 0) { - pr_perror("Unable to open %s (%s)\n", - cr_fdset->desc[i].path, - strerror(errno)); + ret = get_image_path(path, sizeof(path), + fdset_template[i].fmt, pid); + if (ret) + goto err; + + ret = open(path, O_RDWR, CR_FD_PERM); + if (ret < 0) { + pr_perror("Unable to open %s (%s)\n", path, strerror(errno)); goto err; } - pr_debug("Opened %s with %d\n", - cr_fdset->desc[i].path, - cr_fdset->desc[i].fd); - - read_ptr_safe(cr_fdset->desc[i].fd, &magic, err); + pr_debug("Opened %s with %d\n", path, ret); + read_ptr_safe(ret, &magic, err); if (magic != fdset_template[i].magic) { - pr_err("Magic doesn't match for %s\n", - cr_fdset->desc[i].path); + close(ret); + pr_err("Magic doesn't match for %s\n", path); goto err; } + cr_fdset->fds[i] = ret; } + ret = 0; err: return ret; @@ -202,14 +190,12 @@ void close_cr_fdset(struct cr_fdset *cr_fdset) return; for (i = 0; i < CR_FD_MAX; i++) { - if (cr_fdset->desc[i].fd == -1) + if (cr_fdset->fds[i] == -1) continue; - pr_debug("Closed %s with %d\n", - cr_fdset->desc[i].path, - cr_fdset->desc[i].fd); - close(cr_fdset->desc[i].fd); - cr_fdset->desc[i].fd = -1; + pr_debug("Closed %d/%d\n", i, cr_fdset->fds[i]); + close(cr_fdset->fds[i]); + cr_fdset->fds[i] = -1; } } diff --git a/include/crtools.h b/include/crtools.h index 3b1bf4e4b..df78fbb23 100644 --- a/include/crtools.h +++ b/include/crtools.h @@ -70,14 +70,8 @@ extern int open_image_ro_nocheck(const char *fmt, int pid); #define LAST_PID_PATH "/proc/sys/kernel/ns_last_pid" #define LAST_PID_PERM 0666 -/* file descriptors */ -struct cr_fd_desc { - char path[PATH_MAX]; /* the path, based on pid */ - int fd; /* descriptor for open/close */ -}; - struct cr_fdset { - struct cr_fd_desc desc[CR_FD_MAX]; + int fds[CR_FD_MAX]; }; #define CR_FD_DESC_USE(type) ((1 << (type))) @@ -91,10 +85,10 @@ int cr_restore_tasks(pid_t pid, struct cr_options *opts); int cr_show(unsigned long pid, struct cr_options *opts); int convert_to_elf(char *elf_path, int fd_core); -struct cr_fdset *alloc_cr_fdset(pid_t pid); -int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset, +struct cr_fdset *alloc_cr_fdset(void); +int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset, int pid, unsigned long use_mask); -int prep_cr_fdset_for_restore(struct cr_fdset *cr_fdset, +int prep_cr_fdset_for_restore(struct cr_fdset *cr_fdset, int pid, unsigned long use_mask); void close_cr_fdset(struct cr_fdset *cr_fdset); void free_cr_fdset(struct cr_fdset **cr_fdset); diff --git a/parasite-syscall.c b/parasite-syscall.c index ad8489bef..b0d47dbc9 100644 --- a/parasite-syscall.c +++ b/parasite-syscall.c @@ -345,29 +345,22 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f { parasite_args_cmd_dumpsigacts_t parasite_sigacts = { }; - int status, path_len, ret = -1; + int status, ret = -1; pr_info("\n"); pr_info("Dumping sigactions (pid: %d)\n", ctl->pid); pr_info("----------------------------------------\n"); - path_len = strlen(cr_fdset->desc[CR_FD_SIGACT].path); - - if (path_len > sizeof(parasite_sigacts.open_path)) { - pr_panic("Dumping sigactions path is too long (%d while %d allowed)\n", - path_len, sizeof(parasite_sigacts.open_path)); + if (get_image_path(parasite_sigacts.open_path, + sizeof(parasite_sigacts.open_path), + fdset_template[CR_FD_SIGACT].fmt, ctl->pid)) goto out; - } - if (fchmod(cr_fdset->desc[CR_FD_SIGACT].fd, CR_FD_PERM_DUMP)) { + if (fchmod(cr_fdset->fds[CR_FD_SIGACT], CR_FD_PERM_DUMP)) { pr_perror("Can't change permissions on sigactions file\n"); goto out; } - strncpy(parasite_sigacts.open_path, - cr_fdset->desc[CR_FD_SIGACT].path, - sizeof(parasite_sigacts.open_path)); - parasite_sigacts.open_flags = O_WRONLY; parasite_sigacts.open_mode = CR_FD_PERM_DUMP; @@ -376,7 +369,7 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f sizeof(parasite_sigacts)); err: - jerr(fchmod(cr_fdset->desc[CR_FD_SIGACT].fd, CR_FD_PERM), out); + jerr(fchmod(cr_fdset->fds[CR_FD_SIGACT], CR_FD_PERM), out); out: pr_info("----------------------------------------\n"); @@ -397,22 +390,18 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a unsigned long nrpages_dumped = 0; struct vma_area *vma_area; siginfo_t siginfo; - int status, path_len, ret = -1; + int status, ret = -1; pr_info("\n"); pr_info("Dumping pages (type: %d pid: %d)\n", CR_FD_PAGES, ctl->pid); pr_info("----------------------------------------\n"); - path_len = strlen(cr_fdset->desc[CR_FD_PAGES].path); - pr_info("Dumping pages %s\n", cr_fdset->desc[CR_FD_PAGES].path); - - if (path_len > sizeof(parasite_dumppages.open_path)) { - pr_panic("Dumping pages path is too long (%d while %d allowed)\n", - path_len, sizeof(parasite_dumppages.open_path)); + if (get_image_path(parasite_dumppages.open_path, + sizeof(parasite_dumppages.open_path), + fdset_template[CR_FD_PAGES].fmt, ctl->pid)) goto out; - } - if (fchmod(cr_fdset->desc[CR_FD_PAGES].fd, CR_FD_PERM_DUMP)) { + if (fchmod(cr_fdset->fds[CR_FD_PAGES], CR_FD_PERM_DUMP)) { pr_perror("Can't change permissions on pages file\n"); goto out; } @@ -421,11 +410,7 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a * Make sure the data is on disk since we will re-open * it in another process. */ - fsync(cr_fdset->desc[CR_FD_PAGES].fd); - - strncpy(parasite_dumppages.open_path, - cr_fdset->desc[CR_FD_PAGES].path, - sizeof(parasite_dumppages.open_path)); + fsync(cr_fdset->fds[CR_FD_PAGES]); parasite_dumppages.open_flags = O_WRONLY; parasite_dumppages.open_mode = CR_FD_PERM_DUMP; @@ -484,16 +469,16 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a * We don't know the position in file since it's updated * outside of our process. */ - lseek(cr_fdset->desc[CR_FD_PAGES].fd, 0, SEEK_END); + lseek(cr_fdset->fds[CR_FD_PAGES], 0, SEEK_END); /* Ending page */ - write_ptr_safe(cr_fdset->desc[CR_FD_PAGES].fd, &zero_page_entry, err_restore); + write_ptr_safe(cr_fdset->fds[CR_FD_PAGES], &zero_page_entry, err_restore); pr_info("\n"); pr_info("Summary: %16li pages dumped\n", nrpages_dumped); err_restore: - jerr(fchmod(cr_fdset->desc[CR_FD_PAGES].fd, CR_FD_PERM), out); + jerr(fchmod(cr_fdset->fds[CR_FD_PAGES], CR_FD_PERM), out); out: pr_info("----------------------------------------\n"); diff --git a/sockets.c b/sockets.c index 19951482d..b0b8e744c 100644 --- a/sockets.c +++ b/sockets.c @@ -162,8 +162,8 @@ static int dump_one_unix(struct socket_desc *_sk, char *fd, struct cr_fdset *cr_ ue.pad = 0; ue.peer = sk->peer_ino; - write_ptr_safe(cr_fdset->desc[CR_FD_UNIXSK].fd, &ue, err); - write_safe(cr_fdset->desc[CR_FD_UNIXSK].fd, sk->name, ue.namelen, err); + write_ptr_safe(cr_fdset->fds[CR_FD_UNIXSK], &ue, err); + write_safe(cr_fdset->fds[CR_FD_UNIXSK], sk->name, ue.namelen, err); pr_info("Dumping unix socket at %s\n", fd); show_one_unix("Dumping", sk);