diff --git a/cr-restore.c b/cr-restore.c index f8b30a932..22614dba1 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -226,7 +226,7 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr, struct vma_area *p = *pvma; if (vma_area_is(vma, VMA_FILE_PRIVATE)) { - ret = get_filemap_fd(pid, vma->e); + ret = get_filemap_fd(vma); if (ret < 0) { pr_err("Can't fixup VMA's fd\n"); return -1; @@ -583,7 +583,7 @@ static int open_vmas(int pid) else if (vma_area_is(vma, VMA_ANON_SHARED)) ret = get_shmem_fd(pid, vma->e); else if (vma_area_is(vma, VMA_FILE_SHARED)) - ret = get_filemap_fd(pid, vma->e); + ret = get_filemap_fd(vma); else if (vma_area_is(vma, VMA_AREA_SOCKET)) ret = get_socket_fd(pid, vma->e); else diff --git a/fifo.c b/fifo.c index efd375a6e..53ad1dd9b 100644 --- a/fifo.c +++ b/fifo.c @@ -118,7 +118,7 @@ static void collect_fifo_fd(struct file_desc *d, struct fifo_info *info; info = container_of(d, struct fifo_info, d); - if (collect_special_file(info->fe->id)) + if (collect_special_file(info->fe->id) == NULL) BUG(); collect_gen_fd(fle, ri); diff --git a/files-reg.c b/files-reg.c index e4ea09fa5..ae292f208 100644 --- a/files-reg.c +++ b/files-reg.c @@ -672,14 +672,26 @@ static int open_fe_fd(struct file_desc *fd) int open_reg_by_id(u32 id) { /* - * This one gets called by exe link, chroot, - * cwd and file vmas restoring code. No need - * in calling lseek on either of them. + * This one gets called by exe link, chroot and cwd + * restoring code. No need in calling lseek on either + * of them. */ return open_path_by_id(id, do_open_reg_noseek, NULL); } +int get_filemap_fd(struct vma_area *vma) +{ + /* + * Thevma->fd should have been assigned in collect_filemap + * + * We open file w/o lseek, as mappings don't care about it + */ + + BUG_ON(vma->fd == NULL); + return open_path(vma->fd, do_open_reg_noseek, NULL); +} + static void remap_get(struct file_desc *fdesc, char typ) { struct reg_file_info *rfi; @@ -708,7 +720,7 @@ static struct file_desc_ops reg_desc_ops = { .collect_fd = collect_reg_fd, }; -int collect_special_file(u32 id) +struct file_desc *collect_special_file(u32 id) { struct file_desc *fdesc; @@ -722,11 +734,11 @@ int collect_special_file(u32 id) fdesc = find_file_desc_raw(FD_TYPES__REG, id); if (fdesc == NULL) { pr_err("No entry for reg-file-ID %#x\n", id); - return -1; + return NULL; } remap_get(fdesc, 's'); - return 0; + return fdesc; } static int collect_one_regfile(void *o, ProtobufCMessage *base) diff --git a/files.c b/files.c index 8159b72c2..dc3445ee2 100644 --- a/files.c +++ b/files.c @@ -1087,11 +1087,6 @@ out: return ret; } -int get_filemap_fd(int pid, VmaEntry *vma_entry) -{ - return open_reg_by_id(vma_entry->shmid); -} - int shared_fdt_prepare(struct pstree_item *item) { struct pstree_item *parent = item->parent; diff --git a/include/files-reg.h b/include/files-reg.h index 6de0cee17..15c20159e 100644 --- a/include/files-reg.h +++ b/include/files-reg.h @@ -34,7 +34,7 @@ extern int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p); extern struct file_remap *lookup_ghost_remap(u32 dev, u32 ino); extern void remap_put(struct file_remap *remap); -extern int collect_special_file(u32 id); +extern struct file_desc *collect_special_file(u32 id); extern struct collect_image_info reg_file_cinfo; extern struct collect_image_info remap_cinfo; diff --git a/include/files.h b/include/files.h index 88fba39ac..cfa40ac28 100644 --- a/include/files.h +++ b/include/files.h @@ -145,7 +145,7 @@ extern int prepare_fds(struct pstree_item *me); extern int prepare_fd_pid(struct pstree_item *me); extern int prepare_ctl_tty(int pid, struct rst_info *rst_info, u32 ctl_tty_id); extern int prepare_shared_fdinfo(void); -extern int get_filemap_fd(int pid, VmaEntry *vma_entry); +extern int get_filemap_fd(struct vma_area *); extern int prepare_fs(int pid); extern int set_fd_flags(int fd, int flags); diff --git a/include/vma.h b/include/vma.h index 60b337ba3..c0bd80bc0 100644 --- a/include/vma.h +++ b/include/vma.h @@ -21,6 +21,8 @@ static inline void vm_area_list_init(struct vm_area_list *vml) vml->longest = 0; } +struct file_desc; + struct vma_area { struct list_head list; VmaEntry *e; @@ -28,6 +30,7 @@ struct vma_area { union { int vm_file_fd; int vm_socket_id; + struct file_desc *fd; }; unsigned long *page_bitmap; /* existent pages */ unsigned long *ppage_bitmap; /* parent's existent pages */ diff --git a/mem.c b/mem.c index f27d899d4..02cb8df3e 100644 --- a/mem.c +++ b/mem.c @@ -342,9 +342,16 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, return ret; } -static inline int collect_filemap(VmaEntry *vme) +static inline int collect_filemap(struct vma_area *vma) { - return collect_special_file(vme->shmid); + struct file_desc *fd; + + fd = collect_special_file(vma->e->shmid); + if (!fd) + return -1; + + vma->fd = fd; + return 0; } int prepare_mm_pid(struct pstree_item *i) @@ -365,7 +372,7 @@ int prepare_mm_pid(struct pstree_item *i) if (ret < 0) return -1; - if (collect_special_file(ri->mm->exe_file_id)) + if (collect_special_file(ri->mm->exe_file_id) == NULL) return -1; pr_debug("Found %zd VMAs in image\n", ri->mm->n_vmas); @@ -415,7 +422,7 @@ int prepare_mm_pid(struct pstree_item *i) ret = collect_shmem(pid, vma->e); else if (vma_area_is(vma, VMA_FILE_PRIVATE) || vma_area_is(vma, VMA_FILE_SHARED)) - ret = collect_filemap(vma->e); + ret = collect_filemap(vma); else ret = 0; if (ret)