Changeset
block/block-backend.c      |   2 +-
migration/block.c          |  22 +++++++--
migration/migration.c      |  12 +++--
tests/qemu-iotests/183     | 121 +++++++++++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/183.out |  48 ++++++++++++++++++
tests/qemu-iotests/group   |   1 +
6 files changed, 195 insertions(+), 11 deletions(-)
create mode 100755 tests/qemu-iotests/183
create mode 100644 tests/qemu-iotests/183.out
Git apply log
Switched to a new branch '1495548064-10926-1-git-send-email-kwolf@redhat.com'
Applying: block: Fix anonymous BBs in blk_root_inactivate()
Applying: migration: Inactivate images after .save_live_complete_precopy()
Applying: migration/block: Clean up BBs in block_save_complete()
Applying: qemu-iotests: Block migration test
To https://github.com/patchew-project/qemu
 + 0099d05...dfdc728 patchew/1495548064-10926-1-git-send-email-kwolf@redhat.com -> patchew/1495548064-10926-1-git-send-email-kwolf@redhat.com (forced update)
Test passed: s390x

loading

Test passed: docker

loading

Test passed: checkpatch

loading

[Qemu-devel] [PATCH 0/4] Block migration (migrate -b) fixes
Posted by Kevin Wolf, 47 weeks ago
Kevin Wolf (4):
  block: Fix anonymous BBs in blk_root_inactivate()
  migration: Inactivate images after .save_live_complete_precopy()
  migration/block: Clean up BBs in block_save_complete()
  qemu-iotests: Block migration test

 block/block-backend.c      |   2 +-
 migration/block.c          |  22 +++++++--
 migration/migration.c      |  12 +++--
 tests/qemu-iotests/183     | 121 +++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/183.out |  48 ++++++++++++++++++
 tests/qemu-iotests/group   |   1 +
 6 files changed, 195 insertions(+), 11 deletions(-)
 create mode 100755 tests/qemu-iotests/183
 create mode 100644 tests/qemu-iotests/183.out

-- 
1.8.3.1


Re: [Qemu-devel] [PATCH 0/4] Block migration (migrate -b) fixes
Posted by Fam Zheng, 47 weeks ago
On Tue, 05/23 16:01, Kevin Wolf wrote:
> Kevin Wolf (4):
>   block: Fix anonymous BBs in blk_root_inactivate()
>   migration: Inactivate images after .save_live_complete_precopy()
>   migration/block: Clean up BBs in block_save_complete()
>   qemu-iotests: Block migration test

Reviewed-by: Fam Zheng <famz@redhat.com>

[Qemu-devel] [PATCH 1/4] block: Fix anonymous BBs in blk_root_inactivate()
Posted by Kevin Wolf, 47 weeks ago
blk->name isn't an array, but a pointer that can be NULL. Checking for
an anonymous BB must involve a NULL check first, otherwise we get
crashes.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/block-backend.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index f3a6008..7d7f369 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -168,7 +168,7 @@ static int blk_root_inactivate(BdrvChild *child)
      * this point because the VM is stopped) and unattached monitor-owned
      * BlockBackends. If there is still any other user like a block job, then
      * we simply can't inactivate the image. */
-    if (!blk->dev && !blk->name[0]) {
+    if (!blk->dev && !blk_name(blk)[0]) {
         return -EPERM;
     }
 
-- 
1.8.3.1


Re: [Qemu-devel] [PATCH 1/4] block: Fix anonymous BBs in blk_root_inactivate()
Posted by Eric Blake, 47 weeks ago
On 05/23/2017 09:01 AM, Kevin Wolf wrote:
> blk->name isn't an array, but a pointer that can be NULL. Checking for
> an anonymous BB must involve a NULL check first, otherwise we get
> crashes.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  block/block-backend.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

[Qemu-devel] [PATCH 2/4] migration: Inactivate images after .save_live_complete_precopy()
Posted by Kevin Wolf, 47 weeks ago
Block migration may still access the image during its
.save_live_complete_precopy() implementation, so we should only
inactivate the image afterwards.

Another reason for the change is that inactivating an image fails when
there is still a non-device BlockBackend using it, which includes the
BBs used by block migration. We want to give block migration a chance to
release the BBs before trying to inactivate the image (this will be done
in another patch).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 migration/migration.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 0304c01..846ba09 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1787,17 +1787,19 @@ static void migration_completion(MigrationState *s, int current_active_state,
 
         if (!ret) {
             ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
+            if (ret >= 0) {
+                qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX);
+                qemu_savevm_state_complete_precopy(s->to_dst_file, false);
+            }
             /*
              * Don't mark the image with BDRV_O_INACTIVE flag if
              * we will go into COLO stage later.
              */
             if (ret >= 0 && !migrate_colo_enabled()) {
                 ret = bdrv_inactivate_all();
-            }
-            if (ret >= 0) {
-                qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX);
-                qemu_savevm_state_complete_precopy(s->to_dst_file, false);
-                s->block_inactive = true;
+                if (ret >= 0) {
+                    s->block_inactive = true;
+                }
             }
         }
         qemu_mutex_unlock_iothread();
