Commit 6faac3a3 authored by Pavel Emelyanov's avatar Pavel Emelyanov

rst: Factor out vma fd fixup

Just make the fixup_vma_fds read and write vma images and
those called by it provide and fd for this.
Acked-by: 's avatarAndrey Vagin <avagin@parallels.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 29e07fa2
...@@ -476,21 +476,13 @@ static int restore_shmem_content(void *addr, struct shmem_info *si) ...@@ -476,21 +476,13 @@ static int restore_shmem_content(void *addr, struct shmem_info *si)
return ret; return ret;
} }
static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd) static int get_shmem_fd(int pid, struct vma_entry *vi)
{ {
struct shmem_info *si; struct shmem_info *si;
struct shmem_id *shmid; struct shmem_id *shmid;
int sh_fd; int sh_fd;
void *addr;
if (vma_entry_is(vi, VMA_AREA_SYSVIPC)) { int f;
/*
* SYSV IPC shared memory region was created already. We don't
* need to wait. But we have to pass shmid to restorer. Let's
* use vma_entry->fd for it.
*/
vi->fd = vi->shmid;
goto write_fd;
}
si = find_shmem(shmems, vi->shmid); si = find_shmem(shmems, vi->shmid);
pr_info("%d: Search for %016lx shmem %lx %p/%d\n", pid, vi->start, vi->shmid, si, si ? si->pid : -1); pr_info("%d: Search for %016lx shmem %lx %p/%d\n", pid, vi->start, vi->shmid, si, si ? si->pid : -1);
...@@ -499,60 +491,41 @@ static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd) ...@@ -499,60 +491,41 @@ static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd)
return -1; return -1;
} }
if (si->pid != pid) { if (si->pid != pid)
sh_fd = shmem_wait_and_open(pid, si); return shmem_wait_and_open(pid, si);
pr_info("%d: Fixing %lx vma to %lx/%d shmem -> %d\n",
pid, vi->start, si->shmid, si->pid, sh_fd);
if (sh_fd < 0) {
pr_perror("%d: Can't open shmem", pid);
return -1;
}
pr_info("%d: Fixed %lx vma %lx/%d shmem -> %d\n",
pid, vi->start, si->shmid, si->pid, sh_fd);
vi->fd = sh_fd;
} else {
void *addr;
int f;
char path[128];
if (si->start == vi->start) {
/* The following hack solves problems:
* vi->pgoff may be not zero in a target process.
* This mapping may be mapped more then once.
* The restorer doesn't have snprintf.
* Here is a good place to restore content
*/
addr = mmap(NULL, si->size,
PROT_WRITE | PROT_READ,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) {
pr_err("Can't mmap shmid=0x%lx size=%ld\n",
vi->shmid, si->size);
return -1;
}
if (restore_shmem_content(addr, si) < 0) { if (si->start != vi->start)
pr_err("Can't restore shmem content\n"); return dup(si->fd);
return -1;
}
f = open_proc_rw(getpid(), "map_files/%lx-%lx",
(unsigned long) addr,
(unsigned long) addr + si->size);
munmap(addr, si->size);
if (f < 0) /* The following hack solves problems:
return -1; * vi->pgoff may be not zero in a target process.
* This mapping may be mapped more then once.
vi->fd = si->fd = f; * The restorer doesn't have snprintf.
} else * Here is a good place to restore content
vi->fd = dup(si->fd); */
addr = mmap(NULL, si->size,
PROT_WRITE | PROT_READ,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) {
pr_err("Can't mmap shmid=0x%lx size=%ld\n",
vi->shmid, si->size);
return -1;
}
if (restore_shmem_content(addr, si) < 0) {
pr_err("Can't restore shmem content\n");
return -1;
} }
write_fd: f = open_proc_rw(getpid(), "map_files/%lx-%lx",
lseek(fd, -sizeof(*vi), SEEK_CUR); (unsigned long) addr,
return write_img(fd, vi); (unsigned long) addr + si->size);
munmap(addr, si->size);
if (f < 0)
return -1;
si->fd = f;
return f;
} }
static int fixup_vma_fds(int pid, int fd) static int fixup_vma_fds(int pid, int fd)
...@@ -568,21 +541,29 @@ static int fixup_vma_fds(int pid, int fd) ...@@ -568,21 +541,29 @@ static int fixup_vma_fds(int pid, int fd)
if (!(vma_entry_is(&vi, VMA_AREA_REGULAR))) if (!(vma_entry_is(&vi, VMA_AREA_REGULAR)))
continue; continue;
if (vma_entry_is(&vi, VMA_FILE_PRIVATE) || pr_info("%d: Fixing %016lx-%016lx %016lx vma\n",
vma_entry_is(&vi, VMA_FILE_SHARED)) {
pr_info("%d: Fixing %016lx-%016lx %016lx vma\n",
pid, vi.start, vi.end, vi.pgoff); pid, vi.start, vi.end, vi.pgoff);
if (try_fixup_file_map(pid, &vi, fd))
return -1;
}
if (vma_entry_is(&vi, VMA_ANON_SHARED)) { if (vma_entry_is(&vi, VMA_AREA_SYSVIPC))
pr_info("%d: Fixing %016lx-%016lx %016lx vma\n", ret = vi.shmid;
pid, vi.start, vi.end, vi.pgoff); else if (vma_entry_is(&vi, VMA_ANON_SHARED))
if (try_fixup_shared_map(pid, &vi, fd)) ret = get_shmem_fd(pid, &vi);
return -1; else if (vma_entry_is(&vi, VMA_FILE_PRIVATE) ||
vma_entry_is(&vi, VMA_FILE_SHARED))
ret = get_filemap_fd(pid, &vi);
else
continue;
if (ret < 0) {
pr_err("Can't fixup fd\n");
return ret;
} }
lseek(fd, -sizeof(vi), SEEK_CUR);
vi.fd = ret;
ret = write_img(fd, &vi);
if (ret < 0)
return ret;
} }
} }
......
...@@ -516,25 +516,10 @@ static struct fmap_fd *pull_fmap_fd(int pid, unsigned long start) ...@@ -516,25 +516,10 @@ static struct fmap_fd *pull_fmap_fd(int pid, unsigned long start)
return NULL; return NULL;
} }
int try_fixup_file_map(int pid, struct vma_entry *vma_entry, int fd) int get_filemap_fd(int pid, struct vma_entry *vma_entry)
{ {
struct fmap_fd *fmap_fd = pull_fmap_fd(pid, vma_entry->start); struct fmap_fd *fmap_fd;
if (fmap_fd) { fmap_fd = pull_fmap_fd(pid, vma_entry->start);
pr_info("%d: Fixing %lx vma to %d fd\n", return fmap_fd ? fmap_fd->fd : -1;
pid, vma_entry->start, fmap_fd->fd);
lseek(fd, -sizeof(*vma_entry), SEEK_CUR);
vma_entry->fd = fmap_fd->fd;
if (write_img(fd, vma_entry))
goto err;
free(fmap_fd);
}
return 0;
err:
pr_perror("%d: Can't fixup vma", pid);
return -1;
} }
...@@ -40,6 +40,6 @@ struct fdinfo_list_entry { ...@@ -40,6 +40,6 @@ struct fdinfo_list_entry {
extern int prepare_fds(int pid); extern int prepare_fds(int pid);
extern int prepare_fd_pid(int pid); extern int prepare_fd_pid(int pid);
extern int prepare_shared_fdinfo(void); extern int prepare_shared_fdinfo(void);
extern int try_fixup_file_map(int pid, struct vma_entry *vma_entry, int fd); extern int get_filemap_fd(int pid, struct vma_entry *vma_entry);
#endif /* FILES_H_ */ #endif /* FILES_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment