hammer - Fix filesystem selection path bug in cleanup directive
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 15 Aug 2013 07:57:53 +0000 (00:57 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 15 Aug 2013 07:57:53 +0000 (00:57 -0700)
* When being asked to cleanup a hammer filesystem, hammer checks the
  /var/hammer/<filesystem>/ directory for manual snapshots and is able
  to extract the target filesystem from the softlinks it finds.

  If no softlinks are found hammer incorrectly calls 'hammer prune'
  with the /var/hammer/* path instead of the target filesystem path
  which causes the prune code to prune the wrong filesystem.

* Issue only happened when snapshots were disabled but snapshot aging
  was being enforced.  e.g. in the hammer config for the filesystem,
  something like 'snapshots 0d 60d'.  This feature tends to be used
  only on slaves that are the target of a mirror-stream backup.
  Other combinations will either have created snapshot softlinks
  in /var/hammer/* or would have disabled snapshots entirely (which
  causes a prune-everything to happen and doesn't have the bug).

sbin/hammer/cmd_cleanup.c
sbin/hammer/cmd_softprune.c
sbin/hammer/hammer.h

index 1189397..151da3f 100644 (file)
@@ -1048,23 +1048,39 @@ create_snapshot(const char *path, const char *snapshots_path)
 }
 
 static int
-cleanup_prune(const char *path __unused, const char *snapshots_path,
+cleanup_prune(const char *path, const char *snapshots_path,
                  int arg1 __unused, int arg2, int snapshots_disabled)
 {
+       const char *path_or_snapshots_path;
+       struct softprune *base = NULL;
+       struct hammer_ioc_prune dummy_template;
+
+       bzero(&dummy_template, sizeof(dummy_template));
+       hammer_softprune_scandir(&base, &dummy_template, snapshots_path);
+
+       /*
+        * If the snapshots_path (e.g. /var/hammer/...) has no snapshots
+        * in it then prune will get confused and prune the filesystem
+        * containing the snapshots_path instead of the requested
+        * filesystem.  De-confuse prune.  We need a better way.
+        */
+       path_or_snapshots_path = base ? snapshots_path : path;
+
        /*
         * If snapshots have been disabled run prune-everything instead
         * of prune.
         */
        if (snapshots_disabled && arg2) {
-               runcmd(NULL, "hammer -c %s/.prune.cycle -t %d prune-everything %s",
-                       snapshots_path, arg2, path);
+               runcmd(NULL,
+                      "hammer -c %s/.prune.cycle -t %d prune-everything %s",
+                      snapshots_path, arg2, path);
        } else if (snapshots_disabled) {
                runcmd(NULL, "hammer prune-everything %s", path);
        } else if (arg2) {
                runcmd(NULL, "hammer -c %s/.prune.cycle -t %d prune %s",
-                       snapshots_path, arg2, snapshots_path);
+                       snapshots_path, arg2, path_or_snapshots_path);
        } else {
-               runcmd(NULL, "hammer prune %s", snapshots_path);
+               runcmd(NULL, "hammer prune %s", path_or_snapshots_path);
        }
        return(0);
 }
index 7796a21..d336da2 100644 (file)
 
 #include "hammer.h"
 
-struct softprune {
-       struct softprune *next;
-       struct statfs fs;
-       char *filesystem;
-       struct hammer_ioc_prune prune;
-       int maxelms;
-       int prune_min;
-};
-
 static void softprune_usage(int code);
-static void hammer_softprune_scandir(struct softprune **basep,
-                       struct hammer_ioc_prune *template,
-                       const char *dirname);
 static int hammer_softprune_scanmeta(int fd, struct softprune *scan,
                        int delete_all);
 static void hammer_meta_flushdelete(int fd, struct hammer_ioc_snapshot *dsnap);
@@ -250,7 +238,7 @@ hammer_cmd_softprune(char **av, int ac, int everything_opt)
  *      snapshot mechanic we don't have to scan softlinks any more
  *      and can just use the meta-data.  But for now we do both.
  */
-static void
+void
 hammer_softprune_scandir(struct softprune **basep,
                         struct hammer_ioc_prune *template,
                         const char *dirname)
index 31d40a5..faebf7c 100644 (file)
 
 #include <libhammer.h>
 
+struct softprune {
+       struct softprune *next;
+       struct statfs fs;
+       char *filesystem;
+       struct hammer_ioc_prune prune;
+       int maxelms;
+       int prune_min;
+};
+
 extern int RecurseOpt;
 extern int VerboseOpt;
 extern int QuietOpt;
@@ -132,3 +141,6 @@ void hammer_reset_cycle(void);
 int getpfs(struct hammer_ioc_pseudofs_rw *pfs, const char *path);
 void relpfs(int fd, struct hammer_ioc_pseudofs_rw *pfs);
 void hammer_check_restrict(const char *path);
+void hammer_softprune_scandir(struct softprune **basep,
+                         struct hammer_ioc_prune *template,
+                         const char *dirname);