[CRIU] [PATCH RFC 8/8] criu: lazy-pages: enable remoting of lazy pages
Mike Rapoport
rppt at linux.vnet.ibm.com
Sat May 21 03:49:42 PDT 2016
The remote lazy pages variant can be run as follows:
src# criu dump -t <pid> --lazy-pages --port 9876 -D /tmp/1 &
src# while ! sudo fuser 9876/tcp ; do sleep 1; done
src# scp -r /tmp/1/ dst:/tmp/
dst# criu lazy-pages --lazy-addr /tmp/uffd.sock --page-server \
--address dst --port 9876 -D /tmp/1 &
dst# criu restore --lazy-pages --lazy-addr /tmp/uffd.sock -D /tmp/1
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/cr-dump.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
criu/page-read.c | 2 +-
criu/uffd.c | 9 ++++++++-
3 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index 1a551b4..faca73b 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -1298,7 +1298,7 @@ static int dump_one_task(struct pstree_item *item)
}
}
- ret = parasite_dump_pages_seized(parasite_ctl, &vmas, false);
+ ret = parasite_dump_pages_seized(parasite_ctl, &vmas, opts.lazy_pages);
if (ret)
goto err_cure;
@@ -1338,7 +1338,10 @@ static int dump_one_task(struct pstree_item *item)
goto err;
}
- ret = parasite_cure_seized(parasite_ctl);
+ if (opts.lazy_pages)
+ ret = parasite_cure_remote(parasite_ctl);
+ else
+ ret = parasite_cure_seized(parasite_ctl);
if (ret) {
pr_err("Can't cure (pid: %d) from parasite\n", pid);
goto err;
@@ -1525,6 +1528,49 @@ err:
return cr_pre_dump_finish(ret);
}
+static int cr_lazy_mem_dump(void)
+{
+ struct pstree_item *item;
+ int ret = 0;
+
+ pr_info("Lazy pages: pre-dumping memory\n");
+ for_each_pstree_item(item) {
+ struct parasite_ctl *ctl = item->parasite_ctl;
+ struct page_xfer xfer;
+
+ timing_start(TIME_MEMWRITE);
+ ret = open_page_xfer(&xfer, CR_FD_PAGEMAP, ctl->pid.virt);
+ if (ret < 0)
+ goto err;
+
+ ret = page_xfer_dump_pages(&xfer, ctl->mem_pp, 0, false);
+
+ xfer.close(&xfer);
+
+ if (ret)
+ goto err;
+
+ timing_stop(TIME_MEMWRITE);
+ }
+
+ pr_info("Starting lazy pages server\n");
+ ret = cr_page_server(false, -1);
+
+ for_each_pstree_item(item) {
+ struct parasite_ctl *ctl = item->parasite_ctl;
+ destroy_page_pipe(ctl->mem_pp);
+ parasite_cure_local(ctl);
+ }
+
+err:
+ if (ret)
+ pr_err("Lazy pages transfer FAILED.\n");
+ else
+ pr_info("Lazy pages transfer finished successfully\n");
+
+ return ret;
+}
+
static int cr_dump_finish(int ret)
{
int post_dump_ret = 0;
@@ -1583,6 +1629,10 @@ static int cr_dump_finish(int ret)
network_unlock();
delete_link_remaps();
}
+
+ if (opts.lazy_pages)
+ ret = cr_lazy_mem_dump();
+
pstree_switch_state(root_item,
(ret || post_dump_ret) ?
TASK_ALIVE : opts.final_state);
diff --git a/criu/page-read.c b/criu/page-read.c
index e5ec76a..203b170 100644
--- a/criu/page-read.c
+++ b/criu/page-read.c
@@ -92,7 +92,7 @@ static void skip_pagemap_pages(struct page_read *pr, unsigned long len)
return;
pr_debug("\tpr%u Skip %lu bytes from page-dump\n", pr->id, len);
- if (!pr->pe->in_parent)
+ if (!pr->pe->in_parent && !opts.lazy_pages)
lseek(img_raw_fd(pr->pi), len, SEEK_CUR);
pr->cvaddr += len;
}
diff --git a/criu/uffd.c b/criu/uffd.c
index ef1ff89..d140d38 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -33,6 +33,7 @@
#include "xmalloc.h"
#include "syscall-codes.h"
#include "restorer.h"
+#include "page-xfer.h"
#undef LOG_PREFIX
#define LOG_PREFIX "lazy-pages: "
@@ -363,7 +364,10 @@ static int uffd_copy_page(struct lazy_pages_info *lpi, __u64 address,
struct uffdio_copy uffdio_copy;
int rc;
- rc = get_page(lpi, address, dest);
+ if (opts.use_page_server)
+ rc = get_remote_pages(lpi->pid, address, 1, dest);
+ else
+ rc = get_page(lpi, address, dest);
if (rc <= 0)
return rc;
@@ -861,6 +865,9 @@ int cr_lazy_pages()
if (prepare_uffds(epollfd))
return -1;
+ if (connect_to_page_server())
+ return -1;
+
ret = handle_requests(epollfd, events);
lpi_hash_fini();
--
1.9.1
More information about the CRIU
mailing list