[pve-devel] [PATCH qemu-server 4/7] Add CustomCPUConfig for storing/parsing custom CPU models

Stefan Reiter s.reiter at proxmox.com
Mon Sep 2 16:27:56 CEST 2019


Inherits from SectionConfig to provide base parsing infrastructure.

Use with helper functions:
* config_from_file gives bless'd config
* get_model_by_name returns a "formatted" hash for a single CPU model
* config_to_file writes changes back

File reads are cached in a local hash.

Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---

This will definitely require some sort of versioning mechanism, otherwise CPU
definitions could be changed after starting a VM, thus breaking live-migration
by starting the migration-target with different parameters.

Hints, ideas, recommendations?


 PVE/QemuServer/CustomCPUConfig.pm | 129 ++++++++++++++++++++++++++++++
 PVE/QemuServer/Makefile           |   1 +
 2 files changed, 130 insertions(+)
 create mode 100644 PVE/QemuServer/CustomCPUConfig.pm

diff --git a/PVE/QemuServer/CustomCPUConfig.pm b/PVE/QemuServer/CustomCPUConfig.pm
new file mode 100644
index 0000000..87ba9e6
--- /dev/null
+++ b/PVE/QemuServer/CustomCPUConfig.pm
@@ -0,0 +1,129 @@
+package PVE::QemuServer::CustomCPUConfig;
+
+use strict;
+use warnings;
+use PVE::Tools qw(file_get_contents file_set_contents);
+
+use base qw(PVE::SectionConfig);
+
+my $defaultData = {
+    propertyList => {
+	basemodel => {
+	    description => "Emulated CPU type to inherit defaults from.",
+	    type => 'string',
+	    format_description => 'string',
+	    default => 'kvm64',
+	},
+	flags => {
+	    description => "List of additional CPU flags separated by ';'."
+			 . " Use '+FLAG' to enable, '-FLAG' to disable a flag."
+			 . " Supports all flags supported by QEMU/KVM.",
+	    format_description => '+FLAG[;-FLAG...]',
+	    type => 'string',
+	    pattern => qr/[+-][a-zA-Z0-9\-_\.]+(;[+-][a-zA-Z0-9\-_\.]+)*/,
+	    optional => 1,
+	},
+	'phys-bits' => {
+	    type => 'integer',
+	    minimum => 1,
+	    maximum => 64,
+	    optional => 1,
+	    description => "The physical memory bits that are reported to the guest OS. Must be smaller or equal to the host.",
+	},
+	'host-phys-bits' => {
+	    type => 'boolean',
+	    default => 0,
+	    description => "Whether to report the host's physical memory bits. Overrides 'phys-bits' when set.",
+	},
+	vendor => {
+	    type => 'string',
+	    enum => [qw(default AuthenticAMD GenuineIntel)],
+	    default => 'default',
+	    description => "The CPU vendor to report. 'default' uses the host's.",
+	},
+    }
+};
+
+sub private {
+    return $defaultData;
+}
+
+sub options {
+    return {
+	basemodel => { optional => 1 },
+	flags => { optional => 1 },
+	'phys-bits' => { optional => 1 },
+	'host-phys-bits' => { optional => 1 },
+	vendor => { optional => 1 }
+    };
+}
+
+sub type {
+    return 'cpu-model';
+}
+
+# helpers for reading/parsing and writing/formatting of config files
+
+my $default_filename = "/etc/pve/cpu-models.conf";
+my $cfg_cache = {};
+
+sub config_from_file {
+    my ($filename) = @_;
+
+    $filename //= $default_filename;
+
+    if (my $cached = $cfg_cache->{$filename}) {
+	return $cached;
+    }
+
+    return undef if ! -e $filename;
+
+    my $raw = file_get_contents($filename);
+    my $cfg = __PACKAGE__->parse_config($filename, $raw);
+
+    bless $cfg, qw(PVE::QemuServer::CustomCPUConfig);
+    $cfg_cache->{$filename} = $cfg;
+
+    return $cfg;
+}
+
+sub config_to_file {
+    my ($class, $filename) = @_;
+
+    $filename //= $default_filename;
+
+    $cfg_cache->{$filename} = $class;
+
+    my $raw = $class->write_config($filename);
+    file_set_contents($filename, $raw);
+}
+
+# Use this to get a single model in the format described by $defaultData above
+# Includes the name as an additional property and sets default values for undefs
+# Returns undef for unknown $name
+sub get_model_by_name {
+    my ($class, $name) = @_;
+
+    return undef if !defined($class->{ids}->{$name});
+
+    my $model = {
+	name => $name
+    };
+
+    for my $property (keys %{$defaultData->{propertyList}}) {
+	next if $property eq 'type';
+
+	if (my $value = $class->{ids}->{$name}->{$property}) {
+	    $model->{$property} = $value;
+	} elsif (my $default = $defaultData->{propertyList}->{$property}->{default}) {
+	    $model->{$property} = $default;
+	}
+    }
+
+    return $model;
+}
+
+__PACKAGE__->register();
+__PACKAGE__->init();
+
+1;
diff --git a/PVE/QemuServer/Makefile b/PVE/QemuServer/Makefile
index afc39a3..41b4cb6 100644
--- a/PVE/QemuServer/Makefile
+++ b/PVE/QemuServer/Makefile
@@ -5,6 +5,7 @@ SOURCES=PCI.pm		\
 	OVF.pm		\
 	Cloudinit.pm	\
 	Agent.pm	\
+	CustomCPUConfig.pm \
 
 .PHONY: install
 install: ${SOURCES}
-- 
2.20.1





More information about the pve-devel mailing list