mirror of https://github.com/jimsalterjrs/sanoid
commit
f107907dc4
49
sanoid
49
sanoid
|
|
@ -334,6 +334,19 @@ sub take_snapshots {
|
||||||
|
|
||||||
my @newsnaps;
|
my @newsnaps;
|
||||||
|
|
||||||
|
# get utc timestamp of the current day for DST check
|
||||||
|
my $daystartUtc = timelocal(0, 0, 0, $datestamp{'mday'}, ($datestamp{'mon'}-1), $datestamp{'year'});
|
||||||
|
my ($isdst) = (localtime($daystartUtc))[8];
|
||||||
|
my $dstOffset = 0;
|
||||||
|
|
||||||
|
if ($isdst ne $datestamp{'isdst'}) {
|
||||||
|
# current dst is different then at the beginning og the day
|
||||||
|
if ($isdst) {
|
||||||
|
# DST ended in the current day
|
||||||
|
$dstOffset = 60*60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($args{'verbose'}) { print "INFO: taking snapshots...\n"; }
|
if ($args{'verbose'}) { print "INFO: taking snapshots...\n"; }
|
||||||
foreach my $section (keys %config) {
|
foreach my $section (keys %config) {
|
||||||
if ($section =~ /^template/) { next; }
|
if ($section =~ /^template/) { next; }
|
||||||
|
|
@ -357,6 +370,9 @@ sub take_snapshots {
|
||||||
my @preferredtime;
|
my @preferredtime;
|
||||||
my $lastpreferred;
|
my $lastpreferred;
|
||||||
|
|
||||||
|
# to avoid duplicates with DST
|
||||||
|
my $dateSuffix = "";
|
||||||
|
|
||||||
if ($type eq 'hourly') {
|
if ($type eq 'hourly') {
|
||||||
push @preferredtime,0; # try to hit 0 seconds
|
push @preferredtime,0; # try to hit 0 seconds
|
||||||
push @preferredtime,$config{$section}{'hourly_min'};
|
push @preferredtime,$config{$section}{'hourly_min'};
|
||||||
|
|
@ -365,6 +381,13 @@ sub take_snapshots {
|
||||||
push @preferredtime,($datestamp{'mon'}-1); # january is month 0
|
push @preferredtime,($datestamp{'mon'}-1); # january is month 0
|
||||||
push @preferredtime,$datestamp{'year'};
|
push @preferredtime,$datestamp{'year'};
|
||||||
$lastpreferred = timelocal(@preferredtime);
|
$lastpreferred = timelocal(@preferredtime);
|
||||||
|
|
||||||
|
if ($dstOffset ne 0) {
|
||||||
|
# timelocal doesn't take DST into account
|
||||||
|
$lastpreferred += $dstOffset;
|
||||||
|
# DST ended, avoid duplicates
|
||||||
|
$dateSuffix = "_y";
|
||||||
|
}
|
||||||
if ($lastpreferred > time()) { $lastpreferred -= 60*60; } # preferred time is later this hour - so look at last hour's
|
if ($lastpreferred > time()) { $lastpreferred -= 60*60; } # preferred time is later this hour - so look at last hour's
|
||||||
} elsif ($type eq 'daily') {
|
} elsif ($type eq 'daily') {
|
||||||
push @preferredtime,0; # try to hit 0 seconds
|
push @preferredtime,0; # try to hit 0 seconds
|
||||||
|
|
@ -374,7 +397,29 @@ sub take_snapshots {
|
||||||
push @preferredtime,($datestamp{'mon'}-1); # january is month 0
|
push @preferredtime,($datestamp{'mon'}-1); # january is month 0
|
||||||
push @preferredtime,$datestamp{'year'};
|
push @preferredtime,$datestamp{'year'};
|
||||||
$lastpreferred = timelocal(@preferredtime);
|
$lastpreferred = timelocal(@preferredtime);
|
||||||
if ($lastpreferred > time()) { $lastpreferred -= 60*60*24; } # preferred time is later today - so look at yesterday's
|
|
||||||
|
# timelocal doesn't take DST into account
|
||||||
|
$lastpreferred += $dstOffset;
|
||||||
|
|
||||||
|
# check if the planned time has different DST flag than the current
|
||||||
|
my ($isdst) = (localtime($lastpreferred))[8];
|
||||||
|
if ($isdst ne $datestamp{'isdst'}) {
|
||||||
|
if (!$isdst) {
|
||||||
|
# correct DST difference
|
||||||
|
$lastpreferred -= 60*60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($lastpreferred > time()) {
|
||||||
|
$lastpreferred -= 60*60*24;
|
||||||
|
|
||||||
|
if ($dstOffset ne 0) {
|
||||||
|
# because we are going back one day
|
||||||
|
# the DST difference has to be accounted
|
||||||
|
# for in reverse now
|
||||||
|
$lastpreferred -= 2*$dstOffset;
|
||||||
|
}
|
||||||
|
} # preferred time is later today - so look at yesterday's
|
||||||
} elsif ($type eq 'monthly') {
|
} elsif ($type eq 'monthly') {
|
||||||
push @preferredtime,0; # try to hit 0 seconds
|
push @preferredtime,0; # try to hit 0 seconds
|
||||||
push @preferredtime,$config{$section}{'monthly_min'};
|
push @preferredtime,$config{$section}{'monthly_min'};
|
||||||
|
|
@ -402,7 +447,7 @@ sub take_snapshots {
|
||||||
# update to most current possible datestamp
|
# update to most current possible datestamp
|
||||||
%datestamp = get_date();
|
%datestamp = get_date();
|
||||||
# print "we should have had a $type snapshot of $path $maxage seconds ago; most recent is $newestage seconds old.\n";
|
# print "we should have had a $type snapshot of $path $maxage seconds ago; most recent is $newestage seconds old.\n";
|
||||||
push(@newsnaps, "$path\@autosnap_$datestamp{'sortable'}_$type");
|
push(@newsnaps, "$path\@autosnap_$datestamp{'sortable'}${dateSuffix}_$type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# this test will check the behaviour arround a date where DST ends
|
||||||
|
# with hourly, daily and monthly snapshots checked in a 15 minute interval
|
||||||
|
|
||||||
|
# Daylight saving time 2017 in Europe/Vienna began at 02:00 on Sunday, 26 March
|
||||||
|
# and ended at 03:00 on Sunday, 29 October. All times are in
|
||||||
|
# Central European Time.
|
||||||
|
|
||||||
|
. ../common/lib.sh
|
||||||
|
|
||||||
|
POOL_NAME="sanoid-test-2"
|
||||||
|
POOL_TARGET="" # root
|
||||||
|
RESULT="/tmp/sanoid_test_result"
|
||||||
|
RESULT_CHECKSUM="a916d9cd46f4b80f285d069f3497d02671bbb1bfd12b43ef93531cbdaf89d55c"
|
||||||
|
|
||||||
|
# UTC timestamp of start and end
|
||||||
|
START="1509141600"
|
||||||
|
END="1509400800"
|
||||||
|
|
||||||
|
# prepare
|
||||||
|
setup
|
||||||
|
checkEnvironment
|
||||||
|
disableTimeSync
|
||||||
|
|
||||||
|
# set timezone
|
||||||
|
ln -sf /usr/share/zoneinfo/Europe/Vienna /etc/localtime
|
||||||
|
|
||||||
|
timestamp=$START
|
||||||
|
|
||||||
|
mkdir -p "${POOL_TARGET}"
|
||||||
|
truncate -s 512M "${POOL_TARGET}"/zpool2.img
|
||||||
|
|
||||||
|
zpool create -f "${POOL_NAME}" "${POOL_TARGET}"/zpool2.img
|
||||||
|
|
||||||
|
function cleanUp {
|
||||||
|
zpool export "${POOL_NAME}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# export pool in any case
|
||||||
|
trap cleanUp EXIT
|
||||||
|
|
||||||
|
while [ $timestamp -le $END ]; do
|
||||||
|
date --utc --set @$timestamp; date; "${SANOID}" --cron --verbose
|
||||||
|
timestamp=$((timestamp+900))
|
||||||
|
done
|
||||||
|
|
||||||
|
saveSnapshotList "${POOL_NAME}" "${RESULT}"
|
||||||
|
|
||||||
|
# hourly daily monthly
|
||||||
|
verifySnapshotList "${RESULT}" 73 3 1 "${RESULT_CHECKSUM}"
|
||||||
|
|
||||||
|
# one more hour because of DST
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
[sanoid-test-2]
|
||||||
|
use_template = production
|
||||||
|
|
||||||
|
[template_production]
|
||||||
|
hourly = 36
|
||||||
|
daily = 30
|
||||||
|
monthly = 3
|
||||||
|
yearly = 0
|
||||||
|
autosnap = yes
|
||||||
|
autoprune = no
|
||||||
Loading…
Reference in New Issue