criu/criu/cr-dedup.c
Andrei Vagin 2e26b36d44 pagemap: print page regions in the format start - end
During investigations, it’s much easier to read logs when regions are
printed in the start - end format rather than `start/size`.

In addition, all page counters and memory sizes are now printed in
hexadecimal, as they are hard to read in decimal form.

Signed-off-by: Andrei Vagin <avagin@gmail.com>
2025-11-02 07:48:23 -08:00

105 lines
1.8 KiB
C

#include <sys/uio.h>
#include <fcntl.h>
#include <linux/falloc.h>
#include <unistd.h>
#include "int.h"
#include "crtools.h"
#include "pagemap.h"
#include "restorer.h"
static int cr_dedup_one_pagemap(unsigned long img_id, int flags);
int cr_dedup(void)
{
int close_ret, ret = 0;
unsigned long img_id;
DIR *dirp;
struct dirent *ent;
dirp = opendir(CR_PARENT_LINK);
if (dirp == NULL) {
pr_perror("Can't enter previous snapshot folder");
ret = -1;
goto err;
}
while (1) {
errno = 0;
ent = readdir(dirp);
if (ent == NULL) {
if (errno) {
pr_perror("Failed readdir");
ret = -1;
goto err;
}
break;
}
ret = sscanf(ent->d_name, "pagemap-%lu.img", &img_id);
if (ret == 1) {
pr_info("pid=%lu\n", img_id);
ret = cr_dedup_one_pagemap(img_id, PR_TASK);
if (ret < 0)
break;
}
ret = sscanf(ent->d_name, "pagemap-shmem-%lu.img", &img_id);
if (ret == 1) {
pr_info("shmid=%lu\n", img_id);
ret = cr_dedup_one_pagemap(img_id, PR_SHMEM);
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;
}
static int cr_dedup_one_pagemap(unsigned long img_id, int flags)
{
int ret;
struct page_read pr;
struct page_read *prp;
flags |= PR_MOD;
ret = open_page_read(img_id, &pr, flags);
if (ret <= 0)
return -1;
prp = pr.parent;
if (!prp)
goto exit;
while (1) {
ret = pr.advance(&pr);
if (ret <= 0)
goto exit;
pr_debug("dedup iovec %" PRIx64 " - %" PRIx64 "\n",
pr.pe->vaddr, pr.pe->vaddr + pagemap_len(pr.pe));
if (!pagemap_in_parent(pr.pe)) {
ret = dedup_one_iovec(prp, pr.pe->vaddr, pagemap_len(pr.pe));
if (ret)
goto exit;
}
}
exit:
pr.close(&pr);
if (ret < 0)
return ret;
return 0;
}