diff --git a/cgroup.c b/cgroup.c index 97538a8fe..f22efc402 100644 --- a/cgroup.c +++ b/cgroup.c @@ -1300,19 +1300,20 @@ static int rewrite_cgroup_roots(CgroupEntry *cge) int prepare_cgroup(void) { - int fd, ret; + int ret; + struct cr_img *img; CgroupEntry *ce; - fd = open_image(CR_FD_CGROUP, O_RSTR | O_OPT); - if (fd < 0) { + img = open_image(CR_FD_CGROUP, O_RSTR | O_OPT); + if (!img) { if (errno == ENOENT) /* backward compatibility */ return 0; else return -1; } - ret = pb_read_one_eof(fd, &ce, PB_CGROUP); - close(fd); + ret = pb_read_one_eof(img, &ce, PB_CGROUP); + close_image(img); if (ret <= 0) /* Zero is OK -- no sets there. */ return ret; diff --git a/cr-dedup.c b/cr-dedup.c index 77586742f..b6191375a 100644 --- a/cr-dedup.c +++ b/cr-dedup.c @@ -125,7 +125,7 @@ int punch_hole(struct page_read *pr, unsigned long off, unsigned long len, } else { if (bunch->iov_len > 0) { pr_debug("Punch!/%p/%zu/\n", bunch->iov_base, bunch->iov_len); - ret = fallocate(pr->fd_pg, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + ret = fallocate(img_raw_fd(pr->pi), FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, (unsigned long)bunch->iov_base, bunch->iov_len); if (ret != 0) { pr_perror("Error punching hole"); @@ -169,7 +169,7 @@ int dedup_one_iovec(struct page_read *pr, struct iovec *iov) return -1; pagemap2iovec(pr->pe, &piov); piov_end = (unsigned long)piov.iov_base + piov.iov_len; - off_real = lseek(pr->fd_pg, 0, SEEK_CUR); + off_real = lseek(img_raw_fd(pr->pi), 0, SEEK_CUR); if (!pr->pe->in_parent) { ret = punch_hole(pr, off_real, min(piov_end, iov_end) - off, false); if (ret == -1) diff --git a/cr-dump.c b/cr-dump.c index 101a1781e..04c18fa01 100644 --- a/cr-dump.c +++ b/cr-dump.c @@ -693,7 +693,7 @@ static int dump_task_core_all(struct pstree_item *item, const struct parasite_dump_misc *misc, const struct cr_imgset *cr_imgset) { - int fd_core = img_from_set(cr_imgset, CR_FD_CORE); + struct cr_img *img; CoreEntry *core = item->core[0]; pid_t pid = item->pid.real; int ret = -1; @@ -724,7 +724,8 @@ static int dump_task_core_all(struct pstree_item *item, if (ret) goto err; - ret = pb_write_one(fd_core, core, PB_CORE); + img = img_from_set(cr_imgset, CR_FD_CORE); + ret = pb_write_one(img, core, PB_CORE); if (ret < 0) goto err; @@ -1088,7 +1089,8 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl, struct pid *tid = &item->threads[id]; CoreEntry *core = item->core[id]; pid_t pid = tid->real; - int ret = -1, fd_core; + int ret = -1; + struct cr_img *img; pr_info("\n"); pr_info("Dumping core for thread (pid: %d)\n", pid); @@ -1100,13 +1102,13 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl, goto err; } - fd_core = open_image(CR_FD_CORE, O_DUMP, tid->virt); - if (fd_core < 0) + img = open_image(CR_FD_CORE, O_DUMP, tid->virt); + if (!img) goto err; - ret = pb_write_one(fd_core, core, PB_CORE); + ret = pb_write_one(img, core, PB_CORE); - close(fd_core); + close_image(img); err: pr_info("----------------------------------------\n"); return ret; @@ -1116,7 +1118,8 @@ static int dump_one_zombie(const struct pstree_item *item, const struct proc_pid_stat *pps) { CoreEntry *core; - int ret = -1, fd_core; + int ret = -1; + struct cr_img *img; core = core_entry_alloc(0, 1); if (!core) @@ -1126,12 +1129,12 @@ static int dump_one_zombie(const struct pstree_item *item, core->tc->task_state = TASK_DEAD; core->tc->exit_code = pps->exit_code; - fd_core = open_image(CR_FD_CORE, O_DUMP, item->pid.virt); - if (fd_core < 0) + img = open_image(CR_FD_CORE, O_DUMP, item->pid.virt); + if (!img) goto err; - ret = pb_write_one(fd_core, core, PB_CORE); - close(fd_core); + ret = pb_write_one(img, core, PB_CORE); + close_image(img); err: core_entry_free(core); return ret; diff --git a/cr-restore.c b/cr-restore.c index 099911622..4c9308c38 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -633,7 +633,7 @@ static int prepare_sigactions(void) { int pid = current->pid.virt; rt_sigaction_t act; - int fd_sigact; + struct cr_img *img; SaEntry *e; int sig, rst = 0; int ret = 0; @@ -643,15 +643,15 @@ static int prepare_sigactions(void) pr_info("Restore sigacts for %d\n", pid); - fd_sigact = open_image(CR_FD_SIGACT, O_RSTR, pid); - if (fd_sigact < 0) + img = open_image(CR_FD_SIGACT, O_RSTR, pid); + if (!img) return -1; for (sig = 1; sig <= SIGMAX; sig++) { if (sig == SIGKILL || sig == SIGSTOP) continue; - ret = pb_read_one_eof(fd_sigact, &e, PB_SIGACT); + ret = pb_read_one_eof(img, &e, PB_SIGACT); if (ret == 0) { if (sig != SIGMAX_OLD + 1) { /* backward compatibility */ pr_err("Unexpected EOF %d\n", sig); @@ -697,7 +697,7 @@ static int prepare_sigactions(void) SIGMAX - 3 /* KILL, STOP and CHLD */); err: - close_safe(&fd_sigact); + close_image(img); return ret; } @@ -731,7 +731,7 @@ static int collect_helper_pids() static int open_cores(int pid, CoreEntry *leader_core) { - int fd = -1, i, tpid; + int i, tpid; CoreEntry **cores = NULL; cores = xmalloc(sizeof(*cores)*current->nr_threads); @@ -744,16 +744,20 @@ static int open_cores(int pid, CoreEntry *leader_core) if (tpid == pid) cores[i] = leader_core; else { - fd = open_image(CR_FD_CORE, O_RSTR, tpid); - if (fd < 0) { + struct cr_img *img; + + img = open_image(CR_FD_CORE, O_RSTR, tpid); + if (!img) { pr_err("Can't open core data for thread %d\n", tpid); goto err; } - if (pb_read_one(fd, &cores[i], PB_CORE) <= 0) + if (pb_read_one(img, &cores[i], PB_CORE) <= 0) { + close_image(img); goto err; + } - close(fd); + close_image(img); } } @@ -762,7 +766,6 @@ static int open_cores(int pid, CoreEntry *leader_core) return 0; err: xfree(cores); - close_safe(&fd); return -1; } @@ -1001,16 +1004,18 @@ static void maybe_clone_parent(struct pstree_item *item, static inline int fork_with_pid(struct pstree_item *item) { struct cr_clone_arg ca; - int ret = -1, fd; + int ret = -1; pid_t pid = item->pid.virt; if (item->state != TASK_HELPER) { - fd = open_image(CR_FD_CORE, O_RSTR, pid); - if (fd < 0) + struct cr_img *img; + + img = open_image(CR_FD_CORE, O_RSTR, pid); + if (!img) return -1; - ret = pb_read_one(fd, &ca.core, PB_CORE); - close(fd); + ret = pb_read_one(img, &ca.core, PB_CORE); + close_image(img); if (ret < 0) return -1; @@ -1979,14 +1984,15 @@ static inline int decode_itimer(char *n, ItimerEntry *ie, struct itimerval *val) static int prepare_itimers_from_fd(int pid, struct task_restore_args *args) { - int fd, ret = -1; + int ret = -1; + struct cr_img *img; ItimerEntry *ie; - fd = open_image(CR_FD_ITIMERS, O_RSTR, pid); - if (fd < 0) + img = open_image(CR_FD_ITIMERS, O_RSTR, pid); + if (!img) return -1; - ret = pb_read_one(fd, &ie, PB_ITIMER); + ret = pb_read_one(img, &ie, PB_ITIMER); if (ret < 0) goto out; ret = decode_itimer("real", ie, &args->itimers[0]); @@ -1994,7 +2000,7 @@ static int prepare_itimers_from_fd(int pid, struct task_restore_args *args) if (ret < 0) goto out; - ret = pb_read_one(fd, &ie, PB_ITIMER); + ret = pb_read_one(img, &ie, PB_ITIMER); if (ret < 0) goto out; ret = decode_itimer("virt", ie, &args->itimers[1]); @@ -2002,7 +2008,7 @@ static int prepare_itimers_from_fd(int pid, struct task_restore_args *args) if (ret < 0) goto out; - ret = pb_read_one(fd, &ie, PB_ITIMER); + ret = pb_read_one(img, &ie, PB_ITIMER); if (ret < 0) goto out; ret = decode_itimer("prof", ie, &args->itimers[2]); @@ -2010,7 +2016,7 @@ static int prepare_itimers_from_fd(int pid, struct task_restore_args *args) if (ret < 0) goto out; out: - close_safe(&fd); + close_image(img); return ret; } @@ -2100,12 +2106,12 @@ static void sort_posix_timers(void) static int prepare_posix_timers_from_fd(int pid) { - int fd = -1; + struct cr_img *img; int ret = -1; struct restore_posix_timer *t; - fd = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid); - if (fd < 0) { + img = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid); + if (!img) { if (errno == ENOENT) /* backward compatibility */ return 0; else @@ -2115,7 +2121,7 @@ static int prepare_posix_timers_from_fd(int pid) while (1) { PosixTimerEntry *pte; - ret = pb_read_one_eof(fd, &pte, PB_POSIX_TIMER); + ret = pb_read_one_eof(img, &pte, PB_POSIX_TIMER); if (ret <= 0) break; @@ -2131,7 +2137,7 @@ static int prepare_posix_timers_from_fd(int pid) posix_timers_nr++; } - close_safe(&fd); + close_image(img); if (!ret) sort_posix_timers(); @@ -2173,15 +2179,16 @@ static inline int verify_cap_size(CredsEntry *ce) static int prepare_creds(int pid, struct task_restore_args *args) { - int fd, ret; + int ret; + struct cr_img *img; CredsEntry *ce; - fd = open_image(CR_FD_CREDS, O_RSTR, pid); - if (fd < 0) + img = open_image(CR_FD_CREDS, O_RSTR, pid); + if (!img) return -1; - ret = pb_read_one(fd, &ce, PB_CREDS); - close_safe(&fd); + ret = pb_read_one(img, &ce, PB_CREDS); + close_image(img); if (ret < 0) return ret; @@ -2347,13 +2354,14 @@ static unsigned int rlims_nr; static int prepare_rlimits_from_fd(int pid) { struct rlimit *r; - int fd, ret; + int ret; + struct cr_img *img; /* * Old image -- read from the file. */ - fd = open_image(CR_FD_RLIMIT, O_RSTR | O_OPT, pid); - if (fd < 0) { + img = open_image(CR_FD_RLIMIT, O_RSTR | O_OPT, pid); + if (!img) { if (errno == ENOENT) { pr_info("Skip rlimits for %d\n", pid); return 0; @@ -2365,7 +2373,7 @@ static int prepare_rlimits_from_fd(int pid) while (1) { RlimitEntry *re; - ret = pb_read_one_eof(fd, &re, PB_RLIMIT); + ret = pb_read_one_eof(img, &re, PB_RLIMIT); if (ret <= 0) break; @@ -2389,7 +2397,7 @@ static int prepare_rlimits_from_fd(int pid) rlims_nr++; } - close(fd); + close_image(img); return 0; } @@ -2441,10 +2449,11 @@ static int signal_to_mem(SiginfoEntry *sie) static int open_signal_image(int type, pid_t pid, unsigned int *nr) { - int fd, ret; + int ret; + struct cr_img *img; - fd = open_image(type, O_RSTR | O_OPT, pid); - if (fd < 0) { + img = open_image(type, O_RSTR | O_OPT, pid); + if (!img) { if (errno == ENOENT) /* backward compatibility */ return 0; else @@ -2455,7 +2464,7 @@ static int open_signal_image(int type, pid_t pid, unsigned int *nr) while (1) { SiginfoEntry *sie; - ret = pb_read_one_eof(fd, &sie, PB_SIGINFO); + ret = pb_read_one_eof(img, &sie, PB_SIGINFO); if (ret <= 0) break; if (sie->siginfo.len != sizeof(siginfo_t)) { @@ -2473,7 +2482,7 @@ static int open_signal_image(int type, pid_t pid, unsigned int *nr) siginfo_entry__free_unpacked(sie, NULL); } - close(fd); + close_image(img); return ret ? : 0; } diff --git a/cr-show.c b/cr-show.c index 0de92ba2e..dc85502f9 100644 --- a/cr-show.c +++ b/cr-show.c @@ -37,10 +37,10 @@ static LIST_HEAD(pstree_list); -static void pipe_data_handler(int fd, void *obj) +static void pipe_data_handler(struct cr_img *img, void *obj) { PipeDataEntry *e = obj; - print_image_data(fd, e->bytes, opts.show_pages_content); + print_image_data(img, e->bytes, opts.show_pages_content); } static int nice_width_for(unsigned long addr) @@ -115,13 +115,13 @@ void print_data(unsigned long addr, unsigned char *data, size_t size) } } -void print_image_data(int fd, unsigned int length, int show) +void print_image_data(struct cr_img *img, unsigned int length, int show) { void *data; int ret; if (!show) { - lseek(fd, length, SEEK_CUR); + lseek(img_raw_fd(img), length, SEEK_CUR); return; } @@ -130,7 +130,7 @@ void print_image_data(int fd, unsigned int length, int show) data = xmalloc(length); if (!data) return; - ret = read_img_buf(fd, (unsigned char *)data, length); + ret = read_img_buf(img, (unsigned char *)data, length); if (ret < 0) { xfree(data); return; @@ -139,12 +139,12 @@ void print_image_data(int fd, unsigned int length, int show) xfree(data); } -static void show_pagemaps(int fd, void *obj) +static void show_pagemaps(struct cr_img *img, void *obj) { - pb_show_plain_pretty(fd, PB_PAGEMAP, "nr_pages:%u"); + pb_show_plain_pretty(img, PB_PAGEMAP, "nr_pages:%u"); } -void show_siginfo(int fd) +void show_siginfo(struct cr_img *img) { int ret; @@ -153,7 +153,7 @@ void show_siginfo(int fd) SiginfoEntry *sie; siginfo_t *info; - ret = pb_read_one_eof(fd, &sie, PB_SIGINFO); + ret = pb_read_one_eof(img, &sie, PB_SIGINFO); if (ret <= 0) break; @@ -182,7 +182,7 @@ static int pstree_item_from_pb(PstreeEntry *e, struct pstree_item *item) return 0; } -static void pstree_handler(int fd, void *obj) +static void pstree_handler(struct cr_img *img, void *obj) { PstreeEntry *e = obj; struct pstree_item *item = NULL; @@ -199,9 +199,9 @@ static void pstree_handler(int fd, void *obj) list_add_tail(&item->sibling, &pstree_list); } -void show_collect_pstree(int fd, int collect) +static void show_collect_pstree(struct cr_img *img, int collect) { - pb_show_plain_payload_pretty(fd, PB_PSTREE, + pb_show_plain_payload_pretty(img, PB_PSTREE, collect ? pstree_handler : NULL, "*:%d"); } @@ -349,6 +349,7 @@ static int cr_parse_file(void) { u32 magic; int ret = -1, fd; + struct cr_img *img = NULL; fd = open(opts.show_dump_file, O_RDONLY); if (fd < 0) { @@ -356,26 +357,33 @@ static int cr_parse_file(void) goto out; } - if (read_img(fd, &magic) < 0) + img = img_from_fd(fd); + if (!img) goto out; - ret = cr_parse_fd(fd, magic); + if (read_img(img, &magic) < 0) + goto out; + + ret = cr_parse_fd(img, magic); out: - close_safe(&fd); + if (img) + close_image(img); + else + close_safe(&fd); return ret; } -int cr_parse_fd(int fd, u32 magic) +int cr_parse_fd(struct cr_img *img, u32 magic) { int ret = 0, i; if (magic == PSTREE_MAGIC) { - show_collect_pstree(fd, 0); + show_collect_pstree(img, 0); goto out; } if (magic == SIGNAL_MAGIC || magic == PSIGNAL_MAGIC) { - show_siginfo(fd); + show_siginfo(img); goto out; } @@ -386,7 +394,7 @@ int cr_parse_fd(int fd, u32 magic) if (si->magic != magic) continue; - do_pb_show_plain(fd, si->pb_type, si->single, + do_pb_show_plain(img, si->pb_type, si->single, si->payload, si->fmt); goto out; } @@ -403,6 +411,7 @@ out: static int cr_show_pstree_item(struct pstree_item *item) { int ret = -1, i; + struct cr_img *img; struct cr_imgset *cr_imgset = NULL; TaskKobjIdsEntry *ids; @@ -416,22 +425,20 @@ static int cr_show_pstree_item(struct pstree_item *item) cr_parse_fd(img_from_set(cr_imgset, CR_FD_CORE), CORE_MAGIC); if (item->nr_threads > 1) { - int fd_th; - for (i = 0; i < item->nr_threads; i++) { if (item->threads[i].virt == item->pid.virt) continue; - fd_th = open_image(CR_FD_CORE, O_SHOW, item->threads[i].virt); - if (fd_th < 0) + img = open_image(CR_FD_CORE, O_SHOW, item->threads[i].virt); + if (!img) goto outc; pr_msg("Thread %d.%d:\n", item->pid.virt, item->threads[i].virt); pr_msg("----------------------------------------\n"); - cr_parse_fd(fd_th, CORE_MAGIC); - close_safe(&fd_th); + cr_parse_fd(img, CORE_MAGIC); + close_image(img); } } @@ -445,25 +452,25 @@ static int cr_show_pstree_item(struct pstree_item *item) cr_parse_fd(img_from_set(cr_imgset, i), imgset_template[i].magic); } - i = open_image(CR_FD_RLIMIT, O_SHOW | O_OPT, item->pid.virt); - if (i >= 0) { + img = open_image(CR_FD_RLIMIT, O_SHOW | O_OPT, item->pid.virt); + if (img) { pr_msg("* "); pr_msg(imgset_template[CR_FD_RLIMIT].fmt, item->pid.virt); pr_msg(":\n"); - cr_parse_fd(i, RLIMIT_MAGIC); - close(i); + cr_parse_fd(img, RLIMIT_MAGIC); + close_image(img); } if (pb_read_one(img_from_set(cr_imgset, CR_FD_IDS), &ids, PB_IDS) > 0) { - i = open_image(CR_FD_FDINFO, O_SHOW, ids->files_id); - if (i >= 0) { + img = open_image(CR_FD_FDINFO, O_SHOW, ids->files_id); + if (img) { pr_msg("* "); pr_msg(imgset_template[CR_FD_FDINFO].fmt, ids->files_id); pr_msg(":\n"); - cr_parse_fd(i, FDINFO_MAGIC); - close(i); + cr_parse_fd(img, FDINFO_MAGIC); + close_image(img); } task_kobj_ids_entry__free_unpacked(ids, NULL); @@ -480,19 +487,20 @@ out: static int cr_show_pid(int pid) { - int fd, ret; + int ret; + struct cr_img *img; struct pstree_item item; - fd = open_image(CR_FD_PSTREE, O_SHOW); - if (fd < 0) + img = open_image(CR_FD_PSTREE, O_SHOW); + if (!img) return -1; while (1) { PstreeEntry *pe; - ret = pb_read_one_eof(fd, &pe, PB_PSTREE); + ret = pb_read_one_eof(img, &pe, PB_PSTREE); if (ret <= 0) { - close(fd); + close_image(img); return ret; } @@ -505,7 +513,7 @@ static int cr_show_pid(int pid) pstree_entry__free_unpacked(pe, NULL); } - close(fd); + close_image(img); return cr_show_pstree_item(&item); } @@ -513,19 +521,14 @@ static int cr_show_pid(int pid) static int cr_show_all(void) { struct pstree_item *item = NULL, *tmp; - int ret = -1, fd, pid; + int ret = -1, pid; + struct cr_img *img; - fd = open_image(CR_FD_PSTREE, O_SHOW); - if (fd < 0) + img = open_image(CR_FD_PSTREE, O_SHOW); + if (!img) goto out; - show_collect_pstree(fd, 1); - close(fd); - - fd = open_image(CR_FD_SK_QUEUES, O_SHOW); - if (fd < 0) - goto out; - - close(fd); + show_collect_pstree(img, 1); + close_image(img); pid = list_first_entry(&pstree_list, struct pstree_item, sibling)->pid.virt; ret = try_show_namespaces(pid); diff --git a/fifo.c b/fifo.c index af85088cc..bd06da9c1 100644 --- a/fifo.c +++ b/fifo.c @@ -41,7 +41,7 @@ static struct pipe_data_dump pd_fifo = { .img_type = CR_FD_FIFO_DATA, }; static int dump_one_fifo(int lfd, u32 id, const struct fd_parms *p) { - int img = img_from_set(glob_imgset, CR_FD_FIFO); + struct cr_img *img = img_from_set(glob_imgset, CR_FD_FIFO); FifoEntry e = FIFO_ENTRY__INIT; /* diff --git a/file-lock.c b/file-lock.c index f97beae35..210e67cd9 100644 --- a/file-lock.c +++ b/file-lock.c @@ -338,11 +338,12 @@ static int restore_file_locks(int pid) static int restore_file_locks_legacy(int pid) { - int fd, ret = -1; + int ret = -1; + struct cr_img *img; FileLockEntry *fle; - fd = open_image(CR_FD_FILE_LOCKS_PID, O_RSTR | O_OPT, pid); - if (fd < 0) { + img = open_image(CR_FD_FILE_LOCKS_PID, O_RSTR | O_OPT, pid); + if (!img) { if (errno == ENOENT) return 0; else @@ -350,7 +351,7 @@ static int restore_file_locks_legacy(int pid) } while (1) { - ret = pb_read_one_eof(fd, &fle, PB_FILE_LOCK); + ret = pb_read_one_eof(img, &fle, PB_FILE_LOCK); if (ret <= 0) break; @@ -360,7 +361,7 @@ static int restore_file_locks_legacy(int pid) break; } - close_safe(&fd); + close_image(img); return ret; } diff --git a/files-ext.c b/files-ext.c index e0b30e412..b196b2590 100644 --- a/files-ext.c +++ b/files-ext.c @@ -11,7 +11,8 @@ static int dump_one_ext_file(int lfd, u32 id, const struct fd_parms *p) { - int rfd, ret; + int ret; + struct cr_img *rimg; ExtFileEntry xfe = EXT_FILE_ENTRY__INIT; @@ -22,9 +23,8 @@ static int dump_one_ext_file(int lfd, u32 id, const struct fd_parms *p) xfe.id = id; xfe.fown = (FownEntry *)&p->fown; - rfd = img_from_set(glob_imgset, CR_FD_EXT_FILES); - - return pb_write_one(rfd, &xfe, PB_EXT_FILE); + rimg = img_from_set(glob_imgset, CR_FD_EXT_FILES); + return pb_write_one(rimg, &xfe, PB_EXT_FILE); } const struct fdtype_ops ext_dump_ops = { @@ -79,11 +79,11 @@ struct collect_image_info ext_file_cinfo = { }; int dump_unsupp_fd(struct fd_parms *p, int lfd, - const int fdinfo, char *more, char *info) + struct cr_img *img, char *more, char *info) { int ret; - ret = do_dump_gen_file(p, lfd, &ext_dump_ops, fdinfo); + ret = do_dump_gen_file(p, lfd, &ext_dump_ops, img); if (ret == 0) return 0; if (ret == -ENOTSUP) diff --git a/files-reg.c b/files-reg.c index 26117f54a..98c71e9f9 100644 --- a/files-reg.c +++ b/files-reg.c @@ -69,7 +69,7 @@ static LIST_HEAD(link_remaps); */ #define MAX_GHOST_FILE_SIZE (1 * 1024 * 1024) -static int create_ghost(struct ghost_file *gf, GhostFileEntry *gfe, char *root, int ifd) +static int create_ghost(struct ghost_file *gf, GhostFileEntry *gfe, char *root, struct cr_img *img) { int gfd, ghost_flags, ret = -1; char path[PATH_MAX]; @@ -113,7 +113,7 @@ static int create_ghost(struct ghost_file *gf, GhostFileEntry *gfe, char *root, } if (S_ISREG(gfe->mode)) { - if (copy_file(ifd, gfd, 0) < 0) + if (copy_file(img_raw_fd(img), gfd, 0) < 0) goto err_c; } @@ -129,7 +129,7 @@ static int open_remap_ghost(struct reg_file_info *rfi, { struct ghost_file *gf; GhostFileEntry *gfe = NULL; - int ifd; + struct cr_img *img; char *root; list_for_each_entry(gf, &ghost_files, list) @@ -158,11 +158,11 @@ static int open_remap_ghost(struct reg_file_info *rfi, if (!gf->remap.path) goto err; - ifd = open_image(CR_FD_GHOST_FILE, O_RSTR, rfe->remap_id); - if (ifd < 0) + img = open_image(CR_FD_GHOST_FILE, O_RSTR, rfe->remap_id); + if (!img) goto err; - if (pb_read_one(ifd, &gfe, PB_GHOST_FILE) < 0) + if (pb_read_one(img, &gfe, PB_GHOST_FILE) < 0) goto close_ifd; /* @@ -175,11 +175,11 @@ static int open_remap_ghost(struct reg_file_info *rfi, snprintf(gf->remap.path, PATH_MAX, "%s.cr.%x.ghost", rfi->path, rfe->remap_id); - if (create_ghost(gf, gfe, root, ifd)) + if (create_ghost(gf, gfe, root, img)) goto close_ifd; ghost_file_entry__free_unpacked(gfe, NULL); - close(ifd); + close_image(img); gf->id = rfe->remap_id; gf->remap.users = 0; @@ -190,7 +190,7 @@ gf_found: return 0; close_ifd: - close_safe(&ifd); + close_image(img); err: if (gfe) ghost_file_entry__free_unpacked(gfe, NULL); @@ -314,7 +314,7 @@ struct collect_image_info remap_cinfo = { static int dump_ghost_file(int _fd, u32 id, const struct stat *st, dev_t phys_dev) { - int img; + struct cr_img *img; GhostFileEntry gfe = GHOST_FILE_ENTRY__INIT; pr_info("Dumping ghost file contents (id %#x)\n", id); @@ -353,13 +353,13 @@ static int dump_ghost_file(int _fd, u32 id, const struct stat *st, dev_t phys_de pr_perror("Can't open ghost original file"); return -1; } - ret = copy_file(fd, img, st->st_size); + ret = copy_file(fd, img_raw_fd(img), st->st_size); close(fd); if (ret) return -1; } - close(img); + close_image(img); return 0; } @@ -740,7 +740,7 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p) { struct fd_link _link, *link; struct ns_id *nsid; - int rfd; + struct cr_img *rimg; RegFileEntry rfe = REG_FILE_ENTRY__INIT; @@ -787,9 +787,8 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p) rfe.size = p->stat.st_size; } - rfd = img_from_set(glob_imgset, CR_FD_REG_FILES); - - return pb_write_one(rfd, &rfe, PB_REG_FILE); + rimg = img_from_set(glob_imgset, CR_FD_REG_FILES); + return pb_write_one(rimg, &rfe, PB_REG_FILE); } const struct fdtype_ops regfile_dump_ops = { diff --git a/files.c b/files.c index 45ac8d405..42425a25e 100644 --- a/files.c +++ b/files.c @@ -163,7 +163,7 @@ static u32 make_gen_id(const struct fd_parms *p) } int do_dump_gen_file(struct fd_parms *p, int lfd, - const struct fdtype_ops *ops, const int fdinfo) + const struct fdtype_ops *ops, struct cr_img *img) { FdinfoEntry e = FDINFO_ENTRY__INIT; int ret = -1; @@ -183,7 +183,7 @@ int do_dump_gen_file(struct fd_parms *p, int lfd, pr_info("fdinfo: type: 0x%2x flags: %#o/%#o pos: 0x%8"PRIx64" fd: %d\n", ops->type, p->flags, (int)p->fd_flags, p->pos, p->fd); - return pb_write_one(fdinfo, &e, PB_FDINFO); + return pb_write_one(img, &e, PB_FDINFO); } int fill_fdlink(int lfd, const struct fd_parms *p, struct fd_link *link) @@ -264,7 +264,7 @@ static const struct fdtype_ops *get_misc_dev_ops(int minor) return NULL; } -static int dump_chrdev(struct fd_parms *p, int lfd, const int fdinfo) +static int dump_chrdev(struct fd_parms *p, int lfd, struct cr_img *img) { int maj = major(p->stat.st_rdev); const struct fdtype_ops *ops; @@ -287,15 +287,15 @@ static int dump_chrdev(struct fd_parms *p, int lfd, const int fdinfo) char more[32]; sprintf(more, "%d:%d", maj, minor(p->stat.st_rdev)); - return dump_unsupp_fd(p, lfd, fdinfo, "chr", more); + return dump_unsupp_fd(p, lfd, img, "chr", more); } } - return do_dump_gen_file(p, lfd, ops, fdinfo); + return do_dump_gen_file(p, lfd, ops, img); } static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_opts *opts, - const int fdinfo) + struct cr_img *img) { struct fd_parms p = FD_PARMS_INIT; const struct fdtype_ops *ops; @@ -309,10 +309,10 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op return -1; if (S_ISSOCK(p.stat.st_mode)) - return dump_socket(&p, lfd, fdinfo); + return dump_socket(&p, lfd, img); if (S_ISCHR(p.stat.st_mode)) - return dump_chrdev(&p, lfd, fdinfo); + return dump_chrdev(&p, lfd, img); if (p.fs_type == ANON_INODE_FS_MAGIC) { char link[32]; @@ -333,9 +333,9 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op else if (is_timerfd_link(link)) ops = &timerfd_dump_ops; else - return dump_unsupp_fd(&p, lfd, fdinfo, "anon", link); + return dump_unsupp_fd(&p, lfd, img, "anon", link); - return do_dump_gen_file(&p, lfd, ops, fdinfo); + return do_dump_gen_file(&p, lfd, ops, img); } if (S_ISREG(p.stat.st_mode) || S_ISDIR(p.stat.st_mode)) { @@ -346,12 +346,12 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op p.link = &link; if (link.name[1] == '/') - return do_dump_gen_file(&p, lfd, ®file_dump_ops, fdinfo); + return do_dump_gen_file(&p, lfd, ®file_dump_ops, img); if (check_ns_proc(&link)) - return do_dump_gen_file(&p, lfd, &nsfile_dump_ops, fdinfo); + return do_dump_gen_file(&p, lfd, &nsfile_dump_ops, img); - return dump_unsupp_fd(&p, lfd, fdinfo, "reg", link.name + 1); + return dump_unsupp_fd(&p, lfd, img, "reg", link.name + 1); } if (S_ISFIFO(p.stat.st_mode)) { @@ -360,16 +360,17 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op else ops = &fifo_dump_ops; - return do_dump_gen_file(&p, lfd, ops, fdinfo); + return do_dump_gen_file(&p, lfd, ops, img); } - return dump_unsupp_fd(&p, lfd, fdinfo, "unknown", NULL); + return dump_unsupp_fd(&p, lfd, img, "unknown", NULL); } int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, struct parasite_drain_fd *dfds) { - int *lfds, fdinfo; + int *lfds; + struct cr_img *img; struct fd_opts *opts; int i, ret = -1; @@ -389,18 +390,18 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, if (ret) goto err2; - fdinfo = open_image(CR_FD_FDINFO, O_DUMP, item->ids->files_id); - if (fdinfo < 0) + img = open_image(CR_FD_FDINFO, O_DUMP, item->ids->files_id); + if (!img) goto err2; for (i = 0; i < dfds->nr_fds; i++) { - ret = dump_one_file(ctl, dfds->fds[i], lfds[i], opts + i, fdinfo); + ret = dump_one_file(ctl, dfds->fds[i], lfds[i], opts + i, img); close(lfds[i]); if (ret) break; } - close(fdinfo); + close_image(img); pr_info("----------------------------------------\n"); err2: @@ -587,7 +588,8 @@ int prepare_ctl_tty(int pid, struct rst_info *rst_info, u32 ctl_tty_id) int prepare_fd_pid(struct pstree_item *item) { - int fdinfo_fd, ret = 0; + int ret = 0; + struct cr_img *img; pid_t pid = item->pid.virt; struct rst_info *rst_info = item->rst; @@ -596,8 +598,8 @@ int prepare_fd_pid(struct pstree_item *item) INIT_LIST_HEAD(&rst_info->tty_slaves); if (!fdinfo_per_id) { - fdinfo_fd = open_image(CR_FD_FDINFO, O_RSTR | O_OPT, pid); - if (fdinfo_fd < 0) { + img = open_image(CR_FD_FDINFO, O_RSTR | O_OPT, pid); + if (!img) { if (errno == ENOENT) return 0; return -1; @@ -609,15 +611,15 @@ int prepare_fd_pid(struct pstree_item *item) if (item->rst->fdt && item->rst->fdt->pid != item->pid.virt) return 0; - fdinfo_fd = open_image(CR_FD_FDINFO, O_RSTR, item->ids->files_id); - if (fdinfo_fd < 0) + img = open_image(CR_FD_FDINFO, O_RSTR, item->ids->files_id); + if (!img) return -1; } while (1) { FdinfoEntry *e; - ret = pb_read_one_eof(fdinfo_fd, &e, PB_FDINFO); + ret = pb_read_one_eof(img, &e, PB_FDINFO); if (ret <= 0) break; @@ -628,7 +630,7 @@ int prepare_fd_pid(struct pstree_item *item) } } - close(fdinfo_fd); + close_image(img); return ret; } @@ -1083,21 +1085,21 @@ int prepare_fs_pid(struct pstree_item *item) { pid_t pid = item->pid.virt; struct rst_info *ri = item->rst; - int ifd; + struct cr_img *img; FsEntry *fe; - ifd = open_image(CR_FD_FS, O_RSTR | O_OPT, pid); - if (ifd < 0) { + img = open_image(CR_FD_FS, O_RSTR | O_OPT, pid); + if (!img) { if (errno == ENOENT) goto ok; else goto out; } - if (pb_read_one(ifd, &fe, PB_FS) < 0) + if (pb_read_one(img, &fe, PB_FS) < 0) goto out_i; - close(ifd); + close_image(img); ri->cwd = collect_special_file(fe->cwd_id); if (!ri->cwd) { @@ -1123,7 +1125,7 @@ out_f: return -1; out_i: - close(ifd); + close_image(img); out: return -1; } diff --git a/image.c b/image.c index b9a8e4ae6..e7f8b8648 100644 --- a/image.c +++ b/image.c @@ -19,14 +19,15 @@ u32 root_cg_set; int check_img_inventory(void) { - int fd, ret = -1; + int ret = -1; + struct cr_img *img; InventoryEntry *he; - fd = open_image(CR_FD_INVENTORY, O_RSTR); - if (fd < 0) + img = open_image(CR_FD_INVENTORY, O_RSTR); + if (!img) return -1; - if (pb_read_one(fd, &he, PB_INVENTORY) < 0) + if (pb_read_one(img, &he, PB_INVENTORY) < 0) goto out_close; fdinfo_per_id = he->has_fdinfo_per_id ? he->fdinfo_per_id : false; @@ -58,20 +59,20 @@ int check_img_inventory(void) out_err: inventory_entry__free_unpacked(he, NULL); out_close: - close(fd); + close_image(img); return ret; } int write_img_inventory(void) { - int fd; + struct cr_img *img; InventoryEntry he = INVENTORY_ENTRY__INIT; struct pstree_item crt = { }; pr_info("Writing image inventory (version %u)\n", CRTOOLS_IMAGES_V1); - fd = open_image(CR_FD_INVENTORY, O_DUMP); - if (fd < 0) + img = open_image(CR_FD_INVENTORY, O_DUMP); + if (!img) return -1; he.img_version = CRTOOLS_IMAGES_V1; @@ -83,7 +84,7 @@ int write_img_inventory(void) crt.state = TASK_ALIVE; crt.pid.real = getpid(); if (get_task_ids(&crt)) { - close(fd); + close_image(img); return -1; } @@ -93,11 +94,11 @@ int write_img_inventory(void) he.root_ids = crt.ids; - if (pb_write_one(fd, &he, PB_INVENTORY) < 0) + if (pb_write_one(img, &he, PB_INVENTORY) < 0) return -1; xfree(crt.ids); - close(fd); + close_image(img); return 0; } @@ -116,14 +117,14 @@ static struct cr_imgset *alloc_cr_imgset(int nr) if (cr_imgset == NULL) return NULL; - cr_imgset->_imgs = xmalloc(nr * sizeof(int)); + cr_imgset->_imgs = xmalloc(nr * sizeof(struct cr_img *)); if (cr_imgset->_imgs == NULL) { xfree(cr_imgset); return NULL; } for (i = 0; i < nr; i++) - cr_imgset->_imgs[i] = -1; + cr_imgset->_imgs[i] = NULL; cr_imgset->fd_nr = nr; return cr_imgset; } @@ -136,10 +137,10 @@ static void __close_cr_imgset(struct cr_imgset *cr_imgset) return; for (i = 0; i < cr_imgset->fd_nr; i++) { - if (cr_imgset->_imgs[i] == -1) + if (!cr_imgset->_imgs[i]) continue; - close_safe(&cr_imgset->_imgs[i]); - cr_imgset->_imgs[i] = -1; + close_image(cr_imgset->_imgs[i]); + cr_imgset->_imgs[i] = NULL; } } @@ -160,7 +161,6 @@ struct cr_imgset *cr_imgset_open_range(int pid, int from, int to, { struct cr_imgset *imgset; unsigned int i; - int ret = -1; imgset = alloc_cr_imgset(to - from); if (!imgset) @@ -169,15 +169,17 @@ struct cr_imgset *cr_imgset_open_range(int pid, int from, int to, from++; imgset->fd_off = from; for (i = from; i < to; i++) { - ret = open_image(i, flags, pid); - if (ret < 0) { + struct cr_img *img; + + img = open_image(i, flags, pid); + if (!img) { if (!(flags & O_CREAT)) /* caller should check himself */ continue; goto err; } - imgset->_imgs[i - from] = ret; + imgset->_imgs[i - from] = img; } return imgset; @@ -197,13 +199,18 @@ struct cr_imgset *cr_glob_imgset_open(int mode) return cr_imgset_open(-1 /* ignored */, GLOB, mode); } -int open_image_at(int dfd, int type, unsigned long flags, ...) +struct cr_img *open_image_at(int dfd, int type, unsigned long flags, ...) { + struct cr_img *img; unsigned long oflags = flags; char path[PATH_MAX]; va_list args; int ret; + img = xmalloc(sizeof(*img)); + if (!img) + goto errn; + flags &= ~O_OPT; va_start(args, flags); @@ -212,33 +219,56 @@ int open_image_at(int dfd, int type, unsigned long flags, ...) ret = openat(dfd, path, flags, CR_FD_PERM); if (ret < 0) { - if ((oflags & O_OPT) && errno == ENOENT) - return -ENOENT; + if ((oflags & O_OPT) && errno == ENOENT) { + xfree(img); + return NULL; + } + pr_perror("Unable to open %s", path); goto err; } + img->_fd = ret; if (imgset_template[type].magic == RAW_IMAGE_MAGIC) goto skip_magic; if (flags == O_RDONLY) { u32 magic; - if (read_img(ret, &magic) < 0) + if (read_img(img, &magic) < 0) goto err; if (magic != imgset_template[type].magic) { pr_err("Magic doesn't match for %s\n", path); goto err; } } else { - if (write_img(ret, &imgset_template[type].magic)) + if (write_img(img, &imgset_template[type].magic)) goto err; } skip_magic: - return ret; + return img; + err: - return -1; + xfree(img); +errn: + return NULL; +} + +void close_image(struct cr_img *img) +{ + close(img->_fd); + xfree(img); +} + +struct cr_img *img_from_fd(int fd) +{ + struct cr_img *img; + + img = xmalloc(sizeof(*img)); + if (img) + img->_fd = fd; + return img; } int open_image_dir(char *dir) @@ -291,29 +321,29 @@ void up_page_ids_base(void) page_ids += 0x10000; } -int open_pages_image_at(int dfd, unsigned long flags, int pm_fd) +struct cr_img *open_pages_image_at(int dfd, unsigned long flags, struct cr_img *pmi) { unsigned id; if (flags == O_RDONLY || flags == O_RDWR) { PagemapHead *h; - if (pb_read_one(pm_fd, &h, PB_PAGEMAP_HEAD) < 0) - return -1; + if (pb_read_one(pmi, &h, PB_PAGEMAP_HEAD) < 0) + return NULL; id = h->pages_id; pagemap_head__free_unpacked(h, NULL); } else { PagemapHead h = PAGEMAP_HEAD__INIT; id = h.pages_id = page_ids++; - if (pb_write_one(pm_fd, &h, PB_PAGEMAP_HEAD) < 0) - return -1; + if (pb_write_one(pmi, &h, PB_PAGEMAP_HEAD) < 0) + return NULL; } return open_image_at(dfd, CR_FD_PAGES, flags, id); } -int open_pages_image(unsigned long flags, int pm_fd) +struct cr_img *open_pages_image(unsigned long flags, struct cr_img *pmi) { - return open_pages_image_at(get_service_fd(IMG_FD_OFF), flags, pm_fd); + return open_pages_image_at(get_service_fd(IMG_FD_OFF), flags, pmi); } /* @@ -322,9 +352,11 @@ int open_pages_image(unsigned long flags, int pm_fd) * 0 on success * -1 on error (error message is printed) */ -int write_img_buf(int fd, const void *ptr, int size) +int write_img_buf(struct cr_img *img, const void *ptr, int size) { + int fd = img->_fd; int ret; + ret = write(fd, ptr, size); if (ret == size) return 0; @@ -343,9 +375,11 @@ int write_img_buf(int fd, const void *ptr, int size) * 0 on EOF (silently) * -1 on error (error message is printed) */ -int read_img_buf_eof(int fd, void *ptr, int size) +int read_img_buf_eof(struct cr_img *img, void *ptr, int size) { + int fd = img->_fd; int ret; + ret = read(fd, ptr, size); if (ret == size) return 1; @@ -365,11 +399,11 @@ int read_img_buf_eof(int fd, void *ptr, int size) * 1 on success * -1 on error or EOF (error message is printed) */ -int read_img_buf(int fd, void *ptr, int size) +int read_img_buf(struct cr_img *img, void *ptr, int size) { int ret; - ret = read_img_buf_eof(fd, ptr, size); + ret = read_img_buf_eof(img, ptr, size); if (ret == 0) { pr_err("Unexpected EOF\n"); ret = -1; @@ -383,7 +417,7 @@ int read_img_buf(int fd, void *ptr, int size) * the buffer and puts the '\0' at the end */ -int read_img_str(int fd, char **pstr, int size) +int read_img_str(struct cr_img *img, char **pstr, int size) { int ret; char *str; @@ -392,7 +426,7 @@ int read_img_str(int fd, char **pstr, int size) if (!str) return -1; - ret = read_img_buf(fd, str, size); + ret = read_img_buf(img, str, size); if (ret < 0) { xfree(str); return -1; diff --git a/include/cr-show.h b/include/cr-show.h index 165f87a81..6ebdb4c2a 100644 --- a/include/cr-show.h +++ b/include/cr-show.h @@ -4,20 +4,22 @@ #include #include "asm/types.h" +struct cr_img; + struct show_image_info { u32 magic; int pb_type; bool single; - void (*payload)(int, void *); + void (*payload)(struct cr_img *, void *); char *fmt; }; -extern void show_siginfo(int fd); -extern void sk_queue_data_handler(int fd, void *obj); -extern void ipc_shm_handler(int fd, void *obj); -extern void ipc_msg_handler(int fd, void *obj); -extern void ipc_sem_handler(int fd, void *obj); -extern int cr_parse_fd(int fd, u32 magic); -extern void show_tcp_stream(int fd, void *obj); +extern void show_siginfo(struct cr_img *); +extern void sk_queue_data_handler(struct cr_img *, void *obj); +extern void ipc_shm_handler(struct cr_img *, void *obj); +extern void ipc_msg_handler(struct cr_img *, void *obj); +extern void ipc_sem_handler(struct cr_img *, void *obj); +extern int cr_parse_fd(struct cr_img *, u32 magic); +extern void show_tcp_stream(struct cr_img *, void *obj); #endif /* __CR_SHOW_H__ */ diff --git a/include/files.h b/include/files.h index 012a0eceb..07167cbc0 100644 --- a/include/files.h +++ b/include/files.h @@ -125,9 +125,11 @@ struct fdtype_ops { int (*pre_dump)(int pid, int lfd); }; +struct cr_img; + extern int do_dump_gen_file(struct fd_parms *p, int lfd, const struct fdtype_ops *ops, - const int fdinfo); + struct cr_img *); struct parasite_drain_fd; int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, struct parasite_drain_fd *dfds); @@ -163,6 +165,6 @@ extern int shared_fdt_prepare(struct pstree_item *item); extern struct collect_image_info ext_file_cinfo; extern int dump_unsupp_fd(struct fd_parms *p, int lfd, - const int fdinfo, char *more, char *info); + struct cr_img *, char *more, char *info); #endif /* __CR_FILES_H__ */ diff --git a/include/image.h b/include/image.h index e6bdebdd4..ee6ca7e42 100644 --- a/include/image.h +++ b/include/image.h @@ -74,21 +74,34 @@ extern bool ns_per_id; #define O_RSTR (O_RDONLY) #define O_OPT (O_PATH) +struct cr_img { + int _fd; +}; + +static inline int img_raw_fd(struct cr_img *img) +{ + return img->_fd; +} + extern int open_image_dir(char *dir); extern void close_image_dir(void); -extern int open_image_at(int dfd, int type, unsigned long flags, ...); +extern struct cr_img *open_image_at(int dfd, int type, unsigned long flags, ...); #define open_image(typ, flags, ...) open_image_at(get_service_fd(IMG_FD_OFF), typ, flags, ##__VA_ARGS__) -extern int open_pages_image(unsigned long flags, int pm_fd); -extern int open_pages_image_at(int dfd, unsigned long flags, int pm_fd); +extern struct cr_img *open_pages_image(unsigned long flags, struct cr_img *pmi); +extern struct cr_img *open_pages_image_at(int dfd, unsigned long flags, struct cr_img *pmi); extern void up_page_ids_base(void); -extern int write_img_buf(int fd, const void *ptr, int size); -#define write_img(fd, ptr) write_img_buf((fd), (ptr), sizeof(*(ptr))) -extern int read_img_buf_eof(int fd, void *ptr, int size); -#define read_img_eof(fd, ptr) read_img_buf_eof((fd), (ptr), sizeof(*(ptr))) -extern int read_img_buf(int fd, void *ptr, int size); -#define read_img(fd, ptr) read_img_buf((fd), (ptr), sizeof(*(ptr))) -extern int read_img_str(int fd, char **pstr, int size); +extern struct cr_img *img_from_fd(int fd); /* for cr-show mostly */ + +extern int write_img_buf(struct cr_img *, const void *ptr, int size); +#define write_img(img, ptr) write_img_buf((img), (ptr), sizeof(*(ptr))) +extern int read_img_buf_eof(struct cr_img *, void *ptr, int size); +#define read_img_eof(img, ptr) read_img_buf_eof((img), (ptr), sizeof(*(ptr))) +extern int read_img_buf(struct cr_img *, void *ptr, int size); +#define read_img(img, ptr) read_img_buf((img), (ptr), sizeof(*(ptr))) +extern int read_img_str(struct cr_img *, char **pstr, int size); + +extern void close_image(struct cr_img *); #endif /* __CR_IMAGE_H__ */ diff --git a/include/imgset.h b/include/imgset.h index 13c6168bb..04be917e2 100644 --- a/include/imgset.h +++ b/include/imgset.h @@ -3,14 +3,15 @@ #include "image-desc.h" #include "bug.h" +#include "image.h" struct cr_imgset { int fd_off; int fd_nr; - int *_imgs; + struct cr_img **_imgs; }; -static inline int img_from_set(const struct cr_imgset *imgset, int type) +static inline struct cr_img *img_from_set(const struct cr_imgset *imgset, int type) { int idx; diff --git a/include/log.h b/include/log.h index 45303de55..cc59870b0 100644 --- a/include/log.h +++ b/include/log.h @@ -24,8 +24,10 @@ extern int write_pidfile(int pid); #define DEFAULT_LOG_FILENAME "criu.log" +struct cr_img; + extern void print_data(unsigned long addr, unsigned char *data, size_t size); -extern void print_image_data(int fd, unsigned int length, int show); +extern void print_image_data(struct cr_img *, unsigned int length, int show); static inline int pr_quelled(unsigned int loglevel) { diff --git a/include/page-read.h b/include/page-read.h index 64a85794e..df967bdcd 100644 --- a/include/page-read.h +++ b/include/page-read.h @@ -53,8 +53,8 @@ struct page_read { void (*close)(struct page_read *); /* Private data of reader */ - int fd; - int fd_pg; + struct cr_img *pmi; + struct cr_img *pi; PagemapEntry *pe; /* current pagemap we are on */ struct page_read *parent; /* parent pagemap (if ->in_parent diff --git a/include/page-xfer.h b/include/page-xfer.h index d90093204..b50065d99 100644 --- a/include/page-xfer.h +++ b/include/page-xfer.h @@ -20,11 +20,18 @@ struct page_xfer { void (*close)(struct page_xfer *self); /* private data for every page-xfer engine */ - int fd; union { - int fd_pg; - u64 dst_id; + struct /* local */ { + struct cr_img *pmi; /* pagemaps */ + struct cr_img *pi; /* pages */ + }; + + struct /* page-server */ { + int sk; + u64 dst_id; + }; }; + struct page_read *parent; }; diff --git a/include/protobuf.h b/include/protobuf.h index 025cb6d51..83b24c65f 100644 --- a/include/protobuf.h +++ b/include/protobuf.h @@ -7,12 +7,14 @@ #include "compiler.h" #include "util.h" -extern int do_pb_read_one(int fd, void **objp, int type, bool eof); +struct cr_img; + +extern int do_pb_read_one(struct cr_img *, void **objp, int type, bool eof); #define pb_read_one(fd, objp, type) do_pb_read_one(fd, (void **)objp, type, false) #define pb_read_one_eof(fd, objp, type) do_pb_read_one(fd, (void **)objp, type, true) -extern int pb_write_one(int fd, void *obj, int type); +extern int pb_write_one(struct cr_img *, void *obj, int type); #define pb_pksize(__obj, __proto_message_name) \ (__proto_message_name ##__get_packed_size(__obj) + sizeof(u32)) @@ -25,8 +27,8 @@ extern int pb_write_one(int fd, void *obj, int type); #include -extern void do_pb_show_plain(int fd, int type, int single_entry, - void (*payload_hadler)(int fd, void *obj), +extern void do_pb_show_plain(struct cr_img *, int type, int single_entry, + void (*payload_hadler)(struct cr_img *, void *obj), const char *pretty_fmt); /* Don't have objects at hands to also do typechecking here */ diff --git a/include/sockets.h b/include/sockets.h index 34fb1672a..3a2fe81ea 100644 --- a/include/sockets.h +++ b/include/sockets.h @@ -14,6 +14,7 @@ struct file_desc; struct fd_parms; struct cr_imgset; struct nlmsghdr; +struct cr_img; struct socket_desc { unsigned int family; @@ -22,7 +23,7 @@ struct socket_desc { int already_dumped; }; -extern int dump_socket(struct fd_parms *p, int lfd, const int fdinfo); +extern int dump_socket(struct fd_parms *p, int lfd, struct cr_img *); extern int dump_socket_opts(int sk, SkOptsEntry *soe); extern int restore_socket_opts(int sk, SkOptsEntry *soe); extern void release_skopts(SkOptsEntry *); diff --git a/ipc_ns.c b/ipc_ns.c index 7ad04a4cd..8ac429840 100644 --- a/ipc_ns.c +++ b/ipc_ns.c @@ -70,7 +70,7 @@ static void pr_info_ipc_sem_entry(const IpcSemEntry *sem) print_on_level(LOG_INFO, "nsems: %-10d\n", sem->nsems); } -static int dump_ipc_sem_set(int fd, const IpcSemEntry *sem) +static int dump_ipc_sem_set(struct cr_img *img, const IpcSemEntry *sem) { size_t rounded; int ret, size; @@ -93,7 +93,7 @@ static int dump_ipc_sem_set(int fd, const IpcSemEntry *sem) pr_info_ipc_sem_array(sem->nsems, values); memzero((void *)values + size, rounded - size); - ret = write_img_buf(fd, values, rounded); + ret = write_img_buf(img, values, rounded); if (ret < 0) { pr_err("Failed to write IPC message data\n"); goto out; @@ -103,7 +103,7 @@ out: return ret; } -static int dump_ipc_sem_desc(int fd, int id, const struct semid_ds *ds) +static int dump_ipc_sem_desc(struct cr_img *img, int id, const struct semid_ds *ds) { IpcSemEntry sem = IPC_SEM_ENTRY__INIT; IpcDescEntry desc = IPC_DESC_ENTRY__INIT; @@ -115,15 +115,15 @@ static int dump_ipc_sem_desc(int fd, int id, const struct semid_ds *ds) fill_ipc_desc(id, sem.desc, &ds->sem_perm); pr_info_ipc_sem_entry(&sem); - ret = pb_write_one(fd, &sem, PB_IPC_SEM); + ret = pb_write_one(img, &sem, PB_IPC_SEM); if (ret < 0) { pr_err("Failed to write IPC semaphores set\n"); return ret; } - return dump_ipc_sem_set(fd, &sem); + return dump_ipc_sem_set(img, &sem); } -static int dump_ipc_sem(int fd) +static int dump_ipc_sem(struct cr_img *img) { int i, maxid; struct seminfo info; @@ -147,7 +147,7 @@ static int dump_ipc_sem(int fd) pr_perror("Failed to get stats for IPC semaphore set"); break; } - ret = dump_ipc_sem_desc(fd, id, &ds); + ret = dump_ipc_sem_desc(img, id, &ds); if (!ret) slot++; } @@ -171,7 +171,7 @@ static void pr_info_ipc_msg_entry(const IpcMsgEntry *msg) msg->qbytes, msg->qnum); } -static int dump_ipc_msg_queue_messages(int fd, const IpcMsgEntry *msq, +static int dump_ipc_msg_queue_messages(struct cr_img *img, const IpcMsgEntry *msq, unsigned int msg_nr) { struct msgbuf *message = NULL; @@ -210,7 +210,7 @@ static int dump_ipc_msg_queue_messages(int fd, const IpcMsgEntry *msq, pr_info_ipc_msg(msg_cnt, &msg); - ret = pb_write_one(fd, &msg, PB_IPCNS_MSG); + ret = pb_write_one(img, &msg, PB_IPCNS_MSG); if (ret < 0) { pr_err("Failed to write IPC message header\n"); break; @@ -218,7 +218,7 @@ static int dump_ipc_msg_queue_messages(int fd, const IpcMsgEntry *msq, rounded = round_up(msg.msize, sizeof(u64)); memzero(((void *)message->mtext + msg.msize), rounded - msg.msize); - ret = write_img_buf(fd, message->mtext, rounded); + ret = write_img_buf(img, message->mtext, rounded); if (ret < 0) { pr_err("Failed to write IPC message data\n"); break; @@ -230,7 +230,7 @@ err: return ret; } -static int dump_ipc_msg_queue(int fd, int id, const struct msqid_ds *ds) +static int dump_ipc_msg_queue(struct cr_img *img, int id, const struct msqid_ds *ds) { IpcMsgEntry msg = IPC_MSG_ENTRY__INIT; IpcDescEntry desc = IPC_DESC_ENTRY__INIT; @@ -243,15 +243,15 @@ static int dump_ipc_msg_queue(int fd, int id, const struct msqid_ds *ds) pr_info_ipc_msg_entry(&msg); - ret = pb_write_one(fd, &msg, PB_IPCNS_MSG_ENT); + ret = pb_write_one(img, &msg, PB_IPCNS_MSG_ENT); if (ret < 0) { pr_err("Failed to write IPC message queue\n"); return ret; } - return dump_ipc_msg_queue_messages(fd, &msg, ds->msg_qnum); + return dump_ipc_msg_queue_messages(img, &msg, ds->msg_qnum); } -static int dump_ipc_msg(int fd) +static int dump_ipc_msg(struct cr_img *img) { int i, maxid; struct msginfo info; @@ -275,7 +275,7 @@ static int dump_ipc_msg(int fd) pr_perror("Failed to get stats for IPC message queue"); break; } - ret = dump_ipc_msg_queue(fd, id, &ds); + ret = dump_ipc_msg_queue(img, id, &ds); if (!ret) slot++; } @@ -332,7 +332,7 @@ static int ipc_sysctl_req(IpcVarEntry *e, int op) * TODO: Function below should be later improved to locate and dump only dirty * pages via updated sys_mincore(). */ -static int dump_ipc_shm_pages(int fd, const IpcShmEntry *shm) +static int dump_ipc_shm_pages(struct cr_img *img, const IpcShmEntry *shm) { void *data; int ret; @@ -342,7 +342,7 @@ static int dump_ipc_shm_pages(int fd, const IpcShmEntry *shm) pr_perror("Failed to attach IPC shared memory"); return -errno; } - ret = write_img_buf(fd, data, round_up(shm->size, sizeof(u32))); + ret = write_img_buf(img, data, round_up(shm->size, sizeof(u32))); if (ret < 0) { pr_err("Failed to write IPC shared memory data\n"); return ret; @@ -354,7 +354,7 @@ static int dump_ipc_shm_pages(int fd, const IpcShmEntry *shm) return 0; } -static int dump_ipc_shm_seg(int fd, int id, const struct shmid_ds *ds) +static int dump_ipc_shm_seg(struct cr_img *img, int id, const struct shmid_ds *ds) { IpcShmEntry shm = IPC_SHM_ENTRY__INIT; IpcDescEntry desc = IPC_DESC_ENTRY__INIT; @@ -365,15 +365,15 @@ static int dump_ipc_shm_seg(int fd, int id, const struct shmid_ds *ds) fill_ipc_desc(id, shm.desc, &ds->shm_perm); pr_info_ipc_shm(&shm); - ret = pb_write_one(fd, &shm, PB_IPC_SHM); + ret = pb_write_one(img, &shm, PB_IPC_SHM); if (ret < 0) { pr_err("Failed to write IPC shared memory segment\n"); return ret; } - return dump_ipc_shm_pages(fd, &shm); + return dump_ipc_shm_pages(img, &shm); } -static int dump_ipc_shm(int fd) +static int dump_ipc_shm(struct cr_img *img) { int i, maxid, slot; struct shm_info info; @@ -397,7 +397,7 @@ static int dump_ipc_shm(int fd) break; } - ret = dump_ipc_shm_seg(fd, id, &ds); + ret = dump_ipc_shm_seg(img, id, &ds); if (ret < 0) return ret; slot++; @@ -410,7 +410,7 @@ static int dump_ipc_shm(int fd) return 0; } -static int dump_ipc_var(int fd) +static int dump_ipc_var(struct cr_img *img) { IpcVarEntry var = IPC_VAR_ENTRY__INIT; int ret = -1; @@ -426,7 +426,7 @@ static int dump_ipc_var(int fd) goto err; } - ret = pb_write_one(fd, &var, PB_IPC_VAR); + ret = pb_write_one(img, &var, PB_IPC_VAR); if (ret < 0) { pr_err("Failed to write IPC variables\n"); goto err; @@ -480,7 +480,7 @@ err: return ret < 0 ? -1 : 0; } -void ipc_sem_handler(int fd, void *obj) +void ipc_sem_handler(struct cr_img *img, void *obj) { IpcSemEntry *e = obj; u16 *values; @@ -491,37 +491,37 @@ void ipc_sem_handler(int fd, void *obj) values = xmalloc(size); if (values == NULL) return; - if (read_img_buf(fd, values, size) <= 0) { + if (read_img_buf(img, values, size) <= 0) { xfree(values); return; } pr_msg_ipc_sem_array(e->nsems, values); } -static void ipc_msg_data_handler(int fd, void *obj) +static void ipc_msg_data_handler(struct cr_img *img, void *obj) { IpcMsg *e = obj; - print_image_data(fd, round_up(e->msize, sizeof(u64)), opts.show_pages_content); + print_image_data(img, round_up(e->msize, sizeof(u64)), opts.show_pages_content); } -void ipc_msg_handler(int fd, void *obj) +void ipc_msg_handler(struct cr_img *img, void *obj) { IpcMsgEntry *e = obj; int msg_nr = 0; pr_msg("\n"); while (msg_nr++ < e->qnum) - pb_show_plain_payload(fd, PB_IPCNS_MSG, ipc_msg_data_handler); + pb_show_plain_payload(img, PB_IPCNS_MSG, ipc_msg_data_handler); } -void ipc_shm_handler(int fd, void *obj) +void ipc_shm_handler(struct cr_img *img, void *obj) { IpcShmEntry *e = obj; - print_image_data(fd, round_up(e->size, sizeof(u32)), opts.show_pages_content); + print_image_data(img, round_up(e->size, sizeof(u32)), opts.show_pages_content); } -static int prepare_ipc_sem_values(int fd, const IpcSemEntry *sem) +static int prepare_ipc_sem_values(struct cr_img *img, const IpcSemEntry *sem) { int ret, size; u16 *values; @@ -534,7 +534,7 @@ static int prepare_ipc_sem_values(int fd, const IpcSemEntry *sem) goto out; } - ret = read_img_buf(fd, values, size); + ret = read_img_buf(img, values, size); if (ret < 0) { pr_err("Failed to allocate memory for semaphores set values\n"); ret = -ENOMEM; @@ -553,7 +553,7 @@ out: return ret; } -static int prepare_ipc_sem_desc(int fd, const IpcSemEntry *sem) +static int prepare_ipc_sem_desc(struct cr_img *img, const IpcSemEntry *sem) { int ret, id; struct sysctl_req req[] = { @@ -596,7 +596,7 @@ static int prepare_ipc_sem_desc(int fd, const IpcSemEntry *sem) return -EFAULT; } - ret = prepare_ipc_sem_values(fd, sem); + ret = prepare_ipc_sem_values(img, sem); if (ret < 0) { pr_err("Failed to update sem pages\n"); return ret; @@ -606,17 +606,18 @@ static int prepare_ipc_sem_desc(int fd, const IpcSemEntry *sem) static int prepare_ipc_sem(int pid) { - int fd, ret; + int ret; + struct cr_img *img; pr_info("Restoring IPC semaphores sets\n"); - fd = open_image(CR_FD_IPCNS_SEM, O_RSTR, pid); - if (fd < 0) + img = open_image(CR_FD_IPCNS_SEM, O_RSTR, pid); + if (!img) return -1; while (1) { IpcSemEntry *sem; - ret = pb_read_one_eof(fd, &sem, PB_IPC_SEM); + ret = pb_read_one_eof(img, &sem, PB_IPC_SEM); if (ret < 0) { ret = -EIO; goto err; @@ -626,7 +627,7 @@ static int prepare_ipc_sem(int pid) pr_info_ipc_sem_entry(sem); - ret = prepare_ipc_sem_desc(fd, sem); + ret = prepare_ipc_sem_desc(img, sem); ipc_sem_entry__free_unpacked(sem, NULL); if (ret < 0) { @@ -635,13 +636,15 @@ static int prepare_ipc_sem(int pid) } } - return close_safe(&fd); + close_image(img); + return 0; + err: - close_safe(&fd); + close_image(img); return ret; } -static int prepare_ipc_msg_queue_messages(int fd, const IpcMsgEntry *msq) +static int prepare_ipc_msg_queue_messages(struct cr_img *img, const IpcMsgEntry *msq) { IpcMsg *msg = NULL; int msg_nr = 0; @@ -653,7 +656,7 @@ static int prepare_ipc_msg_queue_messages(int fd, const IpcMsgEntry *msq) char mtext[MSGMAX]; } data; - ret = pb_read_one(fd, &msg, PB_IPCNS_MSG); + ret = pb_read_one(img, &msg, PB_IPCNS_MSG); if (ret <= 0) return -EIO; @@ -666,7 +669,7 @@ static int prepare_ipc_msg_queue_messages(int fd, const IpcMsgEntry *msq) break; } - ret = read_img_buf(fd, data.mtext, round_up(msg->msize, sizeof(u64))); + ret = read_img_buf(img, data.mtext, round_up(msg->msize, sizeof(u64))); if (ret < 0) { pr_err("Failed to read IPC message data\n"); break; @@ -687,7 +690,7 @@ static int prepare_ipc_msg_queue_messages(int fd, const IpcMsgEntry *msq) return ret; } -static int prepare_ipc_msg_queue(int fd, const IpcMsgEntry *msq) +static int prepare_ipc_msg_queue(struct cr_img *img, const IpcMsgEntry *msq) { int ret, id; struct sysctl_req req[] = { @@ -729,7 +732,7 @@ static int prepare_ipc_msg_queue(int fd, const IpcMsgEntry *msq) return -EFAULT; } - ret = prepare_ipc_msg_queue_messages(fd, msq); + ret = prepare_ipc_msg_queue_messages(img, msq); if (ret < 0) { pr_err("Failed to update message queue messages\n"); return ret; @@ -739,17 +742,18 @@ static int prepare_ipc_msg_queue(int fd, const IpcMsgEntry *msq) static int prepare_ipc_msg(int pid) { - int fd, ret; + int ret; + struct cr_img *img; pr_info("Restoring IPC message queues\n"); - fd = open_image(CR_FD_IPCNS_MSG, O_RSTR, pid); - if (fd < 0) + img = open_image(CR_FD_IPCNS_MSG, O_RSTR, pid); + if (!img) return -1; while (1) { IpcMsgEntry *msq; - ret = pb_read_one_eof(fd, &msq, PB_IPCNS_MSG_ENT); + ret = pb_read_one_eof(img, &msq, PB_IPCNS_MSG_ENT); if (ret < 0) { pr_err("Failed to read IPC messages queue\n"); ret = -EIO; @@ -760,7 +764,7 @@ static int prepare_ipc_msg(int pid) pr_info_ipc_msg_entry(msq); - ret = prepare_ipc_msg_queue(fd, msq); + ret = prepare_ipc_msg_queue(img, msq); ipc_msg_entry__free_unpacked(msq, NULL); if (ret < 0) { @@ -768,13 +772,15 @@ static int prepare_ipc_msg(int pid) goto err; } } - return close_safe(&fd); + + close_image(img); + return 0; err: - close_safe(&fd); + close_image(img); return ret; } -static int prepare_ipc_shm_pages(int fd, const IpcShmEntry *shm) +static int prepare_ipc_shm_pages(struct cr_img *img, const IpcShmEntry *shm) { int ret; void *data; @@ -784,7 +790,7 @@ static int prepare_ipc_shm_pages(int fd, const IpcShmEntry *shm) pr_perror("Failed to attach IPC shared memory"); return -errno; } - ret = read_img_buf(fd, data, round_up(shm->size, sizeof(u32))); + ret = read_img_buf(img, data, round_up(shm->size, sizeof(u32))); if (ret < 0) { pr_err("Failed to read IPC shared memory data\n"); return ret; @@ -796,7 +802,7 @@ static int prepare_ipc_shm_pages(int fd, const IpcShmEntry *shm) return 0; } -static int prepare_ipc_shm_seg(int fd, const IpcShmEntry *shm) +static int prepare_ipc_shm_seg(struct cr_img *img, const IpcShmEntry *shm) { int ret, id; struct sysctl_req req[] = { @@ -839,7 +845,7 @@ static int prepare_ipc_shm_seg(int fd, const IpcShmEntry *shm) return -EFAULT; } - ret = prepare_ipc_shm_pages(fd, shm); + ret = prepare_ipc_shm_pages(img, shm); if (ret < 0) { pr_err("Failed to update shm pages\n"); return ret; @@ -849,17 +855,18 @@ static int prepare_ipc_shm_seg(int fd, const IpcShmEntry *shm) static int prepare_ipc_shm(int pid) { - int fd, ret; + int ret; + struct cr_img *img; pr_info("Restoring IPC shared memory\n"); - fd = open_image(CR_FD_IPCNS_SHM, O_RSTR, pid); - if (fd < 0) + img = open_image(CR_FD_IPCNS_SHM, O_RSTR, pid); + if (!img) return -1; while (1) { IpcShmEntry *shm; - ret = pb_read_one_eof(fd, &shm, PB_IPC_SHM); + ret = pb_read_one_eof(img, &shm, PB_IPC_SHM); if (ret < 0) { pr_err("Failed to read IPC shared memory segment\n"); ret = -EIO; @@ -870,7 +877,7 @@ static int prepare_ipc_shm(int pid) pr_info_ipc_shm(shm); - ret = prepare_ipc_shm_seg(fd, shm); + ret = prepare_ipc_shm_seg(img, shm); ipc_shm_entry__free_unpacked(shm, NULL); if (ret < 0) { @@ -878,24 +885,27 @@ static int prepare_ipc_shm(int pid) goto err; } } - return close_safe(&fd); + + close_image(img); + return 0; err: - close_safe(&fd); + close_image(img); return ret; } static int prepare_ipc_var(int pid) { - int fd, ret; + int ret; + struct cr_img *img; IpcVarEntry *var; pr_info("Restoring IPC variables\n"); - fd = open_image(CR_FD_IPC_VAR, O_RSTR, pid); - if (fd < 0) + img = open_image(CR_FD_IPC_VAR, O_RSTR, pid); + if (!img) return -1; - ret = pb_read_one(fd, &var, PB_IPC_VAR); - close_safe(&fd); + ret = pb_read_one(img, &var, PB_IPC_VAR); + close_image(img); if (ret <= 0) { pr_err("Failed to read IPC namespace variables\n"); return -EFAULT; diff --git a/irmap.c b/irmap.c index 388e4738b..ab8247e7c 100644 --- a/irmap.c +++ b/irmap.c @@ -298,11 +298,12 @@ int irmap_queue_cache(unsigned int dev, unsigned long ino, int irmap_predump_run(void) { - int ret = 0, fd; + int ret = 0; + struct cr_img *img; struct irmap_predump *ip; - fd = open_image_at(AT_FDCWD, CR_FD_IRMAP_CACHE, O_DUMP); - if (fd < 0) + img = open_image_at(AT_FDCWD, CR_FD_IRMAP_CACHE, O_DUMP); + if (!img) return -1; pr_info("Running irmap pre-dump\n"); @@ -323,13 +324,13 @@ int irmap_predump_run(void) ic.inode = ip->ino; ic.path = ip->fh.path; - ret = pb_write_one(fd, &ic, PB_IRMAP_CACHE); + ret = pb_write_one(img, &ic, PB_IRMAP_CACHE); if (ret) break; } } - close(fd); + close_image(img); return ret; } @@ -366,17 +367,17 @@ static int irmap_cache_one(IrmapCacheEntry *ie) return 0; } -static int open_irmap_cache(int *fd) +static int open_irmap_cache(struct cr_img **img) { int dir = AT_FDCWD; pr_info("Searching irmap cache in work dir\n"); in: - *fd = open_image_at(dir, CR_FD_IRMAP_CACHE, O_RSTR | O_OPT); + *img = open_image_at(dir, CR_FD_IRMAP_CACHE, O_RSTR | O_OPT); if (dir != AT_FDCWD) close(dir); - if (*fd >= 0) { + if (*img) { pr_info("... done\n"); return 1; } @@ -388,7 +389,7 @@ in: goto in; } - if (*fd != -ENOENT) + if (errno != ENOENT) return -1; pr_info("No irmap cache\n"); @@ -397,9 +398,10 @@ in: int irmap_load_cache(void) { - int fd, ret; + int ret; + struct cr_img *img; - ret = open_irmap_cache(&fd); + ret = open_irmap_cache(&img); if (ret <= 0) return ret; @@ -407,7 +409,7 @@ int irmap_load_cache(void) while (1) { IrmapCacheEntry *ic; - ret = pb_read_one_eof(fd, &ic, PB_IRMAP_CACHE); + ret = pb_read_one_eof(img, &ic, PB_IRMAP_CACHE); if (ret <= 0) break; @@ -418,6 +420,6 @@ int irmap_load_cache(void) irmap_cache_entry__free_unpacked(ic, NULL); } - close(fd); + close_image(img); return ret; } diff --git a/mem.c b/mem.c index 0c133685e..2ef9bbbd8 100644 --- a/mem.c +++ b/mem.c @@ -384,18 +384,20 @@ static inline int collect_filemap(struct vma_area *vma) int prepare_mm_pid(struct pstree_item *i) { pid_t pid = i->pid.virt; - int fd, ret = -1, vn = 0; + int ret = -1, vn = 0; + struct cr_img *img; struct rst_info *ri = i->rst; - fd = open_image(CR_FD_MM, O_RSTR | O_OPT, pid); - if (fd < 0) { + img = open_image(CR_FD_MM, O_RSTR | O_OPT, pid); + if (!img) { if (errno == ENOENT) return 0; return -1; } - ret = pb_read_one(fd, &ri->mm, PB_MM); - close(fd); + ret = pb_read_one(img, &ri->mm, PB_MM); + close_image(img); + if (ret < 0) return -1; @@ -403,18 +405,18 @@ int prepare_mm_pid(struct pstree_item *i) return -1; pr_debug("Found %zd VMAs in image\n", ri->mm->n_vmas); - fd = -1; + img = NULL; if (ri->mm->n_vmas == 0) { /* * Old image. Read VMAs from vma-.img */ - fd = open_image(CR_FD_VMAS, O_RSTR, pid); - if (fd < 0) + img = open_image(CR_FD_VMAS, O_RSTR, pid); + if (!img) return -1; } - while (vn < ri->mm->n_vmas || fd >= 0) { + while (vn < ri->mm->n_vmas || img != NULL) { struct vma_area *vma; ret = -1; @@ -424,13 +426,13 @@ int prepare_mm_pid(struct pstree_item *i) ret = 0; ri->vmas.nr++; - if (fd == -1) + if (!img) vma->e = ri->mm->vmas[vn++]; else { - ret = pb_read_one_eof(fd, &vma->e, PB_VMA); + ret = pb_read_one_eof(img, &vma->e, PB_VMA); if (ret <= 0) { xfree(vma); - close(fd); + close_image(img); break; } } diff --git a/mount.c b/mount.c index 8c60693ee..4da0d6fa3 100644 --- a/mount.c +++ b/mount.c @@ -692,7 +692,8 @@ static int tmpfs_dump(struct mount_info *pm) { int ret = -1; char tmpfs_path[PSFDS]; - int fd = -1, fd_img = -1; + int fd = -1; + struct cr_img *img; fd = open_mountpoint(pm); if (fd < 0) @@ -703,13 +704,13 @@ static int tmpfs_dump(struct mount_info *pm) goto out; } - fd_img = open_image(CR_FD_TMPFS_DEV, O_DUMP, pm->s_dev); - if (fd_img < 0) + img = open_image(CR_FD_TMPFS_DEV, O_DUMP, pm->s_dev); + if (!img) goto out; sprintf(tmpfs_path, "/proc/self/fd/%d", fd); - ret = cr_system(-1, fd_img, -1, "tar", (char *[]) + ret = cr_system(-1, img_raw_fd(img), -1, "tar", (char *[]) { "tar", "--create", "--gzip", "--one-file-system", @@ -722,8 +723,8 @@ static int tmpfs_dump(struct mount_info *pm) if (ret) pr_err("Can't dump tmpfs content\n"); + close_image(img); out: - close_safe(&fd_img); close_safe(&fd); return ret; } @@ -731,18 +732,18 @@ out: static int tmpfs_restore(struct mount_info *pm) { int ret; - int fd_img; + struct cr_img *img; - fd_img = open_image(CR_FD_TMPFS_DEV, O_RSTR, pm->s_dev); - if (fd_img < 0 && errno == ENOENT) - fd_img = open_image(CR_FD_TMPFS_IMG, O_RSTR, pm->mnt_id); - if (fd_img < 0) + img = open_image(CR_FD_TMPFS_DEV, O_RSTR, pm->s_dev); + if (!img && errno == ENOENT) + img = open_image(CR_FD_TMPFS_IMG, O_RSTR, pm->mnt_id); + if (!img) return -1; - ret = cr_system(fd_img, -1, -1, "tar", + ret = cr_system(img_raw_fd(img), -1, -1, "tar", (char *[]) {"tar", "--extract", "--gzip", "--directory", pm->mountpoint, NULL}); - close(fd_img); + close_image(img); if (ret) { pr_err("Can't restore tmpfs content\n"); @@ -906,7 +907,7 @@ uns: return &fstypes[0]; } -static int dump_one_mountpoint(struct mount_info *pm, int fd) +static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img) { MntEntry me = MNT_ENTRY__INIT; @@ -954,7 +955,7 @@ static int dump_one_mountpoint(struct mount_info *pm, int fd) } else me.root = pm->root; - if (pb_write_one(fd, &me, PB_MNT)) + if (pb_write_one(img, &me, PB_MNT)) return -1; return 0; @@ -994,21 +995,22 @@ err: static int dump_mnt_ns(struct ns_id *ns, struct mount_info *pms) { struct mount_info *pm; - int img_fd = -1, ret = -1; + int ret = -1; + struct cr_img *img; int ns_id = ns->id; pr_info("Dumping mountpoints\n"); - img_fd = open_image(CR_FD_MNTS, O_DUMP, ns_id); - if (img_fd < 0) + img = open_image(CR_FD_MNTS, O_DUMP, ns_id); + if (!img) goto err; for (pm = pms; pm && pm->nsid == ns; pm = pm->next) - if (dump_one_mountpoint(pm, img_fd)) + if (dump_one_mountpoint(pm, img)) goto err_i; ret = 0; err_i: - close(img_fd); + close_image(img); err: return ret; } @@ -1594,7 +1596,8 @@ static int rst_collect_local_mntns(void) static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid) { MntEntry *me = NULL; - int img, ret, root_len = 1; + int ret, root_len = 1; + struct cr_img *img; char root[PATH_MAX] = "."; img = open_image(CR_FD_MNTS, O_RSTR, nsid->id); @@ -1693,11 +1696,11 @@ static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid) if (me) mnt_entry__free_unpacked(me, NULL); - close(img); + close_image(img); return 0; err: - close_safe(&img); + close_image(img); return -1; } diff --git a/namespaces.c b/namespaces.c index 5d3ff9936..8021cfffb 100644 --- a/namespaces.c +++ b/namespaces.c @@ -239,7 +239,7 @@ static unsigned int get_ns_id(int pid, struct ns_desc *nd) int dump_one_ns_file(int lfd, u32 id, const struct fd_parms *p) { - int fd = img_from_set(glob_imgset, CR_FD_NS_FILES); + struct cr_img *img = img_from_set(glob_imgset, CR_FD_NS_FILES); NsFileEntry nfe = NS_FILE_ENTRY__INIT; struct fd_link *link = p->link; unsigned int nsid; @@ -255,7 +255,7 @@ int dump_one_ns_file(int lfd, u32 id, const struct fd_parms *p) nfe.ns_cflag = link->ns_d->cflag; nfe.flags = p->flags; - return pb_write_one(fd, &nfe, PB_NS_FILE); + return pb_write_one(img, &nfe, PB_NS_FILE); } const struct fdtype_ops nsfile_dump_ops = { @@ -557,16 +557,17 @@ int prepare_namespace(struct pstree_item *item, unsigned long clone_flags) int try_show_namespaces(int ns_pid) { struct cr_imgset *imgset; - int i, fd, ret; + int i, ret; + struct cr_img *img; TaskKobjIdsEntry *ids; pr_msg("Namespaces for %d:\n", ns_pid); - fd = open_image(CR_FD_IDS, O_RSTR, ns_pid); - if (fd < 0) + img = open_image(CR_FD_IDS, O_RSTR, ns_pid); + if (!img) return -1; - ret = pb_read_one(fd, &ids, PB_IDS); - close(fd); + ret = pb_read_one(img, &ids, PB_IDS); + close_image(img); if (ret < 0) return -1; @@ -574,13 +575,11 @@ int try_show_namespaces(int ns_pid) if (imgset) { pr_msg("-------------------NETNS---------------------\n"); for (i = _CR_FD_NETNS_FROM + 1; i < _CR_FD_NETNS_TO; i++) { - int fd; - - fd = img_from_set(imgset, i); - if (fd == -1) + img = img_from_set(imgset, i); + if (!img) continue; - cr_parse_fd(fd, imgset_template[i].magic); + cr_parse_fd(img, imgset_template[i].magic); } close_cr_imgset(&imgset); } @@ -589,27 +588,27 @@ int try_show_namespaces(int ns_pid) if (imgset) { pr_msg("-------------------IPCNS---------------------\n"); for (i = _CR_FD_IPCNS_FROM + 1; i < _CR_FD_IPCNS_TO; i++) { - fd = img_from_set(imgset, i); - if (fd == -1) + img = img_from_set(imgset, i); + if (!img) continue; - cr_parse_fd(fd, imgset_template[i].magic); + cr_parse_fd(img, imgset_template[i].magic); } close_cr_imgset(&imgset); } - fd = open_image(CR_FD_UTSNS, O_SHOW, ids->uts_ns_id); - if (fd >= 0) { + img = open_image(CR_FD_UTSNS, O_SHOW, ids->uts_ns_id); + if (img) { pr_msg("-------------------UTSNS---------------------\n"); - cr_parse_fd(fd, imgset_template[CR_FD_UTSNS].magic); - close(fd); + cr_parse_fd(img, imgset_template[CR_FD_UTSNS].magic); + close_image(img); } - fd = open_image(CR_FD_MNTS, O_SHOW, ids->mnt_ns_id); - if (fd > 0) { + img = open_image(CR_FD_MNTS, O_SHOW, ids->mnt_ns_id); + if (img) { pr_msg("-------------------MNTNS---------------------\n"); - cr_parse_fd(fd, imgset_template[CR_FD_MNTS].magic); - close(fd); + cr_parse_fd(img, imgset_template[CR_FD_MNTS].magic); + close_image(img); } pr_msg("---[ end of %d namespaces ]---\n", ns_pid); diff --git a/net.c b/net.c index d0010d816..fdfd40b9e 100644 --- a/net.c +++ b/net.c @@ -369,22 +369,23 @@ static int restore_link(NetDeviceEntry *nde, int nlsk) static int restore_links(int pid) { - int fd, nlsk, ret; + int nlsk, ret; + struct cr_img *img; NetDeviceEntry *nde; - fd = open_image(CR_FD_NETDEV, O_RSTR, pid); - if (fd < 0) + img = open_image(CR_FD_NETDEV, O_RSTR, pid); + if (!img) return -1; nlsk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (nlsk < 0) { pr_perror("Can't create nlk socket"); - close_safe(&fd); + close_image(img); return -1; } while (1) { - ret = pb_read_one_eof(fd, &nde, PB_NETDEV); + ret = pb_read_one_eof(img, &nde, PB_NETDEV); if (ret <= 0) break; @@ -395,7 +396,7 @@ static int restore_links(int pid) } close(nlsk); - close(fd); + close_image(img); return ret; } @@ -438,27 +439,31 @@ static int run_iptables_tool(char *def_cmd, int fdin, int fdout) static inline int dump_ifaddr(struct cr_imgset *fds) { - return run_ip_tool("addr", "save", -1, img_from_set(fds, CR_FD_IFADDR)); + struct cr_img *img = img_from_set(fds, CR_FD_IFADDR); + return run_ip_tool("addr", "save", -1, img_raw_fd(img)); } static inline int dump_route(struct cr_imgset *fds) { - return run_ip_tool("route", "save", -1, img_from_set(fds, CR_FD_ROUTE)); + struct cr_img *img = img_from_set(fds, CR_FD_ROUTE); + return run_ip_tool("route", "save", -1, img_raw_fd(img)); } static inline int dump_iptables(struct cr_imgset *fds) { - return run_iptables_tool("iptables-save", -1, img_from_set(fds, CR_FD_IPTABLES)); + struct cr_img *img = img_from_set(fds, CR_FD_IPTABLES); + return run_iptables_tool("iptables-save", -1, img_raw_fd(img)); } static int restore_ip_dump(int type, int pid, char *cmd) { - int fd, ret; + int ret = -1; + struct cr_img *img; - ret = fd = open_image(type, O_RSTR, pid); - if (fd >= 0) { - ret = run_ip_tool(cmd, "restore", fd, -1); - close(fd); + img = open_image(type, O_RSTR, pid); + if (img) { + ret = run_ip_tool(cmd, "restore", img_raw_fd(img), -1); + close_image(img); } return ret; @@ -476,12 +481,13 @@ static inline int restore_route(int pid) static inline int restore_iptables(int pid) { - int ret, fd; + int ret = -1; + struct cr_img *img; - ret = fd = open_image(CR_FD_IPTABLES, O_RSTR, pid); - if (fd >= 0) { - ret = run_iptables_tool("iptables-restore", fd, -1); - close(fd); + img = open_image(CR_FD_IPTABLES, O_RSTR, pid); + if (img) { + ret = run_iptables_tool("iptables-restore", img_raw_fd(img), -1); + close_image(img); } return ret; diff --git a/page-read.c b/page-read.c index 3cb43de2a..f67bdfecb 100644 --- a/page-read.c +++ b/page-read.c @@ -20,7 +20,7 @@ static int get_page_vaddr(struct page_read *pr, struct iovec *iov) int ret; u64 img_va; - ret = read_img_eof(pr->fd_pg, &img_va); + ret = read_img_eof(pr->pmi, &img_va); if (ret <= 0) return ret; @@ -34,7 +34,7 @@ static int read_page(struct page_read *pr, unsigned long vaddr, void *buf) { int ret; - ret = read(pr->fd_pg, buf, PAGE_SIZE); + ret = read(img_raw_fd(pr->pmi), buf, PAGE_SIZE); if (ret != PAGE_SIZE) { pr_err("Can't read mapping page %d\n", ret); return -1; @@ -60,7 +60,7 @@ static int get_pagemap(struct page_read *pr, struct iovec *iov) int ret; PagemapEntry *pe; - ret = pb_read_one_eof(pr->fd, &pe, PB_PAGEMAP); + ret = pb_read_one_eof(pr->pmi, &pe, PB_PAGEMAP); if (ret <= 0) return ret; @@ -91,7 +91,7 @@ static void skip_pagemap_pages(struct page_read *pr, unsigned long len) pr_debug("\tpr%u Skip %lx bytes from page-dump\n", pr->id, len); if (!pr->pe->in_parent) - lseek(pr->fd_pg, len, SEEK_CUR); + lseek(img_raw_fd(pr->pi), len, SEEK_CUR); pr->cvaddr += len; } @@ -145,10 +145,11 @@ static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, void *bu if (ret == -1) return ret; } else { - off_t current_vaddr = lseek(pr->fd_pg, 0, SEEK_CUR); + int fd = img_raw_fd(pr->pi); + off_t current_vaddr = lseek(fd, 0, SEEK_CUR); pr_debug("\tpr%u Read page %lx from self %lx/%"PRIx64"\n", pr->id, vaddr, pr->cvaddr, current_vaddr); - ret = read(pr->fd_pg, buf, PAGE_SIZE); + ret = read(fd, buf, PAGE_SIZE); if (ret != PAGE_SIZE) { pr_perror("Can't read mapping page %d", ret); return -1; @@ -184,8 +185,9 @@ static void close_page_read(struct page_read *pr) xfree(pr->parent); } - close(pr->fd_pg); - close(pr->fd); + close_image(pr->pmi); + if (pr->pi) + close_image(pr->pi); } static int try_open_parent(int dfd, int pid, struct page_read *pr, int flags) @@ -227,25 +229,26 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int flags, bool sh pr->bunch.iov_len = 0; pr->bunch.iov_base = NULL; - pr->fd = open_image_at(dfd, shmem ? CR_FD_SHMEM_PAGEMAP : CR_FD_PAGEMAP, O_RSTR, (long)pid); - if (pr->fd < 0) { - pr->fd_pg = open_image_at(dfd, shmem ? CR_FD_SHM_PAGES_OLD : CR_FD_PAGES_OLD, flags, pid); - if (pr->fd_pg < 0) + pr->pmi = open_image_at(dfd, shmem ? CR_FD_SHMEM_PAGEMAP : CR_FD_PAGEMAP, O_RSTR, (long)pid); + if (!pr->pmi) { + pr->pmi = open_image_at(dfd, shmem ? CR_FD_SHM_PAGES_OLD : CR_FD_PAGES_OLD, flags, pid); + if (!pr->pmi) return -1; pr->get_pagemap = get_page_vaddr; pr->put_pagemap = NULL; pr->read_page = read_page; + pr->pi = NULL; } else { static unsigned ids = 1; if (!shmem && try_open_parent(dfd, pid, pr, flags)) { - close(pr->fd); + close_image(pr->pmi); return -1; } - pr->fd_pg = open_pages_image_at(dfd, flags, pr->fd); - if (pr->fd_pg < 0) { + pr->pi = open_pages_image_at(dfd, flags, pr->pmi); + if (!pr->pi) { close_page_read(pr); return -1; } diff --git a/page-xfer.c b/page-xfer.c index 5bd21bb36..41ef1c5d9 100644 --- a/page-xfer.c +++ b/page-xfer.c @@ -431,7 +431,7 @@ static int write_pagemap_to_server(struct page_xfer *xfer, pi.dst_id = xfer->dst_id; iovec2psi(iov, &pi); - if (write(xfer->fd, &pi, sizeof(pi)) != sizeof(pi)) { + if (write(xfer->sk, &pi, sizeof(pi)) != sizeof(pi)) { pr_perror("Can't write pagemap to server"); return -1; } @@ -444,7 +444,7 @@ static int write_pages_to_server(struct page_xfer *xfer, { pr_debug("Splicing %lu bytes / %lu pages into socket\n", len, len / PAGE_SIZE); - if (splice(p, NULL, xfer->fd, NULL, len, SPLICE_F_MOVE) != len) { + if (splice(p, NULL, xfer->sk, NULL, len, SPLICE_F_MOVE) != len) { pr_perror("Can't write pages to socket"); return -1; } @@ -460,7 +460,7 @@ static int write_hole_to_server(struct page_xfer *xfer, struct iovec *iov) pi.dst_id = xfer->dst_id; iovec2psi(iov, &pi); - if (write(xfer->fd, &pi, sizeof(pi)) != sizeof(pi)) { + if (write(xfer->sk, &pi, sizeof(pi)) != sizeof(pi)) { pr_perror("Can't write pagehole to server"); return -1; } @@ -470,14 +470,14 @@ static int write_hole_to_server(struct page_xfer *xfer, struct iovec *iov) static void close_server_xfer(struct page_xfer *xfer) { - xfer->fd = -1; + xfer->sk = -1; } static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id) { struct page_server_iov pi; - xfer->fd = page_server_sk; + xfer->sk = page_server_sk; xfer->write_pagemap = write_pagemap_to_server; xfer->write_pages = write_pages_to_server; xfer->write_hole = write_hole_to_server; @@ -489,7 +489,7 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id) pi.vaddr = 0; pi.nr_pages = 0; - if (write(xfer->fd, &pi, sizeof(pi)) != sizeof(pi)) { + if (write(xfer->sk, &pi, sizeof(pi)) != sizeof(pi)) { pr_perror("Can't write to page server"); return -1; } @@ -511,14 +511,15 @@ static int write_pagemap_loc(struct page_xfer *xfer, return ret; } } - return pb_write_one(xfer->fd, &pe, PB_PAGEMAP); + return pb_write_one(xfer->pmi, &pe, PB_PAGEMAP); } static int write_pages_loc(struct page_xfer *xfer, int p, unsigned long len) { ssize_t ret; - ret = splice(p, NULL, xfer->fd_pg, NULL, len, SPLICE_F_MOVE); + + ret = splice(p, NULL, img_raw_fd(xfer->pi), NULL, len, SPLICE_F_MOVE); if (ret == -1) { pr_perror("Unable to spice data"); return -1; @@ -592,7 +593,7 @@ static int write_pagehole_loc(struct page_xfer *xfer, struct iovec *iov) pe.has_in_parent = true; pe.in_parent = true; - if (pb_write_one(xfer->fd, &pe, PB_PAGEMAP) < 0) + if (pb_write_one(xfer->pmi, &pe, PB_PAGEMAP) < 0) return -1; return 0; @@ -605,8 +606,8 @@ static void close_page_xfer(struct page_xfer *xfer) xfree(xfer->parent); xfer->parent = NULL; } - close(xfer->fd_pg); - close(xfer->fd); + close_image(xfer->pi); + close_image(xfer->pmi); } int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp, @@ -667,13 +668,13 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp, static int open_page_local_xfer(struct page_xfer *xfer, int fd_type, long id) { - xfer->fd = open_image(fd_type, O_DUMP, id); - if (xfer->fd < 0) + xfer->pmi = open_image(fd_type, O_DUMP, id); + if (!xfer->pmi) return -1; - xfer->fd_pg = open_pages_image(O_DUMP, xfer->fd); - if (xfer->fd_pg < 0) { - close(xfer->fd); + xfer->pi = open_pages_image(O_DUMP, xfer->pmi); + if (!xfer->pi) { + close_image(xfer->pmi); return -1; } diff --git a/parasite-syscall.c b/parasite-syscall.c index ca4a913e3..215380a86 100644 --- a/parasite-syscall.c +++ b/parasite-syscall.c @@ -576,7 +576,8 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id, int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_imgset *cr_imgset) { struct parasite_dump_sa_args *args; - int ret, sig, fd; + int ret, sig; + struct cr_img *img; SaEntry se = SA_ENTRY__INIT; args = parasite_args(ctl, struct parasite_dump_sa_args); @@ -585,7 +586,7 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_imgset *cr_ if (ret < 0) return ret; - fd = img_from_set(cr_imgset, CR_FD_SIGACT); + img = img_from_set(cr_imgset, CR_FD_SIGACT); for (sig = 1; sig <= SIGMAX; sig++) { int i = sig - 1; @@ -598,7 +599,7 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_imgset *cr_ ASSIGN_TYPED(se.restorer, encode_pointer(args->sas[i].rt_sa_restorer)); ASSIGN_TYPED(se.mask, args->sas[i].rt_sa_mask.sig[0]); - if (pb_write_one(fd, &se, PB_SIGACT) < 0) + if (pb_write_one(img, &se, PB_SIGACT) < 0) return -1; } diff --git a/pipes.c b/pipes.c index 51b95da8f..ddcc5cf2a 100644 --- a/pipes.c +++ b/pipes.c @@ -43,7 +43,7 @@ static void show_saved_pipe_fds(struct pipe_info *pi) pr_info(" `- FD %d pid %d\n", fle->fe->fd, fle->pid); } -static int pipe_data_read(int fd, struct pipe_data_rst *r) +static int pipe_data_read(struct cr_img *img, struct pipe_data_rst *r) { unsigned long bytes = r->pde->bytes; @@ -66,16 +66,17 @@ static int pipe_data_read(int fd, struct pipe_data_rst *r) return -1; } - return read_img_buf(fd, r->data, bytes); + return read_img_buf(img, r->data, bytes); } int collect_pipe_data(int img_type, struct pipe_data_rst **hash) { - int fd, ret; + int ret; + struct cr_img *img; struct pipe_data_rst *r = NULL; - fd = open_image(img_type, O_RSTR); - if (fd < 0) + img = open_image(img_type, O_RSTR); + if (!img) return -1; while (1) { @@ -84,11 +85,11 @@ int collect_pipe_data(int img_type, struct pipe_data_rst **hash) if (!r) break; - ret = pb_read_one_eof(fd, &r->pde, PB_PIPE_DATA); + ret = pb_read_one_eof(img, &r->pde, PB_PIPE_DATA); if (ret <= 0) break; - ret = pipe_data_read(fd, r); + ret = pipe_data_read(img, r); if (ret < 0) break; @@ -104,7 +105,7 @@ int collect_pipe_data(int img_type, struct pipe_data_rst **hash) pipe_data_entry__free_unpacked(r->pde, NULL); xfree(r); - close(fd); + close_image(img); return ret; } @@ -403,7 +404,7 @@ int collect_pipes(void) int dump_one_pipe_data(struct pipe_data_dump *pd, int lfd, const struct fd_parms *p) { - int img; + struct cr_img *img; int pipe_size, i, bytes; int steal_pipe[2]; int ret = -1; @@ -460,7 +461,7 @@ int dump_one_pipe_data(struct pipe_data_dump *pd, int lfd, const struct fd_parms if (bytes) { int wrote; - wrote = splice(steal_pipe[0], NULL, img, NULL, bytes, 0); + wrote = splice(steal_pipe[0], NULL, img_raw_fd(img), NULL, bytes, 0); if (wrote < 0) { pr_perror("Can't push pipe data"); goto err_close; diff --git a/protobuf.c b/protobuf.c index c3ffccaed..0bd04bc26 100644 --- a/protobuf.c +++ b/protobuf.c @@ -460,14 +460,14 @@ static void pb_show_msg(const void *msg, pb_pr_ctl_t *ctl) } } -static inline void pb_no_payload(int fd, void *obj) { } +static inline void pb_no_payload(struct cr_img *i, void *obj) { } -void do_pb_show_plain(int fd, int type, int single_entry, - void (*payload_hadler)(int fd, void *obj), +void do_pb_show_plain(struct cr_img *img, int type, int single_entry, + void (*payload_hadler)(struct cr_img *, void *obj), const char *pretty_fmt) { pb_pr_ctl_t ctl = {NULL, single_entry, pretty_fmt}; - void (*handle_payload)(int fd, void *obj); + void (*handle_payload)(struct cr_img *, void *obj); if (!cr_pb_descs[type].pb_desc) { pr_err("Wrong object requested %d\n", type); @@ -479,12 +479,12 @@ void do_pb_show_plain(int fd, int type, int single_entry, while (1) { void *obj; - if (pb_read_one_eof(fd, &obj, type) <= 0) + if (pb_read_one_eof(img, &obj, type) <= 0) break; ctl.arg = (void *)cr_pb_descs[type].pb_desc; pb_show_msg(obj, &ctl); - handle_payload(fd, obj); + handle_payload(img, obj); cr_pb_descs[type].free(obj, NULL); if (single_entry) break; @@ -512,8 +512,9 @@ static char *image_name(int fd) * Don't forget to free memory granted to unpacked object in calling code if needed */ -int do_pb_read_one(int fd, void **pobj, int type, bool eof) +int do_pb_read_one(struct cr_img *img, void **pobj, int type, bool eof) { + int fd = img->_fd; u8 local[PB_PKOBJ_LOCAL_SIZE]; void *buf = (void *)&local; u32 size; @@ -586,8 +587,9 @@ err: * 0 on success * -1 on error */ -int pb_write_one(int fd, void *obj, int type) +int pb_write_one(struct cr_img *img, void *obj, int type) { + int fd = img->_fd; u8 local[PB_PKOBJ_LOCAL_SIZE]; void *buf = (void *)&local; u32 size, packed; @@ -633,15 +635,16 @@ err: int collect_image(struct collect_image_info *cinfo) { bool optional = !!(cinfo->flags & COLLECT_OPTIONAL); - int fd, ret; + int ret; + struct cr_img *img; void *(*o_alloc)(size_t size) = malloc; void (*o_free)(void *ptr) = free; pr_info("Collecting %d/%d (flags %x)\n", cinfo->fd_type, cinfo->pb_type, cinfo->flags); - fd = open_image(cinfo->fd_type, O_RSTR | (optional ? O_OPT : 0)); - if (fd < 0) { + img = open_image(cinfo->fd_type, O_RSTR | (optional ? O_OPT : 0)); + if (!img) { if (optional && errno == ENOENT) return 0; else @@ -666,7 +669,7 @@ int collect_image(struct collect_image_info *cinfo) } else obj = NULL; - ret = pb_read_one_eof(fd, &msg, cinfo->pb_type); + ret = pb_read_one_eof(img, &msg, cinfo->pb_type); if (ret <= 0) { o_free(obj); break; @@ -683,7 +686,7 @@ int collect_image(struct collect_image_info *cinfo) cr_pb_descs[cinfo->pb_type].free(msg, NULL); } - close(fd); + close_image(img); pr_debug(" `- ... done\n"); return ret; } diff --git a/pstree.c b/pstree.c index ba9f965a1..29d59f251 100644 --- a/pstree.c +++ b/pstree.c @@ -205,7 +205,7 @@ int dump_pstree(struct pstree_item *root_item) struct pstree_item *item = root_item; PstreeEntry e = PSTREE_ENTRY__INIT; int ret = -1, i; - int pstree_fd; + struct cr_img *img; pr_info("\n"); pr_info("Dumping pstree (pid: %d)\n", root_item->pid.real); @@ -228,8 +228,8 @@ int dump_pstree(struct pstree_item *root_item) } } - pstree_fd = open_image(CR_FD_PSTREE, O_DUMP); - if (pstree_fd < 0) + img = open_image(CR_FD_PSTREE, O_DUMP); + if (!img) return -1; for_each_pstree_item(item) { @@ -248,7 +248,7 @@ int dump_pstree(struct pstree_item *root_item) for (i = 0; i < item->nr_threads; i++) e.threads[i] = item->threads[i].virt; - ret = pb_write_one(pstree_fd, &e, PB_PSTREE); + ret = pb_write_one(img, &e, PB_PSTREE); xfree(e.threads); if (ret) @@ -258,7 +258,7 @@ int dump_pstree(struct pstree_item *root_item) err: pr_info("----------------------------------------\n"); - close(pstree_fd); + close_image(img); return ret; } @@ -318,19 +318,20 @@ static int prepare_pstree_for_shell_job(void) static int read_pstree_image(void) { - int ret = 0, i, ps_fd; + int ret = 0, i; + struct cr_img *img; struct pstree_item *pi, *parent = NULL; pr_info("Reading image tree\n"); - ps_fd = open_image(CR_FD_PSTREE, O_RSTR); - if (ps_fd < 0) + img = open_image(CR_FD_PSTREE, O_RSTR); + if (!img) return -1; while (1) { PstreeEntry *e; - ret = pb_read_one_eof(ps_fd, &e, PB_PSTREE); + ret = pb_read_one_eof(img, &e, PB_PSTREE); if (ret <= 0) break; @@ -404,17 +405,17 @@ static int read_pstree_image(void) pstree_entry__free_unpacked(e, NULL); { - int fd; + struct cr_img *img; - fd = open_image(CR_FD_IDS, O_RSTR, pi->pid.virt); - if (fd < 0) { + img = open_image(CR_FD_IDS, O_RSTR, pi->pid.virt); + if (!img) { if (errno == ENOENT) continue; goto err; } - ret = pb_read_one(fd, &pi->ids, PB_IDS); - close(fd); - } + ret = pb_read_one(img, &pi->ids, PB_IDS); + close_image(img); + } if (ret != 1) goto err; @@ -425,7 +426,7 @@ static int read_pstree_image(void) } } err: - close(ps_fd); + close_image(img); return ret; } diff --git a/shmem.c b/shmem.c index 1b3d51d53..526d9a9ae 100644 --- a/shmem.c +++ b/shmem.c @@ -113,7 +113,7 @@ static int shmem_wait_and_open(int pid, struct shmem_info *si) static int restore_shmem_content(void *addr, struct shmem_info *si) { - int ret = 0; + int ret = 0, fd_pg; struct page_read pr; unsigned long off_real; @@ -121,6 +121,7 @@ static int restore_shmem_content(void *addr, struct shmem_info *si) if (ret) goto err_unmap; + fd_pg = img_raw_fd(pr.pi); while (1) { unsigned long vaddr; unsigned nr_pages; @@ -136,9 +137,9 @@ static int restore_shmem_content(void *addr, struct shmem_info *si) if (vaddr + nr_pages * PAGE_SIZE > si->size) break; - off_real = lseek(pr.fd_pg, 0, SEEK_CUR); + off_real = lseek(fd_pg, 0, SEEK_CUR); - ret = read(pr.fd_pg, addr + vaddr, nr_pages * PAGE_SIZE); + ret = read(fd_pg, addr + vaddr, nr_pages * PAGE_SIZE); if (ret != nr_pages * PAGE_SIZE) { ret = -1; break; diff --git a/sk-queue.c b/sk-queue.c index c2f8640a5..6a39c4b35 100644 --- a/sk-queue.c +++ b/sk-queue.c @@ -36,12 +36,13 @@ static LIST_HEAD(packets_list); int read_sk_queues(void) { struct sk_packet *pkt; - int ret, fd; + int ret; + struct cr_img *img; pr_info("Trying to read socket queues image\n"); - fd = open_image(CR_FD_SK_QUEUES, O_RSTR); - if (fd < 0) + img = open_image(CR_FD_SK_QUEUES, O_RSTR); + if (!img) return -1; while (1) { @@ -51,19 +52,19 @@ int read_sk_queues(void) pr_err("Failed to allocate packet header\n"); break; } - ret = pb_read_one_eof(fd, &pkt->entry, PB_SK_QUEUES); + ret = pb_read_one_eof(img, &pkt->entry, PB_SK_QUEUES); if (ret <= 0) break; - pkt->img_off = lseek(fd, 0, SEEK_CUR); + pkt->img_off = lseek(img_raw_fd(img), 0, SEEK_CUR); /* * NOTE: packet must be added to the tail. Otherwise sequence * will be broken. */ list_add_tail(&pkt->list, &packets_list); - lseek(fd, pkt->entry->length, SEEK_CUR); + lseek(img_raw_fd(img), pkt->entry->length, SEEK_CUR); } - close(fd); + close_image(img); xfree(pkt); return ret; @@ -178,24 +179,25 @@ err_brk: return ret; } -void sk_queue_data_handler(int fd, void *obj) +void sk_queue_data_handler(struct cr_img *img, void *obj) { SkPacketEntry *e = obj; - print_image_data(fd, e->length, opts.show_pages_content); + print_image_data(img, e->length, opts.show_pages_content); } int restore_sk_queue(int fd, unsigned int peer_id) { struct sk_packet *pkt, *tmp; - int ret, img_fd; + int ret; + struct cr_img *img; pr_info("Trying to restore recv queue for %u\n", peer_id); if (restore_prepare_socket(fd)) return -1; - img_fd = open_image(CR_FD_SK_QUEUES, O_RSTR); - if (img_fd < 0) + img = open_image(CR_FD_SK_QUEUES, O_RSTR); + if (!img) return -1; list_for_each_entry_safe(pkt, tmp, &packets_list, list) { @@ -220,12 +222,12 @@ int restore_sk_queue(int fd, unsigned int peer_id) if (buf ==NULL) goto err; - if (lseek(img_fd, pkt->img_off, SEEK_SET) == -1) { + if (lseek(img_raw_fd(img), pkt->img_off, SEEK_SET) == -1) { pr_perror("lseek() failed"); xfree(buf); goto err; } - if (read_img_buf(img_fd, buf, entry->length) != 1) { + if (read_img_buf(img, buf, entry->length) != 1) { xfree(buf); goto err; } @@ -246,9 +248,9 @@ int restore_sk_queue(int fd, unsigned int peer_id) xfree(pkt); } - close(img_fd); + close_image(img); return 0; err: - close_safe(&img_fd); + close_image(img); return -1; } diff --git a/sk-tcp.c b/sk-tcp.c index 29d8618f6..fcc0a57b3 100644 --- a/sk-tcp.c +++ b/sk-tcp.c @@ -310,7 +310,8 @@ err_sopt: static int dump_tcp_conn_state(struct inet_sk_desc *sk) { - int ret, img_fd, aux; + int ret, aux; + struct cr_img *img; TcpStreamEntry tse = TCP_STREAM_ENTRY__INIT; char *in_buf, *out_buf; @@ -371,29 +372,29 @@ static int dump_tcp_conn_state(struct inet_sk_desc *sk) * Push the stuff to image */ - img_fd = open_image(CR_FD_TCP_STREAM, O_DUMP, sk->sd.ino); - if (img_fd < 0) + img = open_image(CR_FD_TCP_STREAM, O_DUMP, sk->sd.ino); + if (!img) goto err_img; - ret = pb_write_one(img_fd, &tse, PB_TCP_STREAM); + ret = pb_write_one(img, &tse, PB_TCP_STREAM); if (ret < 0) goto err_iw; if (in_buf) { - ret = write_img_buf(img_fd, in_buf, tse.inq_len); + ret = write_img_buf(img, in_buf, tse.inq_len); if (ret < 0) goto err_iw; } if (out_buf) { - ret = write_img_buf(img_fd, out_buf, tse.outq_len); + ret = write_img_buf(img, out_buf, tse.outq_len); if (ret < 0) goto err_iw; } pr_info("Done\n"); err_iw: - close(img_fd); + close_image(img); err_img: err_opt: xfree(out_buf); @@ -452,7 +453,7 @@ static int restore_tcp_seqs(int sk, TcpStreamEntry *tse) return 0; } -static int __send_tcp_queue(int sk, int queue, u32 len, int imgfd) +static int __send_tcp_queue(int sk, int queue, u32 len, struct cr_img *img) { int ret, err = -1; int off, max; @@ -462,7 +463,7 @@ static int __send_tcp_queue(int sk, int queue, u32 len, int imgfd) if (!buf) return -1; - if (read_img_buf(imgfd, buf, len) < 0) + if (read_img_buf(img, buf, len) < 0) goto err; max = (queue == TCP_SEND_QUEUE) ? tcp_max_wshare : tcp_max_rshare; @@ -487,7 +488,7 @@ err: return err; } -static int send_tcp_queue(int sk, int queue, u32 len, int imgfd) +static int send_tcp_queue(int sk, int queue, u32 len, struct cr_img *img) { pr_debug("\tRestoring TCP %d queue data %u bytes\n", queue, len); @@ -496,10 +497,10 @@ static int send_tcp_queue(int sk, int queue, u32 len, int imgfd) return -1; } - return __send_tcp_queue(sk, queue, len, imgfd); + return __send_tcp_queue(sk, queue, len, img); } -static int restore_tcp_queues(int sk, TcpStreamEntry *tse, int fd) +static int restore_tcp_queues(int sk, TcpStreamEntry *tse, struct cr_img *img) { u32 len; @@ -507,7 +508,7 @@ static int restore_tcp_queues(int sk, TcpStreamEntry *tse, int fd) return -1; len = tse->inq_len; - if (len && send_tcp_queue(sk, TCP_RECV_QUEUE, len, fd)) + if (len && send_tcp_queue(sk, TCP_RECV_QUEUE, len, img)) return -1; /* @@ -518,7 +519,7 @@ static int restore_tcp_queues(int sk, TcpStreamEntry *tse, int fd) * restored in repair mode. */ len = tse->outq_len - tse->unsq_len; - if (len && send_tcp_queue(sk, TCP_SEND_QUEUE, len, fd)) + if (len && send_tcp_queue(sk, TCP_SEND_QUEUE, len, img)) return -1; /* @@ -527,7 +528,7 @@ static int restore_tcp_queues(int sk, TcpStreamEntry *tse, int fd) */ len = tse->unsq_len; tcp_repair_off(sk); - if (len && __send_tcp_queue(sk, TCP_SEND_QUEUE, len, fd)) + if (len && __send_tcp_queue(sk, TCP_SEND_QUEUE, len, img)) return -1; if (tcp_repair_on(sk)) return -1; @@ -588,16 +589,17 @@ static int restore_tcp_opts(int sk, TcpStreamEntry *tse) static int restore_tcp_conn_state(int sk, struct inet_sk_info *ii) { - int ifd, aux; + int aux; + struct cr_img *img; TcpStreamEntry *tse; pr_info("Restoring TCP connection id %x ino %x\n", ii->ie->id, ii->ie->ino); - ifd = open_image(CR_FD_TCP_STREAM, O_RSTR, ii->ie->ino); - if (ifd < 0) + img = open_image(CR_FD_TCP_STREAM, O_RSTR, ii->ie->ino); + if (!img) goto err; - if (pb_read_one(ifd, &tse, PB_TCP_STREAM) < 0) + if (pb_read_one(img, &tse, PB_TCP_STREAM) < 0) goto err_c; if (restore_tcp_seqs(sk, tse)) @@ -612,7 +614,7 @@ static int restore_tcp_conn_state(int sk, struct inet_sk_info *ii) if (restore_tcp_opts(sk, tse)) goto err_c; - if (restore_tcp_queues(sk, tse, ifd)) + if (restore_tcp_queues(sk, tse, img)) goto err_c; if (tse->has_nodelay && tse->nodelay) { @@ -628,12 +630,12 @@ static int restore_tcp_conn_state(int sk, struct inet_sk_info *ii) } tcp_stream_entry__free_unpacked(tse, NULL); - close(ifd); + close_image(img); return 0; err_c: tcp_stream_entry__free_unpacked(tse, NULL); - close(ifd); + close_image(img); err: return -1; } @@ -719,13 +721,13 @@ out: return ret; } -void show_tcp_stream(int fd, void *obj) +void show_tcp_stream(struct cr_img *img, void *obj) { TcpStreamEntry *e = obj; if (opts.show_pages_content) { pr_msg("In-queue:"); - print_image_data(fd, e->inq_len, 1); + print_image_data(img, e->inq_len, 1); pr_msg("Out-queue:"); - print_image_data(fd, e->outq_len, 1); + print_image_data(img, e->outq_len, 1); } } diff --git a/sockets.c b/sockets.c index f72ef8b23..103774f57 100644 --- a/sockets.c +++ b/sockets.c @@ -439,7 +439,7 @@ void release_skopts(SkOptsEntry *soe) xfree(soe->so_bound_dev); } -int dump_socket(struct fd_parms *p, int lfd, const int fdinfo) +int dump_socket(struct fd_parms *p, int lfd, struct cr_img *img) { int family; const struct fdtype_ops *ops; @@ -468,7 +468,7 @@ int dump_socket(struct fd_parms *p, int lfd, const int fdinfo) return -1; } - return do_dump_gen_file(p, lfd, ops, fdinfo); + return do_dump_gen_file(p, lfd, ops, img); } static int inet_receive_one(struct nlmsghdr *h, void *arg) diff --git a/stats.c b/stats.c index 011c35950..2a80bb31b 100644 --- a/stats.c +++ b/stats.c @@ -105,7 +105,7 @@ void write_stats(int what) DumpStatsEntry ds_entry = DUMP_STATS_ENTRY__INIT; RestoreStatsEntry rs_entry = RESTORE_STATS_ENTRY__INIT; char *name; - int fd; + struct cr_img *img; pr_info("Writing stats\n"); if (what == DUMP_STATS) { @@ -138,10 +138,10 @@ void write_stats(int what) } else return; - fd = open_image_at(AT_FDCWD, CR_FD_STATS, O_DUMP, name); - if (fd >= 0) { - pb_write_one(fd, &stats, PB_STATS); - close(fd); + img = open_image_at(AT_FDCWD, CR_FD_STATS, O_DUMP, name); + if (img) { + pb_write_one(img, &stats, PB_STATS); + close_image(img); } } diff --git a/tun.c b/tun.c index 82cecc4af..bec25c27a 100644 --- a/tun.c +++ b/tun.c @@ -266,7 +266,8 @@ static struct tun_link *get_tun_link_fd(char *name, unsigned flags) static int dump_tunfile(int lfd, u32 id, const struct fd_parms *p) { - int ret, img = img_from_set(glob_imgset, CR_FD_TUNFILE); + int ret; + struct cr_img *img; TunfileEntry tfe = TUNFILE_ENTRY__INIT; struct ifreq ifr; @@ -305,6 +306,7 @@ static int dump_tunfile(int lfd, u32 id, const struct fd_parms *p) return -1; } + img = img_from_set(glob_imgset, CR_FD_TUNFILE); return pb_write_one(img, &tfe, PB_TUNFILE); } diff --git a/uts_ns.c b/uts_ns.c index b495bbbde..b17dde992 100644 --- a/uts_ns.c +++ b/uts_ns.c @@ -14,12 +14,13 @@ int dump_uts_ns(int ns_pid, int ns_id) { - int ret, img_fd; + int ret; + struct cr_img *img; struct utsname ubuf; UtsnsEntry ue = UTSNS_ENTRY__INIT; - img_fd = open_image(CR_FD_UTSNS, O_DUMP, ns_id); - if (img_fd < 0) + img = open_image(CR_FD_UTSNS, O_DUMP, ns_id); + if (!img) return -1; ret = switch_ns(ns_pid, &uts_ns_desc, NULL); @@ -35,15 +36,16 @@ int dump_uts_ns(int ns_pid, int ns_id) ue.nodename = ubuf.nodename; ue.domainname = ubuf.domainname; - ret = pb_write_one(img_fd, &ue, PB_UTSNS); + ret = pb_write_one(img, &ue, PB_UTSNS); err: - close(img_fd); + close_image(img); return ret < 0 ? -1 : 0; } int prepare_utsns(int pid) { - int fd, ret; + int ret; + struct cr_img *img; UtsnsEntry *ue; struct sysctl_req req[3] = { { "kernel/hostname" }, @@ -51,11 +53,11 @@ int prepare_utsns(int pid) { }, }; - fd = open_image(CR_FD_UTSNS, O_RSTR, pid); - if (fd < 0) + img = open_image(CR_FD_UTSNS, O_RSTR, pid); + if (!img) return -1; - ret = pb_read_one(fd, &ue, PB_UTSNS); + ret = pb_read_one(img, &ue, PB_UTSNS); if (ret < 0) goto out; @@ -67,7 +69,7 @@ int prepare_utsns(int pid) ret = sysctl_op(req, CTL_WRITE); utsns_entry__free_unpacked(ue, NULL); out: - close(fd); + close_image(img); return ret; }