qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top
@ 2013-12-16  6:45 Fam Zheng
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 1/7] blkdebug: Use QLIST_FOREACH_SAFE to resume IO Fam Zheng
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Fam Zheng @ 2013-12-16  6:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, pbonzini, jcody, stefanha

Previously live commit of active block device is not supported, this series
implements it and updates corresponding qemu-iotests cases.

This series is based on BlockJobType enum QAPI series.

v7: Fix "Since 1.8" to "Since 2.0".
    Rebase patch 05 to master.

v6: Address comments from Stefan:

    [04/06] commit: support commit active layer
            Fix wording.
    [05/06] qemu-iotests: update test cases for commit active
            Drop is_active.

    Experimental for reviewers: the side by side diff against previous series:

        http://goo.gl/vgN6mc

v5: Address comments from Eric and Paolo:
    Add mirror_start_job and front end wrapper. [Paolo]
    Base on BlockJobType enum in QAPI. [Eric]
    Drop "common" sync mode. [Eric]

v4: Rewrite to reuse block/mirror.c.
    When committing the active layer, the job is internally a mirror job with
    type name faked to "commit".
    When the job completes, the BDSes are swapped, so the base image become
    active and [top, base) dropped.


Fam Zheng (7):
  blkdebug: Use QLIST_FOREACH_SAFE to resume IO
  mirror: Don't close target
  mirror: Move base to MirrorBlockJob
  block: Add commit_active_start()
  commit: Support commit active layer
  qemu-iotests: Update test cases for commit active
  commit: Remove unused check

 block/blkdebug.c          |  8 ++---
 block/commit.c            |  8 +----
 block/mirror.c            | 78 +++++++++++++++++++++++++++++++++++++++--------
 blockdev.c                |  9 ++++--
 include/block/block_int.h | 22 +++++++++++--
 qapi-schema.json          |  5 +--
 tests/qemu-iotests/040    | 74 +++++++++++++++++++-------------------------
 7 files changed, 131 insertions(+), 73 deletions(-)

-- 
1.8.5.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v7 1/7] blkdebug: Use QLIST_FOREACH_SAFE to resume IO
  2013-12-16  6:45 [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Fam Zheng
@ 2013-12-16  6:45 ` Fam Zheng
  2013-12-16  6:49   ` Fam Zheng
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 2/7] mirror: Don't close target Fam Zheng
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 10+ messages in thread
From: Fam Zheng @ 2013-12-16  6:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, pbonzini, jcody, stefanha

Qemu-iotest 030 was broken.

