mirror of
https://github.com/qemu/qemu.git
synced 2026-04-05 21:50:33 +00:00
Merge tag 'for-upstream' of https://gitlab.com/kmwolf/qemu into staging
Block layer patches - Wire up 'flat' mode also for 'query-block' - Never drop BLOCK_IO_ERROR with action=stop for rate limiting - qcow2: Add keep_data_file command-line option - vmdk: fix OOB read in vmdk_read_extent() - curl: fix concurrent completion handling - nfs: Fix deadlock - mirror: Fix missed dirty bitmap writes during startup - throttle-groups: fix deadlock with iolimits and muliple iothreads # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCgAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmmrHbgRHGt3b2xmQHJl # ZGhhdC5jb20ACgkQfwmycsiPL9b+ng/+P4B3q+Rrvb5WWrY8fro/3kzSqGAHjKeL # QqEU8zywck5EorzK0H2f8BskxqXJ/LAe7ut4rFGqCA85l/eyWT7OhGm/DHnO/oI8 # /nU5r800/ZpvKn9HqK5+TSkswYQ6RmmMF9ZYIfYdB/JqPAmVmvbcjdqASVRT4PZ+ # v9QUKY309LDoaWm+vO/f0oPyxhog6yDHVh/rGhDkCOMyNExFyvfvAeLVuu+99Nzz # GFxleM7JyHdVmIErbKRNp2Z/uVSQvlOg5uecI3IZnc2QUbACQWWc97PCP199JzZ+ # HaEq8tP+/TQZSsXEYKHmxYx4AyzCIu15qDmpnfhnoA9MC80P+eLrHJ5sXOsT6S32 # AyTLIE6KKLImtLyG6TZV05G127c7ekrMbY8OfY21ocACUstr4q6MY1J6ZCcLQRMZ # E0BZR0CEOYtImrx0wr1XR0/q7SceiIaDcwFuPkHKz2akRS7bq9KH1RfxHYPpBJiX # nkkLtilV4s/OlhrsoGJeq44C7jZA2MdrgouxNiPe+08CFeJra5wQybC7ZIYqknx6 # D/Eu4Y6KwMbyfnMd/4F0kbzHv9h8R+ri2hHUqfKEtl2pNTqe8JEpsPmn+yMpuRe4 # Cl66DFs0OzcONiUBNJVdGg0dm0jtIyCEo2am1MAJUgGkwYKxtgUQLsouSJS1d4EP # iDe9pZmlytg= # =kPKk # -----END PGP SIGNATURE----- # gpg: Signature made Fri Mar 6 18:32:24 2026 GMT # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "kwolf@redhat.com" # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * tag 'for-upstream' of https://gitlab.com/kmwolf/qemu: iotests/244: Add test cases for keep_data_file iotests/common.filter: Sort keep_data_file qcow2: Simplify size round-up in co_create_opts qcow2: Add keep_data_file command-line option block/nfs: Do not enter coroutine from CB block: Never drop BLOCK_IO_ERROR with action=stop for rate limiting block/throttle-groups: fix deadlock with iolimits and muliple iothreads mirror: Fix missed dirty bitmap writes during startup block/curl: fix concurrent completion handling hmp_nbd_server_start: Don't ask for backing image data block: Wire up 'flat' mode also for 'query-block' block/vmdk: fix OOB read in vmdk_read_extent() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
11
block/curl.c
11
block/curl.c
@@ -324,17 +324,11 @@ curl_find_buf(BDRVCURLState *s, uint64_t start, uint64_t len, CURLAIOCB *acb)
|
||||
static void curl_multi_check_completion(BDRVCURLState *s)
|
||||
{
|
||||
int msgs_in_queue;
|
||||
CURLMsg *msg;
|
||||
|
||||
/* Try to find done transfers, so we can free the easy
|
||||
* handle again. */
|
||||
for (;;) {
|
||||
CURLMsg *msg;
|
||||
msg = curl_multi_info_read(s->multi, &msgs_in_queue);
|
||||
|
||||
/* Quit when there are no more completions */
|
||||
if (!msg)
|
||||
break;
|
||||
|
||||
while ((msg = curl_multi_info_read(s->multi, &msgs_in_queue))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
int i;
|
||||
CURLState *state = NULL;
|
||||
@@ -397,7 +391,6 @@ static void curl_multi_check_completion(BDRVCURLState *s)
|
||||
}
|
||||
|
||||
curl_clean_state(state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ typedef struct MirrorBlockJob {
|
||||
|
||||
typedef struct MirrorBDSOpaque {
|
||||
MirrorBlockJob *job;
|
||||
BdrvDirtyBitmap *dirty_bitmap;
|
||||
bool stop;
|
||||
bool is_commit;
|
||||
} MirrorBDSOpaque;
|
||||
@@ -1675,9 +1676,11 @@ bdrv_mirror_top_do_write(BlockDriverState *bs, MirrorMethod method,
|
||||
abort();
|
||||
}
|
||||
|
||||
if (!copy_to_target && s->job && s->job->dirty_bitmap) {
|
||||
qatomic_set(&s->job->actively_synced, false);
|
||||
bdrv_set_dirty_bitmap(s->job->dirty_bitmap, offset, bytes);
|
||||
if (!copy_to_target) {
|
||||
if (s->job) {
|
||||
qatomic_set(&s->job->actively_synced, false);
|
||||
}
|
||||
bdrv_set_dirty_bitmap(s->dirty_bitmap, offset, bytes);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
@@ -1904,13 +1907,35 @@ static BlockJob *mirror_start_job(
|
||||
|
||||
bdrv_drained_begin(bs);
|
||||
ret = bdrv_append(mirror_top_bs, bs, errp);
|
||||
bdrv_drained_end(bs);
|
||||
|
||||
if (ret < 0) {
|
||||
bdrv_drained_end(bs);
|
||||
bdrv_unref(mirror_top_bs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bs_opaque->dirty_bitmap = bdrv_create_dirty_bitmap(mirror_top_bs,
|
||||
granularity,
|
||||
NULL, errp);
|
||||
if (!bs_opaque->dirty_bitmap) {
|
||||
bdrv_drained_end(bs);
|
||||
bdrv_unref(mirror_top_bs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The mirror job doesn't use the block layer's dirty tracking because it
|
||||
* needs to be able to switch seemlessly between background copy mode (which
|
||||
* does need dirty tracking) and write blocking mode (which doesn't) and
|
||||
* doing that would require draining the node. Instead, mirror_top_bs takes
|
||||
* care of updating the dirty bitmap as appropriate.
|
||||
*
|
||||
* Note that write blocking mode only becomes effective after mirror_run()
|
||||
* sets mirror_top_opaque->job (see should_copy_to_target()). Until then,
|
||||
* we're still in background copy mode irrespective of @copy_mode.
|
||||
*/
|
||||
bdrv_disable_dirty_bitmap(bs_opaque->dirty_bitmap);
|
||||
bdrv_drained_end(bs);
|
||||
|
||||
/* Make sure that the source is not resized while the job is running */
|
||||
s = block_job_create(job_id, driver, NULL, mirror_top_bs,
|
||||
BLK_PERM_CONSISTENT_READ,
|
||||
@@ -2005,24 +2030,13 @@ static BlockJob *mirror_start_job(
|
||||
s->base_overlay = bdrv_find_overlay(bs, base);
|
||||
s->granularity = granularity;
|
||||
s->buf_size = ROUND_UP(buf_size, granularity);
|
||||
s->dirty_bitmap = bs_opaque->dirty_bitmap;
|
||||
s->unmap = unmap;
|
||||
if (auto_complete) {
|
||||
s->should_complete = true;
|
||||
}
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
|
||||
s->dirty_bitmap = bdrv_create_dirty_bitmap(s->mirror_top_bs, granularity,
|
||||
NULL, errp);
|
||||
if (!s->dirty_bitmap) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* The dirty bitmap is set by bdrv_mirror_top_do_write() when not in active
|
||||
* mode.
|
||||
*/
|
||||
bdrv_disable_dirty_bitmap(s->dirty_bitmap);
|
||||
|
||||
bdrv_graph_wrlock_drained();
|
||||
ret = block_job_add_bdrv(&s->common, "source", bs, 0,
|
||||
BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
|
||||
@@ -2102,9 +2116,6 @@ fail:
|
||||
g_free(s->replaces);
|
||||
blk_unref(s->target);
|
||||
bs_opaque->job = NULL;
|
||||
if (s->dirty_bitmap) {
|
||||
bdrv_release_dirty_bitmap(s->dirty_bitmap);
|
||||
}
|
||||
job_early_fail(&s->common.job);
|
||||
}
|
||||
|
||||
@@ -2118,6 +2129,7 @@ fail:
|
||||
bdrv_graph_wrunlock();
|
||||
bdrv_drained_end(bs);
|
||||
|
||||
bdrv_release_dirty_bitmap(bs_opaque->dirty_bitmap);
|
||||
bdrv_unref(mirror_top_bs);
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -422,7 +422,7 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
|
||||
/* Then try adding all block devices. If one fails, close all and
|
||||
* exit.
|
||||
*/
|
||||
block_list = qmp_query_block(NULL);
|
||||
block_list = qmp_query_block(true, true, NULL);
|
||||
|
||||
for (info = block_list; info; info = info->next) {
|
||||
if (!info->value->inserted) {
|
||||
@@ -741,7 +741,7 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
|
||||
|
||||
/* Print BlockBackend information */
|
||||
if (!nodes) {
|
||||
block_list = qmp_query_block(NULL);
|
||||
block_list = qmp_query_block(false, false, NULL);
|
||||
} else {
|
||||
block_list = NULL;
|
||||
}
|
||||
|
||||
19
block/nfs.c
19
block/nfs.c
@@ -249,14 +249,15 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
|
||||
}
|
||||
|
||||
/*
|
||||
* Safe to call: nfs_service(), which called us, is only run from the FD
|
||||
* handlers, never from the request coroutine. The request coroutine in
|
||||
* turn will yield unconditionally.
|
||||
* No need to release the lock, even if we directly enter the coroutine, as
|
||||
* the lock is never re-taken after yielding. (Note: If we do enter the
|
||||
* coroutine, @task will probably be dangling once aio_co_wake() returns.)
|
||||
* Using aio_co_wake() here could re-enter the coroutine directly, while we
|
||||
* still hold the mutex. The current request will not attempt to re-take
|
||||
* the mutex, so that is fine; but if the same coroutine then goes on to
|
||||
* submit another request, that new request will try to re-take the mutex,
|
||||
* resulting in a deadlock.
|
||||
* To prevent that, only schedule the coroutine so it will be entered later,
|
||||
* with the mutex released.
|
||||
*/
|
||||
aio_co_wake(task->co);
|
||||
aio_co_schedule(qemu_coroutine_get_aio_context(task->co), task->co);
|
||||
}
|
||||
|
||||
static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, int64_t offset,
|
||||
@@ -716,8 +717,8 @@ nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
|
||||
if (task->ret < 0) {
|
||||
error_report("NFS Error: %s", nfs_get_error(nfs));
|
||||
}
|
||||
/* Safe to call, see nfs_co_generic_cb() */
|
||||
aio_co_wake(task->co);
|
||||
/* Must not use aio_co_wake(), see nfs_co_generic_cb() */
|
||||
aio_co_schedule(qemu_coroutine_get_aio_context(task->co), task->co);
|
||||
}
|
||||
|
||||
static int64_t coroutine_fn nfs_co_get_allocated_file_size(BlockDriverState *bs)
|
||||
|
||||
@@ -456,7 +456,7 @@ fail:
|
||||
|
||||
/* @p_info will be set only on success. */
|
||||
static void GRAPH_RDLOCK
|
||||
bdrv_query_info(BlockBackend *blk, BlockInfo **p_info, Error **errp)
|
||||
bdrv_query_info(BlockBackend *blk, bool flat, BlockInfo **p_info, Error **errp)
|
||||
{
|
||||
BlockInfo *info = g_malloc0(sizeof(*info));
|
||||
BlockDriverState *bs = blk_bs(blk);
|
||||
@@ -488,7 +488,7 @@ bdrv_query_info(BlockBackend *blk, BlockInfo **p_info, Error **errp)
|
||||
}
|
||||
|
||||
if (bs && bs->drv) {
|
||||
info->inserted = bdrv_block_device_info(blk, bs, false, errp);
|
||||
info->inserted = bdrv_block_device_info(blk, bs, flat, errp);
|
||||
if (info->inserted == NULL) {
|
||||
goto err;
|
||||
}
|
||||
@@ -698,7 +698,7 @@ bdrv_query_bds_stats(BlockDriverState *bs, bool blk_level)
|
||||
return s;
|
||||
}
|
||||
|
||||
BlockInfoList *qmp_query_block(Error **errp)
|
||||
BlockInfoList *qmp_query_block(bool has_flat, bool flat, Error **errp)
|
||||
{
|
||||
BlockInfoList *head = NULL, **p_next = &head;
|
||||
BlockBackend *blk;
|
||||
@@ -714,7 +714,7 @@ BlockInfoList *qmp_query_block(Error **errp)
|
||||
}
|
||||
|
||||
info = g_malloc0(sizeof(*info));
|
||||
bdrv_query_info(blk, &info->value, &local_err);
|
||||
bdrv_query_info(blk, flat, &info->value, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
g_free(info);
|
||||
|
||||
@@ -3991,6 +3991,8 @@ qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts,
|
||||
BlockDriverState *bs = NULL;
|
||||
BlockDriverState *data_bs = NULL;
|
||||
const char *val;
|
||||
bool keep_data_file = false;
|
||||
BlockdevCreateOptionsQcow2 *qcow2_opts;
|
||||
int ret;
|
||||
|
||||
/* Only the keyval visitor supports the dotted syntax needed for
|
||||
@@ -4022,6 +4024,22 @@ qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts,
|
||||
qdict_put_str(qdict, BLOCK_OPT_COMPAT_LEVEL, "v3");
|
||||
}
|
||||
|
||||
val = qdict_get_try_str(qdict, BLOCK_OPT_KEEP_DATA_FILE);
|
||||
if (val) {
|
||||
if (!strcmp(val, "on")) {
|
||||
keep_data_file = true;
|
||||
} else if (!strcmp(val, "off")) {
|
||||
keep_data_file = false;
|
||||
} else {
|
||||
error_setg(errp,
|
||||
"Invalid value '%s' for '%s': Must be 'on' or 'off'",
|
||||
val, BLOCK_OPT_KEEP_DATA_FILE);
|
||||
ret = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
qdict_del(qdict, BLOCK_OPT_KEEP_DATA_FILE);
|
||||
}
|
||||
|
||||
/* Change legacy command line options into QMP ones */
|
||||
static const QDictRenames opt_renames[] = {
|
||||
{ BLOCK_OPT_BACKING_FILE, "backing-file" },
|
||||
@@ -4058,9 +4076,11 @@ qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts,
|
||||
/* Create and open an external data file (protocol layer) */
|
||||
val = qdict_get_try_str(qdict, BLOCK_OPT_DATA_FILE);
|
||||
if (val) {
|
||||
ret = bdrv_co_create_file(val, opts, false, errp);
|
||||
if (ret < 0) {
|
||||
goto finish;
|
||||
if (!keep_data_file) {
|
||||
ret = bdrv_co_create_file(val, opts, false, errp);
|
||||
if (ret < 0) {
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
data_bs = bdrv_co_open(val, NULL, NULL,
|
||||
@@ -4073,6 +4093,11 @@ qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts,
|
||||
|
||||
qdict_del(qdict, BLOCK_OPT_DATA_FILE);
|
||||
qdict_put_str(qdict, "data-file", data_bs->node_name);
|
||||
} else if (keep_data_file) {
|
||||
error_setg(errp, "Must not use '%s=on' without '%s'",
|
||||
BLOCK_OPT_KEEP_DATA_FILE, BLOCK_OPT_DATA_FILE);
|
||||
ret = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Set 'driver' and 'node' options */
|
||||
@@ -4093,9 +4118,39 @@ qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts,
|
||||
goto finish;
|
||||
}
|
||||
|
||||
qcow2_opts = &create_options->u.qcow2;
|
||||
|
||||
if (!qcow2_opts->has_preallocation) {
|
||||
qcow2_opts->preallocation = PREALLOC_MODE_OFF;
|
||||
}
|
||||
|
||||
if (keep_data_file &&
|
||||
qcow2_opts->preallocation != PREALLOC_MODE_OFF &&
|
||||
qcow2_opts->preallocation != PREALLOC_MODE_METADATA)
|
||||
{
|
||||
error_setg(errp, "Preallocating more than only metadata would "
|
||||
"overwrite the external data file's content and is "
|
||||
"therefore incompatible with '%s=on'",
|
||||
BLOCK_OPT_KEEP_DATA_FILE);
|
||||
ret = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (keep_data_file &&
|
||||
qcow2_opts->preallocation == PREALLOC_MODE_OFF &&
|
||||
!qcow2_opts->data_file_raw)
|
||||
{
|
||||
error_setg(errp, "'%s=on' requires '%s=metadata' or '%s=on', or the "
|
||||
"file contents will not be visible",
|
||||
BLOCK_OPT_KEEP_DATA_FILE,
|
||||
BLOCK_OPT_PREALLOC,
|
||||
BLOCK_OPT_DATA_FILE_RAW);
|
||||
ret = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Silently round up size */
|
||||
create_options->u.qcow2.size = ROUND_UP(create_options->u.qcow2.size,
|
||||
BDRV_SECTOR_SIZE);
|
||||
qcow2_opts->size = ROUND_UP(qcow2_opts->size, BDRV_SECTOR_SIZE);
|
||||
|
||||
/* Create the qcow2 image (format layer) */
|
||||
ret = qcow2_co_create(create_options, errp);
|
||||
@@ -4103,7 +4158,9 @@ finish:
|
||||
if (ret < 0) {
|
||||
bdrv_graph_co_rdlock();
|
||||
bdrv_co_delete_file_noerr(bs);
|
||||
bdrv_co_delete_file_noerr(data_bs);
|
||||
if (!keep_data_file) {
|
||||
bdrv_co_delete_file_noerr(data_bs);
|
||||
}
|
||||
bdrv_graph_co_rdunlock();
|
||||
} else {
|
||||
ret = 0;
|
||||
@@ -6202,6 +6259,12 @@ static QemuOptsList qcow2_create_opts = {
|
||||
.help = "Compression method used for image cluster " \
|
||||
"compression", \
|
||||
.def_value_str = "zlib" \
|
||||
}, \
|
||||
{ \
|
||||
.name = BLOCK_OPT_KEEP_DATA_FILE, \
|
||||
.type = QEMU_OPT_BOOL, \
|
||||
.help = "Assume the external data file already exists and " \
|
||||
"do not overwrite it" \
|
||||
},
|
||||
QCOW_COMMON_OPTIONS,
|
||||
{ /* end of list */ }
|
||||
|
||||
@@ -295,19 +295,15 @@ static bool throttle_group_schedule_timer(ThrottleGroupMember *tgm,
|
||||
/* Start the next pending I/O request for a ThrottleGroupMember. Return whether
|
||||
* any request was actually pending.
|
||||
*
|
||||
* This assumes that tg->lock is held.
|
||||
*
|
||||
* @tgm: the current ThrottleGroupMember
|
||||
* @direction: the ThrottleDirection
|
||||
*/
|
||||
static bool coroutine_fn throttle_group_co_restart_queue(ThrottleGroupMember *tgm,
|
||||
ThrottleDirection direction)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
qemu_co_mutex_lock(&tgm->throttled_reqs_lock);
|
||||
ret = qemu_co_queue_next(&tgm->throttled_reqs[direction]);
|
||||
qemu_co_mutex_unlock(&tgm->throttled_reqs_lock);
|
||||
|
||||
return ret;
|
||||
return qemu_co_queue_next(&tgm->throttled_reqs[direction]);
|
||||
}
|
||||
|
||||
/* Look for the next pending I/O request and schedule it.
|
||||
@@ -378,12 +374,8 @@ void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm
|
||||
/* Wait if there's a timer set or queued requests of this type */
|
||||
if (must_wait || tgm->pending_reqs[direction]) {
|
||||
tgm->pending_reqs[direction]++;
|
||||
qemu_mutex_unlock(&tg->lock);
|
||||
qemu_co_mutex_lock(&tgm->throttled_reqs_lock);
|
||||
qemu_co_queue_wait(&tgm->throttled_reqs[direction],
|
||||
&tgm->throttled_reqs_lock);
|
||||
qemu_co_mutex_unlock(&tgm->throttled_reqs_lock);
|
||||
qemu_mutex_lock(&tg->lock);
|
||||
&tg->lock);
|
||||
tgm->pending_reqs[direction]--;
|
||||
}
|
||||
|
||||
@@ -410,15 +402,15 @@ static void coroutine_fn throttle_group_restart_queue_entry(void *opaque)
|
||||
ThrottleDirection direction = data->direction;
|
||||
bool empty_queue;
|
||||
|
||||
qemu_mutex_lock(&tg->lock);
|
||||
empty_queue = !throttle_group_co_restart_queue(tgm, direction);
|
||||
|
||||
/* If the request queue was empty then we have to take care of
|
||||
* scheduling the next one */
|
||||
if (empty_queue) {
|
||||
qemu_mutex_lock(&tg->lock);
|
||||
schedule_next_request(tgm, direction);
|
||||
qemu_mutex_unlock(&tg->lock);
|
||||
}
|
||||
qemu_mutex_unlock(&tg->lock);
|
||||
|
||||
g_free(data);
|
||||
|
||||
@@ -569,7 +561,6 @@ void throttle_group_register_tgm(ThrottleGroupMember *tgm,
|
||||
read_timer_cb,
|
||||
write_timer_cb,
|
||||
tgm);
|
||||
qemu_co_mutex_init(&tgm->throttled_reqs_lock);
|
||||
}
|
||||
|
||||
/* Unregister a ThrottleGroupMember from its group, removing it from the list,
|
||||
|
||||
@@ -1951,10 +1951,10 @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
|
||||
marker = (VmdkGrainMarker *)cluster_buf;
|
||||
compressed_data = marker->data;
|
||||
data_len = le32_to_cpu(marker->size);
|
||||
}
|
||||
if (!data_len || data_len > buf_bytes) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
if (!data_len || data_len > buf_bytes - sizeof(VmdkGrainMarker)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ret = uncompress(uncomp_buf, &buf_len, compressed_data, data_len);
|
||||
if (ret != Z_OK) {
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#define BLOCK_OPT_DATA_FILE_RAW "data_file_raw"
|
||||
#define BLOCK_OPT_COMPRESSION_TYPE "compression_type"
|
||||
#define BLOCK_OPT_EXTL2 "extended_l2"
|
||||
#define BLOCK_OPT_KEEP_DATA_FILE "keep_data_file"
|
||||
|
||||
#define BLOCK_PROBE_BUF_SIZE 512
|
||||
|
||||
|
||||
@@ -35,8 +35,7 @@
|
||||
|
||||
typedef struct ThrottleGroupMember {
|
||||
AioContext *aio_context;
|
||||
/* throttled_reqs_lock protects the CoQueues for throttled requests. */
|
||||
CoMutex throttled_reqs_lock;
|
||||
/* Protected by ThrottleGroup.lock */
|
||||
CoQueue throttled_reqs[THROTTLE_MAX];
|
||||
|
||||
/* Nonzero if the I/O limits are currently being ignored; generally
|
||||
|
||||
@@ -330,14 +330,33 @@ monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict *qdict)
|
||||
{
|
||||
MonitorQAPIEventConf *evconf;
|
||||
MonitorQAPIEventState *evstate;
|
||||
bool throttled;
|
||||
|
||||
assert(event < QAPI_EVENT__MAX);
|
||||
evconf = &monitor_qapi_event_conf[event];
|
||||
trace_monitor_protocol_event_queue(event, qdict, evconf->rate);
|
||||
throttled = evconf->rate;
|
||||
|
||||
/*
|
||||
* Rate limit BLOCK_IO_ERROR only for action != "stop".
|
||||
*
|
||||
* If the VM is stopped after an I/O error, this is important information
|
||||
* for the management tool to keep track of the state of QEMU and we can't
|
||||
* merge any events. At the same time, stopping the VM means that the guest
|
||||
* can't send additional requests and the number of events is already
|
||||
* limited, so we can do without rate limiting.
|
||||
*/
|
||||
if (event == QAPI_EVENT_BLOCK_IO_ERROR) {
|
||||
QDict *data = qobject_to(QDict, qdict_get(qdict, "data"));
|
||||
const char *action = qdict_get_str(data, "action");
|
||||
if (!strcmp(action, "stop")) {
|
||||
throttled = false;
|
||||
}
|
||||
}
|
||||
|
||||
QEMU_LOCK_GUARD(&monitor_lock);
|
||||
|
||||
if (!evconf->rate) {
|
||||
if (!throttled) {
|
||||
/* Unthrottled event */
|
||||
monitor_qapi_event_emit(event, qdict);
|
||||
} else {
|
||||
|
||||
@@ -855,6 +855,10 @@
|
||||
#
|
||||
# Get a list of `BlockInfo` for all virtual block devices.
|
||||
#
|
||||
# @flat: Omit nested data about the backing image, i.e. `BlockInfo`
|
||||
# member 'inserted.image.backing-image' will be absent.
|
||||
# Default is false. (Since 11.0)
|
||||
#
|
||||
# Returns: a list describing each virtual block device. Filter nodes
|
||||
# that were created implicitly are skipped over.
|
||||
#
|
||||
@@ -945,6 +949,7 @@
|
||||
# }
|
||||
##
|
||||
{ 'command': 'query-block', 'returns': ['BlockInfo'],
|
||||
'data': { '*flat': 'bool' },
|
||||
'allow-preconfig': true }
|
||||
|
||||
##
|
||||
@@ -5789,7 +5794,7 @@
|
||||
# .. note:: If action is "stop", a `STOP` event will eventually follow
|
||||
# the `BLOCK_IO_ERROR` event.
|
||||
#
|
||||
# .. note:: This event is rate-limited.
|
||||
# .. note:: This event is rate-limited, except if action is "stop".
|
||||
#
|
||||
# Since: 0.13
|
||||
#
|
||||
|
||||
@@ -66,6 +66,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -92,6 +93,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -118,6 +120,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -144,6 +147,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -170,6 +174,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -196,6 +201,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -222,6 +228,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -248,6 +255,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -288,6 +296,7 @@ Supported qcow2 options:
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
refcount_bits=<num> - Width of a reference count entry in bits
|
||||
@@ -376,6 +385,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -402,6 +412,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -428,6 +439,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -454,6 +466,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -480,6 +493,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -506,6 +520,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -532,6 +547,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -558,6 +574,7 @@ Supported options:
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
@@ -598,6 +615,7 @@ Supported qcow2 options:
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
keep_data_file=<bool (on/off)> - Assume the external data file already exists and do not overwrite it
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
refcount_bits=<num> - Width of a reference count entry in bits
|
||||
|
||||
@@ -384,6 +384,77 @@ $QEMU_IMG compare --image-opts \
|
||||
"driver=raw,file.filename=$TEST_IMG.data" \
|
||||
"file.filename=$TEST_IMG,backing.file.filename=$TEST_IMG.base"
|
||||
|
||||
echo
|
||||
echo '=== keep_data_file tests ==='
|
||||
|
||||
echo
|
||||
echo '--- Creating test data file ---'
|
||||
|
||||
# Easiest way to create the raw data file without having to create and
|
||||
# access it manually
|
||||
_make_test_img -o "data_file=$TEST_IMG.data,data_file_raw=on" 1M
|
||||
# Values chosen by a fair random.org evaluation
|
||||
$QEMU_IO -c 'write -P 3 0 512k' -c 'write -P 96 512k 512k' "$TEST_IMG" |
|
||||
_filter_qemu_io
|
||||
|
||||
echo
|
||||
echo '--- Testing stand-alone option ---'
|
||||
|
||||
# Cannot work, needs data file
|
||||
_make_test_img -o "keep_data_file=on" 1M
|
||||
|
||||
# Invalid option value
|
||||
_make_test_img -o "keep_data_file=true" 1M
|
||||
|
||||
# Should be the same as omitting
|
||||
_make_test_img -o "keep_data_file=off" 1M
|
||||
|
||||
# No preallocation is OK when also specifying data_file_raw; otherwise, none of
|
||||
# the data file will be mapped, i.e. its contents will stay hidden, so
|
||||
# requesting its contents to be kept (but hidden) doesn't make much sense.
|
||||
#
|
||||
# Metadata preallocation is OK: It will not overwrite the data file's contents,
|
||||
# but ensure the contents are mapped and visible.
|
||||
#
|
||||
# Any data preallocation (like falloc) is not OK, as this would overwrite the
|
||||
# data file's contents despite keep_data_file requesting they should not be
|
||||
# overwritten.
|
||||
#
|
||||
# Note that all of these cases use the data file created above: This verifies
|
||||
# that when passing keep_data_file=on, the data file is always kept as-is (and
|
||||
# e.g. not deleted on error).
|
||||
for prealloc in off metadata falloc full; do
|
||||
# Without metadata preallocation, the data_file_raw flag is required so that
|
||||
# the data file's contents are visible.
|
||||
for data_file_raw in off on; do
|
||||
echo
|
||||
echo "--- Testing prealloc=$prealloc data_file_raw=$data_file_raw ---"
|
||||
|
||||
# Remove previously existing qcow2 (metadata) file
|
||||
_cleanup_test_img
|
||||
|
||||
opts="data_file=$TEST_IMG.data,keep_data_file=on"
|
||||
opts+=",preallocation=$prealloc"
|
||||
opts+=",data_file_raw=$data_file_raw"
|
||||
|
||||
_make_test_img -o "$opts" 1M
|
||||
if [ -f "$TEST_IMG" ]; then
|
||||
$QEMU_IO -c 'read -P 3 0 512k' -c 'read -P 96 512k 512k' "$TEST_IMG" |
|
||||
_filter_qemu_io
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo
|
||||
echo '--- Testing non-existent data file ---'
|
||||
|
||||
# Maybe a matter of taste whether this should fail or create the file, but
|
||||
# failing is simpler (= will always skip create) and seems safer (users may
|
||||
# expect the file to exist, and the error will warn them when it does not).
|
||||
_make_test_img \
|
||||
-o "data_file=$TEST_IMG.doesnotexist,keep_data_file=on,data_file_raw=on" \
|
||||
1M
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
rm -f $seq.full
|
||||
|
||||
@@ -197,4 +197,65 @@ wrote 1048576/1048576 bytes at offset 0
|
||||
|
||||
Comparing qcow2 image and raw data file:
|
||||
Images are identical.
|
||||
|
||||
=== keep_data_file tests ===
|
||||
|
||||
--- Creating test data file ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=on
|
||||
wrote 524288/524288 bytes at offset 0
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 524288/524288 bytes at offset 524288
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- Testing stand-alone option ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 keep_data_file=on
|
||||
qemu-img: TEST_DIR/t.IMGFMT: Must not use 'keep_data_file=on' without 'data_file'
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 keep_data_file=true
|
||||
qemu-img: TEST_DIR/t.IMGFMT: Invalid value 'true' for 'keep_data_file': Must be 'on' or 'off'
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 keep_data_file=off
|
||||
|
||||
--- Testing prealloc=off data_file_raw=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=off keep_data_file=on preallocation=off
|
||||
qemu-img: TEST_DIR/t.IMGFMT: 'keep_data_file=on' requires 'preallocation=metadata' or 'data_file_raw=on', or the file contents will not be visible
|
||||
|
||||
--- Testing prealloc=off data_file_raw=on ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=on keep_data_file=on preallocation=off
|
||||
read 524288/524288 bytes at offset 0
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 524288/524288 bytes at offset 524288
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- Testing prealloc=metadata data_file_raw=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=off keep_data_file=on preallocation=metadata
|
||||
read 524288/524288 bytes at offset 0
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 524288/524288 bytes at offset 524288
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- Testing prealloc=metadata data_file_raw=on ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=on keep_data_file=on preallocation=metadata
|
||||
read 524288/524288 bytes at offset 0
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 524288/524288 bytes at offset 524288
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- Testing prealloc=falloc data_file_raw=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=off keep_data_file=on preallocation=falloc
|
||||
qemu-img: TEST_DIR/t.IMGFMT: Preallocating more than only metadata would overwrite the external data file's content and is therefore incompatible with 'keep_data_file=on'
|
||||
|
||||
--- Testing prealloc=falloc data_file_raw=on ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=on keep_data_file=on preallocation=falloc
|
||||
qemu-img: TEST_DIR/t.IMGFMT: Preallocating more than only metadata would overwrite the external data file's content and is therefore incompatible with 'keep_data_file=on'
|
||||
|
||||
--- Testing prealloc=full data_file_raw=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=off keep_data_file=on preallocation=full
|
||||
qemu-img: TEST_DIR/t.IMGFMT: Preallocating more than only metadata would overwrite the external data file's content and is therefore incompatible with 'keep_data_file=on'
|
||||
|
||||
--- Testing prealloc=full data_file_raw=on ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=on keep_data_file=on preallocation=full
|
||||
qemu-img: TEST_DIR/t.IMGFMT: Preallocating more than only metadata would overwrite the external data file's content and is therefore incompatible with 'keep_data_file=on'
|
||||
|
||||
--- Testing non-existent data file ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 data_file=TEST_DIR/t.IMGFMT.doesnotexist data_file_raw=on keep_data_file=on
|
||||
qemu-img: TEST_DIR/t.IMGFMT: Could not open 'TEST_DIR/t.IMGFMT.doesnotexist': No such file or directory
|
||||
*** done
|
||||
|
||||
@@ -182,7 +182,7 @@ _do_filter_img_create()
|
||||
-e 's/^\(fmt\)/0-\1/' \
|
||||
-e 's/^\(size\)/1-\1/' \
|
||||
-e 's/^\(backing\)/2-\1/' \
|
||||
-e 's/^\(data_file\)/3-\1/' \
|
||||
-e 's/^\(\(keep_\)\?data_file\)/3-\1/' \
|
||||
-e 's/^\(encryption\)/4-\1/' \
|
||||
-e 's/^\(preallocation\)/8-\1/' \
|
||||
| LC_ALL=C sort \
|
||||
|
||||
@@ -1849,7 +1849,7 @@ static void addRemovableDevicesMenuItems(void)
|
||||
BlockInfoList *currentDevice, *pointerToFree;
|
||||
NSString *deviceName;
|
||||
|
||||
currentDevice = qmp_query_block(NULL);
|
||||
currentDevice = qmp_query_block(false, false, NULL);
|
||||
pointerToFree = currentDevice;
|
||||
|
||||
menu = [[[NSApp mainMenu] itemWithTitle:@"Machine"] submenu];
|
||||
|
||||
Reference in New Issue
Block a user