[pve-devel] avoiding VMID reuse
Lauri Tirkkonen
lauri at tuxera.com
Mon Mar 12 15:13:59 CET 2018
Hi,
we'd like to keep VMIDs always unique per node, so that we can use zfs
for backups more easily (ie. avoid dataset name collisions; granted,
this still leaves room for collisions if disks are removed and added to
a VM). We've implemented the following (crappy) PoC that accomplishes
just this by storing the highest allocated VMID and returning that for
/cluster/nextid.
The patches are across four repositories, so I'm attaching four files
named by repository.
-------------- next part --------------
diff --git a/data/PVE/Cluster.pm b/data/PVE/Cluster.pm
index b49fd94..fea0639 100644
--- a/data/PVE/Cluster.pm
+++ b/data/PVE/Cluster.pm
@@ -996,6 +996,19 @@ sub log_msg {
syslog("err", "writing cluster log failed: $@") if $@;
}
+sub alloc_vmid {
+ my ($vmid) = @_;
+ check_vmid_unused($vmid);
+ open(my $fh, '+<', '/etc/pve/local/nextid');
+ my $next = 0 + readline($fh);
+ if ($vmid >= $next) {
+ $next = 1 + $vmid;
+ seek($fh, 0, 0);
+ print $fh "$next";
+ }
+ close($fh);
+}
+
sub check_vmid_unused {
my ($vmid, $noerr) = @_;
-------------- next part --------------
diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm
index 733826e..9accfdb 100644
--- a/src/PVE/API2/LXC.pm
+++ b/src/PVE/API2/LXC.pm
@@ -337,6 +337,7 @@ __PACKAGE__->register_method({
die "Could not reserve ID $vmid, already taken\n" if $@;
}
+ PVE::Cluster::alloc_vmid($vmid);
PVE::Cluster::check_cfs_quorum();
my $vollist = [];
-------------- next part --------------
diff --git a/PVE/API2/Cluster.pm b/PVE/API2/Cluster.pm
index 7f38e61c..590f4fb7 100644
--- a/PVE/API2/Cluster.pm
+++ b/PVE/API2/Cluster.pm
@@ -505,11 +505,13 @@ __PACKAGE__->register_method({
raise_param_exc({ vmid => "VM $vmid already exists" });
}
- for (my $i = 100; $i < 10000; $i++) {
- return $i if !defined($idlist->{$i});
- }
-
- die "unable to get any free VMID\n";
+ open(my $fh, '<', '/etc/pve/local/nextid');
+ my $i = 0 + readline($fh);
+ close($fh);
+ if (defined($idlist->{$i})) {
+ die "unable to get any free VMID\n";
+ }
+ return $i;
}});
1;
-------------- next part --------------
diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 0174feb..358d539 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -558,6 +558,7 @@ __PACKAGE__->register_method({
# test after locking
PVE::Cluster::check_vmid_unused($vmid);
+ PVE::Cluster::alloc_vmid($vmid);
# ensure no old replication state are exists
PVE::ReplicationState::delete_guest_states($vmid);
More information about the pve-devel
mailing list