[pve-devel] [PATCH v2 qemu-server 06/12] Verify VM-specific CPU configs seperately

Stefan Reiter s.reiter at proxmox.com
Mon Sep 30 12:58:49 CEST 2019


$cpu_fmt is being reused for custom CPUs as well as VM-specific CPU
settings. The "pve-vm-cpu-conf" format is introduced to verify a config
specifically for use as VM-specific settings.

Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---
 PVE/QemuServer.pm           |  2 +-
 PVE/QemuServer/CPUConfig.pm | 68 +++++++++++++++++++++++++++++++++++--
 2 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index a95006f..abf5578 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -505,7 +505,7 @@ EODESCR
 	optional => 1,
 	description => "Emulated CPU type.",
 	type => 'string',
-	format => $PVE::QemuServer::CPUConfig::cpu_fmt,
+	format => 'pve-vm-cpu-conf',
     },
     parent => get_standard_option('pve-snapshot-name', {
 	optional => 1,
diff --git a/PVE/QemuServer/CPUConfig.pm b/PVE/QemuServer/CPUConfig.pm
index 125b636..61bd024 100644
--- a/PVE/QemuServer/CPUConfig.pm
+++ b/PVE/QemuServer/CPUConfig.pm
@@ -87,9 +87,9 @@ my @supported_cpu_flags = (
     'hv-evmcs',
     'aes'
 );
-my $cpu_flag = qr/[+-](@{[join('|', @supported_cpu_flags)]})/;
+my $cpu_flag_re = qr/([+-])(@{[join('|', @supported_cpu_flags)]})/;
 
-our $cpu_fmt = {
+my $cpu_fmt = {
     cputype => {
 	description => "Emulated CPU type. Can be default or custom name.",
 	type => 'string',
@@ -139,6 +139,70 @@ our $cpu_fmt = {
     },
 };
 
+# $cpu_fmt describes both the CPU config passed as part of a VM config, as well
+# as the definition of a custom CPU model. There are some slight differences
+# though, which we catch in the custom verification function below.
+sub verify_cpu_conf_basic {
+    my ($cpu, $noerr) = @_;
+
+    eval {
+        $cpu = PVE::JSONSchema::parse_property_string($cpu_fmt, $cpu);
+    };
+    if ($@) {
+        die $@ if !$noerr;
+        return undef;
+    }
+
+    # required, but can't be made "optional => 0" since it's not included as a
+    # seperate property in config file
+    if (!$cpu->{cputype}) {
+	die "CPU is missing cputype\n" if !$noerr;
+	return undef;
+    }
+
+    return $cpu;
+}
+
+PVE::JSONSchema::register_format('pve-vm-cpu-conf', \&verify_vm_cpu_conf);
+sub verify_vm_cpu_conf {
+    my ($cpu, $noerr) = @_;
+
+    $cpu = verify_cpu_conf_basic($cpu, $noerr);
+    return undef if !$cpu;
+
+    my $cputype = $cpu->{cputype};
+
+    # Model must exist
+    if ($cpu->{custom}) {
+	my $config = load_custom_model_conf();
+	return $cpu if $config && defined($config->{ids}->{$cputype});
+
+	die "Custom cputype '$cputype' not found\n" if !$noerr;
+	return undef;
+    } else {
+	return $cpu if defined($cpu_vendor_list->{$cputype});
+
+	die "Default cputype '$cputype' not found\n" if !$noerr;
+	return undef;
+    }
+
+    if ($cpu->{flags} && $cpu->{flags} !~ m/$cpu_flag_re(;$cpu_flag_re)*/) {
+	die "VM-specific CPU flags must be a subset of: @{[join(', ', @supported_cpu_flags)]}\n"
+	    if !$noerr;
+	return undef;
+    }
+
+    for my $prop (keys %$cpu) {
+	if ($cpu->{$prop}->{custom_only}) {
+	    die "Property '$prop' not allowed in VM-specific CPU config.\n"
+		if !$noerr;
+	    return undef;
+	}
+    }
+
+    return $cpu;
+}
+
 # Section config settings
 my $defaultData = {
     # shallow copy, since SectionConfig modifies propertyList internally
-- 
2.20.1





More information about the pve-devel mailing list