aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-10-01 18:22:55 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-10-01 18:22:55 +0100
commite32e62f2533cf33a14110a2358526e43d6f362d7 (patch)
tree4e8232bc4a33b6f4f16f4ded017399b718fa70a5
parenta2ef4d9e95400cd387ab4ae19a317741e458fb07 (diff)
parentdd353157942a59c21da07da5ac8749a871f7c3ed (diff)
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches: - qcow2 cache option default changes (Linux: 32 MB maximum, limited by whatever cache size can be made use of with the specific image; default cache-clean-interval of 10 minutes) - reopen: Allow specifying unchanged child node references, and changing a few generic options (discard, detect-zeroes) - Fix werror/rerror defaults for -device drive=<node-name> - Test case fixes # gpg: Signature made Mon 01 Oct 2018 18:17:35 BST # gpg: using RSA key 7F09B272C88F2FD6 # 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: (23 commits) tests/test-bdrv-drain: Fix too late qemu_event_reset() test-replication: Lock AioContext around blk_unref() qcow2: Fix cache-clean-interval documentation block-backend: Set werror/rerror defaults in blk_new() qcow2: Explicit number replaced by a constant qcow2: Set the default cache-clean-interval to 10 minutes qcow2: Resize the cache upon image resizing qcow2: Increase the default upper limit on the L2 cache size qcow2: Assign the L2 cache relatively to the image size qcow2: Avoid duplication in setting the refcount cache size qcow2: Make sizes more humanly readable include: Add a lookup table of sizes qcow2: Options' documentation fixes block: Allow changing 'detect-zeroes' on reopen block: Allow changing 'discard' on reopen file-posix: Forbid trying to change unsupported options during reopen block: Forbid trying to change unsupported options during reopen block: Allow child references on reopen block: Don't look for child references in append_open_options() block: Remove child references from bs->{options,explicit_options} ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--block.c135
-rw-r--r--block/block-backend.c3
-rw-r--r--block/file-posix.c19
-rw-r--r--block/qcow2.c43
-rw-r--r--block/qcow2.h19
-rw-r--r--docs/qcow2-cache.txt59
-rw-r--r--include/block/block.h1
-rw-r--r--include/qemu/units.h55
-rw-r--r--qapi/block-core.json4
-rw-r--r--qemu-io-cmds.c2
-rw-r--r--qemu-options.hx12
-rw-r--r--tests/qemu-iotests/067.out1
-rwxr-xr-xtests/qemu-iotests/1378
-rw-r--r--tests/qemu-iotests/137.out4
-rw-r--r--tests/qemu-iotests/153.out76
-rw-r--r--tests/qemu-iotests/182.out2
-rw-r--r--tests/test-bdrv-drain.c4
-rw-r--r--tests/test-replication.c11
18 files changed, 307 insertions, 151 deletions
diff --git a/block.c b/block.c
index c298ca6a19..7710b399a3 100644
--- a/block.c
+++ b/block.c
@@ -764,6 +764,31 @@ static void bdrv_join_options(BlockDriverState *bs, QDict *options,
}
}
+static BlockdevDetectZeroesOptions bdrv_parse_detect_zeroes(QemuOpts *opts,
+ int open_flags,
+ Error **errp)
+{
+ Error *local_err = NULL;
+ char *value = qemu_opt_get_del(opts, "detect-zeroes");
+ BlockdevDetectZeroesOptions detect_zeroes =
+ qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, value,
+ BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err);
+ g_free(value);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return detect_zeroes;
+ }
+
+ if (detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP &&
+ !(open_flags & BDRV_O_UNMAP))
+ {
+ error_setg(errp, "setting detect-zeroes to unmap is not allowed "
+ "without setting discard operation to unmap");
+ }
+
+ return detect_zeroes;
+}
+
/**
* Set open flags for a given discard mode
*
@@ -1094,19 +1119,19 @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
*flags &= ~BDRV_O_CACHE_MASK;
assert(qemu_opt_find(opts, BDRV_OPT_CACHE_NO_FLUSH));
- if (qemu_opt_get_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, false)) {
+ if (qemu_opt_get_bool_del(opts, BDRV_OPT_CACHE_NO_FLUSH, false)) {
*flags |= BDRV_O_NO_FLUSH;
}
assert(qemu_opt_find(opts, BDRV_OPT_CACHE_DIRECT));
- if (qemu_opt_get_bool(opts, BDRV_OPT_CACHE_DIRECT, false)) {
+ if (qemu_opt_get_bool_del(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)) {
+ if (!qemu_opt_get_bool_del(opts, BDRV_OPT_READ_ONLY, false)) {
*flags |= BDRV_O_RDWR;
}
@@ -1328,7 +1353,6 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
const char *driver_name = NULL;
const char *node_name = NULL;
const char *discard;
- const char *detect_zeroes;
QemuOpts *opts;
BlockDriver *drv;
Error *local_err = NULL;
@@ -1417,29 +1441,12 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
}
}
- detect_zeroes = qemu_opt_get(opts, "detect-zeroes");
- if (detect_zeroes) {
- BlockdevDetectZeroesOptions value =
- qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup,
- detect_zeroes,
- BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
- &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- ret = -EINVAL;
- goto fail_opts;
- }
-
- if (value == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP &&
- !(bs->open_flags & BDRV_O_UNMAP))
- {
- error_setg(errp, "setting detect-zeroes to unmap is not allowed "
- "without setting discard operation to unmap");
- ret = -EINVAL;
- goto fail_opts;
- }
-
- bs->detect_zeroes = value;
+ bs->detect_zeroes =
+ bdrv_parse_detect_zeroes(opts, bs->open_flags, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ ret = -EINVAL;
+ goto fail_opts;
}
if (filename != NULL) {
@@ -2763,12 +2770,15 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
}
}
- /* Remove all children options from bs->options and bs->explicit_options */
+ /* Remove all children options and references
+ * from bs->options and bs->explicit_options */
QLIST_FOREACH(child, &bs->children, next) {
char *child_key_dot;
child_key_dot = g_strdup_printf("%s.", child->name);
qdict_extract_subqdict(bs->explicit_options, NULL, child_key_dot);
qdict_extract_subqdict(bs->options, NULL, child_key_dot);
+ qdict_del(bs->explicit_options, child->name);
+ qdict_del(bs->options, child->name);
g_free(child_key_dot);
}
@@ -3153,7 +3163,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
BlockDriver *drv;
QemuOpts *opts;
QDict *orig_reopen_opts;
- const char *value;
+ char *discard = NULL;
bool read_only;
assert(reopen_state != NULL);
@@ -3176,18 +3186,28 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
update_flags_from_options(&reopen_state->flags, opts);
- /* node-name and driver must be unchanged. Put them back into the QDict, so
- * that they are checked at the end of this function. */
- value = qemu_opt_get(opts, "node-name");
- if (value) {
- qdict_put_str(reopen_state->options, "node-name", value);
+ discard = qemu_opt_get_del(opts, "discard");
+ if (discard != NULL) {
+ if (bdrv_parse_discard_flags(discard, &reopen_state->flags) != 0) {
+ error_setg(errp, "Invalid discard option");
+ ret = -EINVAL;
+ goto error;
+ }
}
- value = qemu_opt_get(opts, "driver");
- if (value) {
- qdict_put_str(reopen_state->options, "driver", value);
+ reopen_state->detect_zeroes =
+ bdrv_parse_detect_zeroes(opts, reopen_state->flags, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ ret = -EINVAL;
+ goto error;
}
+ /* All other options (including node-name and driver) must be unchanged.
+ * Put them back into the QDict, so that they are checked at the end
+ * of this function. */
+ qemu_opts_to_qdict(opts, reopen_state->options);
+
/* If we are to stay read-only, do not allow permission change
* to r/w. Attempting to set to r/w may fail if either BDRV_O_ALLOW_RDWR is
* not set, or if the BDS still has copy_on_read enabled */
@@ -3239,6 +3259,24 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
QObject *new = entry->value;
QObject *old = qdict_get(reopen_state->bs->options, entry->key);
+ /* Allow child references (child_name=node_name) as long as they
+ * point to the current child (i.e. everything stays the same). */
+ if (qobject_type(new) == QTYPE_QSTRING) {
+ BdrvChild *child;
+ QLIST_FOREACH(child, &reopen_state->bs->children, next) {
+ if (!strcmp(child->name, entry->key)) {
+ break;
+ }
+ }
+
+ if (child) {
+ const char *str = qobject_get_try_str(new);
+ if (!strcmp(child->bs->node_name, str)) {
+ continue; /* Found child with this name, skip option */
+ }
+ }
+ }
+
/*
* TODO: When using -drive to specify blockdev options, all values
* will be strings; however, when using -blockdev, blockdev-add or
@@ -3278,6 +3316,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
error:
qemu_opts_del(opts);
qobject_unref(orig_reopen_opts);
+ g_free(discard);
return ret;
}
@@ -3290,6 +3329,7 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
{
BlockDriver *drv;
BlockDriverState *bs;
+ BdrvChild *child;
bool old_can_write, new_can_write;
assert(reopen_state != NULL);
@@ -3313,6 +3353,14 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
bs->options = reopen_state->options;
bs->open_flags = reopen_state->flags;
bs->read_only = !(reopen_state->flags & BDRV_O_RDWR);
+ bs->detect_zeroes = reopen_state->detect_zeroes;
+
+ /* Remove child references from bs->options and bs->explicit_options.
+ * Child options were already removed in bdrv_reopen_queue_child() */
+ QLIST_FOREACH(child, &bs->children, next) {
+ qdict_del(bs->explicit_options, child->name);
+ qdict_del(bs->options, child->name);
+ }
bdrv_refresh_limits(bs, NULL);
@@ -5139,23 +5187,12 @@ static bool append_open_options(QDict *d, BlockDriverState *bs)
{
const QDictEntry *entry;
QemuOptDesc *desc;
- BdrvChild *child;
bool found_any = false;
for (entry = qdict_first(bs->options); entry;
entry = qdict_next(bs->options, entry))
{
- /* Exclude node-name references to children */
- QLIST_FOREACH(child, &bs->children, next) {
- if (!strcmp(entry->key, child->name)) {
- break;
- }
- }
- if (child) {
- continue;
- }
-
- /* And exclude all non-driver-specific options */
+ /* Exclude all non-driver-specific options */
for (desc = bdrv_runtime_opts.desc; desc->name; desc++) {
if (!strcmp(qdict_entry_key(entry), desc->name)) {
break;
diff --git a/block/block-backend.c b/block/block-backend.c
index 7b1ec5071b..dc0cd57724 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -325,6 +325,9 @@ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
blk->shared_perm = shared_perm;
blk_set_enable_write_cache(blk, true);
+ blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT;
+ blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
+
block_acct_init(&blk->stats);
notifier_list_init(&blk->remove_bs_notifiers);
diff --git a/block/file-posix.c b/block/file-posix.c
index fe83cbf0eb..2da3a76355 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -741,8 +741,6 @@ static int raw_check_lock_bytes(int fd, uint64_t perm, uint64_t shared_perm,
"Failed to get \"%s\" lock",
perm_name);
g_free(perm_name);
- error_append_hint(errp,
- "Is another process using the image?\n");
return ret;
}
}
@@ -758,8 +756,6 @@ static int raw_check_lock_bytes(int fd, uint64_t perm, uint64_t shared_perm,
"Failed to get shared \"%s\" lock",
perm_name);
g_free(perm_name);
- error_append_hint(errp,
- "Is another process using the image?\n");
return ret;
}
}
@@ -796,6 +792,9 @@ static int raw_handle_perm_lock(BlockDriverState *bs,
if (!ret) {
return 0;
}
+ error_append_hint(errp,
+ "Is another process using the image [%s]?\n",
+ bs->filename);
}
op = RAW_PL_ABORT;
/* fall through to unlock bytes. */
@@ -850,8 +849,13 @@ static int raw_reopen_prepare(BDRVReopenState *state,
goto out;
}
- rs->check_cache_dropped = qemu_opt_get_bool(opts, "x-check-cache-dropped",
- s->check_cache_dropped);
+ rs->check_cache_dropped =
+ qemu_opt_get_bool_del(opts, "x-check-cache-dropped", false);
+
+ /* This driver's reopen function doesn't currently allow changing
+ * other options, so let's put them back in the original QDict and
+ * bdrv_reopen_prepare() will detect changes and complain. */
+ qemu_opts_to_qdict(opts, state->options);
if (s->type == FTYPE_CD) {
rs->open_flags |= O_NONBLOCK;
@@ -2217,6 +2221,9 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
/* Step two: Check that nobody else has taken conflicting locks */
result = raw_check_lock_bytes(fd, perm, shared, errp);
if (result < 0) {
+ error_append_hint(errp,
+ "Is another process using the image [%s]?\n",
+ file_opts->filename);
goto out_unlock;
}
diff --git a/block/qcow2.c b/block/qcow2.c
index c13153735a..7277feda13 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -777,29 +777,35 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
uint64_t *refcount_cache_size, Error **errp)
{
BDRVQcow2State *s = bs->opaque;
- uint64_t combined_cache_size;
+ uint64_t combined_cache_size, l2_cache_max_setting;
bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set;
int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
+ uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
+ uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
refcount_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_REFCOUNT_CACHE_SIZE);
combined_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_CACHE_SIZE, 0);
- *l2_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_L2_CACHE_SIZE, 0);
+ l2_cache_max_setting = qemu_opt_get_size(opts, QCOW2_OPT_L2_CACHE_SIZE,
+ DEFAULT_L2_CACHE_MAX_SIZE);
*refcount_cache_size = qemu_opt_get_size(opts,
QCOW2_OPT_REFCOUNT_CACHE_SIZE, 0);
*l2_cache_entry_size = qemu_opt_get_size(
opts, QCOW2_OPT_L2_CACHE_ENTRY_SIZE, s->cluster_size);
+ *l2_cache_size = MIN(max_l2_cache, l2_cache_max_setting);
+
if (combined_cache_size_set) {
if (l2_cache_size_set && refcount_cache_size_set) {
error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE
" and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set "
"at the same time");
return;
- } else if (*l2_cache_size > combined_cache_size) {
+ } else if (l2_cache_size_set &&
+ (l2_cache_max_setting > combined_cache_size)) {
error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed "
QCOW2_OPT_CACHE_SIZE);
return;
@@ -814,9 +820,6 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
} else if (refcount_cache_size_set) {
*l2_cache_size = combined_cache_size - *refcount_cache_size;
} else {
- uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
- uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
-
/* Assign as much memory as possible to the L2 cache, and
* use the remainder for the refcount cache */
if (combined_cache_size >= max_l2_cache + min_refcount_cache) {
@@ -828,16 +831,9 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
*l2_cache_size = combined_cache_size - *refcount_cache_size;
}
}
- } else {
- if (!l2_cache_size_set) {
- *l2_cache_size = MAX(DEFAULT_L2_CACHE_BYTE_SIZE,
- (uint64_t)DEFAULT_L2_CACHE_CLUSTERS
- * s->cluster_size);
- }
- if (!refcount_cache_size_set) {
- *refcount_cache_size = min_refcount_cache;
- }
}
+ /* l2_cache_size and refcount_cache_size are ensured to have at least
+ * their minimum values in qcow2_update_options_prepare() */
if (*l2_cache_entry_size < (1 << MIN_CLUSTER_BITS) ||
*l2_cache_entry_size > s->cluster_size ||
@@ -948,7 +944,7 @@ static int qcow2_update_options_prepare(BlockDriverState *bs,
/* New interval for cache cleanup timer */
r->cache_clean_interval =
qemu_opt_get_number(opts, QCOW2_OPT_CACHE_CLEAN_INTERVAL,
- s->cache_clean_interval);
+ DEFAULT_CACHE_CLEAN_INTERVAL);
#ifndef CONFIG_LINUX
if (r->cache_clean_interval != 0) {
error_setg(errp, QCOW2_OPT_CACHE_CLEAN_INTERVAL
@@ -1328,7 +1324,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
/* 2^(s->refcount_order - 3) is the refcount width in bytes */
s->refcount_block_bits = s->cluster_bits - (s->refcount_order - 3);
s->refcount_block_size = 1 << s->refcount_block_bits;
- bs->total_sectors = header.size / 512;
+ bs->total_sectors = header.size / BDRV_SECTOR_SIZE;
s->csize_shift = (62 - (s->cluster_bits - 8));
s->csize_mask = (1 << (s->cluster_bits - 8)) - 1;
s->cluster_offset_mask = (1LL << s->csize_shift) - 1;
@@ -3422,6 +3418,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
uint64_t old_length;
int64_t new_l1_size;
int ret;
+ QDict *options;
if (prealloc != PREALLOC_MODE_OFF && prealloc != PREALLOC_MODE_METADATA &&
prealloc != PREALLOC_MODE_FALLOC && prealloc != PREALLOC_MODE_FULL)
@@ -3453,7 +3450,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
goto fail;
}
- old_length = bs->total_sectors * 512;
+ old_length = bs->total_sectors * BDRV_SECTOR_SIZE;
new_l1_size = size_to_l1(s, offset);
if (offset < old_length) {
@@ -3646,6 +3643,8 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
}
}
+ bs->total_sectors = offset / BDRV_SECTOR_SIZE;
+
/* write updated header.size */
offset = cpu_to_be64(offset);
ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
@@ -3656,6 +3655,14 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
}
s->l1_vm_state_index = new_l1_size;
+
+ /* Update cache sizes */
+ options = qdict_clone_shallow(bs->options);
+ ret = qcow2_update_options(bs, options, s->flags, errp);
+ qobject_unref(options);
+ if (ret < 0) {
+ goto fail;
+ }
ret = 0;
fail:
qemu_co_mutex_unlock(&s->lock);
diff --git a/block/qcow2.h b/block/qcow2.h
index 81b844e936..ba430316b9 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -27,6 +27,7 @@
#include "crypto/block.h"
#include "qemu/coroutine.h"
+#include "qemu/units.h"
//#define DEBUG_ALLOC
//#define DEBUG_ALLOC2
@@ -43,11 +44,11 @@
/* 8 MB refcount table is enough for 2 PB images at 64k cluster size
* (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
-#define QCOW_MAX_REFTABLE_SIZE 0x800000
+#define QCOW_MAX_REFTABLE_SIZE S_8MiB
/* 32 MB L1 table is enough for 2 PB images at 64k cluster size
* (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
-#define QCOW_MAX_L1_SIZE 0x2000000
+#define QCOW_MAX_L1_SIZE S_32MiB
/* Allow for an average of 1k per snapshot table entry, should be plenty of
* space for snapshot names and IDs */
@@ -73,12 +74,16 @@
/* Must be at least 4 to cover all cases of refcount table growth */
#define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */
-/* Whichever is more */
-#define DEFAULT_L2_CACHE_CLUSTERS 8 /* clusters */
-#define DEFAULT_L2_CACHE_BYTE_SIZE 1048576 /* bytes */
-
-#define DEFAULT_CLUSTER_SIZE 65536
+#ifdef CONFIG_LINUX
+#define DEFAULT_L2_CACHE_MAX_SIZE S_32MiB
+#define DEFAULT_CACHE_CLEAN_INTERVAL 600 /* seconds */
+#else
+#define DEFAULT_L2_CACHE_MAX_SIZE S_8MiB
+/* Cache clean interval is currently available only on Linux, so must be 0 */
+#define DEFAULT_CACHE_CLEAN_INTERVAL 0
+#endif
+#define DEFAULT_CLUSTER_SIZE S_64KiB
#define QCOW2_OPT_LAZY_REFCOUNTS "lazy-refcounts"
#define QCOW2_OPT_DISCARD_REQUEST "pass-discard-request"
diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt
index 8a09a5cc5f..c459bf5dd3 100644
--- a/docs/qcow2-cache.txt
+++ b/docs/qcow2-cache.txt
@@ -79,14 +79,14 @@ Choosing the right cache sizes
In order to choose the cache sizes we need to know how they relate to
the amount of allocated space.
-The amount of virtual disk that can be mapped by the L2 and refcount
+The part of the virtual disk that can be mapped by the L2 and refcount
caches (in bytes) is:
disk_size = l2_cache_size * cluster_size / 8
disk_size = refcount_cache_size * cluster_size * 8 / refcount_bits
With the default values for cluster_size (64KB) and refcount_bits
-(16), that is
+(16), this becomes:
disk_size = l2_cache_size * 8192
disk_size = refcount_cache_size * 32768
@@ -97,12 +97,16 @@ need:
l2_cache_size = disk_size_GB * 131072
refcount_cache_size = disk_size_GB * 32768
-QEMU has a default L2 cache of 1MB (1048576 bytes) and a refcount
-cache of 256KB (262144 bytes), so using the formulas we've just seen
-we have
+For example, 1MB of L2 cache is needed to cover every 8 GB of the virtual
+image size (given that the default cluster size is used):
- 1048576 / 131072 = 8 GB of virtual disk covered by that cache
- 262144 / 32768 = 8 GB
+ 8 GB / 8192 = 1 MB
+
+The refcount cache is 4 times the cluster size by default. With the default
+cluster size of 64 KB, it is 256 KB (262144 bytes). This is sufficient for
+8 GB of image size:
+
+ 262144 * 32768 = 8 GB
How to configure the cache sizes
@@ -121,8 +125,15 @@ There are a few things that need to be taken into account:
- Both caches must have a size that is a multiple of the cluster size
(or the cache entry size: see "Using smaller cache sizes" below).
- - The default L2 cache size is 8 clusters or 1MB (whichever is more),
- and the minimum is 2 clusters (or 2 cache entries, see below).
+ - The maximum L2 cache size is 32 MB by default on Linux platforms (enough
+ for full coverage of 256 GB images, with the default cluster size). This
+ value can be modified using the "l2-cache-size" option. QEMU will not use
+ more memory than needed to hold all of the image's L2 tables, regardless
+ of this max. value.
+ On non-Linux platforms the maximal value is smaller by default (8 MB) and
+ this difference stems from the fact that on Linux the cache can be cleared
+ periodically if needed, using the "cache-clean-interval" option (see below).
+ The minimal L2 cache size is 2 clusters (or 2 cache entries, see below).
- The default (and minimum) refcount cache size is 4 clusters.
@@ -130,6 +141,9 @@ There are a few things that need to be taken into account:
memory as possible to the L2 cache before increasing the refcount
cache size.
+ - At most two of "l2-cache-size", "refcount-cache-size", and "cache-size"
+ can be set simultaneously.
+
Unlike L2 tables, refcount blocks are not used during normal I/O but
only during allocations and internal snapshots. In most cases they are
accessed sequentially (even during random guest I/O) so increasing the
@@ -177,9 +191,10 @@ Some things to take into account:
always uses the cluster size as the entry size.
- If the L2 cache is big enough to hold all of the image's L2 tables
- (as explained in the "Choosing the right cache sizes" section
- earlier in this document) then none of this is necessary and you
- can omit the "l2-cache-entry-size" parameter altogether.
+ (as explained in the "Choosing the right cache sizes" and "How to
+ configure the cache sizes" sections in this document) then none of
+ this is necessary and you can omit the "l2-cache-entry-size"
+ parameter altogether.
Reducing the memory usage
@@ -187,18 +202,18 @@ Reducing the memory usage
It is possible to clean unused cache entries in order to reduce the
memory usage during periods of low I/O activity.
-The parameter "cache-clean-interval" defines an interval (in seconds).
-All cache entries that haven't been accessed during that interval are
-removed from memory.
+The parameter "cache-clean-interval" defines an interval (in seconds),
+after which all the cache entries that haven't been accessed during the
+interval are removed from memory. Setting this parameter to 0 disables this
+feature.
-This example removes all unused cache entries every 15 minutes:
+The following example removes all unused cache entries every 15 minutes:
-drive file=hd.qcow2,cache-clean-interval=900
-If unset, the default value for this parameter is 0 and it disables
-this feature.
+If unset, the default value for this parameter is 600 on platforms which
+support this functionality, and is 0 (disabled) on other platforms.
-Note that this functionality currently relies on the MADV_DONTNEED
-argument for madvise() to actually free the memory. This is a
-Linux-specific feature, so cache-clean-interval is not supported in
-other systems.
+This functionality currently relies on the MADV_DONTNEED argument for
+madvise() to actually free the memory. This is a Linux-specific feature,
+so cache-clean-interval is not supported on other systems.
diff --git a/include/block/block.h b/include/block/block.h
index 4edc1e8afa..b189cf422e 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -184,6 +184,7 @@ typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
typedef struct BDRVReopenState {
BlockDriverState *bs;
int flags;
+ BlockdevDetectZeroesOptions detect_zeroes;
uint64_t perm, shared_perm;
QDict *options;
QDict *explicit_options;
diff --git a/include/qemu/units.h b/include/qemu/units.h
index 692db3fbb2..68a7758650 100644
--- a/include/qemu/units.h
+++ b/include/qemu/units.h
@@ -17,4 +17,59 @@
#define PiB (INT64_C(1) << 50)
#define EiB (INT64_C(1) << 60)
+#define S_1KiB 1024
+#define S_2KiB 2048
+#define S_4KiB 4096
+#define S_8KiB 8192
+#define S_16KiB 16384
+#define S_32KiB 32768
+#define S_64KiB 65536
+#define S_128KiB 131072
+#define S_256KiB 262144
+#define S_512KiB 524288
+#define S_1MiB 1048576
+#define S_2MiB 2097152
+#define S_4MiB 4194304
+#define S_8MiB 8388608
+#define S_16MiB 16777216
+#define S_32MiB 33554432
+#define S_64MiB 67108864
+#define S_128MiB 134217728
+#define S_256MiB 268435456
+#define S_512MiB 536870912
+#define S_1GiB 1073741824
+#define S_2GiB 2147483648
+#define S_4GiB 4294967296
+#define S_8GiB 8589934592
+#define S_16GiB 17179869184
+#define S_32GiB 34359738368
+#define S_64GiB 68719476736
+#define S_128GiB 137438953472
+#define S_256GiB 274877906944
+#define S_512GiB 549755813888
+#define S_1TiB 1099511627776
+#define S_2TiB 2199023255552
+#define S_4TiB 4398046511104
+#define S_8TiB 8796093022208
+#define S_16TiB 17592186044416
+#define S_32TiB 35184372088832
+#define S_64TiB 70368744177664
+#define S_128TiB 140737488355328
+#define S_256TiB 281474976710656
+#define S_512TiB 562949953421312
+#define S_1PiB 1125899906842624
+#define S_2PiB 2251799813685248
+#define S_4PiB 4503599627370496
+#define S_8PiB 9007199254740992
+#define S_16PiB 18014398509481984
+#define S_32PiB 36028797018963968
+#define S_64PiB 72057594037927936
+#define S_128PiB 144115188075855872
+#define S_256PiB 288230376151711744
+#define S_512PiB 576460752303423488
+#define S_1EiB 1152921504606846976
+#define S_2EiB 2305843009213693952
+#define S_4EiB 4611686018427387904
+#define S_8EiB 9223372036854775808
+
#endif
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 58ec9931c7..cfb37f8c1d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2897,7 +2897,9 @@
#
# @cache-clean-interval: clean unused entries in the L2 and refcount
# caches. The interval is in seconds. The default value
-# is 0 and it disables this feature (since 2.5)
+# is 600 on supporting platforms, and 0 on other
+# platforms. 0 disables this feature. (since 2.5)
+#
# @encrypt: Image decryption options. Mandatory for
# encrypted images, except when doing a metadata-only
# probe of the image. (since 2.10)
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 5bf5f28178..db0b3ee5ef 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -2025,7 +2025,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
return -EINVAL;
}
- if (writethrough != blk_enable_write_cache(blk) &&
+ if (!writethrough != blk_enable_write_cache(blk) &&
blk_get_attached_dev(blk))
{
error_report("Cannot change cache.writeback: Device attached");
diff --git a/qemu-options.hx b/qemu-options.hx
index a642ad297f..f139459e80 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -732,19 +732,23 @@ image file)
@item cache-size
The maximum total size of the L2 table and refcount block caches in bytes
-(default: 1048576 bytes or 8 clusters, whichever is larger)
+(default: the sum of l2-cache-size and refcount-cache-size)
@item l2-cache-size
The maximum size of the L2 table cache in bytes
-(default: 4/5 of the total cache size)
+(default: if cache-size is not specified - 32M on Linux platforms, and 8M on
+non-Linux platforms; otherwise, as large as possible within the cache-size,
+while permitting the requested or the minimal refcount cache size)
@item refcount-cache-size
The maximum size of the refcount block cache in bytes
-(default: 1/5 of the total cache size)
+(default: 4 times the cluster size; or if cache-size is specified, the part of
+it which is not used for the L2 cache)
@item cache-clean-interval
Clean unused entries in the L2 and refcount caches. The interval is in seconds.
-The default value is 0 and it disables this feature.
+The default value is 600 on supporting platforms, and 0 on other platforms.
+Setting it to 0 disables this feature.
@item pass-discard-request
Whether discard requests to the qcow2 device should be forwarded to the data
diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out
index 2e71cff3ce..b10c71db03 100644
--- a/tests/qemu-iotests/067.out
+++ b/tests/qemu-iotests/067.out
@@ -385,6 +385,7 @@ Testing: -device virtio-scsi -device scsi-cd,id=cd0
{
"return": [
{
+ "io-status": "ok",
"device": "",
"locked": false,
"removable": true,
diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137
index 87965625d8..19e8597306 100755
--- a/tests/qemu-iotests/137
+++ b/tests/qemu-iotests/137
@@ -109,7 +109,6 @@ $QEMU_IO \
-c "reopen -o cache-size=1M,l2-cache-size=64k,refcount-cache-size=64k" \
-c "reopen -o cache-size=1M,l2-cache-size=2M" \
-c "reopen -o cache-size=1M,refcount-cache-size=2M" \
- -c "reopen -o l2-cache-size=256T" \
-c "reopen -o l2-cache-entry-size=33k" \
-c "reopen -o l2-cache-entry-size=128k" \
-c "reopen -o refcount-cache-size=256T" \
@@ -119,6 +118,13 @@ $QEMU_IO \
-c "reopen -o cache-clean-interval=-1" \
"$TEST_IMG" | _filter_qemu_io
+IMGOPTS="cluster_size=256k" _make_test_img 32P
+$QEMU_IO \
+ -c "reopen -o l2-cache-entry-size=512,l2-cache-size=1T" \
+ "$TEST_IMG" | _filter_qemu_io
+
+_make_test_img 64M
+
echo
echo === Test transaction semantics ===
echo
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
index 6a2ffc71fd..2c080b72f3 100644
--- a/tests/qemu-iotests/137.out
+++ b/tests/qemu-iotests/137.out
@@ -19,7 +19,6 @@ Parameter 'lazy-refcounts' expects 'on' or 'off'
cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
l2-cache-size may not exceed cache-size
refcount-cache-size may not exceed cache-size
-L2 cache size too big
L2 cache entry size must be a power of two between 512 and the cluster size (65536)
L2 cache entry size must be a power of two between 512 and the cluster size (65536)
Refcount cache size too big
@@ -27,6 +26,9 @@ Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-c
Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
Cache clean interval too big
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=36028797018963968
+L2 cache size too big
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
=== Test transaction semantics ===
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
index 93eaf10486..884254868c 100644
--- a/tests/qemu-iotests/153.out
+++ b/tests/qemu-iotests/153.out
@@ -12,11 +12,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 backing_file=TEST_DIR/t
== Launching another QEMU, opts: '' ==
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=none,: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
== Launching another QEMU, opts: 'read-only=on' ==
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=none,read-only=on: Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
== Launching another QEMU, opts: 'read-only=on,force-share=on' ==
@@ -24,77 +24,77 @@ Is another process using the image?
_qemu_io_wrapper -c read 0 512 TEST_DIR/t.qcow2
can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2
can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512
can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
no file open, try 'help open'
_qemu_io_wrapper -c open -r TEST_DIR/t.qcow2 -c read 0 512
can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
no file open, try 'help open'
_qemu_img_wrapper info TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper check TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper compare TEST_DIR/t.qcow2 TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper map TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper amend -o TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper commit TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper resize TEST_DIR/t.qcow2 32M
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper rebase TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper snapshot -l TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper convert TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.convert
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper dd if=TEST_DIR/t.qcow2 of=TEST_DIR/t.qcow2.convert bs=512 count=1
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper bench -c 1 TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper bench -w -c 1 TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper create -f qcow2 TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base
qemu-img: TEST_DIR/t.qcow2: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
file format: IMGFMT
== Running utility commands -U ==
@@ -132,7 +132,7 @@ Try 'qemu-img --help' for more information
_qemu_img_wrapper rebase -U TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper snapshot -l -U TEST_DIR/t.qcow2
@@ -157,7 +157,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 backing_file=TEST_DIR/t
== Launching another QEMU, opts: '' ==
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=none,: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
== Launching another QEMU, opts: 'read-only=on' ==
@@ -167,13 +167,13 @@ Is another process using the image?
_qemu_io_wrapper -c read 0 512 TEST_DIR/t.qcow2
can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2
_qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512
can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
no file open, try 'help open'
_qemu_io_wrapper -c open -r TEST_DIR/t.qcow2 -c read 0 512
@@ -188,19 +188,19 @@ _qemu_img_wrapper map TEST_DIR/t.qcow2
_qemu_img_wrapper amend -o TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper commit TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper resize TEST_DIR/t.qcow2 32M
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper rebase TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper snapshot -l TEST_DIR/t.qcow2
@@ -212,11 +212,11 @@ _qemu_img_wrapper bench -c 1 TEST_DIR/t.qcow2
_qemu_img_wrapper bench -w -c 1 TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper create -f qcow2 TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base
qemu-img: TEST_DIR/t.qcow2: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
file format: IMGFMT
== Running utility commands -U ==
@@ -254,7 +254,7 @@ Try 'qemu-img --help' for more information
_qemu_img_wrapper rebase -U TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_img_wrapper snapshot -l -U TEST_DIR/t.qcow2
@@ -372,17 +372,17 @@ Round done
== Two devices with the same image (read-only=off - read-only=off) ==
QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2,read-only=off: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
== Two devices with the same image (read-only=off - read-only=on) ==
QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2,read-only=on: Failed to get shared "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
== Two devices with the same image (read-only=off - read-only=on,force-share=on) ==
== Two devices with the same image (read-only=on - read-only=off) ==
QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2,read-only=off: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
== Two devices with the same image (read-only=on - read-only=on) ==
@@ -403,13 +403,13 @@ Formatting 'TEST_DIR/t.IMGFMT.c', fmt=IMGFMT size=33554432 backing_file=TEST_DIR
== Backing image also as an active device ==
QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
== Backing image also as an active device (ro) ==
== Symbolic link ==
QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
== Active commit to intermediate layer should work when base in use ==
{"return": {}}
@@ -420,7 +420,7 @@ Adding drive
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
Creating overlay with qemu-img when the guest is running should be allowed
_qemu_img_wrapper create -f qcow2 -b TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.overlay
@@ -433,7 +433,7 @@ _qemu_img_wrapper info TEST_DIR/t.qcow2
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
Closing the other
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
diff --git a/tests/qemu-iotests/182.out b/tests/qemu-iotests/182.out
index 23a4dbf809..f1463c8862 100644
--- a/tests/qemu-iotests/182.out
+++ b/tests/qemu-iotests/182.out
@@ -4,5 +4,5 @@ Starting QEMU
Starting a second QEMU using the same image should fail
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=none,id=drive0,file.locking=on: Failed to get "write" lock
-Is another process using the image?
+Is another process using the image [TEST_DIR/t.qcow2]?
*** done
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
index c9f29c8b10..ee1740ff06 100644
--- a/tests/test-bdrv-drain.c
+++ b/tests/test-bdrv-drain.c
@@ -694,6 +694,8 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread)
s->bh_indirection_ctx = ctx_b;
aio_ret = -EINPROGRESS;
+ qemu_event_reset(&done_event);
+
if (drain_thread == 0) {
acb = blk_aio_preadv(blk, 0, &qiov, 0, test_iothread_aio_cb, &aio_ret);
} else {
@@ -723,7 +725,6 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread)
* but the drain in this thread can continue immediately after
* bdrv_dec_in_flight() and aio_ret might be assigned only slightly
* later. */
- qemu_event_reset(&done_event);
do_drain_begin(drain_type, bs);
g_assert_cmpint(bs->in_flight, ==, 0);
@@ -743,7 +744,6 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread)
}
break;
case 1:
- qemu_event_reset(&done_event);
aio_bh_schedule_oneshot(ctx_a, test_iothread_drain_entry, &data);
qemu_event_wait(&done_event);
break;
diff --git a/tests/test-replication.c b/tests/test-replication.c
index c8165ae954..f085d1993a 100644
--- a/tests/test-replication.c
+++ b/tests/test-replication.c
@@ -207,13 +207,17 @@ static BlockBackend *start_primary(void)
static void teardown_primary(void)
{
BlockBackend *blk;
+ AioContext *ctx;
/* remove P_ID */
blk = blk_by_name(P_ID);
assert(blk);
+ ctx = blk_get_aio_context(blk);
+ aio_context_acquire(ctx);
monitor_remove_blk(blk);
blk_unref(blk);
+ aio_context_release(ctx);
}
static void test_primary_read(void)
@@ -365,20 +369,27 @@ static void teardown_secondary(void)
{
/* only need to destroy two BBs */
BlockBackend *blk;
+ AioContext *ctx;
/* remove S_LOCAL_DISK_ID */
blk = blk_by_name(S_LOCAL_DISK_ID);
assert(blk);
+ ctx = blk_get_aio_context(blk);
+ aio_context_acquire(ctx);
monitor_remove_blk(blk);
blk_unref(blk);
+ aio_context_release(ctx);
/* remove S_ID */
blk = blk_by_name(S_ID);
assert(blk);
+ ctx = blk_get_aio_context(blk);
+ aio_context_acquire(ctx);
monitor_remove_blk(blk);
blk_unref(blk);
+ aio_context_release(ctx);
}
static void test_secondary_read(void)