| Line 151... | Line 151... | 
          
            | 151 | # quick convert unix time stamp to YYYY-MM-DD HH:MM
 | 151 | # quick convert unix time stamp to YYYY-MM-DD HH:MM
 | 
          
            | 152 | sub unix2Gregorian {
 | 152 | sub unix2Gregorian {
 | 
          
            | 153 |    use POSIX qw(strftime);
 | 153 |    use POSIX qw(strftime);
 | 
          
            | 154 |    my $timestamp = shift;
 | 154 |    my $timestamp = shift;
 | 
          
            | 155 |    
 | 155 |    
 | 
          
            | 156 |    return strftime( "%F %R", $timestamp );
 | 156 |    return strftime "%F %R", localtime $timestamp ;
 | 
          
            | 157 | }
 | 157 | }
 | 
          
            | 158 |  
 | 158 |  
 | 
          
            | 159 | # just converts a number of seconds to days HH:MM:SS
 | 159 | # just converts a number of seconds to DD day HH:MM
 | 
          
            | 160 |  
 | 160 |  
 | 
          
            | 161 | sub secondsToHuman {
 | 161 | sub secondsToHuman {
 | 
          
            | 162 |    my $seconds = shift;
 | 162 |    my $seconds = shift;
 | 
          
            | 163 |    
 | 163 |    
 | 
          
            | 164 |    my $days = int( $seconds / $SECONDS_PER_DAY );
 | 164 |    my $days = int( $seconds / $SECONDS_PER_DAY );
 | 
          
            | 165 |    $seconds -= $days * $SECONDS_PER_DAY;
 | 165 |    $seconds -= $days * $SECONDS_PER_DAY;
 | 
          
            | 166 |    my $hours = int( $seconds / 60);
 | 166 |    my $hours = int( $seconds / 60);
 | 
          
            | 167 |    $seconds -= $hours * 60;
 | 167 |    $seconds -= $hours * 60;
 | 
          
            | 168 |    my $minutes = int( $seconds / 60 );
 | 168 |    my $minutes = int( $seconds / 60 );
 | 
          
            | 169 |    $seconds -= $minutes * 60;
 | 169 |    $seconds -= $minutes * 60;
 | 
          
            | 170 |    return printf( '%02d days %02:%02:%02', $days, $hours, $minutes, $seconds );
 | 170 |    return sprintf( '%02dD %02dH%02dM', $days, $hours, $minutes );
 | 
          
            | 171 | }
 | 171 | }
 | 
          
            | 172 |  
 | 172 |  
 | 
          
            | 173 | # Merges datasets, snapshots and some stuff from the configuration into the datasets
 | 173 | # Merges datasets, snapshots and some stuff from the configuration into the datasets
 | 
          
            | 174 | # hash. After this, $config and $snapshots should no longer be necessary
 | 174 | # hash. After this, $config and $snapshots should no longer be necessary
 | 
          
            | 175 | sub mergeData {
 | 175 | sub mergeData {
 | 
          
            | Line 203... | Line 203... | 
          
            | 203 |  
 | 203 |  
 | 
          
            | 204 | # check to see if a particular snapshot is ready to be destroyed, ie right now is greater than the retention period
 | 204 | # check to see if a particular snapshot is ready to be destroyed, ie right now is greater than the retention period
 | 
          
            | 205 | # if $recurive is true, add the '-r' to the command to do a recursive destroy
 | 205 | # if $recurive is true, add the '-r' to the command to do a recursive destroy
 | 
          
            | 206 | sub checkRetention {
 | 206 | sub checkRetention {
 | 
          
            | 207 |    my ( $retentionPeriod, $recursive, $snapshots, $now ) = @_;
 | 207 |    my ( $retentionPeriod, $recursive, $snapshots, $now ) = @_;
 | 
          
            | - |   | 208 |    print "\tRemoving snapshots older than " . &unix2Gregorian( $now - $retentionPeriod ) . "\n"  if $config->{'DEBUG'};
 | 
          
            | 208 |    my @toDelete; # an array of destroy commands
 | 209 |    my @toDelete; # an array of destroy commands
 | 
          
            | 209 |    foreach my $thisSnapshot ( keys %$snapshots ) {
 | 210 |    foreach my $thisSnapshot ( keys %$snapshots ) {
 | 
          
            | 210 |       # print "checking $thisSnapshot\n\tNow: $now\n\tDate: $snapshots->{$thisSnapshot}->{date}->{unix}\n\tRetention: $retentionPeriod\n\n";
 | 211 |       # print "checking $thisSnapshot\n\tNow: $now\n\tDate: $snapshots->{$thisSnapshot}->{date}->{unix}\n\tRetention: $retentionPeriod\n\n";
 | 
          
            | 211 |       if ( $now - $snapshots->{$thisSnapshot}->{'date'}->{'unix'} > $retentionPeriod ) { # it is too old
 | 212 |       if ( $now - $snapshots->{$thisSnapshot}->{'date'}->{'unix'} > $retentionPeriod ) { # it is too old
 | 
          
            | 212 |          push ( @toDelete, ( 'zfs destroy ' . ($recursive ? '-r ' : '') . $thisSnapshot ) ); # list it to be destroyed
 | 213 |          push ( @toDelete, ( 'zfs destroy ' . ($recursive ? '-r ' : '') . $thisSnapshot ) ); # list it to be destroyed
 | 
          
            | Line 234... | Line 235... | 
          
            | 234 |    my @toAdd; # will hold all the create commands
 | 235 |    my @toAdd; # will hold all the create commands
 | 
          
            | 235 |    
 | 236 |    
 | 
          
            | 236 |    foreach my $thisDataset ( keys %$datasets ) { # Look at each dataset/volume in turn
 | 237 |    foreach my $thisDataset ( keys %$datasets ) { # Look at each dataset/volume in turn
 | 
          
            | 237 |       if ( $config->{'DEBUG'} ) {
 | 238 |       if ( $config->{'DEBUG'} ) {
 | 
          
            | 238 |          print "Found Datasset $thisDataset\n";
 | 239 |          print "Found Datasset $thisDataset\n";
 | 
          
            | 239 |          print "\tRetention period set to " . &secondsToHuman( $datasets->{$thisDataset}->{'retention'} ) . "\n";
 | - |   | 
          
            | 240 |          print "\tNext Snapshot due " . 
 | 240 |          print "\tNext Snapshot due " . 
 | 
          
            | 241 |             &unix2Gregorian( $datasets->{$thisDataset}->{'lastSnap'} + $datasets->{$thisDataset}->{'frequency'} - $slop ) . "\n";
 | 241 |             &unix2Gregorian( $datasets->{$thisDataset}->{'lastSnap'} + $datasets->{$thisDataset}->{'frequency'} - $slop ) . "\n";
 | 
          
            | - |   | 242 |          print "\tRetention period set to " . &secondsToHuman( $datasets->{$thisDataset}->{'retention'} ) . "\n";
 | 
          
            | 242 |       }
 | 243 |       }
 | 
          
            | 243 |       # if any snapshots need to be destroyed, add them to @toDelete
 | 244 |       # if any snapshots need to be destroyed, add them to @toDelete
 | 
          
            | 244 |       push( @toDelete, 
 | 245 |       push( @toDelete, 
 | 
          
            | 245 |          &checkRetention( 
 | 246 |          &checkRetention( 
 | 
          
            | 246 |          $datasets->{$thisDataset}->{'retention'}, 
 | 247 |          $datasets->{$thisDataset}->{'retention'}, 
 | 
          
            | 247 |          $datasets->{$thisDataset}->{'recursive'}, 
 | 248 |          $datasets->{$thisDataset}->{'recursive'}, 
 | 
          
            | 248 |          $datasets->{$thisDataset}->{'snapshots'}, 
 | 249 |          $datasets->{$thisDataset}->{'snapshots'}, 
 | 
          
            | 249 |          $now )
 | 250 |          $now )
 | 
          
            | 250 |          );
 | 251 |          );
 | 
          
            | 251 |       # if it is time to add a new snapshot, add it to @toAdd
 | 252 |       # if there is no snapshaor or it is time to add a new snapshot, add it to @toAdd
 | 
          
            | 252 |       if ( $datasets->{$thisDataset}->{'lastSnap'} + $datasets->{$thisDataset}->{'frequency'} - $slop < $now ) {
 | 253 |       if ( !$datasets->{$thisDataset}->{'lastSnap'} || $datasets->{$thisDataset}->{'lastSnap'} + $datasets->{$thisDataset}->{'frequency'} - $slop < $now ) {
 | 
          
            | 253 |          push @toAdd, &makeSnapshot( $thisDataset, $datasets->{$thisDataset}->{'recursive'}, $snapshotName )
 | 254 |          push @toAdd, &makeSnapshot( $thisDataset, $datasets->{$thisDataset}->{'recursive'}, $snapshotName )
 | 
          
            | 254 |       }
 | 255 |       }
 | 
          
            | 255 |    }
 | 256 |    }
 | 
          
            | 256 |    # return the actions, deletions first, adds second (executed in that order)
 | 257 |    # return the actions, deletions first, adds second (executed in that order)
 | 
          
            | 257 |    return ( @toDelete, @toAdd );
 | 258 |    return ( @toDelete, @toAdd );
 |