:p
atchew
Login
Merge remote-tracking branch 'remotes/edgar/tags/edgar/xilinx-next-2018-05-29-v1.for-upstream' into staging (2018-05-29 13:01:11 +0100) are available in the git repository at: git://repo.or.cz/qemu/kevin.git tags/for-upstream for you to fetch changes up to 3fb588a0f2c006122c34e1960a15c87ae2b927eb: block/create: Mark blockdev-create stable (2018-05-30 13:31:18 +0200) ---------------------------------------------------------------- Block layer patches: - Add blockdev-create job - qcow2: Silence Coverity false positive ---------------------------------------------------------------- Alberto Garcia (1): qcow2: Fix Coverity warning when calculating the refcount cache size Kevin Wolf (16): vdi: Fix vdi_co_do_create() return value vhdx: Fix vhdx_co_create() return value job: Add error message for failing jobs block/create: Make x-blockdev-create a job qemu-iotests: Add VM.get_qmp_events_filtered() qemu-iotests: Add VM.qmp_log() qemu-iotests: Add iotests.img_info_log() qemu-iotests: Add VM.run_job() qemu-iotests: iotests.py helper for non-file protocols qemu-iotests: Rewrite 206 for blockdev-create job qemu-iotests: Rewrite 207 for blockdev-create job qemu-iotests: Rewrite 210 for blockdev-create job qemu-iotests: Rewrite 211 for blockdev-create job qemu-iotests: Rewrite 212 for blockdev-create job qemu-iotests: Rewrite 213 for blockdev-create job block/create: Mark blockdev-create stable qapi/block-core.json | 18 +- qapi/job.json | 4 +- include/qemu/job.h | 7 +- block/backup.c | 2 +- block/commit.c | 2 +- block/create.c | 67 +++-- block/mirror.c | 2 +- block/qcow2.c | 5 +- block/stream.c | 2 +- block/vdi.c | 1 + block/vhdx.c | 2 +- job-qmp.c | 9 +- job.c | 16 +- tests/test-bdrv-drain.c | 2 +- tests/test-blockjob-txn.c | 2 +- tests/test-blockjob.c | 2 +- tests/qemu-iotests/206 | 680 ++++++++++++++++-------------------------- tests/qemu-iotests/206.out | 253 +++++++++------- tests/qemu-iotests/207 | 440 ++++++++++++--------------- tests/qemu-iotests/207.out | 107 +++---- tests/qemu-iotests/210 | 393 ++++++++++-------------- tests/qemu-iotests/210.out | 197 ++++++++---- tests/qemu-iotests/211 | 381 ++++++++++------------- tests/qemu-iotests/211.out | 133 +++++---- tests/qemu-iotests/212 | 483 +++++++++++------------------- tests/qemu-iotests/212.out | 191 +++++++----- tests/qemu-iotests/213 | 520 ++++++++++++-------------------- tests/qemu-iotests/213.out | 208 ++++++++----- tests/qemu-iotests/iotests.py | 78 +++++ 29 files changed, 1981 insertions(+), 2226 deletions(-)
From: Alberto Garcia <berto@igalia.com> MIN_REFCOUNT_CACHE_SIZE is 4 and the cluster size is guaranteed to be at most 2MB, so the minimum refcount cache size (in bytes) is always going to fit in a 32-bit integer. Coverity doesn't know that, and since we're storing the result in a uint64_t (*refcount_cache_size) it thinks that we need the 64 bits and that we probably want to do a 64-bit multiplication to prevent the result from being truncated. This is a false positive in this case, but it's a fair warning. We could do a 64-bit multiplication to get rid of it, but since we know that a 32-bit variable is enough to store this value let's simply reuse min_refcount_cache, make it a normal int and stop doing casts. Reported-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Alberto Garcia <berto@igalia.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> --- block/qcow2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index XXXXXXX..XXXXXXX 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, BDRVQcow2State *s = bs->opaque; uint64_t combined_cache_size; bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set; + int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size; 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); @@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, } else { uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); - uint64_t min_refcount_cache = - (uint64_t) MIN_REFCOUNT_CACHE_SIZE * s->cluster_size; /* Assign as much memory as possible to the L2 cache, and * use the remainder for the refcount cache */ @@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, * s->cluster_size); } if (!refcount_cache_size_set) { - *refcount_cache_size = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size; + *refcount_cache_size = min_refcount_cache; } } -- 2.13.6
.bdrv_co_create() is supposed to return 0 on success, but vdi could return a positive value instead. Fix this. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> --- block/vdi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/vdi.c b/block/vdi.c index XXXXXXX..XXXXXXX 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options, } } + ret = 0; exit: blk_unref(blk); bdrv_unref(bs_file); -- 2.13.6
.bdrv_co_create() is supposed to return 0 on success, but vhdx could return a positive value instead. Fix this. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> --- block/vhdx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/vhdx.c b/block/vhdx.c index XXXXXXX..XXXXXXX 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -XXX,XX +XXX,XX @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts, goto delete_and_exit; } - + ret = 0; delete_and_exit: blk_unref(blk); bdrv_unref(bs); -- 2.13.6
So far we relied on job->ret and strerror() to produce an error message for failed jobs. Not surprisingly, this tends to result in completely useless messages. This adds a Job.error field that can contain an error string for a failing job, and a parameter to job_completed() that sets the field. As a default, if NULL is passed, we continue to use strerror(job->ret). All existing callers are changed to pass NULL. They can be improved in separate patches. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> --- include/qemu/job.h | 7 ++++++- block/backup.c | 2 +- block/commit.c | 2 +- block/mirror.c | 2 +- block/stream.c | 2 +- job-qmp.c | 9 ++------- job.c | 16 ++++++++++++++-- tests/test-bdrv-drain.c | 2 +- tests/test-blockjob-txn.c | 2 +- tests/test-blockjob.c | 2 +- 10 files changed, 29 insertions(+), 17 deletions(-) diff --git a/include/qemu/job.h b/include/qemu/job.h index XXXXXXX..XXXXXXX 100644 --- a/include/qemu/job.h +++ b/include/qemu/job.h @@ -XXX,XX +XXX,XX @@ typedef struct Job { /** Estimated progress_current value at the completion of the job */ int64_t progress_total; + /** Error string for a failed job (NULL if, and only if, job->ret == 0) */ + char *error; + /** ret code passed to job_completed. */ int ret; @@ -XXX,XX +XXX,XX @@ void job_transition_to_ready(Job *job); /** * @job: The job being completed. * @ret: The status code. + * @error: The error message for a failing job (only with @ret < 0). If @ret is + * negative, but NULL is given for @error, strerror() is used. * * Marks @job as completed. If @ret is non-zero, the job transaction it is part * of is aborted. If @ret is zero, the job moves into the WAITING state. If it * is the last job to complete in its transaction, all jobs in the transaction * move from WAITING to PENDING. */ -void job_completed(Job *job, int ret); +void job_completed(Job *job, int ret, Error *error); /** Asynchronously complete the specified @job. */ void job_complete(Job *job, Error **errp); diff --git a/block/backup.c b/block/backup.c index XXXXXXX..XXXXXXX 100644 --- a/block/backup.c +++ b/block/backup.c @@ -XXX,XX +XXX,XX @@ static void backup_complete(Job *job, void *opaque) { BackupCompleteData *data = opaque; - job_completed(job, data->ret); + job_completed(job, data->ret, NULL); g_free(data); } diff --git a/block/commit.c b/block/commit.c index XXXXXXX..XXXXXXX 100644 --- a/block/commit.c +++ b/block/commit.c @@ -XXX,XX +XXX,XX @@ static void commit_complete(Job *job, void *opaque) * bdrv_set_backing_hd() to fail. */ block_job_remove_all_bdrv(bjob); - job_completed(job, ret); + job_completed(job, ret, NULL); g_free(data); /* If bdrv_drop_intermediate() didn't already do that, remove the commit diff --git a/block/mirror.c b/block/mirror.c index XXXXXXX..XXXXXXX 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -XXX,XX +XXX,XX @@ static void mirror_exit(Job *job, void *opaque) blk_set_perm(bjob->blk, 0, BLK_PERM_ALL, &error_abort); blk_insert_bs(bjob->blk, mirror_top_bs, &error_abort); - job_completed(job, data->ret); + job_completed(job, data->ret, NULL); g_free(data); bdrv_drained_end(src); diff --git a/block/stream.c b/block/stream.c index XXXXXXX..XXXXXXX 100644 --- a/block/stream.c +++ b/block/stream.c @@ -XXX,XX +XXX,XX @@ out: } g_free(s->backing_file_str); - job_completed(job, data->ret); + job_completed(job, data->ret, NULL); g_free(data); } diff --git a/job-qmp.c b/job-qmp.c index XXXXXXX..XXXXXXX 100644 --- a/job-qmp.c +++ b/job-qmp.c @@ -XXX,XX +XXX,XX @@ void qmp_job_dismiss(const char *id, Error **errp) static JobInfo *job_query_single(Job *job, Error **errp) { JobInfo *info; - const char *errmsg = NULL; assert(!job_is_internal(job)); - if (job->ret < 0) { - errmsg = strerror(-job->ret); - } - info = g_new(JobInfo, 1); *info = (JobInfo) { .id = g_strdup(job->id), @@ -XXX,XX +XXX,XX @@ static JobInfo *job_query_single(Job *job, Error **errp) .status = job->status, .current_progress = job->progress_current, .total_progress = job->progress_total, - .has_error = !!errmsg, - .error = g_strdup(errmsg), + .has_error = !!job->error, + .error = g_strdup(job->error), }; return info; diff --git a/job.c b/job.c index XXXXXXX..XXXXXXX 100644 --- a/job.c +++ b/job.c @@ -XXX,XX +XXX,XX @@ void job_unref(Job *job) QLIST_REMOVE(job, job_list); + g_free(job->error); g_free(job->id); g_free(job); } @@ -XXX,XX +XXX,XX @@ static void job_update_rc(Job *job) job->ret = -ECANCELED; } if (job->ret) { + if (!job->error) { + job->error = g_strdup(strerror(-job->ret)); + } job_state_transition(job, JOB_STATUS_ABORTING); } } @@ -XXX,XX +XXX,XX @@ static int job_prepare(Job *job) { if (job->ret == 0 && job->driver->prepare) { job->ret = job->driver->prepare(job); + job_update_rc(job); } return job->ret; } @@ -XXX,XX +XXX,XX @@ static void job_completed_txn_success(Job *job) } } -void job_completed(Job *job, int ret) +void job_completed(Job *job, int ret, Error *error) { assert(job && job->txn && !job_is_completed(job)); + job->ret = ret; + if (error) { + assert(job->ret < 0); + job->error = g_strdup(error_get_pretty(error)); + error_free(error); + } + job_update_rc(job); trace_job_completed(job, ret, job->ret); if (job->ret) { @@ -XXX,XX +XXX,XX @@ void job_cancel(Job *job, bool force) } job_cancel_async(job, force); if (!job_started(job)) { - job_completed(job, -ECANCELED); + job_completed(job, -ECANCELED, NULL); } else if (job->deferred_to_main_loop) { job_completed_txn_abort(job); } else { diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c index XXXXXXX..XXXXXXX 100644 --- a/tests/test-bdrv-drain.c +++ b/tests/test-bdrv-drain.c @@ -XXX,XX +XXX,XX @@ typedef struct TestBlockJob { static void test_job_completed(Job *job, void *opaque) { - job_completed(job, 0); + job_completed(job, 0, NULL); } static void coroutine_fn test_job_start(void *opaque) diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c index XXXXXXX..XXXXXXX 100644 --- a/tests/test-blockjob-txn.c +++ b/tests/test-blockjob-txn.c @@ -XXX,XX +XXX,XX @@ static void test_block_job_complete(Job *job, void *opaque) rc = -ECANCELED; } - job_completed(job, rc); + job_completed(job, rc, NULL); bdrv_unref(bs); } diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c index XXXXXXX..XXXXXXX 100644 --- a/tests/test-blockjob.c +++ b/tests/test-blockjob.c @@ -XXX,XX +XXX,XX @@ static void cancel_job_completed(Job *job, void *opaque) { CancelJob *s = opaque; s->completed = true; - job_completed(job, 0); + job_completed(job, 0, NULL); } static void cancel_job_complete(Job *job, Error **errp) -- 2.13.6
This changes the x-blockdev-create QMP command so that it doesn't block the monitor and the main loop any more, but starts a background job that performs the image creation. The basic job as implemented here is all that is necessary to make image creation asynchronous and to provide a QMP interface that can be marked stable, but it still lacks a few features that jobs usually provide: The job will ignore pause commands and it doesn't publish more than very basic progress yet (total-progress is 1 and current-progress advances from 0 to 1 when the driver callbacks returns). These features can be added later without breaking compatibility. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> --- qapi/block-core.json | 14 ++++++---- qapi/job.json | 4 ++- block/create.c | 67 +++++++++++++++++++++++++++++++++--------------- tests/qemu-iotests/group | 14 +++++----- 4 files changed, 66 insertions(+), 33 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index XXXXXXX..XXXXXXX 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -XXX,XX +XXX,XX @@ ## # @x-blockdev-create: # -# Create an image format on a given node. -# TODO Replace with something asynchronous (block job?) +# Starts a job to create an image format on a given node. The job is +# automatically finalized, but a manual job-dismiss is required. # -# Since: 2.12 +# @job-id: Identifier for the newly created job. +# +# @options: Options for the image creation. +# +# Since: 3.0 ## { 'command': 'x-blockdev-create', - 'data': 'BlockdevCreateOptions', - 'boxed': true } + 'data': { 'job-id': 'str', + 'options': 'BlockdevCreateOptions' } } ## # @blockdev-open-tray: diff --git a/qapi/job.json b/qapi/job.json index XXXXXXX..XXXXXXX 100644 --- a/qapi/job.json +++ b/qapi/job.json @@ -XXX,XX +XXX,XX @@ # # @backup: drive backup job type, see "drive-backup" # +# @create: image creation job type, see "x-blockdev-create" (since 3.0) +# # Since: 1.7 ## { 'enum': 'JobType', - 'data': ['commit', 'stream', 'mirror', 'backup'] } + 'data': ['commit', 'stream', 'mirror', 'backup', 'create'] } ## # @JobStatus: diff --git a/block/create.c b/block/create.c index XXXXXXX..XXXXXXX 100644 --- a/block/create.c +++ b/block/create.c @@ -XXX,XX +XXX,XX @@ #include "qemu/osdep.h" #include "block/block_int.h" +#include "qemu/job.h" #include "qapi/qapi-commands-block-core.h" +#include "qapi/qapi-visit-block-core.h" +#include "qapi/clone-visitor.h" #include "qapi/error.h" -typedef struct BlockdevCreateCo { +typedef struct BlockdevCreateJob { + Job common; BlockDriver *drv; BlockdevCreateOptions *opts; int ret; - Error **errp; -} BlockdevCreateCo; + Error *err; +} BlockdevCreateJob; -static void coroutine_fn bdrv_co_create_co_entry(void *opaque) +static void blockdev_create_complete(Job *job, void *opaque) { - BlockdevCreateCo *cco = opaque; - cco->ret = cco->drv->bdrv_co_create(cco->opts, cco->errp); + BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common); + + job_completed(job, s->ret, s->err); } -void qmp_x_blockdev_create(BlockdevCreateOptions *options, Error **errp) +static void coroutine_fn blockdev_create_run(void *opaque) { + BlockdevCreateJob *s = opaque; + + job_progress_set_remaining(&s->common, 1); + s->ret = s->drv->bdrv_co_create(s->opts, &s->err); + job_progress_update(&s->common, 1); + + qapi_free_BlockdevCreateOptions(s->opts); + job_defer_to_main_loop(&s->common, blockdev_create_complete, NULL); +} + +static const JobDriver blockdev_create_job_driver = { + .instance_size = sizeof(BlockdevCreateJob), + .job_type = JOB_TYPE_CREATE, + .start = blockdev_create_run, +}; + +void qmp_x_blockdev_create(const char *job_id, BlockdevCreateOptions *options, + Error **errp) +{ + BlockdevCreateJob *s; const char *fmt = BlockdevDriver_str(options->driver); BlockDriver *drv = bdrv_find_format(fmt); - Coroutine *co; - BlockdevCreateCo cco; /* If the driver is in the schema, we know that it exists. But it may not * be whitelisted. */ @@ -XXX,XX +XXX,XX @@ void qmp_x_blockdev_create(BlockdevCreateOptions *options, Error **errp) return; } - /* Call callback if it exists */ + /* Error out if the driver doesn't support .bdrv_co_create */ if (!drv->bdrv_co_create) { error_setg(errp, "Driver does not support blockdev-create"); return; } - cco = (BlockdevCreateCo) { - .drv = drv, - .opts = options, - .ret = -EINPROGRESS, - .errp = errp, - }; - - co = qemu_coroutine_create(bdrv_co_create_co_entry, &cco); - qemu_coroutine_enter(co); - while (cco.ret == -EINPROGRESS) { - aio_poll(qemu_get_aio_context(), true); + /* Create the block job */ + /* TODO Running in the main context. Block drivers need to error out or add + * locking when they use a BDS in a different AioContext. */ + s = job_create(job_id, &blockdev_create_job_driver, NULL, + qemu_get_aio_context(), JOB_DEFAULT | JOB_MANUAL_DISMISS, + NULL, NULL, errp); + if (!s) { + return; } + + s->drv = drv, + s->opts = QAPI_CLONE(BlockdevCreateOptions, options), + + job_start(&s->common); } diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -XXX,XX +XXX,XX @@ 203 rw auto migration 204 rw auto quick 205 rw auto quick -206 rw auto -207 rw auto +# TODO The following commented out tests need to be reworked to work +# with the x-blockdev-create job +#206 rw auto +#207 rw auto 208 rw auto quick 209 rw auto quick -210 rw auto -211 rw auto quick -212 rw auto quick -213 rw auto quick +#210 rw auto +#211 rw auto quick +#212 rw auto quick +#213 rw auto quick 214 rw auto 215 rw auto quick 216 rw auto quick -- 2.13.6
This adds a helper function that returns a list of QMP events that are already filtered through filter_qmp_event(). Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> --- tests/qemu-iotests/iotests.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine): output_list += [key + '=' + obj[key]] return ','.join(output_list) + def get_qmp_events_filtered(self, wait=True): + result = [] + for ev in self.get_qmp_events(wait=wait): + result.append(filter_qmp_event(ev)) + return result index_re = re.compile(r'([^\[]+)\[([^\]]+)\]') -- 2.13.6
This adds a helper function that logs both the QMP request and the received response before returning it. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> --- tests/qemu-iotests/iotests.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -XXX,XX +XXX,XX @@ def filter_qmp_event(event): event['timestamp']['microseconds'] = 'USECS' return event +def filter_testfiles(msg): + prefix = os.path.join(test_dir, "%s-" % (os.getpid())) + return msg.replace(prefix, 'TEST_DIR/PID-') + def log(msg, filters=[]): for flt in filters: msg = flt(msg) @@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine): result.append(filter_qmp_event(ev)) return result + def qmp_log(self, cmd, filters=[filter_testfiles], **kwargs): + logmsg = "{'execute': '%s', 'arguments': %s}" % (cmd, kwargs) + log(logmsg, filters) + result = self.qmp(cmd, **kwargs) + log(str(result), filters) + return result + index_re = re.compile(r'([^\[]+)\[([^\]]+)\]') -- 2.13.6
This adds a filter function to postprocess 'qemu-img info' input (similar to what _img_info does), and an img_info_log() function that calls 'qemu-img info' and logs the filtered output. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> --- tests/qemu-iotests/iotests.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -XXX,XX +XXX,XX @@ def qemu_img_pipe(*args): sys.stderr.write('qemu-img received signal %i: %s\n' % (-exitcode, ' '.join(qemu_img_args + list(args)))) return subp.communicate()[0] +def img_info_log(filename, filter_path=None): + output = qemu_img_pipe('info', '-f', imgfmt, filename) + if not filter_path: + filter_path = filename + log(filter_img_info(output, filter_path)) + def qemu_io(*args): '''Run qemu-io and return the stdout data''' args = qemu_io_args + list(args) @@ -XXX,XX +XXX,XX @@ def filter_testfiles(msg): prefix = os.path.join(test_dir, "%s-" % (os.getpid())) return msg.replace(prefix, 'TEST_DIR/PID-') +def filter_img_info(output, filename): + lines = [] + for line in output.split('\n'): + if 'disk size' in line or 'actual-size' in line: + continue + line = line.replace(filename, 'TEST_IMG') \ + .replace(imgfmt, 'IMGFMT') + line = re.sub('iters: [0-9]+', 'iters: XXX', line) + line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line) + lines.append(line) + return '\n'.join(lines) + def log(msg, filters=[]): for flt in filters: msg = flt(msg) -- 2.13.6
Add an iotests.py function that runs a job and only returns when it is destroyed. An error is logged when the job failed and job-finalize and job-dismiss commands are issued if necessary. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> --- tests/qemu-iotests/iotests.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine): log(str(result), filters) return result + def run_job(self, job, auto_finalize=True, auto_dismiss=False): + while True: + for ev in self.get_qmp_events_filtered(wait=True): + if ev['event'] == 'JOB_STATUS_CHANGE': + status = ev['data']['status'] + if status == 'aborting': + result = self.qmp('query-jobs') + for j in result['return']: + if j['id'] == job: + log('Job failed: %s' % (j['error'])) + elif status == 'pending' and not auto_finalize: + self.qmp_log('job-finalize', id=job) + elif status == 'concluded' and not auto_dismiss: + self.qmp_log('job-dismiss', id=job) + elif status == 'null': + return + else: + iotests.log(ev) + index_re = re.compile(r'([^\[]+)\[([^\]]+)\]') -- 2.13.6
This adds two helper functions that are useful for test cases that make use of a non-file protocol (specifically ssh). Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> --- tests/qemu-iotests/iotests.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -XXX,XX +XXX,XX @@ def file_path(*names): return paths[0] if len(paths) == 1 else paths +def remote_filename(path): + if imgproto == 'file': + return path + elif imgproto == 'ssh': + return "ssh://127.0.0.1%s" % (path) + else: + raise Exception("Protocol %s not supported" % (imgproto)) class VM(qtest.QEMUQtestMachine): '''A QEMU VM''' @@ -XXX,XX +XXX,XX @@ def verify_image_format(supported_fmts=[], unsupported_fmts=[]): if not_sup or (imgfmt in unsupported_fmts): notrun('not suitable for this image format: %s' % imgfmt) +def verify_protocol(supported=[], unsupported=[]): + assert not (supported and unsupported) + + if 'generic' in supported: + return + + not_sup = supported and (imgproto not in supported) + if not_sup or (imgproto in unsupported): + notrun('not suitable for this protocol: %s' % imgproto) + def verify_platform(supported_oses=['linux']): if True not in [sys.platform.startswith(x) for x in supported_oses]: notrun('not suitable for this OS: %s' % sys.platform) -- 2.13.6
This rewrites the test case 206 to work with the new x-blockdev-create job rather than the old synchronous version of the command. All of the test cases stay the same as before, but in order to be able to implement proper job handling, the test case is rewritten in Python. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> --- tests/qemu-iotests/206 | 680 ++++++++++++++++++--------------------------- tests/qemu-iotests/206.out | 253 ++++++++++------- tests/qemu-iotests/group | 2 +- 3 files changed, 414 insertions(+), 521 deletions(-) diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/206 +++ b/tests/qemu-iotests/206 @@ -XXX,XX +XXX,XX @@ -#!/bin/bash +#!/usr/bin/env python # # Test qcow2 and file image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <kwolf@redhat.com> +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -XXX,XX +XXX,XX @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator -owner=kwolf@redhat.com - -seq=`basename $0` -echo "QA output created by $seq" - -here=`pwd` -status=1 # failure is the default! - -# get standard environment, filters and checks -. ./common.rc -. ./common.filter - -_supported_fmt qcow2 -_supported_proto file -_supported_os Linux - -function do_run_qemu() -{ - echo Testing: "$@" - $QEMU -nographic -qmp stdio -serial none "$@" - echo -} - -function run_qemu() -{ - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \ - | _filter_qemu | _filter_imgfmt \ - | _filter_actual_image_size -} - -echo -echo "=== Successful image creation (defaults) ===" -echo - -size=$((128 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "blockdev-add", - "arguments": { - "driver": "file", - "node-name": "imgfile", - "filename": "$TEST_IMG" - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "imgfile", - "size": $size - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific - -echo -echo "=== Successful image creation (inline blockdev-add, explicit defaults) ===" -echo - -# Choose a different size to show that we got a new image -size=$((64 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0, - "preallocation": "off", - "nocow": false - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - }, - "size": $size, - "version": "v3", - "cluster-size": 65536, - "preallocation": "off", - "lazy-refcounts": false, - "refcount-bits": 16 - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific - -echo -echo "=== Successful image creation (v3 non-default options) ===" -echo - -# Choose a different size to show that we got a new image -size=$((32 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0, - "preallocation": "falloc", - "nocow": true - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - }, - "size": $size, - "version": "v3", - "cluster-size": 2097152, - "preallocation": "metadata", - "lazy-refcounts": true, - "refcount-bits": 1 - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific - -echo -echo "=== Successful image creation (v2 non-default options) ===" -echo - -mv $TEST_IMG $TEST_IMG.base - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - }, - "size": $size, - "backing-file": "$TEST_IMG.base", - "backing-fmt": "qcow2", - "version": "v2", - "cluster-size": 512 - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific - -echo -echo "=== Successful image creation (encrypted) ===" -echo - -run_qemu -object secret,id=keysec0,data="foo" <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - }, - "size": $size, - "encrypt": { - "format": "luks", - "key-secret": "keysec0", - "cipher-alg": "twofish-128", - "cipher-mode": "ctr", - "ivgen-alg": "plain64", - "ivgen-hash-alg": "md5", - "hash-alg": "sha1", - "iter-time": 10 - } - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific - -echo -echo "=== Invalid BlockdevRef ===" -echo - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "this doesn't exist", - "size": $size - } -} -{ "execute": "quit" } -EOF - - -echo -echo "=== Invalid sizes ===" -echo - -# TODO Negative image sizes aren't handled correctly, but this is a problem -# with QAPI's implementation of the 'size' type and affects other commands as -# well. Once this is fixed, we may want to add a test case here. - -# 1. Misaligned image size -# 2. 2^64 - 512 -# 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this) -# 4. 2^63 - 512 (generally valid, but qcow2 can't handle images this size) - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 1234 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 18446744073709551104 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 9223372036854775808 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 9223372036854775296 - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Invalid version ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "version": "v1" - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "version": "v2", - "lazy-refcounts": true - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "version": "v2", - "refcount-bits": 8 - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Invalid backing file options ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "backing-file": "/dev/null", - "preallocation": "full" - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "backing-fmt": "$IMGFMT" - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Invalid cluster size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "cluster-size": 1234 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "cluster-size": 128 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "cluster-size": 4194304 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "cluster-size": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 281474976710656, - "cluster-size": 512 - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Invalid refcount width ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "refcount-bits": 128 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "refcount-bits": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "refcount-bits": 7 - } -} -{ "execute": "quit" } -EOF - -# success, all done -echo "*** done" -rm -f $seq.full -status=0 +import iotests +from iotests import imgfmt + +iotests.verify_image_format(supported_fmts=['qcow2']) + +def blockdev_create(vm, options): + result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) + + if 'return' in result: + assert result['return'] == {} + vm.run_job('job0') + iotests.log("") + +with iotests.FilePath('t.qcow2') as disk_path, \ + iotests.FilePath('t.qcow2.base') as backing_path, \ + iotests.VM() as vm: + + vm.add_object('secret,id=keysec0,data=foo') + + # + # Successful image creation (defaults) + # + iotests.log("=== Successful image creation (defaults) ===") + iotests.log("") + + size = 128 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + + vm.qmp_log('blockdev-add', driver='file', filename=disk_path, + node_name='imgfile') + + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'imgfile', + 'size': size }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Successful image creation (inline blockdev-add, explicit defaults) + # + iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===") + iotests.log("") + + # Choose a different size to show that we got a new image + size = 64 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0, + 'preallocation': 'off', + 'nocow': False }) + + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'version': 'v3', + 'cluster-size': 65536, + 'preallocation': 'off', + 'lazy-refcounts': False, + 'refcount-bits': 16 }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Successful image creation (v3 non-default options) + # + iotests.log("=== Successful image creation (v3 non-default options) ===") + iotests.log("") + + # Choose a different size to show that we got a new image + size = 32 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0, + 'preallocation': 'falloc', + 'nocow': True }) + + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'version': 'v3', + 'cluster-size': 2097152, + 'preallocation': 'metadata', + 'lazy-refcounts': True, + 'refcount-bits': 1 }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Successful image creation (v2 non-default options) + # + iotests.log("=== Successful image creation (v2 non-default options) ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'backing-file': backing_path, + 'backing-fmt': 'qcow2', + 'version': 'v2', + 'cluster-size': 512 }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Successful image creation (encrypted) + # + iotests.log("=== Successful image creation (encrypted) ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'encrypt': { + 'format': 'luks', + 'key-secret': 'keysec0', + 'cipher-alg': 'twofish-128', + 'cipher-mode': 'ctr', + 'ivgen-alg': 'plain64', + 'ivgen-hash-alg': 'md5', + 'hash-alg': 'sha1', + 'iter-time': 10, + }}) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Invalid BlockdevRef + # + iotests.log("=== Invalid BlockdevRef ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': "this doesn't exist", + 'size': size }) + vm.shutdown() + + # + # Invalid sizes + # + iotests.log("=== Invalid sizes ===") + + # TODO Negative image sizes aren't handled correctly, but this is a problem + # with QAPI's implementation of the 'size' type and affects other commands + # as well. Once this is fixed, we may want to add a test case here. + # + # 1. Misaligned image size + # 2. 2^64 - 512 + # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this) + # 4. 2^63 - 512 (generally valid, but qcow2 can't handle images this size) + + vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) + + vm.launch() + for size in [ 1234, 18446744073709551104, 9223372036854775808, + 9223372036854775296 ]: + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': size }) + vm.shutdown() + + # + # Invalid version + # + iotests.log("=== Invalid version ===") + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'version': 'v1' }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'version': 'v2', + 'lazy-refcounts': True }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'version': 'v2', + 'refcount-bits': 8 }) + vm.shutdown() + + # + # Invalid backing file options + # + iotests.log("=== Invalid backing file options ===") + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'backing-file': '/dev/null', + 'preallocation': 'full' }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'backing-fmt': imgfmt }) + vm.shutdown() + + # + # Invalid cluster size + # + iotests.log("=== Invalid cluster size ===") + + vm.launch() + for csize in [ 1234, 128, 4194304, 0 ]: + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'cluster-size': csize }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 281474976710656, + 'cluster-size': 512 }) + vm.shutdown() + + # + # Invalid refcount width + # + iotests.log("=== Invalid refcount width ===") + + vm.launch() + for refcount_bits in [ 128, 0, 7 ]: + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'refcount-bits': refcount_bits }) + vm.shutdown() diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/206.out +++ b/tests/qemu-iotests/206.out @@ -XXX,XX +XXX,XX @@ -QA output created by 206 - === Successful image creation (defaults) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}} +{u'return': {}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'imgfile', 'size': 134217728}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 128M (134217728 bytes) cluster_size: 65536 @@ -XXX,XX +XXX,XX @@ Format specific information: === Successful image creation (inline blockdev-add, explicit defaults) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': False, 'preallocation': 'off', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'refcount-bits': 16, 'version': 'v3', 'preallocation': 'off', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': False, 'driver': 'qcow2', 'size': 67108864}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +image: TEST_IMG file format: IMGFMT virtual size: 64M (67108864 bytes) cluster_size: 65536 @@ -XXX,XX +XXX,XX @@ Format specific information: === Successful image creation (v3 non-default options) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': True, 'preallocation': 'falloc', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 2097152, 'refcount-bits': 1, 'version': 'v3', 'preallocation': 'metadata', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': True, 'driver': 'qcow2', 'size': 33554432}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 32M (33554432 bytes) cluster_size: 2097152 @@ -XXX,XX +XXX,XX @@ Format specific information: === Successful image creation (v2 non-default options) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'backing-fmt': 'qcow2', 'driver': 'qcow2', 'version': 'v2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'backing-file': 'TEST_DIR/PID-t.qcow2.base', 'size': 33554432}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +image: TEST_IMG file format: IMGFMT virtual size: 32M (33554432 bytes) cluster_size: 512 -backing file: TEST_DIR/t.IMGFMT.base +backing file: TEST_IMG.base backing file format: IMGFMT Format specific information: compat: 0.10 @@ -XXX,XX +XXX,XX @@ Format specific information: === Successful image creation (encrypted) === -Testing: -object secret,id=keysec0,data=foo -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'encrypt': {'key-secret': 'keysec0', 'iter-time': 10, 'cipher-mode': 'ctr', 'ivgen-hash-alg': 'md5', 'cipher-alg': 'twofish-128', 'format': 'luks', 'ivgen-alg': 'plain64', 'hash-alg': 'sha1'}, 'driver': 'qcow2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'size': 33554432}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 32M (33554432 bytes) +encrypted: yes +cluster_size: 65536 Format specific information: compat: 1.1 lazy refcounts: false @@ -XXX,XX +XXX,XX @@ Format specific information: ivgen alg: plain64 hash alg: sha1 cipher alg: twofish-128 - uuid: 00000000-0000-0000-0000-000000000000 + uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX format: luks cipher mode: ctr slots: [0]: active: true - iters: 1024 + iters: XXX key offset: 4096 stripes: 4000 [1]: @@ -XXX,XX +XXX,XX @@ Format specific information: active: false key offset: 462848 payload offset: 528384 - master key iters: 1024 + master key iters: XXX corrupt: false === Invalid BlockdevRef === -Testing: -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': "this doesn't exist", 'size': 33554432}}} +{u'return': {}} +Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Invalid sizes === - -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Image size must be a multiple of 512 bytes"}} -{"error": {"class": "GenericError", "desc": "Could not resize image: Image size cannot be negative"}} -{"error": {"class": "GenericError", "desc": "Could not resize image: Image size cannot be negative"}} -{"error": {"class": "GenericError", "desc": "Could not resize image: Failed to grow the L1 table: File too large"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 1234}}} +{u'return': {}} +Job failed: Image size must be a multiple of 512 bytes +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 18446744073709551104L}}} +{u'return': {}} +Job failed: Could not resize image: Image size cannot be negative +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775808L}}} +{u'return': {}} +Job failed: Could not resize image: Image size cannot be negative +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775296}}} +{u'return': {}} +Job failed: Could not resize image: Failed to grow the L1 table: File too large +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Invalid version === +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'version': 'v1', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'error': {u'class': u'GenericError', u'desc': u"Invalid parameter 'v1'"}} -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Invalid parameter 'v1'"}} -{"error": {"class": "GenericError", "desc": "Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater)"}} -{"error": {"class": "GenericError", "desc": "Different refcount widths than 16 bits require compatibility level 1.1 or above (use version=v3 or greater)"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'lazy-refcounts': True, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater) +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 8, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Different refcount widths than 16 bits require compatibility level 1.1 or above (use version=v3 or greater) +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Invalid backing file options === - -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Backing file and preallocation cannot be used at the same time"}} -{"error": {"class": "GenericError", "desc": "Backing format cannot be used without backing file"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'full', 'driver': 'qcow2', 'backing-file': '/dev/null', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Backing file and preallocation cannot be used at the same time +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'backing-fmt': 'qcow2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Backing format cannot be used without backing file +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Invalid cluster size === - -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Cluster size must be a power of two between 512 and 2048k"}} -{"error": {"class": "GenericError", "desc": "Cluster size must be a power of two between 512 and 2048k"}} -{"error": {"class": "GenericError", "desc": "Cluster size must be a power of two between 512 and 2048k"}} -{"error": {"class": "GenericError", "desc": "Cluster size must be a power of two between 512 and 2048k"}} -{"error": {"class": "GenericError", "desc": "Could not resize image: Failed to grow the L1 table: File too large"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Cluster size must be a power of two between 512 and 2048k +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Cluster size must be a power of two between 512 and 2048k +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4194304, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Cluster size must be a power of two between 512 and 2048k +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Cluster size must be a power of two between 512 and 2048k +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'qcow2', 'file': 'node0', 'size': 281474976710656}}} +{u'return': {}} +Job failed: Could not resize image: Failed to grow the L1 table: File too large +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Invalid refcount width === +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Refcount width must be a power of two and may not exceed 64 bits +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Refcount width must be a power of two and may not exceed 64 bits +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 7, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Refcount width must be a power of two and may not exceed 64 bits +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Refcount width must be a power of two and may not exceed 64 bits"}} -{"error": {"class": "GenericError", "desc": "Refcount width must be a power of two and may not exceed 64 bits"}} -{"error": {"class": "GenericError", "desc": "Refcount width must be a power of two and may not exceed 64 bits"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - -*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -XXX,XX +XXX,XX @@ 203 rw auto migration 204 rw auto quick 205 rw auto quick +206 rw auto # TODO The following commented out tests need to be reworked to work # with the x-blockdev-create job -#206 rw auto #207 rw auto 208 rw auto quick 209 rw auto quick -- 2.13.6
This rewrites the test case 207 to work with the new x-blockdev-create job rather than the old synchronous version of the command. Most of the test cases stay the same as before (the exception being some improved 'size' options that allow distinguishing which command created the image), but in order to be able to implement proper job handling, the test case is rewritten in Python. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> --- tests/qemu-iotests/207 | 440 ++++++++++++++++++++------------------------- tests/qemu-iotests/207.out | 107 +++++------ tests/qemu-iotests/group | 6 +- 3 files changed, 257 insertions(+), 296 deletions(-) diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/207 +++ b/tests/qemu-iotests/207 @@ -XXX,XX +XXX,XX @@ -#!/bin/bash +#!/usr/bin/env python # # Test ssh image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <kwolf@redhat.com> +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -XXX,XX +XXX,XX @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator -owner=kwolf@redhat.com - -seq=`basename $0` -echo "QA output created by $seq" - -here=`pwd` -status=1 # failure is the default! - -# get standard environment, filters and checks -. ./common.rc -. ./common.filter - -_supported_fmt raw -_supported_proto ssh -_supported_os Linux - -function do_run_qemu() -{ - echo Testing: "$@" - $QEMU -nographic -qmp stdio -serial none "$@" - echo -} - -function run_qemu() -{ - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \ - | _filter_qemu | _filter_imgfmt \ - | _filter_actual_image_size -} - -echo -echo "=== Successful image creation (defaults) ===" -echo - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "ssh", - "location": { - "path": "$TEST_IMG_FILE", - "server": { - "host": "127.0.0.1", - "port": "22" - } - }, - "size": 4194304 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info -echo -TEST_IMG=$TEST_IMG_FILE _img_info | _filter_img_info - -echo -echo "=== Test host-key-check options ===" -echo - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "ssh", - "location": { - "path": "$TEST_IMG_FILE", - "server": { - "host": "127.0.0.1", - "port": "22" - }, - "host-key-check": { - "mode": "none" - } - }, - "size": 8388608 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "ssh", - "location": { - "path": "$TEST_IMG_FILE", - "server": { - "host": "127.0.0.1", - "port": "22" - }, - "host-key-check": { - "mode": "known_hosts" - } - }, - "size": 4194304 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - - -key=$(ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | - cut -d" " -f3 | base64 -d | md5sum -b | cut -d" " -f1) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "ssh", - "location": { - "path": "$TEST_IMG_FILE", - "server": { - "host": "127.0.0.1", - "port": "22" - }, - "host-key-check": { - "mode": "hash", - "type": "md5", - "hash": "wrong" - } - }, - "size": 8388608 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "ssh", - "location": { - "path": "$TEST_IMG_FILE", - "server": { - "host": "127.0.0.1", - "port": "22" - }, - "host-key-check": { - "mode": "hash", - "type": "md5", - "hash": "$key" - } - }, - "size": 8388608 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - - -key=$(ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | - cut -d" " -f3 | base64 -d | sha1sum -b | cut -d" " -f1) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "ssh", - "location": { - "path": "$TEST_IMG_FILE", - "server": { - "host": "127.0.0.1", - "port": "22" - }, - "host-key-check": { - "mode": "hash", - "type": "sha1", - "hash": "wrong" - } - }, - "size": 4194304 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "ssh", - "location": { - "path": "$TEST_IMG_FILE", - "server": { - "host": "127.0.0.1", - "port": "22" - }, - "host-key-check": { - "mode": "hash", - "type": "sha1", - "hash": "$key" - } - }, - "size": 4194304 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - -echo -echo "=== Invalid path and user ===" -echo - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "ssh", - "location": { - "path": "/this/is/not/an/existing/path", - "server": { - "host": "127.0.0.1", - "port": "22" - } - }, - "size": 4194304 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "ssh", - "location": { - "path": "$TEST_IMG_FILE", - "user": "invalid user", - "server": { - "host": "127.0.0.1", - "port": "22" - } - }, - "size": 4194304 - } -} -{ "execute": "quit" } -EOF - -# success, all done -echo "*** done" -rm -f $seq.full -status=0 +import iotests +import subprocess +import re + +iotests.verify_image_format(supported_fmts=['raw']) +iotests.verify_protocol(supported=['ssh']) + +def filter_hash(msg): + return re.sub("'hash': '[0-9a-f]+'", "'hash': HASH", msg) + +def blockdev_create(vm, options): + result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options, + filters=[iotests.filter_testfiles, filter_hash]) + + if 'return' in result: + assert result['return'] == {} + vm.run_job('job0') + iotests.log("") + +with iotests.FilePath('t.img') as disk_path, \ + iotests.VM() as vm: + + remote_path = iotests.remote_filename(disk_path) + + # + # Successful image creation (defaults) + # + iotests.log("=== Successful image creation (defaults) ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': 'ssh', + 'location': { + 'path': disk_path, + 'server': { + 'host': '127.0.0.1', + 'port': '22' + } + }, + 'size': 4194304 }) + vm.shutdown() + + iotests.img_info_log(remote_path, filter_path=disk_path) + iotests.log("") + iotests.img_info_log(disk_path) + + # + # Test host-key-check options + # + iotests.log("=== Test host-key-check options ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': 'ssh', + 'location': { + 'path': disk_path, + 'server': { + 'host': '127.0.0.1', + 'port': '22' + }, + 'host-key-check': { + 'mode': 'none' + } + }, + 'size': 8388608 }) + vm.shutdown() + + iotests.img_info_log(remote_path, filter_path=disk_path) + + vm.launch() + blockdev_create(vm, { 'driver': 'ssh', + 'location': { + 'path': disk_path, + 'server': { + 'host': '127.0.0.1', + 'port': '22' + }, + 'host-key-check': { + 'mode': 'known_hosts' + } + }, + 'size': 4194304 }) + vm.shutdown() + + iotests.img_info_log(remote_path, filter_path=disk_path) + + md5_key = subprocess.check_output( + 'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' + + 'cut -d" " -f3 | base64 -d | md5sum -b | cut -d" " -f1', + shell=True).rstrip() + + vm.launch() + blockdev_create(vm, { 'driver': 'ssh', + 'location': { + 'path': disk_path, + 'server': { + 'host': '127.0.0.1', + 'port': '22' + }, + 'host-key-check': { + 'mode': 'hash', + 'type': 'md5', + 'hash': 'wrong', + } + }, + 'size': 2097152 }) + blockdev_create(vm, { 'driver': 'ssh', + 'location': { + 'path': disk_path, + 'server': { + 'host': '127.0.0.1', + 'port': '22' + }, + 'host-key-check': { + 'mode': 'hash', + 'type': 'md5', + 'hash': md5_key, + } + }, + 'size': 8388608 }) + vm.shutdown() + + iotests.img_info_log(remote_path, filter_path=disk_path) + + sha1_key = subprocess.check_output( + 'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' + + 'cut -d" " -f3 | base64 -d | sha1sum -b | cut -d" " -f1', + shell=True).rstrip() + + vm.launch() + blockdev_create(vm, { 'driver': 'ssh', + 'location': { + 'path': disk_path, + 'server': { + 'host': '127.0.0.1', + 'port': '22' + }, + 'host-key-check': { + 'mode': 'hash', + 'type': 'sha1', + 'hash': 'wrong', + } + }, + 'size': 2097152 }) + blockdev_create(vm, { 'driver': 'ssh', + 'location': { + 'path': disk_path, + 'server': { + 'host': '127.0.0.1', + 'port': '22' + }, + 'host-key-check': { + 'mode': 'hash', + 'type': 'sha1', + 'hash': sha1_key, + } + }, + 'size': 4194304 }) + vm.shutdown() + + iotests.img_info_log(remote_path, filter_path=disk_path) + + # + # Invalid path and user + # + iotests.log("=== Invalid path and user ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': 'ssh', + 'location': { + 'path': '/this/is/not/an/existing/path', + 'server': { + 'host': '127.0.0.1', + 'port': '22' + }, + 'host-key-check': { + 'mode': 'none' + } + }, + 'size': 4194304 }) + blockdev_create(vm, { 'driver': 'ssh', + 'location': { + 'path': disk_path, + 'user': 'invalid user', + 'server': { + 'host': '127.0.0.1', + 'port': '22' + }, + 'host-key-check': { + 'mode': 'none' + } + }, + 'size': 4194304 }) + vm.shutdown() diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/207.out +++ b/tests/qemu-iotests/207.out @@ -XXX,XX +XXX,XX @@ -QA output created by 207 - === Successful image creation (defaults) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_DIR/t.IMGFMT"}} +image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}} file format: IMGFMT virtual size: 4.0M (4194304 bytes) -image: TEST_DIR/t.IMGFMT + +image: TEST_IMG file format: IMGFMT virtual size: 4.0M (4194304 bytes) === Test host-key-check options === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_DIR/t.IMGFMT"}} +image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}} file format: IMGFMT virtual size: 8.0M (8388608 bytes) -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - -image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_DIR/t.IMGFMT"}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'known_hosts'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}} file format: IMGFMT virtual size: 4.0M (4194304 bytes) -Testing: -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "remote host key does not match host_key_check 'wrong'"}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - -image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_DIR/t.IMGFMT"}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}} +{u'return': {}} +Job failed: remote host key does not match host_key_check 'wrong' +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}} file format: IMGFMT virtual size: 8.0M (8388608 bytes) -Testing: -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "remote host key does not match host_key_check 'wrong'"}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - -image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_DIR/t.IMGFMT"}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}} +{u'return': {}} +Job failed: remote host key does not match host_key_check 'wrong' +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}} file format: IMGFMT virtual size: 4.0M (4194304 bytes) === Invalid path and user === -Testing: -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "failed to open remote file '/this/is/not/an/existing/path': Failed opening remote file (libssh2 error code: -31)"}} -{"error": {"class": "GenericError", "desc": "failed to authenticate using publickey authentication and the identities held by your ssh-agent"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': '/this/is/not/an/existing/path', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} +{u'return': {}} +Job failed: failed to open remote file '/this/is/not/an/existing/path': Failed opening remote file (libssh2 error code: -31) +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'user': 'invalid user', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} +{u'return': {}} +Job failed: failed to authenticate using publickey authentication and the identities held by your ssh-agent +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -XXX,XX +XXX,XX @@ 204 rw auto quick 205 rw auto quick 206 rw auto -# TODO The following commented out tests need to be reworked to work -# with the x-blockdev-create job -#207 rw auto +207 rw auto 208 rw auto quick 209 rw auto quick +# TODO The following commented out tests need to be reworked to work +# with the x-blockdev-create job #210 rw auto #211 rw auto quick #212 rw auto quick -- 2.13.6
This rewrites the test case 210 to work with the new x-blockdev-create job rather than the old synchronous version of the command. All of the test cases stay the same as before, but in order to be able to implement proper job handling, the test case is rewritten in Python. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> --- tests/qemu-iotests/210 | 393 ++++++++++++++++++------------------------ tests/qemu-iotests/210.out | 197 ++++++++++++++------- tests/qemu-iotests/group | 2 +- tests/qemu-iotests/iotests.py | 12 +- 4 files changed, 314 insertions(+), 290 deletions(-) diff --git a/tests/qemu-iotests/210 b/tests/qemu-iotests/210 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/210 +++ b/tests/qemu-iotests/210 @@ -XXX,XX +XXX,XX @@ -#!/bin/bash +#!/usr/bin/env python # # Test luks and file image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <kwolf@redhat.com> +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -XXX,XX +XXX,XX @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator -owner=kwolf@redhat.com - -seq=`basename $0` -echo "QA output created by $seq" - -here=`pwd` -status=1 # failure is the default! - -# get standard environment, filters and checks -. ./common.rc -. ./common.filter - -_supported_fmt luks -_supported_proto file -_supported_os Linux - -function do_run_qemu() -{ - echo Testing: "$@" - $QEMU -nographic -qmp stdio -serial none "$@" - echo -} - -function run_qemu() -{ - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \ - | _filter_qemu | _filter_imgfmt \ - | _filter_actual_image_size -} - -echo -echo "=== Successful image creation (defaults) ===" -echo - -size=$((128 * 1024 * 1024)) - -run_qemu -object secret,id=keysec0,data="foo" <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG_FILE", - "size": 0 - } -} -{ "execute": "blockdev-add", - "arguments": { - "driver": "file", - "node-name": "imgfile", - "filename": "$TEST_IMG_FILE" - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "imgfile", - "key-secret": "keysec0", - "size": $size, - "iter-time": 10 - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific - -echo -echo "=== Successful image creation (with non-default options) ===" -echo - -# Choose a different size to show that we got a new image -size=$((64 * 1024 * 1024)) - -run_qemu -object secret,id=keysec0,data="foo" <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG_FILE", - "size": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG_FILE" - }, - "size": $size, - "key-secret": "keysec0", - "cipher-alg": "twofish-128", - "cipher-mode": "ctr", - "ivgen-alg": "plain64", - "ivgen-hash-alg": "md5", - "hash-alg": "sha1", - "iter-time": 10 - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific - -echo -echo "=== Invalid BlockdevRef ===" -echo - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "this doesn't exist", - "size": $size - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Zero size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG_FILE",node-name=node0 \ - -object secret,id=keysec0,data="foo" <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "key-secret": "keysec0", - "size": 0, - "iter-time": 10 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - - -echo -echo "=== Invalid sizes ===" -echo - -# TODO Negative image sizes aren't handled correctly, but this is a problem -# with QAPI's implementation of the 'size' type and affects other commands as -# well. Once this is fixed, we may want to add a test case here. - -# 1. 2^64 - 512 -# 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this) -# 3. 2^63 - 512 (generally valid, but with the crypto header the file will -# exceed 63 bits) - -run_qemu -blockdev driver=file,filename="$TEST_IMG_FILE",node-name=node0 \ - -object secret,id=keysec0,data="foo" <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "key-secret": "keysec0", - "size": 18446744073709551104 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "key-secret": "keysec0", - "size": 9223372036854775808 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "key-secret": "keysec0", - "size": 9223372036854775296 - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Resize image with invalid sizes ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG_FILE",node-name=node0 \ - -blockdev driver=luks,file=node0,key-secret=keysec0,node-name=node1 \ - -object secret,id=keysec0,data="foo" <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "block_resize", - "arguments": { - "node-name": "node1", - "size": 9223372036854775296 - } -} -{ "execute": "block_resize", - "arguments": { - "node-name": "node1", - "size": 9223372036854775808 - } -} -{ "execute": "block_resize", - "arguments": { - "node-name": "node1", - "size": 18446744073709551104 - } -} -{ "execute": "block_resize", - "arguments": { - "node-name": "node1", - "size": -9223372036854775808 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - -# success, all done -echo "*** done" -rm -f $seq.full -status=0 +import iotests +from iotests import imgfmt + +iotests.verify_image_format(supported_fmts=['luks']) +iotests.verify_protocol(supported=['file']) + +def blockdev_create(vm, options): + result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) + + if 'return' in result: + assert result['return'] == {} + vm.run_job('job0') + iotests.log("") + +with iotests.FilePath('t.luks') as disk_path, \ + iotests.VM() as vm: + + vm.add_object('secret,id=keysec0,data=foo') + + # + # Successful image creation (defaults) + # + iotests.log("=== Successful image creation (defaults) ===") + iotests.log("") + + size = 128 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + + vm.qmp_log('blockdev-add', driver='file', filename=disk_path, + node_name='imgfile') + + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'imgfile', + 'key-secret': 'keysec0', + 'size': size, + 'iter-time': 10 }) + vm.shutdown() + + # TODO Proper support for images to be used with imgopts and/or protocols + iotests.img_info_log( + 'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path), + filter_path=disk_path, + extra_args=['--object', 'secret,id=keysec0,data=foo'], + imgopts=True) + + # + # Successful image creation (with non-default options) + # + iotests.log("=== Successful image creation (with non-default options) ===") + iotests.log("") + + size = 64 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'key-secret': 'keysec0', + 'cipher-alg': 'twofish-128', + 'cipher-mode': 'ctr', + 'ivgen-alg': 'plain64', + 'ivgen-hash-alg': 'md5', + 'hash-alg': 'sha1', + 'iter-time': 10 }) + vm.shutdown() + + # TODO Proper support for images to be used with imgopts and/or protocols + iotests.img_info_log( + 'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path), + filter_path=disk_path, + extra_args=['--object', 'secret,id=keysec0,data=foo'], + imgopts=True) + + # + # Invalid BlockdevRef + # + iotests.log("=== Invalid BlockdevRef ===") + iotests.log("") + + size = 64 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': "this doesn't exist", + 'size': size }) + vm.shutdown() + + # + # Zero size + # + iotests.log("=== Zero size ===") + iotests.log("") + + vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'key-secret': 'keysec0', + 'size': 0, + 'iter-time': 10 }) + vm.shutdown() + + # TODO Proper support for images to be used with imgopts and/or protocols + iotests.img_info_log( + 'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path), + filter_path=disk_path, + extra_args=['--object', 'secret,id=keysec0,data=foo'], + imgopts=True) + + # + # Invalid sizes + # + + # TODO Negative image sizes aren't handled correctly, but this is a problem + # with QAPI's implementation of the 'size' type and affects other commands as + # well. Once this is fixed, we may want to add a test case here. + + # 1. 2^64 - 512 + # 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this) + # 3. 2^63 - 512 (generally valid, but with the crypto header the file will + # exceed 63 bits) + iotests.log("=== Invalid sizes ===") + iotests.log("") + + vm.launch() + for size in [ 18446744073709551104, 9223372036854775808, 9223372036854775296 ]: + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'key-secret': 'keysec0', + 'size': size }) + vm.shutdown() + + # + # Resize image with invalid sizes + # + iotests.log("=== Resize image with invalid sizes ===") + iotests.log("") + + vm.add_blockdev('driver=luks,file=node0,key-secret=keysec0,node-name=node1') + vm.launch() + vm.qmp_log('block_resize', node_name='node1', size=9223372036854775296) + vm.qmp_log('block_resize', node_name='node1', size=9223372036854775808) + vm.qmp_log('block_resize', node_name='node1', size=18446744073709551104) + vm.qmp_log('block_resize', node_name='node1', size=-9223372036854775808) + vm.shutdown() + + # TODO Proper support for images to be used with imgopts and/or protocols + iotests.img_info_log( + 'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path), + filter_path=disk_path, + extra_args=['--object', 'secret,id=keysec0,data=foo'], + imgopts=True) diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/210.out +++ b/tests/qemu-iotests/210.out @@ -XXX,XX +XXX,XX @@ -QA output created by 210 - === Successful image creation (defaults) === -Testing: -object secret,id=keysec0,data=foo -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}} +{u'return': {}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'imgfile', 'size': 134217728}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"} +image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"} file format: IMGFMT virtual size: 128M (134217728 bytes) +encrypted: yes Format specific information: ivgen alg: plain64 hash alg: sha256 cipher alg: aes-256 - uuid: 00000000-0000-0000-0000-000000000000 + uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX cipher mode: xts slots: [0]: active: true - iters: 1024 + iters: XXX key offset: 4096 stripes: 4000 [1]: @@ -XXX,XX +XXX,XX @@ Format specific information: active: false key offset: 1810432 payload offset: 2068480 - master key iters: 1024 + master key iters: XXX === Successful image creation (with non-default options) === -Testing: -object secret,id=keysec0,data=foo -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'hash-alg': 'sha1', 'cipher-mode': 'ctr', 'cipher-alg': 'twofish-128', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}, 'iter-time': 10, 'ivgen-alg': 'plain64', 'ivgen-hash-alg': 'md5', 'driver': 'luks', 'size': 67108864}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"} +image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"} file format: IMGFMT virtual size: 64M (67108864 bytes) +encrypted: yes Format specific information: ivgen alg: plain64 hash alg: sha1 cipher alg: twofish-128 - uuid: 00000000-0000-0000-0000-000000000000 + uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX cipher mode: ctr slots: [0]: active: true - iters: 1024 + iters: XXX key offset: 4096 stripes: 4000 [1]: @@ -XXX,XX +XXX,XX @@ Format specific information: active: false key offset: 462848 payload offset: 528384 - master key iters: 1024 + master key iters: XXX === Invalid BlockdevRef === -Testing: -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'luks', 'file': "this doesn't exist", 'size': 67108864}}} +{u'return': {}} +Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Zero size === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -object secret,id=keysec0,data=foo -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'node0', 'size': 0}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"} +image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"} file format: IMGFMT virtual size: 0 (0 bytes) +encrypted: yes +Format specific information: + ivgen alg: plain64 + hash alg: sha256 + cipher alg: aes-256 + uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + cipher mode: xts + slots: + [0]: + active: true + iters: XXX + key offset: 4096 + stripes: 4000 + [1]: + active: false + key offset: 262144 + [2]: + active: false + key offset: 520192 + [3]: + active: false + key offset: 778240 + [4]: + active: false + key offset: 1036288 + [5]: + active: false + key offset: 1294336 + [6]: + active: false + key offset: 1552384 + [7]: + active: false + key offset: 1810432 + payload offset: 2068480 + master key iters: XXX === Invalid sizes === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -object secret,id=keysec0,data=foo -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "The requested file size is too large"}} -{"error": {"class": "GenericError", "desc": "The requested file size is too large"}} -{"error": {"class": "GenericError", "desc": "The requested file size is too large"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 18446744073709551104L}}} +{u'return': {}} +Job failed: The requested file size is too large +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775808L}}} +{u'return': {}} +Job failed: The requested file size is too large +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775296}}} +{u'return': {}} +Job failed: The requested file size is too large +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Resize image with invalid sizes === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -blockdev driver=IMGFMT,file=node0,key-secret=keysec0,node-name=node1 -object secret,id=keysec0,data=foo -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "The requested file size is too large"}} -{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'size', expected: integer"}} -{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'size', expected: integer"}} -{"error": {"class": "GenericError", "desc": "Parameter 'size' expects a >0 size"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - -image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"} +{'execute': 'block_resize', 'arguments': {'size': 9223372036854775296, 'node_name': 'node1'}} +{u'error': {u'class': u'GenericError', u'desc': u'The requested file size is too large'}} +{'execute': 'block_resize', 'arguments': {'size': 9223372036854775808L, 'node_name': 'node1'}} +{u'error': {u'class': u'GenericError', u'desc': u"Invalid parameter type for 'size', expected: integer"}} +{'execute': 'block_resize', 'arguments': {'size': 18446744073709551104L, 'node_name': 'node1'}} +{u'error': {u'class': u'GenericError', u'desc': u"Invalid parameter type for 'size', expected: integer"}} +{'execute': 'block_resize', 'arguments': {'size': -9223372036854775808, 'node_name': 'node1'}} +{u'error': {u'class': u'GenericError', u'desc': u"Parameter 'size' expects a >0 size"}} +image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"} file format: IMGFMT virtual size: 0 (0 bytes) -*** done +encrypted: yes +Format specific information: + ivgen alg: plain64 + hash alg: sha256 + cipher alg: aes-256 + uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + cipher mode: xts + slots: + [0]: + active: true + iters: XXX + key offset: 4096 + stripes: 4000 + [1]: + active: false + key offset: 262144 + [2]: + active: false + key offset: 520192 + [3]: + active: false + key offset: 778240 + [4]: + active: false + key offset: 1036288 + [5]: + active: false + key offset: 1294336 + [6]: + active: false + key offset: 1552384 + [7]: + active: false + key offset: 1810432 + payload offset: 2068480 + master key iters: XXX + diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -XXX,XX +XXX,XX @@ 207 rw auto 208 rw auto quick 209 rw auto quick +210 rw auto # TODO The following commented out tests need to be reworked to work # with the x-blockdev-create job -#210 rw auto #211 rw auto quick #212 rw auto quick #213 rw auto quick diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -XXX,XX +XXX,XX @@ def qemu_img_pipe(*args): sys.stderr.write('qemu-img received signal %i: %s\n' % (-exitcode, ' '.join(qemu_img_args + list(args)))) return subp.communicate()[0] -def img_info_log(filename, filter_path=None): - output = qemu_img_pipe('info', '-f', imgfmt, filename) +def img_info_log(filename, filter_path=None, imgopts=False, extra_args=[]): + args = [ 'info' ] + if imgopts: + args.append('--image-opts') + else: + args += [ '-f', imgfmt ] + args += extra_args + args.append(filename) + + output = qemu_img_pipe(*args) if not filter_path: filter_path = filename log(filter_img_info(output, filter_path)) -- 2.13.6
This rewrites the test case 211 to work with the new x-blockdev-create job rather than the old synchronous version of the command. All of the test cases stay the same as before, but in order to be able to implement proper job handling, the test case is rewritten in Python. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> --- tests/qemu-iotests/211 | 381 ++++++++++++++++++--------------------------- tests/qemu-iotests/211.out | 133 +++++++++------- tests/qemu-iotests/group | 2 +- 3 files changed, 229 insertions(+), 287 deletions(-) diff --git a/tests/qemu-iotests/211 b/tests/qemu-iotests/211 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/211 +++ b/tests/qemu-iotests/211 @@ -XXX,XX +XXX,XX @@ -#!/bin/bash +#!/usr/bin/env python # # Test VDI and file image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <kwolf@redhat.com> +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -XXX,XX +XXX,XX @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator -owner=kwolf@redhat.com - -seq=`basename $0` -echo "QA output created by $seq" - -here=`pwd` -status=1 # failure is the default! - -# get standard environment, filters and checks -. ./common.rc -. ./common.filter - -_supported_fmt vdi -_supported_proto file -_supported_os Linux - -function do_run_qemu() -{ - echo Testing: "$@" - $QEMU -nographic -qmp stdio -serial none "$@" - echo -} - -function run_qemu() -{ - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \ - | _filter_qemu | _filter_imgfmt \ - | _filter_actual_image_size -} - -echo -echo "=== Successful image creation (defaults) ===" -echo - -size=$((128 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "blockdev-add", - "arguments": { - "driver": "file", - "node-name": "imgfile", - "filename": "$TEST_IMG" - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "imgfile", - "size": $size - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific -$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map - -echo -echo "=== Successful image creation (explicit defaults) ===" -echo - -# Choose a different size to show that we got a new image -size=$((64 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - }, - "size": $size, - "preallocation": "off" - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific -$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map - -echo -echo "=== Successful image creation (with non-default options) ===" -echo - -# Choose a different size to show that we got a new image -size=$((32 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - }, - "size": $size, - "preallocation": "metadata" - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific -$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map - -echo -echo "=== Invalid BlockdevRef ===" -echo - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "this doesn't exist", - "size": $size - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Zero size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 0 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - -echo -echo "=== Maximum size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 562949819203584 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - -echo -echo "=== Invalid sizes ===" -echo - -# TODO Negative image sizes aren't handled correctly, but this is a problem -# with QAPI's implementation of the 'size' type and affects other commands as -# well. Once this is fixed, we may want to add a test case here. - -# 1. 2^64 - 512 -# 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this) -# 3. 0x1fffff8000001 (one byte more than maximum image size for VDI) - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 18446744073709551104 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 9223372036854775808 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 562949819203585 - } -} -{ "execute": "quit" } -EOF - -# success, all done -echo "*** done" -rm -f $seq.full -status=0 +import iotests +from iotests import imgfmt + +iotests.verify_image_format(supported_fmts=['vdi']) +iotests.verify_protocol(supported=['file']) + +def blockdev_create(vm, options): + result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) + + if 'return' in result: + assert result['return'] == {} + vm.run_job('job0') + iotests.log("") + +with iotests.FilePath('t.vdi') as disk_path, \ + iotests.VM() as vm: + + # + # Successful image creation (defaults) + # + iotests.log("=== Successful image creation (defaults) ===") + iotests.log("") + + size = 128 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + + vm.qmp_log('blockdev-add', driver='file', filename=disk_path, + node_name='imgfile') + + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'imgfile', + 'size': size }) + vm.shutdown() + + iotests.img_info_log(disk_path) + iotests.log(iotests.qemu_img_pipe('map', '--output=json', disk_path)) + + # + # Successful image creation (explicit defaults) + # + iotests.log("=== Successful image creation (explicit defaults) ===") + iotests.log("") + + size = 64 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'preallocation': 'off' }) + vm.shutdown() + + iotests.img_info_log(disk_path) + iotests.log(iotests.qemu_img_pipe('map', '--output=json', disk_path)) + + # + # Successful image creation (with non-default options) + # + iotests.log("=== Successful image creation (with non-default options) ===") + iotests.log("") + + size = 32 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'preallocation': 'metadata' }) + vm.shutdown() + + iotests.img_info_log(disk_path) + iotests.log(iotests.qemu_img_pipe('map', '--output=json', disk_path)) + + # + # Invalid BlockdevRef + # + iotests.log("=== Invalid BlockdevRef ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': "this doesn't exist", + 'size': size }) + vm.shutdown() + + # + # Zero size + # + iotests.log("=== Zero size ===") + iotests.log("") + + vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 0 }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Maximum size + # + iotests.log("=== Maximum size ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 562949819203584 }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Invalid sizes + # + + # TODO Negative image sizes aren't handled correctly, but this is a problem + # with QAPI's implementation of the 'size' type and affects other commands + # as well. Once this is fixed, we may want to add a test case here. + + # 1. 2^64 - 512 + # 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this) + # 3. 0x1fffff8000001 (one byte more than maximum image size for VDI) + + iotests.log("=== Invalid sizes ===") + iotests.log("") + + vm.launch() + for size in [ 18446744073709551104, 9223372036854775808, 562949819203585 ]: + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': size }) + vm.shutdown() diff --git a/tests/qemu-iotests/211.out b/tests/qemu-iotests/211.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/211.out +++ b/tests/qemu-iotests/211.out @@ -XXX,XX +XXX,XX @@ -QA output created by 211 - === Successful image creation (defaults) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}} +{u'return': {}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'imgfile', 'size': 134217728}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 128M (134217728 bytes) +cluster_size: 1048576 + [{ "start": 0, "length": 134217728, "depth": 0, "zero": true, "data": false}] === Successful image creation (explicit defaults) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'off', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 67108864}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +image: TEST_IMG file format: IMGFMT virtual size: 64M (67108864 bytes) +cluster_size: 1048576 + [{ "start": 0, "length": 67108864, "depth": 0, "zero": true, "data": false}] === Successful image creation (with non-default options) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'metadata', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 33554432}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +image: TEST_IMG file format: IMGFMT virtual size: 32M (33554432 bytes) -[{ "start": 0, "length": 3072, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, -{ "start": 3072, "length": 33551360, "depth": 0, "zero": true, "data": true, "offset": OFFSET}] +cluster_size: 1048576 -=== Invalid BlockdevRef === +[{ "start": 0, "length": 3072, "depth": 0, "zero": false, "data": true, "offset": 1024}, +{ "start": 3072, "length": 33551360, "depth": 0, "zero": true, "data": true, "offset": 4096}] -Testing: -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +=== Invalid BlockdevRef === +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': "this doesn't exist", 'size': 33554432}}} +{u'return': {}} +Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Zero size === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 0}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 0 (0 bytes) +cluster_size: 1048576 === Maximum size === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203584}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 512T (562949819203584 bytes) +cluster_size: 1048576 === Invalid sizes === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Unsupported VDI image size (size is 0xfffffffffffffe00, max supported is 0x1fffff8000000)"}} -{"error": {"class": "GenericError", "desc": "Unsupported VDI image size (size is 0x8000000000000000, max supported is 0x1fffff8000000)"}} -{"error": {"class": "GenericError", "desc": "Unsupported VDI image size (size is 0x1fffff8000001, max supported is 0x1fffff8000000)"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 18446744073709551104L}}} +{u'return': {}} +Job failed: Unsupported VDI image size (size is 0xfffffffffffffe00, max supported is 0x1fffff8000000) +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 9223372036854775808L}}} +{u'return': {}} +Job failed: Unsupported VDI image size (size is 0x8000000000000000, max supported is 0x1fffff8000000) +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203585}}} +{u'return': {}} +Job failed: Unsupported VDI image size (size is 0x1fffff8000001, max supported is 0x1fffff8000000) +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -XXX,XX +XXX,XX @@ 208 rw auto quick 209 rw auto quick 210 rw auto +211 rw auto quick # TODO The following commented out tests need to be reworked to work # with the x-blockdev-create job -#211 rw auto quick #212 rw auto quick #213 rw auto quick 214 rw auto -- 2.13.6
This rewrites the test case 212 to work with the new x-blockdev-create job rather than the old synchronous version of the command. All of the test cases stay the same as before, but in order to be able to implement proper job handling, the test case is rewritten in Python. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> --- tests/qemu-iotests/212 | 483 +++++++++++++++++---------------------------- tests/qemu-iotests/212.out | 191 +++++++++++------- tests/qemu-iotests/group | 2 +- 3 files changed, 295 insertions(+), 381 deletions(-) diff --git a/tests/qemu-iotests/212 b/tests/qemu-iotests/212 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/212 +++ b/tests/qemu-iotests/212 @@ -XXX,XX +XXX,XX @@ -#!/bin/bash +#!/usr/bin/env python # # Test parallels and file image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <kwolf@redhat.com> +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -XXX,XX +XXX,XX @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator -owner=kwolf@redhat.com - -seq=`basename $0` -echo "QA output created by $seq" - -here=`pwd` -status=1 # failure is the default! - -# get standard environment, filters and checks -. ./common.rc -. ./common.filter - -_supported_fmt parallels -_supported_proto file -_supported_os Linux - -function do_run_qemu() -{ - echo Testing: "$@" - $QEMU -nographic -qmp stdio -serial none "$@" - echo -} - -function run_qemu() -{ - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \ - | _filter_qemu | _filter_imgfmt \ - | _filter_actual_image_size -} - -echo -echo "=== Successful image creation (defaults) ===" -echo - -size=$((128 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "blockdev-add", - "arguments": { - "driver": "file", - "node-name": "imgfile", - "filename": "$TEST_IMG" - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "imgfile", - "size": $size - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific - -echo -echo "=== Successful image creation (explicit defaults) ===" -echo - -# Choose a different size to show that we got a new image -size=$((64 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - }, - "size": $size, - "cluster-size": 1048576 - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific - -echo -echo "=== Successful image creation (with non-default options) ===" -echo - -# Choose a different size to show that we got a new image -size=$((32 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - }, - "size": $size, - "cluster-size": 65536 - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific - -echo -echo "=== Invalid BlockdevRef ===" -echo - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "this doesn't exist", - "size": $size - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Zero size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 0 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - -echo -echo "=== Maximum size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 4503599627369984 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - -echo -echo "=== Invalid sizes ===" -echo - -# TODO Negative image sizes aren't handled correctly, but this is a problem -# with QAPI's implementation of the 'size' type and affects other commands as -# well. Once this is fixed, we may want to add a test case here. - -# 1. Misaligned image size -# 2. 2^64 - 512 -# 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this) -# 4. 2^63 - 512 (generally valid, but with the image header the file will -# exceed 63 bits) -# 5. 2^52 (512 bytes more than maximum image size) - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 1234 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 18446744073709551104 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 9223372036854775808 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 9223372036854775296 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 4503599627370497 - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Invalid cluster size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "cluster-size": 1234 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "cluster-size": 128 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "cluster-size": 4294967296 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "cluster-size": 9223372036854775808 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "cluster-size": 18446744073709551104 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "cluster-size": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 281474976710656, - "cluster-size": 512 - } -} -{ "execute": "quit" } -EOF - - -# success, all done -echo "*** done" -rm -f $seq.full -status=0 +import iotests +from iotests import imgfmt + +iotests.verify_image_format(supported_fmts=['parallels']) +iotests.verify_protocol(supported=['file']) + +def blockdev_create(vm, options): + result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) + + if 'return' in result: + assert result['return'] == {} + vm.run_job('job0') + iotests.log("") + +with iotests.FilePath('t.parallels') as disk_path, \ + iotests.VM() as vm: + + # + # Successful image creation (defaults) + # + iotests.log("=== Successful image creation (defaults) ===") + iotests.log("") + + size = 128 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + + vm.qmp_log('blockdev-add', driver='file', filename=disk_path, + node_name='imgfile') + + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'imgfile', + 'size': size }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Successful image creation (explicit defaults) + # + iotests.log("=== Successful image creation (explicit defaults) ===") + iotests.log("") + + # Choose a different size to show that we got a new image + size = 64 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'cluster-size': 1048576 }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Successful image creation (with non-default options) + # + iotests.log("=== Successful image creation (with non-default options) ===") + iotests.log("") + + # Choose a different size to show that we got a new image + size = 32 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'cluster-size': 65536 }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Invalid BlockdevRef + # + iotests.log("=== Invalid BlockdevRef ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': "this doesn't exist", + 'size': size }) + vm.shutdown() + + # + # Zero size + # + iotests.log("=== Zero size ===") + iotests.log("") + + vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 0 }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Maximum size + # + iotests.log("=== Maximum size ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 4503599627369984}) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Invalid sizes + # + + # TODO Negative image sizes aren't handled correctly, but this is a problem + # with QAPI's implementation of the 'size' type and affects other commands + # as well. Once this is fixed, we may want to add a test case here. + + # 1. Misaligned image size + # 2. 2^64 - 512 + # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this) + # 4. 2^63 - 512 (generally valid, but with the image header the file will + # exceed 63 bits) + # 5. 2^52 (512 bytes more than maximum image size) + + iotests.log("=== Invalid sizes ===") + iotests.log("") + + vm.launch() + for size in [ 1234, 18446744073709551104, 9223372036854775808, + 9223372036854775296, 4503599627370497 ]: + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': size }) + vm.shutdown() + + # + # Invalid cluster size + # + iotests.log("=== Invalid cluster size ===") + iotests.log("") + + vm.launch() + for csize in [ 1234, 128, 4294967296, 9223372036854775808, + 18446744073709551104, 0 ]: + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'cluster-size': csize }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 281474976710656, + 'cluster-size': 512 }) + vm.shutdown() diff --git a/tests/qemu-iotests/212.out b/tests/qemu-iotests/212.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/212.out +++ b/tests/qemu-iotests/212.out @@ -XXX,XX +XXX,XX @@ -QA output created by 212 - === Successful image creation (defaults) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}} +{u'return': {}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'imgfile', 'size': 134217728}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 128M (134217728 bytes) === Successful image creation (explicit defaults) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1048576, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 67108864}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +image: TEST_IMG file format: IMGFMT virtual size: 64M (67108864 bytes) === Successful image creation (with non-default options) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 33554432}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 32M (33554432 bytes) === Invalid BlockdevRef === -Testing: -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': "this doesn't exist", 'size': 33554432}}} +{u'return': {}} +Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Zero size === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 0}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 0 (0 bytes) === Maximum size === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627369984}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 4096T (4503599627369984 bytes) === Invalid sizes === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Image size must be a multiple of 512 bytes"}} -{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}} -{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}} -{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}} -{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 1234}}} +{u'return': {}} +Job failed: Image size must be a multiple of 512 bytes +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 18446744073709551104L}}} +{u'return': {}} +Job failed: Image size is too large for this cluster size +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775808L}}} +{u'return': {}} +Job failed: Image size is too large for this cluster size +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775296}}} +{u'return': {}} +Job failed: Image size is too large for this cluster size +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627370497}}} +{u'return': {}} +Job failed: Image size is too large for this cluster size +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Invalid cluster size === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Cluster size must be a multiple of 512 bytes"}} -{"error": {"class": "GenericError", "desc": "Cluster size must be a multiple of 512 bytes"}} -{"error": {"class": "GenericError", "desc": "Cluster size is too large"}} -{"error": {"class": "GenericError", "desc": "Cluster size is too large"}} -{"error": {"class": "GenericError", "desc": "Cluster size is too large"}} -{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}} -{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - -*** done +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Cluster size must be a multiple of 512 bytes +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Cluster size must be a multiple of 512 bytes +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4294967296, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Cluster size is too large +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 9223372036854775808L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Cluster size is too large +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 18446744073709551104L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Cluster size is too large +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Image size is too large for this cluster size +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'parallels', 'file': 'node0', 'size': 281474976710656}}} +{u'return': {}} +Job failed: Image size is too large for this cluster size +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -XXX,XX +XXX,XX @@ 209 rw auto quick 210 rw auto 211 rw auto quick +212 rw auto quick # TODO The following commented out tests need to be reworked to work # with the x-blockdev-create job -#212 rw auto quick #213 rw auto quick 214 rw auto 215 rw auto quick -- 2.13.6
This rewrites the test case 213 to work with the new x-blockdev-create job rather than the old synchronous version of the command. All of the test cases stay the same as before, but in order to be able to implement proper job handling, the test case is rewritten in Python. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> --- tests/qemu-iotests/213 | 520 +++++++++++++++++---------------------------- tests/qemu-iotests/213.out | 208 +++++++++++------- tests/qemu-iotests/group | 4 +- 3 files changed, 319 insertions(+), 413 deletions(-) diff --git a/tests/qemu-iotests/213 b/tests/qemu-iotests/213 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/213 +++ b/tests/qemu-iotests/213 @@ -XXX,XX +XXX,XX @@ -#!/bin/bash +#!/usr/bin/env python # # Test vhdx and file image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <kwolf@redhat.com> +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -XXX,XX +XXX,XX @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator -owner=kwolf@redhat.com - -seq=`basename $0` -echo "QA output created by $seq" - -here=`pwd` -status=1 # failure is the default! - -# get standard environment, filters and checks -. ./common.rc -. ./common.filter - -_supported_fmt vhdx -_supported_proto file -_supported_os Linux - -function do_run_qemu() -{ - echo Testing: "$@" - $QEMU -nographic -qmp stdio -serial none "$@" - echo -} - -function run_qemu() -{ - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \ - | _filter_qemu | _filter_imgfmt \ - | _filter_actual_image_size -} - -echo -echo "=== Successful image creation (defaults) ===" -echo - -size=$((128 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "blockdev-add", - "arguments": { - "driver": "file", - "node-name": "imgfile", - "filename": "$TEST_IMG" - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "imgfile", - "size": $size - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific - -echo -echo "=== Successful image creation (explicit defaults) ===" -echo - -# Choose a different size to show that we got a new image -size=$((64 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - }, - "size": $size, - "log-size": 1048576, - "block-size": 8388608, - "subformat": "dynamic", - "block-state-zero": true - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific - -echo -echo "=== Successful image creation (with non-default options) ===" -echo - -# Choose a different size to show that we got a new image -size=$((32 * 1024 * 1024)) - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "file", - "filename": "$TEST_IMG", - "size": 0 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - }, - "size": $size, - "log-size": 8388608, - "block-size": 268435456, - "subformat": "fixed", - "block-state-zero": false - } -} -{ "execute": "quit" } -EOF - -_img_info --format-specific | _filter_img_info --format-specific - -echo -echo "=== Invalid BlockdevRef ===" -echo - -run_qemu <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "this doesn't exist", - "size": $size - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Zero size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 0 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - -echo -echo "=== Maximum size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 70368744177664 - } -} -{ "execute": "quit" } -EOF - -_img_info | _filter_img_info - -echo -echo "=== Invalid sizes ===" -echo - -# TODO Negative image sizes aren't handled correctly, but this is a problem -# with QAPI's implementation of the 'size' type and affects other commands as -# well. Once this is fixed, we may want to add a test case here. - -# 1. 2^64 - 512 -# 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this) -# 3. 2^63 - 512 (generally valid, but with the image header the file will -# exceed 63 bits) -# 4. 2^46 + 1 (one byte more than maximum image size) - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 18446744073709551104 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 9223372036854775808 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 9223372036854775296 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 70368744177665 - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Invalid block size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "block-size": 1234567 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "block-size": 128 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "block-size": 3145728 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "block-size": 536870912 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "block-size": 0 - } -} -{ "execute": "quit" } -EOF - -echo -echo "=== Invalid log size ===" -echo - -run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF -{ "execute": "qmp_capabilities" } -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "log-size": 1234567 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "log-size": 128 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "log-size": 4294967296 - } -} -{ "execute": "x-blockdev-create", - "arguments": { - "driver": "$IMGFMT", - "file": "node0", - "size": 67108864, - "log-size": 0 - } -} -{ "execute": "quit" } -EOF - - -# success, all done -echo "*** done" -rm -f $seq.full -status=0 +import iotests +from iotests import imgfmt + +iotests.verify_image_format(supported_fmts=['vhdx']) +iotests.verify_protocol(supported=['file']) + +def blockdev_create(vm, options): + result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) + + if 'return' in result: + assert result['return'] == {} + vm.run_job('job0') + iotests.log("") + +with iotests.FilePath('t.vhdx') as disk_path, \ + iotests.VM() as vm: + + # + # Successful image creation (defaults) + # + iotests.log("=== Successful image creation (defaults) ===") + iotests.log("") + + size = 128 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + + vm.qmp_log('blockdev-add', driver='file', filename=disk_path, + node_name='imgfile') + + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'imgfile', + 'size': size }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Successful image creation (explicit defaults) + # + iotests.log("=== Successful image creation (explicit defaults) ===") + iotests.log("") + + # Choose a different size to show that we got a new image + size = 64 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'log-size': 1048576, + 'block-size': 8388608, + 'subformat': 'dynamic', + 'block-state-zero': True }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Successful image creation (with non-default options) + # + iotests.log("=== Successful image creation (with non-default options) ===") + iotests.log("") + + # Choose a different size to show that we got a new image + size = 32 * 1024 * 1024 + + vm.launch() + blockdev_create(vm, { 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + blockdev_create(vm, { 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'log-size': 8388608, + 'block-size': 268435456, + 'subformat': 'fixed', + 'block-state-zero': False }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Invalid BlockdevRef + # + iotests.log("=== Invalid BlockdevRef ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': "this doesn't exist", + 'size': size }) + vm.shutdown() + + # + # Zero size + # + iotests.log("=== Zero size ===") + iotests.log("") + + vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 0 }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Maximum size + # + iotests.log("=== Maximum size ===") + iotests.log("") + + vm.launch() + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 70368744177664 }) + vm.shutdown() + + iotests.img_info_log(disk_path) + + # + # Invalid sizes + # + + # TODO Negative image sizes aren't handled correctly, but this is a problem + # with QAPI's implementation of the 'size' type and affects other commands + # as well. Once this is fixed, we may want to add a test case here. + + # 1. 2^64 - 512 + # 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this) + # 3. 2^63 - 512 (generally valid, but with the image header the file will + # exceed 63 bits) + # 4. 2^46 + 1 (one byte more than maximum image size) + + iotests.log("=== Invalid sizes ===") + iotests.log("") + + vm.launch() + for size in [ 18446744073709551104, 9223372036854775808, + 9223372036854775296, 70368744177665 ]: + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': size }) + vm.shutdown() + + # + # Invalid block size + # + iotests.log("=== Invalid block size ===") + iotests.log("") + + vm.launch() + for bsize in [ 1234567, 128, 3145728, 536870912, 0 ]: + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'block-size': bsize }) + vm.shutdown() + + # + # Invalid log size + # + iotests.log("=== Invalid log size ===") + iotests.log("") + + vm.launch() + for lsize in [ 1234567, 128, 4294967296, 0 ]: + blockdev_create(vm, { 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'log-size': lsize }) + vm.shutdown() diff --git a/tests/qemu-iotests/213.out b/tests/qemu-iotests/213.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/213.out +++ b/tests/qemu-iotests/213.out @@ -XXX,XX +XXX,XX @@ -QA output created by 213 - === Successful image creation (defaults) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}} +{u'return': {}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'imgfile', 'size': 134217728}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 128M (134217728 bytes) +cluster_size: 8388608 === Successful image creation (explicit defaults) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 8388608, 'driver': 'vhdx', 'subformat': 'dynamic', 'log-size': 1048576, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': True, 'size': 67108864}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +image: TEST_IMG file format: IMGFMT virtual size: 64M (67108864 bytes) +cluster_size: 8388608 === Successful image creation (with non-default options) === -Testing: -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 268435456, 'driver': 'vhdx', 'subformat': 'fixed', 'log-size': 8388608, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': False, 'size': 33554432}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 32M (33554432 bytes) +cluster_size: 268435456 === Invalid BlockdevRef === -Testing: -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': "this doesn't exist", 'size': 33554432}}} +{u'return': {}} +Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Zero size === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 0}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 0 (0 bytes) +cluster_size: 8388608 === Maximum size === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"return": {}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177664}}} +{u'return': {}} +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} -image: TEST_DIR/t.IMGFMT +image: TEST_IMG file format: IMGFMT virtual size: 64T (70368744177664 bytes) +cluster_size: 67108864 === Invalid sizes === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Image size too large; max of 64TB"}} -{"error": {"class": "GenericError", "desc": "Image size too large; max of 64TB"}} -{"error": {"class": "GenericError", "desc": "Image size too large; max of 64TB"}} -{"error": {"class": "GenericError", "desc": "Image size too large; max of 64TB"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 18446744073709551104L}}} +{u'return': {}} +Job failed: Image size too large; max of 64TB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775808L}}} +{u'return': {}} +Job failed: Image size too large; max of 64TB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775296}}} +{u'return': {}} +Job failed: Image size too large; max of 64TB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177665}}} +{u'return': {}} +Job failed: Image size too large; max of 64TB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Invalid block size === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Block size must be a multiple of 1 MB"}} -{"error": {"class": "GenericError", "desc": "Block size must be a multiple of 1 MB"}} -{"error": {"class": "GenericError", "desc": "Block size must be a power of two"}} -{"error": {"class": "GenericError", "desc": "Block size must not exceed 268435456"}} -{"error": {"class": "GenericError", "desc": "Block size must be a multiple of 1 MB"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 1234567, 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Block size must be a multiple of 1 MB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 128, 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Block size must be a multiple of 1 MB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 3145728, 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Block size must be a power of two +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 536870912, 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Block size must not exceed 268435456 +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 0, 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Block size must be a multiple of 1 MB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} === Invalid log size === -Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -QMP_VERSION -{"return": {}} -{"error": {"class": "GenericError", "desc": "Log size must be a multiple of 1 MB"}} -{"error": {"class": "GenericError", "desc": "Log size must be a multiple of 1 MB"}} -{"error": {"class": "GenericError", "desc": "Log size must be smaller than 4 GB"}} -{"error": {"class": "GenericError", "desc": "Log size must be a multiple of 1 MB"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} - -*** done +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 1234567, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Log size must be a multiple of 1 MB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 128, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Log size must be a multiple of 1 MB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 4294967296, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Log size must be smaller than 4 GB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + +{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 0, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} +{u'return': {}} +Job failed: Log size must be a multiple of 1 MB +{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} +{u'return': {}} + diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -XXX,XX +XXX,XX @@ 210 rw auto 211 rw auto quick 212 rw auto quick -# TODO The following commented out tests need to be reworked to work -# with the x-blockdev-create job -#213 rw auto quick +213 rw auto quick 214 rw auto 215 rw auto quick 216 rw auto quick -- 2.13.6
We're ready to declare the blockdev-create job stable. This renames the corresponding QMP command from x-blockdev-create to blockdev-create. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> --- qapi/block-core.json | 4 ++-- qapi/job.json | 2 +- block/create.c | 4 ++-- tests/qemu-iotests/206 | 2 +- tests/qemu-iotests/206.out | 54 +++++++++++++++++++++++----------------------- tests/qemu-iotests/207 | 2 +- tests/qemu-iotests/207.out | 18 ++++++++-------- tests/qemu-iotests/210 | 2 +- tests/qemu-iotests/210.out | 18 ++++++++-------- tests/qemu-iotests/211 | 2 +- tests/qemu-iotests/211.out | 24 ++++++++++----------- tests/qemu-iotests/212 | 2 +- tests/qemu-iotests/212.out | 42 ++++++++++++++++++------------------ tests/qemu-iotests/213 | 2 +- tests/qemu-iotests/213.out | 44 ++++++++++++++++++------------------- 15 files changed, 111 insertions(+), 111 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index XXXXXXX..XXXXXXX 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -XXX,XX +XXX,XX @@ } } ## -# @x-blockdev-create: +# @blockdev-create: # # Starts a job to create an image format on a given node. The job is # automatically finalized, but a manual job-dismiss is required. @@ -XXX,XX +XXX,XX @@ # # Since: 3.0 ## -{ 'command': 'x-blockdev-create', +{ 'command': 'blockdev-create', 'data': { 'job-id': 'str', 'options': 'BlockdevCreateOptions' } } diff --git a/qapi/job.json b/qapi/job.json index XXXXXXX..XXXXXXX 100644 --- a/qapi/job.json +++ b/qapi/job.json @@ -XXX,XX +XXX,XX @@ # # @backup: drive backup job type, see "drive-backup" # -# @create: image creation job type, see "x-blockdev-create" (since 3.0) +# @create: image creation job type, see "blockdev-create" (since 3.0) # # Since: 1.7 ## diff --git a/block/create.c b/block/create.c index XXXXXXX..XXXXXXX 100644 --- a/block/create.c +++ b/block/create.c @@ -XXX,XX +XXX,XX @@ static const JobDriver blockdev_create_job_driver = { .start = blockdev_create_run, }; -void qmp_x_blockdev_create(const char *job_id, BlockdevCreateOptions *options, - Error **errp) +void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options, + Error **errp) { BlockdevCreateJob *s; const char *fmt = BlockdevDriver_str(options->driver); diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/206 +++ b/tests/qemu-iotests/206 @@ -XXX,XX +XXX,XX @@ from iotests import imgfmt iotests.verify_image_format(supported_fmts=['qcow2']) def blockdev_create(vm, options): - result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) + result = vm.qmp_log('blockdev-create', job_id='job0', options=options) if 'return' in result: assert result['return'] == {} diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/206.out +++ b/tests/qemu-iotests/206.out @@ -XXX,XX +XXX,XX @@ === Successful image creation (defaults) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} {'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'imgfile', 'size': 134217728}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'imgfile', 'size': 134217728}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ Format specific information: === Successful image creation (inline blockdev-add, explicit defaults) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': False, 'preallocation': 'off', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': False, 'preallocation': 'off', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'refcount-bits': 16, 'version': 'v3', 'preallocation': 'off', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': False, 'driver': 'qcow2', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'refcount-bits': 16, 'version': 'v3', 'preallocation': 'off', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': False, 'driver': 'qcow2', 'size': 67108864}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ Format specific information: === Successful image creation (v3 non-default options) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': True, 'preallocation': 'falloc', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': True, 'preallocation': 'falloc', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 2097152, 'refcount-bits': 1, 'version': 'v3', 'preallocation': 'metadata', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': True, 'driver': 'qcow2', 'size': 33554432}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 2097152, 'refcount-bits': 1, 'version': 'v3', 'preallocation': 'metadata', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': True, 'driver': 'qcow2', 'size': 33554432}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ Format specific information: === Successful image creation (v2 non-default options) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'backing-fmt': 'qcow2', 'driver': 'qcow2', 'version': 'v2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'backing-file': 'TEST_DIR/PID-t.qcow2.base', 'size': 33554432}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'backing-fmt': 'qcow2', 'driver': 'qcow2', 'version': 'v2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'backing-file': 'TEST_DIR/PID-t.qcow2.base', 'size': 33554432}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ Format specific information: === Successful image creation (encrypted) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'encrypt': {'key-secret': 'keysec0', 'iter-time': 10, 'cipher-mode': 'ctr', 'ivgen-hash-alg': 'md5', 'cipher-alg': 'twofish-128', 'format': 'luks', 'ivgen-alg': 'plain64', 'hash-alg': 'sha1'}, 'driver': 'qcow2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'size': 33554432}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'encrypt': {'key-secret': 'keysec0', 'iter-time': 10, 'cipher-mode': 'ctr', 'ivgen-hash-alg': 'md5', 'cipher-alg': 'twofish-128', 'format': 'luks', 'ivgen-alg': 'plain64', 'hash-alg': 'sha1'}, 'driver': 'qcow2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'size': 33554432}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ Format specific information: === Invalid BlockdevRef === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': "this doesn't exist", 'size': 33554432}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': "this doesn't exist", 'size': 33554432}}} {u'return': {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} === Invalid sizes === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 1234}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 1234}}} {u'return': {}} Job failed: Image size must be a multiple of 512 bytes {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 18446744073709551104L}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 18446744073709551104L}}} {u'return': {}} Job failed: Could not resize image: Image size cannot be negative {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775808L}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775808L}}} {u'return': {}} Job failed: Could not resize image: Image size cannot be negative {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775296}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775296}}} {u'return': {}} Job failed: Could not resize image: Failed to grow the L1 table: File too large {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} === Invalid version === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'version': 'v1', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'version': 'v1', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'error': {u'class': u'GenericError', u'desc': u"Invalid parameter 'v1'"}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'lazy-refcounts': True, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'lazy-refcounts': True, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater) {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 8, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 8, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Different refcount widths than 16 bits require compatibility level 1.1 or above (use version=v3 or greater) {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} === Invalid backing file options === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'full', 'driver': 'qcow2', 'backing-file': '/dev/null', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'full', 'driver': 'qcow2', 'backing-file': '/dev/null', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Backing file and preallocation cannot be used at the same time {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'backing-fmt': 'qcow2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'backing-fmt': 'qcow2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Backing format cannot be used without backing file {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} === Invalid cluster size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Cluster size must be a power of two between 512 and 2048k {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Cluster size must be a power of two between 512 and 2048k {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4194304, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4194304, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Cluster size must be a power of two between 512 and 2048k {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Cluster size must be a power of two between 512 and 2048k {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'qcow2', 'file': 'node0', 'size': 281474976710656}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'qcow2', 'file': 'node0', 'size': 281474976710656}}} {u'return': {}} Job failed: Could not resize image: Failed to grow the L1 table: File too large {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} === Invalid refcount width === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Refcount width must be a power of two and may not exceed 64 bits {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Refcount width must be a power of two and may not exceed 64 bits {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 7, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 7, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Refcount width must be a power of two and may not exceed 64 bits {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/207 +++ b/tests/qemu-iotests/207 @@ -XXX,XX +XXX,XX @@ def filter_hash(msg): return re.sub("'hash': '[0-9a-f]+'", "'hash': HASH", msg) def blockdev_create(vm, options): - result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options, + result = vm.qmp_log('blockdev-create', job_id='job0', options=options, filters=[iotests.filter_testfiles, filter_hash]) if 'return' in result: diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/207.out +++ b/tests/qemu-iotests/207.out @@ -XXX,XX +XXX,XX @@ === Successful image creation (defaults) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ virtual size: 4.0M (4194304 bytes) === Test host-key-check options === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.po file format: IMGFMT virtual size: 8.0M (8388608 bytes) -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'known_hosts'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'known_hosts'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.po file format: IMGFMT virtual size: 4.0M (4194304 bytes) -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}} {u'return': {}} Job failed: remote host key does not match host_key_check 'wrong' {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.po file format: IMGFMT virtual size: 8.0M (8388608 bytes) -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}} {u'return': {}} Job failed: remote host key does not match host_key_check 'wrong' {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ virtual size: 4.0M (4194304 bytes) === Invalid path and user === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': '/this/is/not/an/existing/path', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': '/this/is/not/an/existing/path', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} {u'return': {}} Job failed: failed to open remote file '/this/is/not/an/existing/path': Failed opening remote file (libssh2 error code: -31) {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'user': 'invalid user', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'user': 'invalid user', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}} {u'return': {}} Job failed: failed to authenticate using publickey authentication and the identities held by your ssh-agent {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} diff --git a/tests/qemu-iotests/210 b/tests/qemu-iotests/210 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/210 +++ b/tests/qemu-iotests/210 @@ -XXX,XX +XXX,XX @@ iotests.verify_image_format(supported_fmts=['luks']) iotests.verify_protocol(supported=['file']) def blockdev_create(vm, options): - result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) + result = vm.qmp_log('blockdev-create', job_id='job0', options=options) if 'return' in result: assert result['return'] == {} diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/210.out +++ b/tests/qemu-iotests/210.out @@ -XXX,XX +XXX,XX @@ === Successful image creation (defaults) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} {'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'imgfile', 'size': 134217728}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'imgfile', 'size': 134217728}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ Format specific information: === Successful image creation (with non-default options) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'hash-alg': 'sha1', 'cipher-mode': 'ctr', 'cipher-alg': 'twofish-128', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}, 'iter-time': 10, 'ivgen-alg': 'plain64', 'ivgen-hash-alg': 'md5', 'driver': 'luks', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'hash-alg': 'sha1', 'cipher-mode': 'ctr', 'cipher-alg': 'twofish-128', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}, 'iter-time': 10, 'ivgen-alg': 'plain64', 'ivgen-hash-alg': 'md5', 'driver': 'luks', 'size': 67108864}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ Format specific information: === Invalid BlockdevRef === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'luks', 'file': "this doesn't exist", 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'luks', 'file': "this doesn't exist", 'size': 67108864}}} {u'return': {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} @@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi === Zero size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'node0', 'size': 0}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'node0', 'size': 0}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ Format specific information: === Invalid sizes === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 18446744073709551104L}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 18446744073709551104L}}} {u'return': {}} Job failed: The requested file size is too large {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775808L}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775808L}}} {u'return': {}} Job failed: The requested file size is too large {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775296}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775296}}} {u'return': {}} Job failed: The requested file size is too large {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} diff --git a/tests/qemu-iotests/211 b/tests/qemu-iotests/211 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/211 +++ b/tests/qemu-iotests/211 @@ -XXX,XX +XXX,XX @@ iotests.verify_image_format(supported_fmts=['vdi']) iotests.verify_protocol(supported=['file']) def blockdev_create(vm, options): - result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) + result = vm.qmp_log('blockdev-create', job_id='job0', options=options) if 'return' in result: assert result['return'] == {} diff --git a/tests/qemu-iotests/211.out b/tests/qemu-iotests/211.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/211.out +++ b/tests/qemu-iotests/211.out @@ -XXX,XX +XXX,XX @@ === Successful image creation (defaults) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} {'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'imgfile', 'size': 134217728}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'imgfile', 'size': 134217728}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ cluster_size: 1048576 === Successful image creation (explicit defaults) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'off', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'off', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 67108864}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ cluster_size: 1048576 === Successful image creation (with non-default options) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'metadata', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 33554432}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'metadata', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 33554432}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ cluster_size: 1048576 === Invalid BlockdevRef === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': "this doesn't exist", 'size': 33554432}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': "this doesn't exist", 'size': 33554432}}} {u'return': {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} @@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi === Zero size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 0}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 0}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ cluster_size: 1048576 === Maximum size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203584}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203584}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ cluster_size: 1048576 === Invalid sizes === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 18446744073709551104L}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 18446744073709551104L}}} {u'return': {}} Job failed: Unsupported VDI image size (size is 0xfffffffffffffe00, max supported is 0x1fffff8000000) {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 9223372036854775808L}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 9223372036854775808L}}} {u'return': {}} Job failed: Unsupported VDI image size (size is 0x8000000000000000, max supported is 0x1fffff8000000) {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203585}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203585}}} {u'return': {}} Job failed: Unsupported VDI image size (size is 0x1fffff8000001, max supported is 0x1fffff8000000) {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} diff --git a/tests/qemu-iotests/212 b/tests/qemu-iotests/212 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/212 +++ b/tests/qemu-iotests/212 @@ -XXX,XX +XXX,XX @@ iotests.verify_image_format(supported_fmts=['parallels']) iotests.verify_protocol(supported=['file']) def blockdev_create(vm, options): - result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) + result = vm.qmp_log('blockdev-create', job_id='job0', options=options) if 'return' in result: assert result['return'] == {} diff --git a/tests/qemu-iotests/212.out b/tests/qemu-iotests/212.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/212.out +++ b/tests/qemu-iotests/212.out @@ -XXX,XX +XXX,XX @@ === Successful image creation (defaults) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} {'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'imgfile', 'size': 134217728}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'imgfile', 'size': 134217728}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ virtual size: 128M (134217728 bytes) === Successful image creation (explicit defaults) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1048576, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1048576, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 67108864}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ virtual size: 64M (67108864 bytes) === Successful image creation (with non-default options) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 33554432}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 33554432}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ virtual size: 32M (33554432 bytes) === Invalid BlockdevRef === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': "this doesn't exist", 'size': 33554432}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': "this doesn't exist", 'size': 33554432}}} {u'return': {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} @@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi === Zero size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 0}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 0}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ virtual size: 0 (0 bytes) === Maximum size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627369984}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627369984}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ virtual size: 4096T (4503599627369984 bytes) === Invalid sizes === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 1234}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 1234}}} {u'return': {}} Job failed: Image size must be a multiple of 512 bytes {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 18446744073709551104L}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 18446744073709551104L}}} {u'return': {}} Job failed: Image size is too large for this cluster size {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775808L}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775808L}}} {u'return': {}} Job failed: Image size is too large for this cluster size {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775296}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775296}}} {u'return': {}} Job failed: Image size is too large for this cluster size {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627370497}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627370497}}} {u'return': {}} Job failed: Image size is too large for this cluster size {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} @@ -XXX,XX +XXX,XX @@ Job failed: Image size is too large for this cluster size === Invalid cluster size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Cluster size must be a multiple of 512 bytes {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Cluster size must be a multiple of 512 bytes {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4294967296, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4294967296, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Cluster size is too large {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 9223372036854775808L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 9223372036854775808L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Cluster size is too large {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 18446744073709551104L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 18446744073709551104L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Cluster size is too large {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Image size is too large for this cluster size {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'parallels', 'file': 'node0', 'size': 281474976710656}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'parallels', 'file': 'node0', 'size': 281474976710656}}} {u'return': {}} Job failed: Image size is too large for this cluster size {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} diff --git a/tests/qemu-iotests/213 b/tests/qemu-iotests/213 index XXXXXXX..XXXXXXX 100755 --- a/tests/qemu-iotests/213 +++ b/tests/qemu-iotests/213 @@ -XXX,XX +XXX,XX @@ iotests.verify_image_format(supported_fmts=['vhdx']) iotests.verify_protocol(supported=['file']) def blockdev_create(vm, options): - result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) + result = vm.qmp_log('blockdev-create', job_id='job0', options=options) if 'return' in result: assert result['return'] == {} diff --git a/tests/qemu-iotests/213.out b/tests/qemu-iotests/213.out index XXXXXXX..XXXXXXX 100644 --- a/tests/qemu-iotests/213.out +++ b/tests/qemu-iotests/213.out @@ -XXX,XX +XXX,XX @@ === Successful image creation (defaults) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} {'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'imgfile', 'size': 134217728}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'imgfile', 'size': 134217728}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ cluster_size: 8388608 === Successful image creation (explicit defaults) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 8388608, 'driver': 'vhdx', 'subformat': 'dynamic', 'log-size': 1048576, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': True, 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 8388608, 'driver': 'vhdx', 'subformat': 'dynamic', 'log-size': 1048576, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': True, 'size': 67108864}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ cluster_size: 8388608 === Successful image creation (with non-default options) === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 268435456, 'driver': 'vhdx', 'subformat': 'fixed', 'log-size': 8388608, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': False, 'size': 33554432}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 268435456, 'driver': 'vhdx', 'subformat': 'fixed', 'log-size': 8388608, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': False, 'size': 33554432}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ cluster_size: 268435456 === Invalid BlockdevRef === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': "this doesn't exist", 'size': 33554432}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': "this doesn't exist", 'size': 33554432}}} {u'return': {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} @@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi === Zero size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 0}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 0}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ cluster_size: 8388608 === Maximum size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177664}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177664}}} {u'return': {}} {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} @@ -XXX,XX +XXX,XX @@ cluster_size: 67108864 === Invalid sizes === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 18446744073709551104L}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 18446744073709551104L}}} {u'return': {}} Job failed: Image size too large; max of 64TB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775808L}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775808L}}} {u'return': {}} Job failed: Image size too large; max of 64TB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775296}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775296}}} {u'return': {}} Job failed: Image size too large; max of 64TB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177665}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177665}}} {u'return': {}} Job failed: Image size too large; max of 64TB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} @@ -XXX,XX +XXX,XX @@ Job failed: Image size too large; max of 64TB === Invalid block size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 1234567, 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 1234567, 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Block size must be a multiple of 1 MB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 128, 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 128, 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Block size must be a multiple of 1 MB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 3145728, 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 3145728, 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Block size must be a power of two {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 536870912, 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 536870912, 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Block size must not exceed 268435456 {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 0, 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 0, 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Block size must be a multiple of 1 MB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} @@ -XXX,XX +XXX,XX @@ Job failed: Block size must be a multiple of 1 MB === Invalid log size === -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 1234567, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 1234567, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Log size must be a multiple of 1 MB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 128, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 128, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Log size must be a multiple of 1 MB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 4294967296, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 4294967296, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Log size must be smaller than 4 GB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} {u'return': {}} -{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 0, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} +{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 0, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}} {u'return': {}} Job failed: Log size must be a multiple of 1 MB {'execute': 'job-dismiss', 'arguments': {'id': 'job0'}} -- 2.13.6
The following changes since commit 13356edb87506c148b163b8c7eb0695647d00c2a: Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2023-01-24 09:45:33 +0000) are available in the Git repository at: https://repo.or.cz/qemu/kevin.git tags/for-upstream for you to fetch changes up to d570177b50c389f379f93183155a27d44856ab46: qemu-img: Change info key names for protocol nodes (2023-02-01 16:52:33 +0100) v4: - Fixed the 'qemu-img-close-errors' test case to run only on Linux and only with the file protocol, use qemu-io instead of truncate v3: - Make the compiler happier on BSD and CentOS Stream 8 v2: - Rebased to resolve merge conflicts in coroutine.h ---------------------------------------------------------------- Block layer patches - qemu-img info: Show protocol-level information - Move more functions to coroutines - Make coroutine annotations ready for static analysis - qemu-img: Fix exit code for errors closing the image - qcow2 bitmaps: Fix theoretical corruption in error path - pflash: Only load non-zero parts of backend image to save memory - Code cleanup and test case improvements ---------------------------------------------------------------- Alberto Faria (2): coroutine: annotate coroutine_fn for libclang block: Add no_coroutine_fn and coroutine_mixed_fn marker Emanuele Giuseppe Esposito (14): block-coroutine-wrapper: support void functions block: Convert bdrv_io_plug() to co_wrapper block: Convert bdrv_io_unplug() to co_wrapper block: Convert bdrv_is_inserted() to co_wrapper block: Rename refresh_total_sectors to bdrv_refresh_total_sectors block: Convert bdrv_refresh_total_sectors() to co_wrapper_mixed block-backend: use bdrv_getlength instead of blk_getlength block: use bdrv_co_refresh_total_sectors when possible block: Convert bdrv_get_allocated_file_size() to co_wrapper block: Convert bdrv_get_info() to co_wrapper_mixed block: Convert bdrv_eject() to co_wrapper block: Convert bdrv_lock_medium() to co_wrapper block: Convert bdrv_debug_event() to co_wrapper_mixed block: Rename bdrv_load/save_vmstate() to bdrv_co_load/save_vmstate() Hanna Reitz (12): block: Improve empty format-specific info dump block/file: Add file-specific image info block/vmdk: Change extent info type block: Split BlockNodeInfo off of ImageInfo qemu-img: Use BlockNodeInfo block/qapi: Let bdrv_query_image_info() recurse block/qapi: Introduce BlockGraphInfo block/qapi: Add indentation to bdrv_node_info_dump() iotests: Filter child node information iotests/106, 214, 308: Read only one size line qemu-img: Let info print block graph qemu-img: Change info key names for protocol nodes Kevin Wolf (4): qcow2: Fix theoretical corruption in store_bitmap() error path qemu-img commit: Report errors while closing the image qemu-img bitmap: Report errors while closing the image qemu-iotests: Test qemu-img bitmap/commit exit code on error Paolo Bonzini (2): qemu-io: do not reinvent the blk_pwrite_zeroes wheel block: remove bdrv_coroutine_enter Philippe Mathieu-Daudé (1): block/nbd: Add missing <qemu/bswap.h> include Thomas Huth (2): tests/qemu-iotests/312: Mark "quorum" as required driver tests/qemu-iotests/262: Check for availability of "blkverify" first Xiang Zheng (1): pflash: Only read non-zero parts of backend image qapi/block-core.json | 123 +++++++- include/block/block-common.h | 11 +- include/block/block-io.h | 41 ++- include/block/block_int-common.h | 26 +- include/block/block_int-io.h | 5 +- include/block/nbd.h | 1 + include/block/qapi.h | 14 +- include/qemu/osdep.h | 44 +++ include/sysemu/block-backend-io.h | 31 +- block.c | 88 +++--- block/blkdebug.c | 11 +- block/blkio.c | 15 +- block/blklogwrites.c | 6 +- block/blkreplay.c | 6 +- block/blkverify.c | 6 +- block/block-backend.c | 38 +-- block/commit.c | 4 +- block/copy-on-read.c | 18 +- block/crypto.c | 14 +- block/curl.c | 10 +- block/file-posix.c | 137 +++++---- block/file-win32.c | 18 +- block/filter-compress.c | 20 +- block/gluster.c | 23 +- block/io.c | 76 ++--- block/iscsi.c | 17 +- block/mirror.c | 6 +- block/monitor/block-hmp-cmds.c | 2 +- block/nbd.c | 8 +- block/nfs.c | 4 +- block/null.c | 13 +- block/nvme.c | 14 +- block/preallocate.c | 16 +- block/qapi.c | 317 ++++++++++++++++----- block/qcow.c | 5 +- block/qcow2-bitmap.c | 5 +- block/qcow2-refcount.c | 2 +- block/qcow2.c | 17 +- block/qed.c | 11 +- block/quorum.c | 8 +- block/raw-format.c | 25 +- block/rbd.c | 9 +- block/replication.c | 6 +- block/ssh.c | 4 +- block/throttle.c | 6 +- block/vdi.c | 7 +- block/vhdx.c | 5 +- block/vmdk.c | 22 +- block/vpc.c | 5 +- blockdev.c | 8 +- hw/block/block.c | 36 ++- hw/scsi/scsi-disk.c | 5 + qemu-img.c | 100 +++++-- qemu-io-cmds.c | 62 +--- tests/unit/test-block-iothread.c | 3 + scripts/block-coroutine-wrapper.py | 20 +- tests/qemu-iotests/iotests.py | 18 +- block/meson.build | 1 + tests/qemu-iotests/065 | 2 +- tests/qemu-iotests/106 | 4 +- tests/qemu-iotests/214 | 6 +- tests/qemu-iotests/262 | 3 +- tests/qemu-iotests/302.out | 5 + tests/qemu-iotests/308 | 4 +- tests/qemu-iotests/312 | 1 + tests/qemu-iotests/common.filter | 22 +- tests/qemu-iotests/common.rc | 22 +- tests/qemu-iotests/tests/qemu-img-close-errors | 96 +++++++ tests/qemu-iotests/tests/qemu-img-close-errors.out | 23 ++ 69 files changed, 1209 insertions(+), 552 deletions(-) create mode 100755 tests/qemu-iotests/tests/qemu-img-close-errors create mode 100644 tests/qemu-iotests/tests/qemu-img-close-errors.out