From: "Michael Köppl" <m.koeppl@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH pve-guest-common v5 3/7] add module to track previously used guest IDs
Date: Mon, 21 Sep 2026 17:54:06 +0200 [thread overview]
Message-ID: <20260921155410.938337-4-m.koeppl@proxmox.com> (raw)
In-Reply-To: <20260921155410.938337-1-m.koeppl@proxmox.com>
The /cluster/nextid API endpoint always suggests the lowest free
guest ID, so IDs of destroyed guests get handed out again. Offering
an opt-out requires recording every ID that has ever been in use
somewhere both the endpoint and the guest create and destroy paths
can reach.
Store them in /etc/pve/used-guest-ids and register it as a cfs file,
so the list is kept in sync cluster-wide. Consecutive IDs are
collapsed into "<start>-<end>" ranges on write to keep the file small
on clusters that churn through many guests, and expanded back into a
hash on read. Entries that do not parse, ranges with reversed bounds
included, are skipped with a warning instead of failing the whole
read.
Originally-by: Daniel Krambrock <krambrock@hrz.uni-marburg.de>
Originally-by: Severen Redwood <severen.redwood@sitehost.co.nz>
Signed-off-by: Michael Köppl <m.koeppl@proxmox.com>
---
src/Makefile | 1 +
src/PVE/UsedGuestIDs.pm | 93 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+)
create mode 100644 src/PVE/UsedGuestIDs.pm
diff --git a/src/Makefile b/src/Makefile
index 030e7f7..83e5ceb 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -14,6 +14,7 @@ install: PVE
install -m 0644 PVE/Replication.pm ${PERL5DIR}/PVE/
install -m 0644 PVE/StorageTunnel.pm ${PERL5DIR}/PVE/
install -m 0644 PVE/Tunnel.pm ${PERL5DIR}/PVE/
+ install -m 0644 PVE/UsedGuestIDs.pm ${PERL5DIR}/PVE/
install -d ${PERL5DIR}/PVE/Mapping
install -m 0644 PVE/Mapping/Dir.pm ${PERL5DIR}/PVE/Mapping/
install -m 0644 PVE/Mapping/PCI.pm ${PERL5DIR}/PVE/Mapping/
diff --git a/src/PVE/UsedGuestIDs.pm b/src/PVE/UsedGuestIDs.pm
new file mode 100644
index 0000000..31036ff
--- /dev/null
+++ b/src/PVE/UsedGuestIDs.pm
@@ -0,0 +1,93 @@
+package PVE::UsedGuestIDs;
+
+use strict;
+use warnings;
+
+use PVE::Cluster qw(
+ cfs_lock_file
+ cfs_read_file
+ cfs_register_file
+ cfs_write_file
+);
+
+my $FILENAME = 'used-guest-ids';
+
+my $parse_id_list = sub {
+ my ($filename, $raw) = @_;
+
+ my $used_ids = {};
+
+ return $used_ids if !defined($raw);
+
+ for my $line (split(/\n/, $raw)) {
+ next if $line =~ m/^\s*$/;
+
+ if ($line =~ m/^(\d+)$/) {
+ $used_ids->{$1} = 1;
+ } elsif ($line =~ m/^(\d+)-(\d+)$/) {
+ my ($start, $end) = ($1, $2);
+ if ($start > $end) {
+ warn "skipping reversed range in $filename: $line\n";
+ next;
+ }
+ $used_ids->{$_} = 1 for $start .. $end;
+ } else {
+ warn "skipping invalid entry in $filename: $line\n";
+ }
+ }
+
+ return $used_ids;
+};
+
+my $format_entry = sub {
+ my ($start, $last) = @_;
+ return $start == $last ? "$start\n" : "$start-$last\n";
+};
+
+my $write_id_list = sub {
+ my ($filename, $used_ids) = @_;
+
+ my $output = '';
+ my ($start, $last);
+
+ for my $curr (sort { $a <=> $b } keys $used_ids->%*) {
+ if (!defined($start)) {
+ ($start, $last) = ($curr, $curr);
+ } elsif ($last + 1 == $curr) {
+ $last = $curr;
+ } else {
+ $output .= $format_entry->($start, $last);
+ ($start, $last) = ($curr, $curr);
+ }
+ }
+
+ $output .= $format_entry->($start, $last) if defined($start);
+
+ return $output;
+};
+
+sub read_list {
+ return cfs_read_file($FILENAME);
+}
+
+sub add_id {
+ my ($id) = @_;
+
+ cfs_lock_file(
+ $FILENAME,
+ 10,
+ sub {
+ my $used_ids = cfs_read_file($FILENAME);
+
+ return if $used_ids->{$id};
+
+ $used_ids->{$id} = 1;
+ cfs_write_file($FILENAME, $used_ids);
+ },
+ );
+ die $@ if $@;
+}
+
+cfs_register_file($FILENAME, $parse_id_list, $write_id_list);
+
+1;
--
2.47.3
next prev parent reply other threads:[~2026-09-21 15:55 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-21 15:54 [PATCH many v5 0/7] add option to prevent suggesting previously used VMIDs Michael Köppl
2026-09-21 15:54 ` [PATCH pve-cluster v5 1/7] cluster files: add used-guest-ids Michael Köppl
2026-09-21 15:54 ` [PATCH pve-cluster v5 2/7] datacenter config: add unique-next-id to schema Michael Köppl
2026-09-21 15:54 ` Michael Köppl [this message]
2026-09-21 15:54 ` [PATCH qemu-server v5 4/7] api: record VM ID as used on creation, cloning, and destruction Michael Köppl
2026-09-21 15:54 ` [PATCH pve-container v5 5/7] api: record CT " Michael Köppl
2026-09-21 15:54 ` [PATCH pve-manager v5 6/7] close #4369: api: optionally only suggest unique IDs Michael Köppl
2026-09-21 15:54 ` [PATCH pve-manager v5 7/7] close #4369: ui: add datacenter option for unique VM/CT IDs Michael Köppl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260921155410.938337-4-m.koeppl@proxmox.com \
--to=m.koeppl@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.