mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches # gpg: Signature made Fri 23 Sep 2016 12:59:46 BST # gpg: using RSA key 0x7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: (33 commits) block: Remove BB interface from blockdev-add/del qemu-iotests/141: Avoid blockdev-add with id block: Avoid printing NULL string in error messages qemu-iotests/139: Avoid blockdev-add with id qemu-iotests/124: Avoid blockdev-add with id qemu-iotests/118: Avoid blockdev-add with id qemu-iotests/117: Avoid blockdev-add with id qemu-iotests/087: Avoid blockdev-add with id qemu-iotests/081: Avoid blockdev-add with id qemu-iotests/071: Avoid blockdev-add with id qemu-iotests/067: Avoid blockdev-add with id qemu-iotests/041: Avoid blockdev-add with id qemu-iotests/118: Test media change with qdev name block: Accept device model name for block_set_io_throttle block: Accept device model name for blockdev-change-medium block: Accept device model name for eject block: Accept device model name for x-blockdev-remove-medium block: Accept device model name for x-blockdev-insert-medium block: Accept device model name for blockdev-open/close-tray qdev-monitor: Add blk_by_qdev_id() ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -733,6 +733,9 @@ static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options,
|
||||
qdict_set_default_str(child_options, BDRV_OPT_CACHE_DIRECT, "off");
|
||||
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
|
||||
|
||||
/* Copy the read-only option from the parent */
|
||||
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
|
||||
|
||||
/* aio=native doesn't work for cache.direct=off, so disable it for the
|
||||
* temporary snapshot */
|
||||
*child_flags &= ~BDRV_O_NATIVE_AIO;
|
||||
@@ -755,6 +758,9 @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
|
||||
qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_DIRECT);
|
||||
qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_NO_FLUSH);
|
||||
|
||||
/* Inherit the read-only option from the parent if it's not set */
|
||||
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
|
||||
|
||||
/* Our block drivers take care to send flushes and respect unmap policy,
|
||||
* so we can default to enable both on lower layers regardless of the
|
||||
* corresponding parent options. */
|
||||
@@ -808,7 +814,8 @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
|
||||
qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_NO_FLUSH);
|
||||
|
||||
/* backing files always opened read-only */
|
||||
flags &= ~(BDRV_O_RDWR | BDRV_O_COPY_ON_READ);
|
||||
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
|
||||
flags &= ~BDRV_O_COPY_ON_READ;
|
||||
|
||||
/* snapshot=on is handled on the top layer */
|
||||
flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_TEMPORARY);
|
||||
@@ -855,6 +862,14 @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
|
||||
if (qemu_opt_get_bool(opts, BDRV_OPT_CACHE_DIRECT, false)) {
|
||||
*flags |= BDRV_O_NOCACHE;
|
||||
}
|
||||
|
||||
*flags &= ~BDRV_O_RDWR;
|
||||
|
||||
assert(qemu_opt_find(opts, BDRV_OPT_READ_ONLY));
|
||||
if (!qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false)) {
|
||||
*flags |= BDRV_O_RDWR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void update_options_from_flags(QDict *options, int flags)
|
||||
@@ -867,6 +882,10 @@ static void update_options_from_flags(QDict *options, int flags)
|
||||
qdict_put(options, BDRV_OPT_CACHE_NO_FLUSH,
|
||||
qbool_from_bool(flags & BDRV_O_NO_FLUSH));
|
||||
}
|
||||
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
|
||||
qdict_put(options, BDRV_OPT_READ_ONLY,
|
||||
qbool_from_bool(!(flags & BDRV_O_RDWR)));
|
||||
}
|
||||
}
|
||||
|
||||
static void bdrv_assign_node_name(BlockDriverState *bs,
|
||||
@@ -930,6 +949,11 @@ static QemuOptsList bdrv_runtime_opts = {
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "Ignore flush requests",
|
||||
},
|
||||
{
|
||||
.name = BDRV_OPT_READ_ONLY,
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "Node is opened in read-only mode",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
@@ -961,6 +985,8 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file,
|
||||
goto fail_opts;
|
||||
}
|
||||
|
||||
update_flags_from_options(&bs->open_flags, opts);
|
||||
|
||||
driver_name = qemu_opt_get(opts, "driver");
|
||||
drv = bdrv_find_format(driver_name);
|
||||
assert(drv != NULL);
|
||||
@@ -1022,9 +1048,6 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file,
|
||||
bs->drv = drv;
|
||||
bs->opaque = g_malloc0(drv->instance_size);
|
||||
|
||||
/* Apply cache mode options */
|
||||
update_flags_from_options(&bs->open_flags, opts);
|
||||
|
||||
/* Open the image, either directly or using a protocol */
|
||||
open_flags = bdrv_open_flags(bs, bs->open_flags);
|
||||
if (drv->bdrv_file_open) {
|
||||
@@ -1675,6 +1698,25 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Set the BDRV_O_RDWR and BDRV_O_ALLOW_RDWR flags.
|
||||
* FIXME: we're parsing the QDict to avoid having to create a
|
||||
* QemuOpts just for this, but neither option is optimal. */
|
||||
if (g_strcmp0(qdict_get_try_str(options, BDRV_OPT_READ_ONLY), "on") &&
|
||||
!qdict_get_try_bool(options, BDRV_OPT_READ_ONLY, false)) {
|
||||
flags |= (BDRV_O_RDWR | BDRV_O_ALLOW_RDWR);
|
||||
} else {
|
||||
flags &= ~BDRV_O_RDWR;
|
||||
}
|
||||
|
||||
if (flags & BDRV_O_SNAPSHOT) {
|
||||
snapshot_options = qdict_new();
|
||||
bdrv_temp_snapshot_options(&snapshot_flags, snapshot_options,
|
||||
flags, options);
|
||||
/* Let bdrv_backing_options() override "read-only" */
|
||||
qdict_del(options, BDRV_OPT_READ_ONLY);
|
||||
bdrv_backing_options(&flags, options, flags, options);
|
||||
}
|
||||
|
||||
bs->open_flags = flags;
|
||||
bs->options = options;
|
||||
options = qdict_clone_shallow(options);
|
||||
@@ -1699,18 +1741,6 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
|
||||
/* Open image file without format layer */
|
||||
if ((flags & BDRV_O_PROTOCOL) == 0) {
|
||||
if (flags & BDRV_O_RDWR) {
|
||||
flags |= BDRV_O_ALLOW_RDWR;
|
||||
}
|
||||
if (flags & BDRV_O_SNAPSHOT) {
|
||||
snapshot_options = qdict_new();
|
||||
bdrv_temp_snapshot_options(&snapshot_flags, snapshot_options,
|
||||
flags, options);
|
||||
bdrv_backing_options(&flags, options, flags, options);
|
||||
}
|
||||
|
||||
bs->open_flags = flags;
|
||||
|
||||
file = bdrv_open_child(filename, options, "file", bs,
|
||||
&child_file, true, &local_err);
|
||||
if (local_err) {
|
||||
@@ -1895,6 +1925,13 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
|
||||
options = qdict_new();
|
||||
}
|
||||
|
||||
/* Check if this BlockDriverState is already in the queue */
|
||||
QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
|
||||
if (bs == bs_entry->state.bs) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Precedence of options:
|
||||
* 1. Explicitly passed in options (highest)
|
||||
@@ -1915,7 +1952,11 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
|
||||
}
|
||||
|
||||
/* Old explicitly set values (don't overwrite by inherited value) */
|
||||
old_options = qdict_clone_shallow(bs->explicit_options);
|
||||
if (bs_entry) {
|
||||
old_options = qdict_clone_shallow(bs_entry->state.explicit_options);
|
||||
} else {
|
||||
old_options = qdict_clone_shallow(bs->explicit_options);
|
||||
}
|
||||
bdrv_join_options(bs, options, old_options);
|
||||
QDECREF(old_options);
|
||||
|
||||
@@ -1954,8 +1995,13 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
|
||||
child->role, options, flags);
|
||||
}
|
||||
|
||||
bs_entry = g_new0(BlockReopenQueueEntry, 1);
|
||||
QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
|
||||
if (!bs_entry) {
|
||||
bs_entry = g_new0(BlockReopenQueueEntry, 1);
|
||||
QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
|
||||
} else {
|
||||
QDECREF(bs_entry->state.options);
|
||||
QDECREF(bs_entry->state.explicit_options);
|
||||
}
|
||||
|
||||
bs_entry->state.bs = bs;
|
||||
bs_entry->state.options = options;
|
||||
@@ -3013,11 +3059,6 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag)
|
||||
return false;
|
||||
}
|
||||
|
||||
int bdrv_is_snapshot(BlockDriverState *bs)
|
||||
{
|
||||
return !!(bs->open_flags & BDRV_O_SNAPSHOT);
|
||||
}
|
||||
|
||||
/* backing_file can either be relative, or absolute, or a protocol. If it is
|
||||
* relative, it must be relative to the chain. So, passing in bs->filename
|
||||
* from a BDS as backing_file should not be done, as that may be relative to
|
||||
|
||||
@@ -559,6 +559,25 @@ void *blk_get_attached_dev(BlockBackend *blk)
|
||||
return blk->dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the BlockBackend which has the device model @dev attached if it
|
||||
* exists, else null.
|
||||
*
|
||||
* @dev must not be null.
|
||||
*/
|
||||
BlockBackend *blk_by_dev(void *dev)
|
||||
{
|
||||
BlockBackend *blk = NULL;
|
||||
|
||||
assert(dev != NULL);
|
||||
while ((blk = blk_all_next(blk)) != NULL) {
|
||||
if (blk->dev == dev) {
|
||||
return blk;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set @blk's device model callbacks to @ops.
|
||||
* @opaque is the opaque argument to pass to the callbacks.
|
||||
|
||||
+4
-4
@@ -242,14 +242,14 @@ void commit_start(const char *job_id, BlockDriverState *bs,
|
||||
orig_overlay_flags = bdrv_get_flags(overlay_bs);
|
||||
|
||||
/* convert base & overlay_bs to r/w, if necessary */
|
||||
if (!(orig_overlay_flags & BDRV_O_RDWR)) {
|
||||
reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL,
|
||||
orig_overlay_flags | BDRV_O_RDWR);
|
||||
}
|
||||
if (!(orig_base_flags & BDRV_O_RDWR)) {
|
||||
reopen_queue = bdrv_reopen_queue(reopen_queue, base, NULL,
|
||||
orig_base_flags | BDRV_O_RDWR);
|
||||
}
|
||||
if (!(orig_overlay_flags & BDRV_O_RDWR)) {
|
||||
reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL,
|
||||
orig_overlay_flags | BDRV_O_RDWR);
|
||||
}
|
||||
if (reopen_queue) {
|
||||
bdrv_reopen_multiple(reopen_queue, &local_err);
|
||||
if (local_err != NULL) {
|
||||
|
||||
@@ -429,7 +429,7 @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
|
||||
|
||||
if (bs->encrypted) {
|
||||
Error *err = NULL;
|
||||
int64_t sector = (cluster_offset + offset_in_cluster)
|
||||
int64_t sector = (src_cluster_offset + offset_in_cluster)
|
||||
>> BDRV_SECTOR_BITS;
|
||||
assert(s->cipher);
|
||||
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
|
||||
|
||||
+2
-1
@@ -2971,7 +2971,8 @@ static BlockDriver vvfat_write_target = {
|
||||
static void vvfat_qcow_options(int *child_flags, QDict *child_options,
|
||||
int parent_flags, QDict *parent_options)
|
||||
{
|
||||
*child_flags = BDRV_O_RDWR | BDRV_O_NO_FLUSH;
|
||||
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
|
||||
*child_flags = BDRV_O_NO_FLUSH;
|
||||
}
|
||||
|
||||
static const BdrvChildRole child_vvfat_qcow = {
|
||||
|
||||
+149
-164
File diff suppressed because it is too large
Load Diff
+41
-37
@@ -72,12 +72,14 @@ Eject a removable medium.
|
||||
|
||||
Arguments:
|
||||
|
||||
- force: force ejection (json-bool, optional)
|
||||
- device: device name (json-string)
|
||||
- "force": force ejection (json-bool, optional)
|
||||
- "device": block device name (deprecated, use @id instead)
|
||||
(json-string, optional)
|
||||
- "id": the name or QOM path of the guest device (json-string, optional)
|
||||
|
||||
Example:
|
||||
|
||||
-> { "execute": "eject", "arguments": { "device": "ide1-cd0" } }
|
||||
-> { "execute": "eject", "arguments": { "id": "ide0-1-0" } }
|
||||
<- { "return": {} }
|
||||
|
||||
Note: The "force" argument defaults to false.
|
||||
@@ -1457,7 +1459,9 @@ Change I/O throttle limits for a block drive.
|
||||
|
||||
Arguments:
|
||||
|
||||
- "device": device name (json-string)
|
||||
- "device": block device name (deprecated, use @id instead)
|
||||
(json-string, optional)
|
||||
- "id": the name or QOM path of the guest device (json-string, optional)
|
||||
- "bps": total throughput limit in bytes per second (json-int)
|
||||
- "bps_rd": read throughput limit in bytes per second (json-int)
|
||||
- "bps_wr": write throughput limit in bytes per second (json-int)
|
||||
@@ -1481,7 +1485,7 @@ Arguments:
|
||||
|
||||
Example:
|
||||
|
||||
-> { "execute": "block_set_io_throttle", "arguments": { "device": "virtio0",
|
||||
-> { "execute": "block_set_io_throttle", "arguments": { "id": "ide0-1-0",
|
||||
"bps": 1000000,
|
||||
"bps_rd": 0,
|
||||
"bps_wr": 0,
|
||||
@@ -3137,7 +3141,7 @@ Example (2):
|
||||
"arguments": {
|
||||
"options": {
|
||||
"driver": "qcow2",
|
||||
"id": "my_disk",
|
||||
"node-name": "my_disk",
|
||||
"discard": "unmap",
|
||||
"cache": {
|
||||
"direct": true,
|
||||
@@ -3164,18 +3168,9 @@ x-blockdev-del
|
||||
------------
|
||||
Since 2.5
|
||||
|
||||
Deletes a block device thas has been added using blockdev-add.
|
||||
The selected device can be either a block backend or a graph node.
|
||||
|
||||
In the former case the backend will be destroyed, along with its
|
||||
inserted medium if there's any. The command will fail if the backend
|
||||
or its medium are in use.
|
||||
|
||||
In the latter case the node will be destroyed. The command will fail
|
||||
if the node is attached to a block backend or is otherwise being
|
||||
used.
|
||||
|
||||
One of "id" or "node-name" must be specified, but not both.
|
||||
Deletes a block device that has been added using blockdev-add.
|
||||
The command will fail if the node is attached to a device or is
|
||||
otherwise being used.
|
||||
|
||||
This command is still a work in progress and is considered
|
||||
experimental. Stay away from it unless you want to help with its
|
||||
@@ -3183,8 +3178,7 @@ development.
|
||||
|
||||
Arguments:
|
||||
|
||||
- "id": Name of the block backend device to delete (json-string, optional)
|
||||
- "node-name": Name of the graph node to delete (json-string, optional)
|
||||
- "node-name": Name of the graph node to delete (json-string)
|
||||
|
||||
Example:
|
||||
|
||||
@@ -3192,7 +3186,7 @@ Example:
|
||||
"arguments": {
|
||||
"options": {
|
||||
"driver": "qcow2",
|
||||
"id": "drive0",
|
||||
"node-name": "node0",
|
||||
"file": {
|
||||
"driver": "file",
|
||||
"filename": "test.qcow2"
|
||||
@@ -3204,7 +3198,7 @@ Example:
|
||||
<- { "return": {} }
|
||||
|
||||
-> { "execute": "x-blockdev-del",
|
||||
"arguments": { "id": "drive0" }
|
||||
"arguments": { "node-name": "node0" }
|
||||
}
|
||||
<- { "return": {} }
|
||||
|
||||
@@ -3228,7 +3222,9 @@ which no such event will be generated, these include:
|
||||
|
||||
Arguments:
|
||||
|
||||
- "device": block device name (json-string)
|
||||
- "device": block device name (deprecated, use @id instead)
|
||||
(json-string, optional)
|
||||
- "id": the name or QOM path of the guest device (json-string, optional)
|
||||
- "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
|
||||
@@ -3237,7 +3233,7 @@ Arguments:
|
||||
Example:
|
||||
|
||||
-> { "execute": "blockdev-open-tray",
|
||||
"arguments": { "device": "ide1-cd0" } }
|
||||
"arguments": { "id": "ide0-1-0" } }
|
||||
|
||||
<- { "timestamp": { "seconds": 1418751016,
|
||||
"microseconds": 716996 },
|
||||
@@ -3258,12 +3254,14 @@ If the tray was already closed before, this will be a no-op.
|
||||
|
||||
Arguments:
|
||||
|
||||
- "device": block device name (json-string)
|
||||
- "device": block device name (deprecated, use @id instead)
|
||||
(json-string, optional)
|
||||
- "id": the name or QOM path of the guest device (json-string, optional)
|
||||
|
||||
Example:
|
||||
|
||||
-> { "execute": "blockdev-close-tray",
|
||||
"arguments": { "device": "ide1-cd0" } }
|
||||
"arguments": { "id": "ide0-1-0" } }
|
||||
|
||||
<- { "timestamp": { "seconds": 1418751345,
|
||||
"microseconds": 272147 },
|
||||
@@ -3286,18 +3284,20 @@ Stay away from it unless you want to help with its development.
|
||||
|
||||
Arguments:
|
||||
|
||||
- "device": block device name (json-string)
|
||||
- "device": block device name (deprecated, use @id instead)
|
||||
(json-string, optional)
|
||||
- "id": the name or QOM path of the guest device (json-string, optional)
|
||||
|
||||
Example:
|
||||
|
||||
-> { "execute": "x-blockdev-remove-medium",
|
||||
"arguments": { "device": "ide1-cd0" } }
|
||||
"arguments": { "id": "ide0-1-0" } }
|
||||
|
||||
<- { "error": { "class": "GenericError",
|
||||
"desc": "Tray of device 'ide1-cd0' is not open" } }
|
||||
"desc": "Tray of device 'ide0-1-0' is not open" } }
|
||||
|
||||
-> { "execute": "blockdev-open-tray",
|
||||
"arguments": { "device": "ide1-cd0" } }
|
||||
"arguments": { "id": "ide0-1-0" } }
|
||||
|
||||
<- { "timestamp": { "seconds": 1418751627,
|
||||
"microseconds": 549958 },
|
||||
@@ -3308,7 +3308,7 @@ Example:
|
||||
<- { "return": {} }
|
||||
|
||||
-> { "execute": "x-blockdev-remove-medium",
|
||||
"arguments": { "device": "ide1-cd0" } }
|
||||
"arguments": { "device": "ide0-1-0" } }
|
||||
|
||||
<- { "return": {} }
|
||||
|
||||
@@ -3324,7 +3324,9 @@ Stay away from it unless you want to help with its development.
|
||||
|
||||
Arguments:
|
||||
|
||||
- "device": block device name (json-string)
|
||||
- "device": block device name (deprecated, use @id instead)
|
||||
(json-string, optional)
|
||||
- "id": the name or QOM path of the guest device (json-string, optional)
|
||||
- "node-name": root node of the BDS tree to insert into the block device
|
||||
|
||||
Example:
|
||||
@@ -3338,7 +3340,7 @@ Example:
|
||||
<- { "return": {} }
|
||||
|
||||
-> { "execute": "x-blockdev-insert-medium",
|
||||
"arguments": { "device": "ide1-cd0",
|
||||
"arguments": { "id": "ide0-1-0",
|
||||
"node-name": "node0" } }
|
||||
|
||||
<- { "return": {} }
|
||||
@@ -3448,7 +3450,9 @@ and loading a new image file which is inserted as the new medium.
|
||||
|
||||
Arguments:
|
||||
|
||||
- "device": device name (json-string)
|
||||
- "device": block device name (deprecated, use @id instead)
|
||||
(json-string, optional)
|
||||
- "id": the name or QOM path of the guest device (json-string, optional)
|
||||
- "filename": filename of the new image (json-string)
|
||||
- "format": format of the new image (json-string, optional)
|
||||
- "read-only-mode": new read-only mode (json-string, optional)
|
||||
@@ -3459,7 +3463,7 @@ Examples:
|
||||
1. Change a removable medium
|
||||
|
||||
-> { "execute": "blockdev-change-medium",
|
||||
"arguments": { "device": "ide1-cd0",
|
||||
"arguments": { "id": "ide0-1-0",
|
||||
"filename": "/srv/images/Fedora-12-x86_64-DVD.iso",
|
||||
"format": "raw" } }
|
||||
<- { "return": {} }
|
||||
@@ -3467,7 +3471,7 @@ Examples:
|
||||
2. Load a read-only medium into a writable drive
|
||||
|
||||
-> { "execute": "blockdev-change-medium",
|
||||
"arguments": { "device": "isa-fd0",
|
||||
"arguments": { "id": "floppyA",
|
||||
"filename": "/srv/images/ro.img",
|
||||
"format": "raw",
|
||||
"read-only-mode": "retain" } }
|
||||
@@ -3477,7 +3481,7 @@ Examples:
|
||||
"desc": "Could not open '/srv/images/ro.img': Permission denied" } }
|
||||
|
||||
-> { "execute": "blockdev-change-medium",
|
||||
"arguments": { "device": "isa-fd0",
|
||||
"arguments": { "id": "floppyA",
|
||||
"filename": "/srv/images/ro.img",
|
||||
"format": "raw",
|
||||
"read-only-mode": "read-only" } }
|
||||
|
||||
@@ -1376,7 +1376,7 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
Error *err = NULL;
|
||||
|
||||
qmp_eject(device, true, force, &err);
|
||||
qmp_eject(true, device, false, NULL, true, force, &err);
|
||||
hmp_handle_error(mon, &err);
|
||||
}
|
||||
|
||||
@@ -1422,8 +1422,9 @@ void hmp_change(Monitor *mon, const QDict *qdict)
|
||||
}
|
||||
}
|
||||
|
||||
qmp_blockdev_change_medium(device, target, !!arg, arg,
|
||||
!!read_only, read_only_mode, &err);
|
||||
qmp_blockdev_change_medium(true, device, false, NULL, target,
|
||||
!!arg, arg, !!read_only, read_only_mode,
|
||||
&err);
|
||||
if (err &&
|
||||
error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
|
||||
error_free(err);
|
||||
@@ -1924,6 +1925,7 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
BlockBackend *blk;
|
||||
BlockBackend *local_blk = NULL;
|
||||
AioContext *aio_context;
|
||||
const char* device = qdict_get_str(qdict, "device");
|
||||
const char* command = qdict_get_str(qdict, "command");
|
||||
Error *err = NULL;
|
||||
@@ -1939,17 +1941,12 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
|
||||
}
|
||||
}
|
||||
|
||||
if (blk) {
|
||||
AioContext *aio_context = blk_get_aio_context(blk);
|
||||
aio_context_acquire(aio_context);
|
||||
aio_context = blk_get_aio_context(blk);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
qemuio_command(blk, command);
|
||||
qemuio_command(blk, command);
|
||||
|
||||
aio_context_release(aio_context);
|
||||
} else {
|
||||
error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", device);
|
||||
}
|
||||
aio_context_release(aio_context);
|
||||
|
||||
fail:
|
||||
blk_unref(local_blk);
|
||||
|
||||
@@ -107,6 +107,7 @@ typedef struct HDGeometry {
|
||||
#define BDRV_OPT_CACHE_WB "cache.writeback"
|
||||
#define BDRV_OPT_CACHE_DIRECT "cache.direct"
|
||||
#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
|
||||
#define BDRV_OPT_READ_ONLY "read-only"
|
||||
|
||||
|
||||
#define BDRV_SECTOR_BITS 9
|
||||
@@ -414,7 +415,6 @@ void bdrv_get_full_backing_filename_from_filename(const char *backed,
|
||||
const char *backing,
|
||||
char *dest, size_t sz,
|
||||
Error **errp);
|
||||
int bdrv_is_snapshot(BlockDriverState *bs);
|
||||
|
||||
int path_has_protocol(const char *path);
|
||||
int path_is_absolute(const char *path);
|
||||
|
||||
@@ -111,6 +111,8 @@ int blk_attach_dev(BlockBackend *blk, void *dev);
|
||||
void blk_attach_dev_nofail(BlockBackend *blk, void *dev);
|
||||
void blk_detach_dev(BlockBackend *blk, void *dev);
|
||||
void *blk_get_attached_dev(BlockBackend *blk);
|
||||
BlockBackend *blk_by_dev(void *dev);
|
||||
BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
|
||||
void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
|
||||
int blk_pread_unthrottled(BlockBackend *blk, int64_t offset, uint8_t *buf,
|
||||
int count);
|
||||
|
||||
+39
-39
@@ -900,7 +900,7 @@
|
||||
# otherwise. (Since 2.4)
|
||||
#
|
||||
# @compress: #optional true to compress data, if the target format supports it.
|
||||
# (default: false) (since 2.7)
|
||||
# (default: false) (since 2.8)
|
||||
#
|
||||
# @on-source-error: #optional the action to take on an error on the source,
|
||||
# default 'report'. 'stop' and 'enospc' can only be used
|
||||
@@ -941,7 +941,7 @@
|
||||
# for unlimited.
|
||||
#
|
||||
# @compress: #optional true to compress data, if the target format supports it.
|
||||
# (default: false) (since 2.7)
|
||||
# (default: false) (since 2.8)
|
||||
#
|
||||
# @on-source-error: #optional the action to take on an error on the source,
|
||||
# default 'report'. 'stop' and 'enospc' can only be used
|
||||
@@ -1377,7 +1377,9 @@
|
||||
#
|
||||
# A set of parameters describing block throttling.
|
||||
#
|
||||
# @device: The name of the device
|
||||
# @device: #optional Block device name (deprecated, use @id instead)
|
||||
#
|
||||
# @id: #optional The name or QOM path of the guest device (since: 2.8)
|
||||
#
|
||||
# @bps: total throughput limit in bytes per second
|
||||
#
|
||||
@@ -1446,8 +1448,8 @@
|
||||
# Since: 1.1
|
||||
##
|
||||
{ 'struct': 'BlockIOThrottle',
|
||||
'data': { 'device': 'str', 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
|
||||
'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
|
||||
'data': { '*device': 'str', '*id': 'str', 'bps': 'int', 'bps_rd': 'int',
|
||||
'bps_wr': 'int', 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
|
||||
'*bps_max': 'int', '*bps_rd_max': 'int',
|
||||
'*bps_wr_max': 'int', '*iops_max': 'int',
|
||||
'*iops_rd_max': 'int', '*iops_wr_max': 'int',
|
||||
@@ -2215,13 +2217,8 @@
|
||||
# block devices, independent of the block driver:
|
||||
#
|
||||
# @driver: block driver name
|
||||
# @id: #optional id by which the new block device can be referred to.
|
||||
# This option is only allowed on the top level of blockdev-add.
|
||||
# A BlockBackend will be created by blockdev-add if and only if
|
||||
# this option is given.
|
||||
# @node-name: #optional the name of a block driver state node (Since 2.0).
|
||||
# This option is required on the top level of blockdev-add if
|
||||
# the @id option is not given there.
|
||||
# @node-name: #optional the node name of the new node (Since 2.0).
|
||||
# This option is required on the top level of blockdev-add.
|
||||
# @discard: #optional discard-related options (default: ignore)
|
||||
# @cache: #optional cache-related options
|
||||
# @aio: #optional AIO backend (default: threads)
|
||||
@@ -2236,8 +2233,6 @@
|
||||
##
|
||||
{ 'union': 'BlockdevOptions',
|
||||
'base': { 'driver': 'BlockdevDriver',
|
||||
# TODO 'id' is a BB-level option, remove it
|
||||
'*id': 'str',
|
||||
'*node-name': 'str',
|
||||
'*discard': 'BlockdevDiscardOptions',
|
||||
'*cache': 'BlockdevCacheOptions',
|
||||
@@ -2321,29 +2316,18 @@
|
||||
# @x-blockdev-del:
|
||||
#
|
||||
# Deletes a block device that has been added using blockdev-add.
|
||||
# The selected device can be either a block backend or a graph node.
|
||||
#
|
||||
# In the former case the backend will be destroyed, along with its
|
||||
# inserted medium if there's any. The command will fail if the backend
|
||||
# or its medium are in use.
|
||||
#
|
||||
# In the latter case the node will be destroyed. The command will fail
|
||||
# if the node is attached to a block backend or is otherwise being
|
||||
# used.
|
||||
#
|
||||
# One of @id or @node-name must be specified, but not both.
|
||||
# The command will fail if the node is attached to a device or is
|
||||
# otherwise being used.
|
||||
#
|
||||
# This command is still a work in progress and is considered
|
||||
# experimental. Stay away from it unless you want to help with its
|
||||
# development.
|
||||
#
|
||||
# @id: #optional Name of the block backend device to delete.
|
||||
#
|
||||
# @node-name: #optional Name of the graph node to delete.
|
||||
# @node-name: Name of the graph node to delete.
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'command': 'x-blockdev-del', 'data': { '*id': 'str', '*node-name': 'str' } }
|
||||
{ 'command': 'x-blockdev-del', 'data': { 'node-name': 'str' } }
|
||||
|
||||
##
|
||||
# @blockdev-open-tray:
|
||||
@@ -2363,7 +2347,9 @@
|
||||
# to it
|
||||
# - if the guest device does not have an actual tray
|
||||
#
|
||||
# @device: block device name
|
||||
# @device: #optional Block device name (deprecated, use @id instead)
|
||||
#
|
||||
# @id: #optional The name or QOM path of the guest device (since: 2.8)
|
||||
#
|
||||
# @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
|
||||
@@ -2373,7 +2359,8 @@
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'command': 'blockdev-open-tray',
|
||||
'data': { 'device': 'str',
|
||||
'data': { '*device': 'str',
|
||||
'*id': 'str',
|
||||
'*force': 'bool' } }
|
||||
|
||||
##
|
||||
@@ -2385,12 +2372,15 @@
|
||||
#
|
||||
# If the tray was already closed before, this will be a no-op.
|
||||
#
|
||||
# @device: block device name
|
||||
# @device: #optional Block device name (deprecated, use @id instead)
|
||||
#
|
||||
# @id: #optional The name or QOM path of the guest device (since: 2.8)
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'command': 'blockdev-close-tray',
|
||||
'data': { 'device': 'str' } }
|
||||
'data': { '*device': 'str',
|
||||
'*id': 'str' } }
|
||||
|
||||
##
|
||||
# @x-blockdev-remove-medium:
|
||||
@@ -2404,12 +2394,15 @@
|
||||
# This command is still a work in progress and is considered experimental.
|
||||
# Stay away from it unless you want to help with its development.
|
||||
#
|
||||
# @device: block device name
|
||||
# @device: #optional Block device name (deprecated, use @id instead)
|
||||
#
|
||||
# @id: #optional The name or QOM path of the guest device (since: 2.8)
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'command': 'x-blockdev-remove-medium',
|
||||
'data': { 'device': 'str' } }
|
||||
'data': { '*device': 'str',
|
||||
'*id': 'str' } }
|
||||
|
||||
##
|
||||
# @x-blockdev-insert-medium:
|
||||
@@ -2421,14 +2414,17 @@
|
||||
# This command is still a work in progress and is considered experimental.
|
||||
# Stay away from it unless you want to help with its development.
|
||||
#
|
||||
# @device: block device name
|
||||
# @device: #optional Block device name (deprecated, use @id instead)
|
||||
#
|
||||
# @id: #optional The name or QOM path of the guest device (since: 2.8)
|
||||
#
|
||||
# @node-name: name of a node in the block driver state graph
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'command': 'x-blockdev-insert-medium',
|
||||
'data': { 'device': 'str',
|
||||
'data': { '*device': 'str',
|
||||
'*id': 'str',
|
||||
'node-name': 'str'} }
|
||||
|
||||
|
||||
@@ -2458,7 +2454,10 @@
|
||||
# combines blockdev-open-tray, x-blockdev-remove-medium,
|
||||
# x-blockdev-insert-medium and blockdev-close-tray).
|
||||
#
|
||||
# @device: block device name
|
||||
# @device: #optional Block device name (deprecated, use @id instead)
|
||||
#
|
||||
# @id: #optional The name or QOM path of the guest device
|
||||
# (since: 2.8)
|
||||
#
|
||||
# @filename: filename of the new image to be loaded
|
||||
#
|
||||
@@ -2471,7 +2470,8 @@
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'command': 'blockdev-change-medium',
|
||||
'data': { 'device': 'str',
|
||||
'data': { '*device': 'str',
|
||||
'*id': 'str',
|
||||
'filename': 'str',
|
||||
'*format': 'str',
|
||||
'*read-only-mode': 'BlockdevChangeReadOnlyMode' } }
|
||||
|
||||
+7
-2
@@ -125,7 +125,9 @@
|
||||
#
|
||||
# Ejects a device from a removable drive.
|
||||
#
|
||||
# @device: The name of the device
|
||||
# @device: #optional Block device name (deprecated, use @id instead)
|
||||
#
|
||||
# @id: #optional The name or QOM path of the guest device (since: 2.8)
|
||||
#
|
||||
# @force: @optional If true, eject regardless of whether the drive is locked.
|
||||
# If not specified, the default value is false.
|
||||
@@ -137,7 +139,10 @@
|
||||
#
|
||||
# Since: 0.14.0
|
||||
##
|
||||
{ 'command': 'eject', 'data': {'device': 'str', '*force': 'bool'} }
|
||||
{ 'command': 'eject',
|
||||
'data': { '*device': 'str',
|
||||
'*id': 'str',
|
||||
'*force': 'bool' } }
|
||||
|
||||
##
|
||||
# @nbd-server-start:
|
||||
|
||||
+30
-4
@@ -28,6 +28,7 @@
|
||||
#include "qemu/config-file.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/help_option.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
|
||||
/*
|
||||
* Aliases were a bad idea from the start. Let's keep them
|
||||
@@ -801,7 +802,7 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
|
||||
object_unref(OBJECT(dev));
|
||||
}
|
||||
|
||||
void qmp_device_del(const char *id, Error **errp)
|
||||
static DeviceState *find_device_state(const char *id, Error **errp)
|
||||
{
|
||||
Object *obj;
|
||||
|
||||
@@ -819,15 +820,40 @@ void qmp_device_del(const char *id, Error **errp)
|
||||
if (!obj) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", id);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!object_dynamic_cast(obj, TYPE_DEVICE)) {
|
||||
error_setg(errp, "%s is not a hotpluggable device", id);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qdev_unplug(DEVICE(obj), errp);
|
||||
return DEVICE(obj);
|
||||
}
|
||||
|
||||
void qmp_device_del(const char *id, Error **errp)
|
||||
{
|
||||
DeviceState *dev = find_device_state(id, errp);
|
||||
if (dev != NULL) {
|
||||
qdev_unplug(dev, errp);
|
||||
}
|
||||
}
|
||||
|
||||
BlockBackend *blk_by_qdev_id(const char *id, Error **errp)
|
||||
{
|
||||
DeviceState *dev;
|
||||
BlockBackend *blk;
|
||||
|
||||
dev = find_device_state(id, errp);
|
||||
if (dev == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
blk = blk_by_dev(dev);
|
||||
if (!blk) {
|
||||
error_setg(errp, "Device does not have a block device backend");
|
||||
}
|
||||
return blk;
|
||||
}
|
||||
|
||||
void qdev_machine_init(void)
|
||||
|
||||
@@ -431,8 +431,8 @@ void qmp_change(const char *device, const char *target,
|
||||
if (strcmp(device, "vnc") == 0) {
|
||||
qmp_change_vnc(target, has_arg, arg, errp);
|
||||
} else {
|
||||
qmp_blockdev_change_medium(device, target, has_arg, arg, false, 0,
|
||||
errp);
|
||||
qmp_blockdev_change_medium(true, device, false, NULL, target,
|
||||
has_arg, arg, false, 0, errp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
FORMAT_LIST="raw qcow2 qed vmdk vpc"
|
||||
if [ "$#" -ne 0 ]; then
|
||||
FORMAT_LIST="$@"
|
||||
fi
|
||||
|
||||
export QEMU_PROG="$(pwd)/x86_64-softmmu/qemu-system-x86_64"
|
||||
export QEMU_IMG_PROG="$(pwd)/qemu-img"
|
||||
export QEMU_IO_PROG="$(pwd)/qemu-io"
|
||||
@@ -12,10 +17,8 @@ fi
|
||||
cd tests/qemu-iotests
|
||||
|
||||
ret=0
|
||||
./check -T -nocache -raw || ret=1
|
||||
./check -T -nocache -qcow2 || ret=1
|
||||
./check -T -nocache -qed|| ret=1
|
||||
./check -T -nocache -vmdk|| ret=1
|
||||
./check -T -nocache -vpc || ret=1
|
||||
for FMT in $FORMAT_LIST ; do
|
||||
./check -T -nocache -$FMT || ret=1
|
||||
done
|
||||
|
||||
exit $ret
|
||||
|
||||
+32
-39
@@ -782,7 +782,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
self.vm.launch()
|
||||
|
||||
#assemble the quorum block device from the individual files
|
||||
args = { "options" : { "driver": "quorum", "id": "quorum0",
|
||||
args = { "options" : { "driver": "quorum", "node-name": "quorum0",
|
||||
"vote-threshold": 2, "children": [ "img0", "img1", "img2" ] } }
|
||||
if self.has_quorum():
|
||||
result = self.vm.qmp("blockdev-add", **args)
|
||||
@@ -804,13 +804,12 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
|
||||
self.assert_no_active_block_jobs()
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
|
||||
node_name="repair0",
|
||||
replaces="img1",
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
|
||||
sync='full', node_name="repair0", replaces="img1",
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
self.assert_qmp(result, 'return', {})
|
||||
|
||||
self.complete_and_wait(drive="quorum0")
|
||||
self.complete_and_wait(drive="job0")
|
||||
self.assert_has_block_node("repair0", quorum_repair_img)
|
||||
# TODO: a better test requiring some QEMU infrastructure will be added
|
||||
# to check that this file is really driven by quorum
|
||||
@@ -824,13 +823,12 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
|
||||
self.assert_no_active_block_jobs()
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
|
||||
node_name="repair0",
|
||||
replaces="img1",
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
|
||||
sync='full', node_name="repair0", replaces="img1",
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
self.assert_qmp(result, 'return', {})
|
||||
|
||||
self.cancel_and_wait(drive="quorum0", force=True)
|
||||
self.cancel_and_wait(drive="job0", force=True)
|
||||
# here we check that the last registered quorum file has not been
|
||||
# swapped out and unref
|
||||
self.assert_has_block_node(None, quorum_img3)
|
||||
@@ -842,13 +840,12 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
|
||||
self.assert_no_active_block_jobs()
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
|
||||
node_name="repair0",
|
||||
replaces="img1",
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
|
||||
sync='full', node_name="repair0", replaces="img1",
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
self.assert_qmp(result, 'return', {})
|
||||
|
||||
self.wait_ready_and_cancel(drive="quorum0")
|
||||
self.wait_ready_and_cancel(drive="job0")
|
||||
# here we check that the last registered quorum file has not been
|
||||
# swapped out and unref
|
||||
self.assert_has_block_node(None, quorum_img3)
|
||||
@@ -862,13 +859,12 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
|
||||
self.assert_no_active_block_jobs()
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
|
||||
node_name="repair0",
|
||||
replaces="img1",
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
|
||||
sync='full', node_name="repair0", replaces="img1",
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
self.assert_qmp(result, 'return', {})
|
||||
|
||||
result = self.vm.qmp('block-job-pause', device='quorum0')
|
||||
result = self.vm.qmp('block-job-pause', device='job0')
|
||||
self.assert_qmp(result, 'return', {})
|
||||
|
||||
time.sleep(1)
|
||||
@@ -879,10 +875,10 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
result = self.vm.qmp('query-block-jobs')
|
||||
self.assert_qmp(result, 'return[0]/offset', offset)
|
||||
|
||||
result = self.vm.qmp('block-job-resume', device='quorum0')
|
||||
result = self.vm.qmp('block-job-resume', device='job0')
|
||||
self.assert_qmp(result, 'return', {})
|
||||
|
||||
self.complete_and_wait(drive="quorum0")
|
||||
self.complete_and_wait(drive="job0")
|
||||
self.vm.shutdown()
|
||||
self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
|
||||
'target image does not match source after mirroring')
|
||||
@@ -894,7 +890,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
if iotests.qemu_default_machine != 'pc':
|
||||
return
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='drive0', # CD-ROM
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0', device='drive0', # CD-ROM
|
||||
sync='full',
|
||||
node_name='repair0',
|
||||
replaces='img1',
|
||||
@@ -905,18 +901,18 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
if not self.has_quorum():
|
||||
return
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
|
||||
node_name='repair0',
|
||||
replaces='img1',
|
||||
mode='existing',
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
|
||||
sync='full', node_name='repair0', replaces='img1',
|
||||
mode='existing', target=quorum_repair_img,
|
||||
format=iotests.imgfmt)
|
||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||
|
||||
def test_device_not_found(self):
|
||||
if not self.has_quorum():
|
||||
return
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='nonexistent', sync='full',
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0',
|
||||
device='nonexistent', sync='full',
|
||||
node_name='repair0',
|
||||
replaces='img1',
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
@@ -926,7 +922,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
if not self.has_quorum():
|
||||
return
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0',
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0', job_id='job0',
|
||||
node_name='repair0',
|
||||
replaces='img1',
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
@@ -936,8 +932,8 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
if not self.has_quorum():
|
||||
return
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
|
||||
replaces='img1',
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
|
||||
sync='full', replaces='img1',
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||
|
||||
@@ -945,9 +941,8 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
if not self.has_quorum():
|
||||
return
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
|
||||
node_name='repair0',
|
||||
replaces='img77',
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
|
||||
sync='full', node_name='repair0', replaces='img77',
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||
|
||||
@@ -959,19 +954,17 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
snapshot_file=quorum_snapshot_file,
|
||||
snapshot_node_name="snap1");
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
|
||||
node_name='repair0',
|
||||
replaces="img1",
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
|
||||
sync='full', node_name='repair0', replaces="img1",
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||
|
||||
result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
|
||||
node_name='repair0',
|
||||
replaces="snap1",
|
||||
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
|
||||
sync='full', node_name='repair0', replaces="snap1",
|
||||
target=quorum_repair_img, format=iotests.imgfmt)
|
||||
self.assert_qmp(result, 'return', {})
|
||||
|
||||
self.complete_and_wait(drive="quorum0")
|
||||
self.complete_and_wait('job0')
|
||||
self.assert_has_block_node("repair0", quorum_repair_img)
|
||||
# TODO: a better test requiring some QEMU infrastructure will be added
|
||||
# to check that this file is really driven by quorum
|
||||
|
||||
@@ -121,7 +121,7 @@ run_qemu <<EOF
|
||||
"arguments": {
|
||||
"options": {
|
||||
"driver": "$IMGFMT",
|
||||
"id": "disk",
|
||||
"node-name": "disk",
|
||||
"file": {
|
||||
"driver": "file",
|
||||
"filename": "$TEST_IMG"
|
||||
@@ -129,13 +129,13 @@ run_qemu <<EOF
|
||||
}
|
||||
}
|
||||
}
|
||||
{ "execute": "query-block" }
|
||||
{ "execute": "query-named-block-nodes" }
|
||||
{ "execute": "device_add",
|
||||
"arguments": { "driver": "virtio-blk", "drive": "disk",
|
||||
"id": "virtio0" } }
|
||||
{ "execute": "device_del", "arguments": { "id": "virtio0" } }
|
||||
{ "execute": "system_reset" }
|
||||
{ "execute": "query-block" }
|
||||
{ "execute": "query-named-block-nodes" }
|
||||
{ "execute": "quit" }
|
||||
EOF
|
||||
|
||||
|
||||
+128
-83
@@ -258,49 +258,72 @@ Testing:
|
||||
{
|
||||
"return": [
|
||||
{
|
||||
"device": "disk",
|
||||
"locked": false,
|
||||
"removable": true,
|
||||
"inserted": {
|
||||
"iops_rd": 0,
|
||||
"detect_zeroes": "off",
|
||||
"image": {
|
||||
"virtual-size": 134217728,
|
||||
"filename": "TEST_DIR/t.qcow2",
|
||||
"cluster-size": 65536,
|
||||
"format": "qcow2",
|
||||
"actual-size": SIZE,
|
||||
"format-specific": {
|
||||
"type": "qcow2",
|
||||
"data": {
|
||||
"compat": "1.1",
|
||||
"lazy-refcounts": false,
|
||||
"refcount-bits": 16,
|
||||
"corrupt": false
|
||||
}
|
||||
},
|
||||
"dirty-flag": false
|
||||
"iops_rd": 0,
|
||||
"detect_zeroes": "off",
|
||||
"image": {
|
||||
"virtual-size": 134217728,
|
||||
"filename": "TEST_DIR/t.qcow2",
|
||||
"cluster-size": 65536,
|
||||
"format": "qcow2",
|
||||
"actual-size": SIZE,
|
||||
"format-specific": {
|
||||
"type": "qcow2",
|
||||
"data": {
|
||||
"compat": "1.1",
|
||||
"lazy-refcounts": false,
|
||||
"refcount-bits": 16,
|
||||
"corrupt": false
|
||||
}
|
||||
},
|
||||
"iops_wr": 0,
|
||||
"ro": false,
|
||||
"node-name": "NODE_NAME",
|
||||
"backing_file_depth": 0,
|
||||
"drv": "qcow2",
|
||||
"iops": 0,
|
||||
"bps_wr": 0,
|
||||
"write_threshold": 0,
|
||||
"encrypted": false,
|
||||
"bps": 0,
|
||||
"bps_rd": 0,
|
||||
"cache": {
|
||||
"no-flush": false,
|
||||
"direct": false,
|
||||
"writeback": true
|
||||
},
|
||||
"file": "TEST_DIR/t.qcow2",
|
||||
"encryption_key_missing": false
|
||||
"dirty-flag": false
|
||||
},
|
||||
"type": "unknown"
|
||||
"iops_wr": 0,
|
||||
"ro": false,
|
||||
"node-name": "disk",
|
||||
"backing_file_depth": 0,
|
||||
"drv": "qcow2",
|
||||
"iops": 0,
|
||||
"bps_wr": 0,
|
||||
"write_threshold": 0,
|
||||
"encrypted": false,
|
||||
"bps": 0,
|
||||
"bps_rd": 0,
|
||||
"cache": {
|
||||
"no-flush": false,
|
||||
"direct": false,
|
||||
"writeback": true
|
||||
},
|
||||
"file": "TEST_DIR/t.qcow2",
|
||||
"encryption_key_missing": false
|
||||
},
|
||||
{
|
||||
"iops_rd": 0,
|
||||
"detect_zeroes": "off",
|
||||
"image": {
|
||||
"virtual-size": 197120,
|
||||
"filename": "TEST_DIR/t.qcow2",
|
||||
"format": "file",
|
||||
"actual-size": SIZE,
|
||||
"dirty-flag": false
|
||||
},
|
||||
"iops_wr": 0,
|
||||
"ro": false,
|
||||
"node-name": "NODE_NAME",
|
||||
"backing_file_depth": 0,
|
||||
"drv": "file",
|
||||
"iops": 0,
|
||||
"bps_wr": 0,
|
||||
"write_threshold": 0,
|
||||
"encrypted": false,
|
||||
"bps": 0,
|
||||
"bps_rd": 0,
|
||||
"cache": {
|
||||
"no-flush": false,
|
||||
"direct": false,
|
||||
"writeback": true
|
||||
},
|
||||
"file": "TEST_DIR/t.qcow2",
|
||||
"encryption_key_missing": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -319,50 +342,72 @@ Testing:
|
||||
{
|
||||
"return": [
|
||||
{
|
||||
"io-status": "ok",
|
||||
"device": "disk",
|
||||
"locked": false,
|
||||
"removable": true,
|
||||
"inserted": {
|
||||
"iops_rd": 0,
|
||||
"detect_zeroes": "off",
|
||||
"image": {
|
||||
"virtual-size": 134217728,
|
||||
"filename": "TEST_DIR/t.qcow2",
|
||||
"cluster-size": 65536,
|
||||
"format": "qcow2",
|
||||
"actual-size": SIZE,
|
||||
"format-specific": {
|
||||
"type": "qcow2",
|
||||
"data": {
|
||||
"compat": "1.1",
|
||||
"lazy-refcounts": false,
|
||||
"refcount-bits": 16,
|
||||
"corrupt": false
|
||||
}
|
||||
},
|
||||
"dirty-flag": false
|
||||
"iops_rd": 0,
|
||||
"detect_zeroes": "off",
|
||||
"image": {
|
||||
"virtual-size": 134217728,
|
||||
"filename": "TEST_DIR/t.qcow2",
|
||||
"cluster-size": 65536,
|
||||
"format": "qcow2",
|
||||
"actual-size": SIZE,
|
||||
"format-specific": {
|
||||
"type": "qcow2",
|
||||
"data": {
|
||||
"compat": "1.1",
|
||||
"lazy-refcounts": false,
|
||||
"refcount-bits": 16,
|
||||
"corrupt": false
|
||||
}
|
||||
},
|
||||
"iops_wr": 0,
|
||||
"ro": false,
|
||||
"node-name": "NODE_NAME",
|
||||
"backing_file_depth": 0,
|
||||
"drv": "qcow2",
|
||||
"iops": 0,
|
||||
"bps_wr": 0,
|
||||
"write_threshold": 0,
|
||||
"encrypted": false,
|
||||
"bps": 0,
|
||||
"bps_rd": 0,
|
||||
"cache": {
|
||||
"no-flush": false,
|
||||
"direct": false,
|
||||
"writeback": true
|
||||
},
|
||||
"file": "TEST_DIR/t.qcow2",
|
||||
"encryption_key_missing": false
|
||||
"dirty-flag": false
|
||||
},
|
||||
"type": "unknown"
|
||||
"iops_wr": 0,
|
||||
"ro": false,
|
||||
"node-name": "disk",
|
||||
"backing_file_depth": 0,
|
||||
"drv": "qcow2",
|
||||
"iops": 0,
|
||||
"bps_wr": 0,
|
||||
"write_threshold": 0,
|
||||
"encrypted": false,
|
||||
"bps": 0,
|
||||
"bps_rd": 0,
|
||||
"cache": {
|
||||
"no-flush": false,
|
||||
"direct": false,
|
||||
"writeback": true
|
||||
},
|
||||
"file": "TEST_DIR/t.qcow2",
|
||||
"encryption_key_missing": false
|
||||
},
|
||||
{
|
||||
"iops_rd": 0,
|
||||
"detect_zeroes": "off",
|
||||
"image": {
|
||||
"virtual-size": 197120,
|
||||
"filename": "TEST_DIR/t.qcow2",
|
||||
"format": "file",
|
||||
"actual-size": SIZE,
|
||||
"dirty-flag": false
|
||||
},
|
||||
"iops_wr": 0,
|
||||
"ro": false,
|
||||
"node-name": "NODE_NAME",
|
||||
"backing_file_depth": 0,
|
||||
"drv": "file",
|
||||
"iops": 0,
|
||||
"bps_wr": 0,
|
||||
"write_threshold": 0,
|
||||
"encrypted": false,
|
||||
"bps": 0,
|
||||
"bps_rd": 0,
|
||||
"cache": {
|
||||
"no-flush": false,
|
||||
"direct": false,
|
||||
"writeback": true
|
||||
},
|
||||
"file": "TEST_DIR/t.qcow2",
|
||||
"encryption_key_missing": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ run_qemu <<EOF
|
||||
"arguments": {
|
||||
"options": {
|
||||
"driver": "$IMGFMT",
|
||||
"id": "drive0-debug",
|
||||
"node-name": "drive0-debug",
|
||||
"file": {
|
||||
"driver": "blkdebug",
|
||||
"image": "drive0",
|
||||
@@ -159,7 +159,7 @@ run_qemu <<EOF
|
||||
"arguments": {
|
||||
"options": {
|
||||
"driver": "blkverify",
|
||||
"id": "drive0-verify",
|
||||
"node-name": "drive0-verify",
|
||||
"test": "drive0",
|
||||
"raw": {
|
||||
"driver": "file",
|
||||
@@ -195,7 +195,7 @@ run_qemu <<EOF
|
||||
"arguments": {
|
||||
"options": {
|
||||
"driver": "blkverify",
|
||||
"id": "drive0-verify",
|
||||
"node-name": "drive0-verify",
|
||||
"test": {
|
||||
"driver": "$IMGFMT",
|
||||
"file": {
|
||||
@@ -234,7 +234,7 @@ run_qemu <<EOF
|
||||
"arguments": {
|
||||
"options": {
|
||||
"driver": "$IMGFMT",
|
||||
"id": "drive0-debug",
|
||||
"node-name": "drive0-debug",
|
||||
"file": {
|
||||
"driver": "blkdebug",
|
||||
"image": "drive0",
|
||||
|
||||
@@ -119,7 +119,7 @@ run_qemu <<EOF
|
||||
"arguments": {
|
||||
"options": {
|
||||
"driver": "quorum",
|
||||
"id": "drive0-quorum",
|
||||
"node-name": "drive0-quorum",
|
||||
"vote-threshold": 2,
|
||||
"children": [
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user