Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cr-dedup.c « criu - github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c0c21f53ee955dfaa675bbe47d58ba932329d810 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#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 base=%" PRIx64 ", len=%lu\n", 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;
}