blockdev: Add blockdev-open-tray

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Max Reitz 2015-10-26 21:39:08 +01:00 committed by Kevin Wolf
parent 38cb18f5b7
commit 7d8a9f71b9
3 changed files with 116 additions and 0 deletions

View file

@ -2088,6 +2088,42 @@ out:
aio_context_release(aio_context);
}
void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
Error **errp)
{
BlockBackend *blk;
bool locked;
if (!has_force) {
force = false;
}
blk = blk_by_name(device);
if (!blk) {
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
"Device '%s' not found", device);
return;
}
if (!blk_dev_has_removable_media(blk)) {
error_setg(errp, "Device '%s' is not removable", device);
return;
}
if (blk_dev_is_tray_open(blk)) {
return;
}
locked = blk_dev_is_medium_locked(blk);
if (locked) {
blk_dev_eject_request(blk, force);
}
if (!locked || force) {
blk_dev_change_media_cb(blk, false);
}
}
/* throttling disk I/O limits */
void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
int64_t bps_wr,

View file

@ -1876,6 +1876,38 @@
##
{ 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
##
# @blockdev-open-tray:
#
# Opens a block device's tray. If there is a block driver state tree inserted as
# a medium, it will become inaccessible to the guest (but it will remain
# associated to the block device, so closing the tray will make it accessible
# again).
#
# If the tray was already open before, this will be a no-op.
#
# Once the tray opens, a DEVICE_TRAY_MOVED event is emitted. There are cases in
# which no such event will be generated, these include:
# - if the guest has locked the tray, @force is false and the guest does not
# respond to the eject request
# - if the BlockBackend denoted by @device does not have a guest device attached
# to it
# - if the guest device does not have an actual tray and is empty, for instance
# for floppy disk drives
#
# @device: block device name
#
# @force: #optional if false (the default), an eject request will be sent to
# the guest if it has locked the tray (and the tray will not be opened
# immediately); if true, the tray will be opened regardless of whether
# it is locked
#
# Since: 2.5
##
{ 'command': 'blockdev-open-tray',
'data': { 'device': 'str',
'*force': 'bool' } }
##
# @BlockErrorAction

View file

@ -3952,6 +3952,54 @@ Example (2):
<- { "return": {} }
EQMP
{
.name = "blockdev-open-tray",
.args_type = "device:s,force:b?",
.mhandler.cmd_new = qmp_marshal_blockdev_open_tray,
},
SQMP
blockdev-open-tray
------------------
Opens a block device's tray. If there is a block driver state tree inserted as a
medium, it will become inaccessible to the guest (but it will remain associated
to the block device, so closing the tray will make it accessible again).
If the tray was already open before, this will be a no-op.
Once the tray opens, a DEVICE_TRAY_MOVED event is emitted. There are cases in
which no such event will be generated, these include:
- if the guest has locked the tray, @force is false and the guest does not
respond to the eject request
- if the BlockBackend denoted by @device does not have a guest device attached
to it
- if the guest device does not have an actual tray and is empty, for instance
for floppy disk drives
Arguments:
- "device": block device name (json-string)
- "force": if false (the default), an eject request will be sent to the guest if
it has locked the tray (and the tray will not be opened immediately);
if true, the tray will be opened regardless of whether it is locked
(json-bool, optional)
Example:
-> { "execute": "blockdev-open-tray",
"arguments": { "device": "ide1-cd0" } }
<- { "timestamp": { "seconds": 1418751016,
"microseconds": 716996 },
"event": "DEVICE_TRAY_MOVED",
"data": { "device": "ide1-cd0",
"tray-open": true } }
<- { "return": {} }
EQMP
{