1 package PVE
::QemuServer
::Machine
;
6 use PVE
::QemuServer
::Helpers
;
7 use PVE
::QemuServer
::Monitor
;
9 # Bump this for VM HW layout changes during a release (where the QEMU machine
10 # version stays the same)
11 our $PVE_MACHINE_VERSION = {
15 sub machine_type_is_q35
{
18 return $conf->{machine
} && ($conf->{machine
} =~ m/q35/) ?
1 : 0;
21 # this only works if VM is running
22 sub get_current_qemu_machine
{
25 my $res = PVE
::QemuServer
::Monitor
::mon_cmd
($vmid, 'query-machines');
27 my ($current, $pve_version, $default);
28 foreach my $e (@$res) {
29 $default = $e->{name
} if $e->{'is-default'};
30 $current = $e->{name
} if $e->{'is-current'};
31 $pve_version = $e->{'pve-version'} if $e->{'pve-version'};
34 $current .= "+$pve_version" if $current && $pve_version;
36 # fallback to the default machine if current is not supported by qemu
37 return $current || $default || 'pc';
40 # returns a string with major.minor+pve<VERSION>, patch version-part is ignored
41 # as it's seldom ressembling a real QEMU machine type, so it would be '0' 99% of
42 # the time anyway.. This explicitly separates pveversion from the machine.
44 my ($machine_type, $kvmversion) = @_;
46 if (defined($machine_type) && $machine_type =~ m/^(?:pc(?:-i440fx|-q35)?|virt)-(\d+)\.(\d+)(?:\.(\d+))?(\+pve\d+)?/) {
47 my $versionstr = "$1.$2";
48 $versionstr .= $4 if $4;
50 } elsif (defined($kvmversion)) {
51 if ($kvmversion =~ m/^(\d+)\.(\d+)/) {
52 my $pvever = get_pve_version
($kvmversion);
53 return "$1.$2+pve$pvever";
61 my ($machine_type, $major, $minor, $pve) = @_;
63 return PVE
::QemuServer
::Helpers
::min_version
(
64 extract_version
($machine_type), $major, $minor, $pve);
70 if ($verstr =~ m/^(\d+\.\d+)/) {
71 return $PVE_MACHINE_VERSION->{$1} // 0;
74 die "internal error: cannot get pve version for invalid string '$verstr'";
77 sub can_run_pve_machine_version
{
78 my ($machine_version, $kvmversion) = @_;
80 $machine_version =~ m/^(\d+)\.(\d+)(?:\+pve(\d+))$/;
85 $kvmversion =~ m/(\d+)\.(\d+)/;
86 return 0 if PVE
::QemuServer
::Helpers
::version_cmp
($1, $major, $2, $minor) < 0;
88 # if $pvever is missing or 0, we definitely support it as long as we didn't
89 # fail the QEMU version check above
92 my $max_supported = get_pve_version
("$major.$minor");
93 return 1 if $max_supported >= $pvever;
98 # dies if a) VM not running or not exisiting b) Version query failed
99 # So, any defined return value is valid, any invalid state can be caught by eval
100 sub runs_at_least_qemu_version
{
101 my ($vmid, $major, $minor, $extra) = @_;
103 my $v = PVE
::QemuServer
::Monitor
::mon_cmd
($vmid, 'query-version');
104 die "could not query currently running version for VM $vmid\n" if !defined($v);
107 return PVE
::QemuServer
::Helpers
::version_cmp
($v->{major
}, $major, $v->{minor
}, $minor, $v->{micro
}, $extra) >= 0;
110 sub qemu_machine_pxe
{
111 my ($vmid, $conf) = @_;
113 my $machine = get_current_qemu_machine
($vmid);
115 if ($conf->{machine
} && $conf->{machine
} =~ m/\.pxe$/) {