From 719fb5fb7470df7f610fd190985765c71a2698e2 Mon Sep 17 00:00:00 2001 From: Axel Burri Date: Thu, 5 Apr 2018 16:42:26 +0200 Subject: [PATCH] btrbk: bugfix: correct scheduling of "first weekly backup in month/year" In the scheduler, a month (or year) does not start at the first day, but at the first `preserve_day_of_week`. Make sure that all days before `preserve_day_of_week` in a month get delta_months+1. Example (corner case): - `preserve_day_of_week sunday` - `target_preserve *m` - no backups in 2018-02 - backup with timestamp 2018-03-01 (which is a thursday) - backup with timestamp 2018-03-04 (which is a sunday) Without this patch, because there are no sunday backups in 2018-02, the first backup is considered a weekly (+4d after sunday), and as such "first weekly of month 2018-03", and the second one is discarded. With this patch, the first item is considered "first weekly of month 2018-02", and the second gets "first weekly of month 2018-03". NOTE: This change may result in (previously preserved) backups to be deleted! --- ChangeLog | 3 +++ btrbk | 22 +++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e17085a..b117093 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ btrbk-0.27.0-dev * Add "preserve_hour_of_day" configuration option (close #202). + * Bugfix: correct scheduling of "first weekly backup in month/year" + (close #217). Note that this change may result in (previously + preserved) backups to be deleted! btrbk-0.26.1 diff --git a/btrbk b/btrbk index 0c6f1e8..b164b23 100755 --- a/btrbk +++ b/btrbk @@ -3746,7 +3746,9 @@ sub schedule(@) # first, do our calendar calculations # - days start on $preserve_hour_of_day (or 00:00 if timestamp_format=short) # - weeks start on $preserve_day_of_week - # - leap hours are NOT taken into account for $delta_hours + # - months start on first $preserve_day_of_week of month + # - years start on first $preserve_day_of_week of year + # NOTE: leap hours are NOT taken into account for $delta_hours my $now_h = timegm_nocheck( 0, 0, $tm_now[2], $tm_now[3], $tm_now[4], $tm_now[5] ); # use timelocal() here (and below) if you want to honor leap hours foreach my $href (@sorted_schedule) @@ -3762,13 +3764,23 @@ sub schedule(@) if($delta_days_from_eow < 0) { $delta_days_from_eow += 7; } + my $month_corr = $tm[4]; # [0..11] + my $year_corr = $tm[5]; + if($tm[3] <= $delta_days_from_eow) { + # our month/year start on first $preserve_day_of_week, corrected value + $month_corr -= 1; + if($month_corr < 0) { + $month_corr = 11; + $year_corr -= 1; + } + } # check timegm: ignores leap hours my $delta_hours = int(($now_h - timegm_nocheck( 0, 0, $tm[2], $tm[3], $tm[4], $tm[5] ) ) / (60 * 60)); my $delta_days = int(($delta_hours + $delta_hours_from_hod) / 24); # days from beginning of day my $delta_weeks = int(($delta_days + $delta_days_from_eow) / 7); # weeks from beginning of week - my $delta_years = ($tm_now[5] - $tm[5]); - my $delta_months = $delta_years * 12 + ($tm_now[4] - $tm[4]); + my $delta_years = ($tm_now[5] - $year_corr); + my $delta_months = $delta_years * 12 + ($tm_now[4] - $month_corr); $href->{delta_hours} = $delta_hours; $href->{delta_days} = $delta_days; @@ -3777,8 +3789,8 @@ sub schedule(@) $href->{delta_years} = $delta_years; # these are only needed for text output (format_preserve_delta) - $href->{year} = $tm[5] + 1900; - $href->{month} = $tm[4] + 1; + $href->{year} = $year_corr + 1900; + $href->{month} = $month_corr + 1; $href->{delta_hours_from_hod} = $delta_hours_from_hod; $href->{delta_days_from_eow} = $delta_days_from_eow; $href->{real_hod} = $preserve_hour_of_day if($has_exact_time);