From: Andre Noll Date: Fri, 14 May 2010 12:43:51 +0000 (+0200) Subject: Introduce snapshot recycling. X-Git-Tag: v0.1.5~19^2 X-Git-Url: http://git.tuebingen.mpg.de/?p=dss.git;a=commitdiff_plain;h=379ec51fd7e1a4a7fa7fd8cbc091ebccf8a70486 Introduce snapshot recycling. When snapshotting large file systems whose contents do not change much between snapshots, we end up removing large amounts of files just to recreate (hard links to) most of them afterwards. This patch changes snapshot creation so that outdated, redundant and orphaned snapshots are reused as the basis for new snapshots. Only if no existing snapshot is suitable for recycling, a new one is created. --- diff --git a/dss.c b/dss.c index bd7ead8..223f80e 100644 --- a/dss.c +++ b/dss.c @@ -1043,22 +1043,48 @@ static int use_rsync_locally(char *logname) static int rename_resume_snap(int64_t creation_time) { struct snapshot_list sl = {.num_snapshots = 0}; - struct snapshot *s; + struct snapshot *s = NULL; char *new_name = incomplete_name(creation_time); int ret; + const char *why; ret = 0; if (conf.no_resume_given) goto out; dss_get_snapshot_list(&sl); + /* + * Snapshot recycling: We first look at the newest snapshot. If this + * snapshot happens to be incomplete, the last rsync process was + * aborted and we reuse this one. Otherwise we look at snapshots which + * could be removed (outdated and redundant snapshots) as candidates + * for recycling. If no outdated/redundant snapshot exists, we check if + * there is an orphaned snapshot, which likely is useless anyway. + * + * Only if no existing snapshot is suitable for recycling, we bite the + * bullet and create a new one. + */ s = get_newest_snapshot(&sl); - if (!s) + if (!s) /* no snapshots at all */ goto out; - if ((s->flags & SS_COMPLETE) != 0) /* complete */ + /* re-use last snapshot if it is incomplete */ + why = "aborted"; + if ((s->flags & SS_COMPLETE) == 0) goto out; - DSS_INFO_LOG("resuming: reusing %s as destination dir\n", s->name); - ret = dss_rename(s->name, new_name); + why = "outdated"; + s = find_outdated_snapshot(&sl); + if (s) + goto out; + why = "redundant"; + s = find_redundant_snapshot(&sl); + if (s) + goto out; + why = "orphaned"; + s = find_orphaned_snapshot(&sl); out: + if (s) { + DSS_INFO_LOG("reusing %s snapshot %s\n", why, s->name); + ret = dss_rename(s->name, new_name); + } if (ret >= 0) DSS_NOTICE_LOG("creating new snapshot %s\n", new_name); free(new_name);