block: Make blockdev-create a job and stable API
v2 cover block: Make blockdev-create a job and stable API
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 progress yet (so both current-progress and total-progress stay at 0). These features can be added later without breaking compatibility.
At the end of the series, the interface is declared stable and the x- prefix is removed.
v2:
- Made job->error == NULL iff job->ret == 0 [Max]
- Fixed a comment in qmp_blockdev_create() and added a TODO comment for AioContext locking at least [Max]
- Many small changes in the tests [Max, Jeff]
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/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 +++++ 28 files changed, 1979 insertions(+), 2223 deletions(-)
Signature · 1 line
2.13.6
PATCH v2 1/16 vdi: Fix vdi_co_do_create() return value
.bdrv_co_create() is supposed to return 0 on success, but vdi could return a positive value instead. Fix this.
--- block/vdi.c | 1 + 1 file changed, 1 insertion(+)
block/vdi.c +1 -0
@@ -865,6 +865,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options, } } + ret =0 ; exit:blk_unref (blk);bdrv_unref (bs_file);
Signature · 1 line
2.13.6
PATCH v2 2/16 vhdx: Fix vhdx_co_create() return value
In reply to Kevin Wolf.bdrv_co_create() is supposed to return 0 on success, but vhdx could return a positive value instead. Fix this.
--- block/vhdx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
block/vhdx.c +1 -1
@@ -1951,7 +1951,7 @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts, goto delete_and_exit; } - + ret =0 ; delete_and_exit:blk_unref (blk);bdrv_unref (bs);
Signature · 1 line
2.13.6
PATCH v2 3/16 job: Add error message for failing jobs
In reply to Kevin WolfSo 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.
--- 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(-)
include/qemu/job.h +6 -1
@@ -124,6 +124,9 @@ 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;
@@ -466,13 +469,15 @@ 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);
block/backup.c +1 -1
@@ -321,7 +321,7 @@ 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); }
block/commit.c +1 -1
@@ -117,7 +117,7 @@ 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
block/mirror.c +1 -1
@@ -581,7 +581,7 @@ 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);
block/stream.c +1 -1
@@ -93,7 +93,7 @@ out: }g_free (s->backing_file_str); -job_completed (job, data->ret); +job_completed (job, data->ret,NULL );g_free (data); }
job-qmp.c +2 -7
@@ -136,14 +136,9 @@ 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),
@@ -151,8 +146,8 @@ 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;
job.c +14 -2
@@ -369,6 +369,7 @@ void job_unref(Job *job)QLIST_REMOVE (job, job_list); +g_free (job->error);g_free (job->id);g_free (job); }
@@ -660,6 +661,9 @@ 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 ); } }
@@ -782,6 +786,7 @@ 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; }
@@ -855,10 +860,17 @@ 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) {
@@ -876,7 +888,7 @@ 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 {
tests/test-bdrv-drain.c +1 -1
@@ -498,7 +498,7 @@ 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)
tests/test-blockjob-txn.c +1 -1
@@ -34,7 +34,7 @@ static void test_block_job_complete(Job *job, void *opaque) rc = -ECANCELED ; } -job_completed (job, rc); +job_completed (job, rc,NULL );bdrv_unref (bs); }
tests/test-blockjob.c +1 -1
@@ -167,7 +167,7 @@ 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)
Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 03/16] job: Add error message for failing jobs
Quoted 169 lines · Kevin Wolf
So far we relied on
job->retandstrerror()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 usestrerror(job->ret).All existing callers are changed to pass NULL. They can be improved in separate patches.
Signed-off-by Kevin Wolf <[email protected]>--- 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(-)include/qemu/job.h +6
-1@@ -124,6 +124,9 @@ 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;@@ -466,13 +469,15 @@ 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);block/backup.c +1
-1@@ -321,7 +321,7 @@ 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); }block/commit.c +1
-1@@ -117,7 +117,7 @@ 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 block/mirror.c +1
-1@@ -581,7 +581,7 @@ 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);block/stream.c +1
-1@@ -93,7 +93,7 @@ out: }g_free (s->backing_file_str); -job_completed (job, data->ret); +job_completed (job, data->ret,NULL );g_free (data); }job-qmp.c +2
-7@@ -136,14 +136,9 @@ 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),@@ -151,8 +146,8 @@ 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;job.c +5
-0@@ -369,6 +369,7 @@ void job_unref(Job *job)QLIST_REMOVE (job, job_list); +g_free (job->error);g_free (job->id);g_free (job); }@@ -660,6 +661,9 @@ 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 ); } }@@ -782,6 +786,7 @@ 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; }
job.c static void job_completed_txn_success(Job *job) · line 865
Quoted 7 lines
job.c +1
-1@@ -855,10 +860,17 @@ 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));
Is it worth it to add '&& job->ret <=0' to the compound assert above? As you said, job->ret being positive is most likely a bug (we treat it like an error return, and abort on it, though). With the patch as-is, we will only catch that when 'error' is set... although, I guess maybe that is by design, since currently nothing sets 'error', we avoid any potential false-positive asserts.
Either way:
Quoted 62 lines
job.c +8
-1+ 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) {@@ -876,7 +888,7 @@ 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 {tests/test-bdrv-drain.c +1
-1@@ -498,7 +498,7 @@ 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)tests/test-blockjob-txn.c +1
-1@@ -34,7 +34,7 @@ static void test_block_job_complete(Job *job, void *opaque) rc = -ECANCELED ; } -job_completed (job, rc); +job_completed (job, rc,NULL );bdrv_unref (bs); }tests/test-blockjob.c +1
-1@@ -167,7 +167,7 @@ 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)Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 03/16] job: Add error message for failing jobs
In reply to Kevin WolfQuoted 12 lines · Kevin Wolf
So far we relied on
job->retandstrerror()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 usestrerror(job->ret).All existing callers are changed to pass NULL. They can be improved in separate patches.
Signed-off-by Kevin Wolf <[email protected]>
Quoted 12 lines
--- 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(-)
PATCH v2 4/16 block/create: Make x-blockdev-create a job
In reply to Kevin WolfThis 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.
--- 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(-)
qapi/block-core.json +9 -5
@@ -4013,14 +4013,18 @@ ## # @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:
qapi/job.json +3 -1
@@ -17,10 +17,12 @@ # # @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:
block/create.c +46 -21
96 lines not on this page · raw message
tests/qemu-iotests/group +8 -6
@@ -204,14 +204,16 @@ 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
Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 04/16] block/create: Make x-blockdev-create a job
Quoted 12 lines · Kevin Wolf
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.
Quoted 2 lines
Signed-off-by Kevin Wolf <[email protected]>Reviewed-by Max Reitz <[email protected]>
Quoted 185 lines
--- 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(-)qapi/block-core.json +9
-5@@ -4013,14 +4013,18 @@ ## # @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:qapi/job.json +3
-1@@ -17,10 +17,12 @@ # # @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:block/create.c +46
-21@@ -24,28 +24,51 @@#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. */ @@ -55,22 +78,24 @@ 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); }tests/qemu-iotests/group +8
-6@@ -204,14 +204,16 @@ 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 quickSignature · 1 line
2.13.6
PATCH v2 5/16 qemu-iotests: Add VM.get_qmp_events_filtered()
In reply to Kevin WolfThis adds a helper function that returns a list of QMP events that are already filtered through filter_qmp_event().
--- tests/qemu-iotests/iotests.py | 5 +++++ 1 file changed, 5 insertions(+)
tests/qemu-iotests/iotests.py +5 -0
@@ -383,6 +383,11 @@ 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'([^\[]+)\[([^\]]+)\]')
Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 05/16] qemu-iotests: Add VM.get_qmp_events_filtered()
Quoted 5 lines · Kevin Wolf
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 <[email protected]>Reviewed-by Max Reitz <[email protected]>
Quoted 23 lines
--- tests/qemu-iotests/iotests.py | 5 +++++ 1 file changed, 5 insertions(+)tests/qemu-iotests/iotests.py +5
-0@@ -383,6 +383,11 @@ 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'([^\[]+)\[([^\]]+)\]')Signature · 1 line
2.13.6
PATCH v2 6/16 qemu-iotests: Add VM.qmp_log()
In reply to Kevin WolfThis adds a helper function that logs both the QMP request and the received response before returning it.
--- tests/qemu-iotests/iotests.py | 11 +++++++++++ 1 file changed, 11 insertions(+)
tests/qemu-iotests/iotests.py +11 -0
@@ -206,6 +206,10 @@ 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)
@@ -389,6 +393,13 @@ 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'([^\[]+)\[([^\]]+)\]')
Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 06/16] qemu-iotests: Add VM.qmp_log()
Quoted 8 lines · Kevin Wolf
This adds a helper function that logs both the QMP request and the received response before returning it.
Signed-off-by Kevin Wolf <[email protected]>Reviewed-by Jeff Cody <[email protected]>--- tests/qemu-iotests/iotests.py | 11 +++++++++++ 1 file changed, 11 insertions(+)
PATCH v2 7/16 qemu-iotests: Add iotests.img_info_log()
In reply to Kevin WolfThis 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.
--- tests/qemu-iotests/iotests.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
tests/qemu-iotests/iotests.py +18 -0
@@ -109,6 +109,12 @@ 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)
@@ -210,6 +216,18 @@ 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)
Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 07/16] qemu-iotests: Add iotests.img_info_log()
Quoted 5 lines · Kevin Wolf
This adds a filter function to postprocess 'qemu-img info' input (similar to what
_img_infodoes), and animg_info_log()function that calls 'qemu-img info' and logs the filtered output.Signed-off-by Kevin Wolf <[email protected]>
Quoted 43 lines
--- tests/qemu-iotests/iotests.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)tests/qemu-iotests/iotests.py +18
-0@@ -109,6 +109,12 @@ 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)@@ -210,6 +216,18 @@ 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)Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 07/16] qemu-iotests: Add iotests.img_info_log()
In reply to Kevin WolfQuoted 8 lines · Kevin Wolf
This adds a filter function to postprocess 'qemu-img info' input (similar to what
_img_infodoes), and animg_info_log()function that calls 'qemu-img info' and logs the filtered output.Signed-off-by Kevin Wolf <[email protected]>--- tests/qemu-iotests/iotests.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
PATCH v2 8/16 qemu-iotests: Add VM.run_job()
In reply to Kevin WolfAdd 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.
--- tests/qemu-iotests/iotests.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
tests/qemu-iotests/iotests.py +19 -0
@@ -418,6 +418,25 @@ 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'([^\[]+)\[([^\]]+)\]')
Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 08/16] qemu-iotests: Add VM.run_job()
Quoted 5 lines · Kevin Wolf
Add an
iotests.pyfunction 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 <[email protected]>
Quoted 37 lines
--- tests/qemu-iotests/iotests.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)tests/qemu-iotests/iotests.py +19
-0@@ -418,6 +418,25 @@ 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'([^\[]+)\[([^\]]+)\]')Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 08/16] qemu-iotests: Add VM.run_job()
In reply to Kevin WolfQuoted 28 lines · Kevin Wolf
Add an
iotests.pyfunction 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 <[email protected]>--- tests/qemu-iotests/iotests.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)tests/qemu-iotests/iotests.py +11
-0@@ -418,6 +418,25 @@ 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:
tests/qemu-iotests/iotests.py class VM(qtest.QEMUQtestMachine): · line 441
Quoted 10 lines
tests/qemu-iotests/iotests.py +8
-0+ 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'([^\[]+)\[([^\]]+)\]')
No, I won't mention that I just realized you could get the job ID from the event and don't actually need it as a parameter.
So without any comments:
PATCH v2 9/16 qemu-iotests: iotests.py helper for non-file protocols
In reply to Kevin WolfThis adds two helper functions that are useful for test cases that make use of a non-file protocol (specifically ssh).
--- tests/qemu-iotests/iotests.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
tests/qemu-iotests/iotests.py +17 -0
@@ -303,6 +303,13 @@ 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'''
@@ -601,6 +608,16 @@ 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)
Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 09/16] qemu-iotests: iotests.py helper for non-file protocols
Quoted 4 lines · Kevin Wolf
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 <[email protected]>
Quoted 42 lines
--- tests/qemu-iotests/iotests.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)tests/qemu-iotests/iotests.py +17
-0@@ -303,6 +303,13 @@ 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'''@@ -601,6 +608,16 @@ 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)Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 09/16] qemu-iotests: iotests.py helper for non-file protocols
In reply to Kevin WolfQuoted 7 lines · Kevin Wolf
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 <[email protected]>--- tests/qemu-iotests/iotests.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
PATCH v2 10/16 qemu-iotests: Rewrite 206 for blockdev-create job
In reply to Kevin WolfThis 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.
--- tests/qemu-iotests/206 | 680 ++++++++++++++++++--------------------------- tests/qemu-iotests/206.out | 253 ++++++++++------- tests/qemu-iotests/group | 2 +- 3 files changed, 414 insertions(+), 521 deletions(-)
tests/qemu-iotests/206 +263 -417
@@ -1,9 +1,11 @@ -#!/bin/bash +#!/usr/bin/env python # # Test qcow2 and file image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <[email protected]> +# # 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
@@ -18,419 +20,263 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator [email protected] - -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()
tests/qemu-iotests/206.out +150 -103
323 lines not on this page · raw message
tests/qemu-iotests/group +1 -1
@@ -204,9 +204,9 @@ 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
Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 10/16] qemu-iotests: Rewrite 206 for blockdev-create job
Quoted 6 lines · Kevin Wolf
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.
Quoted 6 lines
Signed-off-by Kevin Wolf <[email protected]>--- tests/qemu-iotests/206 | 680 ++++++++++++++++++--------------------------- tests/qemu-iotests/206.out | 253 ++++++++++------- tests/qemu-iotests/group | 2 +- 3 files changed, 414 insertions(+), 521 deletions(-)
PATCH v2 11/16 qemu-iotests: Rewrite 207 for blockdev-create job
In reply to Kevin WolfThis 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.
--- tests/qemu-iotests/207 | 440 ++++++++++++++++++++------------------------- tests/qemu-iotests/207.out | 107 +++++------ tests/qemu-iotests/group | 6 +- 3 files changed, 257 insertions(+), 296 deletions(-)
tests/qemu-iotests/207 +198 -242
@@ -1,9 +1,11 @@ -#!/bin/bash +#!/usr/bin/env python # # Test ssh image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <[email protected]> +# # 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
@@ -18,244 +20,198 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator [email protected] - -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()
tests/qemu-iotests/207.out +56 -51
131 lines not on this page · raw message
tests/qemu-iotests/group +3 -3
@@ -205,11 +205,11 @@ 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
Signature · 1 line
2.13.6
Re: [Qemu-devel] [PATCH v2 11/16] qemu-iotests: Rewrite 207 for blockdev-create job
Quoted 8 lines · Kevin Wolf
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.
Quoted 6 lines
Signed-off-by Kevin Wolf <[email protected]>--- tests/qemu-iotests/207 | 440 ++++++++++++++++++++------------------------- tests/qemu-iotests/207.out | 107 +++++------ tests/qemu-iotests/group | 6 +- 3 files changed, 257 insertions(+), 296 deletions(-)
PATCH v2 12/16 qemu-iotests: Rewrite 210 for blockdev-create job
In reply to Kevin WolfThis 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.
--- 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(-)
tests/qemu-iotests/210 +165 -228
@@ -1,9 +1,11 @@ -#!/bin/bash +#!/usr/bin/env python # # Test luks and file image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <[email protected]> +# # 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
@@ -18,230 +20,165 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator [email protected] - -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)
tests/qemu-iotests/210.out +138 -59
254 lines not on this page · raw message
tests/qemu-iotests/group +1 -1
@@ -208,9 +208,9 @@ 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
tests/qemu-iotests/iotests.py +10 -2
@@ -109,8 +109,16 @@ 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))
Signature · 1 line
2.13.6
PATCH v2 13/16 qemu-iotests: Rewrite 211 for blockdev-create job
In reply to Kevin WolfThis 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.
--- tests/qemu-iotests/211 | 381 ++++++++++++++++++--------------------------- tests/qemu-iotests/211.out | 133 +++++++++------- tests/qemu-iotests/group | 2 +- 3 files changed, 229 insertions(+), 287 deletions(-)
tests/qemu-iotests/211 +154 -227
@@ -1,9 +1,11 @@ -#!/bin/bash +#!/usr/bin/env python # # Test VDI and file image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <[email protected]> +# # 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
@@ -18,229 +20,154 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator [email protected] - -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()
tests/qemu-iotests/211.out +74 -59
171 lines not on this page · raw message
tests/qemu-iotests/group +1 -1
@@ -209,9 +209,9 @@ 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
Signature · 1 line
2.13.6
PATCH v2 14/16 qemu-iotests: Rewrite 212 for blockdev-create job
In reply to Kevin WolfThis 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.
--- tests/qemu-iotests/212 | 483 +++++++++++++++++---------------------------- tests/qemu-iotests/212.out | 191 +++++++++++------- tests/qemu-iotests/group | 2 +- 3 files changed, 295 insertions(+), 381 deletions(-)
tests/qemu-iotests/212 +176 -307
@@ -1,9 +1,11 @@ -#!/bin/bash +#!/usr/bin/env python # # Test parallels and file image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <[email protected]> +# # 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
@@ -18,309 +20,176 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator [email protected] - -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()
tests/qemu-iotests/212.out +118 -73
229 lines not on this page · raw message
tests/qemu-iotests/group +1 -1
@@ -210,9 +210,9 @@ 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
Signature · 1 line
2.13.6
PATCH v2 15/16 qemu-iotests: Rewrite 213 for blockdev-create job
In reply to Kevin WolfThis 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.
--- tests/qemu-iotests/213 | 520 +++++++++++++++++---------------------------- tests/qemu-iotests/213.out | 208 +++++++++++------- tests/qemu-iotests/group | 4 +- 3 files changed, 319 insertions(+), 413 deletions(-)
tests/qemu-iotests/213 +190 -330
@@ -1,9 +1,11 @@ -#!/bin/bash +#!/usr/bin/env python # # Test vhdx and file image creation # # Copyright (C) 2018 Red Hat, Inc. # +# Creator/Owner: Kevin Wolf <[email protected]> +# # 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
@@ -18,332 +20,190 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# creator [email protected] - -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()
tests/qemu-iotests/213.out +128 -80
249 lines not on this page · raw message
tests/qemu-iotests/group +1 -3
@@ -211,9 +211,7 @@ 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
Signature · 1 line
2.13.6
PATCH v2 16/16 block/create: Mark blockdev-create stable
In reply to Kevin WolfWe're ready to declare the blockdev-create job stable. This renames the corresponding QMP command from x-blockdev-create to blockdev-create.
--- 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(-)
qapi/block-core.json +2 -2
@@ -4011,7 +4011,7 @@ } } ## -# @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.
@@ -4022,7 +4022,7 @@ # # Since: 3.0 ## -{ 'command': 'x-blockdev-create', +{ 'command': 'blockdev-create', 'data': { 'job-id': 'str', 'options': 'BlockdevCreateOptions' } }
qapi/job.json +1 -1
@@ -17,7 +17,7 @@ # # @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 ##
block/create.c +2 -2
@@ -63,8 +63,8 @@ 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);
tests/qemu-iotests/206 +1 -1
@@ -26,7 +26,7 @@ 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'] == {}
tests/qemu-iotests/206.out +27 -27
194 lines not on this page · raw message
tests/qemu-iotests/207 +1 -1
@@ -31,7 +31,7 @@ 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:
tests/qemu-iotests/207.out +9 -9
@@ -1,6 +1,6 @@ === 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': {}}
@@ -16,7 +16,7 @@ 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': {}}
@@ -25,7 +25,7 @@ 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': {}}
@@ -34,13 +34,13 @@ 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': {}}
@@ -49,13 +49,13 @@ 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': {}}
@@ -66,13 +66,13 @@ 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'}}
tests/qemu-iotests/210 +1 -1
@@ -27,7 +27,7 @@ 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'] == {}
tests/qemu-iotests/210.out +9 -9
@@ -1,13 +1,13 @@ === 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': {}}
@@ -54,12 +54,12 @@ 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': {}}
@@ -106,7 +106,7 @@ 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'}}
@@ -114,7 +114,7 @@ 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': {}}
@@ -161,19 +161,19 @@ 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'}}
tests/qemu-iotests/211 +1 -1
@@ -27,7 +27,7 @@ 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'] == {}
tests/qemu-iotests/211.out +12 -12
@@ -1,13 +1,13 @@ === 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': {}}
@@ -21,12 +21,12 @@ 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': {}}
@@ -40,12 +40,12 @@ 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': {}}
@@ -60,7 +60,7 @@ 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'}}
@@ -68,7 +68,7 @@ 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': {}}
@@ -80,7 +80,7 @@ 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': {}}
@@ -92,19 +92,19 @@ 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'}}
tests/qemu-iotests/212 +1 -1
@@ -27,7 +27,7 @@ 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'] == {}
tests/qemu-iotests/212.out +21 -21
153 lines not on this page · raw message
tests/qemu-iotests/213 +1 -1
@@ -27,7 +27,7 @@ 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'] == {}
tests/qemu-iotests/213.out +22 -22
161 lines not on this page · raw message
Signature · 1 line
2.13.6
Quoted 4 lines · Kevin Wolf
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.
I'm sure modifying the drivers is fodder for a future series, since this series lays the groundwork. But from testing, some image formats (e.g. qcow2) still block the main loop and monitor when doing blockdev-create (preallocation:full, and a larger image size is particularly noticeable).
Quoted 67 lines
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 progress yet (so both current-progress and total-progress stay at 0). These features can be added later without breaking compatibility.
At the end of the series, the interface is declared stable and the x- prefix is removed.
v2:
- Madejob->error== NULL iffjob->ret== 0 [Max]
- Fixed a comment inqmp_blockdev_create()and added a TODO comment for AioContext locking at least [Max]
- Many small changes in the tests [Max, Jeff]Kevin Wolf (16):
vdi: Fixvdi_co_do_create()return value
vhdx: Fixvhdx_co_create()return value
job: Add error message for failing jobs block/create: Make x-blockdev-create a job
qemu-iotests: AddVM.get_qmp_events_filtered()
qemu-iotests: AddVM.qmp_log()
qemu-iotests: Addiotests.img_info_log()
qemu-iotests: AddVM.run_job()
qemu-iotests:iotests.pyhelper 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 stableqapi/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/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 +++++ 28 files changed, 1979 insertions(+), 2223 deletions(-)Signature · 1 line
2.13.6
Quoted 11 lines · Jeff Cody
Quoted 4 lines · Kevin Wolf
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.
I'm sure modifying the drivers is fodder for a future series, since this series lays the groundwork. But from testing, some image formats (e.g. qcow2) still block the main loop and monitor when doing blockdev-create (preallocation:full, and a larger image size is particularly noticeable).
If it helps to reproduce what I'm seeing, here is the QAPI command I am using when testing:
{
"execute": "blockdev-create",
"arguments": {
"job-id": "jobtest1",
"options": {
"driver": "qcow2",
"file": {
"driver": "file",
"filename": "/home/jcody/deleteme.qcow2"
},
"preallocation": "full",
"size": 5120000000
}
}
}Quoted 67 lines
Quoted 67 lines
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 progress yet (so both current-progress and total-progress stay at 0). These features can be added later without breaking compatibility.
At the end of the series, the interface is declared stable and the x- prefix is removed.
v2:
- Madejob->error== NULL iffjob->ret== 0 [Max]
- Fixed a comment inqmp_blockdev_create()and added a TODO comment for AioContext locking at least [Max]
- Many small changes in the tests [Max, Jeff]Kevin Wolf (16):
vdi: Fixvdi_co_do_create()return value
vhdx: Fixvhdx_co_create()return value
job: Add error message for failing jobs block/create: Make x-blockdev-create a job
qemu-iotests: AddVM.get_qmp_events_filtered()
qemu-iotests: AddVM.qmp_log()
qemu-iotests: Addiotests.img_info_log()
qemu-iotests: AddVM.run_job()
qemu-iotests:iotests.pyhelper 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 stableqapi/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/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 +++++ 28 files changed, 1979 insertions(+), 2223 deletions(-)Signature · 1 line
2.13.6
Kevin Wolf
AppliedAm 29.05.2018 um 22:38 hat Kevin Wolf geschrieben:
Quoted 11 lines
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 progress yet (so both current-progress and total-progress stay at 0). These features can be added later without breaking compatibility.
Quoted 2 lines
At the end of the series, the interface is declared stable and the x- prefix is removed.
Applied to the block branch.
Kevin
This series seems to have some coding style problems. See output below for more information:
Hi,
This series seems to have some coding style problems. See output below for more information:
Type: series
Message-id: [email protected]
Subject: [Qemu-devel] [PATCH v2 00/16] block: Make blockdev-create a job and stable API
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
commits="$(git log --format=%H --reverse $BASE..)" for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
t [tag update] patchew/[email protected] -> patchew/[email protected]
* [new tag] patchew/[email protected] -> patchew/[email protected]
Switched to a new branch 'test'122de4416e block/create: Mark blockdev-create stable a083e7beeb qemu-iotests: Rewrite 213 for blockdev-create job c947dfa69d qemu-iotests: Rewrite 212 for blockdev-create job df37241f2a qemu-iotests: Rewrite 211 for blockdev-create job b2775b9daf qemu-iotests: Rewrite 210 for blockdev-create job f60be88204 qemu-iotests: Rewrite 207 for blockdev-create job bafc347497 qemu-iotests: Rewrite 206 for blockdev-create job 868a906170 qemu-iotests: iotests.py helper for non-file protocols 30b2fe3962 qemu-iotests: Add VM.run_job()eee2106258 qemu-iotests: Add iotests.img_info_log() bdd0743777 qemu-iotests: Add VM.qmp_log()f1cc62a518 qemu-iotests: Add VM.get_qmp_events_filtered() f0c0ceee97 block/create: Make x-blockdev-create a job d4d0e41747 job: Add error message for failing jobs 763841f94b vhdx: Fix vhdx_co_create() return value bd60e71ce1 vdi: Fix vdi_co_do_create() return value
=== OUTPUT BEGIN ===
Checking PATCH 1/16: vdi: Fix vdi_co_do_create() return value... Checking PATCH 2/16: vhdx: Fix vhdx_co_create() return value... Checking PATCH 3/16: job: Add error message for failing jobs... Checking PATCH 4/16: block/create: Make x-blockdev-create a job... Checking PATCH 5/16: qemu-iotests: Add VM.get_qmp_events_filtered()... Checking PATCH 6/16: qemu-iotests: Add VM.qmp_log()... Checking PATCH 7/16: qemu-iotests: Add iotests.img_info_log()...
ERROR: line over 90 characters
#42: FILE: tests/qemu-iotests/iotests.py:227:
+ line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
total: 1 errors, 0 warnings, 30 lines checked
Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
Checking PATCH 8/16: qemu-iotests: Add VM.run_job()...
Checking PATCH 9/16: qemu-iotests: iotests.py helper for non-file protocols... Checking PATCH 10/16: qemu-iotests: Rewrite 206 for blockdev-create job... Checking PATCH 11/16: qemu-iotests: Rewrite 207 for blockdev-create job... Checking PATCH 12/16: qemu-iotests: Rewrite 210 for blockdev-create job... Checking PATCH 13/16: qemu-iotests: Rewrite 211 for blockdev-create job... Checking PATCH 14/16: qemu-iotests: Rewrite 212 for blockdev-create job... Checking PATCH 15/16: qemu-iotests: Rewrite 213 for blockdev-create job... Checking PATCH 16/16: block/create: Mark blockdev-create stable... === OUTPUT END ===
Test command exited with code: 1
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to [email protected]