1 | The following changes since commit bb9bf94b3e8926553290bc9a7cb84315af422086: | 1 | The following changes since commit 67c1115edd98f388ca89dd38322ea3fadf034523: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging (2018-12-11 19:18:58 +0000) | 3 | Merge remote-tracking branch 'remotes/kraxel/tags/ui-20210323-pull-request' into staging (2021-03-23 23:47:30 +0000) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | git://github.com/stefanha/qemu.git tags/block-pull-request | 7 | https://gitlab.com/stefanha/qemu.git tags/block-pull-request |
8 | 8 | ||
9 | for you to fetch changes up to e61809ed8ac3a2f68eb1cc231244f84eb06adacf: | 9 | for you to fetch changes up to 3460fd7f3959d1fa7bcc255796844aa261c805a4: |
10 | 10 | ||
11 | virtio-blk: fix comment for virtio_blk_rw_complete as nalloc is initially -1 (2018-12-12 09:16:55 +0000) | 11 | migrate-bitmaps-postcopy-test: check that we can't remove in-flight bitmaps (2021-03-24 13:41:19 +0000) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Pull request | 14 | Pull request |
15 | 15 | ||
16 | Minor virtio-blk fixes. | 16 | This dirty bitmap fix solves a crash that can be triggered in the destination |
17 | QEMU process during live migration. | ||
17 | 18 | ||
18 | ---------------------------------------------------------------- | 19 | ---------------------------------------------------------------- |
19 | 20 | ||
20 | Dongli Zhang (2): | 21 | Vladimir Sementsov-Ogievskiy (2): |
21 | virtio-blk: rename iov to out_iov in virtio_blk_handle_request() | 22 | migration/block-dirty-bitmap: make incoming disabled bitmaps busy |
22 | virtio-blk: fix comment for virtio_blk_rw_complete as nalloc is | 23 | migrate-bitmaps-postcopy-test: check that we can't remove in-flight |
23 | initially -1 | 24 | bitmaps |
24 | 25 | ||
25 | hw/block/virtio-blk.c | 10 +++++----- | 26 | migration/block-dirty-bitmap.c | 6 ++++++ |
26 | 1 file changed, 5 insertions(+), 5 deletions(-) | 27 | tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test | 10 ++++++++++ |
28 | 2 files changed, 16 insertions(+) | ||
27 | 29 | ||
28 | -- | 30 | -- |
29 | 2.19.2 | 31 | 2.30.2 |
30 | 32 | ||
31 | diff view generated by jsdifflib |
1 | From: Dongli Zhang <dongli.zhang@oracle.com> | 1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> |
---|---|---|---|
2 | 2 | ||
3 | In virtio_blk_handle_request(), in_iov is used for input header while iov | 3 | Incoming enabled bitmaps are busy, because we do |
4 | is used for output header. Rename iov to out_iov to pair output header's | 4 | bdrv_dirty_bitmap_create_successor() for them. But disabled bitmaps |
5 | name with in_iov to avoid confusing people when reading source code. | 5 | being migrated are not marked busy, and user can remove them during the |
6 | incoming migration. Then we may crash in cancel_incoming_locked() when | ||
7 | try to remove the bitmap that was already removed by user, like this: | ||
6 | 8 | ||
7 | Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com> | 9 | #0 qemu_mutex_lock_impl (mutex=0x5593d88c50d1, file=0x559680554b20 |
8 | Message-id: 1541520556-8334-1-git-send-email-dongli.zhang@oracle.com | 10 | "../block/dirty-bitmap.c", line=64) at ../util/qemu-thread-posix.c:77 |
11 | #1 bdrv_dirty_bitmaps_lock (bs=0x5593d88c0ee9) | ||
12 | at ../block/dirty-bitmap.c:64 | ||
13 | #2 bdrv_release_dirty_bitmap (bitmap=0x5596810e9570) | ||
14 | at ../block/dirty-bitmap.c:362 | ||
15 | #3 cancel_incoming_locked (s=0x559680be8208 <dbm_state+40>) | ||
16 | at ../migration/block-dirty-bitmap.c:918 | ||
17 | #4 dirty_bitmap_load (f=0x559681d02b10, opaque=0x559680be81e0 | ||
18 | <dbm_state>, version_id=1) at ../migration/block-dirty-bitmap.c:1194 | ||
19 | #5 vmstate_load (f=0x559681d02b10, se=0x559680fb5810) | ||
20 | at ../migration/savevm.c:908 | ||
21 | #6 qemu_loadvm_section_part_end (f=0x559681d02b10, | ||
22 | mis=0x559680fb4a30) at ../migration/savevm.c:2473 | ||
23 | #7 qemu_loadvm_state_main (f=0x559681d02b10, mis=0x559680fb4a30) | ||
24 | at ../migration/savevm.c:2626 | ||
25 | #8 postcopy_ram_listen_thread (opaque=0x0) | ||
26 | at ../migration/savevm.c:1871 | ||
27 | #9 qemu_thread_start (args=0x5596817ccd10) | ||
28 | at ../util/qemu-thread-posix.c:521 | ||
29 | #10 start_thread () at /lib64/libpthread.so.0 | ||
30 | #11 clone () at /lib64/libc.so.6 | ||
31 | |||
32 | Note bs pointer taken from bitmap: it's definitely bad aligned. That's | ||
33 | because we are in use after free, bitmap is already freed. | ||
34 | |||
35 | So, let's make disabled bitmaps (being migrated) busy during incoming | ||
36 | migration. | ||
37 | |||
38 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
9 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 39 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
40 | Message-Id: <20210322094906.5079-2-vsementsov@virtuozzo.com> | ||
10 | --- | 41 | --- |
11 | hw/block/virtio-blk.c | 8 ++++---- | 42 | migration/block-dirty-bitmap.c | 6 ++++++ |
12 | 1 file changed, 4 insertions(+), 4 deletions(-) | 43 | 1 file changed, 6 insertions(+) |
13 | 44 | ||
14 | diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c | 45 | diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c |
15 | index XXXXXXX..XXXXXXX 100644 | 46 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/hw/block/virtio-blk.c | 47 | --- a/migration/block-dirty-bitmap.c |
17 | +++ b/hw/block/virtio-blk.c | 48 | +++ b/migration/block-dirty-bitmap.c |
18 | @@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) | 49 | @@ -XXX,XX +XXX,XX @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) |
19 | { | 50 | error_report_err(local_err); |
20 | uint32_t type; | 51 | return -EINVAL; |
21 | struct iovec *in_iov = req->elem.in_sg; | 52 | } |
22 | - struct iovec *iov = req->elem.out_sg; | 53 | + } else { |
23 | + struct iovec *out_iov = req->elem.out_sg; | 54 | + bdrv_dirty_bitmap_set_busy(s->bitmap, true); |
24 | unsigned in_num = req->elem.in_num; | ||
25 | unsigned out_num = req->elem.out_num; | ||
26 | VirtIOBlock *s = req->dev; | ||
27 | @@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) | ||
28 | return -1; | ||
29 | } | 55 | } |
30 | 56 | ||
31 | - if (unlikely(iov_to_buf(iov, out_num, 0, &req->out, | 57 | b = g_new(LoadBitmapState, 1); |
32 | + if (unlikely(iov_to_buf(out_iov, out_num, 0, &req->out, | 58 | @@ -XXX,XX +XXX,XX @@ static void cancel_incoming_locked(DBMLoadState *s) |
33 | sizeof(req->out)) != sizeof(req->out))) { | 59 | assert(!s->before_vm_start_handled || !b->migrated); |
34 | virtio_error(vdev, "virtio-blk request outhdr too short"); | 60 | if (bdrv_dirty_bitmap_has_successor(b->bitmap)) { |
35 | return -1; | 61 | bdrv_reclaim_dirty_bitmap(b->bitmap, &error_abort); |
62 | + } else { | ||
63 | + bdrv_dirty_bitmap_set_busy(b->bitmap, false); | ||
64 | } | ||
65 | bdrv_release_dirty_bitmap(b->bitmap); | ||
36 | } | 66 | } |
37 | 67 | @@ -XXX,XX +XXX,XX @@ static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s) | |
38 | - iov_discard_front(&iov, &out_num, sizeof(req->out)); | 68 | |
39 | + iov_discard_front(&out_iov, &out_num, sizeof(req->out)); | 69 | if (bdrv_dirty_bitmap_has_successor(s->bitmap)) { |
40 | 70 | bdrv_reclaim_dirty_bitmap(s->bitmap, &error_abort); | |
41 | if (in_iov[in_num - 1].iov_len < sizeof(struct virtio_blk_inhdr)) { | 71 | + } else { |
42 | virtio_error(vdev, "virtio-blk request inhdr too short"); | 72 | + bdrv_dirty_bitmap_set_busy(s->bitmap, false); |
43 | @@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) | 73 | } |
44 | &req->out.sector); | 74 | |
45 | 75 | for (item = s->bitmaps; item; item = g_slist_next(item)) { | |
46 | if (is_write) { | ||
47 | - qemu_iovec_init_external(&req->qiov, iov, out_num); | ||
48 | + qemu_iovec_init_external(&req->qiov, out_iov, out_num); | ||
49 | trace_virtio_blk_handle_write(vdev, req, req->sector_num, | ||
50 | req->qiov.size / BDRV_SECTOR_SIZE); | ||
51 | } else { | ||
52 | -- | 76 | -- |
53 | 2.19.2 | 77 | 2.30.2 |
54 | 78 | ||
55 | diff view generated by jsdifflib |
1 | From: Dongli Zhang <dongli.zhang@oracle.com> | 1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> |
---|---|---|---|
2 | 2 | ||
3 | The initial value of nalloc is -1, but not 1. | 3 | Check that we can't remove bitmaps being migrated on destination vm. |
4 | The new check proves that previous commit helps. | ||
4 | 5 | ||
5 | Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com> | 6 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> |
6 | Reviewed-by: Laurent Vivier <laurent@vivier.eu> | ||
7 | Message-id: 1541479952-32355-1-git-send-email-dongli.zhang@oracle.com | ||
8 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 7 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
8 | Message-Id: <20210322094906.5079-3-vsementsov@virtuozzo.com> | ||
9 | --- | 9 | --- |
10 | hw/block/virtio-blk.c | 2 +- | 10 | tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test | 10 ++++++++++ |
11 | 1 file changed, 1 insertion(+), 1 deletion(-) | 11 | 1 file changed, 10 insertions(+) |
12 | 12 | ||
13 | diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c | 13 | diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test |
14 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100755 |
15 | --- a/hw/block/virtio-blk.c | 15 | --- a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test |
16 | +++ b/hw/block/virtio-blk.c | 16 | +++ b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test |
17 | @@ -XXX,XX +XXX,XX @@ static void virtio_blk_rw_complete(void *opaque, int ret) | 17 | @@ -XXX,XX +XXX,XX @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase): |
18 | trace_virtio_blk_rw_complete(vdev, req, ret); | 18 | self.start_postcopy() |
19 | 19 | ||
20 | if (req->qiov.nalloc != -1) { | 20 | self.vm_b_events += self.vm_b.get_qmp_events() |
21 | - /* If nalloc is != 1 req->qiov is a local copy of the original | 21 | + |
22 | + /* If nalloc is != -1 req->qiov is a local copy of the original | 22 | + # While being here, let's check that we can't remove in-flight bitmaps. |
23 | * external iovec. It was allocated in submit_requests to be | 23 | + for vm in (self.vm_a, self.vm_b): |
24 | * able to merge requests. */ | 24 | + for i in range(0, nb_bitmaps): |
25 | qemu_iovec_destroy(&req->qiov); | 25 | + result = vm.qmp('block-dirty-bitmap-remove', node='drive0', |
26 | + name=f'bitmap{i}') | ||
27 | + self.assert_qmp(result, 'error/desc', | ||
28 | + f"Bitmap 'bitmap{i}' is currently in use by " | ||
29 | + "another operation and cannot be used") | ||
30 | + | ||
31 | self.vm_b.shutdown() | ||
32 | # recreate vm_b, so there is no incoming option, which prevents | ||
33 | # loading bitmaps from disk | ||
26 | -- | 34 | -- |
27 | 2.19.2 | 35 | 2.30.2 |
28 | 36 | ||
29 | diff view generated by jsdifflib |