[PATCH storage 1/1] iscsi: allow to configure multiple portals
ykonotopov at gnome.org
ykonotopov at gnome.org
Wed Aug 16 13:56:27 CEST 2023
From: Yuri Konotopov <ykonotopov at gnome.org>
Fixes: https://bugzilla.proxmox.com/show_bug.cgi?id=254
---
PVE/Storage/ISCSIPlugin.pm | 44 +++++++++++++++++++++++---------------
PVE/Storage/Plugin.pm | 18 ++++++++++++++++
2 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/PVE/Storage/ISCSIPlugin.pm b/PVE/Storage/ISCSIPlugin.pm
index a79fcb0..e056393 100644
--- a/PVE/Storage/ISCSIPlugin.pm
+++ b/PVE/Storage/ISCSIPlugin.pm
@@ -69,24 +69,30 @@ sub iscsi_test_portal {
}
sub iscsi_discovery {
- my ($portal) = @_;
+ my @portals = @{$_[0]};
check_iscsi_support ();
my $res = {};
- return $res if !iscsi_test_portal($portal); # fixme: raise exception here?
+ foreach my $portal (@portals)
+ {
+ next if !iscsi_test_portal($portal); # fixme: raise exception here?
- my $cmd = [$ISCSIADM, '--mode', 'discovery', '--type', 'sendtargets', '--portal', $portal];
- run_command($cmd, outfunc => sub {
- my $line = shift;
+ my $cmd = [$ISCSIADM, '--mode', 'discovery', '--type', 'sendtargets', '--portal', $portal];
+ run_command($cmd, outfunc => sub {
+ my $line = shift;
- 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).
- push @{$res->{$target}}, $portal;
- }
- });
+ 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).
+ push @{$res->{$target}}, $portal;
+ }
+ });
+
+ # In case of multipath we want to exit on any portal available
+ last;
+ }
return $res;
}
@@ -96,7 +102,7 @@ sub iscsi_login {
check_iscsi_support();
- eval { iscsi_discovery($portal_in); };
+ eval { iscsi_discovery(PVE::Storage::Plugin::get_portals($portal_in)); };
warn $@ if $@;
run_command([$ISCSIADM, '--mode', 'node', '--targetname', $target, '--login']);
@@ -245,8 +251,8 @@ sub properties {
type => 'string',
},
portal => {
- description => "iSCSI portal (IP or DNS name with optional port).",
- type => 'string', format => 'pve-storage-portal-dns',
+ description => "iSCSI portal (IP or DNS name with optional port). Multiple portals can be separated by comma (for multipath).",
+ type => 'string', format => 'pve-storage-portals-dns',
},
};
}
@@ -403,8 +409,12 @@ sub deactivate_storage {
sub check_connection {
my ($class, $storeid, $scfg) = @_;
- my $portal = $scfg->{portal};
- return iscsi_test_portal($portal);
+ foreach my $portal (@{PVE::Storage::Plugin::get_portals($scfg->{portal})}) {
+ my $result = iscsi_test_portal($portal);
+ return $result if $result;
+ }
+
+ return 0;
}
sub volume_resize {
diff --git a/PVE/Storage/Plugin.pm b/PVE/Storage/Plugin.pm
index c323085..ee69b14 100644
--- a/PVE/Storage/Plugin.pm
+++ b/PVE/Storage/Plugin.pm
@@ -205,6 +205,13 @@ sub content_hash_to_string {
return join(',', @cta);
}
+sub get_portals {
+ my $portal_cfg = shift;
+ my $portals = [split(',', $portal_cfg)];
+ map { s/^\s+|\s+$//g; } @{$portals};
+ return $portals;
+}
+
sub valid_content_types {
my ($type) = @_;
@@ -301,6 +308,17 @@ sub verify_portal_dns {
return $portal;
}
+PVE::JSONSchema::register_format('pve-storage-portals-dns', \&verify_portals_dns);
+sub verify_portals_dns {
+ my ($portal_in, $noerr) = @_;
+
+ foreach my $portal (@{get_portals($portal_in)}) {
+ verify_portal_dns($portal, $noerr);
+ }
+
+ return $portal_in;
+}
+
PVE::JSONSchema::register_format('pve-storage-content', \&verify_content);
sub verify_content {
my ($ct, $noerr) = @_;
--
2.41.0
More information about the pve-devel
mailing list