[CRIU] [PATCH 1/2] dedup: make bunched auto-deduplication on restore for shmem

Tikhomirov Pavel snorcht at gmail.com
Tue Mar 11 00:07:56 PDT 2014


in restore_shmem_content() put pe, fd, fd_pg into page_read struct

Signed-off-by: Tikhomirov Pavel <snorcht at gmail.com>
---
 shmem.c | 59 +++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 20 deletions(-)

diff --git a/shmem.c b/shmem.c
index 2f8e7e9..ee79e85 100644
--- a/shmem.c
+++ b/shmem.c
@@ -6,6 +6,7 @@
 #include "pid.h"
 #include "shmem.h"
 #include "image.h"
+#include "cr_options.h"
 #include "page-pipe.h"
 #include "page-xfer.h"
 #include "rst-malloc.h"
@@ -106,16 +107,22 @@ static int shmem_wait_and_open(int pid, struct shmem_info *si)
 
 static int restore_shmem_content(void *addr, struct shmem_info *si)
 {
-	int fd, fd_pg, ret = 0;
-
-	fd = open_image(CR_FD_SHMEM_PAGEMAP, O_RSTR, si->shmid);
-	if (fd < 0) {
-		fd_pg = open_image(CR_FD_SHM_PAGES_OLD, O_RSTR, si->shmid);
-		if (fd_pg < 0)
+	struct page_read pr;
+	int ret = 0;
+	unsigned long off_real = 0;
+
+	pr.bunch.iov_base = NULL;
+	pr.bunch.iov_len = 0;
+	pr.id = si->shmid;
+
+	pr.fd = open_image(CR_FD_SHMEM_PAGEMAP, opts.auto_dedup ? O_RDWR : O_RSTR, si->shmid);
+	if (pr.fd < 0) {
+		pr.fd_pg = open_image(CR_FD_SHM_PAGES_OLD, opts.auto_dedup ? O_RDWR : O_RSTR, si->shmid);
+		if (pr.fd_pg < 0)
 			goto err_unmap;
 	} else {
-		fd_pg = open_pages_image(O_RSTR, fd);
-		if (fd_pg < 0)
+		pr.fd_pg = open_pages_image(opts.auto_dedup ? O_RDWR : O_RSTR, pr.fd);
+		if (pr.fd_pg < 0)
 			goto out_close;
 	}
 
@@ -123,21 +130,19 @@ static int restore_shmem_content(void *addr, struct shmem_info *si)
 		unsigned long vaddr;
 		unsigned nr_pages;
 
-		if (fd >= 0) {
-			PagemapEntry *pe;
-
-			ret = pb_read_one_eof(fd, &pe, PB_PAGEMAP);
+		if (pr.fd >= 0) {
+			ret = pb_read_one_eof(pr.fd, &pr.pe, PB_PAGEMAP);
 			if (ret <= 0)
 				break;
 
-			vaddr = (unsigned long)decode_pointer(pe->vaddr);
-			nr_pages = pe->nr_pages;
+			vaddr = (unsigned long)decode_pointer(pr.pe->vaddr);
+			nr_pages = pr.pe->nr_pages;
 
-			pagemap_entry__free_unpacked(pe, NULL);
+			pagemap_entry__free_unpacked(pr.pe, NULL);
 		} else {
 			__u64 img_vaddr;
 
-			ret = read_img_eof(fd_pg, &img_vaddr);
+			ret = read_img_eof(pr.fd_pg, &img_vaddr);
 			if (ret <= 0)
 				break;
 
@@ -148,20 +153,34 @@ static int restore_shmem_content(void *addr, struct shmem_info *si)
 		if (vaddr + nr_pages * PAGE_SIZE > si->size)
 			break;
 
-		ret = read(fd_pg, addr + vaddr, nr_pages * PAGE_SIZE);
+		off_real = lseek(pr.fd_pg, 0, SEEK_CUR);
+
+		ret = read(pr.fd_pg, addr + vaddr, nr_pages * PAGE_SIZE);
 		if (ret != nr_pages * PAGE_SIZE) {
 			ret = -1;
 			break;
 		}
 
+		if (opts.auto_dedup) {
+			ret = punch_hole(&pr, off_real, nr_pages * PAGE_SIZE, false);
+			if (ret == -1) {
+				break;
+			}
+		}
+	}
+
+	if (pr.bunch.iov_len > 0) {
+		ret = punch_hole(&pr, 0, 0, true);
+
+		pr.bunch.iov_len = 0;
 	}
 
-	close_safe(&fd_pg);
-	close_safe(&fd);
+	close_safe(&pr.fd_pg);
+	close_safe(&pr.fd);
 	return ret;
 
 out_close:
-	close_safe(&fd);
+	close_safe(&pr.fd);
 err_unmap:
 	munmap(addr,  si->size);
 	return -1;
-- 
1.8.3.2



More information about the CRIU mailing list