On 01/24/2012 07:16 PM, Luiz Capitulino wrote:
@@ -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);
block.c/blockdev.c separation is nice, but do we really need a function
pointer? Also, we're already emitting the BLOCK_IO_ERROR event in
block.c; is that another place to cleanup, or is this overkill and we
can just put bdrv_dev_medium_eject_notify in block.c?
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;
}
Can you do the call directly in bdrv_eject (but I would skip
bdrv_close)? The only other place where bdrv_eject is called is from
block/raw.c's raw_eject, but I think you should only emit the event if
bs->device_name[0] (otherwise the event is quite useless) and bs->file
will fail the test.
Paolo