From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id C95EC1FF0E3 for ; Tue, 04 Aug 2026 11:08:59 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 6D40621697; Tue, 04 Aug 2026 11:08:26 +0200 (CEST) From: Dietmar Maurer To: pve-devel@lists.proxmox.com Subject: [PATCH storage 7/7] iscsi: add periodic-discovery flag to skip re-discovery on login Date: Tue, 4 Aug 2026 11:08:19 +0200 Message-ID: <20260804090819.2136483-8-dietmar@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260804090819.2136483-1-dietmar@proxmox.com> References: <20260804090819.2136483-1-dietmar@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 2 AWL -0.107 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods RDNS_NONE 1.274 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Message-ID-Hash: 5B45XNBV7P62FW2BXZEINHDB3QPE6SLL X-Message-ID-Hash: 5B45XNBV7P62FW2BXZEINHDB3QPE6SLL X-MailFrom: dietmar@zilli.proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Every login first re-runs sendtargets discovery, which auto-persists node records and resets their node.* settings to defaults. This clobbers tuned records (timeouts, iface binding) and re-imposes the portal's full advertised set, fighting intentional per-node record divergence. With periodic-discovery=0, discovery only runs when the node db has no record for the target, seeding it once; later logins use the existing records as-is. Login stays poll-driven either way, so dropped sessions are still re-established on the next poll. The default (1) keeps the current re-discover-on-login behavior. Static iscsi-node-map configurations already bypass discovery, so the flag has no effect there. Signed-off-by: Dietmar Maurer --- src/PVE/Storage/ISCSIPlugin.pm | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/PVE/Storage/ISCSIPlugin.pm b/src/PVE/Storage/ISCSIPlugin.pm index 85f33aa..33197b9 100644 --- a/src/PVE/Storage/ISCSIPlugin.pm +++ b/src/PVE/Storage/ISCSIPlugin.pm @@ -276,12 +276,12 @@ sub iscsi_discovery { } sub iscsi_login { - my ($target, $portals, $cache, $static) = @_; + my ($target, $portals, $cache, $skip_discovery) = @_; assert_iscsi_support(); - # static configurations have their node db records synced already - if (!$static) { + # skipped when the node db records for the target already exist + if (!$skip_discovery) { eval { iscsi_discovery($target, $portals, $cache); }; warn $@ if $@; } @@ -573,6 +573,15 @@ sub properties { format => $iscsi_node_map_fmt, }, }, + 'periodic-discovery' => { + description => "Re-run sendtargets discovery before every login (default)." + . " When disabled, discovery only runs when the node database has no" + . " record for the target, and logins use the existing records as-is." + . " Has no effect when a static iscsi-node-map configuration applies.", + type => 'boolean', + default => 1, + optional => 1, + }, }; } @@ -581,6 +590,7 @@ sub options { portal => { fixed => 1 }, target => { fixed => 1 }, 'iscsi-node-map' => { optional => 1 }, + 'periodic-discovery' => { optional => 1 }, nodes => { optional => 1 }, disable => { optional => 1 }, content => { optional => 1 }, @@ -716,16 +726,22 @@ sub activate_storage { my $node_targets = get_node_targets($scfg); my $static = $node_targets->{static}; + my $periodic_discovery = $scfg->{'periodic-discovery'} // 1; for my $node_target (@{ $node_targets->{targets} }) { my ($target, $portals) = ($node_target->{target}, $node_target->{portals}); + my $skip_discovery = $static; if ($static) { iscsi_sync_node_records($target, $portals, $cache); } else { # fall back to the configured discovery address on an empty node db my $recorded = iscsi_portals($target); - $portals = $recorded if scalar(@$recorded); + if (scalar(@$recorded)) { + $portals = $recorded; + # seed-once mode: the node db already holds records for this target + $skip_discovery = 1 if !$periodic_discovery; + } } my $sessions = iscsi_session($cache, $target); @@ -745,7 +761,7 @@ sub activate_storage { } if ($do_login) { - eval { iscsi_login($target, $portals, $cache, $static); }; + eval { iscsi_login($target, $portals, $cache, $skip_discovery); }; warn $@ if $@; } else { # make sure we get all devices -- 2.47.3