]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Storage/ISCSIPlugin.pm
Don't remove and recreate lun when changing a volume
[pve-storage.git] / PVE / Storage / ISCSIPlugin.pm
index e5bb7bb4d31ce1cc5344792c74af120de7dc3dc5..131ffa0f87003c4dbe8318ebda41bc85ed81e512 100644 (file)
@@ -5,10 +5,9 @@ use warnings;
 use File::stat;
 use IO::Dir;
 use IO::File;
-use PVE::Tools qw(run_command file_read_firstline trim dir_glob_regex dir_glob_foreach);
+use PVE::Tools qw(run_command file_read_firstline trim dir_glob_regex dir_glob_foreach $IPV4RE $IPV6RE);
 use PVE::Storage::Plugin;
 use PVE::JSONSchema qw(get_standard_option);
-use Net::Ping;
 
 use base qw(PVE::Storage::Plugin);
 
@@ -45,7 +44,7 @@ sub iscsi_session_list {
        run_command($cmd, errmsg => 'iscsi session scan failed', outfunc => sub {
            my $line = shift;
            
-           if ($line =~ m/^tcp:\s+\[(\S+)\]\s+\S+\s+(\S+)\s*$/) {
+           if ($line =~ m/^tcp:\s+\[(\S+)\]\s+\S+\s+(\S+)(\s+\S+)?\s*$/) {
                my ($session, $target) = ($1, $2);
                # there can be several sessions per target (multipath)
                push @{$res->{$target}}, $session;   
@@ -62,10 +61,9 @@ sub iscsi_session_list {
 sub iscsi_test_portal {
     my ($portal) = @_;
 
-    my ($server, $port) = split(':', $portal);
-    my $p = Net::Ping->new("tcp", 2);
-    $p->port_number($port || 3260);
-    return $p->ping($server);
+    my ($server, $port) = PVE::Tools::parse_host_and_port($portal);
+    return 0 if !$server;
+    return PVE::Network::tcp_ping($server, $port || 3260, 2);
 }
 
 sub iscsi_discovery {
@@ -83,7 +81,7 @@ sub iscsi_discovery {
     run_command($cmd, outfunc => sub {
        my $line = shift;
 
-       if ($line =~ m/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+)\,\S+\s+(\S+)\s*$/) {
+       if ($line =~ m/^((?:$IPV4RE|\[$IPV6RE\]):\d+)\,\S+\s+(\S+)\s*$/) {
            my $portal = $1;
            my $target = $2;
            # one target can have more than one portal (multipath).
@@ -138,7 +136,7 @@ sub iscsi_session_rescan {
     }
 
     foreach my $session (@$session_list) {
-       my $cmd = [$ISCSIADM, '--mode', 'session', '-r', $session, '-R'];
+       my $cmd = [$ISCSIADM, '--mode', 'session', '--sid', $session, '--rescan'];
        eval { run_command($cmd, outfunc => sub {}); };
        warn $@ if $@;
     }
@@ -239,6 +237,7 @@ sub type {
 sub plugindata {
     return {
        content => [ {images => 1, none => 1}, { images => 1 }],
+       select_existing => 1,
     };
 }
 
@@ -262,6 +261,7 @@ sub options {
         nodes => { optional => 1},
        disable => { optional => 1},
        content => { optional => 1},
+       bwlimit => { optional => 1 },
     };
 }
 
@@ -271,14 +271,16 @@ sub parse_volname {
     my ($class, $volname) = @_;
 
     if ($volname =~ m!^\d+\.\d+\.\d+\.(\S+)$!) {
-       return ('images', $1, undef);
+       return ('images', $1, undef, undef, undef, undef, 'raw');
     }
 
     die "unable to parse iscsi volume name '$volname'\n";
 }
 
 sub filesystem_path {
-    my ($class, $scfg, $volname) = @_;
+    my ($class, $scfg, $volname, $snapname) = @_;
+
+    die "snapshot is not possible on iscsi storage\n" if defined($snapname);
 
     my ($vtype, $name, $vmid) = $class->parse_volname($volname);