mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-05-02 18:59:41 +00:00
implement PVE Version addition for QEMU machine
With our QEMU 4.1.1 package we can pass a additional internal version to QEMU's machine, it will be split out there and ignored, but returned on a QMP 'query-machines' call. This allows us to use it for increasing the granularity with which we can roll-out HW layout changes/additions for VMs. Until now we required a machine version bump, happening normally every major release of QEMU, with seldom, for us irrelevant, exceptions. This often delays rolling out a feature, which would break live-migration, by several months. That can now be avoided, the new "pve-version" component of the machine can be bumped at will, and thus we are much more flexible. That versions orders after the ($major, $minor) version components from an stable release - it can thus also be reset on the next release. The implementation extends the qemu-machine REGEX, remembers "pve-version" when doing a "query-machines" and integrates support into the min_version and extract_version helpers. We start out with a version of 1. Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> Reviewed-by: Stefan Reiter <s.reiter@proxmox.com>
This commit is contained in:
parent
e2414e73ce
commit
9471e48bf9
@ -93,7 +93,7 @@ PVE::JSONSchema::register_standard_option('pve-qm-image-format', {
|
||||
PVE::JSONSchema::register_standard_option('pve-qemu-machine', {
|
||||
description => "Specifies the Qemu machine type.",
|
||||
type => 'string',
|
||||
pattern => '(pc|pc(-i440fx)?-\d+(\.\d+)+(\.pxe)?|q35|pc-q35-\d+(\.\d+)+(\.pxe)?|virt(?:-\d+(\.\d+)+)?)',
|
||||
pattern => '(pc|pc(-i440fx)?-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|q35|pc-q35-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|virt(?:-\d+(\.\d+)+)?(\+pve\d+)?)',
|
||||
maxLength => 40,
|
||||
optional => 1,
|
||||
});
|
||||
@ -1875,7 +1875,7 @@ sub print_drivedevice_full {
|
||||
}
|
||||
|
||||
# for compatibility only, we prefer scsi-hd (#2408, #2355, #2380)
|
||||
my $version = PVE::QemuServer::Machine::extract_version($machine_type) // kvm_user_version();
|
||||
my $version = PVE::QemuServer::Machine::extract_version($machine_type, kvm_user_version());
|
||||
if ($path =~ m/^iscsi\:\/\// &&
|
||||
!min_version($version, 4, 1)) {
|
||||
$devicetype = 'generic';
|
||||
@ -3361,13 +3361,14 @@ my $default_machines = {
|
||||
};
|
||||
|
||||
sub get_vm_machine {
|
||||
my ($conf, $forcemachine, $arch) = @_;
|
||||
my ($conf, $forcemachine, $arch, $add_pve_version) = @_;
|
||||
|
||||
my $machine = $forcemachine || $conf->{machine};
|
||||
|
||||
if (!$machine) {
|
||||
if (!$machine || $machine =~ m/^(?:pc|q35|virt)$/) {
|
||||
$arch //= 'x86_64';
|
||||
$machine ||= $default_machines->{$arch};
|
||||
$machine .= "+pve$PVE::QemuServer::Machine::PVE_MACHINE_VERSION" if $add_pve_version;
|
||||
}
|
||||
|
||||
return $machine;
|
||||
@ -3469,8 +3470,10 @@ sub config_to_command {
|
||||
my $kvm_binary = get_command_for_arch($arch);
|
||||
my $kvmver = kvm_user_version($kvm_binary);
|
||||
|
||||
my $machine_type = get_vm_machine($conf, $forcemachine, $arch);
|
||||
my $machine_version = PVE::QemuServer::Machine::extract_version($machine_type) // $kvmver;
|
||||
my $add_pve_version = min_version($kvmver, 4, 1);
|
||||
|
||||
my $machine_type = get_vm_machine($conf, $forcemachine, $arch, $add_pve_version);
|
||||
my $machine_version = PVE::QemuServer::Machine::extract_version($machine_type, $kvmver);
|
||||
$kvm //= 1 if is_native($arch);
|
||||
|
||||
if ($kvm) {
|
||||
@ -7049,7 +7052,7 @@ sub qemu_use_old_bios_files {
|
||||
$machine_type = $1;
|
||||
$use_old_bios_files = 1;
|
||||
} else {
|
||||
my $version = PVE::QemuServer::Machine::extract_version($machine_type) // kvm_user_version();
|
||||
my $version = PVE::QemuServer::Machine::extract_version($machine_type, kvm_user_version());
|
||||
# Note: kvm version < 2.4 use non-efi pxe files, and have problems when we
|
||||
# load new efi bios files on migration. So this hack is required to allow
|
||||
# live migration from qemu-2.2 to qemu-2.4, which is sometimes used when
|
||||
|
@ -103,10 +103,10 @@ sub vm_running_locally {
|
||||
}
|
||||
|
||||
sub min_version {
|
||||
my ($verstr, $version_major, $version_minor) = @_;
|
||||
my ($verstr, $major, $minor, $pve) = @_;
|
||||
|
||||
if ($verstr =~ m/^(\d+)\.(\d+)/) {
|
||||
return 1 if version_cmp($1, $version_major, $2, $version_minor) >= 0;
|
||||
if ($verstr =~ m/^(\d+)\.(\d+)(?:\.(\d+))?(?:\+pve(\d+))?/) {
|
||||
return 1 if version_cmp($1, $major, $2, $minor, $4, $pve) >= 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,10 @@ use warnings;
|
||||
use PVE::QemuServer::Helpers;
|
||||
use PVE::QemuServer::Monitor;
|
||||
|
||||
# Bump this for VM HW layout changes during a release (where the QEMU machine
|
||||
# version stays the same)
|
||||
our $PVE_MACHINE_VERSION = 1;
|
||||
|
||||
sub machine_type_is_q35 {
|
||||
my ($conf) = @_;
|
||||
|
||||
@ -18,31 +22,43 @@ sub get_current_qemu_machine {
|
||||
|
||||
my $res = PVE::QemuServer::Monitor::mon_cmd($vmid, 'query-machines');
|
||||
|
||||
my ($current, $default);
|
||||
my ($current, $pve_version, $default);
|
||||
foreach my $e (@$res) {
|
||||
$default = $e->{name} if $e->{'is-default'};
|
||||
$current = $e->{name} if $e->{'is-current'};
|
||||
$pve_version = $e->{'pve-version'} if $e->{'pve-version'};
|
||||
}
|
||||
|
||||
$current .= "+$pve_version" if $current && $pve_version;
|
||||
|
||||
# fallback to the default machine if current is not supported by qemu
|
||||
return $current || $default || 'pc';
|
||||
}
|
||||
|
||||
# returns a string with major.minor+pve<VERSION>, patch version-part is ignored
|
||||
# as it's seldom ressembling a real QEMU machine type, so it would be '0' 99% of
|
||||
# the time anyway.. This explicitly separates pveversion from the machine.
|
||||
sub extract_version {
|
||||
my ($machine_type) = @_;
|
||||
my ($machine_type, $kvmversion) = @_;
|
||||
|
||||
if ($machine_type && $machine_type =~ m/^((?:pc(-i440fx|-q35)?|virt)-(\d+)\.(\d+))/) {
|
||||
return "$3.$4";
|
||||
if (defined($machine_type) && $machine_type =~ m/^(?:pc(?:-i440fx|-q35)?|virt)-(\d+)\.(\d+)(?:\.(\d+))?(\+pve\d+)?/) {
|
||||
my $versionstr = "$1.$2";
|
||||
$versionstr .= $4 if $4;
|
||||
return $versionstr;
|
||||
} elsif (defined($kvmversion)) {
|
||||
if ($kvmversion =~ m/^(\d+)\.(\d+)/) {
|
||||
return "$1.$2+pve$PVE_MACHINE_VERSION";
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub machine_version {
|
||||
my ($machine_type, $version_major, $version_minor) = @_;
|
||||
my ($machine_type, $major, $minor, $pve) = @_;
|
||||
|
||||
return PVE::QemuServer::Helpers::min_version(
|
||||
extract_version($machine_type), $version_major, $version_minor);
|
||||
extract_version($machine_type), $major, $minor, $pve);
|
||||
}
|
||||
|
||||
# dies if a) VM not running or not exisiting b) Version query failed
|
||||
|
@ -33,5 +33,5 @@
|
||||
-netdev 'type=tap,id=net0,ifname=tap8006i0,script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown,vhost=on' \
|
||||
-device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,bootindex=300' \
|
||||
-rtc 'driftfix=slew,base=localtime' \
|
||||
-machine 'type=pc' \
|
||||
-machine 'type=pc+pve1' \
|
||||
-global 'kvm-pit.lost_tick_policy=discard'
|
||||
|
@ -21,4 +21,4 @@
|
||||
-device 'VGA,id=vga,bus=pci.0,addr=0x2' \
|
||||
-device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3' \
|
||||
-iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
|
||||
-machine 'type=pc'
|
||||
-machine 'type=pc+pve1'
|
||||
|
@ -36,4 +36,4 @@
|
||||
-iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
|
||||
-netdev 'type=tap,id=net0,ifname=tap8006i0,script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown,vhost=on' \
|
||||
-device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,bootindex=300' \
|
||||
-machine 'type=q35'
|
||||
-machine 'type=q35+pve1'
|
||||
|
@ -34,5 +34,5 @@
|
||||
-netdev 'type=tap,id=net0,ifname=tap8006i0,script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown,vhost=on' \
|
||||
-device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,bootindex=300' \
|
||||
-rtc 'driftfix=slew,base=localtime' \
|
||||
-machine 'type=q35' \
|
||||
-machine 'type=q35+pve1' \
|
||||
-global 'kvm-pit.lost_tick_policy=discard'
|
||||
|
@ -27,4 +27,4 @@
|
||||
-iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
|
||||
-netdev 'type=tap,id=net0,ifname=tap8006i0,script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown,vhost=on' \
|
||||
-device 'virtio-net-pci,mac=A2:C0:43:67:08:A1,netdev=net0,bus=pci.0,addr=0x12,id=net0,bootindex=300' \
|
||||
-machine 'type=pc'
|
||||
-machine 'type=pc+pve1'
|
||||
|
Loading…
Reference in New Issue
Block a user