diff --git a/criu/include/pagemap.h b/criu/include/pagemap.h index 8c71805598..3ae15deb9c 100644 --- a/criu/include/pagemap.h +++ b/criu/include/pagemap.h @@ -58,6 +58,9 @@ struct page_read { /* Whether or not pages can be read in PIE code */ bool pieok; + /* Whether or not disable image deduplication*/ + bool disable_dedup; + /* Private data of reader */ struct cr_img *pmi; struct cr_img *pi; @@ -112,6 +115,8 @@ int pagemap_render_iovec(struct list_head *from, struct task_restore_args *ta); */ extern void dup_page_read(struct page_read *src, struct page_read *dst); +extern void page_read_disable_dedup(struct page_read *pr); + extern int dedup_one_iovec(struct page_read *pr, unsigned long base, unsigned long len); static inline unsigned long pagemap_len(PagemapEntry *pe) diff --git a/criu/pagemap.c b/criu/pagemap.c index 83f69bba37..85bb922596 100644 --- a/criu/pagemap.c +++ b/criu/pagemap.c @@ -261,7 +261,7 @@ static int read_local_page(struct page_read *pr, unsigned long vaddr, unsigned l break; } - if (opts.auto_dedup) { + if (opts.auto_dedup && !pr->disable_dedup) { ret = punch_hole(pr, pr->pi_off, len, false); if (ret == -1) return -1; @@ -792,6 +792,7 @@ int open_page_read_at(int dfd, unsigned long img_id, struct page_read *pr, int p pr->bunch.iov_base = NULL; pr->pmes = NULL; pr->pieok = false; + pr->disable_dedup = false; pr->pmi = open_image_at(dfd, i_typ, O_RSTR, img_id); if (!pr->pmi) @@ -852,6 +853,14 @@ int open_page_read(unsigned long img_id, struct page_read *pr, int pr_flags) #define DUP_IDS_BASE 1000 +void page_read_disable_dedup(struct page_read *pr) +{ + pr_debug("disable dedup, id: %d\n", pr->id); + pr->disable_dedup = true; + if (pr->parent) + page_read_disable_dedup(pr->parent); +} + void dup_page_read(struct page_read *src, struct page_read *dst) { static int dup_ids = 1; diff --git a/criu/uffd.c b/criu/uffd.c index e07b21b69c..98c2b7e075 100644 --- a/criu/uffd.c +++ b/criu/uffd.c @@ -1098,6 +1098,8 @@ static int handle_fork(struct lazy_pages_info *parent_lpi, struct uffd_msg *msg) lpi_get(lpi->parent); + page_read_disable_dedup(&parent_lpi->pr); + page_read_disable_dedup(&lpi->pr); return 1; out: