1881cfd17SKevin Wolf /* 2881cfd17SKevin Wolf * Block node draining tests 3881cfd17SKevin Wolf * 4881cfd17SKevin Wolf * Copyright (c) 2017 Kevin Wolf <kwolf@redhat.com> 5881cfd17SKevin Wolf * 6881cfd17SKevin Wolf * Permission is hereby granted, free of charge, to any person obtaining a copy 7881cfd17SKevin Wolf * of this software and associated documentation files (the "Software"), to deal 8881cfd17SKevin Wolf * in the Software without restriction, including without limitation the rights 9881cfd17SKevin Wolf * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10881cfd17SKevin Wolf * copies of the Software, and to permit persons to whom the Software is 11881cfd17SKevin Wolf * furnished to do so, subject to the following conditions: 12881cfd17SKevin Wolf * 13881cfd17SKevin Wolf * The above copyright notice and this permission notice shall be included in 14881cfd17SKevin Wolf * all copies or substantial portions of the Software. 15881cfd17SKevin Wolf * 16881cfd17SKevin Wolf * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17881cfd17SKevin Wolf * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18881cfd17SKevin Wolf * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19881cfd17SKevin Wolf * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20881cfd17SKevin Wolf * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21881cfd17SKevin Wolf * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22881cfd17SKevin Wolf * THE SOFTWARE. 23881cfd17SKevin Wolf */ 24881cfd17SKevin Wolf 25881cfd17SKevin Wolf #include "qemu/osdep.h" 26881cfd17SKevin Wolf #include "block/block.h" 277253220dSKevin Wolf #include "block/blockjob_int.h" 28881cfd17SKevin Wolf #include "sysemu/block-backend.h" 29881cfd17SKevin Wolf #include "qapi/error.h" 30db725815SMarkus Armbruster #include "qemu/main-loop.h" 31bb675689SKevin Wolf #include "iothread.h" 32bb675689SKevin Wolf 33bb675689SKevin Wolf static QemuEvent done_event; 34881cfd17SKevin Wolf 35881cfd17SKevin Wolf typedef struct BDRVTestState { 36881cfd17SKevin Wolf int drain_count; 37bb675689SKevin Wolf AioContext *bh_indirection_ctx; 3857320ca9SKevin Wolf bool sleep_in_drain_begin; 39881cfd17SKevin Wolf } BDRVTestState; 40881cfd17SKevin Wolf 41881cfd17SKevin Wolf static void coroutine_fn bdrv_test_co_drain_begin(BlockDriverState *bs) 42881cfd17SKevin Wolf { 43881cfd17SKevin Wolf BDRVTestState *s = bs->opaque; 44881cfd17SKevin Wolf s->drain_count++; 4557320ca9SKevin Wolf if (s->sleep_in_drain_begin) { 4657320ca9SKevin Wolf qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000); 4757320ca9SKevin Wolf } 48881cfd17SKevin Wolf } 49881cfd17SKevin Wolf 50881cfd17SKevin Wolf static void coroutine_fn bdrv_test_co_drain_end(BlockDriverState *bs) 51881cfd17SKevin Wolf { 52881cfd17SKevin Wolf BDRVTestState *s = bs->opaque; 53881cfd17SKevin Wolf s->drain_count--; 54881cfd17SKevin Wolf } 55881cfd17SKevin Wolf 56881cfd17SKevin Wolf static void bdrv_test_close(BlockDriverState *bs) 57881cfd17SKevin Wolf { 58881cfd17SKevin Wolf BDRVTestState *s = bs->opaque; 59881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, >, 0); 60881cfd17SKevin Wolf } 61881cfd17SKevin Wolf 62bb675689SKevin Wolf static void co_reenter_bh(void *opaque) 63bb675689SKevin Wolf { 64bb675689SKevin Wolf aio_co_wake(opaque); 65bb675689SKevin Wolf } 66bb675689SKevin Wolf 67881cfd17SKevin Wolf static int coroutine_fn bdrv_test_co_preadv(BlockDriverState *bs, 68*f7ef38ddSVladimir Sementsov-Ogievskiy int64_t offset, int64_t bytes, 69*f7ef38ddSVladimir Sementsov-Ogievskiy QEMUIOVector *qiov, 70*f7ef38ddSVladimir Sementsov-Ogievskiy BdrvRequestFlags flags) 71881cfd17SKevin Wolf { 72bb675689SKevin Wolf BDRVTestState *s = bs->opaque; 73bb675689SKevin Wolf 74881cfd17SKevin Wolf /* We want this request to stay until the polling loop in drain waits for 75881cfd17SKevin Wolf * it to complete. We need to sleep a while as bdrv_drain_invoke() comes 76881cfd17SKevin Wolf * first and polls its result, too, but it shouldn't accidentally complete 77881cfd17SKevin Wolf * this request yet. */ 78881cfd17SKevin Wolf qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000); 79881cfd17SKevin Wolf 80bb675689SKevin Wolf if (s->bh_indirection_ctx) { 81bb675689SKevin Wolf aio_bh_schedule_oneshot(s->bh_indirection_ctx, co_reenter_bh, 82bb675689SKevin Wolf qemu_coroutine_self()); 83bb675689SKevin Wolf qemu_coroutine_yield(); 84bb675689SKevin Wolf } 85bb675689SKevin Wolf 86881cfd17SKevin Wolf return 0; 87881cfd17SKevin Wolf } 88881cfd17SKevin Wolf 899746b35cSMax Reitz static int bdrv_test_change_backing_file(BlockDriverState *bs, 909746b35cSMax Reitz const char *backing_file, 919746b35cSMax Reitz const char *backing_fmt) 929746b35cSMax Reitz { 939746b35cSMax Reitz return 0; 949746b35cSMax Reitz } 959746b35cSMax Reitz 96881cfd17SKevin Wolf static BlockDriver bdrv_test = { 97881cfd17SKevin Wolf .format_name = "test", 98881cfd17SKevin Wolf .instance_size = sizeof(BDRVTestState), 9925f78d9eSVladimir Sementsov-Ogievskiy .supports_backing = true, 100881cfd17SKevin Wolf 101881cfd17SKevin Wolf .bdrv_close = bdrv_test_close, 102881cfd17SKevin Wolf .bdrv_co_preadv = bdrv_test_co_preadv, 103881cfd17SKevin Wolf 104881cfd17SKevin Wolf .bdrv_co_drain_begin = bdrv_test_co_drain_begin, 105881cfd17SKevin Wolf .bdrv_co_drain_end = bdrv_test_co_drain_end, 10686e1c840SKevin Wolf 107e5d8a406SMax Reitz .bdrv_child_perm = bdrv_default_perms, 1089746b35cSMax Reitz 1099746b35cSMax Reitz .bdrv_change_backing_file = bdrv_test_change_backing_file, 110881cfd17SKevin Wolf }; 111881cfd17SKevin Wolf 112881cfd17SKevin Wolf static void aio_ret_cb(void *opaque, int ret) 113881cfd17SKevin Wolf { 114881cfd17SKevin Wolf int *aio_ret = opaque; 115881cfd17SKevin Wolf *aio_ret = ret; 116881cfd17SKevin Wolf } 117881cfd17SKevin Wolf 1180582eb10SKevin Wolf typedef struct CallInCoroutineData { 1190582eb10SKevin Wolf void (*entry)(void); 1200582eb10SKevin Wolf bool done; 1210582eb10SKevin Wolf } CallInCoroutineData; 1220582eb10SKevin Wolf 1230582eb10SKevin Wolf static coroutine_fn void call_in_coroutine_entry(void *opaque) 1240582eb10SKevin Wolf { 1250582eb10SKevin Wolf CallInCoroutineData *data = opaque; 1260582eb10SKevin Wolf 1270582eb10SKevin Wolf data->entry(); 1280582eb10SKevin Wolf data->done = true; 1290582eb10SKevin Wolf } 1300582eb10SKevin Wolf 1310582eb10SKevin Wolf static void call_in_coroutine(void (*entry)(void)) 1320582eb10SKevin Wolf { 1330582eb10SKevin Wolf Coroutine *co; 1340582eb10SKevin Wolf CallInCoroutineData data = { 1350582eb10SKevin Wolf .entry = entry, 1360582eb10SKevin Wolf .done = false, 1370582eb10SKevin Wolf }; 1380582eb10SKevin Wolf 1390582eb10SKevin Wolf co = qemu_coroutine_create(call_in_coroutine_entry, &data); 1400582eb10SKevin Wolf qemu_coroutine_enter(co); 1410582eb10SKevin Wolf while (!data.done) { 1420582eb10SKevin Wolf aio_poll(qemu_get_aio_context(), true); 1430582eb10SKevin Wolf } 1440582eb10SKevin Wolf } 1450582eb10SKevin Wolf 14686e1c840SKevin Wolf enum drain_type { 14786e1c840SKevin Wolf BDRV_DRAIN_ALL, 14886e1c840SKevin Wolf BDRV_DRAIN, 149d2a85d0fSKevin Wolf BDRV_SUBTREE_DRAIN, 1506c429a6aSKevin Wolf DRAIN_TYPE_MAX, 15186e1c840SKevin Wolf }; 15286e1c840SKevin Wolf 15386e1c840SKevin Wolf static void do_drain_begin(enum drain_type drain_type, BlockDriverState *bs) 15486e1c840SKevin Wolf { 15586e1c840SKevin Wolf switch (drain_type) { 15686e1c840SKevin Wolf case BDRV_DRAIN_ALL: bdrv_drain_all_begin(); break; 15786e1c840SKevin Wolf case BDRV_DRAIN: bdrv_drained_begin(bs); break; 158d2a85d0fSKevin Wolf case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_begin(bs); break; 15986e1c840SKevin Wolf default: g_assert_not_reached(); 16086e1c840SKevin Wolf } 16186e1c840SKevin Wolf } 16286e1c840SKevin Wolf 16386e1c840SKevin Wolf static void do_drain_end(enum drain_type drain_type, BlockDriverState *bs) 16486e1c840SKevin Wolf { 16586e1c840SKevin Wolf switch (drain_type) { 16686e1c840SKevin Wolf case BDRV_DRAIN_ALL: bdrv_drain_all_end(); break; 16786e1c840SKevin Wolf case BDRV_DRAIN: bdrv_drained_end(bs); break; 168d2a85d0fSKevin Wolf case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_end(bs); break; 16986e1c840SKevin Wolf default: g_assert_not_reached(); 17086e1c840SKevin Wolf } 17186e1c840SKevin Wolf } 17286e1c840SKevin Wolf 173f62c1729SKevin Wolf static void do_drain_begin_unlocked(enum drain_type drain_type, BlockDriverState *bs) 174f62c1729SKevin Wolf { 175f62c1729SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 176f62c1729SKevin Wolf aio_context_acquire(bdrv_get_aio_context(bs)); 177f62c1729SKevin Wolf } 178f62c1729SKevin Wolf do_drain_begin(drain_type, bs); 179f62c1729SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 180f62c1729SKevin Wolf aio_context_release(bdrv_get_aio_context(bs)); 181f62c1729SKevin Wolf } 182f62c1729SKevin Wolf } 183f62c1729SKevin Wolf 184f62c1729SKevin Wolf static void do_drain_end_unlocked(enum drain_type drain_type, BlockDriverState *bs) 185f62c1729SKevin Wolf { 186f62c1729SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 187f62c1729SKevin Wolf aio_context_acquire(bdrv_get_aio_context(bs)); 188f62c1729SKevin Wolf } 189f62c1729SKevin Wolf do_drain_end(drain_type, bs); 190f62c1729SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 191f62c1729SKevin Wolf aio_context_release(bdrv_get_aio_context(bs)); 192f62c1729SKevin Wolf } 193f62c1729SKevin Wolf } 194f62c1729SKevin Wolf 19586e1c840SKevin Wolf static void test_drv_cb_common(enum drain_type drain_type, bool recursive) 196881cfd17SKevin Wolf { 197881cfd17SKevin Wolf BlockBackend *blk; 19886e1c840SKevin Wolf BlockDriverState *bs, *backing; 19986e1c840SKevin Wolf BDRVTestState *s, *backing_s; 200881cfd17SKevin Wolf BlockAIOCB *acb; 201881cfd17SKevin Wolf int aio_ret; 202881cfd17SKevin Wolf 203405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0); 204881cfd17SKevin Wolf 205d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 206881cfd17SKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 207881cfd17SKevin Wolf &error_abort); 208881cfd17SKevin Wolf s = bs->opaque; 209881cfd17SKevin Wolf blk_insert_bs(blk, bs, &error_abort); 210881cfd17SKevin Wolf 21186e1c840SKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 21286e1c840SKevin Wolf backing_s = backing->opaque; 21386e1c840SKevin Wolf bdrv_set_backing_hd(bs, backing, &error_abort); 21486e1c840SKevin Wolf 215881cfd17SKevin Wolf /* Simple bdrv_drain_all_begin/end pair, check that CBs are called */ 216881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 21786e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 21886e1c840SKevin Wolf 21986e1c840SKevin Wolf do_drain_begin(drain_type, bs); 22086e1c840SKevin Wolf 221881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 1); 22286e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, !!recursive); 22386e1c840SKevin Wolf 22486e1c840SKevin Wolf do_drain_end(drain_type, bs); 22586e1c840SKevin Wolf 226881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 22786e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 228881cfd17SKevin Wolf 229881cfd17SKevin Wolf /* Now do the same while a request is pending */ 230881cfd17SKevin Wolf aio_ret = -EINPROGRESS; 231881cfd17SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret); 232881cfd17SKevin Wolf g_assert(acb != NULL); 233881cfd17SKevin Wolf g_assert_cmpint(aio_ret, ==, -EINPROGRESS); 234881cfd17SKevin Wolf 235881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 23686e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 23786e1c840SKevin Wolf 23886e1c840SKevin Wolf do_drain_begin(drain_type, bs); 23986e1c840SKevin Wolf 240881cfd17SKevin Wolf g_assert_cmpint(aio_ret, ==, 0); 241881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 1); 24286e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, !!recursive); 243881cfd17SKevin Wolf 24486e1c840SKevin Wolf do_drain_end(drain_type, bs); 24586e1c840SKevin Wolf 24686e1c840SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 24786e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 24886e1c840SKevin Wolf 24986e1c840SKevin Wolf bdrv_unref(backing); 250881cfd17SKevin Wolf bdrv_unref(bs); 251881cfd17SKevin Wolf blk_unref(blk); 252881cfd17SKevin Wolf } 253881cfd17SKevin Wolf 25486e1c840SKevin Wolf static void test_drv_cb_drain_all(void) 25586e1c840SKevin Wolf { 25686e1c840SKevin Wolf test_drv_cb_common(BDRV_DRAIN_ALL, true); 25786e1c840SKevin Wolf } 25886e1c840SKevin Wolf 25986e1c840SKevin Wolf static void test_drv_cb_drain(void) 26086e1c840SKevin Wolf { 26186e1c840SKevin Wolf test_drv_cb_common(BDRV_DRAIN, false); 26286e1c840SKevin Wolf } 26386e1c840SKevin Wolf 264d2a85d0fSKevin Wolf static void test_drv_cb_drain_subtree(void) 265d2a85d0fSKevin Wolf { 266d2a85d0fSKevin Wolf test_drv_cb_common(BDRV_SUBTREE_DRAIN, true); 267d2a85d0fSKevin Wolf } 268d2a85d0fSKevin Wolf 2696d0252f2SKevin Wolf static void test_drv_cb_co_drain_all(void) 2706d0252f2SKevin Wolf { 2716d0252f2SKevin Wolf call_in_coroutine(test_drv_cb_drain_all); 2726d0252f2SKevin Wolf } 2736d0252f2SKevin Wolf 2740582eb10SKevin Wolf static void test_drv_cb_co_drain(void) 2750582eb10SKevin Wolf { 2760582eb10SKevin Wolf call_in_coroutine(test_drv_cb_drain); 2770582eb10SKevin Wolf } 2780582eb10SKevin Wolf 2790582eb10SKevin Wolf static void test_drv_cb_co_drain_subtree(void) 2800582eb10SKevin Wolf { 2810582eb10SKevin Wolf call_in_coroutine(test_drv_cb_drain_subtree); 2820582eb10SKevin Wolf } 2830582eb10SKevin Wolf 28489a6ceabSKevin Wolf static void test_quiesce_common(enum drain_type drain_type, bool recursive) 28589a6ceabSKevin Wolf { 28689a6ceabSKevin Wolf BlockBackend *blk; 28789a6ceabSKevin Wolf BlockDriverState *bs, *backing; 28889a6ceabSKevin Wolf 289d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 29089a6ceabSKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 29189a6ceabSKevin Wolf &error_abort); 29289a6ceabSKevin Wolf blk_insert_bs(blk, bs, &error_abort); 29389a6ceabSKevin Wolf 29489a6ceabSKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 29589a6ceabSKevin Wolf bdrv_set_backing_hd(bs, backing, &error_abort); 29689a6ceabSKevin Wolf 29789a6ceabSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 29889a6ceabSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 29989a6ceabSKevin Wolf 30089a6ceabSKevin Wolf do_drain_begin(drain_type, bs); 30189a6ceabSKevin Wolf 30289a6ceabSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 1); 30389a6ceabSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, !!recursive); 30489a6ceabSKevin Wolf 30589a6ceabSKevin Wolf do_drain_end(drain_type, bs); 30689a6ceabSKevin Wolf 30789a6ceabSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 30889a6ceabSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 30989a6ceabSKevin Wolf 31089a6ceabSKevin Wolf bdrv_unref(backing); 31189a6ceabSKevin Wolf bdrv_unref(bs); 31289a6ceabSKevin Wolf blk_unref(blk); 31389a6ceabSKevin Wolf } 31489a6ceabSKevin Wolf 31589a6ceabSKevin Wolf static void test_quiesce_drain_all(void) 31689a6ceabSKevin Wolf { 31779ab8b21SKevin Wolf test_quiesce_common(BDRV_DRAIN_ALL, true); 31889a6ceabSKevin Wolf } 31989a6ceabSKevin Wolf 32089a6ceabSKevin Wolf static void test_quiesce_drain(void) 32189a6ceabSKevin Wolf { 32289a6ceabSKevin Wolf test_quiesce_common(BDRV_DRAIN, false); 32389a6ceabSKevin Wolf } 32489a6ceabSKevin Wolf 325d2a85d0fSKevin Wolf static void test_quiesce_drain_subtree(void) 326d2a85d0fSKevin Wolf { 327d2a85d0fSKevin Wolf test_quiesce_common(BDRV_SUBTREE_DRAIN, true); 328d2a85d0fSKevin Wolf } 329d2a85d0fSKevin Wolf 3306d0252f2SKevin Wolf static void test_quiesce_co_drain_all(void) 3316d0252f2SKevin Wolf { 3326d0252f2SKevin Wolf call_in_coroutine(test_quiesce_drain_all); 3336d0252f2SKevin Wolf } 3346d0252f2SKevin Wolf 3350582eb10SKevin Wolf static void test_quiesce_co_drain(void) 3360582eb10SKevin Wolf { 3370582eb10SKevin Wolf call_in_coroutine(test_quiesce_drain); 3380582eb10SKevin Wolf } 3390582eb10SKevin Wolf 3400582eb10SKevin Wolf static void test_quiesce_co_drain_subtree(void) 3410582eb10SKevin Wolf { 3420582eb10SKevin Wolf call_in_coroutine(test_quiesce_drain_subtree); 3430582eb10SKevin Wolf } 3440582eb10SKevin Wolf 3456c429a6aSKevin Wolf static void test_nested(void) 3466c429a6aSKevin Wolf { 3476c429a6aSKevin Wolf BlockBackend *blk; 3486c429a6aSKevin Wolf BlockDriverState *bs, *backing; 3496c429a6aSKevin Wolf BDRVTestState *s, *backing_s; 3506c429a6aSKevin Wolf enum drain_type outer, inner; 3516c429a6aSKevin Wolf 352d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 3536c429a6aSKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 3546c429a6aSKevin Wolf &error_abort); 3556c429a6aSKevin Wolf s = bs->opaque; 3566c429a6aSKevin Wolf blk_insert_bs(blk, bs, &error_abort); 3576c429a6aSKevin Wolf 3586c429a6aSKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 3596c429a6aSKevin Wolf backing_s = backing->opaque; 3606c429a6aSKevin Wolf bdrv_set_backing_hd(bs, backing, &error_abort); 3616c429a6aSKevin Wolf 3626c429a6aSKevin Wolf for (outer = 0; outer < DRAIN_TYPE_MAX; outer++) { 3636c429a6aSKevin Wolf for (inner = 0; inner < DRAIN_TYPE_MAX; inner++) { 36479ab8b21SKevin Wolf int backing_quiesce = (outer != BDRV_DRAIN) + 3656c429a6aSKevin Wolf (inner != BDRV_DRAIN); 3666c429a6aSKevin Wolf 3676c429a6aSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 3686c429a6aSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 3696c429a6aSKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 3706c429a6aSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 3716c429a6aSKevin Wolf 3726c429a6aSKevin Wolf do_drain_begin(outer, bs); 3736c429a6aSKevin Wolf do_drain_begin(inner, bs); 3746c429a6aSKevin Wolf 37579ab8b21SKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 2); 3766c429a6aSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, backing_quiesce); 3776c429a6aSKevin Wolf g_assert_cmpint(s->drain_count, ==, 2); 37879ab8b21SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, backing_quiesce); 3796c429a6aSKevin Wolf 3806c429a6aSKevin Wolf do_drain_end(inner, bs); 3816c429a6aSKevin Wolf do_drain_end(outer, bs); 3826c429a6aSKevin Wolf 3836c429a6aSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 3846c429a6aSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 3856c429a6aSKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 3866c429a6aSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 3876c429a6aSKevin Wolf } 3886c429a6aSKevin Wolf } 3896c429a6aSKevin Wolf 3906c429a6aSKevin Wolf bdrv_unref(backing); 3916c429a6aSKevin Wolf bdrv_unref(bs); 3926c429a6aSKevin Wolf blk_unref(blk); 3936c429a6aSKevin Wolf } 3946c429a6aSKevin Wolf 39527e64474SKevin Wolf static void test_multiparent(void) 39627e64474SKevin Wolf { 39727e64474SKevin Wolf BlockBackend *blk_a, *blk_b; 39827e64474SKevin Wolf BlockDriverState *bs_a, *bs_b, *backing; 39927e64474SKevin Wolf BDRVTestState *a_s, *b_s, *backing_s; 40027e64474SKevin Wolf 401d861ab3aSKevin Wolf blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 40227e64474SKevin Wolf bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, 40327e64474SKevin Wolf &error_abort); 40427e64474SKevin Wolf a_s = bs_a->opaque; 40527e64474SKevin Wolf blk_insert_bs(blk_a, bs_a, &error_abort); 40627e64474SKevin Wolf 407d861ab3aSKevin Wolf blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 40827e64474SKevin Wolf bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, 40927e64474SKevin Wolf &error_abort); 41027e64474SKevin Wolf b_s = bs_b->opaque; 41127e64474SKevin Wolf blk_insert_bs(blk_b, bs_b, &error_abort); 41227e64474SKevin Wolf 41327e64474SKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 41427e64474SKevin Wolf backing_s = backing->opaque; 41527e64474SKevin Wolf bdrv_set_backing_hd(bs_a, backing, &error_abort); 41627e64474SKevin Wolf bdrv_set_backing_hd(bs_b, backing, &error_abort); 41727e64474SKevin Wolf 41827e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 41927e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 42027e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 42127e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 42227e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 42327e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 42427e64474SKevin Wolf 42527e64474SKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); 42627e64474SKevin Wolf 42727e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 42827e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 42927e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 1); 43027e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 43127e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 43227e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 1); 43327e64474SKevin Wolf 43427e64474SKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); 43527e64474SKevin Wolf 43627e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 2); 43727e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 2); 43827e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 2); 43927e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 2); 44027e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 2); 44127e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 2); 44227e64474SKevin Wolf 44327e64474SKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); 44427e64474SKevin Wolf 44527e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 44627e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 44727e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 1); 44827e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 44927e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 45027e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 1); 45127e64474SKevin Wolf 45227e64474SKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 45327e64474SKevin Wolf 45427e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 45527e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 45627e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 45727e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 45827e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 45927e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 46027e64474SKevin Wolf 46127e64474SKevin Wolf bdrv_unref(backing); 46227e64474SKevin Wolf bdrv_unref(bs_a); 46327e64474SKevin Wolf bdrv_unref(bs_b); 46427e64474SKevin Wolf blk_unref(blk_a); 46527e64474SKevin Wolf blk_unref(blk_b); 46627e64474SKevin Wolf } 46727e64474SKevin Wolf 46819f7a7e5SKevin Wolf static void test_graph_change_drain_subtree(void) 469acebcf8dSKevin Wolf { 470acebcf8dSKevin Wolf BlockBackend *blk_a, *blk_b; 471acebcf8dSKevin Wolf BlockDriverState *bs_a, *bs_b, *backing; 472acebcf8dSKevin Wolf BDRVTestState *a_s, *b_s, *backing_s; 473acebcf8dSKevin Wolf 474d861ab3aSKevin Wolf blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 475acebcf8dSKevin Wolf bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, 476acebcf8dSKevin Wolf &error_abort); 477acebcf8dSKevin Wolf a_s = bs_a->opaque; 478acebcf8dSKevin Wolf blk_insert_bs(blk_a, bs_a, &error_abort); 479acebcf8dSKevin Wolf 480d861ab3aSKevin Wolf blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 481acebcf8dSKevin Wolf bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, 482acebcf8dSKevin Wolf &error_abort); 483acebcf8dSKevin Wolf b_s = bs_b->opaque; 484acebcf8dSKevin Wolf blk_insert_bs(blk_b, bs_b, &error_abort); 485acebcf8dSKevin Wolf 486acebcf8dSKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 487acebcf8dSKevin Wolf backing_s = backing->opaque; 488acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_a, backing, &error_abort); 489acebcf8dSKevin Wolf 490acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 491acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 492acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 493acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 494acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 495acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 496acebcf8dSKevin Wolf 497acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); 498acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); 499acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); 500acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); 501acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); 502acebcf8dSKevin Wolf 503acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_b, backing, &error_abort); 504acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 5); 505acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 5); 506acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 5); 507acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 5); 508acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 5); 509acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 5); 510acebcf8dSKevin Wolf 511acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_b, NULL, &error_abort); 512acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 3); 513acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 2); 514acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 3); 515acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 3); 516acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 2); 517acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 3); 518acebcf8dSKevin Wolf 519acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_b, backing, &error_abort); 520acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 5); 521acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 5); 522acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 5); 523acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 5); 524acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 5); 525acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 5); 526acebcf8dSKevin Wolf 527acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); 528acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); 529acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 530acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 531acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 532acebcf8dSKevin Wolf 533acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 534acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 535acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 536acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 537acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 538acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 539acebcf8dSKevin Wolf 540acebcf8dSKevin Wolf bdrv_unref(backing); 541acebcf8dSKevin Wolf bdrv_unref(bs_a); 542acebcf8dSKevin Wolf bdrv_unref(bs_b); 543acebcf8dSKevin Wolf blk_unref(blk_a); 544acebcf8dSKevin Wolf blk_unref(blk_b); 545acebcf8dSKevin Wolf } 546acebcf8dSKevin Wolf 54719f7a7e5SKevin Wolf static void test_graph_change_drain_all(void) 54819f7a7e5SKevin Wolf { 54919f7a7e5SKevin Wolf BlockBackend *blk_a, *blk_b; 55019f7a7e5SKevin Wolf BlockDriverState *bs_a, *bs_b; 55119f7a7e5SKevin Wolf BDRVTestState *a_s, *b_s; 55219f7a7e5SKevin Wolf 55319f7a7e5SKevin Wolf /* Create node A with a BlockBackend */ 554d861ab3aSKevin Wolf blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 55519f7a7e5SKevin Wolf bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, 55619f7a7e5SKevin Wolf &error_abort); 55719f7a7e5SKevin Wolf a_s = bs_a->opaque; 55819f7a7e5SKevin Wolf blk_insert_bs(blk_a, bs_a, &error_abort); 55919f7a7e5SKevin Wolf 56019f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 56119f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 56219f7a7e5SKevin Wolf 56319f7a7e5SKevin Wolf /* Call bdrv_drain_all_begin() */ 56419f7a7e5SKevin Wolf bdrv_drain_all_begin(); 56519f7a7e5SKevin Wolf 56619f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 56719f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 56819f7a7e5SKevin Wolf 56919f7a7e5SKevin Wolf /* Create node B with a BlockBackend */ 570d861ab3aSKevin Wolf blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 57119f7a7e5SKevin Wolf bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, 57219f7a7e5SKevin Wolf &error_abort); 57319f7a7e5SKevin Wolf b_s = bs_b->opaque; 57419f7a7e5SKevin Wolf blk_insert_bs(blk_b, bs_b, &error_abort); 57519f7a7e5SKevin Wolf 57619f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 57719f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 57819f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 57919f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 58019f7a7e5SKevin Wolf 58119f7a7e5SKevin Wolf /* Unref and finally delete node A */ 58219f7a7e5SKevin Wolf blk_unref(blk_a); 58319f7a7e5SKevin Wolf 58419f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 58519f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 58619f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 58719f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 58819f7a7e5SKevin Wolf 58919f7a7e5SKevin Wolf bdrv_unref(bs_a); 59019f7a7e5SKevin Wolf 59119f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 59219f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 59319f7a7e5SKevin Wolf 59419f7a7e5SKevin Wolf /* End the drained section */ 59519f7a7e5SKevin Wolf bdrv_drain_all_end(); 59619f7a7e5SKevin Wolf 59719f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 59819f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 5991a6d3bd2SGreg Kurz g_assert_cmpint(qemu_get_aio_context()->external_disable_cnt, ==, 0); 60019f7a7e5SKevin Wolf 60119f7a7e5SKevin Wolf bdrv_unref(bs_b); 60219f7a7e5SKevin Wolf blk_unref(blk_b); 60319f7a7e5SKevin Wolf } 60419f7a7e5SKevin Wolf 605bb675689SKevin Wolf struct test_iothread_data { 606bb675689SKevin Wolf BlockDriverState *bs; 607bb675689SKevin Wolf enum drain_type drain_type; 608bb675689SKevin Wolf int *aio_ret; 609bb675689SKevin Wolf }; 610bb675689SKevin Wolf 611bb675689SKevin Wolf static void test_iothread_drain_entry(void *opaque) 612bb675689SKevin Wolf { 613bb675689SKevin Wolf struct test_iothread_data *data = opaque; 614bb675689SKevin Wolf 615bb675689SKevin Wolf aio_context_acquire(bdrv_get_aio_context(data->bs)); 616bb675689SKevin Wolf do_drain_begin(data->drain_type, data->bs); 617bb675689SKevin Wolf g_assert_cmpint(*data->aio_ret, ==, 0); 618bb675689SKevin Wolf do_drain_end(data->drain_type, data->bs); 619bb675689SKevin Wolf aio_context_release(bdrv_get_aio_context(data->bs)); 620bb675689SKevin Wolf 621bb675689SKevin Wolf qemu_event_set(&done_event); 622bb675689SKevin Wolf } 623bb675689SKevin Wolf 624bb675689SKevin Wolf static void test_iothread_aio_cb(void *opaque, int ret) 625bb675689SKevin Wolf { 626bb675689SKevin Wolf int *aio_ret = opaque; 627bb675689SKevin Wolf *aio_ret = ret; 628bb675689SKevin Wolf qemu_event_set(&done_event); 629bb675689SKevin Wolf } 630bb675689SKevin Wolf 631ecc1a5c7SKevin Wolf static void test_iothread_main_thread_bh(void *opaque) 632ecc1a5c7SKevin Wolf { 633ecc1a5c7SKevin Wolf struct test_iothread_data *data = opaque; 634ecc1a5c7SKevin Wolf 635ecc1a5c7SKevin Wolf /* Test that the AioContext is not yet locked in a random BH that is 636ecc1a5c7SKevin Wolf * executed during drain, otherwise this would deadlock. */ 637ecc1a5c7SKevin Wolf aio_context_acquire(bdrv_get_aio_context(data->bs)); 638ecc1a5c7SKevin Wolf bdrv_flush(data->bs); 639ecc1a5c7SKevin Wolf aio_context_release(bdrv_get_aio_context(data->bs)); 640ecc1a5c7SKevin Wolf } 641ecc1a5c7SKevin Wolf 642bb675689SKevin Wolf /* 643bb675689SKevin Wolf * Starts an AIO request on a BDS that runs in the AioContext of iothread 1. 644bb675689SKevin Wolf * The request involves a BH on iothread 2 before it can complete. 645bb675689SKevin Wolf * 646bb675689SKevin Wolf * @drain_thread = 0 means that do_drain_begin/end are called from the main 647bb675689SKevin Wolf * thread, @drain_thread = 1 means that they are called from iothread 1. Drain 648bb675689SKevin Wolf * for this BDS cannot be called from iothread 2 because only the main thread 649bb675689SKevin Wolf * may do cross-AioContext polling. 650bb675689SKevin Wolf */ 651bb675689SKevin Wolf static void test_iothread_common(enum drain_type drain_type, int drain_thread) 652bb675689SKevin Wolf { 653bb675689SKevin Wolf BlockBackend *blk; 654bb675689SKevin Wolf BlockDriverState *bs; 655bb675689SKevin Wolf BDRVTestState *s; 656bb675689SKevin Wolf BlockAIOCB *acb; 657bb675689SKevin Wolf int aio_ret; 658bb675689SKevin Wolf struct test_iothread_data data; 659bb675689SKevin Wolf 660bb675689SKevin Wolf IOThread *a = iothread_new(); 661bb675689SKevin Wolf IOThread *b = iothread_new(); 662bb675689SKevin Wolf AioContext *ctx_a = iothread_get_aio_context(a); 663bb675689SKevin Wolf AioContext *ctx_b = iothread_get_aio_context(b); 664bb675689SKevin Wolf 665405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0); 666bb675689SKevin Wolf 667bb675689SKevin Wolf /* bdrv_drain_all() may only be called from the main loop thread */ 668bb675689SKevin Wolf if (drain_type == BDRV_DRAIN_ALL && drain_thread != 0) { 669bb675689SKevin Wolf goto out; 670bb675689SKevin Wolf } 671bb675689SKevin Wolf 672d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 673bb675689SKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 674bb675689SKevin Wolf &error_abort); 675bb675689SKevin Wolf s = bs->opaque; 676bb675689SKevin Wolf blk_insert_bs(blk, bs, &error_abort); 677cf312932SKevin Wolf blk_set_disable_request_queuing(blk, true); 678bb675689SKevin Wolf 67997896a48SKevin Wolf blk_set_aio_context(blk, ctx_a, &error_abort); 680bb675689SKevin Wolf aio_context_acquire(ctx_a); 681bb675689SKevin Wolf 682bb675689SKevin Wolf s->bh_indirection_ctx = ctx_b; 683bb675689SKevin Wolf 684bb675689SKevin Wolf aio_ret = -EINPROGRESS; 685dd353157SKevin Wolf qemu_event_reset(&done_event); 686dd353157SKevin Wolf 687bb675689SKevin Wolf if (drain_thread == 0) { 688bb675689SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, test_iothread_aio_cb, &aio_ret); 689bb675689SKevin Wolf } else { 690bb675689SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret); 691bb675689SKevin Wolf } 692bb675689SKevin Wolf g_assert(acb != NULL); 693bb675689SKevin Wolf g_assert_cmpint(aio_ret, ==, -EINPROGRESS); 694bb675689SKevin Wolf 695bb675689SKevin Wolf aio_context_release(ctx_a); 696bb675689SKevin Wolf 697bb675689SKevin Wolf data = (struct test_iothread_data) { 698bb675689SKevin Wolf .bs = bs, 699bb675689SKevin Wolf .drain_type = drain_type, 700bb675689SKevin Wolf .aio_ret = &aio_ret, 701bb675689SKevin Wolf }; 702bb675689SKevin Wolf 703bb675689SKevin Wolf switch (drain_thread) { 704bb675689SKevin Wolf case 0: 705bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 706bb675689SKevin Wolf aio_context_acquire(ctx_a); 707bb675689SKevin Wolf } 708bb675689SKevin Wolf 709ecc1a5c7SKevin Wolf aio_bh_schedule_oneshot(ctx_a, test_iothread_main_thread_bh, &data); 710ecc1a5c7SKevin Wolf 711bb675689SKevin Wolf /* The request is running on the IOThread a. Draining its block device 712bb675689SKevin Wolf * will make sure that it has completed as far as the BDS is concerned, 713bb675689SKevin Wolf * but the drain in this thread can continue immediately after 714bb675689SKevin Wolf * bdrv_dec_in_flight() and aio_ret might be assigned only slightly 715bb675689SKevin Wolf * later. */ 716bb675689SKevin Wolf do_drain_begin(drain_type, bs); 717bb675689SKevin Wolf g_assert_cmpint(bs->in_flight, ==, 0); 718bb675689SKevin Wolf 719bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 720bb675689SKevin Wolf aio_context_release(ctx_a); 721bb675689SKevin Wolf } 722bb675689SKevin Wolf qemu_event_wait(&done_event); 723bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 724bb675689SKevin Wolf aio_context_acquire(ctx_a); 725bb675689SKevin Wolf } 726bb675689SKevin Wolf 727bb675689SKevin Wolf g_assert_cmpint(aio_ret, ==, 0); 728bb675689SKevin Wolf do_drain_end(drain_type, bs); 729bb675689SKevin Wolf 730bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 731bb675689SKevin Wolf aio_context_release(ctx_a); 732bb675689SKevin Wolf } 733bb675689SKevin Wolf break; 734bb675689SKevin Wolf case 1: 735bb675689SKevin Wolf aio_bh_schedule_oneshot(ctx_a, test_iothread_drain_entry, &data); 736bb675689SKevin Wolf qemu_event_wait(&done_event); 737bb675689SKevin Wolf break; 738bb675689SKevin Wolf default: 739bb675689SKevin Wolf g_assert_not_reached(); 740bb675689SKevin Wolf } 741bb675689SKevin Wolf 742bb675689SKevin Wolf aio_context_acquire(ctx_a); 74397896a48SKevin Wolf blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort); 744bb675689SKevin Wolf aio_context_release(ctx_a); 745bb675689SKevin Wolf 746bb675689SKevin Wolf bdrv_unref(bs); 747bb675689SKevin Wolf blk_unref(blk); 748bb675689SKevin Wolf 749bb675689SKevin Wolf out: 750bb675689SKevin Wolf iothread_join(a); 751bb675689SKevin Wolf iothread_join(b); 752bb675689SKevin Wolf } 753bb675689SKevin Wolf 754bb675689SKevin Wolf static void test_iothread_drain_all(void) 755bb675689SKevin Wolf { 756bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN_ALL, 0); 757bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN_ALL, 1); 758bb675689SKevin Wolf } 759bb675689SKevin Wolf 760bb675689SKevin Wolf static void test_iothread_drain(void) 761bb675689SKevin Wolf { 762bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN, 0); 763bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN, 1); 764bb675689SKevin Wolf } 765bb675689SKevin Wolf 766bb675689SKevin Wolf static void test_iothread_drain_subtree(void) 767bb675689SKevin Wolf { 768bb675689SKevin Wolf test_iothread_common(BDRV_SUBTREE_DRAIN, 0); 769bb675689SKevin Wolf test_iothread_common(BDRV_SUBTREE_DRAIN, 1); 770bb675689SKevin Wolf } 771bb675689SKevin Wolf 7727253220dSKevin Wolf 7737253220dSKevin Wolf typedef struct TestBlockJob { 7747253220dSKevin Wolf BlockJob common; 775d49725afSKevin Wolf int run_ret; 776d49725afSKevin Wolf int prepare_ret; 777d8b3afd5SKevin Wolf bool running; 7787253220dSKevin Wolf bool should_complete; 7797253220dSKevin Wolf } TestBlockJob; 7807253220dSKevin Wolf 781ae23dde9SKevin Wolf static int test_job_prepare(Job *job) 782ae23dde9SKevin Wolf { 783ae23dde9SKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 784ae23dde9SKevin Wolf 785ae23dde9SKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 786ae23dde9SKevin Wolf blk_flush(s->common.blk); 787d49725afSKevin Wolf return s->prepare_ret; 788d49725afSKevin Wolf } 789d49725afSKevin Wolf 790d49725afSKevin Wolf static void test_job_commit(Job *job) 791d49725afSKevin Wolf { 792d49725afSKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 793d49725afSKevin Wolf 794d49725afSKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 795d49725afSKevin Wolf blk_flush(s->common.blk); 796d49725afSKevin Wolf } 797d49725afSKevin Wolf 798d49725afSKevin Wolf static void test_job_abort(Job *job) 799d49725afSKevin Wolf { 800d49725afSKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 801d49725afSKevin Wolf 802d49725afSKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 803d49725afSKevin Wolf blk_flush(s->common.blk); 804ae23dde9SKevin Wolf } 805ae23dde9SKevin Wolf 806f67432a2SJohn Snow static int coroutine_fn test_job_run(Job *job, Error **errp) 8077253220dSKevin Wolf { 808f67432a2SJohn Snow TestBlockJob *s = container_of(job, TestBlockJob, common.job); 8097253220dSKevin Wolf 810d8b3afd5SKevin Wolf /* We are running the actual job code past the pause point in 811d8b3afd5SKevin Wolf * job_co_entry(). */ 812d8b3afd5SKevin Wolf s->running = true; 813d8b3afd5SKevin Wolf 8142e1795b5SKevin Wolf job_transition_to_ready(&s->common.job); 8157253220dSKevin Wolf while (!s->should_complete) { 8165599c162SKevin Wolf /* Avoid job_sleep_ns() because it marks the job as !busy. We want to 8175599c162SKevin Wolf * emulate some actual activity (probably some I/O) here so that drain 8185599c162SKevin Wolf * has to wait for this activity to stop. */ 819d8b3afd5SKevin Wolf qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000); 820d8b3afd5SKevin Wolf 82189bd0305SKevin Wolf job_pause_point(&s->common.job); 8227253220dSKevin Wolf } 8237253220dSKevin Wolf 824d49725afSKevin Wolf return s->run_ret; 8257253220dSKevin Wolf } 8267253220dSKevin Wolf 8273453d972SKevin Wolf static void test_job_complete(Job *job, Error **errp) 8287253220dSKevin Wolf { 8293453d972SKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 8307253220dSKevin Wolf s->should_complete = true; 8317253220dSKevin Wolf } 8327253220dSKevin Wolf 8337253220dSKevin Wolf BlockJobDriver test_job_driver = { 83433e9e9bdSKevin Wolf .job_driver = { 8357253220dSKevin Wolf .instance_size = sizeof(TestBlockJob), 83680fa2c75SKevin Wolf .free = block_job_free, 837b15de828SKevin Wolf .user_resume = block_job_user_resume, 838f67432a2SJohn Snow .run = test_job_run, 8397253220dSKevin Wolf .complete = test_job_complete, 840ae23dde9SKevin Wolf .prepare = test_job_prepare, 841d49725afSKevin Wolf .commit = test_job_commit, 842d49725afSKevin Wolf .abort = test_job_abort, 8433453d972SKevin Wolf }, 8447253220dSKevin Wolf }; 8457253220dSKevin Wolf 846d49725afSKevin Wolf enum test_job_result { 847d49725afSKevin Wolf TEST_JOB_SUCCESS, 848d49725afSKevin Wolf TEST_JOB_FAIL_RUN, 849d49725afSKevin Wolf TEST_JOB_FAIL_PREPARE, 850d49725afSKevin Wolf }; 851d49725afSKevin Wolf 852d8b3afd5SKevin Wolf enum test_job_drain_node { 853d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC, 854d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_CHILD, 855d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_PARENT, 856d8b3afd5SKevin Wolf }; 857d8b3afd5SKevin Wolf 858d8b3afd5SKevin Wolf static void test_blockjob_common_drain_node(enum drain_type drain_type, 859d8b3afd5SKevin Wolf bool use_iothread, 860d8b3afd5SKevin Wolf enum test_job_result result, 861d8b3afd5SKevin Wolf enum test_job_drain_node drain_node) 8627253220dSKevin Wolf { 8637253220dSKevin Wolf BlockBackend *blk_src, *blk_target; 864d8b3afd5SKevin Wolf BlockDriverState *src, *src_backing, *src_overlay, *target, *drain_bs; 8657253220dSKevin Wolf BlockJob *job; 866d49725afSKevin Wolf TestBlockJob *tjob; 867f62c1729SKevin Wolf IOThread *iothread = NULL; 868f62c1729SKevin Wolf AioContext *ctx; 8697253220dSKevin Wolf int ret; 8707253220dSKevin Wolf 8717253220dSKevin Wolf src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR, 8727253220dSKevin Wolf &error_abort); 873d8b3afd5SKevin Wolf src_backing = bdrv_new_open_driver(&bdrv_test, "source-backing", 874d8b3afd5SKevin Wolf BDRV_O_RDWR, &error_abort); 875d8b3afd5SKevin Wolf src_overlay = bdrv_new_open_driver(&bdrv_test, "source-overlay", 876d8b3afd5SKevin Wolf BDRV_O_RDWR, &error_abort); 877d8b3afd5SKevin Wolf 878d8b3afd5SKevin Wolf bdrv_set_backing_hd(src_overlay, src, &error_abort); 879d8b3afd5SKevin Wolf bdrv_unref(src); 880d8b3afd5SKevin Wolf bdrv_set_backing_hd(src, src_backing, &error_abort); 881d8b3afd5SKevin Wolf bdrv_unref(src_backing); 882d8b3afd5SKevin Wolf 883d861ab3aSKevin Wolf blk_src = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 884d8b3afd5SKevin Wolf blk_insert_bs(blk_src, src_overlay, &error_abort); 885d8b3afd5SKevin Wolf 886d8b3afd5SKevin Wolf switch (drain_node) { 887d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC: 888d8b3afd5SKevin Wolf drain_bs = src; 889d8b3afd5SKevin Wolf break; 890d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC_CHILD: 891d8b3afd5SKevin Wolf drain_bs = src_backing; 892d8b3afd5SKevin Wolf break; 893d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC_PARENT: 894d8b3afd5SKevin Wolf drain_bs = src_overlay; 895d8b3afd5SKevin Wolf break; 896d8b3afd5SKevin Wolf default: 897d8b3afd5SKevin Wolf g_assert_not_reached(); 898d8b3afd5SKevin Wolf } 8997253220dSKevin Wolf 900f62c1729SKevin Wolf if (use_iothread) { 901f62c1729SKevin Wolf iothread = iothread_new(); 902f62c1729SKevin Wolf ctx = iothread_get_aio_context(iothread); 90397896a48SKevin Wolf blk_set_aio_context(blk_src, ctx, &error_abort); 904f62c1729SKevin Wolf } else { 905f62c1729SKevin Wolf ctx = qemu_get_aio_context(); 906f62c1729SKevin Wolf } 907f62c1729SKevin Wolf 9087253220dSKevin Wolf target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR, 9097253220dSKevin Wolf &error_abort); 910d861ab3aSKevin Wolf blk_target = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 9117253220dSKevin Wolf blk_insert_bs(blk_target, target, &error_abort); 912132ada80SKevin Wolf blk_set_allow_aio_context_change(blk_target, true); 9137253220dSKevin Wolf 914f62c1729SKevin Wolf aio_context_acquire(ctx); 915d49725afSKevin Wolf tjob = block_job_create("job0", &test_job_driver, NULL, src, 916d49725afSKevin Wolf 0, BLK_PERM_ALL, 91775859b94SJohn Snow 0, 0, NULL, NULL, &error_abort); 918d49725afSKevin Wolf job = &tjob->common; 9197253220dSKevin Wolf block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort); 920d49725afSKevin Wolf 921d49725afSKevin Wolf switch (result) { 922d49725afSKevin Wolf case TEST_JOB_SUCCESS: 923d49725afSKevin Wolf break; 924d49725afSKevin Wolf case TEST_JOB_FAIL_RUN: 925d49725afSKevin Wolf tjob->run_ret = -EIO; 926d49725afSKevin Wolf break; 927d49725afSKevin Wolf case TEST_JOB_FAIL_PREPARE: 928d49725afSKevin Wolf tjob->prepare_ret = -EIO; 929d49725afSKevin Wolf break; 930d49725afSKevin Wolf } 931d49725afSKevin Wolf 932da01ff7fSKevin Wolf job_start(&job->job); 933f62c1729SKevin Wolf aio_context_release(ctx); 9347253220dSKevin Wolf 935d8b3afd5SKevin Wolf if (use_iothread) { 936d8b3afd5SKevin Wolf /* job_co_entry() is run in the I/O thread, wait for the actual job 937d8b3afd5SKevin Wolf * code to start (we don't want to catch the job in the pause point in 938d8b3afd5SKevin Wolf * job_co_entry(). */ 939d8b3afd5SKevin Wolf while (!tjob->running) { 940d8b3afd5SKevin Wolf aio_poll(qemu_get_aio_context(), false); 941d8b3afd5SKevin Wolf } 942d8b3afd5SKevin Wolf } 943d8b3afd5SKevin Wolf 944da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 945da01ff7fSKevin Wolf g_assert_false(job->job.paused); 946d8b3afd5SKevin Wolf g_assert_true(tjob->running); 9475599c162SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 9487253220dSKevin Wolf 949d8b3afd5SKevin Wolf do_drain_begin_unlocked(drain_type, drain_bs); 9507253220dSKevin Wolf 9517253220dSKevin Wolf if (drain_type == BDRV_DRAIN_ALL) { 95281193349SKevin Wolf /* bdrv_drain_all() drains both src and target */ 953da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 2); 9547253220dSKevin Wolf } else { 955da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 1); 9567253220dSKevin Wolf } 95789bd0305SKevin Wolf g_assert_true(job->job.paused); 958da01ff7fSKevin Wolf g_assert_false(job->job.busy); /* The job is paused */ 9597253220dSKevin Wolf 960d8b3afd5SKevin Wolf do_drain_end_unlocked(drain_type, drain_bs); 961f62c1729SKevin Wolf 962f62c1729SKevin Wolf if (use_iothread) { 963f62c1729SKevin Wolf /* paused is reset in the I/O thread, wait for it */ 964f62c1729SKevin Wolf while (job->job.paused) { 965f62c1729SKevin Wolf aio_poll(qemu_get_aio_context(), false); 966f62c1729SKevin Wolf } 967f62c1729SKevin Wolf } 9687253220dSKevin Wolf 969da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 970da01ff7fSKevin Wolf g_assert_false(job->job.paused); 97189bd0305SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 9727253220dSKevin Wolf 973132ada80SKevin Wolf do_drain_begin_unlocked(drain_type, target); 9747253220dSKevin Wolf 9757253220dSKevin Wolf if (drain_type == BDRV_DRAIN_ALL) { 97681193349SKevin Wolf /* bdrv_drain_all() drains both src and target */ 977da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 2); 9787253220dSKevin Wolf } else { 979da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 1); 9807253220dSKevin Wolf } 98189bd0305SKevin Wolf g_assert_true(job->job.paused); 982da01ff7fSKevin Wolf g_assert_false(job->job.busy); /* The job is paused */ 9837253220dSKevin Wolf 984132ada80SKevin Wolf do_drain_end_unlocked(drain_type, target); 9857253220dSKevin Wolf 986f62c1729SKevin Wolf if (use_iothread) { 987f62c1729SKevin Wolf /* paused is reset in the I/O thread, wait for it */ 988f62c1729SKevin Wolf while (job->job.paused) { 989f62c1729SKevin Wolf aio_poll(qemu_get_aio_context(), false); 990f62c1729SKevin Wolf } 991f62c1729SKevin Wolf } 992f62c1729SKevin Wolf 993da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 994da01ff7fSKevin Wolf g_assert_false(job->job.paused); 9955599c162SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 9967253220dSKevin Wolf 997f62c1729SKevin Wolf aio_context_acquire(ctx); 9983d70ff53SKevin Wolf ret = job_complete_sync(&job->job, &error_abort); 999d49725afSKevin Wolf g_assert_cmpint(ret, ==, (result == TEST_JOB_SUCCESS ? 0 : -EIO)); 10007253220dSKevin Wolf 1001f62c1729SKevin Wolf if (use_iothread) { 100297896a48SKevin Wolf blk_set_aio_context(blk_src, qemu_get_aio_context(), &error_abort); 1003ad943dcbSKevin Wolf assert(blk_get_aio_context(blk_target) == qemu_get_aio_context()); 1004f62c1729SKevin Wolf } 1005f62c1729SKevin Wolf aio_context_release(ctx); 1006f62c1729SKevin Wolf 10077253220dSKevin Wolf blk_unref(blk_src); 10087253220dSKevin Wolf blk_unref(blk_target); 1009d8b3afd5SKevin Wolf bdrv_unref(src_overlay); 10107253220dSKevin Wolf bdrv_unref(target); 1011f62c1729SKevin Wolf 1012f62c1729SKevin Wolf if (iothread) { 1013f62c1729SKevin Wolf iothread_join(iothread); 1014f62c1729SKevin Wolf } 10157253220dSKevin Wolf } 10167253220dSKevin Wolf 1017d8b3afd5SKevin Wolf static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, 1018d8b3afd5SKevin Wolf enum test_job_result result) 1019d8b3afd5SKevin Wolf { 1020d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1021d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC); 1022d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1023d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_CHILD); 1024d8b3afd5SKevin Wolf if (drain_type == BDRV_SUBTREE_DRAIN) { 1025d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1026d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_PARENT); 1027d8b3afd5SKevin Wolf } 1028d8b3afd5SKevin Wolf } 1029d8b3afd5SKevin Wolf 10307253220dSKevin Wolf static void test_blockjob_drain_all(void) 10317253220dSKevin Wolf { 1032d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_SUCCESS); 10337253220dSKevin Wolf } 10347253220dSKevin Wolf 10357253220dSKevin Wolf static void test_blockjob_drain(void) 10367253220dSKevin Wolf { 1037d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_SUCCESS); 10387253220dSKevin Wolf } 10397253220dSKevin Wolf 1040d2a85d0fSKevin Wolf static void test_blockjob_drain_subtree(void) 1041d2a85d0fSKevin Wolf { 1042d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_SUCCESS); 1043d49725afSKevin Wolf } 1044d49725afSKevin Wolf 1045d49725afSKevin Wolf static void test_blockjob_error_drain_all(void) 1046d49725afSKevin Wolf { 1047d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_RUN); 1048d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_PREPARE); 1049d49725afSKevin Wolf } 1050d49725afSKevin Wolf 1051d49725afSKevin Wolf static void test_blockjob_error_drain(void) 1052d49725afSKevin Wolf { 1053d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_RUN); 1054d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_PREPARE); 1055d49725afSKevin Wolf } 1056d49725afSKevin Wolf 1057d49725afSKevin Wolf static void test_blockjob_error_drain_subtree(void) 1058d49725afSKevin Wolf { 1059d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_RUN); 1060d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_PREPARE); 1061f62c1729SKevin Wolf } 1062f62c1729SKevin Wolf 1063f62c1729SKevin Wolf static void test_blockjob_iothread_drain_all(void) 1064f62c1729SKevin Wolf { 1065d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_SUCCESS); 1066f62c1729SKevin Wolf } 1067f62c1729SKevin Wolf 1068f62c1729SKevin Wolf static void test_blockjob_iothread_drain(void) 1069f62c1729SKevin Wolf { 1070d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_SUCCESS); 1071f62c1729SKevin Wolf } 1072f62c1729SKevin Wolf 1073f62c1729SKevin Wolf static void test_blockjob_iothread_drain_subtree(void) 1074f62c1729SKevin Wolf { 1075d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_SUCCESS); 1076d49725afSKevin Wolf } 1077d49725afSKevin Wolf 1078d49725afSKevin Wolf static void test_blockjob_iothread_error_drain_all(void) 1079d49725afSKevin Wolf { 1080d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_RUN); 1081d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_PREPARE); 1082d49725afSKevin Wolf } 1083d49725afSKevin Wolf 1084d49725afSKevin Wolf static void test_blockjob_iothread_error_drain(void) 1085d49725afSKevin Wolf { 1086d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_RUN); 1087d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_PREPARE); 1088d49725afSKevin Wolf } 1089d49725afSKevin Wolf 1090d49725afSKevin Wolf static void test_blockjob_iothread_error_drain_subtree(void) 1091d49725afSKevin Wolf { 1092d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_RUN); 1093d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_PREPARE); 1094d2a85d0fSKevin Wolf } 1095d2a85d0fSKevin Wolf 10964c8158e3SMax Reitz 10974c8158e3SMax Reitz typedef struct BDRVTestTopState { 10984c8158e3SMax Reitz BdrvChild *wait_child; 10994c8158e3SMax Reitz } BDRVTestTopState; 11004c8158e3SMax Reitz 11014c8158e3SMax Reitz static void bdrv_test_top_close(BlockDriverState *bs) 11024c8158e3SMax Reitz { 11034c8158e3SMax Reitz BdrvChild *c, *next_c; 11044c8158e3SMax Reitz QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) { 11054c8158e3SMax Reitz bdrv_unref_child(bs, c); 11064c8158e3SMax Reitz } 11074c8158e3SMax Reitz } 11084c8158e3SMax Reitz 11094c8158e3SMax Reitz static int coroutine_fn bdrv_test_top_co_preadv(BlockDriverState *bs, 1110*f7ef38ddSVladimir Sementsov-Ogievskiy int64_t offset, int64_t bytes, 1111*f7ef38ddSVladimir Sementsov-Ogievskiy QEMUIOVector *qiov, 1112*f7ef38ddSVladimir Sementsov-Ogievskiy BdrvRequestFlags flags) 11134c8158e3SMax Reitz { 11144c8158e3SMax Reitz BDRVTestTopState *tts = bs->opaque; 11154c8158e3SMax Reitz return bdrv_co_preadv(tts->wait_child, offset, bytes, qiov, flags); 11164c8158e3SMax Reitz } 11174c8158e3SMax Reitz 11184c8158e3SMax Reitz static BlockDriver bdrv_test_top_driver = { 11194c8158e3SMax Reitz .format_name = "test_top_driver", 11204c8158e3SMax Reitz .instance_size = sizeof(BDRVTestTopState), 11214c8158e3SMax Reitz 11224c8158e3SMax Reitz .bdrv_close = bdrv_test_top_close, 11234c8158e3SMax Reitz .bdrv_co_preadv = bdrv_test_top_co_preadv, 11244c8158e3SMax Reitz 112569dca43dSMax Reitz .bdrv_child_perm = bdrv_default_perms, 11264c8158e3SMax Reitz }; 11274c8158e3SMax Reitz 11284c8158e3SMax Reitz typedef struct TestCoDeleteByDrainData { 11294c8158e3SMax Reitz BlockBackend *blk; 11304c8158e3SMax Reitz bool detach_instead_of_delete; 11314c8158e3SMax Reitz bool done; 11324c8158e3SMax Reitz } TestCoDeleteByDrainData; 11334c8158e3SMax Reitz 11344c8158e3SMax Reitz static void coroutine_fn test_co_delete_by_drain(void *opaque) 11354c8158e3SMax Reitz { 11364c8158e3SMax Reitz TestCoDeleteByDrainData *dbdd = opaque; 11374c8158e3SMax Reitz BlockBackend *blk = dbdd->blk; 11384c8158e3SMax Reitz BlockDriverState *bs = blk_bs(blk); 11394c8158e3SMax Reitz BDRVTestTopState *tts = bs->opaque; 11404c8158e3SMax Reitz void *buffer = g_malloc(65536); 1141405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buffer, 65536); 11424c8158e3SMax Reitz 11434c8158e3SMax Reitz /* Pretend some internal write operation from parent to child. 11444c8158e3SMax Reitz * Important: We have to read from the child, not from the parent! 11454c8158e3SMax Reitz * Draining works by first propagating it all up the tree to the 11464c8158e3SMax Reitz * root and then waiting for drainage from root to the leaves 11474c8158e3SMax Reitz * (protocol nodes). If we have a request waiting on the root, 11484c8158e3SMax Reitz * everything will be drained before we go back down the tree, but 11494c8158e3SMax Reitz * we do not want that. We want to be in the middle of draining 11504c8158e3SMax Reitz * when this following requests returns. */ 11514c8158e3SMax Reitz bdrv_co_preadv(tts->wait_child, 0, 65536, &qiov, 0); 11524c8158e3SMax Reitz 11534c8158e3SMax Reitz g_assert_cmpint(bs->refcnt, ==, 1); 11544c8158e3SMax Reitz 11554c8158e3SMax Reitz if (!dbdd->detach_instead_of_delete) { 11564c8158e3SMax Reitz blk_unref(blk); 11574c8158e3SMax Reitz } else { 11584c8158e3SMax Reitz BdrvChild *c, *next_c; 11594c8158e3SMax Reitz QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) { 11604c8158e3SMax Reitz bdrv_unref_child(bs, c); 11614c8158e3SMax Reitz } 11624c8158e3SMax Reitz } 11634c8158e3SMax Reitz 11644c8158e3SMax Reitz dbdd->done = true; 11657b43db3cSMarc-André Lureau g_free(buffer); 11664c8158e3SMax Reitz } 11674c8158e3SMax Reitz 11684c8158e3SMax Reitz /** 11694c8158e3SMax Reitz * Test what happens when some BDS has some children, you drain one of 11704c8158e3SMax Reitz * them and this results in the BDS being deleted. 11714c8158e3SMax Reitz * 11724c8158e3SMax Reitz * If @detach_instead_of_delete is set, the BDS is not going to be 11734c8158e3SMax Reitz * deleted but will only detach all of its children. 11744c8158e3SMax Reitz */ 1175ebd31837SKevin Wolf static void do_test_delete_by_drain(bool detach_instead_of_delete, 1176ebd31837SKevin Wolf enum drain_type drain_type) 11774c8158e3SMax Reitz { 11784c8158e3SMax Reitz BlockBackend *blk; 11794c8158e3SMax Reitz BlockDriverState *bs, *child_bs, *null_bs; 11804c8158e3SMax Reitz BDRVTestTopState *tts; 11814c8158e3SMax Reitz TestCoDeleteByDrainData dbdd; 11824c8158e3SMax Reitz Coroutine *co; 11834c8158e3SMax Reitz 11844c8158e3SMax Reitz bs = bdrv_new_open_driver(&bdrv_test_top_driver, "top", BDRV_O_RDWR, 11854c8158e3SMax Reitz &error_abort); 11864c8158e3SMax Reitz bs->total_sectors = 65536 >> BDRV_SECTOR_BITS; 11874c8158e3SMax Reitz tts = bs->opaque; 11884c8158e3SMax Reitz 11894c8158e3SMax Reitz null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 11904c8158e3SMax Reitz &error_abort); 1191a16be3cdSMax Reitz bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, 1192a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 11934c8158e3SMax Reitz 11944c8158e3SMax Reitz /* This child will be the one to pass to requests through to, and 11954c8158e3SMax Reitz * it will stall until a drain occurs */ 11964c8158e3SMax Reitz child_bs = bdrv_new_open_driver(&bdrv_test, "child", BDRV_O_RDWR, 11974c8158e3SMax Reitz &error_abort); 11984c8158e3SMax Reitz child_bs->total_sectors = 65536 >> BDRV_SECTOR_BITS; 11994c8158e3SMax Reitz /* Takes our reference to child_bs */ 1200a16be3cdSMax Reitz tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child", 1201a16be3cdSMax Reitz &child_of_bds, 1202a16be3cdSMax Reitz BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY, 1203a16be3cdSMax Reitz &error_abort); 12044c8158e3SMax Reitz 12054c8158e3SMax Reitz /* This child is just there to be deleted 12064c8158e3SMax Reitz * (for detach_instead_of_delete == true) */ 12074c8158e3SMax Reitz null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 12084c8158e3SMax Reitz &error_abort); 1209a16be3cdSMax Reitz bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, BDRV_CHILD_DATA, 1210a16be3cdSMax Reitz &error_abort); 12114c8158e3SMax Reitz 1212d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 12134c8158e3SMax Reitz blk_insert_bs(blk, bs, &error_abort); 12144c8158e3SMax Reitz 12154c8158e3SMax Reitz /* Referenced by blk now */ 12164c8158e3SMax Reitz bdrv_unref(bs); 12174c8158e3SMax Reitz 12184c8158e3SMax Reitz g_assert_cmpint(bs->refcnt, ==, 1); 12194c8158e3SMax Reitz g_assert_cmpint(child_bs->refcnt, ==, 1); 12204c8158e3SMax Reitz g_assert_cmpint(null_bs->refcnt, ==, 1); 12214c8158e3SMax Reitz 12224c8158e3SMax Reitz 12234c8158e3SMax Reitz dbdd = (TestCoDeleteByDrainData){ 12244c8158e3SMax Reitz .blk = blk, 12254c8158e3SMax Reitz .detach_instead_of_delete = detach_instead_of_delete, 12264c8158e3SMax Reitz .done = false, 12274c8158e3SMax Reitz }; 12284c8158e3SMax Reitz co = qemu_coroutine_create(test_co_delete_by_drain, &dbdd); 12294c8158e3SMax Reitz qemu_coroutine_enter(co); 12304c8158e3SMax Reitz 12314c8158e3SMax Reitz /* Drain the child while the read operation is still pending. 12324c8158e3SMax Reitz * This should result in the operation finishing and 12334c8158e3SMax Reitz * test_co_delete_by_drain() resuming. Thus, @bs will be deleted 12344c8158e3SMax Reitz * and the coroutine will exit while this drain operation is still 12354c8158e3SMax Reitz * in progress. */ 1236ebd31837SKevin Wolf switch (drain_type) { 1237ebd31837SKevin Wolf case BDRV_DRAIN: 12384c8158e3SMax Reitz bdrv_ref(child_bs); 12394c8158e3SMax Reitz bdrv_drain(child_bs); 12404c8158e3SMax Reitz bdrv_unref(child_bs); 1241ebd31837SKevin Wolf break; 1242ebd31837SKevin Wolf case BDRV_SUBTREE_DRAIN: 1243ebd31837SKevin Wolf /* Would have to ref/unref bs here for !detach_instead_of_delete, but 1244ebd31837SKevin Wolf * then the whole test becomes pointless because the graph changes 1245ebd31837SKevin Wolf * don't occur during the drain any more. */ 1246ebd31837SKevin Wolf assert(detach_instead_of_delete); 1247ebd31837SKevin Wolf bdrv_subtree_drained_begin(bs); 1248ebd31837SKevin Wolf bdrv_subtree_drained_end(bs); 1249ebd31837SKevin Wolf break; 125019f7a7e5SKevin Wolf case BDRV_DRAIN_ALL: 125119f7a7e5SKevin Wolf bdrv_drain_all_begin(); 125219f7a7e5SKevin Wolf bdrv_drain_all_end(); 125319f7a7e5SKevin Wolf break; 1254ebd31837SKevin Wolf default: 1255ebd31837SKevin Wolf g_assert_not_reached(); 1256ebd31837SKevin Wolf } 12574c8158e3SMax Reitz 12584c8158e3SMax Reitz while (!dbdd.done) { 12594c8158e3SMax Reitz aio_poll(qemu_get_aio_context(), true); 12604c8158e3SMax Reitz } 12614c8158e3SMax Reitz 12624c8158e3SMax Reitz if (detach_instead_of_delete) { 12634c8158e3SMax Reitz /* Here, the reference has not passed over to the coroutine, 12644c8158e3SMax Reitz * so we have to delete the BB ourselves */ 12654c8158e3SMax Reitz blk_unref(blk); 12664c8158e3SMax Reitz } 12674c8158e3SMax Reitz } 12684c8158e3SMax Reitz 12694c8158e3SMax Reitz static void test_delete_by_drain(void) 12704c8158e3SMax Reitz { 1271ebd31837SKevin Wolf do_test_delete_by_drain(false, BDRV_DRAIN); 12724c8158e3SMax Reitz } 12734c8158e3SMax Reitz 127419f7a7e5SKevin Wolf static void test_detach_by_drain_all(void) 127519f7a7e5SKevin Wolf { 127619f7a7e5SKevin Wolf do_test_delete_by_drain(true, BDRV_DRAIN_ALL); 127719f7a7e5SKevin Wolf } 127819f7a7e5SKevin Wolf 12794c8158e3SMax Reitz static void test_detach_by_drain(void) 12804c8158e3SMax Reitz { 1281ebd31837SKevin Wolf do_test_delete_by_drain(true, BDRV_DRAIN); 1282ebd31837SKevin Wolf } 1283ebd31837SKevin Wolf 1284ebd31837SKevin Wolf static void test_detach_by_drain_subtree(void) 1285ebd31837SKevin Wolf { 1286ebd31837SKevin Wolf do_test_delete_by_drain(true, BDRV_SUBTREE_DRAIN); 12874c8158e3SMax Reitz } 12884c8158e3SMax Reitz 12894c8158e3SMax Reitz 1290231281abSKevin Wolf struct detach_by_parent_data { 1291231281abSKevin Wolf BlockDriverState *parent_b; 1292231281abSKevin Wolf BdrvChild *child_b; 1293231281abSKevin Wolf BlockDriverState *c; 1294231281abSKevin Wolf BdrvChild *child_c; 129557320ca9SKevin Wolf bool by_parent_cb; 1296231281abSKevin Wolf }; 129757320ca9SKevin Wolf static struct detach_by_parent_data detach_by_parent_data; 1298231281abSKevin Wolf 129957320ca9SKevin Wolf static void detach_indirect_bh(void *opaque) 1300231281abSKevin Wolf { 1301231281abSKevin Wolf struct detach_by_parent_data *data = opaque; 1302231281abSKevin Wolf 1303231281abSKevin Wolf bdrv_unref_child(data->parent_b, data->child_b); 1304231281abSKevin Wolf 1305231281abSKevin Wolf bdrv_ref(data->c); 1306231281abSKevin Wolf data->child_c = bdrv_attach_child(data->parent_b, data->c, "PB-C", 1307a16be3cdSMax Reitz &child_of_bds, BDRV_CHILD_DATA, 1308a16be3cdSMax Reitz &error_abort); 1309231281abSKevin Wolf } 1310231281abSKevin Wolf 131157320ca9SKevin Wolf static void detach_by_parent_aio_cb(void *opaque, int ret) 131257320ca9SKevin Wolf { 131357320ca9SKevin Wolf struct detach_by_parent_data *data = &detach_by_parent_data; 131457320ca9SKevin Wolf 131557320ca9SKevin Wolf g_assert_cmpint(ret, ==, 0); 131657320ca9SKevin Wolf if (data->by_parent_cb) { 131757320ca9SKevin Wolf detach_indirect_bh(data); 131857320ca9SKevin Wolf } 131957320ca9SKevin Wolf } 132057320ca9SKevin Wolf 132157320ca9SKevin Wolf static void detach_by_driver_cb_drained_begin(BdrvChild *child) 132257320ca9SKevin Wolf { 132357320ca9SKevin Wolf aio_bh_schedule_oneshot(qemu_get_current_aio_context(), 132457320ca9SKevin Wolf detach_indirect_bh, &detach_by_parent_data); 1325a16be3cdSMax Reitz child_of_bds.drained_begin(child); 132657320ca9SKevin Wolf } 132757320ca9SKevin Wolf 1328bd86fb99SMax Reitz static BdrvChildClass detach_by_driver_cb_class; 132957320ca9SKevin Wolf 1330231281abSKevin Wolf /* 1331231281abSKevin Wolf * Initial graph: 1332231281abSKevin Wolf * 1333231281abSKevin Wolf * PA PB 1334231281abSKevin Wolf * \ / \ 1335231281abSKevin Wolf * A B C 1336231281abSKevin Wolf * 133757320ca9SKevin Wolf * by_parent_cb == true: Test that parent callbacks don't poll 133857320ca9SKevin Wolf * 133957320ca9SKevin Wolf * PA has a pending write request whose callback changes the child nodes of 134057320ca9SKevin Wolf * PB: It removes B and adds C instead. The subtree of PB is drained, which 134157320ca9SKevin Wolf * will indirectly drain the write request, too. 134257320ca9SKevin Wolf * 134357320ca9SKevin Wolf * by_parent_cb == false: Test that bdrv_drain_invoke() doesn't poll 134457320ca9SKevin Wolf * 1345bd86fb99SMax Reitz * PA's BdrvChildClass has a .drained_begin callback that schedules a BH 134657320ca9SKevin Wolf * that does the same graph change. If bdrv_drain_invoke() calls it, the 134757320ca9SKevin Wolf * state is messed up, but if it is only polled in the single 134857320ca9SKevin Wolf * BDRV_POLL_WHILE() at the end of the drain, this should work fine. 1349231281abSKevin Wolf */ 135057320ca9SKevin Wolf static void test_detach_indirect(bool by_parent_cb) 1351231281abSKevin Wolf { 1352231281abSKevin Wolf BlockBackend *blk; 1353231281abSKevin Wolf BlockDriverState *parent_a, *parent_b, *a, *b, *c; 1354231281abSKevin Wolf BdrvChild *child_a, *child_b; 1355231281abSKevin Wolf BlockAIOCB *acb; 1356231281abSKevin Wolf 1357405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0); 1358231281abSKevin Wolf 135957320ca9SKevin Wolf if (!by_parent_cb) { 1360a16be3cdSMax Reitz detach_by_driver_cb_class = child_of_bds; 1361bd86fb99SMax Reitz detach_by_driver_cb_class.drained_begin = 136257320ca9SKevin Wolf detach_by_driver_cb_drained_begin; 136357320ca9SKevin Wolf } 136457320ca9SKevin Wolf 1365231281abSKevin Wolf /* Create all involved nodes */ 1366231281abSKevin Wolf parent_a = bdrv_new_open_driver(&bdrv_test, "parent-a", BDRV_O_RDWR, 1367231281abSKevin Wolf &error_abort); 1368231281abSKevin Wolf parent_b = bdrv_new_open_driver(&bdrv_test, "parent-b", 0, 1369231281abSKevin Wolf &error_abort); 1370231281abSKevin Wolf 1371231281abSKevin Wolf a = bdrv_new_open_driver(&bdrv_test, "a", BDRV_O_RDWR, &error_abort); 1372231281abSKevin Wolf b = bdrv_new_open_driver(&bdrv_test, "b", BDRV_O_RDWR, &error_abort); 1373231281abSKevin Wolf c = bdrv_new_open_driver(&bdrv_test, "c", BDRV_O_RDWR, &error_abort); 1374231281abSKevin Wolf 1375231281abSKevin Wolf /* blk is a BB for parent-a */ 1376d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 1377231281abSKevin Wolf blk_insert_bs(blk, parent_a, &error_abort); 1378231281abSKevin Wolf bdrv_unref(parent_a); 1379231281abSKevin Wolf 138057320ca9SKevin Wolf /* If we want to get bdrv_drain_invoke() to call aio_poll(), the driver 138157320ca9SKevin Wolf * callback must not return immediately. */ 138257320ca9SKevin Wolf if (!by_parent_cb) { 138357320ca9SKevin Wolf BDRVTestState *s = parent_a->opaque; 138457320ca9SKevin Wolf s->sleep_in_drain_begin = true; 138557320ca9SKevin Wolf } 138657320ca9SKevin Wolf 1387231281abSKevin Wolf /* Set child relationships */ 1388231281abSKevin Wolf bdrv_ref(b); 1389231281abSKevin Wolf bdrv_ref(a); 1390a16be3cdSMax Reitz child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_of_bds, 1391a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 139225191e5fSMax Reitz child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_of_bds, 139325191e5fSMax Reitz BDRV_CHILD_COW, &error_abort); 1394231281abSKevin Wolf 1395231281abSKevin Wolf bdrv_ref(a); 139657320ca9SKevin Wolf bdrv_attach_child(parent_a, a, "PA-A", 1397a16be3cdSMax Reitz by_parent_cb ? &child_of_bds : &detach_by_driver_cb_class, 1398a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 1399231281abSKevin Wolf 1400231281abSKevin Wolf g_assert_cmpint(parent_a->refcnt, ==, 1); 1401231281abSKevin Wolf g_assert_cmpint(parent_b->refcnt, ==, 1); 1402231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 3); 1403231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 2); 1404231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 1); 1405231281abSKevin Wolf 1406231281abSKevin Wolf g_assert(QLIST_FIRST(&parent_b->children) == child_a); 1407231281abSKevin Wolf g_assert(QLIST_NEXT(child_a, next) == child_b); 1408231281abSKevin Wolf g_assert(QLIST_NEXT(child_b, next) == NULL); 1409231281abSKevin Wolf 1410231281abSKevin Wolf /* Start the evil write request */ 141157320ca9SKevin Wolf detach_by_parent_data = (struct detach_by_parent_data) { 1412231281abSKevin Wolf .parent_b = parent_b, 1413231281abSKevin Wolf .child_b = child_b, 1414231281abSKevin Wolf .c = c, 141557320ca9SKevin Wolf .by_parent_cb = by_parent_cb, 1416231281abSKevin Wolf }; 141757320ca9SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, detach_by_parent_aio_cb, NULL); 1418231281abSKevin Wolf g_assert(acb != NULL); 1419231281abSKevin Wolf 1420231281abSKevin Wolf /* Drain and check the expected result */ 1421231281abSKevin Wolf bdrv_subtree_drained_begin(parent_b); 1422231281abSKevin Wolf 142357320ca9SKevin Wolf g_assert(detach_by_parent_data.child_c != NULL); 1424231281abSKevin Wolf 1425231281abSKevin Wolf g_assert_cmpint(parent_a->refcnt, ==, 1); 1426231281abSKevin Wolf g_assert_cmpint(parent_b->refcnt, ==, 1); 1427231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 3); 1428231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 1); 1429231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 2); 1430231281abSKevin Wolf 143157320ca9SKevin Wolf g_assert(QLIST_FIRST(&parent_b->children) == detach_by_parent_data.child_c); 143257320ca9SKevin Wolf g_assert(QLIST_NEXT(detach_by_parent_data.child_c, next) == child_a); 1433231281abSKevin Wolf g_assert(QLIST_NEXT(child_a, next) == NULL); 1434231281abSKevin Wolf 1435231281abSKevin Wolf g_assert_cmpint(parent_a->quiesce_counter, ==, 1); 1436231281abSKevin Wolf g_assert_cmpint(parent_b->quiesce_counter, ==, 1); 1437231281abSKevin Wolf g_assert_cmpint(a->quiesce_counter, ==, 1); 1438231281abSKevin Wolf g_assert_cmpint(b->quiesce_counter, ==, 0); 1439231281abSKevin Wolf g_assert_cmpint(c->quiesce_counter, ==, 1); 1440231281abSKevin Wolf 1441231281abSKevin Wolf bdrv_subtree_drained_end(parent_b); 1442231281abSKevin Wolf 1443231281abSKevin Wolf bdrv_unref(parent_b); 1444231281abSKevin Wolf blk_unref(blk); 1445231281abSKevin Wolf 1446231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 1); 1447231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 1); 1448231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 1); 1449231281abSKevin Wolf bdrv_unref(a); 1450231281abSKevin Wolf bdrv_unref(b); 1451231281abSKevin Wolf bdrv_unref(c); 1452231281abSKevin Wolf } 1453231281abSKevin Wolf 145457320ca9SKevin Wolf static void test_detach_by_parent_cb(void) 145557320ca9SKevin Wolf { 145657320ca9SKevin Wolf test_detach_indirect(true); 145757320ca9SKevin Wolf } 145857320ca9SKevin Wolf 145957320ca9SKevin Wolf static void test_detach_by_driver_cb(void) 146057320ca9SKevin Wolf { 146157320ca9SKevin Wolf test_detach_indirect(false); 146257320ca9SKevin Wolf } 1463231281abSKevin Wolf 1464b994c5bcSKevin Wolf static void test_append_to_drained(void) 1465b994c5bcSKevin Wolf { 1466b994c5bcSKevin Wolf BlockBackend *blk; 1467b994c5bcSKevin Wolf BlockDriverState *base, *overlay; 1468b994c5bcSKevin Wolf BDRVTestState *base_s, *overlay_s; 1469b994c5bcSKevin Wolf 1470d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 1471b994c5bcSKevin Wolf base = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort); 1472b994c5bcSKevin Wolf base_s = base->opaque; 1473b994c5bcSKevin Wolf blk_insert_bs(blk, base, &error_abort); 1474b994c5bcSKevin Wolf 1475b994c5bcSKevin Wolf overlay = bdrv_new_open_driver(&bdrv_test, "overlay", BDRV_O_RDWR, 1476b994c5bcSKevin Wolf &error_abort); 1477b994c5bcSKevin Wolf overlay_s = overlay->opaque; 1478b994c5bcSKevin Wolf 1479b994c5bcSKevin Wolf do_drain_begin(BDRV_DRAIN, base); 1480b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 1); 1481b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 1); 1482b994c5bcSKevin Wolf g_assert_cmpint(base->in_flight, ==, 0); 1483b994c5bcSKevin Wolf 1484b994c5bcSKevin Wolf bdrv_append(overlay, base, &error_abort); 1485b994c5bcSKevin Wolf g_assert_cmpint(base->in_flight, ==, 0); 1486b994c5bcSKevin Wolf g_assert_cmpint(overlay->in_flight, ==, 0); 1487b994c5bcSKevin Wolf 1488b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 1); 1489b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 1); 1490b994c5bcSKevin Wolf g_assert_cmpint(overlay->quiesce_counter, ==, 1); 1491b994c5bcSKevin Wolf g_assert_cmpint(overlay_s->drain_count, ==, 1); 1492b994c5bcSKevin Wolf 1493b994c5bcSKevin Wolf do_drain_end(BDRV_DRAIN, base); 1494b994c5bcSKevin Wolf 1495b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 0); 1496b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 0); 1497b994c5bcSKevin Wolf g_assert_cmpint(overlay->quiesce_counter, ==, 0); 1498b994c5bcSKevin Wolf g_assert_cmpint(overlay_s->drain_count, ==, 0); 1499b994c5bcSKevin Wolf 1500ae9d4417SVladimir Sementsov-Ogievskiy bdrv_unref(overlay); 1501b994c5bcSKevin Wolf bdrv_unref(base); 1502b994c5bcSKevin Wolf blk_unref(blk); 1503b994c5bcSKevin Wolf } 1504b994c5bcSKevin Wolf 1505247d2737SKevin Wolf static void test_set_aio_context(void) 1506247d2737SKevin Wolf { 1507247d2737SKevin Wolf BlockDriverState *bs; 1508247d2737SKevin Wolf IOThread *a = iothread_new(); 1509247d2737SKevin Wolf IOThread *b = iothread_new(); 1510247d2737SKevin Wolf AioContext *ctx_a = iothread_get_aio_context(a); 1511247d2737SKevin Wolf AioContext *ctx_b = iothread_get_aio_context(b); 1512247d2737SKevin Wolf 1513247d2737SKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 1514247d2737SKevin Wolf &error_abort); 1515247d2737SKevin Wolf 1516247d2737SKevin Wolf bdrv_drained_begin(bs); 151726bf15e4SKevin Wolf bdrv_try_set_aio_context(bs, ctx_a, &error_abort); 1518247d2737SKevin Wolf 1519247d2737SKevin Wolf aio_context_acquire(ctx_a); 1520247d2737SKevin Wolf bdrv_drained_end(bs); 1521247d2737SKevin Wolf 1522247d2737SKevin Wolf bdrv_drained_begin(bs); 152326bf15e4SKevin Wolf bdrv_try_set_aio_context(bs, ctx_b, &error_abort); 1524247d2737SKevin Wolf aio_context_release(ctx_a); 1525247d2737SKevin Wolf aio_context_acquire(ctx_b); 152626bf15e4SKevin Wolf bdrv_try_set_aio_context(bs, qemu_get_aio_context(), &error_abort); 1527247d2737SKevin Wolf aio_context_release(ctx_b); 1528247d2737SKevin Wolf bdrv_drained_end(bs); 1529247d2737SKevin Wolf 1530247d2737SKevin Wolf bdrv_unref(bs); 1531247d2737SKevin Wolf iothread_join(a); 1532247d2737SKevin Wolf iothread_join(b); 1533247d2737SKevin Wolf } 1534247d2737SKevin Wolf 15358e442810SMax Reitz 15368e442810SMax Reitz typedef struct TestDropBackingBlockJob { 15378e442810SMax Reitz BlockJob common; 15388e442810SMax Reitz bool should_complete; 15398e442810SMax Reitz bool *did_complete; 15402afdc790SMax Reitz BlockDriverState *detach_also; 15418e442810SMax Reitz } TestDropBackingBlockJob; 15428e442810SMax Reitz 15438e442810SMax Reitz static int coroutine_fn test_drop_backing_job_run(Job *job, Error **errp) 15448e442810SMax Reitz { 15458e442810SMax Reitz TestDropBackingBlockJob *s = 15468e442810SMax Reitz container_of(job, TestDropBackingBlockJob, common.job); 15478e442810SMax Reitz 15488e442810SMax Reitz while (!s->should_complete) { 15498e442810SMax Reitz job_sleep_ns(job, 0); 15508e442810SMax Reitz } 15518e442810SMax Reitz 15528e442810SMax Reitz return 0; 15538e442810SMax Reitz } 15548e442810SMax Reitz 15558e442810SMax Reitz static void test_drop_backing_job_commit(Job *job) 15568e442810SMax Reitz { 15578e442810SMax Reitz TestDropBackingBlockJob *s = 15588e442810SMax Reitz container_of(job, TestDropBackingBlockJob, common.job); 15598e442810SMax Reitz 15608e442810SMax Reitz bdrv_set_backing_hd(blk_bs(s->common.blk), NULL, &error_abort); 15612afdc790SMax Reitz bdrv_set_backing_hd(s->detach_also, NULL, &error_abort); 15628e442810SMax Reitz 15638e442810SMax Reitz *s->did_complete = true; 15648e442810SMax Reitz } 15658e442810SMax Reitz 15668e442810SMax Reitz static const BlockJobDriver test_drop_backing_job_driver = { 15678e442810SMax Reitz .job_driver = { 15688e442810SMax Reitz .instance_size = sizeof(TestDropBackingBlockJob), 15698e442810SMax Reitz .free = block_job_free, 15708e442810SMax Reitz .user_resume = block_job_user_resume, 15718e442810SMax Reitz .run = test_drop_backing_job_run, 15728e442810SMax Reitz .commit = test_drop_backing_job_commit, 15738e442810SMax Reitz } 15748e442810SMax Reitz }; 15758e442810SMax Reitz 15768e442810SMax Reitz /** 15778e442810SMax Reitz * Creates a child node with three parent nodes on it, and then runs a 15788e442810SMax Reitz * block job on the final one, parent-node-2. 15798e442810SMax Reitz * 15808e442810SMax Reitz * The job is then asked to complete before a section where the child 15818e442810SMax Reitz * is drained. 15828e442810SMax Reitz * 15838e442810SMax Reitz * Ending this section will undrain the child's parents, first 15848e442810SMax Reitz * parent-node-2, then parent-node-1, then parent-node-0 -- the parent 15858e442810SMax Reitz * list is in reverse order of how they were added. Ending the drain 15868e442810SMax Reitz * on parent-node-2 will resume the job, thus completing it and 15878e442810SMax Reitz * scheduling job_exit(). 15888e442810SMax Reitz * 15898e442810SMax Reitz * Ending the drain on parent-node-1 will poll the AioContext, which 15908e442810SMax Reitz * lets job_exit() and thus test_drop_backing_job_commit() run. That 15912afdc790SMax Reitz * function first removes the child as parent-node-2's backing file. 15928e442810SMax Reitz * 15938e442810SMax Reitz * In old (and buggy) implementations, there are two problems with 15948e442810SMax Reitz * that: 15958e442810SMax Reitz * (A) bdrv_drain_invoke() polls for every node that leaves the 15968e442810SMax Reitz * drained section. This means that job_exit() is scheduled 15978e442810SMax Reitz * before the child has left the drained section. Its 15988e442810SMax Reitz * quiesce_counter is therefore still 1 when it is removed from 15998e442810SMax Reitz * parent-node-2. 16008e442810SMax Reitz * 16018e442810SMax Reitz * (B) bdrv_replace_child_noperm() calls drained_end() on the old 16028e442810SMax Reitz * child's parents as many times as the child is quiesced. This 16038e442810SMax Reitz * means it will call drained_end() on parent-node-2 once. 16048e442810SMax Reitz * Because parent-node-2 is no longer quiesced at this point, this 16058e442810SMax Reitz * will fail. 16068e442810SMax Reitz * 16078e442810SMax Reitz * bdrv_replace_child_noperm() therefore must call drained_end() on 16088e442810SMax Reitz * the parent only if it really is still drained because the child is 16098e442810SMax Reitz * drained. 16102afdc790SMax Reitz * 16112afdc790SMax Reitz * If removing child from parent-node-2 was successful (as it should 16122afdc790SMax Reitz * be), test_drop_backing_job_commit() will then also remove the child 16132afdc790SMax Reitz * from parent-node-0. 16142afdc790SMax Reitz * 16152afdc790SMax Reitz * With an old version of our drain infrastructure ((A) above), that 16162afdc790SMax Reitz * resulted in the following flow: 16172afdc790SMax Reitz * 16182afdc790SMax Reitz * 1. child attempts to leave its drained section. The call recurses 16192afdc790SMax Reitz * to its parents. 16202afdc790SMax Reitz * 16212afdc790SMax Reitz * 2. parent-node-2 leaves the drained section. Polling in 16222afdc790SMax Reitz * bdrv_drain_invoke() will schedule job_exit(). 16232afdc790SMax Reitz * 16242afdc790SMax Reitz * 3. parent-node-1 leaves the drained section. Polling in 16252afdc790SMax Reitz * bdrv_drain_invoke() will run job_exit(), thus disconnecting 16262afdc790SMax Reitz * parent-node-0 from the child node. 16272afdc790SMax Reitz * 16282afdc790SMax Reitz * 4. bdrv_parent_drained_end() uses a QLIST_FOREACH_SAFE() loop to 16292afdc790SMax Reitz * iterate over the parents. Thus, it now accesses the BdrvChild 16302afdc790SMax Reitz * object that used to connect parent-node-0 and the child node. 16312afdc790SMax Reitz * However, that object no longer exists, so it accesses a dangling 16322afdc790SMax Reitz * pointer. 16332afdc790SMax Reitz * 16342afdc790SMax Reitz * The solution is to only poll once when running a bdrv_drained_end() 16352afdc790SMax Reitz * operation, specifically at the end when all drained_end() 16362afdc790SMax Reitz * operations for all involved nodes have been scheduled. 16372afdc790SMax Reitz * Note that this also solves (A) above, thus hiding (B). 16388e442810SMax Reitz */ 16398e442810SMax Reitz static void test_blockjob_commit_by_drained_end(void) 16408e442810SMax Reitz { 16418e442810SMax Reitz BlockDriverState *bs_child, *bs_parents[3]; 16428e442810SMax Reitz TestDropBackingBlockJob *job; 16438e442810SMax Reitz bool job_has_completed = false; 16448e442810SMax Reitz int i; 16458e442810SMax Reitz 16468e442810SMax Reitz bs_child = bdrv_new_open_driver(&bdrv_test, "child-node", BDRV_O_RDWR, 16478e442810SMax Reitz &error_abort); 16488e442810SMax Reitz 16498e442810SMax Reitz for (i = 0; i < 3; i++) { 16508e442810SMax Reitz char name[32]; 16518e442810SMax Reitz snprintf(name, sizeof(name), "parent-node-%i", i); 16528e442810SMax Reitz bs_parents[i] = bdrv_new_open_driver(&bdrv_test, name, BDRV_O_RDWR, 16538e442810SMax Reitz &error_abort); 16548e442810SMax Reitz bdrv_set_backing_hd(bs_parents[i], bs_child, &error_abort); 16558e442810SMax Reitz } 16568e442810SMax Reitz 16578e442810SMax Reitz job = block_job_create("job", &test_drop_backing_job_driver, NULL, 16588e442810SMax Reitz bs_parents[2], 0, BLK_PERM_ALL, 0, 0, NULL, NULL, 16598e442810SMax Reitz &error_abort); 16608e442810SMax Reitz 16612afdc790SMax Reitz job->detach_also = bs_parents[0]; 16628e442810SMax Reitz job->did_complete = &job_has_completed; 16638e442810SMax Reitz 16648e442810SMax Reitz job_start(&job->common.job); 16658e442810SMax Reitz 16668e442810SMax Reitz job->should_complete = true; 16678e442810SMax Reitz bdrv_drained_begin(bs_child); 16688e442810SMax Reitz g_assert(!job_has_completed); 16698e442810SMax Reitz bdrv_drained_end(bs_child); 16708e442810SMax Reitz g_assert(job_has_completed); 16718e442810SMax Reitz 16728e442810SMax Reitz bdrv_unref(bs_parents[0]); 16738e442810SMax Reitz bdrv_unref(bs_parents[1]); 16748e442810SMax Reitz bdrv_unref(bs_parents[2]); 16758e442810SMax Reitz bdrv_unref(bs_child); 16768e442810SMax Reitz } 16778e442810SMax Reitz 16789746b35cSMax Reitz 16799746b35cSMax Reitz typedef struct TestSimpleBlockJob { 16809746b35cSMax Reitz BlockJob common; 16819746b35cSMax Reitz bool should_complete; 16829746b35cSMax Reitz bool *did_complete; 16839746b35cSMax Reitz } TestSimpleBlockJob; 16849746b35cSMax Reitz 16859746b35cSMax Reitz static int coroutine_fn test_simple_job_run(Job *job, Error **errp) 16869746b35cSMax Reitz { 16879746b35cSMax Reitz TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job); 16889746b35cSMax Reitz 16899746b35cSMax Reitz while (!s->should_complete) { 16909746b35cSMax Reitz job_sleep_ns(job, 0); 16919746b35cSMax Reitz } 16929746b35cSMax Reitz 16939746b35cSMax Reitz return 0; 16949746b35cSMax Reitz } 16959746b35cSMax Reitz 16969746b35cSMax Reitz static void test_simple_job_clean(Job *job) 16979746b35cSMax Reitz { 16989746b35cSMax Reitz TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job); 16999746b35cSMax Reitz *s->did_complete = true; 17009746b35cSMax Reitz } 17019746b35cSMax Reitz 17029746b35cSMax Reitz static const BlockJobDriver test_simple_job_driver = { 17039746b35cSMax Reitz .job_driver = { 17049746b35cSMax Reitz .instance_size = sizeof(TestSimpleBlockJob), 17059746b35cSMax Reitz .free = block_job_free, 17069746b35cSMax Reitz .user_resume = block_job_user_resume, 17079746b35cSMax Reitz .run = test_simple_job_run, 17089746b35cSMax Reitz .clean = test_simple_job_clean, 17099746b35cSMax Reitz }, 17109746b35cSMax Reitz }; 17119746b35cSMax Reitz 17129746b35cSMax Reitz static int drop_intermediate_poll_update_filename(BdrvChild *child, 17139746b35cSMax Reitz BlockDriverState *new_base, 17149746b35cSMax Reitz const char *filename, 17159746b35cSMax Reitz Error **errp) 17169746b35cSMax Reitz { 17179746b35cSMax Reitz /* 17189746b35cSMax Reitz * We are free to poll here, which may change the block graph, if 17199746b35cSMax Reitz * it is not drained. 17209746b35cSMax Reitz */ 17219746b35cSMax Reitz 17229746b35cSMax Reitz /* If the job is not drained: Complete it, schedule job_exit() */ 17239746b35cSMax Reitz aio_poll(qemu_get_current_aio_context(), false); 17249746b35cSMax Reitz /* If the job is not drained: Run job_exit(), finish the job */ 17259746b35cSMax Reitz aio_poll(qemu_get_current_aio_context(), false); 17269746b35cSMax Reitz 17279746b35cSMax Reitz return 0; 17289746b35cSMax Reitz } 17299746b35cSMax Reitz 17309746b35cSMax Reitz /** 17319746b35cSMax Reitz * Test a poll in the midst of bdrv_drop_intermediate(). 17329746b35cSMax Reitz * 1733bd86fb99SMax Reitz * bdrv_drop_intermediate() calls BdrvChildClass.update_filename(), 17349746b35cSMax Reitz * which can yield or poll. This may lead to graph changes, unless 17359746b35cSMax Reitz * the whole subtree in question is drained. 17369746b35cSMax Reitz * 17379746b35cSMax Reitz * We test this on the following graph: 17389746b35cSMax Reitz * 17399746b35cSMax Reitz * Job 17409746b35cSMax Reitz * 17419746b35cSMax Reitz * | 17429746b35cSMax Reitz * job-node 17439746b35cSMax Reitz * | 17449746b35cSMax Reitz * v 17459746b35cSMax Reitz * 17469746b35cSMax Reitz * job-node 17479746b35cSMax Reitz * 17489746b35cSMax Reitz * | 17499746b35cSMax Reitz * backing 17509746b35cSMax Reitz * | 17519746b35cSMax Reitz * v 17529746b35cSMax Reitz * 17539746b35cSMax Reitz * node-2 --chain--> node-1 --chain--> node-0 17549746b35cSMax Reitz * 17559746b35cSMax Reitz * We drop node-1 with bdrv_drop_intermediate(top=node-1, base=node-0). 17569746b35cSMax Reitz * 17579746b35cSMax Reitz * This first updates node-2's backing filename by invoking 17589746b35cSMax Reitz * drop_intermediate_poll_update_filename(), which polls twice. This 17599746b35cSMax Reitz * causes the job to finish, which in turns causes the job-node to be 17609746b35cSMax Reitz * deleted. 17619746b35cSMax Reitz * 17629746b35cSMax Reitz * bdrv_drop_intermediate() uses a QLIST_FOREACH_SAFE() loop, so it 17639746b35cSMax Reitz * already has a pointer to the BdrvChild edge between job-node and 17649746b35cSMax Reitz * node-1. When it tries to handle that edge, we probably get a 17659746b35cSMax Reitz * segmentation fault because the object no longer exists. 17669746b35cSMax Reitz * 17679746b35cSMax Reitz * 17689746b35cSMax Reitz * The solution is for bdrv_drop_intermediate() to drain top's 17699746b35cSMax Reitz * subtree. This prevents graph changes from happening just because 1770bd86fb99SMax Reitz * BdrvChildClass.update_filename() yields or polls. Thus, the block 17719746b35cSMax Reitz * job is paused during that drained section and must finish before or 17729746b35cSMax Reitz * after. 17739746b35cSMax Reitz * 17749746b35cSMax Reitz * (In addition, bdrv_replace_child() must keep the job paused.) 17759746b35cSMax Reitz */ 17769746b35cSMax Reitz static void test_drop_intermediate_poll(void) 17779746b35cSMax Reitz { 1778bd86fb99SMax Reitz static BdrvChildClass chain_child_class; 17799746b35cSMax Reitz BlockDriverState *chain[3]; 17809746b35cSMax Reitz TestSimpleBlockJob *job; 17819746b35cSMax Reitz BlockDriverState *job_node; 17829746b35cSMax Reitz bool job_has_completed = false; 17839746b35cSMax Reitz int i; 17849746b35cSMax Reitz int ret; 17859746b35cSMax Reitz 178625191e5fSMax Reitz chain_child_class = child_of_bds; 1787bd86fb99SMax Reitz chain_child_class.update_filename = drop_intermediate_poll_update_filename; 17889746b35cSMax Reitz 17899746b35cSMax Reitz for (i = 0; i < 3; i++) { 17909746b35cSMax Reitz char name[32]; 17919746b35cSMax Reitz snprintf(name, 32, "node-%i", i); 17929746b35cSMax Reitz 17939746b35cSMax Reitz chain[i] = bdrv_new_open_driver(&bdrv_test, name, 0, &error_abort); 17949746b35cSMax Reitz } 17959746b35cSMax Reitz 17969746b35cSMax Reitz job_node = bdrv_new_open_driver(&bdrv_test, "job-node", BDRV_O_RDWR, 17979746b35cSMax Reitz &error_abort); 17989746b35cSMax Reitz bdrv_set_backing_hd(job_node, chain[1], &error_abort); 17999746b35cSMax Reitz 18009746b35cSMax Reitz /* 18019746b35cSMax Reitz * Establish the chain last, so the chain links are the first 18029746b35cSMax Reitz * elements in the BDS.parents lists 18039746b35cSMax Reitz */ 18049746b35cSMax Reitz for (i = 0; i < 3; i++) { 18059746b35cSMax Reitz if (i) { 18069746b35cSMax Reitz /* Takes the reference to chain[i - 1] */ 18079746b35cSMax Reitz chain[i]->backing = bdrv_attach_child(chain[i], chain[i - 1], 1808bd86fb99SMax Reitz "chain", &chain_child_class, 180925191e5fSMax Reitz BDRV_CHILD_COW, &error_abort); 18109746b35cSMax Reitz } 18119746b35cSMax Reitz } 18129746b35cSMax Reitz 18139746b35cSMax Reitz job = block_job_create("job", &test_simple_job_driver, NULL, job_node, 18149746b35cSMax Reitz 0, BLK_PERM_ALL, 0, 0, NULL, NULL, &error_abort); 18159746b35cSMax Reitz 18169746b35cSMax Reitz /* The job has a reference now */ 18179746b35cSMax Reitz bdrv_unref(job_node); 18189746b35cSMax Reitz 18199746b35cSMax Reitz job->did_complete = &job_has_completed; 18209746b35cSMax Reitz 18219746b35cSMax Reitz job_start(&job->common.job); 18229746b35cSMax Reitz job->should_complete = true; 18239746b35cSMax Reitz 18249746b35cSMax Reitz g_assert(!job_has_completed); 18259746b35cSMax Reitz ret = bdrv_drop_intermediate(chain[1], chain[0], NULL); 18269746b35cSMax Reitz g_assert(ret == 0); 18279746b35cSMax Reitz g_assert(job_has_completed); 18289746b35cSMax Reitz 18299746b35cSMax Reitz bdrv_unref(chain[2]); 18309746b35cSMax Reitz } 18319746b35cSMax Reitz 18320513f984SMax Reitz 18330513f984SMax Reitz typedef struct BDRVReplaceTestState { 18340513f984SMax Reitz bool was_drained; 18350513f984SMax Reitz bool was_undrained; 18360513f984SMax Reitz bool has_read; 18370513f984SMax Reitz 18380513f984SMax Reitz int drain_count; 18390513f984SMax Reitz 18400513f984SMax Reitz bool yield_before_read; 18410513f984SMax Reitz Coroutine *io_co; 18420513f984SMax Reitz Coroutine *drain_co; 18430513f984SMax Reitz } BDRVReplaceTestState; 18440513f984SMax Reitz 18450513f984SMax Reitz static void bdrv_replace_test_close(BlockDriverState *bs) 18460513f984SMax Reitz { 18470513f984SMax Reitz } 18480513f984SMax Reitz 18490513f984SMax Reitz /** 18500513f984SMax Reitz * If @bs has a backing file: 18510513f984SMax Reitz * Yield if .yield_before_read is true (and wait for drain_begin to 18520513f984SMax Reitz * wake us up). 18530513f984SMax Reitz * Forward the read to bs->backing. Set .has_read to true. 18540513f984SMax Reitz * If drain_begin has woken us, wake it in turn. 18550513f984SMax Reitz * 18560513f984SMax Reitz * Otherwise: 18570513f984SMax Reitz * Set .has_read to true and return success. 18580513f984SMax Reitz */ 18590513f984SMax Reitz static int coroutine_fn bdrv_replace_test_co_preadv(BlockDriverState *bs, 1860*f7ef38ddSVladimir Sementsov-Ogievskiy int64_t offset, 1861*f7ef38ddSVladimir Sementsov-Ogievskiy int64_t bytes, 18620513f984SMax Reitz QEMUIOVector *qiov, 1863*f7ef38ddSVladimir Sementsov-Ogievskiy BdrvRequestFlags flags) 18640513f984SMax Reitz { 18650513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 18660513f984SMax Reitz 18670513f984SMax Reitz if (bs->backing) { 18680513f984SMax Reitz int ret; 18690513f984SMax Reitz 18700513f984SMax Reitz g_assert(!s->drain_count); 18710513f984SMax Reitz 18720513f984SMax Reitz s->io_co = qemu_coroutine_self(); 18730513f984SMax Reitz if (s->yield_before_read) { 18740513f984SMax Reitz s->yield_before_read = false; 18750513f984SMax Reitz qemu_coroutine_yield(); 18760513f984SMax Reitz } 18770513f984SMax Reitz s->io_co = NULL; 18780513f984SMax Reitz 1879fae2681aSVladimir Sementsov-Ogievskiy ret = bdrv_co_preadv(bs->backing, offset, bytes, qiov, 0); 18800513f984SMax Reitz s->has_read = true; 18810513f984SMax Reitz 18820513f984SMax Reitz /* Wake up drain_co if it runs */ 18830513f984SMax Reitz if (s->drain_co) { 18840513f984SMax Reitz aio_co_wake(s->drain_co); 18850513f984SMax Reitz } 18860513f984SMax Reitz 18870513f984SMax Reitz return ret; 18880513f984SMax Reitz } 18890513f984SMax Reitz 18900513f984SMax Reitz s->has_read = true; 18910513f984SMax Reitz return 0; 18920513f984SMax Reitz } 18930513f984SMax Reitz 18940513f984SMax Reitz /** 18950513f984SMax Reitz * If .drain_count is 0, wake up .io_co if there is one; and set 18960513f984SMax Reitz * .was_drained. 18970513f984SMax Reitz * Increment .drain_count. 18980513f984SMax Reitz */ 18990513f984SMax Reitz static void coroutine_fn bdrv_replace_test_co_drain_begin(BlockDriverState *bs) 19000513f984SMax Reitz { 19010513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 19020513f984SMax Reitz 19030513f984SMax Reitz if (!s->drain_count) { 19040513f984SMax Reitz /* Keep waking io_co up until it is done */ 19050513f984SMax Reitz s->drain_co = qemu_coroutine_self(); 19060513f984SMax Reitz while (s->io_co) { 19070513f984SMax Reitz aio_co_wake(s->io_co); 19080513f984SMax Reitz s->io_co = NULL; 19090513f984SMax Reitz qemu_coroutine_yield(); 19100513f984SMax Reitz } 19110513f984SMax Reitz s->drain_co = NULL; 19120513f984SMax Reitz 19130513f984SMax Reitz s->was_drained = true; 19140513f984SMax Reitz } 19150513f984SMax Reitz s->drain_count++; 19160513f984SMax Reitz } 19170513f984SMax Reitz 19180513f984SMax Reitz /** 19190513f984SMax Reitz * Reduce .drain_count, set .was_undrained once it reaches 0. 19200513f984SMax Reitz * If .drain_count reaches 0 and the node has a backing file, issue a 19210513f984SMax Reitz * read request. 19220513f984SMax Reitz */ 19230513f984SMax Reitz static void coroutine_fn bdrv_replace_test_co_drain_end(BlockDriverState *bs) 19240513f984SMax Reitz { 19250513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 19260513f984SMax Reitz 19270513f984SMax Reitz g_assert(s->drain_count > 0); 19280513f984SMax Reitz if (!--s->drain_count) { 19290513f984SMax Reitz int ret; 19300513f984SMax Reitz 19310513f984SMax Reitz s->was_undrained = true; 19320513f984SMax Reitz 19330513f984SMax Reitz if (bs->backing) { 19340513f984SMax Reitz char data; 19350513f984SMax Reitz QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, &data, 1); 19360513f984SMax Reitz 19370513f984SMax Reitz /* Queue a read request post-drain */ 19380513f984SMax Reitz ret = bdrv_replace_test_co_preadv(bs, 0, 1, &qiov, 0); 19390513f984SMax Reitz g_assert(ret >= 0); 19400513f984SMax Reitz } 19410513f984SMax Reitz } 19420513f984SMax Reitz } 19430513f984SMax Reitz 19440513f984SMax Reitz static BlockDriver bdrv_replace_test = { 19450513f984SMax Reitz .format_name = "replace_test", 19460513f984SMax Reitz .instance_size = sizeof(BDRVReplaceTestState), 19470513f984SMax Reitz 19480513f984SMax Reitz .bdrv_close = bdrv_replace_test_close, 19490513f984SMax Reitz .bdrv_co_preadv = bdrv_replace_test_co_preadv, 19500513f984SMax Reitz 19510513f984SMax Reitz .bdrv_co_drain_begin = bdrv_replace_test_co_drain_begin, 19520513f984SMax Reitz .bdrv_co_drain_end = bdrv_replace_test_co_drain_end, 19530513f984SMax Reitz 195469dca43dSMax Reitz .bdrv_child_perm = bdrv_default_perms, 19550513f984SMax Reitz }; 19560513f984SMax Reitz 19570513f984SMax Reitz static void coroutine_fn test_replace_child_mid_drain_read_co(void *opaque) 19580513f984SMax Reitz { 19590513f984SMax Reitz int ret; 19600513f984SMax Reitz char data; 19610513f984SMax Reitz 19620513f984SMax Reitz ret = blk_co_pread(opaque, 0, 1, &data, 0); 19630513f984SMax Reitz g_assert(ret >= 0); 19640513f984SMax Reitz } 19650513f984SMax Reitz 19660513f984SMax Reitz /** 19670513f984SMax Reitz * We test two things: 19680513f984SMax Reitz * (1) bdrv_replace_child_noperm() must not undrain the parent if both 19690513f984SMax Reitz * children are drained. 19700513f984SMax Reitz * (2) bdrv_replace_child_noperm() must never flush I/O requests to a 19710513f984SMax Reitz * drained child. If the old child is drained, it must flush I/O 19720513f984SMax Reitz * requests after the new one has been attached. If the new child 19730513f984SMax Reitz * is drained, it must flush I/O requests before the old one is 19740513f984SMax Reitz * detached. 19750513f984SMax Reitz * 19760513f984SMax Reitz * To do so, we create one parent node and two child nodes; then 19770513f984SMax Reitz * attach one of the children (old_child_bs) to the parent, then 19780513f984SMax Reitz * drain both old_child_bs and new_child_bs according to 19790513f984SMax Reitz * old_drain_count and new_drain_count, respectively, and finally 19800513f984SMax Reitz * we invoke bdrv_replace_node() to replace old_child_bs by 19810513f984SMax Reitz * new_child_bs. 19820513f984SMax Reitz * 19830513f984SMax Reitz * The test block driver we use here (bdrv_replace_test) has a read 19840513f984SMax Reitz * function that: 19850513f984SMax Reitz * - For the parent node, can optionally yield, and then forwards the 19860513f984SMax Reitz * read to bdrv_preadv(), 19870513f984SMax Reitz * - For the child node, just returns immediately. 19880513f984SMax Reitz * 19890513f984SMax Reitz * If the read yields, the drain_begin function will wake it up. 19900513f984SMax Reitz * 19910513f984SMax Reitz * The drain_end function issues a read on the parent once it is fully 19920513f984SMax Reitz * undrained (which simulates requests starting to come in again). 19930513f984SMax Reitz */ 19940513f984SMax Reitz static void do_test_replace_child_mid_drain(int old_drain_count, 19950513f984SMax Reitz int new_drain_count) 19960513f984SMax Reitz { 19970513f984SMax Reitz BlockBackend *parent_blk; 19980513f984SMax Reitz BlockDriverState *parent_bs; 19990513f984SMax Reitz BlockDriverState *old_child_bs, *new_child_bs; 20000513f984SMax Reitz BDRVReplaceTestState *parent_s; 20010513f984SMax Reitz BDRVReplaceTestState *old_child_s, *new_child_s; 20020513f984SMax Reitz Coroutine *io_co; 20030513f984SMax Reitz int i; 20040513f984SMax Reitz 20050513f984SMax Reitz parent_bs = bdrv_new_open_driver(&bdrv_replace_test, "parent", 0, 20060513f984SMax Reitz &error_abort); 20070513f984SMax Reitz parent_s = parent_bs->opaque; 20080513f984SMax Reitz 20090513f984SMax Reitz parent_blk = blk_new(qemu_get_aio_context(), 20100513f984SMax Reitz BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL); 20110513f984SMax Reitz blk_insert_bs(parent_blk, parent_bs, &error_abort); 20120513f984SMax Reitz 20130513f984SMax Reitz old_child_bs = bdrv_new_open_driver(&bdrv_replace_test, "old-child", 0, 20140513f984SMax Reitz &error_abort); 20150513f984SMax Reitz new_child_bs = bdrv_new_open_driver(&bdrv_replace_test, "new-child", 0, 20160513f984SMax Reitz &error_abort); 20170513f984SMax Reitz old_child_s = old_child_bs->opaque; 20180513f984SMax Reitz new_child_s = new_child_bs->opaque; 20190513f984SMax Reitz 20200513f984SMax Reitz /* So that we can read something */ 20210513f984SMax Reitz parent_bs->total_sectors = 1; 20220513f984SMax Reitz old_child_bs->total_sectors = 1; 20230513f984SMax Reitz new_child_bs->total_sectors = 1; 20240513f984SMax Reitz 20250513f984SMax Reitz bdrv_ref(old_child_bs); 20260513f984SMax Reitz parent_bs->backing = bdrv_attach_child(parent_bs, old_child_bs, "child", 202725191e5fSMax Reitz &child_of_bds, BDRV_CHILD_COW, 202825191e5fSMax Reitz &error_abort); 20290513f984SMax Reitz 20300513f984SMax Reitz for (i = 0; i < old_drain_count; i++) { 20310513f984SMax Reitz bdrv_drained_begin(old_child_bs); 20320513f984SMax Reitz } 20330513f984SMax Reitz for (i = 0; i < new_drain_count; i++) { 20340513f984SMax Reitz bdrv_drained_begin(new_child_bs); 20350513f984SMax Reitz } 20360513f984SMax Reitz 20370513f984SMax Reitz if (!old_drain_count) { 20380513f984SMax Reitz /* 20390513f984SMax Reitz * Start a read operation that will yield, so it will not 20400513f984SMax Reitz * complete before the node is drained. 20410513f984SMax Reitz */ 20420513f984SMax Reitz parent_s->yield_before_read = true; 20430513f984SMax Reitz io_co = qemu_coroutine_create(test_replace_child_mid_drain_read_co, 20440513f984SMax Reitz parent_blk); 20450513f984SMax Reitz qemu_coroutine_enter(io_co); 20460513f984SMax Reitz } 20470513f984SMax Reitz 20480513f984SMax Reitz /* If we have started a read operation, it should have yielded */ 20490513f984SMax Reitz g_assert(!parent_s->has_read); 20500513f984SMax Reitz 20510513f984SMax Reitz /* Reset drained status so we can see what bdrv_replace_node() does */ 20520513f984SMax Reitz parent_s->was_drained = false; 20530513f984SMax Reitz parent_s->was_undrained = false; 20540513f984SMax Reitz 20550513f984SMax Reitz g_assert(parent_bs->quiesce_counter == old_drain_count); 20560513f984SMax Reitz bdrv_replace_node(old_child_bs, new_child_bs, &error_abort); 20570513f984SMax Reitz g_assert(parent_bs->quiesce_counter == new_drain_count); 20580513f984SMax Reitz 20590513f984SMax Reitz if (!old_drain_count && !new_drain_count) { 20600513f984SMax Reitz /* 20610513f984SMax Reitz * From undrained to undrained drains and undrains the parent, 20620513f984SMax Reitz * because bdrv_replace_node() contains a drained section for 20630513f984SMax Reitz * @old_child_bs. 20640513f984SMax Reitz */ 20650513f984SMax Reitz g_assert(parent_s->was_drained && parent_s->was_undrained); 20660513f984SMax Reitz } else if (!old_drain_count && new_drain_count) { 20670513f984SMax Reitz /* 20680513f984SMax Reitz * From undrained to drained should drain the parent and keep 20690513f984SMax Reitz * it that way. 20700513f984SMax Reitz */ 20710513f984SMax Reitz g_assert(parent_s->was_drained && !parent_s->was_undrained); 20720513f984SMax Reitz } else if (old_drain_count && !new_drain_count) { 20730513f984SMax Reitz /* 20740513f984SMax Reitz * From drained to undrained should undrain the parent and 20750513f984SMax Reitz * keep it that way. 20760513f984SMax Reitz */ 20770513f984SMax Reitz g_assert(!parent_s->was_drained && parent_s->was_undrained); 20780513f984SMax Reitz } else /* if (old_drain_count && new_drain_count) */ { 20790513f984SMax Reitz /* 20800513f984SMax Reitz * From drained to drained must not undrain the parent at any 20810513f984SMax Reitz * point 20820513f984SMax Reitz */ 20830513f984SMax Reitz g_assert(!parent_s->was_drained && !parent_s->was_undrained); 20840513f984SMax Reitz } 20850513f984SMax Reitz 20860513f984SMax Reitz if (!old_drain_count || !new_drain_count) { 20870513f984SMax Reitz /* 20880513f984SMax Reitz * If !old_drain_count, we have started a read request before 20890513f984SMax Reitz * bdrv_replace_node(). If !new_drain_count, the parent must 20900513f984SMax Reitz * have been undrained at some point, and 20910513f984SMax Reitz * bdrv_replace_test_co_drain_end() starts a read request 20920513f984SMax Reitz * then. 20930513f984SMax Reitz */ 20940513f984SMax Reitz g_assert(parent_s->has_read); 20950513f984SMax Reitz } else { 20960513f984SMax Reitz /* 20970513f984SMax Reitz * If the parent was never undrained, there is no way to start 20980513f984SMax Reitz * a read request. 20990513f984SMax Reitz */ 21000513f984SMax Reitz g_assert(!parent_s->has_read); 21010513f984SMax Reitz } 21020513f984SMax Reitz 21030513f984SMax Reitz /* A drained child must have not received any request */ 21040513f984SMax Reitz g_assert(!(old_drain_count && old_child_s->has_read)); 21050513f984SMax Reitz g_assert(!(new_drain_count && new_child_s->has_read)); 21060513f984SMax Reitz 21070513f984SMax Reitz for (i = 0; i < new_drain_count; i++) { 21080513f984SMax Reitz bdrv_drained_end(new_child_bs); 21090513f984SMax Reitz } 21100513f984SMax Reitz for (i = 0; i < old_drain_count; i++) { 21110513f984SMax Reitz bdrv_drained_end(old_child_bs); 21120513f984SMax Reitz } 21130513f984SMax Reitz 21140513f984SMax Reitz /* 21150513f984SMax Reitz * By now, bdrv_replace_test_co_drain_end() must have been called 21160513f984SMax Reitz * at some point while the new child was attached to the parent. 21170513f984SMax Reitz */ 21180513f984SMax Reitz g_assert(parent_s->has_read); 21190513f984SMax Reitz g_assert(new_child_s->has_read); 21200513f984SMax Reitz 21210513f984SMax Reitz blk_unref(parent_blk); 21220513f984SMax Reitz bdrv_unref(parent_bs); 21230513f984SMax Reitz bdrv_unref(old_child_bs); 21240513f984SMax Reitz bdrv_unref(new_child_bs); 21250513f984SMax Reitz } 21260513f984SMax Reitz 21270513f984SMax Reitz static void test_replace_child_mid_drain(void) 21280513f984SMax Reitz { 21290513f984SMax Reitz int old_drain_count, new_drain_count; 21300513f984SMax Reitz 21310513f984SMax Reitz for (old_drain_count = 0; old_drain_count < 2; old_drain_count++) { 21320513f984SMax Reitz for (new_drain_count = 0; new_drain_count < 2; new_drain_count++) { 21330513f984SMax Reitz do_test_replace_child_mid_drain(old_drain_count, new_drain_count); 21340513f984SMax Reitz } 21350513f984SMax Reitz } 21360513f984SMax Reitz } 21370513f984SMax Reitz 2138881cfd17SKevin Wolf int main(int argc, char **argv) 2139881cfd17SKevin Wolf { 2140bb675689SKevin Wolf int ret; 2141bb675689SKevin Wolf 2142881cfd17SKevin Wolf bdrv_init(); 2143881cfd17SKevin Wolf qemu_init_main_loop(&error_abort); 2144881cfd17SKevin Wolf 2145881cfd17SKevin Wolf g_test_init(&argc, &argv, NULL); 2146bb675689SKevin Wolf qemu_event_init(&done_event, false); 2147881cfd17SKevin Wolf 2148881cfd17SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all); 214986e1c840SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain); 2150d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain_subtree", 2151d2a85d0fSKevin Wolf test_drv_cb_drain_subtree); 2152881cfd17SKevin Wolf 21536d0252f2SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain_all", 21546d0252f2SKevin Wolf test_drv_cb_co_drain_all); 21550582eb10SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain", test_drv_cb_co_drain); 21560582eb10SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain_subtree", 21570582eb10SKevin Wolf test_drv_cb_co_drain_subtree); 21580582eb10SKevin Wolf 21590582eb10SKevin Wolf 216089a6ceabSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all); 216189a6ceabSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain); 2162d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain_subtree", 2163d2a85d0fSKevin Wolf test_quiesce_drain_subtree); 216489a6ceabSKevin Wolf 21656d0252f2SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain_all", 21666d0252f2SKevin Wolf test_quiesce_co_drain_all); 21670582eb10SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain", test_quiesce_co_drain); 21680582eb10SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain_subtree", 21690582eb10SKevin Wolf test_quiesce_co_drain_subtree); 21700582eb10SKevin Wolf 21716c429a6aSKevin Wolf g_test_add_func("/bdrv-drain/nested", test_nested); 217227e64474SKevin Wolf g_test_add_func("/bdrv-drain/multiparent", test_multiparent); 217319f7a7e5SKevin Wolf 217419f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/graph-change/drain_subtree", 217519f7a7e5SKevin Wolf test_graph_change_drain_subtree); 217619f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/graph-change/drain_all", 217719f7a7e5SKevin Wolf test_graph_change_drain_all); 21786c429a6aSKevin Wolf 2179bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain_all", test_iothread_drain_all); 2180bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain", test_iothread_drain); 2181bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain_subtree", 2182bb675689SKevin Wolf test_iothread_drain_subtree); 2183bb675689SKevin Wolf 21847253220dSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all); 21857253220dSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain); 2186d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain_subtree", 2187d2a85d0fSKevin Wolf test_blockjob_drain_subtree); 21887253220dSKevin Wolf 2189d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain_all", 2190d49725afSKevin Wolf test_blockjob_error_drain_all); 2191d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain", 2192d49725afSKevin Wolf test_blockjob_error_drain); 2193d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain_subtree", 2194d49725afSKevin Wolf test_blockjob_error_drain_subtree); 2195d49725afSKevin Wolf 2196f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain_all", 2197f62c1729SKevin Wolf test_blockjob_iothread_drain_all); 2198f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain", 2199f62c1729SKevin Wolf test_blockjob_iothread_drain); 2200f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain_subtree", 2201f62c1729SKevin Wolf test_blockjob_iothread_drain_subtree); 2202f62c1729SKevin Wolf 2203d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_all", 2204d49725afSKevin Wolf test_blockjob_iothread_error_drain_all); 2205d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain", 2206d49725afSKevin Wolf test_blockjob_iothread_error_drain); 2207d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_subtree", 2208d49725afSKevin Wolf test_blockjob_iothread_error_drain_subtree); 2209d49725afSKevin Wolf 2210ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/deletion/drain", test_delete_by_drain); 221119f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain_all", test_detach_by_drain_all); 2212ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain", test_detach_by_drain); 2213ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain_subtree", test_detach_by_drain_subtree); 2214231281abSKevin Wolf g_test_add_func("/bdrv-drain/detach/parent_cb", test_detach_by_parent_cb); 221557320ca9SKevin Wolf g_test_add_func("/bdrv-drain/detach/driver_cb", test_detach_by_driver_cb); 22164c8158e3SMax Reitz 2217b994c5bcSKevin Wolf g_test_add_func("/bdrv-drain/attach/drain", test_append_to_drained); 2218b994c5bcSKevin Wolf 2219247d2737SKevin Wolf g_test_add_func("/bdrv-drain/set_aio_context", test_set_aio_context); 2220247d2737SKevin Wolf 22218e442810SMax Reitz g_test_add_func("/bdrv-drain/blockjob/commit_by_drained_end", 22228e442810SMax Reitz test_blockjob_commit_by_drained_end); 22238e442810SMax Reitz 22249746b35cSMax Reitz g_test_add_func("/bdrv-drain/bdrv_drop_intermediate/poll", 22259746b35cSMax Reitz test_drop_intermediate_poll); 22269746b35cSMax Reitz 22270513f984SMax Reitz g_test_add_func("/bdrv-drain/replace_child/mid-drain", 22280513f984SMax Reitz test_replace_child_mid_drain); 22290513f984SMax Reitz 2230bb675689SKevin Wolf ret = g_test_run(); 2231bb675689SKevin Wolf qemu_event_destroy(&done_event); 2232bb675689SKevin Wolf return ret; 2233881cfd17SKevin Wolf } 2234