URI: 
       tdcheck.c - dedup - data deduplication program
  HTML git clone git://bitreich.org/dedup/ git://hg6vgqziawt5s4dj.onion/dedup/
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
       tdcheck.c (2945B)
       ---
            1 #include <sys/types.h>
            2 #include <sys/stat.h>
            3 #include <sys/file.h>
            4 
            5 #include <err.h>
            6 #include <fcntl.h>
            7 #include <stdio.h>
            8 #include <stdint.h>
            9 #include <stdlib.h>
           10 #include <string.h>
           11 #include <unistd.h>
           12 
           13 #include "arg.h"
           14 #include "blake2.h"
           15 #include "dedup.h"
           16 
           17 static struct snap_hdr snap_hdr;
           18 static struct blk_hdr blk_hdr;
           19 static int ifd;
           20 static int sfd;
           21 static int hash_algo = HASH_BLAKE2B;
           22 static int compr_algo = COMPR_LZ4;
           23 
           24 int verbose;
           25 char *argv0;
           26 
           27 static void
           28 print_md(FILE *fp, uint8_t *md, size_t size)
           29 {
           30         size_t i;
           31 
           32         for (i = 0; i < size; i++)
           33                 fprintf(fp, "%02x", md[i]);
           34 }
           35 
           36 /*
           37  * Hash every block referenced by the given snapshot
           38  * and compare its hash with the one stored in the corresponding
           39  * block descriptor.
           40  */
           41 static int
           42 check_snap(struct snap *snap, void *arg)
           43 {
           44         struct compr_ctx ctx;
           45         uint8_t *buf;
           46         int *ret = arg;
           47         uint64_t i;
           48 
           49         if (verbose > 0) {
           50                 fprintf(stderr, "Checking snapshot: ");
           51                 print_md(stderr, snap->md, sizeof(snap->md));
           52                 fputc('\n', stderr);
           53         }
           54 
           55         if (compr_init(&ctx, compr_algo) < 0)
           56                 errx(1, "compr_init failed");
           57         buf = alloc_buf(compr_size(&ctx, BLKSIZE_MAX));
           58         for (i = 0; i < snap->nr_blk_descs; i++) {
           59                 uint8_t md[MD_SIZE];
           60                 struct blk_desc *blk_desc;
           61 
           62                 blk_desc = &snap->blk_desc[i];
           63                 read_blk(sfd, buf, blk_desc);
           64                 hash_blk(buf, blk_desc->size, md, hash_algo);
           65 
           66                 if (memcmp(blk_desc->md, md, sizeof(blk_desc->md)) == 0)
           67                         continue;
           68 
           69                 fprintf(stderr, "Block hash mismatch\n");
           70                 fprintf(stderr, "  Expected hash: ");
           71                 print_md(stderr, blk_desc->md, sizeof(blk_desc->md));
           72                 fputc('\n', stderr);
           73                 fprintf(stderr, "  Actual hash: ");
           74                 print_md(stderr, md, sizeof(md));
           75                 fputc('\n', stderr);
           76                 fprintf(stderr, "  Offset: %llu\n",
           77                         (unsigned long long)blk_desc->offset);
           78                 fprintf(stderr, "  Size: %llu\n",
           79                         (unsigned long long)blk_desc->size);
           80                 *ret = -1;
           81         }
           82         free_buf(buf);
           83         compr_final(&ctx);
           84         return WALK_CONTINUE;
           85 }
           86 
           87 static void
           88 init(void)
           89 {
           90         ifd = open(SNAPSF, O_RDONLY, 0600);
           91         if (ifd < 0)
           92                 err(1, "open %s", SNAPSF);
           93 
           94         sfd = open(STOREF, O_RDONLY, 0600);
           95         if (sfd < 0)
           96                 err(1, "open %s", STOREF);
           97 
           98         if (flock(ifd, LOCK_NB | LOCK_EX) < 0 ||
           99             flock(sfd, LOCK_NB | LOCK_EX) < 0)
          100                 err(1, "flock");
          101 
          102         xlseek(ifd, 0, SEEK_SET);
          103         load_snap_hdr(ifd, &snap_hdr);
          104         xlseek(sfd, 0, SEEK_SET);
          105         load_blk_hdr(sfd, &blk_hdr, &compr_algo, &hash_algo);
          106 }
          107 
          108 static void
          109 term(void)
          110 {
          111         close(ifd);
          112         close(sfd);
          113 }
          114 
          115 static void
          116 usage(void)
          117 {
          118         fprintf(stderr, "usage: %s [-v] [repo]\n", argv0);
          119         exit(1);
          120 }
          121 
          122 int
          123 main(int argc, char *argv[])
          124 {
          125         char *repo = NULL;
          126         int ret;
          127 
          128         ARGBEGIN {
          129         case 'v':
          130                 verbose++;
          131                 break;
          132         default:
          133                 usage();
          134         } ARGEND
          135 
          136         switch (argc) {
          137         case 0:
          138                 repo = ".";
          139                 break;
          140         case 1:
          141                 repo = argv[0];
          142                 break;
          143         default:
          144                 usage();
          145         };
          146 
          147         if (chdir(repo) < 0)
          148                 err(1, "chdir: %s", repo);
          149 
          150         init();
          151         ret = 0;
          152         walk_snap(ifd, &snap_hdr, check_snap, &ret);
          153         if (ret != 0)
          154                 errx(1, "%s or %s is corrupted", SNAPSF, STOREF);
          155         term();
          156         return 0;
          157 }