[CRIU] [PATCH 13/14]v3 deduplication: add auto-dedup local

Tikhomirov Pavel snorcht at gmail.com
Tue Dec 17 07:27:12 PST 2013


Signed-off-by: Tikhomirov Pavel <snorcht at gmail.com>
---
 include/page-read.h |    1 +
 include/page-xfer.h |    2 ++
 page-read.c         |    4 +---
 page-xfer.c         |   34 ++++++++++++++++++++++++++++++++++
 4 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/include/page-read.h b/include/page-read.h
index 3d32371..eccaaa4 100644
--- a/include/page-read.h
+++ b/include/page-read.h
@@ -67,6 +67,7 @@ struct page_read {
 };
 
 extern int open_page_read(int pid, struct page_read *);
+extern int open_page_at(int dfd, int pid, struct page_read *pr, int flags);
 extern int open_page_rw(int pid, struct page_read *);
 extern inline void pagemap2iovec(PagemapEntry *pe, struct iovec *iov);
 extern int seek_pagemap_page(struct page_read *pr, unsigned long vaddr, bool warn);
diff --git a/include/page-xfer.h b/include/page-xfer.h
index a681eb6..f376702 100644
--- a/include/page-xfer.h
+++ b/include/page-xfer.h
@@ -1,5 +1,6 @@
 #ifndef __CR_PAGE_XFER__H__
 #define __CR_PAGE_XFER__H__
+#include "page-read.h"
 
 extern int cr_page_server(bool daemon_mode);
 
@@ -24,6 +25,7 @@ struct page_xfer {
 		int fd_pg;
 		u64 dst_id;
 	};
+	struct page_read* parent;
 };
 
 extern int open_page_xfer(struct page_xfer *xfer, int fd_type, long id);
diff --git a/page-read.c b/page-read.c
index e10e131..60bbc3a 100644
--- a/page-read.c
+++ b/page-read.c
@@ -163,8 +163,6 @@ static void close_page_read(struct page_read *pr)
 	close(pr->fd);
 }
 
-static int open_page_at(int dfd, int pid, struct page_read *pr, int flags);
-
 static int try_open_parent(int dfd, int pid, struct page_read *pr, int flags)
 {
 	int pfd;
@@ -197,7 +195,7 @@ err_cl:
 	return -1;
 }
 
-static int open_page_at(int dfd, int pid, struct page_read *pr, int flags)
+int open_page_at(int dfd, int pid, struct page_read *pr, int flags)
 {
 	pr->pe = NULL;
 
diff --git a/page-xfer.c b/page-xfer.c
index ff2cda0..c3f4f9b 100644
--- a/page-xfer.c
+++ b/page-xfer.c
@@ -1,6 +1,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <linux/falloc.h>
 #include <unistd.h>
 #include <fcntl.h>
 
@@ -440,11 +441,19 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id)
 static int write_pagemap_loc(struct page_xfer *xfer,
 		struct iovec *iov)
 {
+	int ret;
 	PagemapEntry pe = PAGEMAP_ENTRY__INIT;
 
 	pe.vaddr = encode_pointer(iov->iov_base);
 	pe.nr_pages = iov->iov_len / PAGE_SIZE;
 
+	if (opts.auto_dedup && !opts.use_page_server && xfer->parent != NULL) {
+		ret = dedup_one_iovec(xfer->parent, iov);
+		if (ret == -1) {
+			pr_perror("Auto-deduplication failed");
+			return ret;
+		}
+	}
 	return pb_write_one(xfer->fd, &pe, PB_PAGEMAP);
 }
 
@@ -546,6 +555,31 @@ static int open_page_local_xfer(struct page_xfer *xfer, int fd_type, long id)
 		return -1;
 	}
 
+	if (opts.auto_dedup && !opts.use_page_server) {
+		int ret;
+		int pfd;
+		pfd = openat(get_service_fd(IMG_FD_OFF), CR_PARENT_LINK, O_RDONLY);
+		if (pfd < 0 && errno == ENOENT)
+			goto out;
+
+		xfer->parent = xmalloc(sizeof(*xfer->parent));
+		if (!xfer->parent) {
+			close(pfd);
+			return -1;
+		}
+
+		ret = open_page_at(pfd, id, xfer->parent, O_RDWR);
+		if (ret) {
+			pr_perror("Can't dedup old image format");
+			xfree(xfer->parent);
+			xfer->parent = NULL;
+			close(pfd);
+			goto out;
+		}
+		close(pfd);
+	}
+
+out:
 	xfer->write_pagemap = write_pagemap_loc;
 	xfer->write_pages = write_pages_loc;
 	xfer->write_hole = write_pagehole_loc;
-- 
1.7.9.5



More information about the CRIU mailing list