[CRIU] [PATCH 4/5] restore: support SYSV IPC vma

Kinsbursky Stanislav skinsbursky at openvz.org
Tue Feb 14 12:20:10 EST 2012


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: Stanislav Kinsbursky <skinsbursky at openvz.org>

---
 cr-restore.c            |   16 +++++++++++++---
 include/syscall-codes.h |    1 +
 include/syscall.h       |    4 ++++
 restorer.c              |    5 +++++
 4 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 3613d7b..de1be9a 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -17,6 +17,7 @@
 #include <sys/user.h>
 #include <sys/wait.h>
 #include <sys/file.h>
+#include <sys/shm.h>
 
 #include <sched.h>
 
@@ -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 23ac949..28def99 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 e42e94a..02e5ee6 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 d60223c..3eb5e35 100644
--- a/restorer.c
+++ b/restorer.c
@@ -7,6 +7,7 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <sys/time.h>
+#include <sys/shm.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <sched.h>
@@ -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 */



More information about the CRIU mailing list