]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer/Machine.pm
machine: get current: add flag if current machine is deprecated in list context
[qemu-server.git] / PVE / QemuServer / Machine.pm
CommitLineData
3392d6ca
SR
1package PVE::QemuServer::Machine;
2
3use strict;
4use warnings;
5
2ea5fb7e 6use PVE::QemuServer::Helpers;
3392d6ca
SR
7use PVE::QemuServer::Monitor;
8
9471e48b
TL
9# Bump this for VM HW layout changes during a release (where the QEMU machine
10# version stays the same)
ac0077cc 11our $PVE_MACHINE_VERSION = {
b8fb1c03 12 '4.1' => 2,
ac0077cc 13};
9471e48b 14
3392d6ca
SR
15sub machine_type_is_q35 {
16 my ($conf) = @_;
17
18 return $conf->{machine} && ($conf->{machine} =~ m/q35/) ? 1 : 0;
19}
20
da841554 21# In list context, also returns whether the current machine is deprecated or not.
ea71be24 22sub current_from_query_machines {
081eed3b 23 my ($machines) = @_;
3392d6ca 24
7d6a6292 25 my ($current, $default);
081eed3b
FE
26 for my $machine ($machines->@*) {
27 $default = $machine->{name} if $machine->{'is-default'};
3392d6ca 28
7d6a6292
FE
29 if ($machine->{'is-current'}) {
30 $current = $machine->{name};
31 # pve-version only exists for the current machine
32 $current .= "+$machine->{'pve-version'}" if $machine->{'pve-version'};
da841554 33 return wantarray ? ($current, $machine->{deprecated} ? 1 : 0) : $current;
7d6a6292
FE
34 }
35 }
9471e48b 36
da841554
FE
37 # fallback to the default machine if current is not supported by qemu - assume never deprecated
38 my $fallback = $default || 'pc';
39 return wantarray ? ($fallback, 0) : $fallback;
3392d6ca
SR
40}
41
da841554
FE
42# This only works if VM is running.
43# In list context, also returns whether the current machine is deprecated or not.
ea71be24
FE
44sub get_current_qemu_machine {
45 my ($vmid) = @_;
46
47 my $res = PVE::QemuServer::Monitor::mon_cmd($vmid, 'query-machines');
48
49 return current_from_query_machines($res);
50}
51
9471e48b
TL
52# returns a string with major.minor+pve<VERSION>, patch version-part is ignored
53# as it's seldom ressembling a real QEMU machine type, so it would be '0' 99% of
54# the time anyway.. This explicitly separates pveversion from the machine.
2ea5fb7e 55sub extract_version {
9471e48b
TL
56 my ($machine_type, $kvmversion) = @_;
57
d4be7f31
SR
58 if (defined($machine_type) && $machine_type =~
59 m/^(?:pc(?:-i440fx|-q35)?|virt)-(\d+)\.(\d+)(?:\.(\d+))?(\+pve\d+)?(?:\.pxe)?/)
60 {
9471e48b
TL
61 my $versionstr = "$1.$2";
62 $versionstr .= $4 if $4;
63 return $versionstr;
64 } elsif (defined($kvmversion)) {
65 if ($kvmversion =~ m/^(\d+)\.(\d+)/) {
ac0077cc
SR
66 my $pvever = get_pve_version($kvmversion);
67 return "$1.$2+pve$pvever";
9471e48b 68 }
3392d6ca
SR
69 }
70
d1c1af4b 71 return;
3392d6ca
SR
72}
73
2ea5fb7e 74sub machine_version {
9471e48b 75 my ($machine_type, $major, $minor, $pve) = @_;
3392d6ca 76
2ea5fb7e 77 return PVE::QemuServer::Helpers::min_version(
9471e48b 78 extract_version($machine_type), $major, $minor, $pve);
3392d6ca
SR
79}
80
ac0077cc
SR
81sub get_pve_version {
82 my ($verstr) = @_;
83
84 if ($verstr =~ m/^(\d+\.\d+)/) {
85 return $PVE_MACHINE_VERSION->{$1} // 0;
86 }
87
88 die "internal error: cannot get pve version for invalid string '$verstr'";
89}
90
91sub can_run_pve_machine_version {
92 my ($machine_version, $kvmversion) = @_;
93
d4be7f31 94 $machine_version =~ m/^(\d+)\.(\d+)(?:\+pve(\d+))?(?:\.pxe)?$/;
ac0077cc
SR
95 my $major = $1;
96 my $minor = $2;
97 my $pvever = $3;
98
99 $kvmversion =~ m/(\d+)\.(\d+)/;
100 return 0 if PVE::QemuServer::Helpers::version_cmp($1, $major, $2, $minor) < 0;
101
102 # if $pvever is missing or 0, we definitely support it as long as we didn't
103 # fail the QEMU version check above
104 return 1 if !$pvever;
105
106 my $max_supported = get_pve_version("$major.$minor");
107 return 1 if $max_supported >= $pvever;
108
109 return 0;
110}
111
3392d6ca
SR
112# dies if a) VM not running or not exisiting b) Version query failed
113# So, any defined return value is valid, any invalid state can be caught by eval
114sub runs_at_least_qemu_version {
115 my ($vmid, $major, $minor, $extra) = @_;
116
117 my $v = PVE::QemuServer::Monitor::mon_cmd($vmid, 'query-version');
118 die "could not query currently running version for VM $vmid\n" if !defined($v);
119 $v = $v->{qemu};
120
825ae5bc 121 return PVE::QemuServer::Helpers::version_cmp($v->{major}, $major, $v->{minor}, $minor, $v->{micro}, $extra) >= 0;
3392d6ca
SR
122}
123
124sub qemu_machine_pxe {
125 my ($vmid, $conf) = @_;
126
127 my $machine = get_current_qemu_machine($vmid);
128
129 if ($conf->{machine} && $conf->{machine} =~ m/\.pxe$/) {
130 $machine .= '.pxe';
131 }
132
133 return $machine;
134}
135
1361;