Signed-off-by: Luiz Capitulino <lcapitul...@redhat.com> --- QMP/qmp-events.txt | 21 +++++++++++++++++++++ block.c | 15 +++++++++++++++ monitor.c | 3 +++ monitor.h | 1 + 4 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt index 06cb404..ab32e62 100644 --- a/QMP/qmp-events.txt +++ b/QMP/qmp-events.txt @@ -26,6 +26,27 @@ Example: Note: If action is "stop", a STOP event will eventually follow the BLOCK_IO_ERROR event. +GUEST_MEDIUM_EJECTED +-------------------- + +Emitted when the guest succeeds ejecting a removable medium. If the drive +has a tray, this is only emitted if the tray opens or closes. + +Data: + +- "device": device name (json-string) +- "ejected": true if the tray has been opened or false if it has been closed + +Example: + +{ "event": "GUEST_MEDIUM_EJECTED", + "data": { "device": "ide1-cd1", + "ejected": true }, + "timestamp": { "seconds": 1265044230, "microseconds": 450486 } } + +Note: This event does not track all tray changes, as QMP/HMP commands like +'eject' can also change the tray. + RESET ----- diff --git a/block.c b/block.c index 77ace49..7f5b56d 100644 --- a/block.c +++ b/block.c @@ -2244,6 +2244,17 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, return data.ret; } +static void bdrv_emit_qmp_eject_event(BlockDriverState *bs, bool is_ejected) +{ + QObject *data; + + data = qobject_from_jsonf("{ 'device': %s, 'ejected': %i }", + bdrv_get_device_name(bs), is_ejected); + monitor_protocol_event(QEVENT_GUEST_MEDIUM_EJECTED, data); + + qobject_decref(data); +} + void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv, BlockQMPEventAction action, int is_read) { @@ -3567,6 +3578,10 @@ void bdrv_eject(BlockDriverState *bs, bool eject_flag, bool tray_changed) if (drv && drv->bdrv_eject) { drv->bdrv_eject(bs, eject_flag); } + + if (tray_changed && bs->device_name[0]) { + bdrv_emit_qmp_eject_event(bs, eject_flag); + } } /** diff --git a/monitor.c b/monitor.c index aadbdcb..48b1dea 100644 --- a/monitor.c +++ b/monitor.c @@ -485,6 +485,9 @@ void monitor_protocol_event(MonitorEvent event, QObject *data) case QEVENT_BLOCK_JOB_CANCELLED: event_name = "BLOCK_JOB_CANCELLED"; break; + case QEVENT_GUEST_MEDIUM_EJECTED: + event_name = "GUEST_MEDIUM_EJECTED"; + break; default: abort(); break; diff --git a/monitor.h b/monitor.h index b72ea07..06be7bb 100644 --- a/monitor.h +++ b/monitor.h @@ -38,6 +38,7 @@ typedef enum MonitorEvent { QEVENT_SPICE_DISCONNECTED, QEVENT_BLOCK_JOB_COMPLETED, QEVENT_BLOCK_JOB_CANCELLED, + QEVENT_GUEST_MEDIUM_EJECTED, QEVENT_MAX, } MonitorEvent; -- 1.7.9.111.gf3fb0.dirty