Skip to content

Instantly share code, notes, and snippets.

@anazawa
Created October 9, 2013 19:58
Show Gist options
  • Save anazawa/6907321 to your computer and use it in GitHub Desktop.
Save anazawa/6907321 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
use Time::Seconds;
our $VERSION = '0.01';
my $device = '/dev/ada0p2';
#my $backupdir = '/backup/esprimo';
my $backupdir = '/home/anazawa/work/backup/tmp';
my $prefix = 'root';
my $size_limit = 100000; # MB
my @dumpdates;
if ( open my $fh, '<', '/etc/dumpdates' ) {
while ( my $line = <$fh> ) {
chomp $line;
my ( $d, $level, $date ) = split ' ', $line, 3;
next unless $d eq $device;
$date = localtime->strptime( $date, '%a %b %e %T %Y' );
push @dumpdates, { level => $level, date => $date };
}
close $fh;
}
my $now = localtime;
my @full_backups = grep { $_->{level} == 0 } @dumpdates;
if ( !@dumpdates or $now->ymd(q{}) > $dumpdates[-1]{date}->ymd(q{}) ) {
my $level = @dumpdates ? $dumpdates[-1]{level} + 1 : 0;
$level = 1 if $level > 7; # differencial backup
$level = 0 if @full_backups and $now - $full_backups[-1]{date} >= ONE_MONTH;
my $file = "$backupdir/$prefix";
$file .= '-' . $now->ymd(q{});
$file .= $level == 1 ? '-D' : '-I' if $level;
$file .= '.dump';
die "File already exists: $file" if -e $file;
# TODO: -L is missing
my @options = (
"-$level", # dump level
'-u', # update /etc/dumpdates
'-a', # auto-size
'-b' => 64, # blocksize
'-C' => 32, # cachesize
'-f' => $file, #
);
system '/sbin/dump', @options, $device;
}
my @old_backups;
if ( @full_backups > 1 and opendir my $dh, $backupdir ) {
for my $basename ( sort readdir $dh ) {
next unless $basename =~ /^$prefix\-(\d{8})(?:\-\w)?\.dump$/;
last if $1 >= $full_backups[-2]{date}->ymd(q{});
push @old_backups, $basename;
}
closedir $dh;
}
# TODO: use autodie;
if ( @old_backups ) {
( my $tarball = $old_backups[0] ) =~ s/\.dump$/\.tar\.gz/;
chdir $backupdir or die "Can't cd to $backupdir: $!\n";
die "File already exists: $backupdir/$tarball" if -e $tarball;
system( 'tar', '-czf', $tarball, @old_backups ) == 0 or die "Failed to create tarball";
unlink or warn "Can't unlink $_: $!" for @old_backups;
}
__END__
=head1 NAME
dump.pl - Multilevel incremental backup using dump(8)
=head1 SYNOPSIS
./dump.pl filesystem
=head1 DESCRIPTION
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment