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:
parent
b1999e87b4
commit
0402a5d65e
@ -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
|
||||
-----------------
|
||||
|
||||
|
11
hw/qdev.c
11
hw/qdev.c
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
##
|
||||
|
Loading…
Reference in New Issue
Block a user