qdev: DEVICE_DELETED event

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 <mst@redhat.com>
This commit is contained in:
Michael S. Tsirkin 2013-03-06 14:58:59 +02:00
parent b1999e87b4
commit 0402a5d65e
5 changed files with 32 additions and 1 deletions

View File

@ -136,6 +136,22 @@ Example:
Note: The "ready to complete" status is always reset by a BLOCK_JOB_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
-----------------

View File

@ -30,6 +30,8 @@
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qapi/visitor.h"
#include "qapi/qmp/qjson.h"
#include "monitor/monitor.h"
int qdev_hotplug = 0;
static bool qdev_hot_added = false;
@ -761,6 +763,7 @@ static void device_unparent(Object *obj)
DeviceState *dev = DEVICE(obj);
DeviceClass *dc = DEVICE_GET_CLASS(dev);
BusState *bus;
QObject *event_data;
while (dev->num_child_bus) {
bus = QLIST_FIRST(&dev->child_bus);
@ -779,6 +782,14 @@ static void device_unparent(Object *obj)
object_unref(OBJECT(dev->parent_bus));
dev->parent_bus = NULL;
}
if (dev->id) {
event_data = qobject_from_jsonf("{ 'device': %s }", dev->id);
} else {
event_data = qobject_from_jsonf("{ }");
}
monitor_protocol_event(QEVENT_DEVICE_DELETED, event_data);
qobject_decref(event_data);
}
static void device_class_init(ObjectClass *class, void *data)

View File

@ -39,6 +39,7 @@ typedef enum MonitorEvent {
QEVENT_BLOCK_JOB_CANCELLED,
QEVENT_BLOCK_JOB_ERROR,
QEVENT_BLOCK_JOB_READY,
QEVENT_DEVICE_DELETED,
QEVENT_DEVICE_TRAY_MOVED,
QEVENT_SUSPEND,
QEVENT_SUSPEND_DISK,

View File

@ -458,6 +458,7 @@ static const char *monitor_event_names[] = {
[QEVENT_BLOCK_JOB_CANCELLED] = "BLOCK_JOB_CANCELLED",
[QEVENT_BLOCK_JOB_ERROR] = "BLOCK_JOB_ERROR",
[QEVENT_BLOCK_JOB_READY] = "BLOCK_JOB_READY",
[QEVENT_DEVICE_DELETED] = "DEVICE_DELETED",
[QEVENT_DEVICE_TRAY_MOVED] = "DEVICE_TRAY_MOVED",
[QEVENT_SUSPEND] = "SUSPEND",
[QEVENT_SUSPEND_DISK] = "SUSPEND_DISK",

View File

@ -2354,7 +2354,9 @@
# Notes: When this command completes, the device may not be removed from the
# guest. Hot removal is an operation that requires guest cooperation.
# This command merely requests that the guest begin the hot removal
# process.
# process. Completion of the device removal process is signaled with a
# DEVICE_DELETED event. Guest reset will automatically complete removal
# for all devices.
#
# Since: 0.14.0
##