qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] qmp: add BLOCK_MEDIUM_EJECT event


From: Luiz Capitulino
Subject: [Qemu-devel] [PATCH] qmp: add BLOCK_MEDIUM_EJECT event
Date: Tue, 24 Jan 2012 16:16:28 -0200

Libvirt wants to be notified when the guest ejects a medium, so that
it can update its view of the guest.

This code has been originally written by Daniel Berrange. It adds
the event to IDE and SCSI emulation.

Please, note that this only covers guest initiated ejects, that's,
the QMP/HMP commands 'eject' and 'change' are not covered.

Signed-off-by: Luiz Capitulino <address@hidden>
---

PS: Bugs are mine.

 QMP/qmp-events.txt |   18 ++++++++++++++++++
 block.c            |   12 ++++++++++++
 block.h            |    5 +++++
 block_int.h        |    3 +++
 blockdev.c         |   13 +++++++++++++
 hw/ide/atapi.c     |    1 +
 hw/scsi-disk.c     |    1 +
 monitor.c          |    3 +++
 monitor.h          |    1 +
 9 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt
index af586ec..e414128 100644
--- a/QMP/qmp-events.txt
+++ b/QMP/qmp-events.txt
@@ -26,6 +26,24 @@ Example:
 Note: If action is "stop", a STOP event will eventually follow the
 BLOCK_IO_ERROR event.
 
+BLOCK_MEDIUM_EJECT
+------------------
+
+Emitted when the guest succeeds ejecting a medium. If the device has a tray,
+then this event is emitted whenever the guest opens or closes the tray.
+
+Data:
+
+- "device": device name (json-string)
+- "ejected": true if the tray has been opened or false if it has been closed
+
+Example:
+
+{ "event": "BLOCK_MEDIUM_EJECT",
+    "data": { "device": "ide1-cd1",
+              "ejected": true },
+    "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+
 RESET
 -----
 
diff --git a/block.c b/block.c
index 3f072f6..b25932b 100644
--- a/block.c
+++ b/block.c
@@ -1998,6 +1998,18 @@ BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, 
int is_read)
     return is_read ? bs->on_read_error : bs->on_write_error;
 }
 
+void bdrv_dev_set_medium_eject_notify(BlockDriverState *bs,
+                                      bdrv_dev_medium_eject_notify_cb cb)
+{
+    bs->dev_medium_eject_notify_cb = cb;
+}
+
+void bdrv_dev_medium_eject_notify(BlockDriverState *bs, int is_ejected)
+{
+    assert(bs->dev_medium_eject_notify_cb);
+    bs->dev_medium_eject_notify_cb(bs, is_ejected);
+}
+
 int bdrv_is_read_only(BlockDriverState *bs)
 {
     return bs->read_only;
diff --git a/block.h b/block.h
index 3bd4398..344ca0d 100644
--- a/block.h
+++ b/block.h
@@ -247,6 +247,11 @@ int bdrv_get_translation_hint(BlockDriverState *bs);
 void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
                        BlockErrorAction on_write_error);
 BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read);
+typedef void (*bdrv_dev_medium_eject_notify_cb)(BlockDriverState *bs,
+                                                int is_ejected);
+void bdrv_dev_set_medium_eject_notify(BlockDriverState *bs,
+                                      bdrv_dev_medium_eject_notify_cb cb);
+void bdrv_dev_medium_eject_notify(BlockDriverState *bs, int is_ejected);
 int bdrv_is_read_only(BlockDriverState *bs);
 int bdrv_is_sg(BlockDriverState *bs);
 int bdrv_enable_write_cache(BlockDriverState *bs);
diff --git a/block_int.h b/block_int.h
index 311bd2a..50c34f6 100644
--- a/block_int.h
+++ b/block_int.h
@@ -260,6 +260,9 @@ struct BlockDriverState {
     QTAILQ_ENTRY(BlockDriverState) list;
     void *private;
 
+    /* Callback for medium eject */
+    bdrv_dev_medium_eject_notify_cb dev_medium_eject_notify_cb;
+
     QLIST_HEAD(, BdrvTrackedRequest) tracked_requests;
 };
 
diff --git a/blockdev.c b/blockdev.c
index 1f83c88..71b50fa 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -11,6 +11,7 @@
 #include "blockdev.h"
 #include "monitor.h"
 #include "qerror.h"
+#include "qjson.h"
 #include "qemu-option.h"
 #include "qemu-config.h"
 #include "sysemu.h"
@@ -237,6 +238,17 @@ static bool do_check_io_limits(BlockIOLimit *io_limits)
     return true;
 }
 
+static void on_medium_eject(BlockDriverState *bs, int is_ejected)
+{
+    QObject *data;
+
+    data = qobject_from_jsonf("{ 'device': %s, 'ejected': %i }",
+                              bdrv_get_device_name(bs), is_ejected);
+    monitor_protocol_event(QEVENT_BLOCK_MEDIUM_EJECT, data);
+
+    qobject_decref(data);
+}
+
 DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
 {
     const char *buf;
@@ -503,6 +515,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
     QTAILQ_INSERT_TAIL(&drives, dinfo, next);
 
     bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
+    bdrv_dev_set_medium_eject_notify(dinfo->bdrv, on_medium_eject);
 
     /* disk I/O throttling */
     bdrv_set_io_limits(dinfo->bdrv, &io_limits);
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 0adb27b..4b4bc61 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -885,6 +885,7 @@ static void cmd_start_stop_unit(IDEState *s, uint8_t* buf)
         }
         bdrv_eject(s->bs, !start);
         s->tray_open = !start;
+        bdrv_dev_medium_eject_notify(s->bs, !start);
     }
 
     ide_atapi_cmd_ok(s);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 5d8bf53..35e55f4 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1061,6 +1061,7 @@ static int scsi_disk_emulate_start_stop(SCSIDiskReq *r)
         }
         bdrv_eject(s->qdev.conf.bs, !start);
         s->tray_open = !start;
+        bdrv_dev_medium_eject_notify(s->qdev.conf.bs, !start);
     }
     return 0;
 }
diff --git a/monitor.c b/monitor.c
index 187083c..df6b475 100644
--- a/monitor.c
+++ b/monitor.c
@@ -479,6 +479,9 @@ void monitor_protocol_event(MonitorEvent event, QObject 
*data)
         case QEVENT_SPICE_DISCONNECTED:
             event_name = "SPICE_DISCONNECTED";
             break;
+        case QEVENT_BLOCK_MEDIUM_EJECT:
+            event_name = "BLOCK_MEDIUM_EJECT";
+            break;
         default:
             abort();
             break;
diff --git a/monitor.h b/monitor.h
index 887c472..16fab50 100644
--- a/monitor.h
+++ b/monitor.h
@@ -36,6 +36,7 @@ typedef enum MonitorEvent {
     QEVENT_SPICE_CONNECTED,
     QEVENT_SPICE_INITIALIZED,
     QEVENT_SPICE_DISCONNECTED,
+    QEVENT_BLOCK_MEDIUM_EJECT,
     QEVENT_MAX,
 } MonitorEvent;
 
-- 
1.7.9.rc2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]