[pve-devel] [PATCH v7 pve-storage 03/10] Basic iscsiadm interaction code

mir at datanom.net mir at datanom.net
Tue Jun 20 22:39:55 CEST 2017


From: Michael Rasmussen <mir at datanom.net>

Signed-off-by: Michael Rasmussen <mir at datanom.net>
---
 PVE/Storage/FreeNASPlugin.pm | 119 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/PVE/Storage/FreeNASPlugin.pm b/PVE/Storage/FreeNASPlugin.pm
index a50a2f6..e930cea 100644
--- a/PVE/Storage/FreeNASPlugin.pm
+++ b/PVE/Storage/FreeNASPlugin.pm
@@ -22,6 +22,9 @@ my $rows_per_request = 50; # limit for get requests
                            # in FreeNAS API is 20) can cause race conditions
                            # on the FreeNAS host (seems like an unstable
                            # pagination algorithm implemented in FreeNAS)
+my $version;
+my $target_prefix = 'iqn.2005-10.org.freenas.ctl'; # automatically prepended
+                                                   # in FreeNAS
 
 # Configuration
 
@@ -242,6 +245,121 @@ my $freenas_list_zvol = sub {
     return $list;
 };
 
+my $os_request = sub {
+    my ($cmd, $noerr, $timeout) = @_;
+
+    $timeout = 5 unless $timeout;
+    $noerr = 0 unless $noerr;
+
+    my $text = '';
+
+    my $output = sub {
+        my $line = shift;
+        $text .= "$line\n";
+    };
+
+    my $exit_code = run_command($cmd, noerr => $noerr, errfunc => $output, outfunc => $output, timeout => $timeout);
+
+    return wantarray ? ($exit_code, $text) : $exit_code;
+};
+
+my $freenas_get_target_name = sub {
+    my ($scfg, $volname) = @_;
+    my $name = undef;
+    
+    if ($volname =~ /^(vm|base)-(\d+)-/) {
+        $name = "vm-$2";
+        return "$target_prefix\:$name";
+    }
+
+    return undef;
+};
+
+my $get_sid = sub {
+    my ($scfg, $volname) = @_;
+    my $sid = -1;
+    my $text = '';
+    my $exit = 0;
+    
+    my $target = $freenas_get_target_name->($scfg, $volname);
+
+    eval {
+        ($exit, $text) = $os_request->(
+            ['iscsiadm', '-m', 'node', '-T', $target, '-p', $scfg->{portal}, '-s'], 1, 60);
+    };
+    if ($@) {
+        # An exist code of 21 or 22 means no active session otherwise an error
+        if ($exit != 21 || $exit != 22) {
+            die "$@\n";
+        }
+    }
+    if ($text =~ /.*\[sid\:\s*(\d+),\s*.*/) {
+        $sid = $1;
+    }
+
+    return $sid;
+};
+
+my $create_session = sub {
+    my ($scfg, $volname) = @_;
+    my $sid = -1;
+    my $exit = undef;
+    
+    my $target = $freenas_get_target_name->($scfg, $volname);
+
+    eval {
+        $exit = $os_request->(
+            ['iscsiadm', '-m', 'node', '-T', $target, '-p', $scfg->{portal}, '--login'], 1, 60);
+        if ($exit == 21) {
+            eval {
+                $os_request->(
+                    ['iscsiadm', '-m', 'discovery', '-t', 'sendtargets', '-p', $scfg->{portal}], 0, 60);
+                $os_request->(
+                    ['iscsiadm', '-m', 'node', '-T', $target, '-p', $scfg->{portal}, '--login'], 0, 60);
+            };
+        }
+    };
+    if ($@) {
+        if ($exit == 21) {
+            eval {
+                $os_request->(
+                    ['iscsiadm', '-m', 'discovery', '-t', 'sendtargets', '-p', $scfg->{portal}], 0, 60);
+                $os_request->(
+                    ['iscsiadm', '-m', 'node', '-T', $target, '-p', $scfg->{portal}, '--login'], 0, 60);
+            };
+        } else {
+            die "$@\n";
+        }
+    }
+    eval {
+        $sid = $get_sid->($scfg, $volname);
+    };
+    die "$@\n" if $@;
+    die "Could not create session\n" if $sid < 0;
+    
+    return $sid;
+};
+
+my $delete_session = sub {
+    my ($scfg, $sid) = @_;
+    
+    eval {
+        $os_request->(['iscsiadm', '-m', 'session', '-r', $sid, '--logout'], 0, 60);
+    };
+    warn "Delete session failed: $@\n" if $@;
+};
+
+my $remove_local_lun = sub {
+    my ($id) = @_;
+    
+    open (my $fh, '>', "/sys/bus/scsi/devices/$id/delete") or
+        warn "Remove local LUN failed: $!\n";
+    if ($fh) {
+        print $fh '1';
+        close $fh;
+    }
+};
+
 # Storage implementation
 
 sub volume_size_info {
@@ -256,6 +374,7 @@ sub volume_size_info {
     die "Could not get zfs volume size\n";
 }
 
+
 sub parse_volname {
     my ($class, $volname) = @_;
 
-- 
2.11.0


----

This mail was virus scanned and spam checked before delivery.
This mail is also DKIM signed. See header dkim-signature.




More information about the pve-devel mailing list