X7ROOT File Manager
Current Path:
/usr/lib64/amanda
usr
/
lib64
/
amanda
/
📁
..
📄
amanda-sh-lib.sh
(913 B)
📄
amandad
(35.36 KB)
📄
amcat.awk
(184 B)
📄
amcheck-device
(9.64 KB)
📄
amdumpd
(10.1 KB)
📄
amidxtaped
(29.5 KB)
📄
amindexd
(47.25 KB)
📄
amlogroll
(2.36 KB)
📄
amndmjob
(48.44 KB)
📄
amplot.awk
(18.08 KB)
📄
amplot.g
(3.26 KB)
📄
amplot.gp
(3.27 KB)
📄
amtrmidx
(18.98 KB)
📄
amtrmlog
(14.97 KB)
📁
application
📄
calcsize
(19.14 KB)
📄
chg-disk
(7.73 KB)
📄
chg-lib.sh
(4.05 KB)
📄
chg-manual
(7.55 KB)
📄
chg-multi
(12.38 KB)
📄
chg-zd-mtx
(44.8 KB)
📄
chunker
(27.07 KB)
📄
driver
(75.41 KB)
📄
dumper
(51.27 KB)
📄
killpgrp
(10.98 KB)
📄
ndmjob
(52.44 KB)
📄
noop
(10.95 KB)
📄
patch-system
(4.89 KB)
📄
planner
(63.27 KB)
📄
rundump
(10.95 KB)
📄
runtar
(14.96 KB)
📄
selfcheck
(35.05 KB)
📄
sendbackup
(56.48 KB)
📄
sendsize
(55.48 KB)
📄
taper
(2.56 KB)
📄
teecount
(10.94 KB)
Editing: amdumpd
#! /usr/bin/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 # 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 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com use lib '/usr/lib64/perl5/vendor_perl'; use strict; use warnings; use Data::Dumper; ## # ClientService class package main::ClientService; use base 'Amanda::ClientService'; use Symbol; use IPC::Open3; use Amanda::Debug qw( debug info warning ); use Amanda::Util qw( :constants ); use Amanda::Feature; use Amanda::Config qw( :init :getconf config_dir_relative ); use Amanda::Cmdline; use Amanda::Paths; use Amanda::Disklist; use Amanda::Util qw( match_disk match_host ); # Note that this class performs its control IO synchronously. This is adequate # for this service, as it never receives unsolicited input from the remote # system. sub run { my $self = shift; $self->{'my_features'} = Amanda::Feature::Set->mine(); $self->{'their_features'} = Amanda::Feature::Set->old(); $self->setup_streams(); } sub setup_streams { my $self = shift; # always started from amandad. my $req = $self->get_req(); # make some sanity checks my $errors = []; if (defined $req->{'options'}{'auth'} and defined $self->amandad_auth() and $req->{'options'}{'auth'} ne $self->amandad_auth()) { my $reqauth = $req->{'options'}{'auth'}; my $amauth = $self->amandad_auth(); push @$errors, "recover program requested auth '$reqauth', " . "but amandad is using auth '$amauth'"; $main::exit_status = 1; } # and pull out the features, if given if (defined($req->{'features'})) { $self->{'their_features'} = $req->{'features'}; } $self->send_rep(['CTL' => 'rw'], $errors); return $self->quit() if (@$errors); $self->{'ctl_stream'} = 'CTL'; $self->read_command(); } sub cmd_config { my $self = shift; if (defined $self->{'config'}) { $self->sendctlline("ERROR duplicate CONFIG command"); $self->{'abort'} = 1; return; } my $config = $1; config_init($CONFIG_INIT_EXPLICIT_NAME, $config); my ($cfgerr_level, @cfgerr_errors) = config_errors(); if ($cfgerr_level >= $CFGERR_ERRORS) { $self->sendctlline("ERROR configuration errors; aborting connection"); $self->{'abort'} = 1; return; } Amanda::Util::finish_setup($RUNNING_AS_DUMPUSER_PREFERRED); # and the disklist my $diskfile = Amanda::Config::config_dir_relative(getconf($CNF_DISKFILE)); $cfgerr_level = Amanda::Disklist::read_disklist('filename' => $diskfile); if ($cfgerr_level >= $CFGERR_ERRORS) { $self->sendctlline("ERROR Errors processing disklist"); $self->{'abort'} = 1; return; } $self->{'config'} = $config; $self->check_host(); } sub cmd_features { my $self = shift; my $features; $self->{'their_features'} = Amanda::Feature::Set->from_string($features); my $featreply; my $featurestr = $self->{'my_features'}->as_string(); $featreply = "FEATURES $featurestr"; $self->sendctlline($featreply); } sub cmd_list { my $self = shift; if (!defined $self->{'config'}) { $self->sendctlline("CONFIG must be set before listing the disk"); return; } for my $disk (@{$self->{'host'}->{'disks'}}) { $self->sendctlline(Amanda::Util::quote_string($disk)); } $self->sendctlline("ENDLIST"); } sub cmd_disk { my $self = shift; my $qdiskname = shift; my $diskname = Amanda::Util::unquote_string($qdiskname); if (!defined $self->{'config'}) { $self->sendctlline("CONFIG must be set before setting the disk"); return; } for my $disk (@{$self->{'host'}->{'disks'}}) { if ($disk eq $diskname) { push @{$self->{'disk'}}, $diskname; $self->sendctlline("DISK $diskname added"); last; } } } sub cmd_dump { my $self = shift; if (!defined $self->{'config'}) { $self->sendctlline("CONFIG must be set before doing a backup"); return; } my $logdir = config_dir_relative(getconf($CNF_LOGDIR)); if (-f "$logdir/log" || -f "$logdir/amdump" || -f "$logdir/amflush") { $self->sendctlline("BUSY Amanda is busy, retry later"); return; } $self->sendctlline("DUMPING"); my @command = ("$sbindir/amdump", "--no-taper", "--from-client", $self->{'config'}, $self->{'host'}->{'hostname'}); if (defined $self->{'disk'}) { @command = (@command, @{$self->{'disk'}}); } debug("command: @command"); my $amdump_out; my $amdump_in; my $pid = open3($amdump_in, $amdump_out, $amdump_out, @command); close($amdump_in); while (<$amdump_out>) { chomp; $self->sendctlline($_); } $self->sendctlline("ENDDUMP"); } sub cmd_check { my $self = shift; if (!defined $self->{'config'}) { $self->sendctlline("CONFIG must be set before doing a backup"); return; } my $logdir = config_dir_relative(getconf($CNF_LOGDIR)); if (-f "$logdir/log" || -f "$logdir/amdump" || -f "$logdir/amflush") { $self->sendctlline("BUSY Amanda is busy, retry later"); return; } $self->sendctlline("CHECKING"); my @command = ("$sbindir/amcheck", "-c", $self->{'config'}, $self->{'host'}->{'hostname'}); if (defined $self->{'disk'}) { @command = (@command, @{$self->{'disk'}}); } debug("command: @command"); my $amcheck_out; my $amcheck_in; my $pid = open3($amcheck_in, $amcheck_out, $amcheck_out, @command); close($amcheck_in); while (<$amcheck_out>) { chomp; $self->sendctlline($_); } $self->sendctlline("ENDCHECK"); } sub read_command { my $self = shift; my $ctl_stream = $self->{'ctl_stream'}; my $command = $self->{'command'} = {}; my @known_commands = qw( CONFIG DUMP FEATURES LIST DISK); while (!$self->{'abort'} and ($_ = $self->getline($ctl_stream))) { $_ =~ s/\r?\n$//g; last if /^END$/; last if /^[0-9]+$/; if (/^CONFIG (.*)$/) { $self->cmd_config($1); } elsif (/^FEATURES (.*)$/) { $self->cmd_features($1); } elsif (/^LIST$/) { $self->cmd_list(); } elsif (/^DISK (.*)$/) { $self->cmd_disk($1); } elsif (/^CHECK$/) { $self->cmd_check(); } elsif (/^DUMP$/) { $self->cmd_dump(); } elsif (/^END$/) { $self->{'abort'} = 1; } else { $self->sendctlline("invalid command '$_'"); } } } sub check_host { my $self = shift; my @hosts = Amanda::Disklist::all_hosts(); my $peer = $ENV{'AMANDA_AUTHENTICATED_PEER'}; if (!defined($peer)) { debug("no authenticated peer name is available; rejecting request."); $self->sendctlline("no authenticated peer name is available; rejecting request."); die(); } # try to find the host that match the connection my $matched = 0; for my $host (@hosts) { if (lc($peer) eq lc($host->{'hostname'})) { $matched = 1; $self->{'host'} = $host; last; } } if (!$matched) { debug("The peer host '$peer' doesn't match a host in the disklist."); $self->sendctlline("The peer host '$peer' doesn't match a host in the disklist."); $self->{'abort'} = 1; } } sub get_req { my $self = shift; my $req_str = ''; while (1) { my $buf = Amanda::Util::full_read($self->rfd('main'), 1024); last unless $buf; $req_str .= $buf; } # we've read main to EOF, so close it $self->close('main', 'r'); return $self->{'req'} = $self->parse_req($req_str); } sub send_rep { my $self = shift; my ($streams, $errors) = @_; my $rep = ''; # first, if there were errors in the REQ, report them if (@$errors) { for my $err (@$errors) { $rep .= "ERROR $err\n"; } } else { my $connline = $self->connect_streams(@$streams); $rep .= "$connline\n"; } # rep needs a empty-line terminator, I think $rep .= "\n"; # write the whole rep packet, and close main to signal the end of the packet $self->senddata('main', $rep); $self->close('main', 'w'); } # helper function to get a line, including the trailing '\n', from a stream. This # reads a character at a time to ensure that no extra characters are consumed. This # could certainly be more efficient! (TODO) sub getline { my $self = shift; my ($stream) = @_; my $fd = $self->rfd($stream); my $line = undef; while (1) { my $c; my $a = POSIX::read($fd, $c, 1); last if $a != 1; $line .= $c; last if $c eq "\n"; } if ($line) { my $chopped = $line; $chopped =~ s/[\r\n]*$//g; debug("CTL << $chopped"); } else { debug("CTL << EOF"); } return $line; } # helper function to write a data to a stream. This does not add newline characters. sub senddata { my $self = shift; my ($stream, $data) = @_; my $fd = $self->wfd($stream); Amanda::Util::full_write($fd, $data, length($data)) or die "writing to $stream: $!"; } # send a line on the control stream, or just log it if the ctl stream is gone; # async callback is just like for senddata sub sendctlline { my $self = shift; my ($msg) = @_; if ($self->{'ctl_stream'}) { debug("CTL >> $msg"); return $self->senddata($self->{'ctl_stream'}, $msg . "\n"); } else { debug("not sending CTL message as CTL is closed >> $msg"); } } ## # main driver package main; use Amanda::Debug qw( debug ); use Amanda::Util qw( :constants ); use Amanda::Config qw( :init ); our $exit_status = 0; sub main { Amanda::Util::setup_application("amdumpd", "server", $CONTEXT_DAEMON); config_init(0, undef); Amanda::Debug::debug_dup_stderr_to_debug(); my $cs = main::ClientService->new(); $cs->run(); debug("exiting with $exit_status"); Amanda::Util::finish_application(); } main(); exit($exit_status);
Upload File
Create Folder