[CRIU] [PATCH 5/6] criu: pagemap: add PE_PRESENT flag
Mike Rapoport
rppt at linux.vnet.ibm.com
Thu Sep 8 00:39:11 PDT 2016
The PE_PRESENT flags is always set for pagemap entries that have
corresponding pages in the pages*img. Pagemap entries describing a hole
either with zero page or with pages in the parent snapshot will no have
PE_PRESENT flag set.
Pagemap entry that may be lazily restored is a special case. For the lazy
restore from disk case, both PE_LAZY and PE_PRESENT will be set in the
pagemap, but for the remote lazy pages case only PE_LAZY will be set.
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/include/pagemap.h | 6 ++++++
criu/page-xfer.c | 16 +++++++++++-----
criu/pagemap.c | 10 +++++++++-
3 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/criu/include/pagemap.h b/criu/include/pagemap.h
index f4a9285..705a9af 100644
--- a/criu/include/pagemap.h
+++ b/criu/include/pagemap.h
@@ -97,6 +97,7 @@ extern int dedup_one_iovec(struct page_read *pr, struct iovec *iov);
#define PE_PARENT (1 << 0) /* pages are in parent snapshot */
#define PE_ZERO (1 << 1) /* pages can be lazily restored */
#define PE_LAZY (1 << 2) /* pages are mapped to zero pfn */
+#define PE_PRESENT (1 << 3) /* pages are present in pages*img */
static inline bool pagemap_in_parent(PagemapEntry *pe)
{
@@ -113,4 +114,9 @@ static inline bool pagemap_lazy(PagemapEntry *pe)
return !!(pe->flags & PE_LAZY);
}
+static inline bool pagemap_present(PagemapEntry *pe)
+{
+ return !!(pe->flags & PE_PRESENT);
+}
+
#endif /* __CR_PAGE_READ_H__ */
diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index 68dba86..798ea0b 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -440,6 +440,7 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
for (i = 0; i < ppb->nr_segs; i++) {
struct iovec iov = get_iov(ppb->iov, i, pp->flags & PP_COMPAT);
+ u32 flags = PE_PRESENT;
ret = dump_holes(xfer, pp, &cur_hole, iov.iov_base, off);
if (ret)
@@ -450,13 +451,18 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
pr_debug("\tp %p [%u]\n", iov.iov_base,
(unsigned int)(iov.iov_len / PAGE_SIZE));
- if (!dump_lazy && ppb->flags & PPB_LAZY) {
- if (xfer->write_hole(xfer, &iov, PS_IOV_LAZY))
- return -1;
- continue;
+ if (ppb->flags & PPB_LAZY) {
+ if (!dump_lazy) {
+ if (xfer->write_hole(xfer, &iov,
+ PS_IOV_LAZY))
+ return -1;
+ continue;
+ } else {
+ flags |= PE_LAZY;
+ }
}
- if (xfer->write_pagemap(xfer, &iov, 0))
+ if (xfer->write_pagemap(xfer, &iov, flags))
return -1;
if (xfer->write_pages(xfer, ppb->p[0], iov.iov_len))
return -1;
diff --git a/criu/pagemap.c b/criu/pagemap.c
index aaef5a4..71ae11e 100644
--- a/criu/pagemap.c
+++ b/criu/pagemap.c
@@ -158,7 +158,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 (!pagemap_in_parent(pr->pe) && !pagemap_zero(pr->pe) && !pagemap_lazy(pr->pe))
+ if (pagemap_present(pr->pe))
pr->pi_off += len;
pr->cvaddr += len;
}
@@ -360,8 +360,16 @@ err_cl:
static void init_compat_pagemap_entry(PagemapEntry *pe)
{
+ /*
+ * pagemap image generated with older version will either
+ * contain a hole because the pages are in the parent
+ * shanpshot or a pagemap that should be marked with
+ * PE_PRESENT
+ */
if (pe->has_in_parent && pe->in_parent)
pe->flags |= PE_PARENT;
+ else if (!pe->has_flags)
+ pe->flags = PE_PRESENT;
}
/*
--
1.9.1
More information about the CRIU
mailing list