Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/get_diff.c
48529 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* This file and its contents are supplied under the terms of the
4
* Common Development and Distribution License ("CDDL"), version 1.0.
5
* You may only use this file in accordance with the terms of version
6
* 1.0 of the CDDL.
7
*
8
* A full copy of the text of the CDDL should have accompanied this
9
* source. A copy of the CDDL is also available via the Internet at
10
* http://www.illumos.org/license/CDDL.
11
*/
12
13
/*
14
* Copyright (c) 2018 by Delphix. All rights reserved.
15
*/
16
17
#include <stdio.h>
18
#include <fcntl.h>
19
#include <unistd.h>
20
#include <stdlib.h>
21
#include <string.h>
22
#include <assert.h>
23
#include <sys/param.h>
24
#include <sys/types.h>
25
#include <sys/stat.h>
26
#include <errno.h>
27
28
static void
29
usage(const char *msg, int exit_value)
30
{
31
(void) fprintf(stderr, "usage: get_diff file redacted_file\n%s\n", msg);
32
exit(exit_value);
33
}
34
35
/*
36
* This utility compares two files, an original and its redacted counterpart
37
* (in that order). It compares the files 512 bytes at a time, printing out
38
* any ranges (as offset and length) where the redacted file does not match
39
* the original. This output is used to verify that the expected ranges of
40
* a redacted file do not contain the original data.
41
*/
42
int
43
main(int argc, char *argv[])
44
{
45
off_t diff_off = 0, diff_len = 0, off = 0;
46
int fd1, fd2;
47
char *fname1, *fname2;
48
char buf1[DEV_BSIZE], buf2[DEV_BSIZE];
49
ssize_t bytes;
50
51
if (argc != 3)
52
usage("Incorrect number of arguments.", 1);
53
54
if ((fname1 = argv[1]) == NULL)
55
usage("Filename missing.", 1);
56
if ((fd1 = open(fname1, O_LARGEFILE | O_RDONLY)) < 0) {
57
perror("open1 failed");
58
exit(1);
59
}
60
61
if ((fname2 = argv[2]) == NULL)
62
usage("Redacted filename missing.", 1);
63
if ((fd2 = open(fname2, O_LARGEFILE | O_RDONLY)) < 0) {
64
perror("open2 failed");
65
exit(1);
66
}
67
68
while ((bytes = pread(fd1, buf1, DEV_BSIZE, off)) > 0) {
69
if (pread(fd2, buf2, DEV_BSIZE, off) < 0) {
70
if (errno == EIO) {
71
/*
72
* A read in a redacted section of a file will
73
* fail with EIO. If we get EIO, continue on
74
* but ensure that a comparison of buf1 and
75
* buf2 will fail, indicating a redacted block.
76
*/
77
buf2[0] = ~buf1[0];
78
} else {
79
perror("pread failed");
80
exit(1);
81
}
82
}
83
if (memcmp(buf1, buf2, bytes) == 0) {
84
if (diff_len != 0) {
85
(void) fprintf(stdout, "%lld,%lld\n",
86
(long long)diff_off, (long long)diff_len);
87
assert(off == diff_off + diff_len);
88
diff_len = 0;
89
}
90
diff_off = 0;
91
} else {
92
if (diff_len == 0)
93
diff_off = off;
94
assert(off == diff_off + diff_len);
95
diff_len += bytes;
96
}
97
off += bytes;
98
}
99
100
if (diff_len != 0) {
101
(void) fprintf(stdout, "%lld,%lld\n", (long long)diff_off,
102
(long long)diff_len);
103
}
104
105
(void) close(fd1);
106
(void) close(fd2);
107
108
return (0);
109
}
110
111