Imported Upstream version 3.1.0
[debian/amanda] / application-src / amzfs-sendrecv.pl
index 628f3aff96a7e9b5d876f32da678cb298cb41461..63bb0bcc073f727fecd0664687ccb382e3e97de5 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@
-# Copyright (c) 2005-2008 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2008,2009 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
@@ -14,7 +14,7 @@
 # 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@';
@@ -36,13 +36,21 @@ use Amanda::Util qw( :constants );
 
 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;
@@ -54,6 +62,9 @@ sub new {
     $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";
@@ -67,9 +78,8 @@ sub new {
 
 sub check_for_backup_failure {
    my $self = shift;
-   my $action = shift;
 
-   $self->zfs_destroy_snapshot($action);
+   $self->zfs_destroy_snapshot();
 }
 
 sub command_support {
@@ -85,27 +95,50 @@ 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";
@@ -113,7 +146,7 @@ sub command_estimate() {
       output_size($level, $size);
     }
 
-    $self->zfs_destroy_snapshot("estimate");
+    $self->zfs_destroy_snapshot();
 
     exit 0;
 }
@@ -136,11 +169,22 @@ sub command_backup {
     my $self = shift;
 
     my $mesgout_fd;
-    open($mesgout_fd, '>&=3') || die();
+    open($mesgout_fd, '>&=3') ||
+       $self->print_to_server_and_die("Can't open mesgout_fd: $!",
+                                      $Amanda::Script_App::ERROR);
     $self->{mesgout} = $mesgout_fd;
 
-    $self->zfs_set_value("backup");
-    $self->zfs_create_snapshot("backup");
+    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();
 
     my $size = -1;
     my $level = $self->{level}[0];
@@ -154,7 +198,7 @@ sub command_backup {
       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);
       }
     }
 
@@ -169,9 +213,9 @@ sub command_backup {
     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;
@@ -184,12 +228,12 @@ sub command_backup {
     print $mesgout_fd "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;
@@ -199,7 +243,6 @@ sub estimate_snapshot
 {
     my $self = shift;
     my $level = shift;
-    my $action = shift;
 
     debug "\$filesystem = $self->{filesystem}";
     debug "\$snapshot = $self->{snapshot}";
@@ -229,27 +272,65 @@ sub estimate_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 {
 }
@@ -277,6 +358,9 @@ my $zfs_path = 'zfs';
 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(
@@ -293,10 +377,13 @@ 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]);