From d8613d13797db640f9cf7432f29677056bddeb43 Mon Sep 17 00:00:00 2001 From: Christoph Klaffl Date: Tue, 7 Nov 2017 08:03:53 +0100 Subject: [PATCH 1/6] implemented frequent snapshots with configurable period Fixes #75 --- sanoid | 21 +++++++++++++++++---- sanoid.conf | 2 ++ sanoid.defaults.conf | 7 +++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/sanoid b/sanoid index d6e58ce..e8756db 100755 --- a/sanoid +++ b/sanoid @@ -121,12 +121,13 @@ sub monitor_snapshots { my $path = $config{$section}{'path'}; push @paths, $path; - my @types = ('yearly','monthly','daily','hourly'); + my @types = ('yearly','monthly','daily','hourly','frequently'); foreach my $type (@types) { my $smallerperiod = 0; # we need to set the period length in seconds first - if ($type eq 'hourly') { $smallerperiod = 60; } + if ($type eq 'frequently') { $smallerperiod = 1; } + elsif ($type eq 'hourly') { $smallerperiod = 60; } elsif ($type eq 'daily') { $smallerperiod = 60*60; } elsif ($type eq 'monthly') { $smallerperiod = 60*60*24; } elsif ($type eq 'yearly') { $smallerperiod = 60*60*24; } @@ -200,7 +201,8 @@ sub prune_snapshots { unless ($type =~ /ly$/) { next; } # we need to set the period length in seconds first - if ($type eq 'hourly') { $period = 60*60; } + if ($type eq 'frequently') { $period = 60 * $config{$section}{'frequent_period'}; } + elsif ($type eq 'hourly') { $period = 60*60; } elsif ($type eq 'daily') { $period = 60*60*24; } elsif ($type eq 'monthly') { $period = 60*60*24*31; } elsif ($type eq 'yearly') { $period = 60*60*24*365.25; } @@ -291,7 +293,18 @@ sub take_snapshots { my @preferredtime; my $lastpreferred; - if ($type eq 'hourly') { + if ($type eq 'frequently') { + my $frequentslice = int($datestamp{'min'} / $config{$section}{'frequent_period'}); + + push @preferredtime,0; # try to hit 0 seconds + push @preferredtime,$frequentslice * $config{$section}{'frequent_period'}; + push @preferredtime,$datestamp{'hour'}; + push @preferredtime,$datestamp{'mday'}; + push @preferredtime,($datestamp{'mon'}-1); # january is month 0 + push @preferredtime,$datestamp{'year'}; + $lastpreferred = timelocal(@preferredtime); + if ($lastpreferred > time()) { $lastpreferred -= 60 * $config{$section}{'frequent_period'}; } # preferred time is later this frequent period - so look at last frequent period + } elsif ($type eq 'hourly') { push @preferredtime,0; # try to hit 0 seconds push @preferredtime,$config{$section}{'hourly_min'}; push @preferredtime,$datestamp{'hour'}; diff --git a/sanoid.conf b/sanoid.conf index 9b1f19d..b999634 100644 --- a/sanoid.conf +++ b/sanoid.conf @@ -40,6 +40,7 @@ daily = 60 [template_production] + frequently = 0 hourly = 36 daily = 30 monthly = 3 @@ -49,6 +50,7 @@ [template_backup] autoprune = yes + frequently = 0 hourly = 30 daily = 90 monthly = 12 diff --git a/sanoid.defaults.conf b/sanoid.defaults.conf index 35c804d..b5e4e63 100644 --- a/sanoid.defaults.conf +++ b/sanoid.defaults.conf @@ -16,12 +16,17 @@ recursive = use_template = process_children_only = +# The period in minutes for frequent snapshots, +# should be in the range of 1-30 and divide an hour without remainder +frequent_period = 15 + # If any snapshot type is set to 0, we will not take snapshots for it - and will immediately # prune any of those type snapshots already present. # # Otherwise, if autoprune is set, we will prune any snapshots of that type which are older # than (setting * periodicity) - so if daily = 90, we'll prune any dailies older than 90 days. autoprune = yes +frequently = 0 hourly = 48 daily = 90 monthly = 6 @@ -62,6 +67,8 @@ yearly_min = 0 monitor = yes monitor_dont_warn = no monitor_dont_crit = no +frequently_warn = 2000 +frequently_crit = 8000 hourly_warn = 90 hourly_crit = 360 daily_warn = 28 From c9adcdab1e7e2a7eaa04bdbc15a24881278cefdb Mon Sep 17 00:00:00 2001 From: Christoph Klaffl Date: Wed, 8 Nov 2017 20:25:07 +0100 Subject: [PATCH 2/6] hardcoded new defaults --- sanoid | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sanoid b/sanoid index e8756db..6428cdf 100755 --- a/sanoid +++ b/sanoid @@ -553,6 +553,18 @@ sub getsnaps { #################################################################################### #################################################################################### +sub verify_option_existence { + my ($hash, $key, $default) = @_; + + if (! defined (%$hash{$key})) { + $hash->{$key} = $default; + } +} + +#################################################################################### +#################################################################################### +#################################################################################### + sub init { my ($conf_file, $default_conf_file) = @_; my %config; @@ -568,6 +580,12 @@ sub init { my @istrue=(1,"true","True","TRUE","yes","Yes","YES","on","On","ON"); my @isfalse=(0,"false","False","FALSE","no","No","NO","off","Off","OFF"); + # hardcoded defaults which may be missing from older default configuration file + verify_option_existence($defaults{'template_default'}, 'frequent_period', 15); + verify_option_existence($defaults{'template_default'}, 'frequently', 0); + verify_option_existence($defaults{'template_default'}, 'frequently_warn', 2000); + verify_option_existence($defaults{'template_default'}, 'frequently_crit', 8000); + foreach my $section (keys %ini) { # first up - die with honor if unknown parameters are set in any modules or templates by the user. From 8bd98f18008494e27c47c6d16cc1fbbaec9a33a6 Mon Sep 17 00:00:00 2001 From: Christoph Klaffl Date: Wed, 8 Nov 2017 21:40:30 +0100 Subject: [PATCH 3/6] added more documentation for frequent snapshots --- README.md | 1 + sanoid.defaults.conf | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9c4e6ba..863b697 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ And its /etc/sanoid/sanoid.conf might look something like this: ############################# [template_production] + frequently = 0 hourly = 36 daily = 30 monthly = 3 diff --git a/sanoid.defaults.conf b/sanoid.defaults.conf index b5e4e63..e7c22a8 100644 --- a/sanoid.defaults.conf +++ b/sanoid.defaults.conf @@ -16,8 +16,16 @@ recursive = use_template = process_children_only = -# The period in minutes for frequent snapshots, -# should be in the range of 1-30 and divide an hour without remainder +# for snapshots shorter than one hour, the period duration must be defined +# in minutes. Because they are executed within a full hour, the selected +# value should divide 60 minutes without remainder so taken snapshots +# are apart in equal intervals. Values larger than 59 aren't practical +# as only one snapshot will be taken on each full hour in this case. +# examples: +# frequent_period = 15 -> four snapshot each hour 15 minutes apart +# frequent_period = 5 -> twelve snapshots each hour 5 minutes apart +# frequent_period = 45 -> two snapshots each hour with different time gaps +# between them: 45 minutes and 15 minutes in this case frequent_period = 15 # If any snapshot type is set to 0, we will not take snapshots for it - and will immediately From bc2f8bd4e9b150294bad5c3150a682a3e857e3e0 Mon Sep 17 00:00:00 2001 From: Christoph Klaffl Date: Wed, 8 Nov 2017 21:48:37 +0100 Subject: [PATCH 4/6] Revert "hardcoded new defaults" This reverts commit c9adcdab1e7e2a7eaa04bdbc15a24881278cefdb. --- sanoid | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/sanoid b/sanoid index 6428cdf..e8756db 100755 --- a/sanoid +++ b/sanoid @@ -553,18 +553,6 @@ sub getsnaps { #################################################################################### #################################################################################### -sub verify_option_existence { - my ($hash, $key, $default) = @_; - - if (! defined (%$hash{$key})) { - $hash->{$key} = $default; - } -} - -#################################################################################### -#################################################################################### -#################################################################################### - sub init { my ($conf_file, $default_conf_file) = @_; my %config; @@ -580,12 +568,6 @@ sub init { my @istrue=(1,"true","True","TRUE","yes","Yes","YES","on","On","ON"); my @isfalse=(0,"false","False","FALSE","no","No","NO","off","Off","OFF"); - # hardcoded defaults which may be missing from older default configuration file - verify_option_existence($defaults{'template_default'}, 'frequent_period', 15); - verify_option_existence($defaults{'template_default'}, 'frequently', 0); - verify_option_existence($defaults{'template_default'}, 'frequently_warn', 2000); - verify_option_existence($defaults{'template_default'}, 'frequently_crit', 8000); - foreach my $section (keys %ini) { # first up - die with honor if unknown parameters are set in any modules or templates by the user. From 293d83bdaa6155e765432a9a145a786d72afed9e Mon Sep 17 00:00:00 2001 From: Christoph Klaffl Date: Wed, 8 Nov 2017 22:08:02 +0100 Subject: [PATCH 5/6] versioning and compatibility check for default configuration file --- sanoid | 12 ++++++++++++ sanoid.defaults.conf | 2 ++ 2 files changed, 14 insertions(+) diff --git a/sanoid b/sanoid index e8756db..452f535 100755 --- a/sanoid +++ b/sanoid @@ -5,6 +5,7 @@ # project's Git repository at https://github.com/jimsalterjrs/sanoid/blob/master/LICENSE. $::VERSION = '1.4.17'; +my $MINIMUM_DEFAULTS_VERSION = 2; use strict; use warnings; @@ -568,6 +569,17 @@ sub init { my @istrue=(1,"true","True","TRUE","yes","Yes","YES","on","On","ON"); my @isfalse=(0,"false","False","FALSE","no","No","NO","off","Off","OFF"); + # check if default configuration file is up to date + my $defaults_version = 1; + if (defined $defaults{'version'}{'version'}) { + $defaults_version = $defaults{'version'}{'version'}; + delete $defaults{'version'}; + } + + if ($defaults_version < $MINIMUM_DEFAULTS_VERSION) { + die "FATAL: you're using sanoid.defaults.conf v$defaults_version, this version of sanoid requires a minimum sanoid.defaults.conf v$MINIMUM_DEFAULTS_VERSION"; + } + foreach my $section (keys %ini) { # first up - die with honor if unknown parameters are set in any modules or templates by the user. diff --git a/sanoid.defaults.conf b/sanoid.defaults.conf index e7c22a8..06fc714 100644 --- a/sanoid.defaults.conf +++ b/sanoid.defaults.conf @@ -5,6 +5,8 @@ # # # you have been warned. # ################################################################################### +[version] +version = 2 [template_default] From ac16b2128e6863a8af619d0bf9282bf92f6dfbc9 Mon Sep 17 00:00:00 2001 From: Christoph Klaffl Date: Thu, 9 Nov 2017 17:44:04 +0100 Subject: [PATCH 6/6] disable monitoring of frequent snapshots --- sanoid.defaults.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sanoid.defaults.conf b/sanoid.defaults.conf index 06fc714..a521401 100644 --- a/sanoid.defaults.conf +++ b/sanoid.defaults.conf @@ -77,8 +77,8 @@ yearly_min = 0 monitor = yes monitor_dont_warn = no monitor_dont_crit = no -frequently_warn = 2000 -frequently_crit = 8000 +frequently_warn = 0 +frequently_crit = 0 hourly_warn = 90 hourly_crit = 360 daily_warn = 28