Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/get_diff.c
48529 views
// SPDX-License-Identifier: CDDL-1.01/*2* This file and its contents are supplied under the terms of the3* Common Development and Distribution License ("CDDL"), version 1.0.4* You may only use this file in accordance with the terms of version5* 1.0 of the CDDL.6*7* A full copy of the text of the CDDL should have accompanied this8* source. A copy of the CDDL is also available via the Internet at9* http://www.illumos.org/license/CDDL.10*/1112/*13* Copyright (c) 2018 by Delphix. All rights reserved.14*/1516#include <stdio.h>17#include <fcntl.h>18#include <unistd.h>19#include <stdlib.h>20#include <string.h>21#include <assert.h>22#include <sys/param.h>23#include <sys/types.h>24#include <sys/stat.h>25#include <errno.h>2627static void28usage(const char *msg, int exit_value)29{30(void) fprintf(stderr, "usage: get_diff file redacted_file\n%s\n", msg);31exit(exit_value);32}3334/*35* This utility compares two files, an original and its redacted counterpart36* (in that order). It compares the files 512 bytes at a time, printing out37* any ranges (as offset and length) where the redacted file does not match38* the original. This output is used to verify that the expected ranges of39* a redacted file do not contain the original data.40*/41int42main(int argc, char *argv[])43{44off_t diff_off = 0, diff_len = 0, off = 0;45int fd1, fd2;46char *fname1, *fname2;47char buf1[DEV_BSIZE], buf2[DEV_BSIZE];48ssize_t bytes;4950if (argc != 3)51usage("Incorrect number of arguments.", 1);5253if ((fname1 = argv[1]) == NULL)54usage("Filename missing.", 1);55if ((fd1 = open(fname1, O_LARGEFILE | O_RDONLY)) < 0) {56perror("open1 failed");57exit(1);58}5960if ((fname2 = argv[2]) == NULL)61usage("Redacted filename missing.", 1);62if ((fd2 = open(fname2, O_LARGEFILE | O_RDONLY)) < 0) {63perror("open2 failed");64exit(1);65}6667while ((bytes = pread(fd1, buf1, DEV_BSIZE, off)) > 0) {68if (pread(fd2, buf2, DEV_BSIZE, off) < 0) {69if (errno == EIO) {70/*71* A read in a redacted section of a file will72* fail with EIO. If we get EIO, continue on73* but ensure that a comparison of buf1 and74* buf2 will fail, indicating a redacted block.75*/76buf2[0] = ~buf1[0];77} else {78perror("pread failed");79exit(1);80}81}82if (memcmp(buf1, buf2, bytes) == 0) {83if (diff_len != 0) {84(void) fprintf(stdout, "%lld,%lld\n",85(long long)diff_off, (long long)diff_len);86assert(off == diff_off + diff_len);87diff_len = 0;88}89diff_off = 0;90} else {91if (diff_len == 0)92diff_off = off;93assert(off == diff_off + diff_len);94diff_len += bytes;95}96off += bytes;97}9899if (diff_len != 0) {100(void) fprintf(stdout, "%lld,%lld\n", (long long)diff_off,101(long long)diff_len);102}103104(void) close(fd1);105(void) close(fd2);106107return (0);108}109110111