From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 373371FF0AA for ; Tue, 03 Nov 2026 19:57:13 +0100 (CET) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 978F82167D; Tue, 03 Nov 2026 19:56:46 +0100 (CET) From: Hannes Laimer To: pve-devel@lists.proxmox.com Subject: [PATCH qemu-server v4 10/13] network: sdn: push the DHCP mappings of a guest when it resumes Date: Tue, 3 Nov 2026 19:55:56 +0100 Message-ID: <20261103185559.420277-11-h.laimer@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261103185559.420277-1-h.laimer@proxmox.com> References: <20261103185559.420277-1-h.laimer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1793732175856 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.321 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) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: ENXHVYTWWSBYES4ESWGP5VVBNJJTGOPF X-Message-ID-Hash: ENXHVYTWWSBYES4ESWGP5VVBNJJTGOPF X-MailFrom: h.laimer@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: A mapping edit and a migration of the guest exclude each other, but an edit through a node not yet upgraded takes no lock and writes no reservation, so it can land while the guest is migrated. Every resume now pushes the mapping of each NIC of the guest on the local node before the guest continues, and the last step of a live migration resumes the target after the config moved, so the target serves what the cache vouches for. The push reads the cache only and asks the IPAM for nothing, so the paused guest waits on no request. Signed-off-by: Hannes Laimer --- src/PVE/QemuServer/Network.pm | 17 +++++++++++++++++ src/PVE/QemuServer/RunState.pm | 2 ++ 2 files changed, 19 insertions(+) diff --git a/src/PVE/QemuServer/Network.pm b/src/PVE/QemuServer/Network.pm index b4893c015646..b063f5b75b36 100644 --- a/src/PVE/QemuServer/Network.pm +++ b/src/PVE/QemuServer/Network.pm @@ -272,6 +272,23 @@ sub add_random_macs { } } +# every resume pushes the current mapping of each NIC, so the target of a +# live migration, resumed after the config moved, holds what the cache +# vouches for. The push takes it from the cache and asks the IPAM for +# nothing, so the paused guest waits on no request +sub add_nets_dhcp_mapping { + my ($conf) = @_; + + for my $opt (keys %$conf) { + next if $opt !~ m/^net\d+$/; + my $net = parse_net($conf->{$opt}, 1) or next; + next if !$net->{bridge} || !$net->{macaddr}; + # a resume does not fail on its DHCP backend + eval { PVE::Network::SDN::Dhcp::update_mapping($net->{bridge}, $net->{macaddr}, 1) }; + warn $@ if $@; + } +} + sub add_nets_bridge_fdb { my ($conf, $vmid) = @_; diff --git a/src/PVE/QemuServer/RunState.pm b/src/PVE/QemuServer/RunState.pm index 889ddd28287b..828d79159e90 100644 --- a/src/PVE/QemuServer/RunState.pm +++ b/src/PVE/QemuServer/RunState.pm @@ -181,6 +181,8 @@ sub vm_resume($vmid, $skiplock = undef, $nocheck = undef) { PVE::QemuServer::Network::add_nets_bridge_fdb($conf, $vmid) if $resume_cmd eq 'cont'; + PVE::QemuServer::Network::add_nets_dhcp_mapping($conf) + if $resume_cmd eq 'cont'; mon_cmd($vmid, $resume_cmd); }, -- 2.47.3