[pve-devel] [PATCH qemu-server 07/11] refactor: extract QEMU machine related helpers to package
Stefan Reiter
s.reiter at proxmox.com
Mon Oct 28 11:36:39 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>
---
Not sure if PVE::QemuMachine wouldn't be a better package name. I'm fine with
both (or other suggestions), if someone has preferences.
PVE/QemuConfig.pm | 3 +-
PVE/QemuMigrate.pm | 3 +-
PVE/QemuServer.pm | 101 +++-----------------------------------
PVE/QemuServer/Machine.pm | 100 +++++++++++++++++++++++++++++++++++++
PVE/QemuServer/Makefile | 1 +
PVE/VZDump/QemuServer.pm | 3 +-
6 files changed, 115 insertions(+), 96 deletions(-)
create mode 100644 PVE/QemuServer/Machine.pm
diff --git a/PVE/QemuConfig.pm b/PVE/QemuConfig.pm
index bcad9c8..0a7f1ab 100644
--- a/PVE/QemuConfig.pm
+++ b/PVE/QemuConfig.pm
@@ -10,6 +10,7 @@ use PVE::INotify;
use PVE::ProcFSTools;
use PVE::QemuSchema;
use PVE::QemuServer;
+use PVE::QemuServer::Machine;
use PVE::QMP qw(vm_mon_cmd vm_mon_cmd_nocheck);
use PVE::Storage;
use PVE::Tools;
@@ -149,7 +150,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 aea7eac..9ac78f8 100644
--- a/PVE/QemuMigrate.pm
+++ b/PVE/QemuMigrate.pm
@@ -12,6 +12,7 @@ use PVE::Cluster;
use PVE::Storage;
use PVE::QemuConfig;
use PVE::QemuServer;
+use PVE::QemuServer::Machine;
use PVE::QMP qw(vm_mon_cmd vm_mon_cmd_nocheck);
use Time::HiRes qw( usleep );
use PVE::RPCEnvironment;
@@ -217,7 +218,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 bf696a7..e026a10 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -43,6 +43,7 @@ use PVE::QMPClient;
use PVE::QemuConfig;
use PVE::QemuSchema;
use PVE::QemuServer::Cloudinit;
+use PVE::QemuServer::Machine qw(qemu_machine_feature_enabled);
use PVE::QemuServer::Memory;
use PVE::QemuServer::PCI qw(print_pci_addr print_pcie_addr print_pcie_root_port);
use PVE::QemuServer::USB qw(parse_usb_device);
@@ -1828,20 +1829,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';
@@ -2190,7 +2185,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;
@@ -3479,7 +3474,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);
@@ -4113,7 +4108,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});
@@ -4189,7 +4184,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);
@@ -4503,7 +4498,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
@@ -6987,23 +6982,6 @@ sub clone_disk {
return $disk;
}
-# this only works if VM is running
-sub get_current_qemu_machine {
- my ($vmid) = @_;
-
- my $cmd = { execute => 'query-machines', arguments => {} };
- my $res = vm_qmp_command($vmid, $cmd);
-
- 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 $cmd = { execute => 'query-version', arguments => {} };
@@ -7011,69 +6989,6 @@ sub get_running_qemu_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;
-}
-
-sub runs_at_least_qemu_version {
- my ($vmid, $major, $minor, $extra) = @_;
-
- my $v = eval { vm_qmp_command($vmid, { execute => 'query-version' }) } // {};
- $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..2602e5f
--- /dev/null
+++ b/PVE/QemuServer/Machine.pm
@@ -0,0 +1,100 @@
+package PVE::QemuServer::Machine;
+
+use strict;
+use warnings;
+
+use PVE::QemuConfig;
+use PVE::QMP qw(vm_qmp_command);
+
+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 $cmd = { execute => 'query-machines', arguments => {} };
+ my $res = vm_qmp_command($vmid, $cmd);
+
+ 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;
+}
+
+sub runs_at_least_qemu_version {
+ my ($vmid, $major, $minor, $extra) = @_;
+
+ my $v = eval { vm_qmp_command($vmid, { execute => 'query-version' }) } // {};
+ $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 afc39a3..35380c3 100644
--- a/PVE/QemuServer/Makefile
+++ b/PVE/QemuServer/Makefile
@@ -5,6 +5,7 @@ SOURCES=PCI.pm \
OVF.pm \
Cloudinit.pm \
Agent.pm \
+ Machine.pm \
.PHONY: install
install: ${SOURCES}
diff --git a/PVE/VZDump/QemuServer.pm b/PVE/VZDump/QemuServer.pm
index dc6b29a..f8a2f81 100644
--- a/PVE/VZDump/QemuServer.pm
+++ b/PVE/VZDump/QemuServer.pm
@@ -19,6 +19,7 @@ use PVE::VZDump;
use PVE::QemuConfig;
use PVE::QemuServer;
+use PVE::QemuServer::Machine;
use PVE::QMP qw(vm_mon_cmd);
use base qw (PVE::VZDump::Plugin);
@@ -79,7 +80,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