[CRIU] [PATCH 2/5] vma: Turn embeded VmaEntry on vma_area into pointer

Pavel Emelyanov xemul at parallels.com
Mon Feb 3 12:08:16 PST 2014


On restore we will read all VmaEntries in one big MmEntry object,
so to avoif copying them all into vma_areas, make them be pointable.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 arch/x86/vdso.c    |  28 ++++++-------
 cr-dump.c          |  14 +++----
 cr-restore.c       | 100 +++++++++++++++++++++++-----------------------
 include/vma.h      |  10 ++---
 mem.c              |  22 +++++------
 parasite-syscall.c |  12 +++---
 proc_parse.c       | 114 ++++++++++++++++++++++++++---------------------------
 sk-packet.c        |   4 +-
 util.c             |  19 ++++-----
 9 files changed, 163 insertions(+), 160 deletions(-)

diff --git a/arch/x86/vdso.c b/arch/x86/vdso.c
index f24de54..8fb89f6 100644
--- a/arch/x86/vdso.c
+++ b/arch/x86/vdso.c
@@ -100,10 +100,10 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 		if (!vma_area_is(vma, VMA_AREA_REGULAR))
 			continue;
 
-		if ((vma->vma.prot & VDSO_PROT) != VDSO_PROT)
+		if ((vma->e->prot & VDSO_PROT) != VDSO_PROT)
 			continue;
 
-		if (vma->vma.start > TASK_SIZE)
+		if (vma->e->start > TASK_SIZE)
 			continue;
 
 		/*
@@ -111,7 +111,7 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 		 * otherwise if task never called for vdso functions
 		 * page frame number won't be reported.
 		 */
-		args->start = vma->vma.start;
+		args->start = vma->e->start;
 		args->len = vma_area_len(vma);
 
 		if (parasite_execute_daemon(PARASITE_CMD_CHECK_VDSO_MARK, ctl)) {
@@ -131,10 +131,10 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 			continue;
 		}
 
-		off = (vma->vma.start / PAGE_SIZE) * sizeof(u64);
+		off = (vma->e->start / PAGE_SIZE) * sizeof(u64);
 		if (lseek(fd, off, SEEK_SET) != off) {
 			pr_perror("Failed to seek address %lx\n",
-				  (long unsigned int)vma->vma.start);
+				  (long unsigned int)vma->e->start);
 			ret = -1;
 			goto err;
 		}
@@ -155,14 +155,14 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 		if (pfn == vdso_pfn) {
 			if (!vma_area_is(vma, VMA_AREA_VDSO)) {
 				pr_debug("vdso: Restore status by pfn at %lx\n",
-					 (long)vma->vma.start);
-				vma->vma.status |= VMA_AREA_VDSO;
+					 (long)vma->e->start);
+				vma->e->status |= VMA_AREA_VDSO;
 			}
 		} else {
 			if (vma_area_is(vma, VMA_AREA_VDSO)) {
 				pr_debug("vdso: Drop mishinted status at %lx\n",
-					 (long)vma->vma.start);
-				vma->vma.status &= ~VMA_AREA_VDSO;
+					 (long)vma->e->start);
+				vma->e->status &= ~VMA_AREA_VDSO;
 			}
 		}
 	}
@@ -173,23 +173,23 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 	 */
 	if (marked) {
 		pr_debug("vdso: Found marked at %lx (proxy at %lx)\n",
-			 (long)marked->vma.start, (long)proxy_addr);
+			 (long)marked->e->start, (long)proxy_addr);
 
 		/*
 		 * Don't forget to restore the proxy vdso status, since
 		 * it's being not recognized by the kernel as vdso.
 		 */
 		list_for_each_entry(vma, &vma_area_list->h, list) {
-			if (vma->vma.start == proxy_addr) {
-				vma->vma.status |= VMA_AREA_REGULAR | VMA_AREA_VDSO;
+			if (vma->e->start == proxy_addr) {
+				vma->e->status |= VMA_AREA_REGULAR | VMA_AREA_VDSO;
 				pr_debug("vdso: Restore proxy status at %lx\n",
-					 (long)vma->vma.start);
+					 (long)vma->e->start);
 				break;
 			}
 		}
 
 		pr_debug("vdso: Droppping marked vdso at %lx\n",
-			 (long)vma->vma.start);
+			 (long)vma->e->start);
 		list_del(&marked->list);
 		xfree(marked);
 	}
diff --git a/cr-dump.c b/cr-dump.c
index 2cc7d64..183441a 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -84,15 +84,15 @@ bool privately_dump_vma(struct vma_area *vma)
 	/*
 	 * The special areas are not dumped.
 	 */
-	if (!(vma->vma.status & VMA_AREA_REGULAR))
+	if (!(vma->e->status & VMA_AREA_REGULAR))
 		return false;
 
 	/* No dumps for file-shared mappings */
