Patchwork [3/3] QMP: Introduce the BLOCK_MEDIA_EJECT event

login
register
mail settings
Submitter Luiz Capitulino
Date Jan. 12, 2011, 6:22 p.m.
Message ID <1294856523-4288-4-git-send-email-lcapitulino@redhat.com>
Download mbox | patch
Permalink /patch/78604/
State New
Headers show

Comments

Luiz Capitulino - Jan. 12, 2011, 6:22 p.m.
Conforms to the event specification defined in the
QMP/qmp-events.txt file.

Please, note the following (very important) details:

 o The event should be emitted only by devices which support the
   eject operation, which (afaik) are: CDROMs (IDE and SCSI) and
   floppies

 o Human monitor commands "eject" and "change" also cause the
   event to be emitted

 o The event is only emitted when there's a tray transition from
   closed to opened. To implement this in the human monitor, we
   only emit the event if the device is removable and a media is
   present

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 block.c    |   12 ++++++++++++
 block.h    |    1 +
 blockdev.c |    5 +++++
 monitor.c  |    3 +++
 monitor.h  |    1 +
 5 files changed, 22 insertions(+), 0 deletions(-)

Patch

diff --git a/block.c b/block.c
index 5de7559..4b87a60 100644
--- a/block.c
+++ b/block.c
@@ -1553,6 +1553,15 @@  int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
 }
 
+void bdrv_eject_mon_event(const BlockDriverState *bdrv)
+{
+    QObject *data;
+
+    data = qobject_from_jsonf("{ 'device': %s }", bdrv->device_name);
+    monitor_protocol_event(QEVENT_BLOCK_MEDIA_EJECT, data);
+    qobject_decref(data);
+}
+
 void bdrv_error_mon_event(const BlockDriverState *bdrv,
                           BlockMonEventAction action, int is_read)
 {
@@ -2671,6 +2680,9 @@  int bdrv_eject(BlockDriverState *bs, int eject_flag)
         ret = 0;
     }
     if (ret >= 0) {
+        if (eject_flag && !bs->tray_open) {
+            bdrv_eject_mon_event(bs);
+        }
         bs->tray_open = eject_flag;
     }
 
diff --git a/block.h b/block.h
index 4874b85..bf5c1b2 100644
--- a/block.h
+++ b/block.h
@@ -50,6 +50,7 @@  typedef enum {
     BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP
 } BlockMonEventAction;
 
+void bdrv_eject_mon_event(const BlockDriverState *bdrv);
 void bdrv_error_mon_event(const BlockDriverState *bdrv,
                           BlockMonEventAction action, int is_read);
 void bdrv_info_print(Monitor *mon, const QObject *data);
diff --git a/blockdev.c b/blockdev.c
index d7add36..4d7ce9b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -591,6 +591,11 @@  static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
             return -1;
         }
     }
+
+    if (bdrv_is_removable(bs) && bdrv_is_inserted(bs)) {
+        bdrv_eject_mon_event(bs);
+    }
+
     bdrv_close(bs);
     return 0;
 }
diff --git a/monitor.c b/monitor.c
index f258000..bf50cc4 100644
--- a/monitor.c
+++ b/monitor.c
@@ -450,6 +450,9 @@  void monitor_protocol_event(MonitorEvent event, QObject *data)
         case QEVENT_VNC_DISCONNECTED:
             event_name = "VNC_DISCONNECTED";
             break;
+        case QEVENT_BLOCK_MEDIA_EJECT:
+            event_name = "BLOCK_MEDIA_EJECT";
+            break;
         case QEVENT_BLOCK_IO_ERROR:
             event_name = "BLOCK_IO_ERROR";
             break;
diff --git a/monitor.h b/monitor.h
index 4f2d328..7a04137 100644
--- a/monitor.h
+++ b/monitor.h
@@ -29,6 +29,7 @@  typedef enum MonitorEvent {
     QEVENT_VNC_CONNECTED,
     QEVENT_VNC_INITIALIZED,
     QEVENT_VNC_DISCONNECTED,
+    QEVENT_BLOCK_MEDIA_EJECT,
     QEVENT_BLOCK_IO_ERROR,
     QEVENT_RTC_CHANGE,
     QEVENT_WATCHDOG,