[pve-devel] [PATCH v3 qemu-server 5/8] refactor: extract QEMU machine related helpers to package

Stefan Reiter s.reiter at proxmox.com
Mon Nov 4 14:57:30 CET 2019


...PVE::QemuServer::Machine.

qemu_machine_feature_enabled is exported since it has a *lot* of users
in PVE::QemuServer and a long enough name as it is.

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

I left the code exporting qemu_machine_feature_enabled from v2 and only remove
it in the next patch, just to make sure this patch works standalone as well.

 PVE/QemuConfig.pm         |   3 +-
 PVE/QemuMigrate.pm        |   3 +-
 PVE/QemuServer.pm         | 103 +++-----------------------------------
 PVE/QemuServer/Machine.pm | 102 +++++++++++++++++++++++++++++++++++++
 PVE/QemuServer/Makefile   |   1 +
 PVE/VZDump/QemuServer.pm  |   3 +-
 6 files changed, 117 insertions(+), 98 deletions(-)
 create mode 100644 PVE/QemuServer/Machine.pm

diff --git a/PVE/QemuConfig.pm b/PVE/QemuConfig.pm
index e2e722d..48b7a7c 100644
--- a/PVE/QemuConfig.pm
+++ b/PVE/QemuConfig.pm
@@ -8,6 +8,7 @@ use PVE::INotify;
 use PVE::QemuServer::Helpers;
 use PVE::QemuServer::Monitor qw(mon_cmd);
 use PVE::QemuServer;
+use PVE::QemuServer::Machine;
 use PVE::Storage;
 use PVE::Tools;
 
