提交 2814f672 编写于 作者: M Max Reitz 提交者: Kevin Wolf

blockdev: Add blockdev-remove-medium

Signed-off-by: NMax Reitz <mreitz@redhat.com>
Signed-off-by: NKevin Wolf <kwolf@redhat.com>
上级 abaaf59d
......@@ -2147,6 +2147,57 @@ void qmp_blockdev_close_tray(const char *device, Error **errp)
blk_dev_change_media_cb(blk, true);
}
void qmp_blockdev_remove_medium(const char *device, Error **errp)
{
BlockBackend *blk;
BlockDriverState *bs;
AioContext *aio_context;
bool has_device;
blk = blk_by_name(device);
if (!blk) {
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
"Device '%s' not found", device);
return;
}
/* For BBs without a device, we can exchange the BDS tree at will */
has_device = blk_get_attached_dev(blk);
if (has_device && !blk_dev_has_removable_media(blk)) {
error_setg(errp, "Device '%s' is not removable", device);
return;
}
if (has_device && !blk_dev_is_tray_open(blk)) {
error_setg(errp, "Tray of device '%s' is not open", device);
return;
}
bs = blk_bs(blk);
if (!bs) {
return;
}
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
goto out;
}
/* This follows the convention established by bdrv_make_anon() */
if (bs->device_list.tqe_prev) {
QTAILQ_REMOVE(&bdrv_states, bs, device_list);
bs->device_list.tqe_prev = NULL;
}
blk_remove_bs(blk);
out:
aio_context_release(aio_context);
}
/* 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,
......
......@@ -1924,6 +1924,22 @@
{ 'command': 'blockdev-close-tray',
'data': { 'device': 'str' } }
##
# @blockdev-remove-medium:
#
# Removes a medium (a block driver state tree) from a block device. That block
# device's tray must currently be open (unless there is no attached guest
# device).
#
# If the tray is open and there is no medium inserted, this will be a no-op.
#
# @device: block device name
#
# Since: 2.5
##
{ 'command': 'blockdev-remove-medium',
'data': { 'device': 'str' } }
##
# @BlockErrorAction
......
......@@ -4035,6 +4035,51 @@ Example:
<- { "return": {} }
EQMP
{
.name = "blockdev-remove-medium",
.args_type = "device:s",
.mhandler.cmd_new = qmp_marshal_blockdev_remove_medium,
},
SQMP
blockdev-remove-medium
----------------------
Removes a medium (a block driver state tree) from a block device. That block
device's tray must currently be open (unless there is no attached guest device).
If the tray is open and there is no medium inserted, this will be a no-op.
Arguments:
- "device": block device name (json-string)
Example:
-> { "execute": "blockdev-remove-medium",
"arguments": { "device": "ide1-cd0" } }
<- { "error": { "class": "GenericError",
"desc": "Tray of device 'ide1-cd0' is not open" } }
-> { "execute": "blockdev-open-tray",
"arguments": { "device": "ide1-cd0" } }
<- { "timestamp": { "seconds": 1418751627,
"microseconds": 549958 },
"event": "DEVICE_TRAY_MOVED",
"data": { "device": "ide1-cd0",
"tray-open": true } }
<- { "return": {} }
-> { "execute": "blockdev-remove-medium",
"arguments": { "device": "ide1-cd0" } }
<- { "return": {} }
EQMP
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册