[pve-devel] [PATCH 1/1] Use ssh key stored in pmxcfg. Use ssh -i /etc/pve/priv/zfs/portal_id_rsa for remote commands
mir at datanom.net
mir at datanom.net
Wed Oct 23 02:53:08 CEST 2013
From: Michael Rasmussen <mir at datanom.net>
Signed-off-by: Michael Rasmussen <mir at datanom.net>
---
PVE/Storage/LunCmd/Comstar.pm | 141 +++----
PVE/Storage/LunCmd/Iet.pm | 7 +-
PVE/Storage/LunCmd/Istgt.pm | 861 +++++++++++++++++++++---------------------
PVE/Storage/ZFSPlugin.pm | 335 ++++++++--------
4 files changed, 674 insertions(+), 670 deletions(-)
diff --git a/PVE/Storage/LunCmd/Comstar.pm b/PVE/Storage/LunCmd/Comstar.pm
index 8c01d55..45ad6a5 100644
--- a/PVE/Storage/LunCmd/Comstar.pm
+++ b/PVE/Storage/LunCmd/Comstar.pm
@@ -8,94 +8,95 @@ use Data::Dumper;
my @ssh_opts = ('-o', 'BatchMode=yes');
my @ssh_cmd = ('/usr/bin/ssh', @ssh_opts);
+my $id_rsa_path = '/etc/pve/priv/zfs';
my $get_lun_cmd_map = sub {
- my ($method) = @_;
-
- my $stmfadmcmd = "/usr/sbin/stmfadm";
- my $sbdadmcmd = "/usr/sbin/sbdadm";
-
- my $cmdmap = {
- create_lu => { cmd => $stmfadmcmd, method => 'create-lu' },
- delete_lu => { cmd => $stmfadmcmd, method => 'delete-lu' },
- import_lu => { cmd => $stmfadmcmd, method => 'import-lu' },
- modify_lu => { cmd => $stmfadmcmd, method => 'modify-lu' },
- add_view => { cmd => $stmfadmcmd, method => 'add-view' },
- list_view => { cmd => $stmfadmcmd, method => 'list-view' },
- list_lu => { cmd => $sbdadmcmd, method => 'list-lu' },
- };
-
- die "unknown command '$method'" unless exists $cmdmap->{$method};
-
- return $cmdmap->{$method};
+ my ($method) = @_;
+
+ my $stmfadmcmd = "/usr/sbin/stmfadm";
+ my $sbdadmcmd = "/usr/sbin/sbdadm";
+
+ my $cmdmap = {
+ create_lu => { cmd => $stmfadmcmd, method => 'create-lu' },
+ delete_lu => { cmd => $stmfadmcmd, method => 'delete-lu' },
+ import_lu => { cmd => $stmfadmcmd, method => 'import-lu' },
+ modify_lu => { cmd => $stmfadmcmd, method => 'modify-lu' },
+ add_view => { cmd => $stmfadmcmd, method => 'add-view' },
+ list_view => { cmd => $stmfadmcmd, method => 'list-view' },
+ list_lu => { cmd => $sbdadmcmd, method => 'list-lu' },
+ };
+
+ die "unknown command '$method'" unless exists $cmdmap->{$method};
+
+ return $cmdmap->{$method};
};
sub get_base {
- return '/dev/zvol/rdsk';
+ return '/dev/zvol/rdsk';
}
sub run_lun_command {
- my ($scfg, $timeout, $method, @params) = @_;
+ my ($scfg, $timeout, $method, @params) = @_;
my $msg = '';
my $luncmd;
my $target;
my $guid;
$timeout = 10 if !$timeout;
-
+
my $output = sub {
my $line = shift;
- $msg .= "$line\n";
+ $msg .= "$line\n";
};
- if ($method eq 'create_lu') {
- my $prefix = '600144f';
- my $digest = md5_hex($params[0]);
- $digest =~ /(\w{7}(.*))/;
- $guid = "$prefix$2";
- @params = ('-p', 'wcd=false', '-p', "guid=$guid", @params);
- } elsif ($method eq 'modify_lu') {
- @params = ('-s', @params);
- } elsif ($method eq 'list_view') {
- @params = ('-l', @params);
- } elsif ($method eq 'list_lu') {
- $guid = $params[0];
- @params = undef;
- }
-
- my $cmdmap = $get_lun_cmd_map->($method);
- $luncmd = $cmdmap->{cmd};
- my $lunmethod = $cmdmap->{method};
-
- $target = 'root@' . $scfg->{portal};
-
- my $cmd = [@ssh_cmd, $target, $luncmd, $lunmethod, @params];
-
- run_command($cmd, outfunc => $output, timeout => $timeout);
-
- if ($method eq 'list_view') {
- my @lines = split /\n/, $msg;
- $msg = undef;
- foreach my $line (@lines) {
- if ($line =~ /^\s*LUN\s*:\s*(\d+)$/) {
- $msg = $1;
- last;
- }
- }
+ if ($method eq 'create_lu') {
+ my $prefix = '600144f';
+ my $digest = md5_hex($params[0]);
+ $digest =~ /(\w{7}(.*))/;
+ $guid = "$prefix$2";
+ @params = ('-p', 'wcd=false', '-p', "guid=$guid", @params);
+ } elsif ($method eq 'modify_lu') {
+ @params = ('-s', @params);
+ } elsif ($method eq 'list_view') {
+ @params = ('-l', @params);
} elsif ($method eq 'list_lu') {
- my $object = $guid;
- my @lines = split /\n/, $msg;
- $msg = undef;
- foreach my $line (@lines) {
- if ($line =~ /(\w+)\s+\d+\s+$object$/) {
- $msg = $1;
- last;
- }
- }
- } elsif ($method eq 'create_lu') {
- $msg = $guid;
- }
-
- return $msg;
+ $guid = $params[0];
+ @params = undef;
+ }
+
+ my $cmdmap = $get_lun_cmd_map->($method);
+ $luncmd = $cmdmap->{cmd};
+ my $lunmethod = $cmdmap->{method};
+
+ $target = 'root@' . $scfg->{portal};
+
+ my $cmd = [@ssh_cmd, '-i', "$id_rsa_path/$scfg->{portal}_id_rsa", $target, $luncmd, $lunmethod, @params];
+
+ run_command($cmd, outfunc => $output, timeout => $timeout);
+
+ if ($method eq 'list_view') {
+ my @lines = split /\n/, $msg;
+ $msg = undef;
+ foreach my $line (@lines) {
+ if ($line =~ /^\s*LUN\s*:\s*(\d+)$/) {
+ $msg = $1;
+ last;
+ }
+ }
+ } elsif ($method eq 'list_lu') {
+ my $object = $guid;
+ my @lines = split /\n/, $msg;
+ $msg = undef;
+ foreach my $line (@lines) {
+ if ($line =~ /(\w+)\s+\d+\s+$object$/) {
+ $msg = $1;
+ last;
+ }
+ }
+ } elsif ($method eq 'create_lu') {
+ $msg = $guid;
+ }
+
+ return $msg;
}
diff --git a/PVE/Storage/LunCmd/Iet.pm b/PVE/Storage/LunCmd/Iet.pm
index e378b9f..98c062b 100644
--- a/PVE/Storage/LunCmd/Iet.pm
+++ b/PVE/Storage/LunCmd/Iet.pm
@@ -33,6 +33,7 @@ my $OLD_CONFIG = undef;
my @ssh_opts = ('-o', 'BatchMode=yes');
my @ssh_cmd = ('/usr/bin/ssh', @ssh_opts);
my @scp_cmd = ('/usr/bin/scp', @ssh_opts);
+my $id_rsa_path = '/etc/pve/priv/zfs';
my $ietadm = '/usr/sbin/ietadm';
my $execute_command = sub {
@@ -59,9 +60,9 @@ my $execute_command = sub {
$target = 'root@' . $scfg->{portal};
if ($exec eq 'scp') {
- $cmd = [@scp_cmd, $method, "$target:$params[0]"];
+ $cmd = [@scp_cmd, '-i', "$id_rsa_path/$scfg->{portal}_id_rsa", $method, "$target:$params[0]"];
} else {
- $cmd = [@ssh_cmd, $target, $method, @params];
+ $cmd = [@ssh_cmd, '-i', "$id_rsa_path/$scfg->{portal}_id_rsa", $target, $method, @params];
}
eval {
@@ -103,7 +104,7 @@ my $read_config = sub {
$target = 'root@' . $scfg->{portal};
- my $cmd = [@ssh_cmd, $target, $luncmd, $CONFIG_FILE];
+ my $cmd = [@ssh_cmd, '-i', "$id_rsa_path/$scfg->{portal}_id_rsa", $target, $luncmd, $CONFIG_FILE];
eval {
run_command($cmd, outfunc => $output, errfunc => $errfunc, timeout => $timeout);
};
diff --git a/PVE/Storage/LunCmd/Istgt.pm b/PVE/Storage/LunCmd/Istgt.pm
index 5c05a3d..9bbdfa0 100644
--- a/PVE/Storage/LunCmd/Istgt.pm
+++ b/PVE/Storage/LunCmd/Istgt.pm
@@ -10,12 +10,12 @@ use PVE::Tools qw(run_command file_read_firstline trim dir_glob_regex dir_glob_f
use Data::Dumper;
my @CONFIG_FILES = (
- '/usr/local/etc/istgt/istgt.conf', # FreeBSD, FreeNAS
- '/var/etc/iscsi/istgt.conf' # NAS4Free
+ '/usr/local/etc/istgt/istgt.conf', # FreeBSD, FreeNAS
+ '/var/etc/iscsi/istgt.conf' # NAS4Free
);
my @DAEMONS = (
- '/usr/local/etc/rc.d/istgt', # FreeBSD, FreeNAS
- '/var/etc/rc.d/istgt' # NAS4Free
+ '/usr/local/etc/rc.d/istgt', # FreeBSD, FreeNAS
+ '/var/etc/rc.d/istgt' # NAS4Free
);
# A logical unit can max have 63 LUNs
@@ -31,6 +31,7 @@ my $OLD_CONFIG = undef;
my @ssh_opts = ('-o', 'BatchMode=yes');
my @ssh_cmd = ('/usr/bin/ssh', @ssh_opts);
my @scp_cmd = ('/usr/bin/scp', @ssh_opts);
+my $id_rsa_path = '/etc/pve/priv/zfs';
#Current SIGHUP reload limitations (http://www.peach.ne.jp/archives/istgt/):
#
@@ -38,7 +39,7 @@ my @scp_cmd = ('/usr/bin/scp', @ssh_opts);
# LU connected by the initiator can't be reloaded by SIGHUP.
# PG and IG mapped to LU can't be deleted by SIGHUP.
# If you delete an active LU, all connections of the LU are closed by SIGHUP.
-# Updating IG is not affected until the next login.
+# Updating IG is not affected until the next login.
#
# FreeBSD
# 1. Alt-F2 to change to native shell (zfsguru)
@@ -59,57 +60,57 @@ sub get_base;
sub run_lun_command;
my $read_config = sub {
- my ($scfg, $timeout, $method) = @_;
-
+ my ($scfg, $timeout, $method) = @_;
+
my $msg = '';
- my $err = undef;
+ my $err = undef;
my $luncmd = 'cat';
my $target;
$timeout = 10 if !$timeout;
-
+
my $output = sub {
my $line = shift;
- $msg .= "$line\n";
+ $msg .= "$line\n";
};
-
- my $errfunc = sub {
+
+ my $errfunc = sub {
my $line = shift;
- $err .= "$line";
- };
-
- $target = 'root@' . $scfg->{portal};
-
- my $daemon = 0;
- foreach my $config (@CONFIG_FILES) {
- $err = undef;
- my $cmd = [@ssh_cmd, $target, $luncmd, $config];
- eval {
- run_command($cmd, outfunc => $output, errfunc => $errfunc, timeout => $timeout);
- };
- do {
- $err = undef;
- $DAEMON = $DAEMONS[$daemon];
- $CONFIG_FILE = $config;
- last;
- } unless $@;
- $daemon++;
- }
- die $err if ($err && $err !~ /No such file or directory/);
- die "No configuration found. Install istgt on $scfg->{portal}" if $msg eq '';
-
- return $msg;
+ $err .= "$line";
+ };
+
+ $target = 'root@' . $scfg->{portal};
+
+ my $daemon = 0;
+ foreach my $config (@CONFIG_FILES) {
+ $err = undef;
+ my $cmd = [@ssh_cmd, '-i', "$id_rsa_path/$scfg->{portal}_id_rsa", $target, $luncmd, $config];
+ eval {
+ run_command($cmd, outfunc => $output, errfunc => $errfunc, timeout => $timeout);
+ };
+ do {
+ $err = undef;
+ $DAEMON = $DAEMONS[$daemon];
+ $CONFIG_FILE = $config;
+ last;
+ } unless $@;
+ $daemon++;
+ }
+ die $err if ($err && $err !~ /No such file or directory/);
+ die "No configuration found. Install istgt on $scfg->{portal}" if $msg eq '';
+
+ return $msg;
};
my $get_config = sub {
- my ($scfg) = @_;
- my @conf = undef;
-
- my $config = $read_config->($scfg, undef, 'get_config');
- die "Missing config file" unless $config;
+ my ($scfg) = @_;
+ my @conf = undef;
- $OLD_CONFIG = $config;
+ my $config = $read_config->($scfg, undef, 'get_config');
+ die "Missing config file" unless $config;
- return $config;
+ $OLD_CONFIG = $config;
+
+ return $config;
};
my $parse_size = sub {
@@ -118,25 +119,25 @@ my $parse_size = sub {
return 0 if !$text;
if ($text =~ m/^(\d+(\.\d+)?)([TGMK]B)?$/) {
- my ($size, $reminder, $unit) = ($1, $2, $3);
- return $size if !$unit;
- if ($unit eq 'KB') {
- $size *= 1024;
- } elsif ($unit eq 'MB') {
- $size *= 1024*1024;
- } elsif ($unit eq 'GB') {
- $size *= 1024*1024*1024;
- } elsif ($unit eq 'TB') {
- $size *= 1024*1024*1024*1024;
- }
- if ($reminder) {
- $size = ceil($size);
- }
- return $size;
+ my ($size, $reminder, $unit) = ($1, $2, $3);
+ return $size if !$unit;
+ if ($unit eq 'KB') {
+ $size *= 1024;
+ } elsif ($unit eq 'MB') {
+ $size *= 1024*1024;
+ } elsif ($unit eq 'GB') {
+ $size *= 1024*1024*1024;
+ } elsif ($unit eq 'TB') {
+ $size *= 1024*1024*1024*1024;
+ }
+ if ($reminder) {
+ $size = ceil($size);
+ }
+ return $size;
} elsif ($text =~ /^auto$/i) {
- return 'AUTO';
- } else {
- return 0;
+ return 'AUTO';
+ } else {
+ return 0;
}
};
@@ -145,435 +146,435 @@ my $size_with_unit = sub {
return '0KB' if !$size;
- return $size if $size eq 'AUTO';
-
+ return $size if $size eq 'AUTO';
+
if ($size =~ m/^\d+$/) {
- ++$n and $size /= 1024 until $size < 1024;
- if ($size =~ /\./) {
- return sprintf "%.2f%s", $size, ( qw[bytes KB MB GB TB] )[ $n ];
- } else {
- return sprintf "%d%s", $size, ( qw[bytes KB MB GB TB] )[ $n ];
- }
- }
- die "$size: Not a number";
+ ++$n and $size /= 1024 until $size < 1024;
+ if ($size =~ /\./) {
+ return sprintf "%.2f%s", $size, ( qw[bytes KB MB GB TB] )[ $n ];
+ } else {
+ return sprintf "%d%s", $size, ( qw[bytes KB MB GB TB] )[ $n ];
+ }
+ }
+ die "$size: Not a number";
};
my $lun_dumper = sub {
- my ($lun) = @_;
- my $config = '';
-
- $config .= "\n[$lun]\n";
- $config .= 'TargetName ' . $SETTINGS->{$lun}->{TargetName} . "\n";
- $config .= 'Mapping ' . $SETTINGS->{$lun}->{Mapping} . "\n";
- $config .= 'AuthGroup ' . $SETTINGS->{$lun}->{AuthGroup} . "\n";
- $config .= 'UnitType ' . $SETTINGS->{$lun}->{UnitType} . "\n";
- $config .= 'QueueDepth ' . $SETTINGS->{$lun}->{QueueDepth} . "\n";
-
- foreach my $conf (@{$SETTINGS->{$lun}->{luns}}) {
- $config .= "$conf->{lun} Storage " . $conf->{Storage};
- $config .= ' ' . $size_with_unit->($conf->{Size}) . "\n";
- }
- $config .= "\n";
-
- return $config;
+ my ($lun) = @_;
+ my $config = '';
+
+ $config .= "\n[$lun]\n";
+ $config .= 'TargetName ' . $SETTINGS->{$lun}->{TargetName} . "\n";
+ $config .= 'Mapping ' . $SETTINGS->{$lun}->{Mapping} . "\n";
+ $config .= 'AuthGroup ' . $SETTINGS->{$lun}->{AuthGroup} . "\n";
+ $config .= 'UnitType ' . $SETTINGS->{$lun}->{UnitType} . "\n";
+ $config .= 'QueueDepth ' . $SETTINGS->{$lun}->{QueueDepth} . "\n";
+
+ foreach my $conf (@{$SETTINGS->{$lun}->{luns}}) {
+ $config .= "$conf->{lun} Storage " . $conf->{Storage};
+ $config .= ' ' . $size_with_unit->($conf->{Size}) . "\n";
+ }
+ $config .= "\n";
+
+ return $config;
};
my $get_lu_name = sub {
- my ($target) = @_;
- my $used = ();
- my $i;
-
- if (! exists $SETTINGS->{$target}->{used}) {
- for ($i = 0; $i < $MAX_LUNS; $i++) {
- $used->{$i} = 0;
- }
- foreach my $lun (@{$SETTINGS->{$target}->{luns}}) {
- $lun->{lun} =~ /^LUN(\d+)$/;
- $used->{$1} = 1;
- }
- $SETTINGS->{$target}->{used} = $used;
- }
-
- $used = $SETTINGS->{$target}->{used};
- for ($i = 0; $i < $MAX_LUNS; $i++) {
- last unless $used->{$i};
- }
- $SETTINGS->{$target}->{used}->{$i} = 1;
-
- return "LUN$i";
+ my ($target) = @_;
+ my $used = ();
+ my $i;
+
+ if (! exists $SETTINGS->{$target}->{used}) {
+ for ($i = 0; $i < $MAX_LUNS; $i++) {
+ $used->{$i} = 0;
+ }
+ foreach my $lun (@{$SETTINGS->{$target}->{luns}}) {
+ $lun->{lun} =~ /^LUN(\d+)$/;
+ $used->{$1} = 1;
+ }
+ $SETTINGS->{$target}->{used} = $used;
+ }
+
+ $used = $SETTINGS->{$target}->{used};
+ for ($i = 0; $i < $MAX_LUNS; $i++) {
+ last unless $used->{$i};
+ }
+ $SETTINGS->{$target}->{used}->{$i} = 1;
+
+ return "LUN$i";
};
my $init_lu_name = sub {
- my ($target) = @_;
- my $used = ();
-
- if (! exists($SETTINGS->{$target}->{used})) {
- for (my $i = 0; $i < $MAX_LUNS; $i++) {
- $used->{$i} = 0;
- }
- $SETTINGS->{$target}->{used} = $used;
- }
- foreach my $lun (@{$SETTINGS->{$target}->{luns}}) {
- $lun->{lun} =~ /^LUN(\d+)$/;
- $SETTINGS->{$target}->{used}->{$1} = 1;
- }
+ my ($target) = @_;
+ my $used = ();
+
+ if (! exists($SETTINGS->{$target}->{used})) {
+ for (my $i = 0; $i < $MAX_LUNS; $i++) {
+ $used->{$i} = 0;
+ }
+ $SETTINGS->{$target}->{used} = $used;
+ }
+ foreach my $lun (@{$SETTINGS->{$target}->{luns}}) {
+ $lun->{lun} =~ /^LUN(\d+)$/;
+ $SETTINGS->{$target}->{used}->{$1} = 1;
+ }
};
my $free_lu_name = sub {
- my ($target, $lu_name) = @_;
+ my ($target, $lu_name) = @_;
- $lu_name =~ /^LUN(\d+)$/;
- $SETTINGS->{$target}->{used}->{$1} = 0;
+ $lu_name =~ /^LUN(\d+)$/;
+ $SETTINGS->{$target}->{used}->{$1} = 0;
};
my $make_lun = sub {
- my ($path) = @_;
-
- my $target = $SETTINGS->{current};
- die 'Maximum number of LUNs per target is 63' if scalar @{$SETTINGS->{$target}->{luns}} >= $MAX_LUNS;
-
- my $lun = $get_lu_name->($target);
- my $conf = {
- lun => $lun,
- Storage => $path,
- Size => 'AUTO',
- };
- push @{$SETTINGS->{$target}->{luns}}, $conf;
-
- return $conf->{lun};
+ my ($path) = @_;
+
+ my $target = $SETTINGS->{current};
+ die 'Maximum number of LUNs per target is 63' if scalar @{$SETTINGS->{$target}->{luns}} >= $MAX_LUNS;
+
+ my $lun = $get_lu_name->($target);
+ my $conf = {
+ lun => $lun,
+ Storage => $path,
+ Size => 'AUTO',
+ };
+ push @{$SETTINGS->{$target}->{luns}}, $conf;
+
+ return $conf->{lun};
};
my $parser = sub {
- my ($scfg) = @_;
-
- my $lun = undef;
- my $line = 0;
-
- my $config = $get_config->($scfg);
- my @cfgfile = split "\n", $config;
-
- foreach (@cfgfile) {
- $line++;
- if ($_ =~ /^\s*\[(PortalGroup\d+)\]\s*/) {
- $lun = undef;
- $SETTINGS->{$1} = ();
- } elsif ($_ =~ /^\s*\[(InitiatorGroup\d+)\]\s*/) {
- $lun = undef;
- $SETTINGS->{$1} = ();
- } elsif ($_ =~ /^\s*PidFile\s+"?([\w\/\.]+)"?\s*/) {
- $lun = undef;
- $SETTINGS->{pidfile} = $1;
- } elsif ($_ =~ /^\s*NodeBase\s+"?([\w\-\.]+)"?\s*/) {
- $lun = undef;
- $SETTINGS->{nodebase} = $1;
- } elsif ($_ =~ /^\s*\[(LogicalUnit\d+)\]\s*/) {
- $lun = $1;
- $SETTINGS->{$lun} = ();
- $SETTINGS->{targets}++;
- } elsif ($lun) {
- next if (($_ =~ /^\s*#/) || ($_ =~ /^\s*$/));
- if ($_ =~ /^\s*(\w+)\s+(.+)\s*/) {
- #next if $2 =~ /^Option.*/;
- $SETTINGS->{$lun}->{$1} = $2;
- $SETTINGS->{$lun}->{$1} =~ s/^\s+|\s+$|"\s*//g;
- } else {
- die "$line: parse error [$_]";
- }
- }
- $CONFIG .= "$_\n" unless $lun;
- }
-
- $CONFIG =~ s/\n$//;
- die "$scfg->{target}: Target not found" unless $SETTINGS->{targets};
- my $max = $SETTINGS->{targets};
- my $base = get_base;
-
- for (my $i = 1; $i <= $max; $i++) {
- my $target = $SETTINGS->{nodebase}.':'.$SETTINGS->{"LogicalUnit$i"}->{TargetName};
- if ($target eq $scfg->{target}) {
- my $lu = ();
- while ((my $key, my $val) = each(%{$SETTINGS->{"LogicalUnit$i"}})) {
- if ($key =~ /^LUN\d+/) {
- if ($val =~ /^Storage\s+([\w\/\-]+)\s+(\w+)/) {
- my $storage = $1;
- my $size = $parse_size->($2);
- my $conf = undef;
- if ($storage =~ /^$base\/$scfg->{pool}\/([\w\-]+)$/) {
- $conf = {
- lun => $key,
- Storage => $storage,
- Size => $size,
- };
- }
- push @$lu, $conf if $conf;
- }
- delete $SETTINGS->{"LogicalUnit$i"}->{$key};
- }
- }
- $SETTINGS->{"LogicalUnit$i"}->{luns} = $lu;
- $SETTINGS->{current} = "LogicalUnit$i";
- $init_lu_name->("LogicalUnit$i");
- } else {
- $CONFIG .= $lun_dumper->("LogicalUnit$i");
- delete $SETTINGS->{"LogicalUnit$i"};
- $SETTINGS->{targets}--;
- }
- }
- die "$scfg->{target}: Target not found" unless $SETTINGS->{targets} > 0;
+ my ($scfg) = @_;
+
+ my $lun = undef;
+ my $line = 0;
+
+ my $config = $get_config->($scfg);
+ my @cfgfile = split "\n", $config;
+
+ foreach (@cfgfile) {
+ $line++;
+ if ($_ =~ /^\s*\[(PortalGroup\d+)\]\s*/) {
+ $lun = undef;
+ $SETTINGS->{$1} = ();
+ } elsif ($_ =~ /^\s*\[(InitiatorGroup\d+)\]\s*/) {
+ $lun = undef;
+ $SETTINGS->{$1} = ();
+ } elsif ($_ =~ /^\s*PidFile\s+"?([\w\/\.]+)"?\s*/) {
+ $lun = undef;
+ $SETTINGS->{pidfile} = $1;
+ } elsif ($_ =~ /^\s*NodeBase\s+"?([\w\-\.]+)"?\s*/) {
+ $lun = undef;
+ $SETTINGS->{nodebase} = $1;
+ } elsif ($_ =~ /^\s*\[(LogicalUnit\d+)\]\s*/) {
+ $lun = $1;
+ $SETTINGS->{$lun} = ();
+ $SETTINGS->{targets}++;
+ } elsif ($lun) {
+ next if (($_ =~ /^\s*#/) || ($_ =~ /^\s*$/));
+ if ($_ =~ /^\s*(\w+)\s+(.+)\s*/) {
+ #next if $2 =~ /^Option.*/;
+ $SETTINGS->{$lun}->{$1} = $2;
+ $SETTINGS->{$lun}->{$1} =~ s/^\s+|\s+$|"\s*//g;
+ } else {
+ die "$line: parse error [$_]";
+ }
+ }
+ $CONFIG .= "$_\n" unless $lun;
+ }
+
+ $CONFIG =~ s/\n$//;
+ die "$scfg->{target}: Target not found" unless $SETTINGS->{targets};
+ my $max = $SETTINGS->{targets};
+ my $base = get_base;
+
+ for (my $i = 1; $i <= $max; $i++) {
+ my $target = $SETTINGS->{nodebase}.':'.$SETTINGS->{"LogicalUnit$i"}->{TargetName};
+ if ($target eq $scfg->{target}) {
+ my $lu = ();
+ while ((my $key, my $val) = each(%{$SETTINGS->{"LogicalUnit$i"}})) {
+ if ($key =~ /^LUN\d+/) {
+ if ($val =~ /^Storage\s+([\w\/\-]+)\s+(\w+)/) {
+ my $storage = $1;
+ my $size = $parse_size->($2);
+ my $conf = undef;
+ if ($storage =~ /^$base\/$scfg->{pool}\/([\w\-]+)$/) {
+ $conf = {
+ lun => $key,
+ Storage => $storage,
+ Size => $size,
+ };
+ }
+ push @$lu, $conf if $conf;
+ }
+ delete $SETTINGS->{"LogicalUnit$i"}->{$key};
+ }
+ }
+ $SETTINGS->{"LogicalUnit$i"}->{luns} = $lu;
+ $SETTINGS->{current} = "LogicalUnit$i";
+ $init_lu_name->("LogicalUnit$i");
+ } else {
+ $CONFIG .= $lun_dumper->("LogicalUnit$i");
+ delete $SETTINGS->{"LogicalUnit$i"};
+ $SETTINGS->{targets}--;
+ }
+ }
+ die "$scfg->{target}: Target not found" unless $SETTINGS->{targets} > 0;
};
my $list_lun = sub {
- my ($scfg, $timeout, $method, @params) = @_;
- my $name = undef;
-
- my $object = $params[0];
- for my $key (keys %$SETTINGS) {
- next unless $key =~ /^LogicalUnit\d+$/;
- foreach my $lun (@{$SETTINGS->{$key}->{luns}}) {
- if ($lun->{Storage} =~ /^$object$/) {
- return $lun->{Storage};
- }
- }
- }
-
- return $name;
+ my ($scfg, $timeout, $method, @params) = @_;
+ my $name = undef;
+
+ my $object = $params[0];
+ for my $key (keys %$SETTINGS) {
+ next unless $key =~ /^LogicalUnit\d+$/;
+ foreach my $lun (@{$SETTINGS->{$key}->{luns}}) {
+ if ($lun->{Storage} =~ /^$object$/) {
+ return $lun->{Storage};
+ }
+ }
+ }
+
+ return $name;
};
my $create_lun = sub {
- my ($scfg, $timeout, $method, @params) = @_;
- my $res = ();
- my $file = "/tmp/config$$";
-
- if ($list_lun->($scfg, $timeout, $method, @params)) {
- die "$params[0]: LUN exists";
- }
- my $lun = $params[0];
- $lun = $make_lun->($lun);
- my $config = $lun_dumper->($SETTINGS->{current});
- open(my $fh, '>', $file) or die "Could not open file '$file' $!";
-
- print $fh $CONFIG;
- print $fh $config;
- close $fh;
- @params = ($CONFIG_FILE);
- $res = {
- cmd => 'scp',
- method => $file,
- params => \@params,
- msg => $lun,
- post_exe => sub {
- unlink $file;
- },
- };
-
- return $res;
+ my ($scfg, $timeout, $method, @params) = @_;
+ my $res = ();
+ my $file = "/tmp/config$$";
+
+ if ($list_lun->($scfg, $timeout, $method, @params)) {
+ die "$params[0]: LUN exists";
+ }
+ my $lun = $params[0];
+ $lun = $make_lun->($lun);
+ my $config = $lun_dumper->($SETTINGS->{current});
+ open(my $fh, '>', $file) or die "Could not open file '$file' $!";
+
+ print $fh $CONFIG;
+ print $fh $config;
+ close $fh;
+ @params = ($CONFIG_FILE);
+ $res = {
+ cmd => 'scp',
+ method => $file,
+ params => \@params,
+ msg => $lun,
+ post_exe => sub {
+ unlink $file;
+ },
+ };
+
+ return $res;
};
my $delete_lun = sub {
- my ($scfg, $timeout, $method, @params) = @_;
- my $res = ();
- my $file = "/tmp/config$$";
-
- my $target = $SETTINGS->{current};
- my $luns = ();
-
- foreach my $conf (@{$SETTINGS->{$target}->{luns}}) {
- if ($conf->{Storage} =~ /^$params[0]$/) {
- $free_lu_name->($target, $conf->{lun});
- } else {
- push @$luns, $conf;
- }
- }
- $SETTINGS->{$target}->{luns} = $luns;
-
- my $config = $lun_dumper->($SETTINGS->{current});
- open(my $fh, '>', $file) or die "Could not open file '$file' $!";
-
- print $fh $CONFIG;
- print $fh $config;
- close $fh;
- @params = ($CONFIG_FILE);
- $res = {
- cmd => 'scp',
- method => $file,
- params => \@params,
- post_exe => sub {
- unlink $file;
- run_lun_command($scfg, undef, 'add_view', 'restart');
- },
- };
-
- return $res;
+ my ($scfg, $timeout, $method, @params) = @_;
+ my $res = ();
+ my $file = "/tmp/config$$";
+
+ my $target = $SETTINGS->{current};
+ my $luns = ();
+
+ foreach my $conf (@{$SETTINGS->{$target}->{luns}}) {
+ if ($conf->{Storage} =~ /^$params[0]$/) {
+ $free_lu_name->($target, $conf->{lun});
+ } else {
+ push @$luns, $conf;
+ }
+ }
+ $SETTINGS->{$target}->{luns} = $luns;
+
+ my $config = $lun_dumper->($SETTINGS->{current});
+ open(my $fh, '>', $file) or die "Could not open file '$file' $!";
+
+ print $fh $CONFIG;
+ print $fh $config;
+ close $fh;
+ @params = ($CONFIG_FILE);
+ $res = {
+ cmd => 'scp',
+ method => $file,
+ params => \@params,
+ post_exe => sub {
+ unlink $file;
+ run_lun_command($scfg, undef, 'add_view', 'restart');
+ },
+ };
+
+ return $res;
};
my $import_lun = sub {
- my ($scfg, $timeout, $method, @params) = @_;
+ my ($scfg, $timeout, $method, @params) = @_;
- my $res = $create_lun->($scfg, $timeout, $method, @params);
+ my $res = $create_lun->($scfg, $timeout, $method, @params);
- return $res;
+ return $res;
};
my $add_view = sub {
- my ($scfg, $timeout, $method, @params) = @_;
- my $cmdmap;
-
- if (@params && $params[0] eq 'restart') {
- @params = ('restart', '1>&2', '>', '/dev/null');
- $cmdmap = {
- cmd => 'ssh',
- method => $DAEMON,
- params => \@params,
- };
- } else {
- @params = ('-HUP', '$(cat '. "$SETTINGS->{pidfile})");
- $cmdmap = {
- cmd => 'ssh',
- method => 'kill',
- params => \@params,
- };
- }
-
- return $cmdmap;
+ my ($scfg, $timeout, $method, @params) = @_;
+ my $cmdmap;
+
+ if (@params && $params[0] eq 'restart') {
+ @params = ('restart', '1>&2', '>', '/dev/null');
+ $cmdmap = {
+ cmd => 'ssh',
+ method => $DAEMON,
+ params => \@params,
+ };
+ } else {
+ @params = ('-HUP', '$(cat '. "$SETTINGS->{pidfile})");
+ $cmdmap = {
+ cmd => 'ssh',
+ method => 'kill',
+ params => \@params,
+ };
+ }
+
+ return $cmdmap;
};
my $modify_lun = sub {
- my ($scfg, $timeout, $method, @params) = @_;
-
- # Current SIGHUP reload limitations
- # LU connected by the initiator can't be reloaded by SIGHUP.
- # Until above limitation persists modifying a LUN will require
- # a restart of the daemon breaking all current connections
- #die 'Modify a connected LUN is not currently supported by istgt';
- @params = ('restart', @params);
-
- return $add_view->($scfg, $timeout, $method, @params);
+ my ($scfg, $timeout, $method, @params) = @_;
+
+ # Current SIGHUP reload limitations
+ # LU connected by the initiator can't be reloaded by SIGHUP.
+ # Until above limitation persists modifying a LUN will require
+ # a restart of the daemon breaking all current connections
+ #die 'Modify a connected LUN is not currently supported by istgt';
+ @params = ('restart', @params);
+
+ return $add_view->($scfg, $timeout, $method, @params);
};
my $list_view = sub {
- my ($scfg, $timeout, $method, @params) = @_;
- my $lun = undef;
-
- my $object = $params[0];
- for my $key (keys %$SETTINGS) {
- next unless $key =~ /^LogicalUnit\d+$/;
- foreach my $lun (@{$SETTINGS->{$key}->{luns}}) {
- if ($lun->{Storage} =~ /^$object$/) {
- if ($lun->{lun} =~ /^LUN(\d+)/) {
- return $1;
- }
- die "$lun->{Storage}: Missing LUN";
- }
- }
- }
-
- return $lun;
+ my ($scfg, $timeout, $method, @params) = @_;
+ my $lun = undef;
+
+ my $object = $params[0];
+ for my $key (keys %$SETTINGS) {
+ next unless $key =~ /^LogicalUnit\d+$/;
+ foreach my $lun (@{$SETTINGS->{$key}->{luns}}) {
+ if ($lun->{Storage} =~ /^$object$/) {
+ if ($lun->{lun} =~ /^LUN(\d+)/) {
+ return $1;
+ }
+ die "$lun->{Storage}: Missing LUN";
+ }
+ }
+ }
+
+ return $lun;
};
my $get_lun_cmd_map = sub {
- my ($method) = @_;
-
- my $cmdmap = {
- create_lu => { cmd => $create_lun },
- delete_lu => { cmd => $delete_lun },
- import_lu => { cmd => $import_lun },
- modify_lu => { cmd => $modify_lun },
- add_view => { cmd => $add_view },
- list_view => { cmd => $list_view },
- list_lu => { cmd => $list_lun },
- };
-
- die "unknown command '$method'" unless exists $cmdmap->{$method};
-
- return $cmdmap->{$method};
+ my ($method) = @_;
+
+ my $cmdmap = {
+ create_lu => { cmd => $create_lun },
+ delete_lu => { cmd => $delete_lun },
+ import_lu => { cmd => $import_lun },
+ modify_lu => { cmd => $modify_lun },
+ add_view => { cmd => $add_view },
+ list_view => { cmd => $list_view },
+ list_lu => { cmd => $list_lun },
+ };
+
+ die "unknown command '$method'" unless exists $cmdmap->{$method};
+
+ return $cmdmap->{$method};
};
sub run_lun_command {
- my ($scfg, $timeout, $method, @params) = @_;
+ my ($scfg, $timeout, $method, @params) = @_;
my $msg = '';
my $luncmd;
my $target;
- my $cmd;
- my $res;
+ my $cmd;
+ my $res;
$timeout = 10 if !$timeout;
- my $is_add_view = 0;
-
+ my $is_add_view = 0;
+
my $output = sub {
my $line = shift;
- $msg .= "$line\n";
+ $msg .= "$line\n";
+ };
+
+ $target = 'root@' . $scfg->{portal};
+
+ $parser->($scfg) unless $SETTINGS;
+ my $cmdmap = $get_lun_cmd_map->($method);
+ if ($method eq 'add_view') {
+ $is_add_view = 1 ;
+ $timeout = 15;
+ }
+ if (ref $cmdmap->{cmd} eq 'CODE') {
+ $res = $cmdmap->{cmd}->($scfg, $timeout, $method, @params);
+ if (ref $res) {
+ $method = $res->{method};
+ @params = @{$res->{params}};
+ if ($res->{cmd} eq 'scp') {
+ $cmd = [@scp_cmd, '-i', "$id_rsa_path/$scfg->{portal}_id_rsa", $method, "$target:$params[0]"];
+ } else {
+ $cmd = [@ssh_cmd, '-i', "$id_rsa_path/$scfg->{portal}_id_rsa", $target, $method, @params];
+ }
+ } else {
+ return $res;
+ }
+ } else {
+ $luncmd = $cmdmap->{cmd};
+ $method = $cmdmap->{method};
+ $cmd = [@ssh_cmd, '-i', "$id_rsa_path/$scfg->{portal}_id_rsa", $target, $luncmd, $method, @params];
+ }
+
+ eval {
+ run_command($cmd, outfunc => $output, timeout => $timeout);
};
+ if ($@ && $is_add_view) {
+ my $err = $@;
+ if ($OLD_CONFIG) {
+ my $err1 = undef;
+ my $file = "/tmp/config$$";
+ open(my $fh, '>', $file) or die "Could not open file '$file' $!";
+ print $fh $OLD_CONFIG;
+ close $fh;
+ $cmd = [@scp_cmd, '-i', "$id_rsa_path/$scfg->{portal}_id_rsa", $file, $CONFIG_FILE];
+ eval {
+ run_command($cmd, outfunc => $output, timeout => $timeout);
+ };
+ $err1 = $@ if $@;
+ unlink $file;
+ die "$err\n$err1" if $err1;
+ eval {
+ run_lun_command($scfg, undef, 'add_view', 'restart');
+ };
+ die "$err\n$@" if ($@);
+ }
+ die $err;
+ } elsif ($@) {
+ die $@;
+ } elsif ($is_add_view) {
+ $OLD_CONFIG = undef;
+ }
+
+ if ($res->{post_exe} && ref $res->{post_exe} eq 'CODE') {
+ $res->{post_exe}->();
+ }
+
+ if ($res->{msg}) {
+ $msg = $res->{msg};
+ }
- $target = 'root@' . $scfg->{portal};
-
- $parser->($scfg) unless $SETTINGS;
- my $cmdmap = $get_lun_cmd_map->($method);
- if ($method eq 'add_view') {
- $is_add_view = 1 ;
- $timeout = 15;
- }
- if (ref $cmdmap->{cmd} eq 'CODE') {
- $res = $cmdmap->{cmd}->($scfg, $timeout, $method, @params);
- if (ref $res) {
- $method = $res->{method};
- @params = @{$res->{params}};
- if ($res->{cmd} eq 'scp') {
- $cmd = [@scp_cmd, $method, "$target:$params[0]"];
- } else {
- $cmd = [@ssh_cmd, $target, $method, @params];
- }
- } else {
- return $res;
- }
- } else {
- $luncmd = $cmdmap->{cmd};
- $method = $cmdmap->{method};
- $cmd = [@ssh_cmd, $target, $luncmd, $method, @params];
- }
-
- eval {
- run_command($cmd, outfunc => $output, timeout => $timeout);
- };
- if ($@ && $is_add_view) {
- my $err = $@;
- if ($OLD_CONFIG) {
- my $err1 = undef;
- my $file = "/tmp/config$$";
- open(my $fh, '>', $file) or die "Could not open file '$file' $!";
- print $fh $OLD_CONFIG;
- close $fh;
- $cmd = [@scp_cmd, $file, $CONFIG_FILE];
- eval {
- run_command($cmd, outfunc => $output, timeout => $timeout);
- };
- $err1 = $@ if $@;
- unlink $file;
- die "$err\n$err1" if $err1;
- eval {
- run_lun_command($scfg, undef, 'add_view', 'restart');
- };
- die "$err\n$@" if ($@);
- }
- die $err;
- } elsif ($@) {
- die $@;
- } elsif ($is_add_view) {
- $OLD_CONFIG = undef;
- }
-
- if ($res->{post_exe} && ref $res->{post_exe} eq 'CODE') {
- $res->{post_exe}->();
- }
-
- if ($res->{msg}) {
- $msg = $res->{msg};
- }
-
- return $msg;
+ return $msg;
}
sub get_base {
- return '/dev/zvol';
+ return '/dev/zvol';
}
-1;
\ No newline at end of file
+1;
diff --git a/PVE/Storage/ZFSPlugin.pm b/PVE/Storage/ZFSPlugin.pm
index 1c0acc6..d077cfb 100644
--- a/PVE/Storage/ZFSPlugin.pm
+++ b/PVE/Storage/ZFSPlugin.pm
@@ -14,35 +14,36 @@ use PVE::Storage::LunCmd::Iet;
my @ssh_opts = ('-o', 'BatchMode=yes');
my @ssh_cmd = ('/usr/bin/ssh', @ssh_opts);
+my $id_rsa_path = '/etc/pve/priv/zfs';
my $lun_cmds = {
- create_lu => 1,
- delete_lu => 1,
- import_lu => 1,
- modify_lu => 1,
- add_view => 1,
- list_view => 1,
- list_lu => 1,
+ create_lu => 1,
+ delete_lu => 1,
+ import_lu => 1,
+ modify_lu => 1,
+ add_view => 1,
+ list_view => 1,
+ list_lu => 1,
};
my $zfs_unknown_scsi_provider = sub {
- my ($provider) = @_;
+ my ($provider) = @_;
- die "$provider: unknown iscsi provider. Available [comstar, istgt, iet]";
+ die "$provider: unknown iscsi provider. Available [comstar, istgt, iet]";
};
my $zfs_get_base = sub {
- my ($scfg) = @_;
-
- if ($scfg->{iscsiprovider} eq 'comstar') {
- return PVE::Storage::LunCmd::Comstar::get_base;
- } elsif ($scfg->{iscsiprovider} eq 'istgt') {
- return PVE::Storage::LunCmd::Istgt::get_base;
- } elsif ($scfg->{iscsiprovider} eq 'iet') {
- return PVE::Storage::LunCmd::Iet::get_base;
- } else {
- $zfs_unknown_scsi_provider->($scfg->{iscsiprovider});
- }
+ my ($scfg) = @_;
+
+ if ($scfg->{iscsiprovider} eq 'comstar') {
+ return PVE::Storage::LunCmd::Comstar::get_base;
+ } elsif ($scfg->{iscsiprovider} eq 'istgt') {
+ return PVE::Storage::LunCmd::Istgt::get_base;
+ } elsif ($scfg->{iscsiprovider} eq 'iet') {
+ return PVE::Storage::LunCmd::Iet::get_base;
+ } else {
+ $zfs_unknown_scsi_provider->($scfg->{iscsiprovider});
+ }
};
sub zfs_request {
@@ -51,41 +52,41 @@ sub zfs_request {
my $cmdmap;
my $zfscmd;
my $target;
- my $msg;
+ my $msg;
$timeout = 5 if !$timeout;
- if ($lun_cmds->{$method}) {
- if ($scfg->{iscsiprovider} eq 'comstar') {
- $msg = PVE::Storage::LunCmd::Comstar::run_lun_command($scfg, $timeout, $method, @params);
- } elsif ($scfg->{iscsiprovider} eq 'istgt') {
- $msg = PVE::Storage::LunCmd::Istgt::run_lun_command($scfg, $timeout, $method, @params);
- } elsif ($scfg->{iscsiprovider} eq 'iet') {
- $msg = PVE::Storage::LunCmd::Iet::run_lun_command($scfg, $timeout, $method, @params);
- } else {
- $zfs_unknown_scsi_provider->($scfg->{iscsiprovider});
- }
- } else {
- if ($method eq 'zpool_list') {
- $zfscmd = 'zpool';
- $method = 'list',
- } else {
- $zfscmd = 'zfs';
- }
-
- $target = 'root@' . $scfg->{portal};
-
- my $cmd = [@ssh_cmd, $target, $zfscmd, $method, @params];
-
- $msg = '';
-
- my $output = sub {
- my $line = shift;
- $msg .= "$line\n";
- };
-
- run_command($cmd, outfunc => $output, timeout => $timeout);
- }
+ if ($lun_cmds->{$method}) {
+ if ($scfg->{iscsiprovider} eq 'comstar') {
+ $msg = PVE::Storage::LunCmd::Comstar::run_lun_command($scfg, $timeout, $method, @params);
+ } elsif ($scfg->{iscsiprovider} eq 'istgt') {
+ $msg = PVE::Storage::LunCmd::Istgt::run_lun_command($scfg, $timeout, $method, @params);
+ } elsif ($scfg->{iscsiprovider} eq 'iet') {
+ $msg = PVE::Storage::LunCmd::Iet::run_lun_command($scfg, $timeout, $method, @params);
+ } else {
+ $zfs_unknown_scsi_provider->($scfg->{iscsiprovider});
+ }
+ } else {
+ if ($method eq 'zpool_list') {
+ $zfscmd = 'zpool';
+ $method = 'list',
+ } else {
+ $zfscmd = 'zfs';
+ }
+
+ $target = 'root@' . $scfg->{portal};
+
+ my $cmd = [@ssh_cmd, '-i', "$id_rsa_path/$scfg->{portal}_id_rsa", $target, $zfscmd, $method, @params];
+
+ $msg = '';
+
+ my $output = sub {
+ my $line = shift;
+ $msg .= "$line\n";
+ };
+
+ run_command($cmd, outfunc => $output, timeout => $timeout);
+ }
return $msg;
}
@@ -96,24 +97,24 @@ sub zfs_parse_size {
return 0 if !$text;
if ($text =~ m/^(\d+(\.\d+)?)([TGMK])?$/) {
- my ($size, $reminder, $unit) = ($1, $2, $3);
- return $size if !$unit;
- if ($unit eq 'K') {
- $size *= 1024;
- } elsif ($unit eq 'M') {
- $size *= 1024*1024;
- } elsif ($unit eq 'G') {
- $size *= 1024*1024*1024;
- } elsif ($unit eq 'T') {
- $size *= 1024*1024*1024*1024;
- }
-
- if ($reminder) {
- $size = ceil($size);
- }
- return $size;
+ my ($size, $reminder, $unit) = ($1, $2, $3);
+ return $size if !$unit;
+ if ($unit eq 'K') {
+ $size *= 1024;
+ } elsif ($unit eq 'M') {
+ $size *= 1024*1024;
+ } elsif ($unit eq 'G') {
+ $size *= 1024*1024*1024;
+ } elsif ($unit eq 'T') {
+ $size *= 1024*1024*1024*1024;
+ }
+
+ if ($reminder) {
+ $size = ceil($size);
+ }
+ return $size;
} else {
- return 0;
+ return 0;
}
}
@@ -124,16 +125,16 @@ sub zfs_get_pool_stats {
my $used = 0;
my $text = zfs_request($scfg, undef, 'get', '-o', 'value', '-Hp',
- 'available,used', $scfg->{pool});
+ 'available,used', $scfg->{pool});
my @lines = split /\n/, $text;
if($lines[0] =~ /^(\d+)$/) {
- $available = $1;
+ $available = $1;
}
if($lines[1] =~ /^(\d+)$/) {
- $used = $1;
+ $used = $1;
}
return ($available, $used);
@@ -148,28 +149,28 @@ sub zfs_parse_zvol_list {
my @lines = split /\n/, $text;
foreach my $line (@lines) {
- if ($line =~ /^(.+)\s+([a-zA-Z0-9\.]+|\-)\s+(.+)$/) {
- my $zvol = {};
- my $name;
- my $disk;
- my @zvols = split /\//, $1;
- my $pool = $zvols[0];
-
- if (scalar(@zvols) == 2 && $zvols[0] !~ /^rpool$/) {
- $disk = $zvols[1];
- next unless $disk =~ m!^(\w+)-(\d+)-(\w+)-(\d+)$!;
- $name = $pool . '/' . $disk;
- } else {
- next;
- }
-
- $zvol->{name} = $name;
- $zvol->{size} = zfs_parse_size($2);
- if ($3 !~ /^-$/) {
- $zvol->{origin} = $3;
- }
- push @$list, $zvol;
- }
+ if ($line =~ /^(.+)\s+([a-zA-Z0-9\.]+|\-)\s+(.+)$/) {
+ my $zvol = {};
+ my $name;
+ my $disk;
+ my @zvols = split /\//, $1;
+ my $pool = $zvols[0];
+
+ if (scalar(@zvols) == 2 && $zvols[0] !~ /^rpool$/) {
+ $disk = $zvols[1];
+ next unless $disk =~ m!^(\w+)-(\d+)-(\w+)-(\d+)$!;
+ $name = $pool . '/' . $disk;
+ } else {
+ next;
+ }
+
+ $zvol->{name} = $name;
+ $zvol->{size} = zfs_parse_size($2);
+ if ($3 !~ /^-$/) {
+ $zvol->{origin} = $3;
+ }
+ push @$list, $zvol;
+ }
}
return $list;
@@ -179,7 +180,7 @@ sub zfs_get_lu_name {
my ($scfg, $zvol) = @_;
my $object;
- my $base = $zfs_get_base->($scfg);
+ my $base = $zfs_get_base->($scfg);
if ($zvol =~ /^.+\/.+/) {
$object = "$base/$zvol";
} else {
@@ -188,8 +189,8 @@ sub zfs_get_lu_name {
my $lu_name = zfs_request($scfg, undef, 'list_lu', $object);
- return $lu_name if $lu_name;
-
+ return $lu_name if $lu_name;
+
die "Could not find lu_name for zvol $zvol";
}
@@ -199,7 +200,7 @@ sub zfs_get_zvol_size {
my $text = zfs_request($scfg, undef, 'get', '-Hp', 'volsize', "$scfg->{pool}/$zvol");
if($text =~ /volsize\s(\d+)/){
- return $1;
+ return $1;
}
die "Could not get zvol size";
@@ -209,9 +210,9 @@ sub zfs_add_lun_mapping_entry {
my ($scfg, $zvol, $guid) = @_;
if (! defined($guid)) {
- $guid = zfs_get_lu_name($scfg, $zvol);
+ $guid = zfs_get_lu_name($scfg, $zvol);
}
-
+
zfs_request($scfg, undef, 'add_view', $guid);
}
@@ -226,7 +227,7 @@ sub zfs_delete_lu {
sub zfs_create_lu {
my ($scfg, $zvol) = @_;
- my $base = $zfs_get_base->($scfg);
+ my $base = $zfs_get_base->($scfg);
my $guid = zfs_request($scfg, undef, 'create_lu', "$base/$scfg->{pool}/$zvol");
return $guid;
@@ -235,7 +236,7 @@ sub zfs_create_lu {
sub zfs_import_lu {
my ($scfg, $zvol) = @_;
- my $base = $zfs_get_base->($scfg);
+ my $base = $zfs_get_base->($scfg);
zfs_request($scfg, undef, 'import_lu', "$base/$scfg->{pool}/$zvol");
}
@@ -276,26 +277,26 @@ sub zfs_list_zvol {
my $list = ();
foreach my $zvol (@$zvols) {
- my @values = split('/', $zvol->{name});
-
- my $pool = $values[0];
- my $image = $values[1];
-
- next if $image !~ m/^((vm|base)-(\d+)-\S+)$/;
- my $owner = $3;
-
- my $parent = $zvol->{origin};
- if($zvol->{origin} && $zvol->{origin} =~ m/^$scfg->{pool}\/(\S+)$/){
- $parent = $1;
- }
-
- $list->{$pool}->{$image} = {
- name => $image,
- size => $zvol->{size},
- parent => $parent,
- format => 'raw',
- vmid => $owner
- };
+ my @values = split('/', $zvol->{name});
+
+ my $pool = $values[0];
+ my $image = $values[1];
+
+ next if $image !~ m/^((vm|base)-(\d+)-\S+)$/;
+ my $owner = $3;
+
+ my $parent = $zvol->{origin};
+ if($zvol->{origin} && $zvol->{origin} =~ m/^$scfg->{pool}\/(\S+)$/){
+ $parent = $1;
+ }
+
+ $list->{$pool}->{$image} = {
+ name => $image,
+ size => $zvol->{size},
+ parent => $parent,
+ format => 'raw',
+ vmid => $owner
+ };
}
return $list;
@@ -309,16 +310,16 @@ sub type {
sub plugindata {
return {
- content => [ {images => 1}, { images => 1 }],
+ content => [ {images => 1}, { images => 1 }],
};
}
sub properties {
return {
- iscsiprovider => {
- description => "iscsi provider",
- type => 'string',
- },
+ iscsiprovider => {
+ description => "iscsi provider",
+ type => 'string',
+ },
blocksize => {
description => "block size",
type => 'string',
@@ -331,11 +332,11 @@ sub options {
nodes => { optional => 1 },
disable => { optional => 1 },
portal => { fixed => 1 },
- target => { fixed => 1 },
+ target => { fixed => 1 },
pool => { fixed => 1 },
- blocksize => { fixed => 1 },
- iscsiprovider => { fixed => 1 },
- content => { optional => 1 },
+ blocksize => { fixed => 1 },
+ iscsiprovider => { fixed => 1 },
+ content => { optional => 1 },
};
}
@@ -345,7 +346,7 @@ sub parse_volname {
my ($class, $volname) = @_;
if ($volname =~ m/^(((base|vm)-(\d+)-\S+)\/)?((base)?(vm)?-(\d+)-\S+)$/) {
- return ('images', $5, $8, $2, $4, $6);
+ return ('images', $5, $8, $2, $4, $6);
}
die "unable to parse zfs volume name '$volname'\n";
@@ -361,9 +362,9 @@ sub path {
my $guid = zfs_get_lu_name($scfg, $name);
my $lun = zfs_get_lun_number($scfg, $guid);
-
+
my $path = "iscsi://$portal/$target/$lun";
-
+
return ($path, $vmid, $vtype);
}
@@ -448,7 +449,7 @@ sub alloc_image {
die "unsupported format '$fmt'" if $fmt ne 'raw';
die "illegal name '$name' - sould be 'vm-$vmid-*'\n"
- if $name && $name !~ m/^vm-$vmid-/;
+ if $name && $name !~ m/^vm-$vmid-/;
$name = &$find_free_diskname($storeid, $scfg, $vmid);
@@ -487,31 +488,31 @@ sub list_images {
if (my $dat = $cache->{zfs}->{$zfspool}) {
- foreach my $image (keys %$dat) {
+ foreach my $image (keys %$dat) {
- my $volname = $dat->{$image}->{name};
- my $parent = $dat->{$image}->{parent};
+ my $volname = $dat->{$image}->{name};
+ my $parent = $dat->{$image}->{parent};
- my $volid = undef;
+ my $volid = undef;
if ($parent && $parent =~ m/^(\S+)@(\S+)$/) {
- my ($basename) = ($1);
- $volid = "$storeid:$basename/$volname";
- } else {
- $volid = "$storeid:$volname";
- }
-
- my $owner = $dat->{$volname}->{vmid};
- if ($vollist) {
- my $found = grep { $_ eq $volid } @$vollist;
- next if !$found;
- } else {
- next if defined ($vmid) && ($owner ne $vmid);
- }
-
- my $info = $dat->{$volname};
- $info->{volid} = $volid;
- push @$res, $info;
- }
+ my ($basename) = ($1);
+ $volid = "$storeid:$basename/$volname";
+ } else {
+ $volid = "$storeid:$volname";
+ }
+
+ my $owner = $dat->{$volname}->{vmid};
+ if ($vollist) {
+ my $found = grep { $_ eq $volid } @$vollist;
+ next if !$found;
+ } else {
+ next if defined ($vmid) && ($owner ne $vmid);
+ }
+
+ my $info = $dat->{$volname};
+ $info->{volid} = $volid;
+ push @$res, $info;
+ }
}
return $res;
@@ -526,9 +527,9 @@ sub status {
my $active = 0;
eval {
- ($free, $used) = zfs_get_pool_stats($scfg);
- $active = 1;
- $total = $free + $used;
+ ($free, $used) = zfs_get_pool_stats($scfg);
+ $active = 1;
+ $total = $free + $used;
};
warn $@ if $@;
@@ -598,21 +599,21 @@ sub volume_has_feature {
my ($class, $scfg, $feature, $storeid, $volname, $snapname, $running) = @_;
my $features = {
- snapshot => { current => 1, snap => 1},
- clone => { base => 1},
- template => { current => 1},
- copy => { base => 1, current => 1},
+ snapshot => { current => 1, snap => 1},
+ clone => { base => 1},
+ template => { current => 1},
+ copy => { base => 1, current => 1},
};
my ($vtype, $name, $vmid, $basename, $basevmid, $isBase) =
- $class->parse_volname($volname);
+ $class->parse_volname($volname);
my $key = undef;
if ($snapname) {
- $key = 'snap';
+ $key = 'snap';
} else {
- $key = $isBase ? 'base' : 'current';
+ $key = $isBase ? 'base' : 'current';
}
return 1 if $features->{$feature}->{$key};
--
1.8.4.rc3
More information about the pve-devel
mailing list