diff --git a/PVE/Storage/ISCSIDirectPlugin.pm b/PVE/Storage/ISCSIDirectPlugin.pm new file mode 100644 index 0000000..82b7521 --- /dev/null +++ b/PVE/Storage/ISCSIDirectPlugin.pm @@ -0,0 +1,189 @@ +package PVE::Storage::ISCSIDirectPlugin; + +use strict; +use warnings; +use IO::File; +use HTTP::Request; +use LWP::UserAgent; +use PVE::Tools qw(run_command file_read_firstline trim dir_glob_regex dir_glob_foreach); +use PVE::Storage::Plugin; +use PVE::JSONSchema qw(get_standard_option); + +use base qw(PVE::Storage::Plugin); + + +sub iscsi_ls{ + my ($scfg, $storeid) = @_; + + + my $portal = $scfg->{portal}; + my $cmd = ['/usr/bin/iscsi-ls', '-s', 'iscsi://'.$portal ]; + my $list = {}; + my $test = ""; + + my $errfunc = sub { + my $line = shift; + $line = trim($line); + + die $line if $line; + }; + + eval { + + run_command($cmd, errmsg => "iscsi error", errfunc => $errfunc,outfunc => sub { + my $line = shift; + $line = trim($line); + if( $line =~ /Lun:(\d+)\s+([A-Za-z0-9\-\_\.\:]*)\s+\(Size:(\d+)G\)/ ) { + $test = $1; + + my $image = $1; + my $size = $3; + + $list->{$storeid}->{$image} = { + name => $image, + size => $size, + }; + } + }); + }; + + my $err = $@; + die $err if $err && $err !~ m/TESTUNITREADY failed with SENSE KEY/ ; + return $list; + +} + +# Configuration + +sub type { + return 'iscsidirect'; +} + +sub plugindata { + return { + content => [ {images => 1, none => 1}, { images => 1 }], + }; +} + +sub options { + return { + portal => { fixed => 1 }, + target => { fixed => 1 }, + nodes => { optional => 1}, + disable => { optional => 1}, + content => { optional => 1}, + }; +} + + +# Storage implementation + +sub parse_volname { + my ($class, $volname) = @_; + + + if ($volname =~ m/^(\d+)$/) { + return ('images', $1, undef); + } + + die "unable to parse iscsi volume name '$volname'\n"; + +} + +sub path { + my ($class, $scfg, $volname) = @_; + + my ($vtype, $lun, $vmid) = $class->parse_volname($volname); + + my $target = $scfg->{target}; + my $portal = $scfg->{portal}; + + my $path = "iscsi://$portal/$target/$lun"; + + return ($path, $vmid, $vtype); +} + + +sub alloc_image { + my ($class, $storeid, $scfg, $vmid, $fmt, $name, $size) = @_; + + die "can't allocate space in iscsi storage\n"; +} + +sub free_image { + my ($class, $storeid, $scfg, $volname) = @_; + + die "can't free space in iscsi storage\n"; +} + + +sub list_images { + my ($class, $storeid, $scfg, $vmid, $vollist, $cache) = @_; + + my $res = []; + + $cache->{directiscsi} = iscsi_ls($scfg,$storeid) if !$cache->{directiscsi}; + + # we have no owner for iscsi devices + + my $target = $scfg->{target}; + + if (my $dat = $cache->{directiscsi}->{$storeid}) { + + foreach my $volname (keys %$dat) { + + my $volid = "$storeid:$volname"; + + if ($vollist) { + my $found = grep { $_ eq $volid } @$vollist; + next if !$found; + } else { + # we have no owner for iscsi devices + next if defined($vmid); + } + + my $info = $dat->{$volname}; + $info->{volid} = $volid; + + push @$res, $info; + } + } + + return $res; +} + + +sub status { + my ($class, $storeid, $scfg, $cache) = @_; + + my $total = 0; + my $free = 0; + my $used = 0; + my $active = 1; + return ($total,$free,$used,$active); + + return undef; +} + +sub activate_storage { + my ($class, $storeid, $scfg, $cache) = @_; + return 1; +} + +sub deactivate_storage { + my ($class, $storeid, $scfg, $cache) = @_; + return 1; +} + +sub activate_volume { + my ($class, $storeid, $scfg, $volname, $exclusive, $cache) = @_; + return 1; +} + +sub deactivate_volume { + my ($class, $storeid, $scfg, $volname, $exclusive, $cache) = @_; + return 1; +} + + +1; diff --git a/PVE/Storage/Makefile b/PVE/Storage/Makefile index e13890f..407f55c 100644 --- a/PVE/Storage/Makefile +++ b/PVE/Storage/Makefile @@ -1,4 +1,4 @@ -SOURCES=Plugin.pm DirPlugin.pm LVMPlugin.pm NFSPlugin.pm ISCSIPlugin.pm RBDPlugin.pm SheepdogPlugin.pm +SOURCES=Plugin.pm DirPlugin.pm LVMPlugin.pm NFSPlugin.pm ISCSIPlugin.pm RBDPlugin.pm SheepdogPlugin.pm ISCSIDirectPlugin.pm .PHONY: install install: diff --git a/PVE/Storage/Plugin.pm b/PVE/Storage/Plugin.pm index 946c3b8..908c6c3 100644 --- a/PVE/Storage/Plugin.pm +++ b/PVE/Storage/Plugin.pm @@ -300,7 +300,7 @@ sub parse_config { $d->{content} = $def->{content}->[1] if !$d->{content}; } - if ($type eq 'iscsi' || $type eq 'nfs' || $type eq 'rbd' || $type eq 'sheepdog' ) { + if ($type eq 'iscsi' || $type eq 'nfs' || $type eq 'rbd' || $type eq 'sheepdog' || $type eq 'iscsidirect' ) { $d->{shared} = 1; } }