[CRIU] [PATCH 06/10] deduplication: look up for old pages in previous snapshot
Andrew Vagin
avagin at parallels.com
Tue Nov 19 04:06:38 PST 2013
On Tue, Nov 19, 2013 at 02:28:25PM +0400, Tikhomirov Pavel wrote:
> old snapshot from "parent" symlink, and pids from pagemap-PID.img files
>
> Signed-off-by: Tikhomirov Pavel <snorcht at gmail.com>
> ---
> cr-dedup.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++
> include/page-read.h | 1 +
> page-read.c | 24 ++++++++---
> 3 files changed, 135 insertions(+), 7 deletions(-)
>
> diff --git a/cr-dedup.c b/cr-dedup.c
> index 225ab2d..a8df351 100644
> --- a/cr-dedup.c
> +++ b/cr-dedup.c
> @@ -1,8 +1,125 @@
> #include <unistd.h>
>
> #include "crtools.h"
> +#include "page-read.h"
> +#include "restorer.h"
> +
> +int cr_dedup_one_pagemap(int pid);
>
> int cr_dedup(void)
> {
> + int close_ret, ret = 0;
> + int pid;
> + DIR * dirp;
> + struct dirent *ent;
> +
> + dirp = opendir(CR_PARENT_LINK);
> + if (dirp == NULL) {
> + pr_err("Can't enter previous snapshot folder, error=%d\n", errno);
> + ret = -1;
> + goto err;
> + }
> +
> + while (1) {
> + errno = 0;
> + ent = readdir(dirp);
> + if (ent == NULL) {
> + if (errno) {
> + pr_err("Failed readdir, error=%d\n", errno);
> + ret = -1;
> + goto err;
> + }
> + break;
> + }
> +
> + ret = sscanf(ent->d_name, "pagemap-%d.img", &pid);
> + if (ret == 1) {
> + pr_info("pid=%d\n", pid);
> + ret = cr_dedup_one_pagemap(pid);
> + if (ret < 0)
> + break;
> + }
> + }
> +
> +err:
> + if (dirp) {
> + close_ret = closedir(dirp);
> + if (close_ret == -1)
> + return close_ret;
> + }
> +
> + if (ret < 0)
> + return ret;
> +
> + pr_info("Deduplicated\n");
> + return 0;
> +}
> +
> +int cr_dedup_one_pagemap(int pid)
> +{
> + int ret;
> + struct page_read pr;
> + struct page_read * prp;
> + unsigned long off, off_real = 0;
> + struct iovec iov;
> +
> + ret = open_page_rw(pid, &pr);
> + if (ret) {
> + ret = -1;
> + goto exit;
> + }
> +
> + prp = pr.parent;
> + if (!prp)
> + goto exit;
> +
> + ret = pr.get_pagemap(&pr, &iov);
> + if (ret <= 0)
> + goto exit;
> +
> + off = (unsigned long)iov.iov_base;
^^^^^^^
> + while (1) {
> + unsigned long iov_end, piov_end;
Can we change unsigned long on void * to avoid type conversion
> + struct iovec piov;
> +
> + iov_end = (unsigned long)iov.iov_base + iov.iov_len;
^^^^^^^
> +
> + ret = seek_pagemap_page(prp, off, DO_NOT_PRINT_ERROR);
> + if (ret == -1) {
> + if (off < prp->cvaddr)
> + if (prp->cvaddr < iov_end)
> + off = prp->cvaddr;
> + else
> + goto new_pagemap;
> + else
> + goto exit;
> + }
> +
> + if (prp->pe)
> + pagemap2iovec(prp->pe, &piov);
> + piov_end = (unsigned long)piov.iov_base + piov.iov_len;
piov may be used uninitialized
> + off_real = lseek(prp->fd_pg, 0, SEEK_CUR);
Is this patch compilable?
off_real is not used
> +
> + /*Here to punch that pagemap*/
> +
> + if (piov_end < iov_end) {
> + off = piov_end;
> + continue;
> + }
> +new_pagemap:
> + pr.put_pagemap(&pr);
> +
> + ret = pr.get_pagemap(&pr, &iov);
> + if (ret <= 0)
> + goto exit;
> +
> + off = (unsigned long)iov.iov_base;
> + }
> +exit:
> + pr.close(&pr);
> +
> + if (ret < 0)
> + return ret;
> +
> return 0;
> }
> diff --git a/include/page-read.h b/include/page-read.h
> index 231877a..5da9d86 100644
> --- a/include/page-read.h
> +++ b/include/page-read.h
> @@ -66,6 +66,7 @@ struct page_read {
> };
>
> int open_page_read(int pid, struct page_read *);
> +int open_page_rw(int pid, struct page_read *);
> inline void pagemap2iovec(PagemapEntry *pe, struct iovec *iov);
> int seek_pagemap_page(struct page_read *pr, unsigned long vaddr, int flags);
>
> diff --git a/page-read.c b/page-read.c
> index 4fe6b86..1d51e90 100644
> --- a/page-read.c
> +++ b/page-read.c
> @@ -158,9 +158,9 @@ static void close_page_read(struct page_read *pr)
> close(pr->fd);
> }
>
> -static int open_page_read_at(int dfd, int pid, struct page_read *pr);
> +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)
> +static int try_open_parent(int dfd, int pid, struct page_read *pr, int flags)
> {
> int pfd;
> struct page_read *parent = NULL;
> @@ -173,7 +173,7 @@ static int try_open_parent(int dfd, int pid, struct page_read *pr)
> if (!parent)
> goto err_cl;
>
> - if (open_page_read_at(pfd, pid, parent)) {
> + if (open_page_at(pfd, pid, parent, flags)) {
> if (errno != ENOENT)
> goto err_free;
> xfree(parent);
> @@ -192,13 +192,13 @@ err_cl:
> return -1;
> }
>
> -static int open_page_read_at(int dfd, int pid, struct page_read *pr)
> +static int open_page_at(int dfd, int pid, struct page_read *pr, int flags)
> {
> pr->pe = NULL;
>
> pr->fd = open_image_at(dfd, CR_FD_PAGEMAP, O_RSTR, (long)pid);
> if (pr->fd < 0) {
> - pr->fd_pg = open_image_at(dfd, CR_FD_PAGES_OLD, O_RSTR, pid);
> + pr->fd_pg = open_image_at(dfd, CR_FD_PAGES_OLD, flags, pid);
> if (pr->fd_pg < 0)
> return -1;
>
> @@ -209,12 +209,12 @@ static int open_page_read_at(int dfd, int pid, struct page_read *pr)
> } else {
> static unsigned ids = 1;
>
> - if (try_open_parent(dfd, pid, pr)) {
> + if (try_open_parent(dfd, pid, pr, flags)) {
> close(pr->fd);
> return -1;
> }
>
> - pr->fd_pg = open_pages_image_at(dfd, O_RSTR, pr->fd);
> + pr->fd_pg = open_pages_image_at(dfd, flags, pr->fd);
> if (pr->fd_pg < 0) {
> close_page_read(pr);
> return -1;
> @@ -234,7 +234,17 @@ static int open_page_read_at(int dfd, int pid, struct page_read *pr)
> return 0;
> }
>
> +static int open_page_read_at(int dfd, int pid, struct page_read *pr)
> +{
> + return open_page_at(dfd, pid, pr, O_RSTR);
> +}
> +
> int open_page_read(int pid, struct page_read *pr)
> {
> return open_page_read_at(get_service_fd(IMG_FD_OFF), pid, pr);
> }
> +
> +int open_page_rw(int pid, struct page_read *pr)
> +{
> + return open_page_at(get_service_fd(IMG_FD_OFF), pid, pr, O_RDWR);
> +}
> --
> 1.7.9.5
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list