-	if (vma->vma.status & VMA_FILE_SHARED)
+	if (vma->e->status & VMA_FILE_SHARED)
 		return false;
 
 	/* No dumps for SYSV IPC mappings */
-	if (vma->vma.status & VMA_AREA_SYSVIPC)
+	if (vma->e->status & VMA_AREA_SYSVIPC)
 		return false;
 
 	if (vma_area_is(vma, VMA_ANON_SHARED))
@@ -104,7 +104,7 @@ bool privately_dump_vma(struct vma_area *vma)
 		return false;
 	}
 
-	if (vma->vma.end > TASK_SIZE)
+	if (vma->e->end > TASK_SIZE)
 		return false;
 
 	return true;
@@ -114,7 +114,7 @@ static void close_vma_file(struct vma_area *vma)
 {
 	if (vma->vm_file_fd < 0)
 		return;
-	if (vma->vma.status & VMA_AREA_SOCKET)
+	if (vma->e->status & VMA_AREA_SOCKET)
 		return;
 	if (vma->file_borrowed)
 		return;
@@ -347,7 +347,7 @@ static int dump_filemap(pid_t pid, struct vma_area *vma_area,
 		const struct cr_fdset *fdset)
 {
 	struct fd_parms p = FD_PARMS_INIT;
-	VmaEntry *vma = &vma_area->vma;
+	VmaEntry *vma = vma_area->e;
 
 	BUG_ON(!vma_area->st);
 	p.stat = *vma_area->st;
@@ -417,7 +417,7 @@ static int dump_task_mm(pid_t pid, const struct proc_pid_stat *stat,
 	fd = fdset_fd(fdset, CR_FD_VMAS);
 
 	list_for_each_entry(vma_area, &vma_area_list->h, list) {
-		VmaEntry *vma = &vma_area->vma;
+		VmaEntry *vma = vma_area->e;
 
 		pr_info_vma(vma_area);
 
diff --git a/cr-restore.c b/cr-restore.c
index a6ee865..89d6136 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -217,40 +217,40 @@ 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->vma);
+		ret = get_filemap_fd(pid, vma->e);
 		if (ret < 0) {
 			pr_err("Can't fixup VMA's fd\n");
 			return -1;
 		}
-		vma->vma.fd = ret;
+		vma->e->fd = ret;
 	}
 
-	nr_pages = vma_entry_len(&vma->vma) / PAGE_SIZE;
+	nr_pages = vma_entry_len(vma->e) / PAGE_SIZE;
 	vma->page_bitmap = xzalloc(BITS_TO_LONGS(nr_pages) * sizeof(long));
 	if (vma->page_bitmap == NULL)
 		return -1;
 
 	list_for_each_entry_continue(p, pvma_list, list) {
-		if (p->vma.start > vma->vma.start)
+		if (p->e->start > vma->e->start)
 			 break;
 
-		if (!vma_priv(&p->vma))
+		if (!vma_priv(p->e))
 			continue;
 
-		 if (p->vma.end != vma->vma.end ||
-		     p->vma.start != vma->vma.start)
+		 if (p->e->end != vma->e->end ||
+		     p->e->start != vma->e->start)
 			continue;
 
 		/* Check flags, which must be identical for both vma-s */
-		if ((vma->vma.flags ^ p->vma.flags) & (MAP_GROWSDOWN | MAP_ANONYMOUS))
+		if ((vma->e->flags ^ p->e->flags) & (MAP_GROWSDOWN | MAP_ANONYMOUS))
 			break;
 
-		if (!(vma->vma.flags & MAP_ANONYMOUS) &&
-		    vma->vma.shmid != p->vma.shmid)
+		if (!(vma->e->flags & MAP_ANONYMOUS) &&
+		    vma->e->shmid != p->e->shmid)
 			break;
 
 		pr_info("COW 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" vma\n",
-			vma->vma.start, vma->vma.end, vma->vma.pgoff);
+			vma->e->start, vma->e->end, vma->e->pgoff);
 		paddr = decode_pointer(vma->premmaped_addr);
 	}
 
@@ -260,25 +260,25 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
 	 * A grow-down VMA has a guard page, which protect a VMA below it.
 	 * So one more page is mapped here to restore content of the first page
 	 */
-	if (vma->vma.flags & MAP_GROWSDOWN) {
-		vma->vma.start -= PAGE_SIZE;
+	if (vma->e->flags & MAP_GROWSDOWN) {
+		vma->e->start -= PAGE_SIZE;
 		if (paddr)
 			paddr -= PAGE_SIZE;
 	}
 
-	size = vma_entry_len(&vma->vma);
+	size = vma_entry_len(vma->e);
 	if (paddr == NULL) {
 		/*
 		 * The respective memory area was NOT found in the parent.
 		 * Map a new one.
 		 */
 		pr_info("Map 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" vma\n",
-			vma->vma.start, vma->vma.end, vma->vma.pgoff);
+			vma->e->start, vma->e->end, vma->e->pgoff);
 
 		addr = mmap(tgt_addr, size,
-				vma->vma.prot | PROT_WRITE,
-				vma->vma.flags | MAP_FIXED,
-				vma->vma.fd, vma->vma.pgoff);
+				vma->e->prot | PROT_WRITE,
+				vma->e->flags | MAP_FIXED,
+				vma->e->fd, vma->e->pgoff);
 
 		if (addr == MAP_FAILED) {
 			pr_perror("Unable to map ANON_VMA");
@@ -302,15 +302,15 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
 
 	vma->premmaped_addr = (unsigned long) addr;
 	pr_debug("\tpremap 0x%016"PRIx64"-0x%016"PRIx64" -> %016lx\n",
-		vma->vma.start, vma->vma.end, (unsigned long)addr);
+		vma->e->start, vma->e->end, (unsigned long)addr);
 
-	if (vma->vma.flags & MAP_GROWSDOWN) { /* Skip gurad page */
-		vma->vma.start += PAGE_SIZE;
+	if (vma->e->flags & MAP_GROWSDOWN) { /* Skip gurad page */
+		vma->e->start += PAGE_SIZE;
 		vma->premmaped_addr += PAGE_SIZE;
 	}
 
 	if (vma_area_is(vma, VMA_FILE_PRIVATE))
-		close(vma->vma.fd);
+		close(vma->e->fd);
 
 	return size;
 }
@@ -354,7 +354,7 @@ static int restore_priv_vma_content(pid_t pid)
 			 * The lookup is over *all* possible VMAs
 			 * read from image file.
 			 */
-			while (va >= vma->vma.end) {
+			while (va >= vma->e->end) {
 				if (vma->list.next == vmas)
 					goto err_addr;
 				vma = list_entry(vma->list.next, struct vma_area, list);
@@ -366,14 +366,14 @@ static int restore_priv_vma_content(pid_t pid)
 			 * there is no guarantee that the data from pagemap is
 			 * valid.
 			 */
-			if (va < vma->vma.start)
+			if (va < vma->e->start)
 				goto err_addr;
-			else if (unlikely(!vma_priv(&vma->vma))) {
+			else if (unlikely(!vma_priv(vma->e))) {
 				pr_err("Trying to restore page for non-private VMA\n");
 				goto err_addr;
 			}
 
-			off = (va - vma->vma.start) / PAGE_SIZE;
+			off = (va - vma->e->start) / PAGE_SIZE;
 			p = decode_pointer((off) * PAGE_SIZE +
 					vma->premmaped_addr);
 
@@ -419,7 +419,7 @@ err_read:
 		if (vma->ppage_bitmap == NULL)
 			continue;
 
-		size = vma_entry_len(&vma->vma) / PAGE_SIZE;
+		size = vma_entry_len(vma->e) / PAGE_SIZE;
 		while (1) {
 			/* Find all pages, which are not shared with this child */
 			i = find_next_bit(vma->ppage_bitmap, size, i);
@@ -449,7 +449,7 @@ err_read:
 
 err_addr:
 	pr_err("Page entry address %lx outside of VMA %lx-%lx\n",
-	       va, (long)vma->vma.start, (long)vma->vma.end);
+	       va, (long)vma->e->start, (long)vma->e->end);
 	return -1;
 }
 
@@ -493,14 +493,14 @@ static int prepare_mappings(int pid)
 	pvma = list_entry(parent_vmas, struct vma_area, list);
 
 	list_for_each_entry(vma, &vmas->h, list) {
-		if (pstart > vma->vma.start) {
+		if (pstart > vma->e->start) {
 			ret = -1;
 			pr_err("VMA-s are not sorted in the image file\n");
 			break;
 		}
-		pstart = vma->vma.start;
+		pstart = vma->e->start;
 
-		if (!vma_priv(&vma->vma))
+		if (!vma_priv(vma->e))
 			continue;
 
 		ret = map_private_vma(pid, vma, addr, &pvma, parent_vmas);
@@ -535,10 +535,10 @@ static int unmap_guard_pages()
 	struct list_head *vmas = &current->rst->vmas.h;
 
 	list_for_each_entry(vma, vmas, list) {
-		if (!vma_priv(&vma->vma))
+		if (!vma_priv(vma->e))
 			continue;
 
-		if (vma->vma.flags & MAP_GROWSDOWN) {
+		if (vma->e->flags & MAP_GROWSDOWN) {
 			void *addr = decode_pointer(vma->premmaped_addr);
 
 			if (munmap(addr - PAGE_SIZE, PAGE_SIZE)) {
@@ -562,17 +562,17 @@ static int open_vmas(int pid)
 			continue;
 
 		pr_info("Opening 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" (%x) vma\n",
-				vma->vma.start, vma->vma.end,
-				vma->vma.pgoff, vma->vma.status);
+				vma->e->start, vma->e->end,
+				vma->e->pgoff, vma->e->status);
 
 		if (vma_area_is(vma, VMA_AREA_SYSVIPC))
-			ret = vma->vma.shmid;
+			ret = vma->e->shmid;
 		else if (vma_area_is(vma, VMA_ANON_SHARED))
-			ret = get_shmem_fd(pid, &vma->vma);
+			ret = get_shmem_fd(pid, vma->e);
 		else if (vma_area_is(vma, VMA_FILE_SHARED))
-			ret = get_filemap_fd(pid, &vma->vma);
+			ret = get_filemap_fd(pid, vma->e);
 		else if (vma_area_is(vma, VMA_AREA_SOCKET))
-			ret = get_socket_fd(pid, &vma->vma);
+			ret = get_socket_fd(pid, vma->e);
 		else
 			continue;
 
@@ -582,7 +582,7 @@ static int open_vmas(int pid)
 		}
 
 		pr_info("\t`- setting %d as mapping fd\n", ret);
-		vma->vma.fd = ret;
+		vma->e->fd = ret;
 	}
 
 	return ret < 0 ? -1 : 0;
@@ -1619,36 +1619,38 @@ static long restorer_get_vma_hint(pid_t pid, struct list_head *tgt_vma_list,
 	struct vma_area *t_vma, *s_vma;
 	long prev_vma_end = 0;
 	struct vma_area end_vma;
+	VmaEntry end_e;
 
-	end_vma.vma.start = end_vma.vma.end = TASK_SIZE;
+	end_vma.e = &end_e;
+	end_e.start = end_e.end = TASK_SIZE;
 	prev_vma_end = PAGE_SIZE * 0x10; /* CONFIG_LSM_MMAP_MIN_ADDR=65536 */
 
 	s_vma = list_first_entry(self_vma_list, struct vma_area, list);
 	t_vma = list_first_entry(tgt_vma_list, struct vma_area, list);
 
 	while (1) {
-		if (prev_vma_end + vma_len > s_vma->vma.start) {
+		if (prev_vma_end + vma_len > s_vma->e->start) {
 			if (s_vma->list.next == self_vma_list) {
 				s_vma = &end_vma;
 				continue;
 			}
 			if (s_vma == &end_vma)
 				break;
-			if (prev_vma_end < s_vma->vma.end)
-				prev_vma_end = s_vma->vma.end;
+			if (prev_vma_end < s_vma->e->end)
+				prev_vma_end = s_vma->e->end;
 			s_vma = list_entry(s_vma->list.next, struct vma_area, list);
 			continue;
 		}
 
-		if (prev_vma_end + vma_len > t_vma->vma.start) {
+		if (prev_vma_end + vma_len > t_vma->e->start) {
 			if (t_vma->list.next == tgt_vma_list) {
 				t_vma = &end_vma;
 				continue;
 			}
 			if (t_vma == &end_vma)
 				break;
-			if (prev_vma_end < t_vma->vma.end)
-				prev_vma_end = t_vma->vma.end;
+			if (prev_vma_end < t_vma->e->end)
+				prev_vma_end = t_vma->e->end;
 			t_vma = list_entry(t_vma->list.next, struct vma_area, list);
 			continue;
 		}
@@ -2196,9 +2198,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 		if (!vme)
 			goto err_nv;
 
-		*vme = vma->vma;
+		*vme = *vma->e;
 
-		if (vma_priv(&vma->vma))
+		if (vma_priv(vma->e))
 			vma_premmaped_start(vme) = vma->premmaped_addr;
 	}
 
diff --git a/include/vma.h b/include/vma.h
index c1190d7..60b337b 100644
--- a/include/vma.h
+++ b/include/vma.h
@@ -23,7 +23,7 @@ static inline void vm_area_list_init(struct vm_area_list *vml)
 
 struct vma_area {
 	struct list_head	list;
-	VmaEntry		vma;
+	VmaEntry		*e;
 
 	union {
 		int		vm_file_fd;
@@ -44,8 +44,8 @@ extern int collect_mappings(pid_t pid, struct vm_area_list *vma_area_list);
 extern void free_mappings(struct vm_area_list *vma_area_list);
 extern bool privately_dump_vma(struct vma_area *vma);
 
-#define vma_area_is(vma_area, s)	vma_entry_is(&((vma_area)->vma), s)
-#define vma_area_len(vma_area)		vma_entry_len(&((vma_area)->vma))
+#define vma_area_is(vma_area, s)	vma_entry_is((vma_area)->e, s)
+#define vma_area_len(vma_area)		vma_entry_len((vma_area)->e)
 #define vma_entry_is(vma, s)		(((vma)->status & (s)) == (s))
 #define vma_entry_len(vma)		((vma)->end - (vma)->start)
 
@@ -59,8 +59,8 @@ extern bool privately_dump_vma(struct vma_area *vma);
 
 static inline int in_vma_area(struct vma_area *vma, unsigned long addr)
 {
-	return addr >= (unsigned long)vma->vma.start &&
-		addr < (unsigned long)vma->vma.end;
+	return addr >= (unsigned long)vma->e->start &&
+		addr < (unsigned long)vma->e->end;
 }
 
 #endif /* __CR_VMA_H__ */
diff --git a/mem.c b/mem.c
index 1fbde26..1003872 100644
--- a/mem.c
+++ b/mem.c
@@ -111,7 +111,7 @@ static int generate_iovs(struct vma_area *vma, int pagemap, struct page_pipe *pp
 	u64 from, len;
 
 	nr_to_scan = vma_area_len(vma) / PAGE_SIZE;
-	from = vma->vma.start / PAGE_SIZE * sizeof(*map);
+	from = vma->e->start / PAGE_SIZE * sizeof(*map);
 	len = nr_to_scan * sizeof(*map);
 	if (pread(pagemap, map, len, from) != len) {
 		pr_perror("Can't read pagemap file");
@@ -122,10 +122,10 @@ static int generate_iovs(struct vma_area *vma, int pagemap, struct page_pipe *pp
 		unsigned long vaddr;
 		int ret;
 
-		if (!should_dump_page(&vma->vma, map[pfn]))
+		if (!should_dump_page(vma->e, map[pfn]))
 			continue;
 
-		vaddr = vma->vma.start + pfn * PAGE_SIZE;
+		vaddr = vma->e->start + pfn * PAGE_SIZE;
 
 		/*
 		 * If we're doing incremental dump (parent images
@@ -169,12 +169,12 @@ static struct parasite_dump_pages_args *prep_dump_pages_args(struct parasite_ctl
 	list_for_each_entry(vma, &vma_area_list->h, list) {
 		if (!privately_dump_vma(vma))
 			continue;
-		if (vma->vma.prot & PROT_READ)
+		if (vma->e->prot & PROT_READ)
 			continue;
 
-		p_vma->start = vma->vma.start;
+		p_vma->start = vma->e->start;
 		p_vma->len = vma_area_len(vma);
-		p_vma->prot = vma->vma.prot;
+		p_vma->prot = vma->e->prot;
 
 		args->nr_vmas++;
 		p_vma++;
@@ -371,23 +371,23 @@ int prepare_mm_pid(struct pstree_item *i)
 		}
 
 		ri->vmas.nr++;
-		vma->vma = *vi;
+		*vma->e = *vi;
 		list_add_tail(&vma->list, &ri->vmas.h);
 		vma_entry__free_unpacked(vi, NULL);
 
-		if (vma_priv(&vma->vma)) {
+		if (vma_priv(vma->e)) {
 			ri->vmas.priv_size += vma_area_len(vma);
-			if (vma->vma.flags & MAP_GROWSDOWN)
+			if (vma->e->flags & MAP_GROWSDOWN)
 				ri->vmas.priv_size += PAGE_SIZE;
 		}
 
-		pr_info("vma 0x%"PRIx64" 0x%"PRIx64"\n", vma->vma.start, vma->vma.end);
+		pr_info("vma 0x%"PRIx64" 0x%"PRIx64"\n", vma->e->start, vma->e->end);
 
 		if (!vma_area_is(vma, VMA_ANON_SHARED) ||
 				vma_area_is(vma, VMA_AREA_SYSVIPC))
 			continue;
 
-		ret = collect_shmem(pid, &vma->vma);
+		ret = collect_shmem(pid, vma->e);
 		if (ret)
 			break;
 	}
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 2b592ac..2bc2ac0 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -46,9 +46,9 @@ static int can_run_syscall(unsigned long ip, unsigned long start, unsigned long
 
 static int syscall_fits_vma_area(struct vma_area *vma_area)
 {
-	return can_run_syscall((unsigned long)vma_area->vma.start,
-			       (unsigned long)vma_area->vma.start,
-			       (unsigned long)vma_area->vma.end);
+	return can_run_syscall((unsigned long)vma_area->e->start,
+			       (unsigned long)vma_area->e->start,
+			       (unsigned long)vma_area->e->end);
 }
 
 static struct vma_area *get_vma_by_ip(struct list_head *vma_area_list, unsigned long ip)
@@ -56,9 +56,9 @@ static struct vma_area *get_vma_by_ip(struct list_head *vma_area_list, unsigned
 	struct vma_area *vma_area;
 
 	list_for_each_entry(vma_area, vma_area_list, list) {
-		if (vma_area->vma.start >= TASK_SIZE)
+		if (vma_area->e->start >= TASK_SIZE)
 			continue;
-		if (!(vma_area->vma.prot & PROT_EXEC))
+		if (!(vma_area->e->prot & PROT_EXEC))
 			continue;
 		if (syscall_fits_vma_area(vma_area))
 			return vma_area;
@@ -1048,7 +1048,7 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_
 		goto err;
 	}
 
-	ctl->syscall_ip	= vma_area->vma.start;
+	ctl->syscall_ip	= vma_area->e->start;
 
 	return ctl;
 
diff --git a/proc_parse.c b/proc_parse.c
index 4ca80bd..441992e 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -105,29 +105,29 @@ static int parse_vmflags(char *buf, struct vma_area *vma_area)
 	do {
 		/* mmap() block */
 		if (_vmflag_match(tok, "gd"))
-			vma_area->vma.flags |= MAP_GROWSDOWN;
+			vma_area->e->flags |= MAP_GROWSDOWN;
 		else if (_vmflag_match(tok, "lo"))
-			vma_area->vma.flags |= MAP_LOCKED;
+			vma_area->e->flags |= MAP_LOCKED;
 		else if (_vmflag_match(tok, "nr"))
-			vma_area->vma.flags |= MAP_NORESERVE;
+			vma_area->e->flags |= MAP_NORESERVE;
 		else if (_vmflag_match(tok, "ht"))
-			vma_area->vma.flags |= MAP_HUGETLB;
+			vma_area->e->flags |= MAP_HUGETLB;
 
 		/* madvise() block */
 		if (_vmflag_match(tok, "sr"))
-			vma_area->vma.madv |= (1ul << MADV_SEQUENTIAL);
+			vma_area->e->madv |= (1ul << MADV_SEQUENTIAL);
 		else if (_vmflag_match(tok, "rr"))
-			vma_area->vma.madv |= (1ul << MADV_RANDOM);
+			vma_area->e->madv |= (1ul << MADV_RANDOM);
 		else if (_vmflag_match(tok, "dc"))
-			vma_area->vma.madv |= (1ul << MADV_DONTFORK);
+			vma_area->e->madv |= (1ul << MADV_DONTFORK);
 		else if (_vmflag_match(tok, "dd"))
-			vma_area->vma.madv |= (1ul << MADV_DONTDUMP);
+			vma_area->e->madv |= (1ul << MADV_DONTDUMP);
 		else if (_vmflag_match(tok, "mg"))
-			vma_area->vma.madv |= (1ul << MADV_MERGEABLE);
+			vma_area->e->madv |= (1ul << MADV_MERGEABLE);
 		else if (_vmflag_match(tok, "hg"))
-			vma_area->vma.madv |= (1ul << MADV_HUGEPAGE);
+			vma_area->e->madv |= (1ul << MADV_HUGEPAGE);
 		else if (_vmflag_match(tok, "nh"))
-			vma_area->vma.madv |= (1ul << MADV_NOHUGEPAGE);
+			vma_area->e->madv |= (1ul << MADV_NOHUGEPAGE);
 
 		/*
 		 * Anything else is just ignored.
@@ -136,8 +136,8 @@ static int parse_vmflags(char *buf, struct vma_area *vma_area)
 
 #undef _vmflag_match
 
-	if (vma_area->vma.madv)
-		vma_area->vma.has_madv = true;
+	if (vma_area->e->madv)
+		vma_area->e->has_madv = true;
 
 	return 0;
 }
@@ -173,17 +173,17 @@ static int vma_get_mapfile(struct vma_area *vma, DIR *mfd,
 		struct vma_area *prev = prev_vfi->vma;
 
 		pr_debug("vma %lx borrows vfi from previous %lx\n",
-				vma->vma.start, prev->vma.start);
+				vma->e->start, prev->e->start);
 		vma->vm_file_fd = prev->vm_file_fd;
-		if (prev->vma.status & VMA_AREA_SOCKET)
-			vma->vma.status |= VMA_AREA_SOCKET | VMA_AREA_REGULAR;
+		if (prev->e->status & VMA_AREA_SOCKET)
+			vma->e->status |= VMA_AREA_SOCKET | VMA_AREA_REGULAR;
 		vma->file_borrowed = true;
 
 		return 0;
 	}
 
 	/* Figure out if it's file mapping */
-	snprintf(path, sizeof(path), "%lx-%lx", vma->vma.start, vma->vma.end);
+	snprintf(path, sizeof(path), "%lx-%lx", vma->e->start, vma->e->end);
 
 	/*
 	 * Note that we "open" it in dumper process space
@@ -202,8 +202,8 @@ static int vma_get_mapfile(struct vma_area *vma, DIR *mfd,
 				return -1;
 
 			pr_info("Found socket %"PRIu64" mapping @%lx\n",
-					buf.st_ino, vma->vma.start);
-			vma->vma.status |= VMA_AREA_SOCKET | VMA_AREA_REGULAR;
+					buf.st_ino, vma->e->start);
+			vma->e->status |= VMA_AREA_SOCKET | VMA_AREA_REGULAR;
 			vma->vm_socket_id = buf.st_ino;
 		} else if (errno != ENOENT)
 			return -1;
@@ -251,7 +251,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_file
 			if (!strncmp(buf, "Nonlinear", 9)) {
 				BUG_ON(!vma_area);
 				pr_err("Nonlinear mapping found %016"PRIx64"-%016"PRIx64"\n",
-				       vma_area->vma.start, vma_area->vma.end);
+				       vma_area->e->start, vma_area->e->end);
 				/*
 				 * VMA is already on list and will be
 				 * freed later as list get destroyed.
@@ -269,9 +269,9 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_file
 
 		if (vma_area) {
 			/* If we've split the stack vma, only the lowest one has the guard page. */
-			if ((vma_area->vma.flags & MAP_GROWSDOWN) && !prev_growsdown)
-				vma_area->vma.start -= PAGE_SIZE; /* Guard page */
-			prev_growsdown = (bool)(vma_area->vma.flags & MAP_GROWSDOWN);
+			if ((vma_area->e->flags & MAP_GROWSDOWN) && !prev_growsdown)
+				vma_area->e->start -= PAGE_SIZE; /* Guard page */
+			prev_growsdown = (bool)(vma_area->e->flags & MAP_GROWSDOWN);
 
 			list_add_tail(&vma_area->list, &vma_area_list->h);
 			vma_area_list->nr++;
@@ -303,42 +303,42 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_file
 			goto err;
 		}
 
-		vma_area->vma.start	= start;
-		vma_area->vma.end	= end;
-		vma_area->vma.pgoff	= pgoff;
-		vma_area->vma.prot	= PROT_NONE;
+		vma_area->e->start	= start;
+		vma_area->e->end	= end;
+		vma_area->e->pgoff	= pgoff;
+		vma_area->e->prot	= PROT_NONE;
 
 		if (vma_get_mapfile(vma_area, map_files_dir, &vfi, &prev_vfi))
 			goto err_bogus_mapfile;
 
 		if (r == 'r')
-			vma_area->vma.prot |= PROT_READ;
+			vma_area->e->prot |= PROT_READ;
 		if (w == 'w')
-			vma_area->vma.prot |= PROT_WRITE;
+			vma_area->e->prot |= PROT_WRITE;
 		if (x == 'x')
-			vma_area->vma.prot |= PROT_EXEC;
+			vma_area->e->prot |= PROT_EXEC;
 
 		if (s == 's')
-			vma_area->vma.flags = MAP_SHARED;
+			vma_area->e->flags = MAP_SHARED;
 		else if (s == 'p')
-			vma_area->vma.flags = MAP_PRIVATE;
+			vma_area->e->flags = MAP_PRIVATE;
 		else {
 			pr_err("Unexpected VMA met (%c)\n", s);
 			goto err;
 		}
 
-		if (vma_area->vma.status != 0) {
+		if (vma_area->e->status != 0) {
 			continue;
 		} else if (strstr(buf, "[vsyscall]") || strstr(buf, "[vectors]")) {
-			vma_area->vma.status |= VMA_AREA_VSYSCALL;
+			vma_area->e->status |= VMA_AREA_VSYSCALL;
 		} else if (strstr(buf, "[vdso]")) {
-			vma_area->vma.status |= VMA_AREA_REGULAR;
-			if ((vma_area->vma.prot & VDSO_PROT) == VDSO_PROT)
-				vma_area->vma.status |= VMA_AREA_VDSO;
+			vma_area->e->status |= VMA_AREA_REGULAR;
+			if ((vma_area->e->prot & VDSO_PROT) == VDSO_PROT)
+				vma_area->e->status |= VMA_AREA_VDSO;
 		} else if (strstr(buf, "[heap]")) {
-			vma_area->vma.status |= VMA_AREA_REGULAR | VMA_AREA_HEAP;
+			vma_area->e->status |= VMA_AREA_REGULAR | VMA_AREA_HEAP;
 		} else {
-			vma_area->vma.status = VMA_AREA_REGULAR;
+			vma_area->e->status = VMA_AREA_REGULAR;
 		}
 
 		/*
@@ -353,9 +353,9 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_file
 			 * Status is copied as-is as it should be zero here,
 			 * and have full match with the previous.
 			 */
-			vma_area->vma.flags |= (prev->vma.flags & MAP_ANONYMOUS);
-			vma_area->vma.status = prev->vma.status;
-			vma_area->vma.shmid = prev->vma.shmid;
+			vma_area->e->flags |= (prev->e->flags & MAP_ANONYMOUS);
+			vma_area->e->status = prev->e->status;
+			vma_area->e->shmid = prev->e->shmid;
 			vma_area->st = prev->st;
 		} else if (vma_area->vm_file_fd >= 0) {
 			struct stat *st_buf;
@@ -380,33 +380,33 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_file
 			 * otherwise it's some file mapping.
 			 */
 			if (is_anon_shmem_map(st_buf->st_dev)) {
-				if (!(vma_area->vma.flags & MAP_SHARED))
+				if (!(vma_area->e->flags & MAP_SHARED))
 					goto err_bogus_mapping;
-				vma_area->vma.flags  |= MAP_ANONYMOUS;
-				vma_area->vma.status |= VMA_ANON_SHARED;
-				vma_area->vma.shmid = st_buf->st_ino;
+				vma_area->e->flags  |= MAP_ANONYMOUS;
+				vma_area->e->status |= VMA_ANON_SHARED;
+				vma_area->e->shmid = st_buf->st_ino;
 
 				if (!strcmp(file_path, "/SYSV")) {
 					pr_info("path: %s\n", file_path);
-					vma_area->vma.status |= VMA_AREA_SYSVIPC;
+					vma_area->e->status |= VMA_AREA_SYSVIPC;
 				}
 			} else {
-				if (vma_area->vma.flags & MAP_PRIVATE)
-					vma_area->vma.status |= VMA_FILE_PRIVATE;
+				if (vma_area->e->flags & MAP_PRIVATE)
+					vma_area->e->status |= VMA_FILE_PRIVATE;
 				else
-					vma_area->vma.status |= VMA_FILE_SHARED;
+					vma_area->e->status |= VMA_FILE_SHARED;
 			}
 		} else {
 			/*
 			 * No file but mapping -- anonymous one.
 			 */
-			if (vma_area->vma.flags & MAP_SHARED) {
-				vma_area->vma.status |= VMA_ANON_SHARED;
-				vma_area->vma.shmid = vfi.ino;
+			if (vma_area->e->flags & MAP_SHARED) {
+				vma_area->e->status |= VMA_ANON_SHARED;
+				vma_area->e->shmid = vfi.ino;
 			} else {
-				vma_area->vma.status |= VMA_ANON_PRIVATE;
+				vma_area->e->status |= VMA_ANON_PRIVATE;
 			}
-			vma_area->vma.flags  |= MAP_ANONYMOUS;
+			vma_area->e->flags  |= MAP_ANONYMOUS;
 		}
 	}
 
@@ -425,8 +425,8 @@ err:
 
 err_bogus_mapping:
 	pr_err("Bogus mapping 0x%"PRIx64"-0x%"PRIx64" (flags: %#x vm_file_fd: %d)\n",
-	       vma_area->vma.start, vma_area->vma.end,
-	       vma_area->vma.flags, vma_area->vm_file_fd);
+	       vma_area->e->start, vma_area->e->end,
+	       vma_area->e->flags, vma_area->vm_file_fd);
 	goto err;
 
 err_bogus_mapfile:
diff --git a/sk-packet.c b/sk-packet.c
index 2ed7ca6..410da8f 100644
--- a/sk-packet.c
+++ b/sk-packet.c
@@ -221,8 +221,8 @@ int dump_socket_map(struct vma_area *vma)
 		return -1;
 	}
 
-	pr_info("Dumping socket map %x -> %"PRIx64"\n", sd->file_id, vma->vma.start);
-	vma->vma.shmid = sd->file_id;
+	pr_info("Dumping socket map %x -> %"PRIx64"\n", sd->file_id, vma->e->start);
+	vma->e->shmid = sd->file_id;
 	return 0;
 }
 
diff --git a/util.c b/util.c
index 053980a..38d8dd9 100644
--- a/util.c
+++ b/util.c
@@ -51,7 +51,7 @@ static void vma_opt_str(const struct vma_area *v, char *opt)
 	int p = 0;
 
 #define opt2s(_o, _s)	do {				\
-		if (v->vma.status & _o)			\
+		if (v->e->status & _o)			\
 			p += sprintf(opt + p, _s " ");	\
 	} while (0)
 
@@ -83,12 +83,12 @@ void pr_vma(unsigned int loglevel, const struct vma_area *vma_area)
 	vma_opt_str(vma_area, opt);
 	print_on_level(loglevel, "%#"PRIx64"-%#"PRIx64" (%"PRIi64"K) prot %#x flags %#x off %#"PRIx64" "
 			"%s shmid: %#"PRIx64"\n",
-			vma_area->vma.start, vma_area->vma.end,
+			vma_area->e->start, vma_area->e->end,
 			KBYTES(vma_area_len(vma_area)),
-			vma_area->vma.prot,
-			vma_area->vma.flags,
-			vma_area->vma.pgoff,
-			opt, vma_area->vma.shmid);
+			vma_area->e->prot,
+			vma_area->e->flags,
+			vma_area->e->pgoff,
+			opt, vma_area->e->shmid);
 }
 
 int close_safe(int *fd)
@@ -651,11 +651,12 @@ struct vma_area *alloc_vma_area(void)
 {
 	struct vma_area *p;
 
-	p = xzalloc(sizeof(*p));
+	p = xzalloc(sizeof(*p) + sizeof(VmaEntry));
 	if (p) {
-		vma_entry__init(&p->vma);
+		p->e = (VmaEntry *)(p + 1);
+		vma_entry__init(p->e);
 		p->vm_file_fd = -1;
-		p->vma.fd = -1;
+		p->e->fd = -1;
 	}
 
 	return p;
-- 
1.8.4.2


More information about the CRIU mailing list