X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=application-src%2Famzfs-sendrecv.pl;h=1bbbb9c97a2621bdb67b32ee230af3fda5da85d4;hb=ca9fbb570498b74f4c6adaebd629bff20f146a14;hp=63bb0bcc073f727fecd0664687ccb382e3e97de5;hpb=fd48f3e498442f0cbff5f3606c7c403d0566150e;p=debian%2Famanda diff --git a/application-src/amzfs-sendrecv.pl b/application-src/amzfs-sendrecv.pl index 63bb0bc..1bbbb9c 100644 --- a/application-src/amzfs-sendrecv.pl +++ b/application-src/amzfs-sendrecv.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008, 2009, 2010 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 @@ -19,6 +19,7 @@ use lib '@amperldir@'; use strict; +use warnings; use Getopt::Long; package Amanda::Application::Amzfs_sendrecv; @@ -32,7 +33,7 @@ use Amanda::Constants; use Amanda::Config qw( :init :getconf config_dir_relative ); use Amanda::Debug qw( :logging ); use Amanda::Paths; -use Amanda::Util qw( :constants ); +use Amanda::Util qw( :constants quote_string ); sub new { my $class = shift; @@ -89,7 +90,7 @@ sub command_support { print "HOST YES\n"; print "DISK YES\n"; print "MAX-LEVEL 9\n"; - print "INDEX-LINE NO\n"; + print "INDEX-LINE YES\n"; print "INDEX-XML NO\n"; print "MESSAGE-LINE YES\n"; print "MESSAGE-XML NO\n"; @@ -101,6 +102,10 @@ sub command_support { sub command_selfcheck { my $self = shift; + $self->print_to_server("disk " . quote_string($self->{disk})); + + $self->print_to_server("amzfs-sendrecv version " . $Amanda::Constants::VERSION, + $Amanda::Script_App::GOOD); $self->zfs_set_value(); if (!defined $self->{device}) { @@ -110,7 +115,6 @@ sub command_selfcheck { if ($self->{error_status} == $Amanda::Script_App::GOOD) { $self->zfs_create_snapshot(); $self->zfs_destroy_snapshot(); - print "OK " . $self->{disk} . "\n"; print "OK " . $self->{device} . "\n"; } @@ -168,12 +172,6 @@ sub output_size { sub command_backup { my $self = shift; - my $mesgout_fd; - open($mesgout_fd, '>&=3') || - $self->print_to_server_and_die("Can't open mesgout_fd: $!", - $Amanda::Script_App::ERROR); - $self->{mesgout} = $mesgout_fd; - if ($#{$self->{include_list}} >= 0) { $self->print_to_server("include-list not supported for backup", $Amanda::Script_App::ERROR); @@ -196,7 +194,7 @@ sub command_backup { my $refsnapshotname = $self->zfs_find_snapshot_level($level-1); debug "Referenced snapshot name: $refsnapshotname|"; if ($refsnapshotname ne "") { - $cmd = "$self->{pfexec_cmd} $self->{zfs_path} send -i $refsnapshotname $self->{filesystem}\@$self->{snapshot} | $Amanda::Paths::amlibexecdir/teecount"; + $cmd = "$self->{pfexec_cmd} $self->{zfs_path} send -i $self->{filesystem}\@$refsnapshotname $self->{filesystem}\@$self->{snapshot} | $Amanda::Paths::amlibexecdir/teecount"; } else { $self->print_to_server_and_die("cannot backup snapshot '$self->{filesystem}\@$self->{snapshot}': reference snapshot doesn't exists for level $level", $Amanda::Script_App::ERROR); } @@ -208,6 +206,16 @@ sub command_backup { $err = Symbol::gensym; $pid = open3($wtr, '>&STDOUT', $err, $cmd); close $wtr; + + if (defined($self->{index})) { + my $indexout; + open($indexout, '>&=4') || + $self->print_to_server_and_die("Can't open indexout: $!", + $Amanda::Script_App::ERROR); + print $indexout "/\n"; + close($indexout); + } + $errmsg = <$err>; waitpid $pid, 0; close $err; @@ -224,8 +232,8 @@ sub command_backup { my($ksize) = int ($size/1024); $ksize=32 if ($ksize<32); - print $mesgout_fd "sendbackup: size $ksize\n"; - print $mesgout_fd "sendbackup: end\n"; + print {$self->{mesgout}} "sendbackup: size $ksize\n"; + print {$self->{mesgout}} "sendbackup: end\n"; # destroy all snapshot of this level and higher $self->zfs_purge_snapshot($level, 9); @@ -326,11 +334,105 @@ sub command_index_from_output { sub command_index_from_image { } -#sub command_restore { -# my $self = shift; -# -#TODO -#} +sub command_restore { + my $self = shift; + + my $current_snapshot; + my $level = $self->{level}[0]; + my $device = $self->{device}; + if (defined $device) { + $device =~ s,^/,,; + $current_snapshot = $self->zfs_build_snapshotname($device); + $self->{'snapshot'} = $self->zfs_build_snapshotname($device, $level); + } + + my $directory = $device; + $directory = $self->{directory} if defined $self->{directory}; + $directory =~ s,^/,,; + + my @cmd = (); + + if ($self->{pfexec_cmd}) { + push @cmd, $self->{pfexec_cmd}; + } + push @cmd, $self->{zfs_path}; + push @cmd, "recv"; + push @cmd, $directory; + + debug("cmd:" . join(" ", @cmd)); + system @cmd; + + my $snapshotname; + my $newsnapname; + if (defined $device) { + $snapshotname = "$directory\@$current_snapshot"; + $newsnapname = "$directory\@$self->{'snapshot'}"; + } else { + # find snapshot name + @cmd = (); + if ($self->{pfexec_cmd}) { + push @cmd, $self->{pfexec_cmd}; + } + push @cmd, $self->{zfs_path}; + push @cmd, "list"; + push @cmd, "-r"; + push @cmd, "-t"; + push @cmd, "snapshot"; + push @cmd, $directory; + debug("cmd:" . join(" ", @cmd)); + + my($wtr, $rdr, $err, $pid); + my($msg, $errmsg); + $err = Symbol::gensym; + $pid = open3($wtr, $rdr, $err, @cmd); + close $wtr; + while ($msg = <$rdr>) { + next if $msg =~ /^NAME/; + my ($name, $used, $avail) = split(/ +/, $msg); + if ($name =~ /-current$/) { + $snapshotname = $name; + last; + } + } + $errmsg = <$err>; + waitpid $pid, 0; + close $rdr; + close $err; + + if (defined $snapshotname and defined($level)) { + $newsnapname = $snapshotname; + $newsnapname =~ s/current$/$level/; + } else { + # destroy the snapshot + # restoring next level will fail. + @cmd = (); + if ($self->{pfexec_cmd}) { + push @cmd, $self->{pfexec_cmd}; + } + push @cmd, $self->{zfs_path}; + push @cmd, "destroy"; + push @cmd, $snapshotname; + + debug("cmd:" . join(" ", @cmd)); + system @cmd; + } + } + + if (defined $newsnapname) { + # rename -current snapshot to -level + @cmd = (); + if ($self->{pfexec_cmd}) { + push @cmd, $self->{pfexec_cmd}; + } + push @cmd, $self->{zfs_path}; + push @cmd, "rename"; + push @cmd, $snapshotname; + push @cmd, $newsnapname; + + debug("cmd:" . join(" ", @cmd)); + system @cmd; + } +} sub command_print_command { }