Merge branch 'refs/heads/t/min-complete'
authorAndre Noll <maan@tuebingen.mpg.de>
Fri, 12 Dec 2014 13:21:53 +0000 (14:21 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Fri, 12 Dec 2014 13:21:53 +0000 (14:21 +0100)
dss.c
dss.ggo
snap.c
snap.h

diff --git a/dss.c b/dss.c
index 0ad7a35989a75e893fe40e30d84d1ff18f4d94ff..006cd27c333e097231ae140374fffdf3b8d689f6 100644 (file)
--- a/dss.c
+++ b/dss.c
@@ -531,17 +531,25 @@ static struct snapshot *find_outdated_snapshot(struct snapshot_list *sl)
 
 static struct snapshot *find_oldest_removable_snapshot(struct snapshot_list *sl)
 {
-       int i;
-       struct snapshot *s;
+       int i, num_complete;
+       struct snapshot *s, *ref = NULL;
+
+       num_complete = num_complete_snapshots(sl);
+       if (num_complete <= conf.min_complete_arg)
+               return NULL;
        FOR_EACH_SNAPSHOT(s, i, sl) {
                if (snapshot_is_being_created(s))
                        continue;
-               if (is_reference_snapshot(s))
+               if (is_reference_snapshot(s)) { /* avoid this one */
+                       ref = s;
                        continue;
+               }
                DSS_INFO_LOG(("oldest removable snapshot: %s\n", s->name));
                return s;
        }
-       return NULL;
+       assert(ref);
+       DSS_WARNING_LOG(("removing reference snapshot %s\n", ref->name));
+       return ref;
 }
 
 static int rename_incomplete_snapshot(int64_t start)
diff --git a/dss.ggo b/dss.ggo
index ac7f5b7875279914e7b71ca15b26d8d60e36faf6..9587dd24c7b11a439b2c63335ba922361e1cf988 100644 (file)
--- a/dss.ggo
+++ b/dss.ggo
@@ -439,3 +439,23 @@ details="
        becomes low. Use this flag if the file system containing the
        destination directory is used for snapshots only.
 "
+
+option "min-complete" -
+#~~~~~~~~~~~~~~~~~~~~~~
+"Minimal number of complete snapshots to keep"
+int typestr = "num"
+default = "1"
+optional
+details = "
+       This option is only relevant if snapshots must be deleted
+       because disk space gets low.
+
+       dss refuses to remove old snapshots if there are fewer complete
+       snapshots left than the given number. The default value of one
+       guarantees that at least one complete snapshot is available
+       at all times.
+
+       If only <num> complete snapshot are left, and there is not
+       enough disk space available for another snapshot, the program
+       terminates with a \"No space left on device\" error.
+"
diff --git a/snap.c b/snap.c
index 4dbb4461ed43c3152460ed3b312caa6f434143fd..7c16d2e870b8e4e918a1486ab801bf31f1344c47 100644 (file)
--- a/snap.c
+++ b/snap.c
@@ -232,3 +232,13 @@ __malloc char *name_of_newest_complete_snapshot(struct snapshot_list *sl)
        return name;
 }
 
+int num_complete_snapshots(struct snapshot_list *sl)
+{
+       struct snapshot *s;
+       int i, ret = 0;
+
+       FOR_EACH_SNAPSHOT(s, i, sl)
+               if (s->flags & SS_COMPLETE)
+                       ret++;
+       return ret;
+}
diff --git a/snap.h b/snap.h
index 8fee1389595840f62cffb9932d21f51c6b33943f..626ecad003a52a1a465ea6f7f2e11f960a97df3c 100644 (file)
--- a/snap.h
+++ b/snap.h
@@ -88,6 +88,7 @@ __malloc char *incomplete_name(int64_t start);
 __malloc char *being_deleted_name(struct snapshot *s);
 int complete_name(int64_t start, int64_t end, char **result);
 __malloc char *name_of_newest_complete_snapshot(struct snapshot_list *sl);
+int num_complete_snapshots(struct snapshot_list *sl);
 
 /**
  * Get the newest snapshot in a snapshot list.