-- 
1.8.3.1


Re: [Qemu-devel] [PATCH 2/4] migration: Inactivate images after .save_live_complete_precopy()
Posted by Eric Blake, 47 weeks ago
On 05/23/2017 09:01 AM, Kevin Wolf wrote:
> Block migration may still access the image during its
> .save_live_complete_precopy() implementation, so we should only
> inactivate the image afterwards.
> 
> Another reason for the change is that inactivating an image fails when
> there is still a non-device BlockBackend using it, which includes the
> BBs used by block migration. We want to give block migration a chance to
> release the BBs before trying to inactivate the image (this will be done
> in another patch).
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  migration/migration.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

[Qemu-devel] [PATCH 3/4] migration/block: Clean up BBs in block_save_complete()
Posted by Kevin Wolf, 47 weeks ago
We need to release any block migrations BlockBackends on the source
before successfully completing the migration because otherwise
inactivating the images will fail (inactivation only tolerates device
BBs).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 migration/block.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/migration/block.c b/migration/block.c
index 060087f..d3aaeaf 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -674,16 +674,14 @@ static int64_t get_remaining_dirty(void)
     return dirty << BDRV_SECTOR_BITS;
 }
 
-/* Called with iothread lock taken.  */
 
-static void block_migration_cleanup(void *opaque)
+
+/* Called with iothread lock taken.  */
+static void block_migration_cleanup_bmds(void)
 {
     BlkMigDevState *bmds;
-    BlkMigBlock *blk;
     AioContext *ctx;
 
-    bdrv_drain_all();
-
     unset_dirty_tracking();
 
     while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) {
@@ -701,6 +699,16 @@ static void block_migration_cleanup(void *opaque)
         g_free(bmds->aio_bitmap);
         g_free(bmds);
     }
