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:
M | Makefile | | | 12 | ++++++++---- |
A | dup-rm.1 | | | 26 | ++++++++++++++++++++++++++ |
A | dup-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;
+}