From 17e6c1cc9412026d87f4a70a5e86b39e2e13ce62 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 1 Feb 2010 10:21:35 +0100 Subject: [PATCH] Introduce --no-resume. If the dss daemon (or the rsync process) is killed while a snaphot is being created, e.g. because of a server shutdown, the latest snapshot remains incomplete until it is removed by the usual shapshot pruning mechanism. This patch changes the snapshot creation behaviour if the most recently created snapshot happens to be incomplete and the new --no-resume option is not given. In this case the directory of the incomplete snapshot is reused as the destination directory for the the new snapshot. This change saves disk space and reduces the snapshot creation time, depending of course on how far the previous rsync process got before it was interrupted. --- dss.c | 33 +++++++++++++++++++++++++++++---- dss.ggo | 15 +++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/dss.c b/dss.c index 93ab802..eae8b3e 100644 --- a/dss.c +++ b/dss.c @@ -966,6 +966,32 @@ static int use_rsync_locally(char *logname) return 1; } +static int rename_resume_snap(int64_t creation_time) +{ + struct snapshot_list sl = {.num_snapshots = 0}; + struct snapshot *s; + char *new_name = incomplete_name(creation_time); + int ret; + + ret = 0; + if (conf.no_resume_given) + goto out; + dss_get_snapshot_list(&sl); + s = get_newest_snapshot(&sl); + if (!s) + goto out; + if ((s->flags & SS_COMPLETE) != 0) /* complete */ + goto out; + DSS_INFO_LOG("resuming: reusing %s as destination dir\n", s->name); + ret = dss_rename(s->name, new_name); +out: + if (ret >= 0) + DSS_NOTICE_LOG("creating new snapshot %s\n", new_name); + free(new_name); + free_snapshot_list(&sl); + return ret; +} + static void create_rsync_argv(char ***argv, int64_t *num) { char *logname; @@ -1018,11 +1044,10 @@ static void free_rsync_argv(char **argv) static int create_snapshot(char **argv) { int ret, fds[3] = {0, 0, 0}; - char *name; - name = incomplete_name(current_snapshot_creation_time); - DSS_NOTICE_LOG("creating new snapshot %s\n", name); - free(name); + ret = rename_resume_snap(current_snapshot_creation_time); + if (ret < 0) + return ret; ret = dss_exec(&create_pid, argv[0], argv, fds); if (ret < 0) return ret; diff --git a/dss.ggo b/dss.ggo index 506fbf1..09e345d 100644 --- a/dss.ggo +++ b/dss.ggo @@ -194,6 +194,21 @@ details=" dss. " +option "no-resume" - +#~~~~~~~~~~~~~~~~~~~ +"Do not try to resume from previous runs" +flag off +details = " + Starting from version 0.1.4, dss tries to resume from a + previously cancelled dss instance by default. It does so by + looking at the status of the most recently created snapshot. If + this snapshot status is incomplete, its directory is reused + as the destination directory for a subsequent rsync run. + + The --no-resume option deactivates this feature so that a new + directory is always used as the rsync destination directory. +" + option "rsync-option" O #~~~~~~~~~~~~~~~~~~~~~~ "Further rsync options" -- 2.39.2