hammer2 - Check duplicate H2 partitions during hammer2 cleanup
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 20 Jun 2018 06:33:28 +0000 (23:33 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 20 Jun 2018 06:33:28 +0000 (23:33 -0700)
* hammer2 cleanup operates on the partition the mount resides on,
  so if multiple hammer2 snapshots from the same partition are mounted
  we do not need to run it for each mount.

sbin/hammer2/cmd_cleanup.c

index 35f0d18..c16a647 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The DragonFly Project.  All rights reserved.
+ * Copyright (c) 2017-2018 The DragonFly Project.  All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
  * by Matthew Dillon <dillon@dragonflybsd.org>
@@ -32,6 +32,9 @@
 #include "hammer2.h"
 
 static int docleanup(const char *path);
+static int sameh2prefix(const char *from);
+static void saveh2prefix(const char *from);
+static void freeh2prefixes(void);
 
 int
 cmd_cleanup(const char *sel_path)
@@ -39,6 +42,7 @@ cmd_cleanup(const char *sel_path)
        struct statfs *fsary;
        char *fstype;
        char *path;
+       char *from;
        int i;
        int n;
        int r;
@@ -56,13 +60,22 @@ cmd_cleanup(const char *sel_path)
        for (i = 0; i < n; ++i) {
                fstype = fsary[i].f_fstypename;
                path = fsary[i].f_mntonname;
+               from = fsary[i].f_mntfromname;
 
-               if (strcmp(fstype, "hammer2") == 0) {
+               if (strcmp(fstype, "hammer2") != 0)
+                       continue;
+               if (sameh2prefix(from)) {
+                       printf("hammer2 cleanup \"%s\" (same partition)\n",
+                               path);
+               } else {
                        r = docleanup(path);
                        if (r)
                                rc = r;
+                       saveh2prefix(from);
                }
        }
+       freeh2prefixes();
+
        return rc;
 }
 
@@ -77,3 +90,59 @@ docleanup(const char *path)
 
        return rc;
 }
+
+char **h2prefixes;
+int h2count;
+int h2limit;
+
+static
+int
+sameh2prefix(const char *from)
+{
+       char *ptr;
+       int rc = 0;
+       int i;
+
+       ptr = strdup(from);
+       if (strchr(ptr, '@'))
+               *strchr(ptr, '@') = 0;
+       for (i = 0; i < h2count; ++i) {
+               if (strcmp(h2prefixes[i], ptr) == 0) {
+                       rc = 1;
+                       break;
+               }
+       }
+       free(ptr);
+
+       return rc;
+}
+
+static
+void
+saveh2prefix(const char *from)
+{
+       char *ptr;
+
+       if (h2count >= h2limit) {
+               h2limit = (h2limit + 8) << 1;
+               h2prefixes = realloc(h2prefixes, sizeof(char *) * h2limit);
+       }
+       ptr = strdup(from);
+       if (strchr(ptr, '@'))
+               *strchr(ptr, '@') = 0;
+       h2prefixes[h2count++] = ptr;
+}
+
+static
+void
+freeh2prefixes(void)
+{
+       int i;
+
+       for (i = 0; i < h2count; ++i)
+               free(h2prefixes[i]);
+       free(h2prefixes);
+       h2prefixes = NULL;
+       h2count = 0;
+       h2limit = 0;
+}