#! @PERL@
# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved.
#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 as published
-# by the Free Software Foundation.
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
use Getopt::Long;
use POSIX qw(WIFEXITED WEXITSTATUS strftime);
+use File::Glob qw( :glob );
use Amanda::Config qw( :init :getconf );
use Amanda::Util qw( :constants );
sub usage {
my ($msg) = @_;
print STDERR <<EOF;
-Usage: amdump <conf> [--no-taper] [--from-client] [-o configoption]* [host/disk]*
+Usage: amdump <conf> [--no-taper] [--from-client] [--exact-match] [-o configoption]* [host/disk]*
EOF
print STDERR "$msg\n" if $msg;
exit 1;
my $opt_no_taper = 0;
my $opt_from_client = 0;
+my $opt_exact_match = 0;
debug("Arguments: " . join(' ', @ARGV));
Getopt::Long::Configure(qw(bundling));
'help|usage|?' => \&usage,
'no-taper' => \$opt_no_taper,
'from-client' => \$opt_from_client,
+ 'exact-match' => \$opt_exact_match,
'o=s' => sub {
push @config_overrides_opts, "-o" . $_[1];
add_config_override_opt($config_overrides, $_[1]);
my $datestamp = strftime "%Y%m%d", @now;
my $starttime_locale_independent = strftime "%Y-%m-%d %H:%M:%S %Z", @now;
my $trace_log_filename = "$logdir/log";
-my $amdump_log_filename = "$logdir/amdump";
+my $amdump_log_filename_default = "$logdir/amdump";
+my $amdump_log_filename = "$logdir/amdump.$timestamp";
my $exit_code = 0;
my $amdump_log = \*STDERR;
}
sub do_amcleanup {
- return unless -f $amdump_log_filename || -f $trace_log_filename;
+ return unless -f $amdump_log_filename_default || -f $trace_log_filename;
# logfiles are still around. First, try an amcleanup -p to see if
# the actual processes are already dead
run_subprocess("$sbindir/amcleanup", '-p', $config_name, @config_overrides_opts);
# and check again
- return unless -f $amdump_log_filename || -f $trace_log_filename;
+ return unless -f $amdump_log_filename_default || -f $trace_log_filename;
bail_already_running();
}
# Must be opened in append so that all subprocess can write to it.
open($amdump_log, ">>", $amdump_log_filename)
or die("could not open amdump log file '$amdump_log_filename': $!");
+ unlink $amdump_log_filename_default;
+ symlink $amdump_log_filename, $amdump_log_filename_default;
}
sub planner_driver_pipeline {
my $driver = "$amlibexecdir/driver";
my @no_taper = $opt_no_taper? ('--no-taper'):();
my @from_client = $opt_from_client? ('--from-client'):();
+ my @exact_match = $opt_exact_match? ('--exact-match'):();
check_exec($planner);
check_exec($driver);
close($amdump_log);
exec $planner,
# note that @no_taper must follow --starttime
- $config_name, '--starttime', $timestamp, @no_taper, @from_client, @config_overrides_opts, @hostdisk;
+ $config_name, '--starttime', $timestamp, @no_taper, @from_client, @exact_match, @config_overrides_opts, @hostdisk;
die "Could not exec $planner: $!";
}
debug(" planner: $pl_pid");
sub roll_amdump_logs {
debug("renaming amdump log and trimming old amdump logs (beyond tapecycle+2)");
- # rename all the way along the tapecycle
+ unlink "$amdump_log_filename_default.1";
+ rename $amdump_log_filename_default, "$amdump_log_filename_default.1";
+
+ # keep the latest tapecycle files.
+ my @files = sort {-M $b <=> -M $a} grep { !/^\./ && -f "$_"} <$logdir/amdump.*>;
my $days = getconf($CNF_TAPECYCLE) + 2;
for (my $i = $days-1; $i >= 1; $i--) {
- next unless -f "$amdump_log_filename.$i";
- rename("$amdump_log_filename.$i", "$amdump_log_filename.".($i+1));
+ my $a = pop @files;
+ }
+ foreach my $name (@files) {
+ unlink $name;
+ amdump_log("unlink $name");
}
-
- # now swap the current logfile in
- rename("$amdump_log_filename", "$amdump_log_filename.1");
}
# now do the meat of the amdump work; these operations are ported directly