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 37C311FF09B for ; Mon, 12 Oct 2026 17:46:33 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id ECCA721618; Mon, 12 Oct 2026 17:46:14 +0200 (CEST) From: =?UTF-8?q?Michael=20K=C3=B6ppl?= To: pve-devel@lists.proxmox.com Subject: [PATCH guest-common v8 10/22] guest id: optionally enforce the next-id range and uniqueness Date: Mon, 12 Oct 2026 17:45:48 +0200 Message-ID: <20261012154600.877830-11-m.koeppl@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261012154600.877830-1-m.koeppl@proxmox.com> References: <20261012154600.877830-1-m.koeppl@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1791819968688 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.283 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: GMZ5W3Q2JGJOGOKQIUOQS5XW7WEPLF7I X-Message-ID-Hash: GMZ5W3Q2JGJOGOKQIUOQS5XW7WEPLF7I X-MailFrom: m.koeppl@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: If the 'enforce' subproperty of next-id is enabled, ensure that only guest IDs from the configured range and, if unique is enabled as well, only previously unused IDs can be used. Actions on existing guests, such as destroy, remote migration with --delete, and restore over an existing guest, are always exempt from enforcement. A guest counts as existing if its config is present in the cluster. IDs are recorded before a guest exists and stay recorded if its creation fails later. With both 'enforce' and 'unique' set, retrying a failed creation with the same ID is therefore rejected. Signed-off-by: Michael Köppl Reviewed-by: Fiona Ebner Tested-by: Fiona Ebner --- src/PVE/GuestID.pm | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/PVE/GuestID.pm b/src/PVE/GuestID.pm index 0494913..83876db 100644 --- a/src/PVE/GuestID.pm +++ b/src/PVE/GuestID.pm @@ -192,25 +192,47 @@ my sub insert_id($ranges, $id) { return 1; } +my sub assert_id_in_next_id_range($next_id_opts, $id) { + my $lower = $next_id_opts->{lower}; + my $upper = $next_id_opts->{upper}; + + die "guest ID $id is below the lower boundary $lower of the next-id range\n" + if defined($lower) && $id < $lower; + die "guest ID $id is not below the upper boundary $upper of the next-id range\n" + if defined($upper) && $id >= $upper; +} + +# Records $id as used. If the next-id datacenter option enforces its +# range or uniqueness, IDs a new guest must not use are rejected. +# IDs of currently existing guests are never rejected. sub register_used_id($id) { - cfs_lock_file( + my $next_id_opts = cfs_read_file('datacenter.cfg')->{'next-id'} // {}; + my $enforce = $next_id_opts->{enforce} && PVE::Cluster::check_vmid_unused($id, 1); + + assert_id_in_next_id_range($next_id_opts, $id) if $enforce; + + my $recorded = cfs_lock_file( $FILENAME, 10, sub { my $ranges = cfs_read_file($FILENAME); - return if !insert_id($ranges, $id); + return 0 if !insert_id($ranges, $id); cfs_write_file($FILENAME, $ranges); + return 1; }, ); if (my $err = $@) { - my $dc_conf = cfs_read_file('datacenter.cfg'); - my $emsg = "unable to record guest ID $id as used"; - die "$emsg - $err" if $dc_conf->{'next-id'}->{unique}; + die "$emsg - $err" if $next_id_opts->{unique}; warn "$emsg - $err"; + + return; } + + die "guest ID $id was used before\n" + if $enforce && $next_id_opts->{unique} && !$recorded; } cfs_register_file($FILENAME, \&parse_id_list, \&write_id_list); -- 2.47.3