iChange snapshot format - dedup - deduplicating backup program Err bitreich.org 70 hgit clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/ URL:git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/ bitreich.org 70 1Log /scm/dedup/log.gph bitreich.org 70 1Files /scm/dedup/files.gph bitreich.org 70 1Refs /scm/dedup/refs.gph bitreich.org 70 1Tags /scm/dedup/tag bitreich.org 70 1README /scm/dedup/file/README.gph bitreich.org 70 1LICENSE /scm/dedup/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit 03aa3e43c5b81940bab9e6990d71bf036a188f27 /scm/dedup/commit/03aa3e43c5b81940bab9e6990d71bf036a188f27.gph bitreich.org 70 1parent 14a97f465c31b9e0c707730ca8798dfd4140cb03 /scm/dedup/commit/14a97f465c31b9e0c707730ca8798dfd4140cb03.gph bitreich.org 70 hAuthor: sin URL:mailto:sin@2f30.org bitreich.org 70 iDate: Tue, 7 May 2019 20:56:44 +0100 Err bitreich.org 70 i Err bitreich.org 70 iChange snapshot format Err bitreich.org 70 i Err bitreich.org 70 iInclude a header at the front so we can store the nonce etc. Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M snap.c | 136 +++++++++++++++++++++++++++++-- Err bitreich.org 70 i Err bitreich.org 70 i1 file changed, 128 insertions(+), 8 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/snap.c b/snap.c /scm/dedup/file/snap.c.gph bitreich.org 70 i@@ -2,6 +2,7 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i Err bitreich.org 70 i+#include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i@@ -12,13 +13,37 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i #include "config.h" Err bitreich.org 70 i #include "misc.h" Err bitreich.org 70 i #include "queue.h" Err bitreich.org 70 i #include "snap.h" Err bitreich.org 70 i Err bitreich.org 70 i+#define SHDRMAGIC "SNAPSNAPPYSNOOP" Err bitreich.org 70 i+#define NSHDRMAGIC sizeof(SHDRMAGIC) Err bitreich.org 70 i+#define VMIN 0 Err bitreich.org 70 i+#define VMAJ 1 Err bitreich.org 70 i+#define VMINMASK 0xff Err bitreich.org 70 i+#define VMAJSHIFT 8 Err bitreich.org 70 i+#define VMAJMASK 0xff Err bitreich.org 70 i+#define SHDRSIZE (NSHDRMAGIC + 24 + 24 + 8 + 8) Err bitreich.org 70 i+ Err bitreich.org 70 i #define NERRBUF 128 Err bitreich.org 70 i Err bitreich.org 70 i+/* misc helpers */ Err bitreich.org 70 i+extern int pack(unsigned char *, char *, ...); Err bitreich.org 70 i+extern int unpack(unsigned char *, char *, ...); Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Snapshot header structure */ Err bitreich.org 70 i+struct shdr { Err bitreich.org 70 i+ char magic[NSHDRMAGIC]; /* magic number for file(1) */ Err bitreich.org 70 i+ unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES]; Err bitreich.org 70 i+ unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; Err bitreich.org 70 i+ uint64_t flags; /* version number */ Err bitreich.org 70 i+ uint64_t nbd; /* number of block hashes */ Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i struct mdnode { Err bitreich.org 70 i unsigned char md[MDSIZE]; /* hash of block */ Err bitreich.org 70 i TAILQ_ENTRY(mdnode) e; /* mdhead link node */ Err bitreich.org 70 i@@ -29,10 +54,54 @@ struct sctx { Err bitreich.org 70 i struct mdnode *mdnext; /* next hash to be returned via sget() */ Err bitreich.org 70 i int fd; /* underlying snapshot file descriptor */ Err bitreich.org 70 i int rdonly; /* when set to 1, the ssync() operation is a no-op */ Err bitreich.org 70 i+ struct shdr shdr; Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i static char errbuf[NERRBUF]; Err bitreich.org 70 i Err bitreich.org 70 i+/* Read snapshot header */ Err bitreich.org 70 i+static int Err bitreich.org 70 i+unpackshdr(int fd, struct shdr *shdr) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ unsigned char buf[SHDRSIZE]; Err bitreich.org 70 i+ int n; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (xread(fd, buf, sizeof(buf)) != sizeof(buf)) { Err bitreich.org 70 i+ sseterr("failed to read snapshot header: %s", strerror(errno)); Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ n = unpack(buf, "'16'24qq", Err bitreich.org 70 i+ shdr->magic, Err bitreich.org 70 i+ shdr->nonce, Err bitreich.org 70 i+ &shdr->flags, Err bitreich.org 70 i+ &shdr->nbd); Err bitreich.org 70 i+ Err bitreich.org 70 i+ assert(n == sizeof(buf)); Err bitreich.org 70 i+ return n; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Write snapshot header */ Err bitreich.org 70 i+static int Err bitreich.org 70 i+packshdr(int fd, struct shdr *shdr) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ unsigned char buf[SHDRSIZE]; Err bitreich.org 70 i+ int n; Err bitreich.org 70 i+ Err bitreich.org 70 i+ n = pack(buf, "'16'24qq", Err bitreich.org 70 i+ shdr->magic, Err bitreich.org 70 i+ shdr->nonce, Err bitreich.org 70 i+ shdr->flags, Err bitreich.org 70 i+ shdr->nbd); Err bitreich.org 70 i+ Err bitreich.org 70 i+ assert(n == SHDRSIZE); Err bitreich.org 70 i+ if (xwrite(fd, buf, n) != n) { Err bitreich.org 70 i+ sseterr("failed to write snapshot header: %s", strerror(errno)); Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ return n; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i static int Err bitreich.org 70 i loadmd(struct sctx *sctx) Err bitreich.org 70 i { Err bitreich.org 70 i@@ -55,15 +124,11 @@ loadmd(struct sctx *sctx) Err bitreich.org 70 i static int Err bitreich.org 70 i initmdhead(struct sctx *sctx) Err bitreich.org 70 i { Err bitreich.org 70 i- struct stat st; Err bitreich.org 70 i- uint64_t i, n; Err bitreich.org 70 i+ struct shdr *shdr; Err bitreich.org 70 i+ uint64_t i; Err bitreich.org 70 i Err bitreich.org 70 i- if (fstat(sctx->fd, &st) < 0) { Err bitreich.org 70 i- sseterr("fstat: %s", strerror(errno)); Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- } Err bitreich.org 70 i- n = st.st_size / MDSIZE; Err bitreich.org 70 i- for (i = 0; i < n; i++) { Err bitreich.org 70 i+ shdr = &sctx->shdr; Err bitreich.org 70 i+ for (i = 0; i < shdr->nbd; i++) { Err bitreich.org 70 i if (loadmd(sctx) == 0) Err bitreich.org 70 i continue; Err bitreich.org 70 i Err bitreich.org 70 i@@ -83,6 +148,7 @@ initmdhead(struct sctx *sctx) Err bitreich.org 70 i int Err bitreich.org 70 i screat(char *path, int mode, struct sctx **sctx) Err bitreich.org 70 i { Err bitreich.org 70 i+ struct shdr *shdr; Err bitreich.org 70 i int fd; Err bitreich.org 70 i Err bitreich.org 70 i if (path == NULL || sctx == NULL) { Err bitreich.org 70 i@@ -90,6 +156,11 @@ screat(char *path, int mode, struct sctx **sctx) Err bitreich.org 70 i return -1; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+ if (sodium_init() < 0) { Err bitreich.org 70 i+ sseterr("sodium_init: failed"); Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i fd = open(path, O_RDWR | O_CREAT | O_EXCL, mode); Err bitreich.org 70 i if (fd < 0) { Err bitreich.org 70 i sseterr("open: %s", strerror(errno)); Err bitreich.org 70 i@@ -106,12 +177,25 @@ screat(char *path, int mode, struct sctx **sctx) Err bitreich.org 70 i TAILQ_INIT(&(*sctx)->mdhead); Err bitreich.org 70 i (*sctx)->mdnext = NULL; Err bitreich.org 70 i (*sctx)->fd = fd; Err bitreich.org 70 i+ Err bitreich.org 70 i+ shdr = &(*sctx)->shdr; Err bitreich.org 70 i+ memcpy(shdr->magic, SHDRMAGIC, NSHDRMAGIC); Err bitreich.org 70 i+ shdr->flags = (VMAJ << VMAJSHIFT) | VMIN; Err bitreich.org 70 i+ shdr->nbd = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (packshdr(fd, shdr) < 0) { Err bitreich.org 70 i+ free(*sctx); Err bitreich.org 70 i+ close(fd); Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i return 0; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i sopen(char *path, int flags, int mode, struct sctx **sctx) Err bitreich.org 70 i { Err bitreich.org 70 i+ struct shdr *shdr; Err bitreich.org 70 i int fd; Err bitreich.org 70 i Err bitreich.org 70 i if (path == NULL || sctx == NULL) { Err bitreich.org 70 i@@ -125,6 +209,11 @@ sopen(char *path, int flags, int mode, struct sctx **sctx) Err bitreich.org 70 i return -1; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+ if (sodium_init() < 0) { Err bitreich.org 70 i+ sseterr("sodium_init: failed"); Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i fd = open(path, O_RDONLY, mode); Err bitreich.org 70 i if (fd < 0) { Err bitreich.org 70 i sseterr("open: %s", strerror(errno)); Err bitreich.org 70 i@@ -143,6 +232,29 @@ sopen(char *path, int flags, int mode, struct sctx **sctx) Err bitreich.org 70 i (*sctx)->fd = fd; Err bitreich.org 70 i (*sctx)->rdonly = 1; Err bitreich.org 70 i Err bitreich.org 70 i+ shdr = &(*sctx)->shdr; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (unpackshdr(fd, shdr) < 0) { Err bitreich.org 70 i+ free(sctx); Err bitreich.org 70 i+ close(fd); Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (memcmp(shdr->magic, SHDRMAGIC, NSHDRMAGIC) != 0) { Err bitreich.org 70 i+ free(sctx); Err bitreich.org 70 i+ close(fd); Err bitreich.org 70 i+ sseterr("unknown snapshot header magic"); Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* If the major version is different, the format is incompatible */ Err bitreich.org 70 i+ if (((shdr->flags >> VMAJSHIFT) & VMAJMASK) != VMAJ) { Err bitreich.org 70 i+ free(sctx); Err bitreich.org 70 i+ close(fd); Err bitreich.org 70 i+ sseterr("snapshot header version mismatch"); Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i if (initmdhead(*sctx) < 0) { Err bitreich.org 70 i free(*sctx); Err bitreich.org 70 i close(fd); Err bitreich.org 70 i@@ -154,6 +266,7 @@ sopen(char *path, int flags, int mode, struct sctx **sctx) Err bitreich.org 70 i int Err bitreich.org 70 i sput(struct sctx *sctx, unsigned char *md) Err bitreich.org 70 i { Err bitreich.org 70 i+ struct shdr *shdr; Err bitreich.org 70 i struct mdnode *mdnode; Err bitreich.org 70 i Err bitreich.org 70 i if (sctx == NULL || md == NULL) { Err bitreich.org 70 i@@ -166,6 +279,8 @@ sput(struct sctx *sctx, unsigned char *md) Err bitreich.org 70 i sseterr("calloc: %s", strerror(errno)); Err bitreich.org 70 i return -1; Err bitreich.org 70 i } Err bitreich.org 70 i+ shdr = &sctx->shdr; Err bitreich.org 70 i+ shdr->nbd++; Err bitreich.org 70 i memcpy(mdnode->md, md, MDSIZE); Err bitreich.org 70 i TAILQ_INSERT_TAIL(&sctx->mdhead, mdnode, e); Err bitreich.org 70 i return 0; Err bitreich.org 70 i@@ -208,6 +323,7 @@ srewind(struct sctx *sctx) Err bitreich.org 70 i int Err bitreich.org 70 i ssync(struct sctx *sctx) Err bitreich.org 70 i { Err bitreich.org 70 i+ struct shdr *shdr; Err bitreich.org 70 i struct mdnode *mdnode; Err bitreich.org 70 i Err bitreich.org 70 i if (sctx == NULL) { Err bitreich.org 70 i@@ -222,6 +338,10 @@ ssync(struct sctx *sctx) Err bitreich.org 70 i sseterr("lseek: %s", strerror(errno)); Err bitreich.org 70 i return -1; Err bitreich.org 70 i } Err bitreich.org 70 i+ Err bitreich.org 70 i+ shdr = &sctx->shdr; Err bitreich.org 70 i+ if (packshdr(sctx->fd, shdr) < 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i TAILQ_FOREACH(mdnode, &sctx->mdhead, e) { Err bitreich.org 70 i if (xwrite(sctx->fd, mdnode->md, MDSIZE) != MDSIZE) { Err bitreich.org 70 i sseterr("failed to write block hash: %s", Err bitreich.org 70 .