--- ZFSPlugin.pm.orig 2018-05-16 04:06:14.000000000 -0400 +++ ZFSPlugin.pm 2018-08-19 15:44:12.472851999 -0400 @@ -10,6 +10,7 @@ use base qw(PVE::Storage::ZFSPoolPlugin); use PVE::Storage::LunCmd::Comstar; +use PVE::Storage::LunCmd::FreeNAS; use PVE::Storage::LunCmd::Istgt; use PVE::Storage::LunCmd::Iet; @@ -25,13 +26,14 @@ modify_lu => 1, add_view => 1, list_view => 1, + list_extent => 1, list_lu => 1, }; my $zfs_unknown_scsi_provider = sub { my ($provider) = @_; - die "$provider: unknown iscsi provider. Available [comstar, istgt, iet]"; + die "$provider: unknown iscsi provider. Available [comstar, freenas, istgt, iet]"; }; my $zfs_get_base = sub { @@ -39,6 +41,8 @@ if ($scfg->{iscsiprovider} eq 'comstar') { return PVE::Storage::LunCmd::Comstar::get_base; + } elsif ($scfg->{iscsiprovider} eq 'freenas') { + return PVE::Storage::LunCmd::FreeNAS::get_base; } elsif ($scfg->{iscsiprovider} eq 'istgt') { return PVE::Storage::LunCmd::Istgt::get_base; } elsif ($scfg->{iscsiprovider} eq 'iet') { @@ -59,6 +63,8 @@ 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 'freenas') { + $msg = PVE::Storage::LunCmd::FreeNAS::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') { @@ -155,6 +161,14 @@ return $class->zfs_request($scfg, undef, 'list_view', $guid); } +sub zfs_get_wwid_number { + my ($class, $scfg, $guid) = @_; + + die "could not find lun_number for guid $guid" if !$guid; + + return $class->zfs_request($scfg, undef, 'list_extent', $guid); +} + # Configuration sub type { @@ -173,6 +187,22 @@ description => "iscsi provider", type => 'string', }, + freenas_user => { + description => "FreeNAS API Username", + type => 'string', + }, + freenas_password => { + description => "FreeNAS API Password", + type => 'string', + }, + freenas_use_ssl => { + description => "FreeNAS API access via SSL", + type => 'boolean', + }, + freenas_apiv4_host => { + description => "FreeNAS API Host", + type => 'string', + }, # this will disable write caching on comstar and istgt. # it is not implemented for iet. iet blockio always operates with # writethrough caching when not in readonly mode @@ -204,6 +234,10 @@ sparse => { optional => 1 }, comstar_hg => { optional => 1 }, comstar_tg => { optional => 1 }, + freenas_user => { optional => 1 }, + freenas_password => { optional => 1 }, + freenas_use_ssl => { optional => 1 }, + freenas_apiv4_host => { optional => 1 }, content => { optional => 1 }, bwlimit => { optional => 1 }, }; @@ -225,7 +259,41 @@ my $guid = $class->zfs_get_lu_name($scfg, $name); my $lun = $class->zfs_get_lun_number($scfg, $guid); - my $path = "iscsi://$portal/$target/$lun"; + my $wwid = $class->zfs_get_wwid_number($scfg, $guid); +# syslog(info,"JD: path get_lun_number guid $uid"); + + if ($wwid =~ /^([-\@\w.]+)$/) { + $wwid = $1; # $data now untainted + } else { + die "Bad data in '$wwid'"; # log this somewhere + } + my $wwid_end = substr $wwid, 16; + + my $mapper = ''; + sleep 3; + run_command("iscsiadm -m session --rescan"); + sleep 3; + my $line = `multipath -ll | grep \"$wwid_end\"`; + my ($mapper_device) = split(' ', $line); + $mapper_device = "" unless $mapper_device; + $mapper .= $mapper_device; + + my $path = ""; + + if ($mapper =~ /^([-\@\w.]+)$/) { + $mapper = $1; # $data now untainted + } else { + $mapper = ''; + } + +# syslog(info,"Mapper: $mapper\n"); + if ($mapper eq "") + { + $path = "iscsi://$portal/$target/$lun"; + } else { + $path = "/dev/mapper/$mapper"; + sleep 5; + } return ($path, $vmid, $vtype); }