Commit 574302bf authored by Kinsbursky Stanislav's avatar Kinsbursky Stanislav Committed by Cyrill Gorcunov

restore: support SYSV IPC vma

This patch introduces the following changes:
1) writing of shmid value into vma_area->fd instead of
   waiting for shared memory region is open by parent,
   reopen it and dump fd.
2) new syscall support: sys_shmat
3) use sys_shmat() to map memory region in restorer's
   mapping function if vma flag VMA_AREA_SYSVIPC is set.
Signed-off-by: 's avatarStanislav Kinsbursky <skinsbursky@openvz.org>
Acked-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent e9675665
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <sys/user.h> #include <sys/user.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/file.h> #include <sys/file.h>
#include <sys/shm.h>
#include <sched.h> #include <sched.h>
...@@ -530,6 +531,7 @@ static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd) ...@@ -530,6 +531,7 @@ static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd)
{ {
struct shmem_info *si; struct shmem_info *si;
struct shmem_id *shmid; struct shmem_id *shmid;
int sh_fd;
shmid = find_shmem_id(vi->start); shmid = find_shmem_id(vi->start);
if (!shmid) if (!shmid)
...@@ -543,9 +545,17 @@ static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd) ...@@ -543,9 +545,17 @@ static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd)
return -1; return -1;
} }
if (si->pid != pid) { if (vma_entry_is(vi, VMA_AREA_SYSVIPC)) {
int sh_fd; /*
* 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); sh_fd = shmem_wait_and_open(pid, si);
pr_info("%d: Fixing %lx vma to %lx/%d shmem -> %d\n", pr_info("%d: Fixing %lx vma to %lx/%d shmem -> %d\n",
pid, vi->start, si->shmid, si->pid, sh_fd); 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) ...@@ -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); pr_perror("%d: Can't open shmem", pid);
return -1; return -1;
} }
write_fd:
lseek(fd, -sizeof(*vi), SEEK_CUR); lseek(fd, -sizeof(*vi), SEEK_CUR);
vi->fd = sh_fd; vi->fd = sh_fd;
pr_info("%d: Fixed %lx vma %lx/%d shmem -> %d\n", pr_info("%d: Fixed %lx vma %lx/%d shmem -> %d\n",
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#define __NR_rt_sigaction 13 #define __NR_rt_sigaction 13
#define __NR_rt_sigreturn 15 #define __NR_rt_sigreturn 15
#define __NR_mincore 27 #define __NR_mincore 27
#define __NR_shmat 30
#define __NR_dup 32 #define __NR_dup 32
#define __NR_dup2 33 #define __NR_dup2 33
#define __NR_pause 34 #define __NR_pause 34
......
...@@ -136,6 +136,10 @@ static always_inline unsigned long sys_pause(void) ...@@ -136,6 +136,10 @@ static always_inline unsigned long sys_pause(void)
return syscall0(__NR_pause); 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, static always_inline unsigned long sys_mmap(void *addr, unsigned long len, unsigned long prot,
unsigned long flags, unsigned long fd, unsigned long offset) unsigned long flags, unsigned long fd, unsigned long offset)
{ {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/shm.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sched.h> #include <sched.h>
...@@ -290,6 +291,10 @@ static u64 restore_mapping(const struct vma_entry *vma_entry) ...@@ -290,6 +291,10 @@ static u64 restore_mapping(const struct vma_entry *vma_entry)
{ {
int prot; 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; prot = vma_entry->prot;
/* A mapping of file with MAP_SHARED is up to date */ /* A mapping of file with MAP_SHARED is up to date */
......
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