diff --git a/cr-restore.c b/cr-restore.c index 3613d7b47..de1be9ae5 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -530,6 +531,7 @@ static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd) { struct shmem_info *si; struct shmem_id *shmid; + int sh_fd; shmid = find_shmem_id(vi->start); if (!shmid) @@ -543,9 +545,17 @@ static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd) return -1; } - if (si->pid != pid) { - int sh_fd; + if (vma_entry_is(vi, VMA_AREA_SYSVIPC)) { + /* + * 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. + */ + sh_fd = si->shmid; + goto write_fd; + } + if (si->pid != pid) { sh_fd = 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); @@ -553,7 +563,7 @@ static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd) pr_perror("%d: Can't open shmem", pid); return -1; } - +write_fd: lseek(fd, -sizeof(*vi), SEEK_CUR); vi->fd = sh_fd; pr_info("%d: Fixed %lx vma %lx/%d shmem -> %d\n", diff --git a/include/syscall-codes.h b/include/syscall-codes.h index 23ac9495f..28def9900 100644 --- a/include/syscall-codes.h +++ b/include/syscall-codes.h @@ -15,6 +15,7 @@ #define __NR_rt_sigaction 13 #define __NR_rt_sigreturn 15 #define __NR_mincore 27 +#define __NR_shmat 30 #define __NR_dup 32 #define __NR_dup2 33 #define __NR_pause 34 diff --git a/include/syscall.h b/include/syscall.h index e42e94aa4..02e5ee6cb 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -136,6 +136,10 @@ static always_inline unsigned long sys_pause(void) return syscall0(__NR_pause); } +static always_inline unsigned long sys_shmat(int shmid, void *shmaddr, int shmflag) +{ + return syscall3(__NR_shmat, shmid, (unsigned long)shmaddr, shmflag); +} static always_inline unsigned long sys_mmap(void *addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long offset) { diff --git a/restorer.c b/restorer.c index d60223c6f..3eb5e35b9 100644 --- a/restorer.c +++ b/restorer.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -290,6 +291,10 @@ static u64 restore_mapping(const struct vma_entry *vma_entry) { int prot; + if (vma_entry_is(vma_entry, VMA_AREA_SYSVIPC)) + return sys_shmat(vma_entry->fd, (void *)vma_entry->start, + (vma_entry->prot & PROT_WRITE) ? 0 : SHM_RDONLY); + prot = vma_entry->prot; /* A mapping of file with MAP_SHARED is up to date */