From 2e0ff1213c233fa7e8a2c61b4dc31b3f2ba1a9a6 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Thu, 5 Jun 2014 07:09:17 +0200 Subject: [PATCH 8/9] qdev: DEVICE_DELETED event RH-Author: Marcel Apfelbaum Message-id: <1401952158-29608-7-git-send-email-marcel.a@redhat.com> Patchwork-id: 59152 O-Subject: [RHEL-6.6 qemu-kvm PATCH v5 6/7] qdev: DEVICE_DELETED event Bugzilla: 813748 RH-Acked-by: Michael S. Tsirkin RH-Acked-by: Laszlo Ersek RH-Acked-by: Luiz Capitulino libvirt has a long-standing bug: when removing the device, it can request removal but does not know when the removal completes. Add an event so we can fix this in a robust way. Signed-off-by: Michael S. Tsirkin (cherry picked from commit 0402a5d65ec004df5345d1f736e2ddaa7aee6665) Conflicts: QMP/qmp-events.txt hw/qdev.c include/monitor/monitor.h monitor.c qapi-schema.json RHEL6 Notes: - conflicts: - include/monitor/monitor.h: file still in root folder; events missing. - QMP/qmp-events.txt, monitor.c: not the same event before DEVICE_DELETED. - hw/qdev.c: includes mismatch; upstream added the event to device_unparent, but in RHEL6.6 was added to qdev_free. - qapi-schema.json: dropped the hunk because it was a comment for "device_del" that is not yet backported. Signed-off-by: Marcel Apfelbaum --- QMP/qmp-events.txt | 16 ++++++++++++++++ hw/qdev.c | 11 +++++++++++ monitor.c | 1 + monitor.h | 1 + 4 files changed, 29 insertions(+) Signed-off-by: jen --- QMP/qmp-events.txt | 16 ++++++++++++++++ hw/qdev.c | 11 +++++++++++ monitor.c | 1 + monitor.h | 1 + 4 files changed, 29 insertions(+), 0 deletions(-) diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt index 55bfd46..b6694d9 100644 --- a/QMP/qmp-events.txt +++ b/QMP/qmp-events.txt @@ -63,6 +63,22 @@ Example: Note: If action is "stop", a STOP event will eventually follow the BLOCK_IO_ERROR event. +DEVICE_DELETED +----------------- + +Emitted whenever the device removal completion is acknowledged +by the guest. +At this point, it's safe to reuse the specified device ID. +Device removal can be initiated by the guest or by HMP/QMP commands. + +Data: + +- "device": device name (json-string, optional) + +{ "event": "DEVICE_DELETED", + "data": { "device": "virtio-net-pci-0" }, + "timestamp": { "seconds": 1265044230, "microseconds": 450486 } } + DEVICE_TRAY_MOVED ----------------- diff --git a/hw/qdev.c b/hw/qdev.c index 3a27892..b4102ca 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -28,6 +28,7 @@ #include "net.h" #include "qdev.h" #include "sysemu.h" +#include "qjson.h" #include "monitor.h" static int qdev_hotplug = 0; @@ -354,6 +355,13 @@ void qdev_free(DeviceState *dev) { BusState *bus; Property *prop; + QObject *event_data; + + if (dev->id) { + event_data = qobject_from_jsonf("{ 'device': %s }", dev->id); + } else { + event_data = qobject_from_jsonf("{ }"); + } if (dev->state == DEV_STATE_INITIALIZED) { while (dev->num_child_bus) { @@ -374,6 +382,9 @@ void qdev_free(DeviceState *dev) prop->info->free(dev, prop); } } + + monitor_protocol_event(QEVENT_DEVICE_DELETED, event_data); + qobject_decref(event_data); qemu_free(dev); } diff --git a/monitor.c b/monitor.c index 6a947b9..4a3375e 100644 --- a/monitor.c +++ b/monitor.c @@ -501,6 +501,7 @@ static const char *monitor_event_names[] = { [QEVENT_RH_SPICE_DISCONNECTED] = RFQDN_REDHAT "SPICE_DISCONNECTED", [QEVENT_BLOCK_JOB_COMPLETED] = "BLOCK_JOB_COMPLETED", [QEVENT_BLOCK_JOB_CANCELLED] = "BLOCK_JOB_CANCELLED", + [QEVENT_DEVICE_DELETED] = "DEVICE_DELETED", [QEVENT_DEVICE_TRAY_MOVED] = "DEVICE_TRAY_MOVED", [QEVENT_SUSPEND] = "SUSPEND", [QEVENT_SUSPEND_DISK] = "SUSPEND_DISK", diff --git a/monitor.h b/monitor.h index 4b4a00d..06ea58c 100644 --- a/monitor.h +++ b/monitor.h @@ -39,6 +39,7 @@ typedef enum MonitorEvent { QEVENT_SPICE_CONNECTED, QEVENT_SPICE_INITIALIZED, QEVENT_SPICE_DISCONNECTED, + QEVENT_DEVICE_DELETED, QEVENT_DEVICE_TRAY_MOVED, QEVENT_BLOCK_JOB_COMPLETED, QEVENT_BLOCK_JOB_CANCELLED, -- 1.7.1