X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Famvault.pl;fp=server-src%2Famvault.pl;h=88111f7c9728b3324ce4e4d9911f450c235fd474;hb=109540caa4e37a3663b3dcfb9a205b9609e3f561;hp=87a43fb95790c2aacf3c5862a2062f37ff6adb51;hpb=4c9eba1feb11adf189bceb4001c425e641f0b56a;p=debian%2Famanda diff --git a/server-src/amvault.pl b/server-src/amvault.pl index 87a43fb..88111f7 100644 --- a/server-src/amvault.pl +++ b/server-src/amvault.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-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 @@ -141,6 +141,7 @@ sub new { exporting => 0, # is an export in progress? call_after_export => undef, # call this when export complete config_overrides_opts => $params{'config_overrides_opts'}, + trace_log_filename => getconf($CNF_LOGDIR) . "/log", # called when the operation is complete, with the exit # status @@ -148,6 +149,47 @@ sub new { }, $class; } +sub run_subprocess { + my ($proc, @args) = @_; + + my $pid = POSIX::fork(); + if ($pid == 0) { + my $null = POSIX::open("/dev/null", POSIX::O_RDWR); + POSIX::dup2($null, 0); + POSIX::dup2($null, 1); + POSIX::dup2($null, 2); + exec $proc, @args; + die "Could not exec $proc: $!"; + } + waitpid($pid, 0); + my $s = $? >> 8; + debug("$proc exited with code $s: $!"); +} + +sub do_amcleanup { + my $self = shift; + + return 1 unless -f $self->{'trace_log_filename'}; + + # logfiles are still around. First, try an amcleanup -p to see if + # the actual processes are already dead + debug("runing amcleanup -p"); + run_subprocess("$sbindir/amcleanup", '-p', $self->{'config_name'}, + $self->{'config_overrides_opts'}); + + return 1 unless -f $self->{'trace_log_filename'}; + + return 0; +} + +sub bail_already_running() { + my $self = shift; + my $msg = "An Amanda process is already running - please run amcleanup manually"; + print "$msg\n"; + debug($msg); + $self->{'exit_cb'}->(1); +} + sub run { my $self = shift; my ($exit_cb) = @_; @@ -163,7 +205,20 @@ sub run { # open up a trace log file and put our imprimatur on it, unless dry_runing if (!$self->{'opt_dry_run'}) { + if (!$self->do_amcleanup()) { + return $self->bail_already_running(); + } log_add($L_INFO, "amvault pid $$"); + + # Check we own the log file + open(my $tl, "<", $self->{'trace_log_filename'}) + or die("could not open trace log file '$self->{'trace_log_filename'}': $!"); + if (<$tl> !~ /^INFO amvault amvault pid $$/) { + debug("another amdump raced with this one, and won"); + close($tl); + return $self->bail_already_running(); + } + close($tl); log_add($L_START, "date " . $self->{'dst_write_timestamp'}); Amanda::Debug::add_amanda_log_handler($amanda_log_trace_log); $self->{'cleanup'}{'roll_trace_log'} = 1; @@ -249,7 +304,7 @@ sub setup_src { # convert the timestamp and level to a dumpspec my $level = $self->{'fulls_only'}? "0" : undef; push @dumpspecs, Amanda::Cmdline::dumpspec_t->new( - undef, undef, $self->{'src_write_timestamp'}, $level, undef); + undef, undef, undef, $level, $self->{'src_write_timestamp'}); } # if we ignored all of the dumpspecs and didn't create any, then dump