summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
c4feb13)
Currently dss cowardly refuses to remove the last complete snapshot
even if disk space is low, and fails if there is not enough disk space
left for a second snapshot. However, in some situations it is more
important to have a recent snapshot and to to keep dss up and running.
This commit introduces a new integer option, --min-complete, which
defaults to one to resemble the old behaviour.
If it is set to zero, dss will happily remove the last complete
snapshot, even if it is used as the reference directory for rsync's
--link-dest option. This is dangerous, but it's the only way to keep
dss going.
Conversely, --min-complete may be set to a value greater than one
to guarantee there is always a certain number of complete snapshots
available.
static struct snapshot *find_oldest_removable_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;
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;
DSS_INFO_LOG(("oldest removable snapshot: %s\n", s->name));
return s;
}
DSS_INFO_LOG(("oldest removable snapshot: %s\n", s->name));
return s;
}
+ assert(ref);
+ DSS_WARNING_LOG(("removing reference snapshot %s\n", ref->name));
+ return ref;
}
static int rename_incomplete_snapshot(int64_t start)
}
static int rename_incomplete_snapshot(int64_t start)
becomes low. Use this flag if the file system containing the
destination directory is used for snapshots only.
"
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.
+"
+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;
+}
__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);
__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.
/**
* Get the newest snapshot in a snapshot list.