+}
+
+/* Called with iothread lock taken.  */
+static void block_migration_cleanup(void *opaque)
+{
+    BlkMigBlock *blk;
+
+    bdrv_drain_all();
+
+    block_migration_cleanup_bmds();
 
     blk_mig_lock();
     while ((blk = QSIMPLEQ_FIRST(&block_mig_state.blk_list)) != NULL) {
@@ -844,6 +852,10 @@ static int block_save_complete(QEMUFile *f, void *opaque)
 
     qemu_put_be64(f, BLK_MIG_FLAG_EOS);
 
+    /* Make sure that our BlockBackends are gone, so that the block driver
+     * nodes can be inactivated. */
+    block_migration_cleanup_bmds();
+
     return 0;
 }
 
-- 
1.8.3.1


Re: [Qemu-devel] [PATCH 3/4] migration/block: Clean up BBs in block_save_complete()
Posted by Eric Blake, 47 weeks ago
On 05/23/2017 09:01 AM, Kevin Wolf wrote:
> We need to release any block migrations BlockBackends on the source
> before successfully completing the migration because otherwise
> inactivating the images will fail (inactivation only tolerates device
> BBs).
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  migration/block.c | 22 +++++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
> 

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

[Qemu-devel] [PATCH 4/4] qemu-iotests: Block migration test
Posted by Kevin Wolf, 47 weeks ago
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 tests/qemu-iotests/183     | 121 +++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/183.out |  48 ++++++++++++++++++
 tests/qemu-iotests/group   |   1 +
 3 files changed, 170 insertions(+)
 create mode 100755 tests/qemu-iotests/183
 create mode 100644 tests/qemu-iotests/183.out

diff --git a/tests/qemu-iotests/183 b/tests/qemu-iotests/183
new file mode 100755
index 0000000..0e1442c
--- /dev/null
+++ b/tests/qemu-iotests/183
@@ -0,0 +1,121 @@
+#!/bin/bash
+#
+# Test old-style block migration (migrate -b)
+#
+# Copyright (C) 2017 Red Hat, Inc.
+#
+# 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
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=kwolf@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1	# failure is the default!
+
+MIG_SOCKET="${TEST_DIR}/migrate"
+
+_cleanup()
+{
+    rm -f "${MIG_SOCKET}"
+    rm -f "${TEST_IMG}.dest"
+	_cleanup_test_img
+    _cleanup_qemu
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+_supported_fmt generic
+_supported_proto file
+_supported_os Linux
+
+size=64M
+_make_test_img $size
+TEST_IMG="${TEST_IMG}.dest" _make_test_img $size
+
+echo
+echo === Starting VMs ===
+echo
+
+qemu_comm_method="monitor"
+
+_launch_qemu \
+    -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk
+src=$QEMU_HANDLE
+
+_launch_qemu \
+    -drive file="${TEST_IMG}.dest",cache=${CACHEMODE},driver=$IMGFMT,id=disk \
+    -incoming "unix:${MIG_SOCKET}"
+dest=$QEMU_HANDLE
+
+echo
+echo === Write something on the source ===
+echo
+
+_send_qemu_cmd $src 'qemu-io disk "write -P 0x55 0 64k"' "(qemu)"
+_send_qemu_cmd $src "" "ops/sec"
+silent=yes _timed_wait_for $src "(qemu)"
+_send_qemu_cmd $src 'qemu-io disk "read -P 0x55 0 64k"' "(qemu)"
+_send_qemu_cmd $src "" "ops/sec"
+silent=yes _timed_wait_for $src "(qemu)"
+
+echo
+echo === Do block migration to destination ===
+echo
+
+_send_qemu_cmd $src "migrate -b unix:${MIG_SOCKET}" "(qemu)"
+_send_qemu_cmd $src "info migrate" "(qemu)" | sed -e "s/Completed [0-9]* %//g"
+_send_qemu_cmd $src "" "(qemu)" | grep "status"
+
+echo
+echo === Do some I/O on the destination ===
+echo
+
+# It is important that we use the BlockBackend of the guest device here instead
+# of the node name, which would create a new BlockBackend and not test whether
+# the guest has the necessary permissions to access the image now
+_send_qemu_cmd $dest "info status" "(qemu)"
+_send_qemu_cmd $dest 'qemu-io disk "read -P 0x55 0 64k"' "(qemu)" |
+    sed -e "s/Completed [0-9]* %//g"
+_send_qemu_cmd $dest "" "ops/sec"
+silent=yes _timed_wait_for $dest "(qemu)"
+_send_qemu_cmd $dest 'qemu-io disk "write -P 0x66 1M 64k"' "(qemu)"
+_send_qemu_cmd $dest "" "ops/sec"
+silent=yes _timed_wait_for $dest "(qemu)"
+
+echo
+echo === Shut down and check image ===
+echo
+
+_send_qemu_cmd $src 'quit' ""
+_send_qemu_cmd $dest 'quit' ""
+wait=1 _cleanup_qemu
+
+_check_test_img
+TEST_IMG="${TEST_IMG}.dest" _check_test_img
+
+$QEMU_IO -c 'write -P 0x66 1M 64k' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IMG compare "$TEST_IMG.dest" "$TEST_IMG"
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/183.out b/tests/qemu-iotests/183.out
new file mode 100644
index 0000000..5e05d2a
--- /dev/null
+++ b/tests/qemu-iotests/183.out
@@ -0,0 +1,48 @@
+QA output created by 183
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT.dest', fmt=IMGFMT size=67108864
+
+=== Starting VMs ===
+
+
+=== Write something on the source ===
+
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qemu-io disk "write -P 0x55 0 64k"
+wrote 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+(qemu) qemu-io disk "read -P 0x55 0 64k"
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Do block migration to destination ===
+
+(qemu) migrate -b unix:TEST_DIR/migrate
+
+(qemu) info migrate
+Migration status: completed
+
+=== Do some I/O on the destination ===
+
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) Receiving block device images
+
+info status
+VM status: running
+(qemu) qemu-io disk "read -P 0x55 0 64k"
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+(qemu) qemu-io disk "write -P 0x66 1M 64k"
+wrote 65536/65536 bytes at offset 1048576
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Shut down and check image ===
+
+(qemu) quit
+(qemu) quit
+No errors were found on the image.
+No errors were found on the image.
+wrote 65536/65536 bytes at offset 1048576
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Images are identical.
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 5c8ea0f..a6acaff 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -174,3 +174,4 @@
 179 rw auto quick
 181 rw auto migration
 182 rw auto quick
+183 rw auto migration
-- 
1.8.3.1


Re: [Qemu-devel] [PATCH 4/4] qemu-iotests: Block migration test
Posted by Eric Blake, 47 weeks ago
On 05/23/2017 09:01 AM, Kevin Wolf wrote:
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  tests/qemu-iotests/183     | 121 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/qemu-iotests/183.out |  48 ++++++++++++++++++
>  tests/qemu-iotests/group   |   1 +
>  3 files changed, 170 insertions(+)
>  create mode 100755 tests/qemu-iotests/183
>  create mode 100644 tests/qemu-iotests/183.out
> 

Does this test gracefully skip when coupled with the efforts for a
configure option to disable block migration?
https://lists.gnu.org/archive/html/qemu-devel/2017-05/msg04398.html

> +echo
> +echo === Do block migration to destination ===
> +echo
> +
> +_send_qemu_cmd $src "migrate -b unix:${MIG_SOCKET}" "(qemu)"

I don't see any earlier checks, so it looks like you'd choke here if -b
is not compiled in.

Should we also check the use of -i?

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

Re: [Qemu-devel] [PATCH 4/4] qemu-iotests: Block migration test
Posted by Kevin Wolf, 47 weeks ago
Am 23.05.2017 um 17:46 hat Eric Blake geschrieben:
> On 05/23/2017 09:01 AM, Kevin Wolf wrote:
> > Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> > ---
> >  tests/qemu-iotests/183     | 121 +++++++++++++++++++++++++++++++++++++++++++++
> >  tests/qemu-iotests/183.out |  48 ++++++++++++++++++
> >  tests/qemu-iotests/group   |   1 +
> >  3 files changed, 170 insertions(+)
> >  create mode 100755 tests/qemu-iotests/183
> >  create mode 100644 tests/qemu-iotests/183.out
> 
> Does this test gracefully skip when coupled with the efforts for a
> configure option to disable block migration?
> https://lists.gnu.org/archive/html/qemu-devel/2017-05/msg04398.html

Obviously it doesn't. How would we even check? Just grep whether the
magic error string turns up somewhere after doing 'migrate -b'?

I don't think we have other test cases that don't skip immediately, but
only after doing half of the test, but I think it might work anyway.

> > +echo
> > +echo === Do block migration to destination ===
> > +echo
> > +
> > +_send_qemu_cmd $src "migrate -b unix:${MIG_SOCKET}" "(qemu)"
> 
> I don't see any earlier checks, so it looks like you'd choke here if -b
> is not compiled in.
> 
> Should we also check the use of -i?

Good point, though I don't even know how to use -i manually. :-)

We can either have a follow-up patch extending this one or a completely
separate test case for it. I would have to try out -i before I could say
which makes more sense.

Kevin
Re: [Qemu-devel] [PATCH 4/4] qemu-iotests: Block migration test
Posted by Eric Blake, 47 weeks ago
On 05/23/2017 11:18 AM, Kevin Wolf wrote:
> Am 23.05.2017 um 17:46 hat Eric Blake geschrieben:
>> On 05/23/2017 09:01 AM, Kevin Wolf wrote:
>>> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
>>> ---
>>>  tests/qemu-iotests/183     | 121 +++++++++++++++++++++++++++++++++++++++++++++
>>>  tests/qemu-iotests/183.out |  48 ++++++++++++++++++
>>>  tests/qemu-iotests/group   |   1 +
>>>  3 files changed, 170 insertions(+)
>>>  create mode 100755 tests/qemu-iotests/183
>>>  create mode 100644 tests/qemu-iotests/183.out
>>
>> Does this test gracefully skip when coupled with the efforts for a
>> configure option to disable block migration?
>> https://lists.gnu.org/archive/html/qemu-devel/2017-05/msg04398.html
> 
> Obviously it doesn't. How would we even check? Just grep whether the
> magic error string turns up somewhere after doing 'migrate -b'?

I think the easiest way (once Juan's series lands) would be to try this
QMP on a standalone qemu execution prior to firing up the rest of the test:

 { "execute":"migrate-set-capabilities", "arguments":{
    "capabilities": [ { "capability":"block", "state":true } ] } }

If that command fails, block migration is not compiled in (or we're
talking to an older qemu that lacks the capability altogether, but we
don't have to worry about that in our iotests).  Of course, if we do
that, then we could use QMP 'migrate' with the capabilities rather than
HMP -b to drive the same aspect of the test.

> 
> I don't think we have other test cases that don't skip immediately, but
> only after doing half of the test, but I think it might work anyway.

That's an option too - grepping for the magic failure string and
gracefully exiting if we were unable to start migration.  I think we
have done something like that recently to grep whether we have
op-blocking support via fcntl OFD semantics, and exit early if it is an
older kernel that has less-sane locks based on the error message.


>> Should we also check the use of -i?
> 
> Good point, though I don't even know how to use -i manually. :-)
> 
> We can either have a follow-up patch extending this one or a completely
> separate test case for it. I would have to try out -i before I could say
> which makes more sense.

An incremental patch to expand this test is fine.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org