Commit 724de4c0 authored by Nigel Kukard's avatar Nigel Kukard
Browse files

Better support for other versions of tar

parent 3253de2c
......@@ -41,7 +41,7 @@ use MIME::Base64;
my $VERSION = "0.0.10";
my $VERSION = "0.0.12";
# System dirs we don't care about
my @defaultSystemExcl = ("/dev","/run","/proc","/sys","/tmp","/var/tmp");
# These should be backed up separately
......@@ -49,7 +49,8 @@ my @defaultDataExcl = (
"/var/lib/mysql","/var/lib/pgsql",
"/var/amavis/tmp/",
"/var/spool/mailman/retry",
"/var/spool/postfix/public"
"/var/spool/postfix/public",
"/var/spool/postfix/private"
);
......@@ -75,6 +76,7 @@ use constant {
# Main config
my %config = (
'log-level' => LOG_NOTICE,
'tar' => 'tar',
'exclude-system' => 0,
);
# Choose default compression method
......@@ -99,6 +101,7 @@ GetOptions(\%optctl,
"config=s",
"log-level=i",
"tar=s",
"backup",
"compress:s",
......@@ -241,6 +244,16 @@ if (defined($optctl{'compress'})) {
$config{'compress'} = $optctl{'compress'};
}
if (defined($optctl{'tar'})) {
# Check if tar is executable
if ( -x $optctl{'tar'}) {
$config{'tar'} = $optctl{'tar'};
} else {
print(STDERR "ERROR: tar '".$optctl{'tar'}."' does not exist or is not executable\n");
}
}
my $tarVer = getTarVer($config{'tar'});
if (defined($optctl{'log-level'})) {
$config{'log-level'} = $optctl{'log-level'};
}
......@@ -662,20 +675,6 @@ sub backup
# Get current sequence
my $seq = $newPathAttribs{$path}->{'sequence'};
# File list to backup
open(MANIFEST,"> $dest/$path/dbackup$seq.manifest")
or die "Failed to open '$dest/$path/dbackup$seq.manifest': $!";
foreach my $item (@manifestList) {
# If this is not the top dir, use /
if ($path ne "") {
print(MANIFEST "$path/$item\0");
# If it is, don't use /
} else {
print(MANIFEST "$item\0");
}
}
close(MANIFEST);
# Setup tar args
my @tarArgs = ();
my $tarExt;
......@@ -696,6 +695,58 @@ sub backup
$newPathAttribs{$path}->{'format'} = "tar";
$newPathAttribs{$path}->{'compression'} = $config{'compress'};
# Sort out manifest format
my $manifestDelim;
# Are we overriding the manifest format?
if (defined($config{'manifest-format'})) {
$newPathAttribs{$path}->{'manifest.format'} = $config{'manifest-format'};
} else {
# If not choose best
if (defined($origPathAttribs{$path}->{'manifest.format'})) {
$newPathAttribs{$path}->{'manifest.format'} = $origPathAttribs{$path}->{'manifest.format'};
} else {
# Tar pre-1.22 is buggered with \0 manifest files
if ($tarVer > 122) {
$newPathAttribs{$path}->{'manifest.format'} = "null";
} else {
$newPathAttribs{$path}->{'manifest.format'} = "newline";
}
}
}
# Setup manifest delim & tar options
if ($newPathAttribs{$path}->{'manifest.format'} eq "null") {
push(@tarArgs,"--null");
push(@tarArgs,"--files-from", "$dest/$path/dbackup$seq.manifest");
push(@tarArgs,"--no-unquote");
$manifestDelim = "\0";
} elsif ($newPathAttribs{$path}->{'manifest.format'} eq "newline") {
push(@tarArgs,"--files-from", "$dest/$path/dbackup$seq.manifest");
$manifestDelim = "\n";
} else {
printLog(LOG_ERROR,"Invalid manifest.format '".$newPathAttribs{$path}->{'manifest.format'}."'\n");
exit 1;
}
# File list to backup
open(MANIFEST,"> $dest/$path/dbackup$seq.manifest")
or die "Failed to open '$dest/$path/dbackup$seq.manifest': $!";
foreach my $item (@manifestList) {
# Sanity check to see if this filename is going to work
if ($manifestDelim eq "\n" && $item =~ /[\n"'\\]/) {
printLog(LOG_ERROR,"ERROR: Your version of tar cannot backup => path:'$path', file '$item'\n");
next;
}
# If this is not the top dir, use /
if ($path ne "") {
print(MANIFEST "$path/$item$manifestDelim");
# If it is, don't use /
} else {
print(MANIFEST "$item$manifestDelim");
}
}
close(MANIFEST);
# Change dir and start backup
system(
"tar",
......@@ -705,10 +756,6 @@ sub backup
"--file", "$dest/$path/dbackup$seq.tar$tarExt",
# cd into here first...
"--directory", "$source",
# Read file list from here
"--null",
"--files-from", "$dest/$path/dbackup$seq.manifest",
"--no-unquote",
# Do not recurse
"--no-recursion",
# Output to this file
......@@ -727,7 +774,7 @@ sub backup
} else {
my $retcode = $? >> 8;
# If tar died, lets die too
if ($retcode == 2) {
if ($retcode >= 2) {
printLog(LOG_ERROR,"tar died with error code $retcode\n");
exit 1;
}
......@@ -988,6 +1035,24 @@ sub restore
return @list;
}
# Setup manifest delim & tar options
if ($origPathAttribs{$path}->{'manifest.format'} eq "null") {
push(@tarArgs,"--null");
push(@tarArgs,"--files-from", "$source/$path/dbackup$seq.manifest");
push(@tarArgs,"--no-unquote");
} elsif ($origPathAttribs{$path}->{'manifest.format'} eq "newline") {
push(@tarArgs,"--files-from", "$source/$path/dbackup$seq.manifest");
} else {
printLog(LOG_ERROR,"Invalid manifest.format '".$origPathAttribs{$path}->{'manifest.format'}."'\n");
exit 1;
}
# Sanity check
if ($tarVer < 122 && $origPathAttribs{$path}->{'manifest.format'} eq "null") {
printLog(LOG_ERROR,"Your version of tar does NOT support manifest.format of 'null'\n");
exit 1;
}
# Other tar options
if (defined($optctl{'tar-keep-newer'})) {
push(@tarArgs,"--keep-newer-files");
......@@ -1004,10 +1069,6 @@ sub restore
"--file", "$source/$path/dbackup$seq.tar$tarExt",
# cd into here first...
"--directory", "$dest",
# Read file list from here
"--null",
"--files-from", "$source/$path/dbackup$seq.manifest",
"--no-unquote",
# Do not recurse
"--no-recursion",
# Incremental options
......@@ -1023,7 +1084,7 @@ sub restore
} else {
my $retcode = $? >> 8;
# If tar died, lets die too
if ($retcode == 2) {
if ($retcode >= 2) {
printLog(LOG_ERROR,"tar died with error code $retcode\n");
exit 1;
}
......@@ -1301,4 +1362,27 @@ sub toArray
}
}
sub getTarVer
{
my $tar = shift;
open(TAR, $config{'tar'} . " --version |")
or die "FAILED to execute '".$config{'tar'}."': $!";
if (!($tarVer = <TAR>)) {
print(STDERR "ERROR: Failed to read tar version\n");
exit 1;
}
($tarVer) = ($tarVer =~ /([0-9]+\.[0-9]+)/);
if (!defined($tarVer) || $tarVer eq "") {
print(STDERR "ERROR: Failed to parse tar version\n");
exit 1;
}
$tarVer =~ s/\.//g;
close(TAR);
if ($tarVer < 100) {
print(STDERR "ERROR: Failed to read tar version or your version is simply too old\n");
exit 1;
}
}
# vim: ts=4
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment