-# Copyright (c) 2005-2008 Zmanda Inc. All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved.
#
-# This library is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License version 2.1 as
-# published by the Free Software Foundation.
+# 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
# 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
-# Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
+# Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
+# Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
package Amanda::Application::Zfs;
sub zfs_set_value {
my $self = shift;
- my $action = $_[0];
-
if (defined $self->{execute_where} && $self->{execute_where} ne "client") {
- $self->print_to_server_and_die($action, " Script must be run on the client 'execute_where client'", $Amanda::Script_App::ERROR);
- }
- if (!defined $self->{device}) {
- $self->print_to_server_and_die($action, "'--device' is not provided",
- $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die(" Script must be run on the client 'execute-where client'", $Amanda::Script_App::ERROR);
}
if ($self->{df_path} ne "df" && !-e $self->{df_path}) {
- $self->print_to_server_and_die($action, "Can't execute DF-PATH '$self->{df_path}' command",
+ $self->print_to_server_and_die("Can't execute DF-PATH '$self->{df_path}' command",
$Amanda::Script_App::ERROR);
}
if ($self->{zfs_path} ne "zfs" && !-e $self->{zfs_path}) {
- $self->print_to_server_and_die($action, "Can't execute ZFS-PATH '$self->{zfs_path}' command",
+ $self->print_to_server_and_die("Can't execute ZFS-PATH '$self->{zfs_path}' command",
$Amanda::Script_App::ERROR);
}
$self->{pfexec_cmd} = $self->{pfexec_path};
}
if (defined $self->{pfexec_cmd} && $self->{pfexec_cmd} ne "pfexec" && !-e $self->{pfexec_cmd}) {
- $self->print_to_server_and_die($action, "Can't execute PFEXEC-PATH '$self->{pfexec_cmd}' command",
+ $self->print_to_server_and_die("Can't execute PFEXEC-PATH '$self->{pfexec_cmd}' command",
$Amanda::Script_App::ERROR);
}
if (!defined $self->{pfexec_cmd}) {
$self->{pfexec_cmd} = "";
}
- # determine if $self->{device} is a mountpoint or ZFS dataset
- my $cmd = "$self->{pfexec_cmd} $self->{zfs_path} get -H -o value mountpoint $self->{device}";
+ if (!defined $self->{device}) {
+ if ($self->{action} eq "check") {
+ return;
+ } else {
+ $self->print_to_server_and_die("'--device' is not provided",
+ $Amanda::Script_App::ERROR);
+ }
+ }
+
+ my $device = $self->{device};
+ $device = $self->{directory} if defined $self->{directory};
+ # determine if $device is a mountpoint or ZFS dataset
+ my $cmd = "$self->{pfexec_cmd} $self->{zfs_path} get -H -o value mountpoint $device";
debug "running: $cmd";
my($wtr, $rdr, $err, $pid);
$err = Symbol::gensym;
chomp $zmountpoint;
# zfs dataset supplied
- $self->{filesystem} = $self->{device};
+ $self->{filesystem} = $device;
# check if zfs volume
if ($zmountpoint ne '-') {
}
} else {
# filesystem, directory or invalid ZFS dataset name
- $cmd = "$self->{df_path} $self->{device}";
- debug "running: $self->{df_path} $self->{device}";
+ $cmd = "$self->{df_path} $device";
+ debug "running: $self->{df_path} $device";
$err = Symbol::gensym;
$pid = open3($wtr, $rdr, $err, $cmd);
close $wtr;
chomp $errmsg;
}
if (defined $ret && defined $errmsg) {
- $self->print_to_server_and_die($action, "$ret, $errmsg", $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die("$ret, $errmsg", $Amanda::Script_App::ERROR);
} elsif (defined $ret) {
- $self->print_to_server_and_die($action, $ret, $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die($ret, $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,
- "Failed to find mount points: $self->{device}",
+ $self->print_to_server_and_die(
+ "Failed to find mount points: $device",
$Amanda::Script_App::ERROR);
}
}
$self->{mountpoint} = $1;
$self->{filesystem} = $4;
} else {
- $self->print_to_server_and_die($action,
- "Failed to find mount points: $self->{device}",
+ $self->print_to_server_and_die(
+ "Failed to find mount points: $device",
$Amanda::Script_App::ERROR);
}
} else {
$self->{mountpoint} = $6;
$self->{filesystem} = $1;
} else {
- $self->print_to_server_and_die($action,
- "Failed to find mount points: $self->{device}",
+ $self->print_to_server_and_die(
+ "Failed to find mount points: $device",
$Amanda::Script_App::ERROR);
}
}
chomp $errmsg;
}
if (defined $zmountpoint && defined $errmsg) {
- $self->print_to_server_and_die($action, $zmountpoint, $errmsg, $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die($zmountpoint, $errmsg, $Amanda::Script_App::ERROR);
} elsif (defined $zmountpoint) {
- $self->print_to_server_and_die($action, $zmountpoint, $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die($zmountpoint, $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,
+ $self->print_to_server_and_die(
"Failed to find mount points: $self->{filesystem}",
$Amanda::Script_App::ERROR);
}
}
if ($zmountpoint ne 'legacy' && $zmountpoint ne $self->{mountpoint}) {
- $self->print_to_server_and_die($action,
+ $self->print_to_server_and_die(
"mountpoint from 'df' ($self->{mountpoint}) and 'zfs list' ($zmountpoint) differ",
$Amanda::Script_App::ERROR);
}
- if (!($self->{device} =~ /^$self->{mountpoint}/)) {
- $self->print_to_server_and_die($action,
- "mountpoint '$self->{mountpoint}' is not a prefix of diskdevice '$self->{device}'",
+ if (!($device =~ /^$self->{mountpoint}/)) {
+ $self->print_to_server_and_die(
+ "mountpoint '$self->{mountpoint}' is not a prefix of the device '$device'",
$Amanda::Script_App::ERROR);
}
}
- if ($action eq 'check') {
- $self->{snapshot} = $self->zfs_build_snapshotname($self->{device}, -1);
- } else {
- $self->{snapshot} = $self->zfs_build_snapshotname($self->{device});
- }
+ $self->{snapshot} = $self->zfs_build_snapshotname($device);
if (defined $self->{mountpoint}) {
- if ($self->{device} =~ /^$self->{mountpoint}/) {
- $self->{dir} = $self->{device};
+ if ($device =~ /^$self->{mountpoint}/) {
+ $self->{dir} = $device;
$self->{dir} =~ s,^$self->{mountpoint},,;
$self->{directory} = $self->{mountpoint} . "/.zfs/snapshot/" .
$self->{snapshot} . $self->{dir};
sub zfs_create_snapshot {
my $self = shift;
- my $action = shift;
my $cmd = "$self->{pfexec_cmd} $self->{zfs_path} snapshot $self->{filesystem}\@$self->{snapshot}";
debug "running: $cmd";
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 create snapshot '$self->{filesystem}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die("cannot create snapshot '$self->{filesystem}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
}
}
}
sub zfs_destroy_snapshot {
my $self = shift;
- my $action = shift;
my $cmd = "$self->{pfexec_cmd} $self->{zfs_path} destroy $self->{filesystem}\@$self->{snapshot}";
debug "running: $cmd|";
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 destroy snapshot '$self->{filesystem}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die("cannot destroy snapshot '$self->{filesystem}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
}
}
}
sub zfs_destroy_snapshot_level {
my $self = shift;
my $level = shift;
- my $action = shift;
my $snapshotname = $self->zfs_find_snapshot_level($level);
debug "zfs_destroy_snapshot_level: Current $snapshotname";
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 destroy snapshot '$self->{filesystem}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die("cannot destroy snapshot '$self->{filesystem}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
}
}
}
sub zfs_rename_snapshot {
my $self = shift;
my $level = shift;
- my $action = shift;
- my $newsnapshotname = $self->zfs_build_snapshotname($self->{device}, $level);
- my $cmd = "$self->{pfexec_cmd} $self->{zfs_path} rename $self->{filesystem}\@$self->{snapshot} $newsnapshotname";
+ my $device = $self->{device};
+ $device = $self->{directory} if defined $self->{directory};
+ my $newsnapshotname = $self->zfs_build_snapshotname($device, $level);
+ my $cmd = "$self->{pfexec_cmd} $self->{zfs_path} rename $self->{filesystem}\@$self->{snapshot} $self->{filesystem}\@$newsnapshotname";
debug "running: $cmd|";
my($wtr, $rdr, $err, $pid);
my($msg, $errmsg);
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 rename snapshot '$self->{filesystem}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
+ $self->print_to_server_and_die("cannot rename snapshot '$self->{filesystem}\@$self->{snapshot}': unknown reason", $Amanda::Script_App::ERROR);
}
}
}
my $self = shift;
my $minlevel = shift;
my $maxlevel = shift;
- my $action = shift;
my $level;
for ($level = $maxlevel; $level >= $minlevel; $level--) {
debug "zfs_purge_snapshot: Check for existing snapshot at level $level";
- $self->zfs_destroy_snapshot_level($level, $action);
+ $self->zfs_destroy_snapshot_level($level);
}
}
sub zfs_find_snapshot_level {
my $self = shift;
my $level = shift;
- my $action = shift;
- my $snapshotname = $self->zfs_build_snapshotname($self->{device}, $level);
+ my $device = $self->{device};
+ $device = $self->{directory} if defined $self->{directory};
+ my $snapshotname = $self->zfs_build_snapshotname($device, $level);
my $cmd = "$self->{pfexec_cmd} $self->{zfs_path} list -t snapshot $self->{filesystem}\@$snapshotname";
debug "running: $cmd|";
my $self = shift;
my $device = shift;
my $level = shift;
- my $action = shift;
my $snapshotname = "";
- if (!defined $level) {
- $snapshotname = "amanda-" . Amanda::Util::sanitise_filename($device) . "-current";
+ if ($self->{action} eq 'check') {
+ $snapshotname = "amanda-" . Amanda::Util::sanitise_filename($self->{disk}) . "-check";
+ } elsif (!defined $level) {
+ $snapshotname = "amanda-" . Amanda::Util::sanitise_filename($self->{disk}) . "-current";
} else {
- if ($level < 0) {
- $snapshotname = "amanda-" . Amanda::Util::sanitise_filename($device) . "-check";
- } else {
- $snapshotname = "amanda-" . Amanda::Util::sanitise_filename($device) . "-" . $level;
- }
- }
+ $snapshotname = "amanda-" . Amanda::Util::sanitise_filename($self->{disk}) . "-" . $level;
+ }
return $snapshotname;
}