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.
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) = @_;
 
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 = [];
 
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;
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);
_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to