When the coroutine runs and finishes, it will remove itself from the req
list, so let's use safe version of foreach to avoid use after free.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 block/blkdebug.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/block/blkdebug.c b/block/blkdebug.c
index 37cf028..957be2c 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -594,9 +594,9 @@ static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event,
 static int blkdebug_debug_resume(BlockDriverState *bs, const char *tag)
 {
     BDRVBlkdebugState *s = bs->opaque;
-    BlkdebugSuspendedReq *r;
+    BlkdebugSuspendedReq *r, *next;
 
-    QLIST_FOREACH(r, &s->suspended_reqs, next) {
+    QLIST_FOREACH_SAFE(r, &s->suspended_reqs, next, next) {
         if (!strcmp(r->tag, tag)) {
             qemu_coroutine_enter(r->co, NULL);
             return 0;
@@ -609,7 +609,7 @@ static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs,
                                             const char *tag)
 {
     BDRVBlkdebugState *s = bs->opaque;
-    BlkdebugSuspendedReq *r;
+    BlkdebugSuspendedReq *r, *r_next;
     BlkdebugRule *rule, *next;
     int i, ret = -ENOENT;
 
@@ -622,7 +622,7 @@ static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs,
             }
         }
     }
-    QLIST_FOREACH(r, &s->suspended_reqs, next) {
+    QLIST_FOREACH_SAFE(r, &s->suspended_reqs, next, r_next) {
         if (!strcmp(r->tag, tag)) {
             qemu_coroutine_enter(r->co, NULL);
             ret = 0;
-- 
1.8.5.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v7 2/7] mirror: Don't close target
  2013-12-16  6:45 [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Fam Zheng
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 1/7] blkdebug: Use QLIST_FOREACH_SAFE to resume IO Fam Zheng
@ 2013-12-16  6:45 ` Fam Zheng
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 3/7] mirror: Move base to MirrorBlockJob Fam Zheng
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2013-12-16  6:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, pbonzini, jcody, stefanha

Let reference count manage target and don't call bdrv_close here.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
---
 block/mirror.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/block/mirror.c b/block/mirror.c
index 6dc27ad..5b2c119 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -482,7 +482,6 @@ immediate_exit:
         }
         bdrv_swap(s->target, s->common.bs);
     }
-    bdrv_close(s->target);
     bdrv_unref(s->target);
     block_job_completed(&s->common, ret);
 }
-- 
1.8.5.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v7 3/7] mirror: Move base to MirrorBlockJob
  2013-12-16  6:45 [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Fam Zheng
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 1/7] blkdebug: Use QLIST_FOREACH_SAFE to resume IO Fam Zheng
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 2/7] mirror: Don't close target Fam Zheng
@ 2013-12-16  6:45 ` Fam Zheng
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 4/7] block: Add commit_active_start() Fam Zheng
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2013-12-16  6:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, pbonzini, jcody, stefanha

This allows setting the base before entering mirror_run, commit will
make use of it.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
---
 block/mirror.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index 5b2c119..605dda6 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -31,6 +31,7 @@ typedef struct MirrorBlockJob {
     BlockJob common;
     RateLimit limit;
     BlockDriverState *target;
+    BlockDriverState *base;
     MirrorSyncMode mode;
     BlockdevOnError on_source_error, on_target_error;
     bool synced;
@@ -337,8 +338,7 @@ static void coroutine_fn mirror_run(void *opaque)
 
     if (s->mode != MIRROR_SYNC_MODE_NONE) {
         /* First part, loop on the sectors and initialize the dirty bitmap.  */
-        BlockDriverState *base;
-        base = s->mode == MIRROR_SYNC_MODE_FULL ? NULL : bs->backing_hd;
+        BlockDriverState *base = s->base;
         for (sector_num = 0; sector_num < end; ) {
             int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1;
             ret = bdrv_is_allocated_above(bs, base,
@@ -543,6 +543,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
                   void *opaque, Error **errp)
 {
     MirrorBlockJob *s;
+    BlockDriverState *base = NULL;
 
     if (granularity == 0) {
         /* Choose the default granularity based on the target file's cluster
@@ -565,6 +566,12 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
         return;
     }
 
+    if (mode == MIRROR_SYNC_MODE_TOP) {
+        base = bs->backing_hd;
+    } else {
+        base = NULL;
+    }
+
     s = block_job_create(&mirror_job_driver, bs, speed, cb, opaque, errp);
     if (!s) {
         return;
@@ -574,6 +581,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
     s->on_target_error = on_target_error;
     s->target = target;
     s->mode = mode;
+    s->base = base;
     s->granularity = granularity;
     s->buf_size = MAX(buf_size, granularity);
 
-- 
1.8.5.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v7 4/7] block: Add commit_active_start()
  2013-12-16  6:45 [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Fam Zheng
                   ` (2 preceding siblings ...)
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 3/7] mirror: Move base to MirrorBlockJob Fam Zheng
@ 2013-12-16  6:45 ` Fam Zheng
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 5/7] commit: Support commit active layer Fam Zheng
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2013-12-16  6:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, pbonzini, jcody, stefanha

commit_active_start is implemented in block/mirror.c, It will create a
job with "commit" type and designated base in block-commit command. This
will be used for committing active layer of device.

Sync mode is removed from MirrorBlockJob because there's no proper type
for commit. The used information is is_none_mode.

The common part of mirror_start and commit_active_start is moved to
mirror_start_job().

Fix the comment wording for commit_start.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
---
 block/mirror.c            | 66 +++++++++++++++++++++++++++++++++++------------
 include/block/block_int.h | 22 +++++++++++++---
 2 files changed, 69 insertions(+), 19 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index 605dda6..04af341 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -32,7 +32,7 @@ typedef struct MirrorBlockJob {
     RateLimit limit;
     BlockDriverState *target;
     BlockDriverState *base;
-    MirrorSyncMode mode;
+    bool is_none_mode;
     BlockdevOnError on_source_error, on_target_error;
     bool synced;
     bool should_complete;
@@ -336,7 +336,7 @@ static void coroutine_fn mirror_run(void *opaque)
     sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
     mirror_free_init(s);
 
-    if (s->mode != MIRROR_SYNC_MODE_NONE) {
+    if (!s->is_none_mode) {
         /* First part, loop on the sectors and initialize the dirty bitmap.  */
         BlockDriverState *base = s->base;
         for (sector_num = 0; sector_num < end; ) {
@@ -535,15 +535,26 @@ static const BlockJobDriver mirror_job_driver = {
     .complete      = mirror_complete,
 };
 
-void mirror_start(BlockDriverState *bs, BlockDriverState *target,
-                  int64_t speed, int64_t granularity, int64_t buf_size,
-                  MirrorSyncMode mode, BlockdevOnError on_source_error,
-                  BlockdevOnError on_target_error,
-                  BlockDriverCompletionFunc *cb,
-                  void *opaque, Error **errp)
+static const BlockJobDriver commit_active_job_driver = {
+    .instance_size = sizeof(MirrorBlockJob),
+    .job_type      = BLOCK_JOB_TYPE_COMMIT,
+    .set_speed     = mirror_set_speed,
+    .iostatus_reset
+                   = mirror_iostatus_reset,
+    .complete      = mirror_complete,
+};
+
+static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
+                            int64_t speed, int64_t granularity,
+                            int64_t buf_size,
+                            BlockdevOnError on_source_error,
+                            BlockdevOnError on_target_error,
+                            BlockDriverCompletionFunc *cb,
+                            void *opaque, Error **errp,
+                            const BlockJobDriver *driver,
+                            bool is_none_mode, BlockDriverState *base)
 {
     MirrorBlockJob *s;
-    BlockDriverState *base = NULL;
 
     if (granularity == 0) {
         /* Choose the default granularity based on the target file's cluster
@@ -566,13 +577,8 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
         return;
     }
 
-    if (mode == MIRROR_SYNC_MODE_TOP) {
-        base = bs->backing_hd;
-    } else {
-        base = NULL;
-    }
 
-    s = block_job_create(&mirror_job_driver, bs, speed, cb, opaque, errp);
+    s = block_job_create(driver, bs, speed, cb, opaque, errp);
     if (!s) {
         return;
     }
@@ -580,7 +586,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
     s->on_source_error = on_source_error;
     s->on_target_error = on_target_error;
     s->target = target;
-    s->mode = mode;
+    s->is_none_mode = is_none_mode;
     s->base = base;
     s->granularity = granularity;
     s->buf_size = MAX(buf_size, granularity);
@@ -593,3 +599,31 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
     trace_mirror_start(bs, s, s->common.co, opaque);
     qemu_coroutine_enter(s->common.co, s);
 }
+
+void mirror_start(BlockDriverState *bs, BlockDriverState *target,
+                  int64_t speed, int64_t granularity, int64_t buf_size,
+                  MirrorSyncMode mode, BlockdevOnError on_source_error,
+                  BlockdevOnError on_target_error,
+                  BlockDriverCompletionFunc *cb,
+                  void *opaque, Error **errp)
+{
+    bool is_none_mode;
+    BlockDriverState *base;
+
+    is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
+    base = mode == MIRROR_SYNC_MODE_TOP ? bs->backing_hd : NULL;
+    mirror_start_job(bs, target, speed, granularity, buf_size,
+                     on_source_error, on_target_error, cb, opaque, errp,
+                     &mirror_job_driver, is_none_mode, base);
+}
+
+void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
+                         int64_t speed,
+                         BlockdevOnError on_error,
+                         BlockDriverCompletionFunc *cb,
+                         void *opaque, Error **errp)
+{
+    mirror_start_job(bs, base, speed, 0, 0,
+                     on_error, on_error, cb, opaque, errp,
+                     &commit_active_job_driver, false, base);
+}
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 8b132d7..2772f2f 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -394,8 +394,9 @@ void stream_start(BlockDriverState *bs, BlockDriverState *base,
 
 /**
  * commit_start:
- * @bs: Top Block device
- * @base: Block device that will be written into, and become the new top
+ * @bs: Active block device.
+ * @top: Top block device to be committed.
+ * @base: Block device that will be written into, and become the new top.
  * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
  * @on_error: The action to take upon error.
  * @cb: Completion function for the job.
@@ -407,7 +408,22 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,
                  BlockDriverState *top, int64_t speed,
                  BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
                  void *opaque, Error **errp);
-
+/**
+ * commit_active_start:
+ * @bs: Active block device to be committed.
+ * @base: Block device that will be written into, and become the new top.
+ * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
+ * @on_error: The action to take upon error.
+ * @cb: Completion function for the job.
+ * @opaque: Opaque pointer value passed to @cb.
+ * @errp: Error object.
+ *
+ */
+void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
+                         int64_t speed,
+                         BlockdevOnError on_error,
+                         BlockDriverCompletionFunc *cb,
+                         void *opaque, Error **errp);
 /*
  * mirror_start:
  * @bs: Block device to operate on.
-- 
1.8.5.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v7 5/7] commit: Support commit active layer
  2013-12-16  6:45 [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Fam Zheng
                   ` (3 preceding siblings ...)
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 4/7] block: Add commit_active_start() Fam Zheng
@ 2013-12-16  6:45 ` Fam Zheng
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 6/7] qemu-iotests: Update test cases for commit active Fam Zheng
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2013-12-16  6:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, pbonzini, jcody, stefanha

If active is top, it will be mirrored to base, (with block/mirror.c
code), then the image is switched when user completes the block job.

QMP documentation is updated.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 block/mirror.c   | 11 +++++++++++
 blockdev.c       |  9 +++++++--
 qapi-schema.json |  5 +++--
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index 04af341..2932bab 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -481,6 +481,13 @@ immediate_exit:
             bdrv_reopen(s->target, bdrv_get_flags(s->common.bs), NULL);
         }
         bdrv_swap(s->target, s->common.bs);
+        if (s->common.driver->job_type == BLOCK_JOB_TYPE_COMMIT) {
+            /* drop the bs loop chain formed by the swap: break the loop then
+             * trigger the unref from the top one */
+            BlockDriverState *p = s->base->backing_hd;
+            s->base->backing_hd = NULL;
+            bdrv_unref(p);
+        }
     }
     bdrv_unref(s->target);
     block_job_completed(&s->common, ret);
@@ -623,6 +630,10 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
                          BlockDriverCompletionFunc *cb,
                          void *opaque, Error **errp)
 {
+    if (bdrv_reopen(base, bs->open_flags, errp)) {
+        return;
+    }
+    bdrv_ref(base);
     mirror_start_job(bs, base, speed, 0, 0,
                      on_error, on_error, cb, opaque, errp,
                      &commit_active_job_driver, false, base);
diff --git a/blockdev.c b/blockdev.c
index 44755e1..db8c86e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1820,8 +1820,13 @@ void qmp_block_commit(const char *device,
         return;
     }
 
-    commit_start(bs, base_bs, top_bs, speed, on_error, block_job_cb, bs,
-                &local_err);
+    if (top_bs == bs) {
+        commit_active_start(bs, base_bs, speed, on_error, block_job_cb,
+                            bs, &local_err);
+    } else {
+        commit_start(bs, base_bs, top_bs, speed, on_error, block_job_cb, bs,
+                    &local_err);
+    }
     if (local_err != NULL) {
         error_propagate(errp, local_err);
         return;
diff --git a/qapi-schema.json b/qapi-schema.json
index d6f8615..4342abc 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1967,9 +1967,11 @@
 #
 # @top:              The file name of the backing image within the image chain,
 #                    which contains the topmost data to be committed down.
-#                    Note, the active layer as 'top' is currently unsupported.
 #
 #                    If top == base, that is an error.
+#                    If top == active, the job will not be completed by itself,
+#                    user needs to complete the job with the block-job-complete
+#                    command after getting the ready event. (Since 2.0)
 #
 #
 # @speed:  #optional the maximum speed, in bytes per second
@@ -1979,7 +1981,6 @@
 #          If @device does not exist, DeviceNotFound
 #          If image commit is not supported by this device, NotSupported
 #          If @base or @top is invalid, a generic error is returned
-#          If @top is the active layer, or omitted, a generic error is returned
 #          If @speed is invalid, InvalidParameter
 #
 # Since: 1.3
-- 
1.8.5.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v7 6/7] qemu-iotests: Update test cases for commit active
  2013-12-16  6:45 [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Fam Zheng
                   ` (4 preceding siblings ...)
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 5/7] commit: Support commit active layer Fam Zheng
@ 2013-12-16  6:45 ` Fam Zheng
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 7/7] commit: Remove unused check Fam Zheng
  2013-12-20 15:40 ` [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Stefan Hajnoczi
  7 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2013-12-16  6:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, pbonzini, jcody, stefanha

Factor out commit test common logic into super class, and update test
of committing the active image.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 tests/qemu-iotests/040 | 74 ++++++++++++++++++++++----------------------------
 1 file changed, 32 insertions(+), 42 deletions(-)

diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
index 18dcd61..72eaad5 100755
--- a/tests/qemu-iotests/040
+++ b/tests/qemu-iotests/040
@@ -39,6 +39,29 @@ class ImageCommitTestCase(iotests.QMPTestCase):
         result = self.vm.qmp('query-block-jobs')
         self.assert_qmp(result, 'return', [])
 
+    def run_commit_test(self, top, base):
+        self.assert_no_active_commit()
+        result = self.vm.qmp('block-commit', device='drive0', top=top, base=base)
+        self.assert_qmp(result, 'return', {})
+
+        completed = False
+        while not completed:
+            for event in self.vm.get_qmp_events(wait=True):
+                if event['event'] == 'BLOCK_JOB_COMPLETED':
+                    self.assert_qmp(event, 'data/type', 'commit')
+                    self.assert_qmp(event, 'data/device', 'drive0')
+                    self.assert_qmp(event, 'data/offset', self.image_len)
+                    self.assert_qmp(event, 'data/len', self.image_len)
+                    completed = True
+                elif event['event'] == 'BLOCK_JOB_READY':
+                    self.assert_qmp(event, 'data/type', 'commit')
+                    self.assert_qmp(event, 'data/device', 'drive0')
+                    self.assert_qmp(event, 'data/len', self.image_len)
+                    self.vm.qmp('block-job-complete', device='drive0')
+
+        self.assert_no_active_commit()
+        self.vm.shutdown()
+
 class TestSingleDrive(ImageCommitTestCase):
     image_len = 1 * 1024 * 1024
     test_len = 1 * 1024 * 256
@@ -59,23 +82,7 @@ class TestSingleDrive(ImageCommitTestCase):
         os.remove(backing_img)
 
     def test_commit(self):
-        self.assert_no_active_commit()
-        result = self.vm.qmp('block-commit', device='drive0', top='%s' % mid_img)
-        self.assert_qmp(result, 'return', {})
-
-        completed = False
-        while not completed:
-            for event in self.vm.get_qmp_events(wait=True):
-                if event['event'] == 'BLOCK_JOB_COMPLETED':
-                    self.assert_qmp(event, 'data/type', 'commit')
-                    self.assert_qmp(event, 'data/device', 'drive0')
-                    self.assert_qmp(event, 'data/offset', self.image_len)
-                    self.assert_qmp(event, 'data/len', self.image_len)
-                    completed = True
-
-        self.assert_no_active_commit()
-        self.vm.shutdown()
-
+        self.run_commit_test(mid_img, backing_img)
         self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
         self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
 
@@ -102,10 +109,9 @@ class TestSingleDrive(ImageCommitTestCase):
         self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found')
 
     def test_top_is_active(self):
-        self.assert_no_active_commit()
-        result = self.vm.qmp('block-commit', device='drive0', top='%s' % test_img, base='%s' % backing_img)
-        self.assert_qmp(result, 'error/class', 'GenericError')
-        self.assert_qmp(result, 'error/desc', 'Top image as the active layer is currently unsupported')
+        self.run_commit_test(test_img, backing_img)
+        self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
+        self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
 
     def test_top_and_base_reversed(self):
         self.assert_no_active_commit()
@@ -166,23 +172,7 @@ class TestRelativePaths(ImageCommitTestCase):
                 raise
 
     def test_commit(self):
-        self.assert_no_active_commit()
-        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.mid_img)
-        self.assert_qmp(result, 'return', {})
-
-        completed = False
-        while not completed:
-            for event in self.vm.get_qmp_events(wait=True):
-                if event['event'] == 'BLOCK_JOB_COMPLETED':
-                    self.assert_qmp(event, 'data/type', 'commit')
-                    self.assert_qmp(event, 'data/device', 'drive0')
-                    self.assert_qmp(event, 'data/offset', self.image_len)
-                    self.assert_qmp(event, 'data/len', self.image_len)
-                    completed = True
-
-        self.assert_no_active_commit()
-        self.vm.shutdown()
-
+        self.run_commit_test(self.mid_img, self.backing_img)
         self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
         self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
 
@@ -209,10 +199,9 @@ class TestRelativePaths(ImageCommitTestCase):
         self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found')
 
     def test_top_is_active(self):
-        self.assert_no_active_commit()
-        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.test_img, base='%s' % self.backing_img)
-        self.assert_qmp(result, 'error/class', 'GenericError')
-        self.assert_qmp(result, 'error/desc', 'Top image as the active layer is currently unsupported')
+        self.run_commit_test(self.test_img, self.backing_img)
+        self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
+        self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
 
     def test_top_and_base_reversed(self):
         self.assert_no_active_commit()
@@ -229,6 +218,7 @@ class TestSetSpeed(ImageCommitTestCase):
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
         qemu_io('-c', 'write -P 0x1 0 512', test_img)
+        qemu_io('-c', 'write -P 0xef 524288 524288', mid_img)
         self.vm = iotests.VM().add_drive(test_img)
         self.vm.launch()
 
-- 
1.8.5.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v7 7/7] commit: Remove unused check
  2013-12-16  6:45 [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Fam Zheng
                   ` (5 preceding siblings ...)
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 6/7] qemu-iotests: Update test cases for commit active Fam Zheng
@ 2013-12-16  6:45 ` Fam Zheng
  2013-12-20 15:40 ` [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Stefan Hajnoczi
  7 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2013-12-16  6:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, pbonzini, jcody, stefanha

We support top == active for commit now, remove the check and add an
assertion here.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
---
 block/commit.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/block/commit.c b/block/commit.c
index d4090cb..acec4ac 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -198,13 +198,7 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,
         return;
     }
 
-    /* Once we support top == active layer, remove this check */
-    if (top == bs) {
-        error_setg(errp,
-                   "Top image as the active layer is currently unsupported");
-        return;
-    }
-
+    assert(top != bs);
     if (top == base) {
         error_setg(errp, "Invalid files for merge: top and base are the same");
         return;
-- 
1.8.5.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v7 1/7] blkdebug: Use QLIST_FOREACH_SAFE to resume IO
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 1/7] blkdebug: Use QLIST_FOREACH_SAFE to resume IO Fam Zheng
@ 2013-12-16  6:49   ` Fam Zheng
  0 siblings, 0 replies; 10+ messages in thread
From: Fam Zheng @ 2013-12-16  6:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, pbonzini, jcody, stefanha

On 2013年12月16日 14:45, Fam Zheng wrote:
> Qemu-iotest 030 was broken.
>
> When the coroutine runs and finishes, it will remove itself from the req
> list, so let's use safe version of foreach to avoid use after free.
>
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---

This one is already applied to Kevin's tree, please skip it.

Fam

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top
  2013-12-16  6:45 [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Fam Zheng
                   ` (6 preceding siblings ...)
  2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 7/7] commit: Remove unused check Fam Zheng
@ 2013-12-20 15:40 ` Stefan Hajnoczi
  7 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2013-12-20 15:40 UTC (permalink / raw)
  To: Fam Zheng; +Cc: kwolf, pbonzini, jcody, qemu-devel, stefanha

On Mon, Dec 16, 2013 at 02:45:26PM +0800, Fam Zheng wrote:
> Previously live commit of active block device is not supported, this series
> implements it and updates corresponding qemu-iotests cases.
> 
> This series is based on BlockJobType enum QAPI series.
> 
> v7: Fix "Since 1.8" to "Since 2.0".
>     Rebase patch 05 to master.
> 
> v6: Address comments from Stefan:
> 
>     [04/06] commit: support commit active layer
>             Fix wording.
>     [05/06] qemu-iotests: update test cases for commit active
>             Drop is_active.
> 
>     Experimental for reviewers: the side by side diff against previous series:
> 
>         http://goo.gl/vgN6mc
> 
> v5: Address comments from Eric and Paolo:
>     Add mirror_start_job and front end wrapper. [Paolo]
>     Base on BlockJobType enum in QAPI. [Eric]
>     Drop "common" sync mode. [Eric]
> 
> v4: Rewrite to reuse block/mirror.c.
>     When committing the active layer, the job is internally a mirror job with
>     type name faked to "commit".
>     When the job completes, the BDSes are swapped, so the base image become
>     active and [top, base) dropped.
> 
> 
> Fam Zheng (7):
>   blkdebug: Use QLIST_FOREACH_SAFE to resume IO
>   mirror: Don't close target
>   mirror: Move base to MirrorBlockJob
>   block: Add commit_active_start()
>   commit: Support commit active layer
>   qemu-iotests: Update test cases for commit active
>   commit: Remove unused check
> 
>  block/blkdebug.c          |  8 ++---
>  block/commit.c            |  8 +----
>  block/mirror.c            | 78 +++++++++++++++++++++++++++++++++++++++--------
>  blockdev.c                |  9 ++++--
>  include/block/block_int.h | 22 +++++++++++--
>  qapi-schema.json          |  5 +--
>  tests/qemu-iotests/040    | 74 +++++++++++++++++++-------------------------
>  7 files changed, 131 insertions(+), 73 deletions(-)
> 
> -- 
> 1.8.5.1
> 
> 

Thanks, applied to my block tree:
https://github.com/stefanha/qemu/commits/block

Stefan

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-12-20 15:41 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-16  6:45 [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Fam Zheng
2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 1/7] blkdebug: Use QLIST_FOREACH_SAFE to resume IO Fam Zheng
2013-12-16  6:49   ` Fam Zheng
2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 2/7] mirror: Don't close target Fam Zheng
2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 3/7] mirror: Move base to MirrorBlockJob Fam Zheng
2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 4/7] block: Add commit_active_start() Fam Zheng
2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 5/7] commit: Support commit active layer Fam Zheng
2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 6/7] qemu-iotests: Update test cases for commit active Fam Zheng
2013-12-16  6:45 ` [Qemu-devel] [PATCH v7 7/7] commit: Remove unused check Fam Zheng
2013-12-20 15:40 ` [Qemu-devel] [PATCH v7 0/7] block: allow commit active as top Stefan Hajnoczi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).