mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-05-29 14:53:53 +00:00

Fixes device hotplug in combination with QEMU 9.2. QEMU commit be93fd5372 ("qdev-monitor: avoid QemuOpts in QMP device_add") notes: > This patch changes the behavior of QMP device_add but not HMP > device_add. QMP clients that sent incorrectly typed device_add QMP > commands no longer work. This is a breaking change but clients should be > using the correct types already. The qemu_deviceadd() helper does not have the required type information right now, so switch to using HMP, which still behaves the same when passing a device commandline string. QEMU commit be93fd5372 fixes passing in complex properties via JSON, but the qemu_deviceadd() helper never uses any such, as it already only received a string (and naively split it up). Use HMP for 'device_del' too, simply to keep the qemu_deviceadd() and qemu_devicedel() helpers consistent. Switching back to QMP using the correct types in the JSON can still be done later. Unfortunately, 'qmp-query-schema' does not provide device-specific types, so another way is needed. A timeout of 25 seconds is used rather then relying on the low default like before, since device plug operations require actions by the guest kernel and might require IO. Device plug is often an interactive operation, so a too high timeout could lead to bad UX. For now stay a few seconds under the default timeout of 30 seconds of our web UI's API request handler. Should specific devices need a higher timeout, it can still be increased further for them in the future. Signed-off-by: Fiona Ebner <f.ebner@proxmox.com> [TL: reduce timeout from 30s to 25s to ensure sync API requests (without a task worker) do not run into the frontend timeout] Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
67 lines
1.4 KiB
Perl
67 lines
1.4 KiB
Perl
package PVE::QemuServer::QMPHelpers;
|
|
|
|
use warnings;
|
|
use strict;
|
|
|
|
use PVE::QemuServer::Helpers;
|
|
use PVE::QemuServer::Monitor qw(mon_cmd);
|
|
|
|
use base 'Exporter';
|
|
|
|
our @EXPORT_OK = qw(
|
|
qemu_deviceadd
|
|
qemu_devicedel
|
|
qemu_objectadd
|
|
qemu_objectdel
|
|
);
|
|
|
|
sub nbd_stop {
|
|
my ($vmid) = @_;
|
|
|
|
mon_cmd($vmid, 'nbd-server-stop', timeout => 25);
|
|
}
|
|
|
|
sub qemu_deviceadd {
|
|
my ($vmid, $devicefull) = @_;
|
|
|
|
$devicefull = "driver=".$devicefull;
|
|
|
|
PVE::QemuServer::Monitor::hmp_cmd($vmid, "device_add $devicefull", 25);
|
|
}
|
|
|
|
sub qemu_devicedel {
|
|
my ($vmid, $deviceid) = @_;
|
|
|
|
PVE::QemuServer::Monitor::hmp_cmd($vmid, "device_del $deviceid", 25);
|
|
}
|
|
|
|
sub qemu_objectadd {
|
|
my ($vmid, $objectid, $qomtype) = @_;
|
|
|
|
mon_cmd($vmid, "object-add", id => $objectid, "qom-type" => $qomtype);
|
|
|
|
return 1;
|
|
}
|
|
|
|
sub qemu_objectdel {
|
|
my ($vmid, $objectid) = @_;
|
|
|
|
mon_cmd($vmid, "object-del", id => $objectid);
|
|
|
|
return 1;
|
|
}
|
|
|
|
# dies if a) VM not running or not existing 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 PVE::QemuServer::Helpers::version_cmp($v->{major}, $major, $v->{minor}, $minor, $v->{micro}, $extra) >= 0;
|
|
}
|
|
|
|
1;
|