@@ -160,7 +161,7 @@ sub __snapshot_save_vmstate {
     $name .= ".raw" if $scfg->{path}; # add filename extension for file base storage
 
     my $statefile = PVE::Storage::vdisk_alloc($storecfg, $target, $vmid, 'raw', $name, $size*1024);
-    my $runningmachine = PVE::QemuServer::get_current_qemu_machine($vmid);
+    my $runningmachine = PVE::QemuServer::Machine::get_current_qemu_machine($vmid);
 
     if ($suspend) {
 	$conf->{vmstate} = $statefile;
diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm
index ce06af0..20cf473 100644
--- a/PVE/QemuMigrate.pm
+++ b/PVE/QemuMigrate.pm
@@ -11,6 +11,7 @@ use PVE::Tools;
 use PVE::Cluster;
 use PVE::Storage;
 use PVE::QemuServer;
+use PVE::QemuServer::Machine;
 use PVE::QemuServer::Monitor qw(mon_cmd);
 use Time::HiRes qw( usleep );
 use PVE::RPCEnvironment;
@@ -216,7 +217,7 @@ sub prepare {
 	die "can't migrate running VM without --online\n" if !$online;
 	$running = $pid;
 
-	$self->{forcemachine} = PVE::QemuServer::qemu_machine_pxe($vmid, $conf);
+	$self->{forcemachine} = PVE::QemuServer::Machine::qemu_machine_pxe($vmid, $conf);
 
     }
     my $loc_res = PVE::QemuServer::check_local_resources($conf, 1);
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 5b5de10..da6c7bb 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -41,6 +41,7 @@ use PVE::QMPClient;
 use PVE::QemuConfig;
 use PVE::QemuServer::Helpers;
 use PVE::QemuServer::Cloudinit;
+use PVE::QemuServer::Machine qw(qemu_machine_feature_enabled);
 use PVE::QemuServer::Memory;
 use PVE::QemuServer::Monitor qw(mon_cmd);
 use PVE::QemuServer::PCI qw(print_pci_addr print_pcie_addr print_pcie_root_port);
@@ -1827,20 +1828,14 @@ sub path_is_scsi {
     return $res;
 }
 
-sub machine_type_is_q35 {
-    my ($conf) = @_;
-
-    return $conf->{machine} && ($conf->{machine} =~ m/q35/) ? 1 : 0;
-}
-
 sub print_tabletdevice_full {
     my ($conf, $arch) = @_;
 
-    my $q35 = machine_type_is_q35($conf);
+    my $q35 = PVE::QemuServer::Machine::machine_type_is_q35($conf);
 
     # we use uhci for old VMs because tablet driver was buggy in older qemu
     my $usbbus;
-    if (machine_type_is_q35($conf) || $arch eq 'aarch64') {
+    if (PVE::QemuServer::Machine::machine_type_is_q35($conf) || $arch eq 'aarch64') {
 	$usbbus = 'ehci';
     } else {
 	$usbbus = 'uhci';
@@ -2189,7 +2184,7 @@ sub print_vga_device {
 	$memory = ",ram_size=67108864,vram_size=33554432";
     }
 
-    my $q35 = machine_type_is_q35($conf);
+    my $q35 = PVE::QemuServer::Machine::machine_type_is_q35($conf);
     my $vgaid = "vga" . ($id // '');
     my $pciaddr;
 
@@ -3486,7 +3481,7 @@ sub config_to_command {
 
     die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
 
-    my $q35 = machine_type_is_q35($conf);
+    my $q35 = PVE::QemuServer::Machine::machine_type_is_q35($conf);
     my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
     my $use_old_bios_files = undef;
     ($use_old_bios_files, $machine_type) = qemu_use_old_bios_files($machine_type);
@@ -4120,7 +4115,7 @@ sub vm_devices_list {
 sub vm_deviceplug {
     my ($storecfg, $conf, $vmid, $deviceid, $device, $arch, $machine_type) = @_;
 
-    my $q35 = machine_type_is_q35($conf);
+    my $q35 = PVE::QemuServer::Machine::machine_type_is_q35($conf);
 
     my $devices_list = vm_devices_list($vmid);
     return 1 if defined($devices_list->{$deviceid});
@@ -4196,7 +4191,7 @@ sub vm_deviceplug {
 
 	return undef if !qemu_netdevadd($vmid, $conf, $arch, $device, $deviceid);
 
-	my $machine_type = PVE::QemuServer::qemu_machine_pxe($vmid, $conf);
+	my $machine_type = PVE::QemuServer::Machine::qemu_machine_pxe($vmid, $conf);
 	my $use_old_bios_files = undef;
 	($use_old_bios_files, $machine_type) = qemu_use_old_bios_files($machine_type);
 
@@ -4510,7 +4505,7 @@ sub qemu_usb_hotplug {
 sub qemu_cpu_hotplug {
     my ($vmid, $conf, $vcpus) = @_;
 
-    my $machine_type = PVE::QemuServer::get_current_qemu_machine($vmid);
+    my $machine_type = PVE::QemuServer::Machine::get_current_qemu_machine($vmid);
 
     my $sockets = 1;
     $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
@@ -6975,94 +6970,12 @@ sub clone_disk {
     return $disk;
 }
 
-# this only works if VM is running
-sub get_current_qemu_machine {
-    my ($vmid) = @_;
-
-    my $res = mon_cmd($vmid, "query-machines");
-
-    my ($current, $default);
-    foreach my $e (@$res) {
-	$default = $e->{name} if $e->{'is-default'};
-	$current = $e->{name} if $e->{'is-current'};
-    }
-
-    # fallback to the default machine if current is not supported by qemu
-    return $current || $default || 'pc';
-}
-
 sub get_running_qemu_version {
     my ($vmid) = @_;
     my $res = mon_cmd($vmid, "query-version");
     return "$res->{qemu}->{major}.$res->{qemu}->{minor}";
 }
 
-sub qemu_machine_feature_enabled {
-    my ($machine, $kvmver, $version_major, $version_minor) = @_;
-
-    my $current_major;
-    my $current_minor;
-
-    if ($machine && $machine =~ m/^((?:pc(-i440fx|-q35)?|virt)-(\d+)\.(\d+))/) {
-
-	$current_major = $3;
-	$current_minor = $4;
-
-    } elsif ($kvmver =~ m/^(\d+)\.(\d+)/) {
-
-	$current_major = $1;
-	$current_minor = $2;
-    }
-
-    return 1 if version_cmp($current_major, $version_major, $current_minor, $version_minor) >= 0;
-}
-
-# gets in pairs the versions you want to compares, i.e.:
-# ($a-major, $b-major, $a-minor, $b-minor, $a-extra, $b-extra, ...)
-# returns 0 if same, -1 if $a is older than $b, +1 if $a is newer than $b
-sub version_cmp {
-    my @versions = @_;
-
-    my $size = scalar(@versions);
-
-    return 0 if $size == 0;
-    die "cannot compare odd count of versions" if $size & 1;
-
-    for (my $i = 0; $i < $size; $i += 2) {
-	my ($a, $b) = splice(@versions, 0, 2);
-	$a //= 0;
-	$b //= 0;
-
-	return 1 if $a > $b;
-	return -1 if $a < $b;
-    }
-    return 0;
-}
-
-# dies if a) VM not running or not exisiting b) Version query failed
-# So, any defined return value is valid, any invalid state can be caught by eval
-sub runs_at_least_qemu_version {
-    my ($vmid, $major, $minor, $extra) = @_;
-
-    my $v = mon_cmd($vmid, "query-version");
-    die "could not query currently running version for VM $vmid\n" if !defined($v);
-    $v = $v->{qemu};
-
-    return version_cmp($v->{major}, $major, $v->{minor}, $minor, $v->{micro}, $extra) >= 0;
-}
-
-sub qemu_machine_pxe {
-    my ($vmid, $conf) = @_;
-
-    my $machine =  PVE::QemuServer::get_current_qemu_machine($vmid);
-
-    if ($conf->{machine} && $conf->{machine} =~ m/\.pxe$/) {
-	$machine .= '.pxe';
-    }
-
-    return $machine;
-}
-
 sub qemu_use_old_bios_files {
     my ($machine_type) = @_;
 
diff --git a/PVE/QemuServer/Machine.pm b/PVE/QemuServer/Machine.pm
new file mode 100644
index 0000000..d47f4e4
--- /dev/null
+++ b/PVE/QemuServer/Machine.pm
@@ -0,0 +1,102 @@
+package PVE::QemuServer::Machine;
+
+use strict;
+use warnings;
+
+use PVE::QemuConfig;
+use PVE::QemuServer::Monitor;
+
+use base 'Exporter';
+our @EXPORT_OK = qw(
+qemu_machine_feature_enabled
+);
+
+sub machine_type_is_q35 {
+    my ($conf) = @_;
+
+    return $conf->{machine} && ($conf->{machine} =~ m/q35/) ? 1 : 0;
+}
+
+# this only works if VM is running
+sub get_current_qemu_machine {
+    my ($vmid) = @_;
+
+    my $res = PVE::QemuServer::Monitor::mon_cmd($vmid, 'query-machines');
+
+    my ($current, $default);
+    foreach my $e (@$res) {
+	$default = $e->{name} if $e->{'is-default'};
+	$current = $e->{name} if $e->{'is-current'};
+    }
+
+    # fallback to the default machine if current is not supported by qemu
+    return $current || $default || 'pc';
+}
+
+sub qemu_machine_feature_enabled {
+    my ($machine, $kvmver, $version_major, $version_minor) = @_;
+
+    my $current_major;
+    my $current_minor;
+
+    if ($machine && $machine =~ m/^((?:pc(-i440fx|-q35)?|virt)-(\d+)\.(\d+))/) {
+
+	$current_major = $3;
+	$current_minor = $4;
+
+    } elsif ($kvmver =~ m/^(\d+)\.(\d+)/) {
+
+	$current_major = $1;
+	$current_minor = $2;
+    }
+
+    return 1 if version_cmp($current_major, $version_major, $current_minor, $version_minor) >= 0;
+}
+
+# gets in pairs the versions you want to compares, i.e.:
+# ($a-major, $b-major, $a-minor, $b-minor, $a-extra, $b-extra, ...)
+# returns 0 if same, -1 if $a is older than $b, +1 if $a is newer than $b
+sub version_cmp {
+    my @versions = @_;
+
+    my $size = scalar(@versions);
+
+    return 0 if $size == 0;
+    die "cannot compare odd count of versions" if $size & 1;
+
+    for (my $i = 0; $i < $size; $i += 2) {
+	my ($a, $b) = splice(@versions, 0, 2);
+	$a //= 0;
+	$b //= 0;
+
+	return 1 if $a > $b;
+	return -1 if $a < $b;
+    }
+    return 0;
+}
+
+# dies if a) VM not running or not exisiting b) Version query failed
+# So, any defined return value is valid, any invalid state can be caught by eval
+sub runs_at_least_qemu_version {
+    my ($vmid, $major, $minor, $extra) = @_;
+
+    my $v = PVE::QemuServer::Monitor::mon_cmd($vmid, 'query-version');
+    die "could not query currently running version for VM $vmid\n" if !defined($v);
+    $v = $v->{qemu};
+
+    return version_cmp($v->{major}, $major, $v->{minor}, $minor, $v->{micro}, $extra) >= 0;
+}
+
+sub qemu_machine_pxe {
+    my ($vmid, $conf) = @_;
+
+    my $machine =  get_current_qemu_machine($vmid);
+
+    if ($conf->{machine} && $conf->{machine} =~ m/\.pxe$/) {
+	$machine .= '.pxe';
+    }
+
+    return $machine;
+}
+
+1;
diff --git a/PVE/QemuServer/Makefile b/PVE/QemuServer/Makefile
index 02b0209..670105a 100644
--- a/PVE/QemuServer/Makefile
+++ b/PVE/QemuServer/Makefile
@@ -7,6 +7,7 @@ SOURCES=PCI.pm		\
 	Agent.pm	\
 	Helpers.pm	\
 	Monitor.pm	\
+	Machine.pm	\
 
 .PHONY: install
 install: ${SOURCES}
diff --git a/PVE/VZDump/QemuServer.pm b/PVE/VZDump/QemuServer.pm
index 4322cb8..1902b2f 100644
--- a/PVE/VZDump/QemuServer.pm
+++ b/PVE/VZDump/QemuServer.pm
@@ -18,6 +18,7 @@ use PVE::Tools;
 use PVE::VZDump;
 
 use PVE::QemuServer;
+use PVE::QemuServer::Machine;
 use PVE::QemuServer::Monitor qw(mon_cmd);
 
 use base qw (PVE::VZDump::Plugin);
@@ -78,7 +79,7 @@ sub prepare {
 	    $self->loginfo("exclude disk '$ds' '$volid' (backup=no)");
 	    return;
 	} elsif ($self->{vm_was_running} && $drive->{iothread}) {
-	    if (!PVE::QemuServer::runs_at_least_qemu_version($vmid, 4, 0, 1)) {
+	    if (!PVE::QemuServer::Machine::runs_at_least_qemu_version($vmid, 4, 0, 1)) {
 		die "disk '$ds' '$volid' (iothread=on) can't use backup feature with running QEMU " .
 		    "version < 4.0.1! Either set backup=no for this drive or upgrade QEMU and restart VM\n";
 	    }
-- 
2.20.1





More information about the pve-devel mailing list