Don't create two snapshots in the same second.
authorAndre Noll <maan@systemlinux.org>
Mon, 1 Oct 2012 17:10:02 +0000 (19:10 +0200)
committerAndre Noll <maan@systemlinux.org>
Mon, 1 Oct 2012 17:10:02 +0000 (19:10 +0200)
This can only happen if all of the follwing are true:

(a) source and destination directories are small
(b) rsync completes successfully within one second
(c) At most two snapshots are missing

In this case the rename() call which changes the snapshot name from
*-incomplete to the proper name fails for the second snapshot with
EEXIST. This is because the previous snapshot name coincides with
the name of the second snapshot.

The fix is a bit ugly but also non-invasive and simple: Just sleep
one second in this case.

dss.c

diff --git a/dss.c b/dss.c
index 7620cfe..354bdb8 100644 (file)
--- a/dss.c
+++ b/dss.c
@@ -548,10 +548,17 @@ static int rename_incomplete_snapshot(int64_t start)
 {
        char *old_name;
        int ret;
+       int64_t now;
 
+       /*
+        * We don't want the dss_rename() below to fail with EEXIST because the
+        * last complete snapshot was created (and completed) in the same
+        * second as this one.
+        */
+       while ((now = get_current_time()) == start)
+               sleep(1);
        free(path_to_last_complete_snapshot);
-       ret = complete_name(start, get_current_time(),
-               &path_to_last_complete_snapshot);
+       ret = complete_name(start, now, &path_to_last_complete_snapshot);
        if (ret < 0)
                return ret;
        old_name = incomplete_name(start);