From d4d72473957544283b6d426c3d4fa0b3f583da87 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 1 Sep 2019 19:34:54 +0200 Subject: [PATCH] Revamp com_prune(). The prune subcommand implements its own logic for picking the snapshot to remove. The algorithm is similar but not identical to how the run subcommand gets rid of snapshots. This patch eliminates this inconsistency by changing com_prune() to call the find_removable_snapshot() helper which was introduced in the previous commit. Since find_removable_snapshot() returns a dynamically allocated string via the "why" pointer, we have to introduce another label for freeing this memory. The patch also improves the help text of the prune subcommand slightly. --- dss.c | 39 ++++++++++++++++----------------------- dss.suite | 25 ++++++++++++++----------- err.h | 1 + 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/dss.c b/dss.c index b09fc96..e2ee7dd 100644 --- a/dss.c +++ b/dss.c @@ -1659,7 +1659,7 @@ static int com_prune(void) struct snapshot_list sl; struct snapshot *victim; struct disk_space ds; - const char *why; + char *why; lock_dss_or_die(); ret = get_disk_space(".", &ds); @@ -1667,47 +1667,40 @@ static int com_prune(void) return ret; log_disk_space(&ds); dss_get_snapshot_list(&sl); - why = "outdated"; - victim = find_outdated_snapshot(&sl); - if (victim) - goto rm; - why = "redundant"; - victim = find_redundant_snapshot(&sl); - if (victim) - goto rm; - dss_msg("nothing to prune\n"); - ret = 0; - goto out; -rm: + victim = find_removable_snapshot(&sl, disk_space_low(&ds), &why); + if (!victim) { + dss_msg("nothing to prune\n"); + ret = 0; + goto free_sl; + } if (OPT_GIVEN(DSS, DRY_RUN)) { - dss_msg("%s snapshot %s (interval = %i)\n", + dss_msg("picking %s snapshot %s (interval = %i)\n", why, victim->name, victim->interval); ret = 0; - goto out; + goto free_why; } pre_remove_hook(victim, why); if (snapshot_removal_status == HS_PRE_RUNNING) { ret = wait_for_remove_process(); if (ret < 0) - goto out; + goto free_why; ret = -E_HOOK_FAILED; if (snapshot_removal_status != HS_PRE_SUCCESS) - goto out; + goto free_why; } ret = exec_rm(); if (ret < 0) - goto out; + goto free_why; ret = wait_for_remove_process(); if (ret < 0) - goto out; + goto free_why; assert(snapshot_removal_status == HS_SUCCESS); post_remove_hook(); assert(snapshot_removal_status == HS_POST_RUNNING); ret = wait_for_remove_process(); - if (ret < 0) - goto out; - ret = 1; -out: +free_why: + free(why); +free_sl: free_snapshot_list(&sl); return ret; } diff --git a/dss.suite b/dss.suite index 16c7e58..2719827 100644 --- a/dss.suite +++ b/dss.suite @@ -450,18 +450,21 @@ caption = Subcommands snapshots. [/description] [subcommand prune] - purpose = remove redundant and outdated snapshots + purpose = remove snapshots [description] - A snapshot is considered outdated if its interval number is greater or - equal than the specified number of unit intervals. See --unit-interval - and --num-intervals above. - - A snapshot is said to be redundant if the interval it belongs to - contains more than the configured number of snapshots. - - The prune command gets rid of both outdated and redundant snapshots. At - most one snapshot is removed per invocation. If --dry-run is given, the - subcommand only prints the snapshot that would be removed. + A snapshot is said to be (a) outdated if its interval number is greater + or equal than the specified number of unit intervals, (b) redundant if + the interval it belongs to contains more than the configured number of + snapshots, and (c) orphaned if it is incomplete and not being created + or deleted. All other snapshots are called regular. + + Unless --dry-run is given, which just prints the snapshot that would be + removed, this subcommand gets rid of non-regular snapshots. At most + one snapshot is removed per invocation. If no such snapshot exists + and disk space is low, the subcommand also removes regular snapshots, + always picking the oldest one. + + The subcommand fails if there is another dss "run" process. [/description] [subcommand ls] purpose = print the list of all snapshots diff --git a/err.h b/err.h index 9505dfc..bd22554 100644 --- a/err.h +++ b/err.h @@ -44,6 +44,7 @@ static inline char *dss_strerror(int num) DSS_ERROR(INVALID_NUMBER, "invalid number"), \ DSS_ERROR(STRFTIME, "strftime() failed"), \ DSS_ERROR(LOCALTIME, "localtime() failed"), \ + DSS_ERROR(HOOK_FAILED, "hook failure"), \ DSS_ERROR(MOUNTPOINT, "destination directory is no mountpoint"), \ DSS_ERROR(NULL_OPEN, "can not open /dev/null"), \ DSS_ERROR(DUP_PIPE, "exec error: can not create pipe"), \ -- 2.39.2