#!@PERL@
-# Copyright (c) 2005-2008 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
# 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 Mathlida Ave, Suite 300
+# Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
# Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
use lib '@amperldir@';
use strict;
+use warnings;
use Getopt::Long;
package Amanda::Application::Amzfs_sendrecv;
sub new {
my $class = shift;
- my ($config, $host, $disk, $device, $level, $index, $message, $collection, $record, $df_path, $zfs_path, $pfexec_path, $pfexec, $keep_snapshot) = @_;
- my $self = $class->SUPER::new();
+ my ($config, $host, $disk, $device, $level, $index, $message, $collection, $record, $df_path, $zfs_path, $pfexec_path, $pfexec, $keep_snapshot, $exclude_list, $include_list, $directory) = @_;
+ my $self = $class->SUPER::new($config);
$self->{config} = $config;
$self->{host} = $host;
- $self->{disk} = $disk;
- $self->{device} = $device;
+ if (defined $disk) {
+ $self->{disk} = $disk;
+ } else {
+ $self->{disk} = $device;
+ }
+ if (defined $device) {
+ $self->{device} = $device;
+ } else {
+ $self->{device} = $disk;
+ }
$self->{level} = [ @{$level} ];
$self->{index} = $index;
$self->{message} = $message;
$self->{pfexec} = $pfexec;
$self->{keep_snapshot} = $keep_snapshot;
$self->{pfexec_cmd} = undef;
+ $self->{exclude_list} = [ @{$exclude_list} ];
+ $self->{include_list} = [ @{$include_list} ];
+ $self->{directory} = $directory;
if ($self->{keep_snapshot} =~ /^YES$/i) {
$self->{keep_snapshot} = "YES";
sub check_for_backup_failure {
my $self = shift;
- my $action = shift;
- $self->zfs_destroy_snapshot($action);
+ $self->zfs_destroy_snapshot();
}
sub command_support {
print "MESSAGE-XML NO\n";
print "RECORD YES\n";
print "COLLECTION NO\n";
+ print "CLIENT-ESTIMATE YES\n";
}
sub command_selfcheck {
my $self = shift;
- $self->zfs_set_value("check");
+ $self->zfs_set_value();
+
+ if (!defined $self->{device}) {
+ return;
+ }
+
if ($self->{error_status} == $Amanda::Script_App::GOOD) {
- $self->zfs_create_snapshot("check");
- $self->zfs_destroy_snapshot("check");
+ $self->zfs_create_snapshot();
+ $self->zfs_destroy_snapshot();
print "OK " . $self->{disk} . "\n";
print "OK " . $self->{device} . "\n";
}
+
+ if ($#{$self->{include_list}} >= 0) {
+ $self->print_to_server("include-list not supported for backup",
+ $Amanda::Script_App::ERROR);
+ }
+ if ($#{$self->{exclude_list}} >= 0) {
+ $self->print_to_server("exclude-list not supported for backup",
+ $Amanda::Script_App::ERROR);
+ }
}
sub command_estimate() {
my $self = shift;
-
my $level = 0;
- $self->zfs_set_value("estimate");
- $self->zfs_create_snapshot("estimate");
+ if ($#{$self->{include_list}} >= 0) {
+ $self->print_to_server("include-list not supported for backup",
+ $Amanda::Script_App::ERROR);
+ }
+ if ($#{$self->{exclude_list}} >= 0) {
+ $self->print_to_server("exclude-list not supported for backup",
+ $Amanda::Script_App::ERROR);
+ }
+
+ $self->zfs_set_value();
+ $self->zfs_create_snapshot();
while (defined ($level = shift @{$self->{level}})) {
debug "Estimate of level $level";
output_size($level, $size);
}
- $self->zfs_destroy_snapshot("estimate");
+ $self->zfs_destroy_snapshot();
exit 0;
}
sub command_backup {
my $self = shift;
- my $mesgout_fd;
- open($mesgout_fd, '>&=3') || die();
- $self->{mesgout} = $mesgout_fd;
+ if ($#{$self->{include_list}} >= 0) {
+ $self->print_to_server("include-list not supported for backup",
+ $Amanda::Script_App::ERROR);
+ }
+ if ($#{$self->{exclude_list}} >= 0) {
+ $self->print_to_server("exclude-list not supported for backup",
+ $Amanda::Script_App::ERROR);
+ }
- $self->zfs_set_value("backup");
- $self->zfs_create_snapshot("backup");
+ $self->zfs_set_value();
+ $self->zfs_create_snapshot();
my $size = -1;
my $level = $self->{level}[0];
if ($refsnapshotname ne "") {
$cmd = "$self->{pfexec_cmd} $self->{zfs_path} send -i $refsnapshotname $self->{filesystem}\@$self->{snapshot} | $Amanda::Paths::amlibexecdir/teecount";
} else {
- $self->print_to_server_and_die("sendbackup", "cannot backup snapshot '$self->{filesystem}\@$self->{snapshot}': reference snapshot doesn't exists for level $level", $Amanda::Script_App::ERROR);
+ $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);
}
}
close $err;
if ($? != 0) {
if (defined $errmsg) {
- $self->print_to_server_and_die("sendbackup", $errmsg, $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die($errmsg, $Amanda::Script_App::ERROR);
} else {
- $self->print_to_server_and_die("sendbackup", "cannot backup snapshot '$self->{filesystem}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die("cannot backup snapshot '$self->{filesystem}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
}
}
$size = $errmsg;
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, "backup");
+ $self->zfs_purge_snapshot($level, 9);
if ($self->{keep_snapshot} eq 'YES') {
- $self->zfs_rename_snapshot($level, "backup");
+ $self->zfs_rename_snapshot($level);
} else {
- $self->zfs_destroy_snapshot("backup");
+ $self->zfs_destroy_snapshot();
}
exit 0;
{
my $self = shift;
my $level = shift;
- my $action = shift;
debug "\$filesystem = $self->{filesystem}";
debug "\$snapshot = $self->{snapshot}";
close $err;
if ($? != 0) {
if (defined $msg && defined $errmsg) {
- $self->print_to_server_and_die($action, "$msg, $errmsg", $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die("$msg, $errmsg", $Amanda::Script_App::ERROR);
} elsif (defined $msg) {
- $self->print_to_server_and_die($action, $msg, $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die($msg, $Amanda::Script_App::ERROR);
} elsif (defined $errmsg) {
- $self->print_to_server_and_die($action, $errmsg, $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die($errmsg, $Amanda::Script_App::ERROR);
} else {
- $self->print_to_server_and_die($action, "cannot estimate snapshot '$self->{snapshot}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die("cannot estimate snapshot '$self->{snapshot}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
}
}
+ if ($level == 0) {
+ my $compratio = $self->get_compratio();
+ chop($compratio);
+ $msg *= $compratio;
+ }
return $msg;
}
+sub get_compratio
+{
+ my $self = shift;
+
+ my $cmd;
+ $cmd = "$self->{pfexec_cmd} $self->{zfs_path} get -Hp -o value compressratio $self->{filesystem}\@$self->{snapshot}";
+ debug "running (get-compression): $cmd";
+ my($wtr, $rdr, $err, $pid);
+ $err = Symbol::gensym;
+ $pid = open3($wtr, $rdr, $err, $cmd);
+ close $wtr;
+ my ($msg) = <$rdr>;
+ my ($errmsg) = <$err>;
+ waitpid $pid, 0;
+ close $rdr;
+ close $err;
+ if ($? != 0) {
+ if (defined $msg && defined $errmsg) {
+ $self->print_to_server_and_die("$msg, $errmsg", $Amanda::Script_App::ERROR);
+ } elsif (defined $msg) {
+ $self->print_to_server_and_die($msg, $Amanda::Script_App::ERROR);
+ } elsif (defined $errmsg) {
+ $self->print_to_server_and_die($errmsg, $Amanda::Script_App::ERROR);
+ } else {
+ $self->print_to_server_and_die("cannot read compression ratio '$self->{snapshot}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
+ }
+ }
+ return $msg
+}
+
sub command_index_from_output {
}
sub command_index_from_image {
}
-sub command_restore {
-}
+#sub command_restore {
+# my $self = shift;
+#
+#TODO
+#}
sub command_print_command {
}
my $pfexec_path = 'pfexec';
my $pfexec = "NO";
my $opt_keep_snapshot = "YES";
+my @opt_exclude_list;
+my @opt_include_list;
+my $opt_directory;
Getopt::Long::Configure(qw{bundling});
GetOptions(
'zfs-path=s' => \$zfs_path,
'pfexec-path=s' => \$pfexec_path,
'pfexec=s' => \$pfexec,
- 'keep-snapshot=s' => \$opt_keep_snapshot
+ 'keep-snapshot=s' => \$opt_keep_snapshot,
+ 'exclude-list=s' => \@opt_exclude_list,
+ 'include-list=s' => \@opt_include_list,
+ 'directory=s' => \$opt_directory,
) or usage();
-my $application = Amanda::Application::Amzfs_sendrecv->new($opt_config, $opt_host, $opt_disk, $opt_device, \@opt_level, $opt_index, $opt_message, $opt_collection, $opt_record, $df_path, $zfs_path, $pfexec_path, $pfexec, $opt_keep_snapshot);
+my $application = Amanda::Application::Amzfs_sendrecv->new($opt_config, $opt_host, $opt_disk, $opt_device, \@opt_level, $opt_index, $opt_message, $opt_collection, $opt_record, $df_path, $zfs_path, $pfexec_path, $pfexec, $opt_keep_snapshot, \@opt_exclude_list, \@opt_include_list, $opt_directory);
$application->do($ARGV[0]);