dedup

deduplicating backup program
git clone git://git.2f30.org/dedup
Log | Files | Refs | README | LICENSE

commit d6e4ca0475985f2f98e35fcfd5bdb3b4304a0eff
parent a5062b8799146166bf125a7f49630fa46d84639b
Author: sin <sin@2f30.org>
Date:   Thu, 25 Apr 2019 22:04:37 +0100

Implement dup-rm(1)

dup-rm(1) relies on the fallocate system call.  Not every filesystem
supports it.

Diffstat:
MMakefile | 12++++++++----
Adup-rm.1 | 26++++++++++++++++++++++++++
Adup-rm.c | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ include config.mk -BIN = dup-check dup-init dup-pack dup-unpack -MAN = dup-check.1 dup-init.1 dup-pack.1 dup-unpack.1 +BIN = dup-check dup-init dup-pack dup-rm dup-unpack +MAN = dup-check.1 dup-init.1 dup-pack.1 dup-rm.1 dup-unpack.1 HDR = \ arg.h \ @@ -27,16 +27,17 @@ COMMOBJ = \ DCHECKOBJ = $(COMMOBJ) dup-check.o DINITOBJ = $(COMMOBJ) dup-init.o DPACKOBJ = $(COMMOBJ) dup-pack.o +DRMOBJ = $(COMMOBJ) dup-rm.o DUNPACKOBJ = $(COMMOBJ) dup-unpack.o LDLIBS = -lsnappy all: $(BIN) -$(DCHECKOBJ) $(DINITOBJ) $(DPACKOBJ) $(DUNPACKOBJ): $(HDR) +$(DCHECKOBJ) $(DINITOBJ) $(DPACKOBJ) $(DRMOBJ) $(DUNPACKOBJ): $(HDR) clean: - rm -f $(DCHECKOBJ) $(DINITOBJ) $(DPACKOBJ) $(DUNPACKOBJ) $(BIN) + rm -f $(DCHECKOBJ) $(DINITOBJ) $(DPACKOBJ) $(DRMOBJ) $(DUNPACKOBJ) $(BIN) rm -rf dedup-$(VERSION) dedup-$(VERSION).tar.gz install: all @@ -68,5 +69,8 @@ dup-init: $(DINITOBJ) dup-pack: $(DPACKOBJ) $(CC) -o $@ $(DPACKOBJ) $(LDFLAGS) $(LDLIBS) +dup-rm: $(DRMOBJ) + $(CC) -o $@ $(DRMOBJ) $(LDFLAGS) $(LDLIBS) + dup-unpack: $(DUNPACKOBJ) $(CC) -o $@ $(DUNPACKOBJ) $(LDFLAGS) $(LDLIBS) diff --git a/dup-rm.1 b/dup-rm.1 @@ -0,0 +1,26 @@ +.Dd April 25, 2019 +.Dt DUP-RM 1 +.Os +.Sh NAME +.Nm dup-rm +.Nd Remove snapshot +.Sh SYNOPSIS +.Nm dup-rm +.Op Fl v +.Op Fl r Ar repo +.Ar name +.Sh DESCRIPTION +.Nm +removes the snapshot specified by +.Ar name . +.Sh OPTIONS +.Bl -tag -width "-r repo" +.It Fl r Ar repo +Repository directory. +By default the current working directory is used. +.It Fl v +Enable verbose mode. +.El +.Sh AUTHORS +.An Dimitris Papastamos Aq Mt sin@2f30.org , +.An z3bra Aq Mt contactatz3bradotorg . diff --git a/dup-rm.c b/dup-rm.c @@ -0,0 +1,85 @@ +#include <sys/types.h> +#include <sys/stat.h> + +#include <err.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "arg.h" +#include "block.h" +#include "config.h" +#include "snap.h" + +int verbose; +char *argv0; + +static int +rm(struct sctx *sctx, struct bctx *bctx) +{ + unsigned char md[MDSIZE]; + int sn; + + while ((sn = sget(sctx, md)) == MDSIZE) { + if (brm(bctx, md) < 0) + return -1; + } + if (sn < 0) + return -1; + return 0; +} + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [-v] [-r repo] name\n", argv0); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + char spath[PATH_MAX]; + char bpath[PATH_MAX]; + struct sctx *sctx; + struct bctx *bctx; + struct bparam bparam; + char *repo = "."; + + ARGBEGIN { + case 'r': + repo = EARGF(usage()); + break; + case 'v': + verbose++; + break; + default: + usage(); + } ARGEND + + if (argc != 1) + usage(); + + snprintf(spath, sizeof(spath), "%s/archive/%s", repo, argv[0]); + if (sopen(spath, O_RDONLY, 0600, &sctx) < 0) + errx(1, "sopen: %s: failed", spath); + + snprintf(bpath, sizeof(bpath), "%s/storage", repo); + if (bopen(bpath, O_RDWR, 0600, &bparam, &bctx) <0) + errx(1, "bopen: %s: failed", bpath); + + if (rm(sctx, bctx) < 0) + errx(1, "rm: failed"); + + if (bclose(bctx) < 0) + errx(1, "bclose: failed"); + if (sclose(sctx) < 0) + errx(1, "sclose: failed"); + + if (unlink(spath) < 0) + errx(1, "unlink: %s", spath); + + return 0; +}