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, 68f7ef38ddSVladimir Sementsov-Ogievskiy int64_t offset, int64_t bytes, 69f7ef38ddSVladimir Sementsov-Ogievskiy QEMUIOVector *qiov, 70f7ef38ddSVladimir 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; 7751b177bbeSVladimir Sementsov-Ogievskiy BlockDriverState *bs; 776d49725afSKevin Wolf int run_ret; 777d49725afSKevin Wolf int prepare_ret; 778d8b3afd5SKevin Wolf bool running; 7797253220dSKevin Wolf bool should_complete; 7807253220dSKevin Wolf } TestBlockJob; 7817253220dSKevin Wolf 782ae23dde9SKevin Wolf static int test_job_prepare(Job *job) 783ae23dde9SKevin Wolf { 784ae23dde9SKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 785ae23dde9SKevin Wolf 786ae23dde9SKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 7871b177bbeSVladimir Sementsov-Ogievskiy bdrv_flush(s->bs); 788d49725afSKevin Wolf return s->prepare_ret; 789d49725afSKevin Wolf } 790d49725afSKevin Wolf 791d49725afSKevin Wolf static void test_job_commit(Job *job) 792d49725afSKevin Wolf { 793d49725afSKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 794d49725afSKevin Wolf 795d49725afSKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 7961b177bbeSVladimir Sementsov-Ogievskiy bdrv_flush(s->bs); 797d49725afSKevin Wolf } 798d49725afSKevin Wolf 799d49725afSKevin Wolf static void test_job_abort(Job *job) 800d49725afSKevin Wolf { 801d49725afSKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 802d49725afSKevin Wolf 803d49725afSKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 8041b177bbeSVladimir Sementsov-Ogievskiy bdrv_flush(s->bs); 805ae23dde9SKevin Wolf } 806ae23dde9SKevin Wolf 807f67432a2SJohn Snow static int coroutine_fn test_job_run(Job *job, Error **errp) 8087253220dSKevin Wolf { 809f67432a2SJohn Snow TestBlockJob *s = container_of(job, TestBlockJob, common.job); 8107253220dSKevin Wolf 811d8b3afd5SKevin Wolf /* We are running the actual job code past the pause point in 812d8b3afd5SKevin Wolf * job_co_entry(). */ 813d8b3afd5SKevin Wolf s->running = true; 814d8b3afd5SKevin Wolf 8152e1795b5SKevin Wolf job_transition_to_ready(&s->common.job); 8167253220dSKevin Wolf while (!s->should_complete) { 8175599c162SKevin Wolf /* Avoid job_sleep_ns() because it marks the job as !busy. We want to 8185599c162SKevin Wolf * emulate some actual activity (probably some I/O) here so that drain 8195599c162SKevin Wolf * has to wait for this activity to stop. */ 820d8b3afd5SKevin Wolf qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000); 821d8b3afd5SKevin Wolf 82289bd0305SKevin Wolf job_pause_point(&s->common.job); 8237253220dSKevin Wolf } 8247253220dSKevin Wolf 825d49725afSKevin Wolf return s->run_ret; 8267253220dSKevin Wolf } 8277253220dSKevin Wolf 8283453d972SKevin Wolf static void test_job_complete(Job *job, Error **errp) 8297253220dSKevin Wolf { 8303453d972SKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 8317253220dSKevin Wolf s->should_complete = true; 8327253220dSKevin Wolf } 8337253220dSKevin Wolf 8347253220dSKevin Wolf BlockJobDriver test_job_driver = { 83533e9e9bdSKevin Wolf .job_driver = { 8367253220dSKevin Wolf .instance_size = sizeof(TestBlockJob), 83780fa2c75SKevin Wolf .free = block_job_free, 838b15de828SKevin Wolf .user_resume = block_job_user_resume, 839f67432a2SJohn Snow .run = test_job_run, 8407253220dSKevin Wolf .complete = test_job_complete, 841ae23dde9SKevin Wolf .prepare = test_job_prepare, 842d49725afSKevin Wolf .commit = test_job_commit, 843d49725afSKevin Wolf .abort = test_job_abort, 8443453d972SKevin Wolf }, 8457253220dSKevin Wolf }; 8467253220dSKevin Wolf 847d49725afSKevin Wolf enum test_job_result { 848d49725afSKevin Wolf TEST_JOB_SUCCESS, 849d49725afSKevin Wolf TEST_JOB_FAIL_RUN, 850d49725afSKevin Wolf TEST_JOB_FAIL_PREPARE, 851d49725afSKevin Wolf }; 852d49725afSKevin Wolf 853d8b3afd5SKevin Wolf enum test_job_drain_node { 854d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC, 855d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_CHILD, 856d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_PARENT, 857d8b3afd5SKevin Wolf }; 858d8b3afd5SKevin Wolf 859d8b3afd5SKevin Wolf static void test_blockjob_common_drain_node(enum drain_type drain_type, 860d8b3afd5SKevin Wolf bool use_iothread, 861d8b3afd5SKevin Wolf enum test_job_result result, 862d8b3afd5SKevin Wolf enum test_job_drain_node drain_node) 8637253220dSKevin Wolf { 8647253220dSKevin Wolf BlockBackend *blk_src, *blk_target; 865d8b3afd5SKevin Wolf BlockDriverState *src, *src_backing, *src_overlay, *target, *drain_bs; 8667253220dSKevin Wolf BlockJob *job; 867d49725afSKevin Wolf TestBlockJob *tjob; 868f62c1729SKevin Wolf IOThread *iothread = NULL; 869f62c1729SKevin Wolf AioContext *ctx; 8707253220dSKevin Wolf int ret; 8717253220dSKevin Wolf 8727253220dSKevin Wolf src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR, 8737253220dSKevin Wolf &error_abort); 874d8b3afd5SKevin Wolf src_backing = bdrv_new_open_driver(&bdrv_test, "source-backing", 875d8b3afd5SKevin Wolf BDRV_O_RDWR, &error_abort); 876d8b3afd5SKevin Wolf src_overlay = bdrv_new_open_driver(&bdrv_test, "source-overlay", 877d8b3afd5SKevin Wolf BDRV_O_RDWR, &error_abort); 878d8b3afd5SKevin Wolf 879d8b3afd5SKevin Wolf bdrv_set_backing_hd(src_overlay, src, &error_abort); 880d8b3afd5SKevin Wolf bdrv_unref(src); 881d8b3afd5SKevin Wolf bdrv_set_backing_hd(src, src_backing, &error_abort); 882d8b3afd5SKevin Wolf bdrv_unref(src_backing); 883d8b3afd5SKevin Wolf 884d861ab3aSKevin Wolf blk_src = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 885d8b3afd5SKevin Wolf blk_insert_bs(blk_src, src_overlay, &error_abort); 886d8b3afd5SKevin Wolf 887d8b3afd5SKevin Wolf switch (drain_node) { 888d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC: 889d8b3afd5SKevin Wolf drain_bs = src; 890d8b3afd5SKevin Wolf break; 891d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC_CHILD: 892d8b3afd5SKevin Wolf drain_bs = src_backing; 893d8b3afd5SKevin Wolf break; 894d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC_PARENT: 895d8b3afd5SKevin Wolf drain_bs = src_overlay; 896d8b3afd5SKevin Wolf break; 897d8b3afd5SKevin Wolf default: 898d8b3afd5SKevin Wolf g_assert_not_reached(); 899d8b3afd5SKevin Wolf } 9007253220dSKevin Wolf 901f62c1729SKevin Wolf if (use_iothread) { 902f62c1729SKevin Wolf iothread = iothread_new(); 903f62c1729SKevin Wolf ctx = iothread_get_aio_context(iothread); 90497896a48SKevin Wolf blk_set_aio_context(blk_src, ctx, &error_abort); 905f62c1729SKevin Wolf } else { 906f62c1729SKevin Wolf ctx = qemu_get_aio_context(); 907f62c1729SKevin Wolf } 908f62c1729SKevin Wolf 9097253220dSKevin Wolf target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR, 9107253220dSKevin Wolf &error_abort); 911d861ab3aSKevin Wolf blk_target = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 9127253220dSKevin Wolf blk_insert_bs(blk_target, target, &error_abort); 913132ada80SKevin Wolf blk_set_allow_aio_context_change(blk_target, true); 9147253220dSKevin Wolf 915f62c1729SKevin Wolf aio_context_acquire(ctx); 916d49725afSKevin Wolf tjob = block_job_create("job0", &test_job_driver, NULL, src, 917d49725afSKevin Wolf 0, BLK_PERM_ALL, 91875859b94SJohn Snow 0, 0, NULL, NULL, &error_abort); 9191b177bbeSVladimir Sementsov-Ogievskiy tjob->bs = src; 920d49725afSKevin Wolf job = &tjob->common; 9217253220dSKevin Wolf block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort); 922d49725afSKevin Wolf 923d49725afSKevin Wolf switch (result) { 924d49725afSKevin Wolf case TEST_JOB_SUCCESS: 925d49725afSKevin Wolf break; 926d49725afSKevin Wolf case TEST_JOB_FAIL_RUN: 927d49725afSKevin Wolf tjob->run_ret = -EIO; 928d49725afSKevin Wolf break; 929d49725afSKevin Wolf case TEST_JOB_FAIL_PREPARE: 930d49725afSKevin Wolf tjob->prepare_ret = -EIO; 931d49725afSKevin Wolf break; 932d49725afSKevin Wolf } 933d49725afSKevin Wolf 934da01ff7fSKevin Wolf job_start(&job->job); 935f62c1729SKevin Wolf aio_context_release(ctx); 9367253220dSKevin Wolf 937d8b3afd5SKevin Wolf if (use_iothread) { 938d8b3afd5SKevin Wolf /* job_co_entry() is run in the I/O thread, wait for the actual job 939d8b3afd5SKevin Wolf * code to start (we don't want to catch the job in the pause point in 940d8b3afd5SKevin Wolf * job_co_entry(). */ 941d8b3afd5SKevin Wolf while (!tjob->running) { 942d8b3afd5SKevin Wolf aio_poll(qemu_get_aio_context(), false); 943d8b3afd5SKevin Wolf } 944d8b3afd5SKevin Wolf } 945d8b3afd5SKevin Wolf 946*191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 947da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 948da01ff7fSKevin Wolf g_assert_false(job->job.paused); 949d8b3afd5SKevin Wolf g_assert_true(tjob->running); 9505599c162SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 951*191e7af3SEmanuele Giuseppe Esposito } 9527253220dSKevin Wolf 953d8b3afd5SKevin Wolf do_drain_begin_unlocked(drain_type, drain_bs); 9547253220dSKevin Wolf 955*191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 9567253220dSKevin Wolf if (drain_type == BDRV_DRAIN_ALL) { 95781193349SKevin Wolf /* bdrv_drain_all() drains both src and target */ 958da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 2); 9597253220dSKevin Wolf } else { 960da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 1); 9617253220dSKevin Wolf } 96289bd0305SKevin Wolf g_assert_true(job->job.paused); 963da01ff7fSKevin Wolf g_assert_false(job->job.busy); /* The job is paused */ 964*191e7af3SEmanuele Giuseppe Esposito } 9657253220dSKevin Wolf 966d8b3afd5SKevin Wolf do_drain_end_unlocked(drain_type, drain_bs); 967f62c1729SKevin Wolf 968f62c1729SKevin Wolf if (use_iothread) { 969*191e7af3SEmanuele Giuseppe Esposito /* 970*191e7af3SEmanuele Giuseppe Esposito * Here we are waiting for the paused status to change, 971*191e7af3SEmanuele Giuseppe Esposito * so don't bother protecting the read every time. 972*191e7af3SEmanuele Giuseppe Esposito * 973*191e7af3SEmanuele Giuseppe Esposito * paused is reset in the I/O thread, wait for it 974*191e7af3SEmanuele Giuseppe Esposito */ 975f62c1729SKevin Wolf while (job->job.paused) { 976f62c1729SKevin Wolf aio_poll(qemu_get_aio_context(), false); 977f62c1729SKevin Wolf } 978f62c1729SKevin Wolf } 9797253220dSKevin Wolf 980*191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 981da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 982da01ff7fSKevin Wolf g_assert_false(job->job.paused); 98389bd0305SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 984*191e7af3SEmanuele Giuseppe Esposito } 9857253220dSKevin Wolf 986132ada80SKevin Wolf do_drain_begin_unlocked(drain_type, target); 9877253220dSKevin Wolf 988*191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 9897253220dSKevin Wolf if (drain_type == BDRV_DRAIN_ALL) { 99081193349SKevin Wolf /* bdrv_drain_all() drains both src and target */ 991da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 2); 9927253220dSKevin Wolf } else { 993da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 1); 9947253220dSKevin Wolf } 99589bd0305SKevin Wolf g_assert_true(job->job.paused); 996da01ff7fSKevin Wolf g_assert_false(job->job.busy); /* The job is paused */ 997*191e7af3SEmanuele Giuseppe Esposito } 9987253220dSKevin Wolf 999132ada80SKevin Wolf do_drain_end_unlocked(drain_type, target); 10007253220dSKevin Wolf 1001f62c1729SKevin Wolf if (use_iothread) { 1002*191e7af3SEmanuele Giuseppe Esposito /* 1003*191e7af3SEmanuele Giuseppe Esposito * Here we are waiting for the paused status to change, 1004*191e7af3SEmanuele Giuseppe Esposito * so don't bother protecting the read every time. 1005*191e7af3SEmanuele Giuseppe Esposito * 1006*191e7af3SEmanuele Giuseppe Esposito * paused is reset in the I/O thread, wait for it 1007*191e7af3SEmanuele Giuseppe Esposito */ 1008f62c1729SKevin Wolf while (job->job.paused) { 1009f62c1729SKevin Wolf aio_poll(qemu_get_aio_context(), false); 1010f62c1729SKevin Wolf } 1011f62c1729SKevin Wolf } 1012f62c1729SKevin Wolf 1013*191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 1014da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 1015da01ff7fSKevin Wolf g_assert_false(job->job.paused); 10165599c162SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 1017*191e7af3SEmanuele Giuseppe Esposito } 10187253220dSKevin Wolf 1019f62c1729SKevin Wolf aio_context_acquire(ctx); 1020*191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 1021*191e7af3SEmanuele Giuseppe Esposito ret = job_complete_sync_locked(&job->job, &error_abort); 1022*191e7af3SEmanuele Giuseppe Esposito } 1023d49725afSKevin Wolf g_assert_cmpint(ret, ==, (result == TEST_JOB_SUCCESS ? 0 : -EIO)); 10247253220dSKevin Wolf 1025f62c1729SKevin Wolf if (use_iothread) { 102697896a48SKevin Wolf blk_set_aio_context(blk_src, qemu_get_aio_context(), &error_abort); 1027ad943dcbSKevin Wolf assert(blk_get_aio_context(blk_target) == qemu_get_aio_context()); 1028f62c1729SKevin Wolf } 1029f62c1729SKevin Wolf aio_context_release(ctx); 1030f62c1729SKevin Wolf 10317253220dSKevin Wolf blk_unref(blk_src); 10327253220dSKevin Wolf blk_unref(blk_target); 1033d8b3afd5SKevin Wolf bdrv_unref(src_overlay); 10347253220dSKevin Wolf bdrv_unref(target); 1035f62c1729SKevin Wolf 1036f62c1729SKevin Wolf if (iothread) { 1037f62c1729SKevin Wolf iothread_join(iothread); 1038f62c1729SKevin Wolf } 10397253220dSKevin Wolf } 10407253220dSKevin Wolf 1041d8b3afd5SKevin Wolf static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, 1042d8b3afd5SKevin Wolf enum test_job_result result) 1043d8b3afd5SKevin Wolf { 1044d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1045d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC); 1046d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1047d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_CHILD); 1048d8b3afd5SKevin Wolf if (drain_type == BDRV_SUBTREE_DRAIN) { 1049d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1050d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_PARENT); 1051d8b3afd5SKevin Wolf } 1052d8b3afd5SKevin Wolf } 1053d8b3afd5SKevin Wolf 10547253220dSKevin Wolf static void test_blockjob_drain_all(void) 10557253220dSKevin Wolf { 1056d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_SUCCESS); 10577253220dSKevin Wolf } 10587253220dSKevin Wolf 10597253220dSKevin Wolf static void test_blockjob_drain(void) 10607253220dSKevin Wolf { 1061d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_SUCCESS); 10627253220dSKevin Wolf } 10637253220dSKevin Wolf 1064d2a85d0fSKevin Wolf static void test_blockjob_drain_subtree(void) 1065d2a85d0fSKevin Wolf { 1066d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_SUCCESS); 1067d49725afSKevin Wolf } 1068d49725afSKevin Wolf 1069d49725afSKevin Wolf static void test_blockjob_error_drain_all(void) 1070d49725afSKevin Wolf { 1071d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_RUN); 1072d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_PREPARE); 1073d49725afSKevin Wolf } 1074d49725afSKevin Wolf 1075d49725afSKevin Wolf static void test_blockjob_error_drain(void) 1076d49725afSKevin Wolf { 1077d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_RUN); 1078d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_PREPARE); 1079d49725afSKevin Wolf } 1080d49725afSKevin Wolf 1081d49725afSKevin Wolf static void test_blockjob_error_drain_subtree(void) 1082d49725afSKevin Wolf { 1083d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_RUN); 1084d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_PREPARE); 1085f62c1729SKevin Wolf } 1086f62c1729SKevin Wolf 1087f62c1729SKevin Wolf static void test_blockjob_iothread_drain_all(void) 1088f62c1729SKevin Wolf { 1089d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_SUCCESS); 1090f62c1729SKevin Wolf } 1091f62c1729SKevin Wolf 1092f62c1729SKevin Wolf static void test_blockjob_iothread_drain(void) 1093f62c1729SKevin Wolf { 1094d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_SUCCESS); 1095f62c1729SKevin Wolf } 1096f62c1729SKevin Wolf 1097f62c1729SKevin Wolf static void test_blockjob_iothread_drain_subtree(void) 1098f62c1729SKevin Wolf { 1099d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_SUCCESS); 1100d49725afSKevin Wolf } 1101d49725afSKevin Wolf 1102d49725afSKevin Wolf static void test_blockjob_iothread_error_drain_all(void) 1103d49725afSKevin Wolf { 1104d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_RUN); 1105d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_PREPARE); 1106d49725afSKevin Wolf } 1107d49725afSKevin Wolf 1108d49725afSKevin Wolf static void test_blockjob_iothread_error_drain(void) 1109d49725afSKevin Wolf { 1110d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_RUN); 1111d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_PREPARE); 1112d49725afSKevin Wolf } 1113d49725afSKevin Wolf 1114d49725afSKevin Wolf static void test_blockjob_iothread_error_drain_subtree(void) 1115d49725afSKevin Wolf { 1116d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_RUN); 1117d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_PREPARE); 1118d2a85d0fSKevin Wolf } 1119d2a85d0fSKevin Wolf 11204c8158e3SMax Reitz 11214c8158e3SMax Reitz typedef struct BDRVTestTopState { 11224c8158e3SMax Reitz BdrvChild *wait_child; 11234c8158e3SMax Reitz } BDRVTestTopState; 11244c8158e3SMax Reitz 11254c8158e3SMax Reitz static void bdrv_test_top_close(BlockDriverState *bs) 11264c8158e3SMax Reitz { 11274c8158e3SMax Reitz BdrvChild *c, *next_c; 11284c8158e3SMax Reitz QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) { 11294c8158e3SMax Reitz bdrv_unref_child(bs, c); 11304c8158e3SMax Reitz } 11314c8158e3SMax Reitz } 11324c8158e3SMax Reitz 11334c8158e3SMax Reitz static int coroutine_fn bdrv_test_top_co_preadv(BlockDriverState *bs, 1134f7ef38ddSVladimir Sementsov-Ogievskiy int64_t offset, int64_t bytes, 1135f7ef38ddSVladimir Sementsov-Ogievskiy QEMUIOVector *qiov, 1136f7ef38ddSVladimir Sementsov-Ogievskiy BdrvRequestFlags flags) 11374c8158e3SMax Reitz { 11384c8158e3SMax Reitz BDRVTestTopState *tts = bs->opaque; 11394c8158e3SMax Reitz return bdrv_co_preadv(tts->wait_child, offset, bytes, qiov, flags); 11404c8158e3SMax Reitz } 11414c8158e3SMax Reitz 11424c8158e3SMax Reitz static BlockDriver bdrv_test_top_driver = { 11434c8158e3SMax Reitz .format_name = "test_top_driver", 11444c8158e3SMax Reitz .instance_size = sizeof(BDRVTestTopState), 11454c8158e3SMax Reitz 11464c8158e3SMax Reitz .bdrv_close = bdrv_test_top_close, 11474c8158e3SMax Reitz .bdrv_co_preadv = bdrv_test_top_co_preadv, 11484c8158e3SMax Reitz 114969dca43dSMax Reitz .bdrv_child_perm = bdrv_default_perms, 11504c8158e3SMax Reitz }; 11514c8158e3SMax Reitz 11524c8158e3SMax Reitz typedef struct TestCoDeleteByDrainData { 11534c8158e3SMax Reitz BlockBackend *blk; 11544c8158e3SMax Reitz bool detach_instead_of_delete; 11554c8158e3SMax Reitz bool done; 11564c8158e3SMax Reitz } TestCoDeleteByDrainData; 11574c8158e3SMax Reitz 11584c8158e3SMax Reitz static void coroutine_fn test_co_delete_by_drain(void *opaque) 11594c8158e3SMax Reitz { 11604c8158e3SMax Reitz TestCoDeleteByDrainData *dbdd = opaque; 11614c8158e3SMax Reitz BlockBackend *blk = dbdd->blk; 11624c8158e3SMax Reitz BlockDriverState *bs = blk_bs(blk); 11634c8158e3SMax Reitz BDRVTestTopState *tts = bs->opaque; 11644c8158e3SMax Reitz void *buffer = g_malloc(65536); 1165405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buffer, 65536); 11664c8158e3SMax Reitz 11674c8158e3SMax Reitz /* Pretend some internal write operation from parent to child. 11684c8158e3SMax Reitz * Important: We have to read from the child, not from the parent! 11694c8158e3SMax Reitz * Draining works by first propagating it all up the tree to the 11704c8158e3SMax Reitz * root and then waiting for drainage from root to the leaves 11714c8158e3SMax Reitz * (protocol nodes). If we have a request waiting on the root, 11724c8158e3SMax Reitz * everything will be drained before we go back down the tree, but 11734c8158e3SMax Reitz * we do not want that. We want to be in the middle of draining 11744c8158e3SMax Reitz * when this following requests returns. */ 11754c8158e3SMax Reitz bdrv_co_preadv(tts->wait_child, 0, 65536, &qiov, 0); 11764c8158e3SMax Reitz 11774c8158e3SMax Reitz g_assert_cmpint(bs->refcnt, ==, 1); 11784c8158e3SMax Reitz 11794c8158e3SMax Reitz if (!dbdd->detach_instead_of_delete) { 11804c8158e3SMax Reitz blk_unref(blk); 11814c8158e3SMax Reitz } else { 11824c8158e3SMax Reitz BdrvChild *c, *next_c; 11834c8158e3SMax Reitz QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) { 11844c8158e3SMax Reitz bdrv_unref_child(bs, c); 11854c8158e3SMax Reitz } 11864c8158e3SMax Reitz } 11874c8158e3SMax Reitz 11884c8158e3SMax Reitz dbdd->done = true; 11897b43db3cSMarc-André Lureau g_free(buffer); 11904c8158e3SMax Reitz } 11914c8158e3SMax Reitz 11924c8158e3SMax Reitz /** 11934c8158e3SMax Reitz * Test what happens when some BDS has some children, you drain one of 11944c8158e3SMax Reitz * them and this results in the BDS being deleted. 11954c8158e3SMax Reitz * 11964c8158e3SMax Reitz * If @detach_instead_of_delete is set, the BDS is not going to be 11974c8158e3SMax Reitz * deleted but will only detach all of its children. 11984c8158e3SMax Reitz */ 1199ebd31837SKevin Wolf static void do_test_delete_by_drain(bool detach_instead_of_delete, 1200ebd31837SKevin Wolf enum drain_type drain_type) 12014c8158e3SMax Reitz { 12024c8158e3SMax Reitz BlockBackend *blk; 12034c8158e3SMax Reitz BlockDriverState *bs, *child_bs, *null_bs; 12044c8158e3SMax Reitz BDRVTestTopState *tts; 12054c8158e3SMax Reitz TestCoDeleteByDrainData dbdd; 12064c8158e3SMax Reitz Coroutine *co; 12074c8158e3SMax Reitz 12084c8158e3SMax Reitz bs = bdrv_new_open_driver(&bdrv_test_top_driver, "top", BDRV_O_RDWR, 12094c8158e3SMax Reitz &error_abort); 12104c8158e3SMax Reitz bs->total_sectors = 65536 >> BDRV_SECTOR_BITS; 12114c8158e3SMax Reitz tts = bs->opaque; 12124c8158e3SMax Reitz 12134c8158e3SMax Reitz null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 12144c8158e3SMax Reitz &error_abort); 1215a16be3cdSMax Reitz bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, 1216a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 12174c8158e3SMax Reitz 12184c8158e3SMax Reitz /* This child will be the one to pass to requests through to, and 12194c8158e3SMax Reitz * it will stall until a drain occurs */ 12204c8158e3SMax Reitz child_bs = bdrv_new_open_driver(&bdrv_test, "child", BDRV_O_RDWR, 12214c8158e3SMax Reitz &error_abort); 12224c8158e3SMax Reitz child_bs->total_sectors = 65536 >> BDRV_SECTOR_BITS; 12234c8158e3SMax Reitz /* Takes our reference to child_bs */ 1224a16be3cdSMax Reitz tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child", 1225a16be3cdSMax Reitz &child_of_bds, 1226a16be3cdSMax Reitz BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY, 1227a16be3cdSMax Reitz &error_abort); 12284c8158e3SMax Reitz 12294c8158e3SMax Reitz /* This child is just there to be deleted 12304c8158e3SMax Reitz * (for detach_instead_of_delete == true) */ 12314c8158e3SMax Reitz null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 12324c8158e3SMax Reitz &error_abort); 1233a16be3cdSMax Reitz bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, BDRV_CHILD_DATA, 1234a16be3cdSMax Reitz &error_abort); 12354c8158e3SMax Reitz 1236d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 12374c8158e3SMax Reitz blk_insert_bs(blk, bs, &error_abort); 12384c8158e3SMax Reitz 12394c8158e3SMax Reitz /* Referenced by blk now */ 12404c8158e3SMax Reitz bdrv_unref(bs); 12414c8158e3SMax Reitz 12424c8158e3SMax Reitz g_assert_cmpint(bs->refcnt, ==, 1); 12434c8158e3SMax Reitz g_assert_cmpint(child_bs->refcnt, ==, 1); 12444c8158e3SMax Reitz g_assert_cmpint(null_bs->refcnt, ==, 1); 12454c8158e3SMax Reitz 12464c8158e3SMax Reitz 12474c8158e3SMax Reitz dbdd = (TestCoDeleteByDrainData){ 12484c8158e3SMax Reitz .blk = blk, 12494c8158e3SMax Reitz .detach_instead_of_delete = detach_instead_of_delete, 12504c8158e3SMax Reitz .done = false, 12514c8158e3SMax Reitz }; 12524c8158e3SMax Reitz co = qemu_coroutine_create(test_co_delete_by_drain, &dbdd); 12534c8158e3SMax Reitz qemu_coroutine_enter(co); 12544c8158e3SMax Reitz 12554c8158e3SMax Reitz /* Drain the child while the read operation is still pending. 12564c8158e3SMax Reitz * This should result in the operation finishing and 12574c8158e3SMax Reitz * test_co_delete_by_drain() resuming. Thus, @bs will be deleted 12584c8158e3SMax Reitz * and the coroutine will exit while this drain operation is still 12594c8158e3SMax Reitz * in progress. */ 1260ebd31837SKevin Wolf switch (drain_type) { 1261ebd31837SKevin Wolf case BDRV_DRAIN: 12624c8158e3SMax Reitz bdrv_ref(child_bs); 12634c8158e3SMax Reitz bdrv_drain(child_bs); 12644c8158e3SMax Reitz bdrv_unref(child_bs); 1265ebd31837SKevin Wolf break; 1266ebd31837SKevin Wolf case BDRV_SUBTREE_DRAIN: 1267ebd31837SKevin Wolf /* Would have to ref/unref bs here for !detach_instead_of_delete, but 1268ebd31837SKevin Wolf * then the whole test becomes pointless because the graph changes 1269ebd31837SKevin Wolf * don't occur during the drain any more. */ 1270ebd31837SKevin Wolf assert(detach_instead_of_delete); 1271ebd31837SKevin Wolf bdrv_subtree_drained_begin(bs); 1272ebd31837SKevin Wolf bdrv_subtree_drained_end(bs); 1273ebd31837SKevin Wolf break; 127419f7a7e5SKevin Wolf case BDRV_DRAIN_ALL: 127519f7a7e5SKevin Wolf bdrv_drain_all_begin(); 127619f7a7e5SKevin Wolf bdrv_drain_all_end(); 127719f7a7e5SKevin Wolf break; 1278ebd31837SKevin Wolf default: 1279ebd31837SKevin Wolf g_assert_not_reached(); 1280ebd31837SKevin Wolf } 12814c8158e3SMax Reitz 12824c8158e3SMax Reitz while (!dbdd.done) { 12834c8158e3SMax Reitz aio_poll(qemu_get_aio_context(), true); 12844c8158e3SMax Reitz } 12854c8158e3SMax Reitz 12864c8158e3SMax Reitz if (detach_instead_of_delete) { 12874c8158e3SMax Reitz /* Here, the reference has not passed over to the coroutine, 12884c8158e3SMax Reitz * so we have to delete the BB ourselves */ 12894c8158e3SMax Reitz blk_unref(blk); 12904c8158e3SMax Reitz } 12914c8158e3SMax Reitz } 12924c8158e3SMax Reitz 12934c8158e3SMax Reitz static void test_delete_by_drain(void) 12944c8158e3SMax Reitz { 1295ebd31837SKevin Wolf do_test_delete_by_drain(false, BDRV_DRAIN); 12964c8158e3SMax Reitz } 12974c8158e3SMax Reitz 129819f7a7e5SKevin Wolf static void test_detach_by_drain_all(void) 129919f7a7e5SKevin Wolf { 130019f7a7e5SKevin Wolf do_test_delete_by_drain(true, BDRV_DRAIN_ALL); 130119f7a7e5SKevin Wolf } 130219f7a7e5SKevin Wolf 13034c8158e3SMax Reitz static void test_detach_by_drain(void) 13044c8158e3SMax Reitz { 1305ebd31837SKevin Wolf do_test_delete_by_drain(true, BDRV_DRAIN); 1306ebd31837SKevin Wolf } 1307ebd31837SKevin Wolf 1308ebd31837SKevin Wolf static void test_detach_by_drain_subtree(void) 1309ebd31837SKevin Wolf { 1310ebd31837SKevin Wolf do_test_delete_by_drain(true, BDRV_SUBTREE_DRAIN); 13114c8158e3SMax Reitz } 13124c8158e3SMax Reitz 13134c8158e3SMax Reitz 1314231281abSKevin Wolf struct detach_by_parent_data { 1315231281abSKevin Wolf BlockDriverState *parent_b; 1316231281abSKevin Wolf BdrvChild *child_b; 1317231281abSKevin Wolf BlockDriverState *c; 1318231281abSKevin Wolf BdrvChild *child_c; 131957320ca9SKevin Wolf bool by_parent_cb; 1320231281abSKevin Wolf }; 132157320ca9SKevin Wolf static struct detach_by_parent_data detach_by_parent_data; 1322231281abSKevin Wolf 132357320ca9SKevin Wolf static void detach_indirect_bh(void *opaque) 1324231281abSKevin Wolf { 1325231281abSKevin Wolf struct detach_by_parent_data *data = opaque; 1326231281abSKevin Wolf 1327231281abSKevin Wolf bdrv_unref_child(data->parent_b, data->child_b); 1328231281abSKevin Wolf 1329231281abSKevin Wolf bdrv_ref(data->c); 1330231281abSKevin Wolf data->child_c = bdrv_attach_child(data->parent_b, data->c, "PB-C", 1331a16be3cdSMax Reitz &child_of_bds, BDRV_CHILD_DATA, 1332a16be3cdSMax Reitz &error_abort); 1333231281abSKevin Wolf } 1334231281abSKevin Wolf 133557320ca9SKevin Wolf static void detach_by_parent_aio_cb(void *opaque, int ret) 133657320ca9SKevin Wolf { 133757320ca9SKevin Wolf struct detach_by_parent_data *data = &detach_by_parent_data; 133857320ca9SKevin Wolf 133957320ca9SKevin Wolf g_assert_cmpint(ret, ==, 0); 134057320ca9SKevin Wolf if (data->by_parent_cb) { 134157320ca9SKevin Wolf detach_indirect_bh(data); 134257320ca9SKevin Wolf } 134357320ca9SKevin Wolf } 134457320ca9SKevin Wolf 134557320ca9SKevin Wolf static void detach_by_driver_cb_drained_begin(BdrvChild *child) 134657320ca9SKevin Wolf { 134757320ca9SKevin Wolf aio_bh_schedule_oneshot(qemu_get_current_aio_context(), 134857320ca9SKevin Wolf detach_indirect_bh, &detach_by_parent_data); 1349a16be3cdSMax Reitz child_of_bds.drained_begin(child); 135057320ca9SKevin Wolf } 135157320ca9SKevin Wolf 1352bd86fb99SMax Reitz static BdrvChildClass detach_by_driver_cb_class; 135357320ca9SKevin Wolf 1354231281abSKevin Wolf /* 1355231281abSKevin Wolf * Initial graph: 1356231281abSKevin Wolf * 1357231281abSKevin Wolf * PA PB 1358231281abSKevin Wolf * \ / \ 1359231281abSKevin Wolf * A B C 1360231281abSKevin Wolf * 136157320ca9SKevin Wolf * by_parent_cb == true: Test that parent callbacks don't poll 136257320ca9SKevin Wolf * 136357320ca9SKevin Wolf * PA has a pending write request whose callback changes the child nodes of 136457320ca9SKevin Wolf * PB: It removes B and adds C instead. The subtree of PB is drained, which 136557320ca9SKevin Wolf * will indirectly drain the write request, too. 136657320ca9SKevin Wolf * 136757320ca9SKevin Wolf * by_parent_cb == false: Test that bdrv_drain_invoke() doesn't poll 136857320ca9SKevin Wolf * 1369bd86fb99SMax Reitz * PA's BdrvChildClass has a .drained_begin callback that schedules a BH 137057320ca9SKevin Wolf * that does the same graph change. If bdrv_drain_invoke() calls it, the 137157320ca9SKevin Wolf * state is messed up, but if it is only polled in the single 137257320ca9SKevin Wolf * BDRV_POLL_WHILE() at the end of the drain, this should work fine. 1373231281abSKevin Wolf */ 137457320ca9SKevin Wolf static void test_detach_indirect(bool by_parent_cb) 1375231281abSKevin Wolf { 1376231281abSKevin Wolf BlockBackend *blk; 1377231281abSKevin Wolf BlockDriverState *parent_a, *parent_b, *a, *b, *c; 1378231281abSKevin Wolf BdrvChild *child_a, *child_b; 1379231281abSKevin Wolf BlockAIOCB *acb; 1380231281abSKevin Wolf 1381405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0); 1382231281abSKevin Wolf 138357320ca9SKevin Wolf if (!by_parent_cb) { 1384a16be3cdSMax Reitz detach_by_driver_cb_class = child_of_bds; 1385bd86fb99SMax Reitz detach_by_driver_cb_class.drained_begin = 138657320ca9SKevin Wolf detach_by_driver_cb_drained_begin; 138757320ca9SKevin Wolf } 138857320ca9SKevin Wolf 1389231281abSKevin Wolf /* Create all involved nodes */ 1390231281abSKevin Wolf parent_a = bdrv_new_open_driver(&bdrv_test, "parent-a", BDRV_O_RDWR, 1391231281abSKevin Wolf &error_abort); 1392231281abSKevin Wolf parent_b = bdrv_new_open_driver(&bdrv_test, "parent-b", 0, 1393231281abSKevin Wolf &error_abort); 1394231281abSKevin Wolf 1395231281abSKevin Wolf a = bdrv_new_open_driver(&bdrv_test, "a", BDRV_O_RDWR, &error_abort); 1396231281abSKevin Wolf b = bdrv_new_open_driver(&bdrv_test, "b", BDRV_O_RDWR, &error_abort); 1397231281abSKevin Wolf c = bdrv_new_open_driver(&bdrv_test, "c", BDRV_O_RDWR, &error_abort); 1398231281abSKevin Wolf 1399231281abSKevin Wolf /* blk is a BB for parent-a */ 1400d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 1401231281abSKevin Wolf blk_insert_bs(blk, parent_a, &error_abort); 1402231281abSKevin Wolf bdrv_unref(parent_a); 1403231281abSKevin Wolf 140457320ca9SKevin Wolf /* If we want to get bdrv_drain_invoke() to call aio_poll(), the driver 140557320ca9SKevin Wolf * callback must not return immediately. */ 140657320ca9SKevin Wolf if (!by_parent_cb) { 140757320ca9SKevin Wolf BDRVTestState *s = parent_a->opaque; 140857320ca9SKevin Wolf s->sleep_in_drain_begin = true; 140957320ca9SKevin Wolf } 141057320ca9SKevin Wolf 1411231281abSKevin Wolf /* Set child relationships */ 1412231281abSKevin Wolf bdrv_ref(b); 1413231281abSKevin Wolf bdrv_ref(a); 1414a16be3cdSMax Reitz child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_of_bds, 1415a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 141625191e5fSMax Reitz child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_of_bds, 141725191e5fSMax Reitz BDRV_CHILD_COW, &error_abort); 1418231281abSKevin Wolf 1419231281abSKevin Wolf bdrv_ref(a); 142057320ca9SKevin Wolf bdrv_attach_child(parent_a, a, "PA-A", 1421a16be3cdSMax Reitz by_parent_cb ? &child_of_bds : &detach_by_driver_cb_class, 1422a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 1423231281abSKevin Wolf 1424231281abSKevin Wolf g_assert_cmpint(parent_a->refcnt, ==, 1); 1425231281abSKevin Wolf g_assert_cmpint(parent_b->refcnt, ==, 1); 1426231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 3); 1427231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 2); 1428231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 1); 1429231281abSKevin Wolf 1430231281abSKevin Wolf g_assert(QLIST_FIRST(&parent_b->children) == child_a); 1431231281abSKevin Wolf g_assert(QLIST_NEXT(child_a, next) == child_b); 1432231281abSKevin Wolf g_assert(QLIST_NEXT(child_b, next) == NULL); 1433231281abSKevin Wolf 1434231281abSKevin Wolf /* Start the evil write request */ 143557320ca9SKevin Wolf detach_by_parent_data = (struct detach_by_parent_data) { 1436231281abSKevin Wolf .parent_b = parent_b, 1437231281abSKevin Wolf .child_b = child_b, 1438231281abSKevin Wolf .c = c, 143957320ca9SKevin Wolf .by_parent_cb = by_parent_cb, 1440231281abSKevin Wolf }; 144157320ca9SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, detach_by_parent_aio_cb, NULL); 1442231281abSKevin Wolf g_assert(acb != NULL); 1443231281abSKevin Wolf 1444231281abSKevin Wolf /* Drain and check the expected result */ 1445231281abSKevin Wolf bdrv_subtree_drained_begin(parent_b); 1446231281abSKevin Wolf 144757320ca9SKevin Wolf g_assert(detach_by_parent_data.child_c != NULL); 1448231281abSKevin Wolf 1449231281abSKevin Wolf g_assert_cmpint(parent_a->refcnt, ==, 1); 1450231281abSKevin Wolf g_assert_cmpint(parent_b->refcnt, ==, 1); 1451231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 3); 1452231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 1); 1453231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 2); 1454231281abSKevin Wolf 145557320ca9SKevin Wolf g_assert(QLIST_FIRST(&parent_b->children) == detach_by_parent_data.child_c); 145657320ca9SKevin Wolf g_assert(QLIST_NEXT(detach_by_parent_data.child_c, next) == child_a); 1457231281abSKevin Wolf g_assert(QLIST_NEXT(child_a, next) == NULL); 1458231281abSKevin Wolf 1459231281abSKevin Wolf g_assert_cmpint(parent_a->quiesce_counter, ==, 1); 1460231281abSKevin Wolf g_assert_cmpint(parent_b->quiesce_counter, ==, 1); 1461231281abSKevin Wolf g_assert_cmpint(a->quiesce_counter, ==, 1); 1462231281abSKevin Wolf g_assert_cmpint(b->quiesce_counter, ==, 0); 1463231281abSKevin Wolf g_assert_cmpint(c->quiesce_counter, ==, 1); 1464231281abSKevin Wolf 1465231281abSKevin Wolf bdrv_subtree_drained_end(parent_b); 1466231281abSKevin Wolf 1467231281abSKevin Wolf bdrv_unref(parent_b); 1468231281abSKevin Wolf blk_unref(blk); 1469231281abSKevin Wolf 1470231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 1); 1471231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 1); 1472231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 1); 1473231281abSKevin Wolf bdrv_unref(a); 1474231281abSKevin Wolf bdrv_unref(b); 1475231281abSKevin Wolf bdrv_unref(c); 1476231281abSKevin Wolf } 1477231281abSKevin Wolf 147857320ca9SKevin Wolf static void test_detach_by_parent_cb(void) 147957320ca9SKevin Wolf { 148057320ca9SKevin Wolf test_detach_indirect(true); 148157320ca9SKevin Wolf } 148257320ca9SKevin Wolf 148357320ca9SKevin Wolf static void test_detach_by_driver_cb(void) 148457320ca9SKevin Wolf { 148557320ca9SKevin Wolf test_detach_indirect(false); 148657320ca9SKevin Wolf } 1487231281abSKevin Wolf 1488b994c5bcSKevin Wolf static void test_append_to_drained(void) 1489b994c5bcSKevin Wolf { 1490b994c5bcSKevin Wolf BlockBackend *blk; 1491b994c5bcSKevin Wolf BlockDriverState *base, *overlay; 1492b994c5bcSKevin Wolf BDRVTestState *base_s, *overlay_s; 1493b994c5bcSKevin Wolf 1494d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 1495b994c5bcSKevin Wolf base = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort); 1496b994c5bcSKevin Wolf base_s = base->opaque; 1497b994c5bcSKevin Wolf blk_insert_bs(blk, base, &error_abort); 1498b994c5bcSKevin Wolf 1499b994c5bcSKevin Wolf overlay = bdrv_new_open_driver(&bdrv_test, "overlay", BDRV_O_RDWR, 1500b994c5bcSKevin Wolf &error_abort); 1501b994c5bcSKevin Wolf overlay_s = overlay->opaque; 1502b994c5bcSKevin Wolf 1503b994c5bcSKevin Wolf do_drain_begin(BDRV_DRAIN, base); 1504b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 1); 1505b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 1); 1506b994c5bcSKevin Wolf g_assert_cmpint(base->in_flight, ==, 0); 1507b994c5bcSKevin Wolf 1508b994c5bcSKevin Wolf bdrv_append(overlay, base, &error_abort); 1509b994c5bcSKevin Wolf g_assert_cmpint(base->in_flight, ==, 0); 1510b994c5bcSKevin Wolf g_assert_cmpint(overlay->in_flight, ==, 0); 1511b994c5bcSKevin Wolf 1512b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 1); 1513b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 1); 1514b994c5bcSKevin Wolf g_assert_cmpint(overlay->quiesce_counter, ==, 1); 1515b994c5bcSKevin Wolf g_assert_cmpint(overlay_s->drain_count, ==, 1); 1516b994c5bcSKevin Wolf 1517b994c5bcSKevin Wolf do_drain_end(BDRV_DRAIN, base); 1518b994c5bcSKevin Wolf 1519b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 0); 1520b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 0); 1521b994c5bcSKevin Wolf g_assert_cmpint(overlay->quiesce_counter, ==, 0); 1522b994c5bcSKevin Wolf g_assert_cmpint(overlay_s->drain_count, ==, 0); 1523b994c5bcSKevin Wolf 1524ae9d4417SVladimir Sementsov-Ogievskiy bdrv_unref(overlay); 1525b994c5bcSKevin Wolf bdrv_unref(base); 1526b994c5bcSKevin Wolf blk_unref(blk); 1527b994c5bcSKevin Wolf } 1528b994c5bcSKevin Wolf 1529247d2737SKevin Wolf static void test_set_aio_context(void) 1530247d2737SKevin Wolf { 1531247d2737SKevin Wolf BlockDriverState *bs; 1532247d2737SKevin Wolf IOThread *a = iothread_new(); 1533247d2737SKevin Wolf IOThread *b = iothread_new(); 1534247d2737SKevin Wolf AioContext *ctx_a = iothread_get_aio_context(a); 1535247d2737SKevin Wolf AioContext *ctx_b = iothread_get_aio_context(b); 1536247d2737SKevin Wolf 1537247d2737SKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 1538247d2737SKevin Wolf &error_abort); 1539247d2737SKevin Wolf 1540247d2737SKevin Wolf bdrv_drained_begin(bs); 154126bf15e4SKevin Wolf bdrv_try_set_aio_context(bs, ctx_a, &error_abort); 1542247d2737SKevin Wolf 1543247d2737SKevin Wolf aio_context_acquire(ctx_a); 1544247d2737SKevin Wolf bdrv_drained_end(bs); 1545247d2737SKevin Wolf 1546247d2737SKevin Wolf bdrv_drained_begin(bs); 154726bf15e4SKevin Wolf bdrv_try_set_aio_context(bs, ctx_b, &error_abort); 1548247d2737SKevin Wolf aio_context_release(ctx_a); 1549247d2737SKevin Wolf aio_context_acquire(ctx_b); 155026bf15e4SKevin Wolf bdrv_try_set_aio_context(bs, qemu_get_aio_context(), &error_abort); 1551247d2737SKevin Wolf aio_context_release(ctx_b); 1552247d2737SKevin Wolf bdrv_drained_end(bs); 1553247d2737SKevin Wolf 1554247d2737SKevin Wolf bdrv_unref(bs); 1555247d2737SKevin Wolf iothread_join(a); 1556247d2737SKevin Wolf iothread_join(b); 1557247d2737SKevin Wolf } 1558247d2737SKevin Wolf 15598e442810SMax Reitz 15608e442810SMax Reitz typedef struct TestDropBackingBlockJob { 15618e442810SMax Reitz BlockJob common; 15628e442810SMax Reitz bool should_complete; 15638e442810SMax Reitz bool *did_complete; 15642afdc790SMax Reitz BlockDriverState *detach_also; 15651b177bbeSVladimir Sementsov-Ogievskiy BlockDriverState *bs; 15668e442810SMax Reitz } TestDropBackingBlockJob; 15678e442810SMax Reitz 15688e442810SMax Reitz static int coroutine_fn test_drop_backing_job_run(Job *job, Error **errp) 15698e442810SMax Reitz { 15708e442810SMax Reitz TestDropBackingBlockJob *s = 15718e442810SMax Reitz container_of(job, TestDropBackingBlockJob, common.job); 15728e442810SMax Reitz 15738e442810SMax Reitz while (!s->should_complete) { 15748e442810SMax Reitz job_sleep_ns(job, 0); 15758e442810SMax Reitz } 15768e442810SMax Reitz 15778e442810SMax Reitz return 0; 15788e442810SMax Reitz } 15798e442810SMax Reitz 15808e442810SMax Reitz static void test_drop_backing_job_commit(Job *job) 15818e442810SMax Reitz { 15828e442810SMax Reitz TestDropBackingBlockJob *s = 15838e442810SMax Reitz container_of(job, TestDropBackingBlockJob, common.job); 15848e442810SMax Reitz 15851b177bbeSVladimir Sementsov-Ogievskiy bdrv_set_backing_hd(s->bs, NULL, &error_abort); 15862afdc790SMax Reitz bdrv_set_backing_hd(s->detach_also, NULL, &error_abort); 15878e442810SMax Reitz 15888e442810SMax Reitz *s->did_complete = true; 15898e442810SMax Reitz } 15908e442810SMax Reitz 15918e442810SMax Reitz static const BlockJobDriver test_drop_backing_job_driver = { 15928e442810SMax Reitz .job_driver = { 15938e442810SMax Reitz .instance_size = sizeof(TestDropBackingBlockJob), 15948e442810SMax Reitz .free = block_job_free, 15958e442810SMax Reitz .user_resume = block_job_user_resume, 15968e442810SMax Reitz .run = test_drop_backing_job_run, 15978e442810SMax Reitz .commit = test_drop_backing_job_commit, 15988e442810SMax Reitz } 15998e442810SMax Reitz }; 16008e442810SMax Reitz 16018e442810SMax Reitz /** 16028e442810SMax Reitz * Creates a child node with three parent nodes on it, and then runs a 16038e442810SMax Reitz * block job on the final one, parent-node-2. 16048e442810SMax Reitz * 16058e442810SMax Reitz * The job is then asked to complete before a section where the child 16068e442810SMax Reitz * is drained. 16078e442810SMax Reitz * 16088e442810SMax Reitz * Ending this section will undrain the child's parents, first 16098e442810SMax Reitz * parent-node-2, then parent-node-1, then parent-node-0 -- the parent 16108e442810SMax Reitz * list is in reverse order of how they were added. Ending the drain 16118e442810SMax Reitz * on parent-node-2 will resume the job, thus completing it and 16128e442810SMax Reitz * scheduling job_exit(). 16138e442810SMax Reitz * 16148e442810SMax Reitz * Ending the drain on parent-node-1 will poll the AioContext, which 16158e442810SMax Reitz * lets job_exit() and thus test_drop_backing_job_commit() run. That 16162afdc790SMax Reitz * function first removes the child as parent-node-2's backing file. 16178e442810SMax Reitz * 16188e442810SMax Reitz * In old (and buggy) implementations, there are two problems with 16198e442810SMax Reitz * that: 16208e442810SMax Reitz * (A) bdrv_drain_invoke() polls for every node that leaves the 16218e442810SMax Reitz * drained section. This means that job_exit() is scheduled 16228e442810SMax Reitz * before the child has left the drained section. Its 16238e442810SMax Reitz * quiesce_counter is therefore still 1 when it is removed from 16248e442810SMax Reitz * parent-node-2. 16258e442810SMax Reitz * 16268e442810SMax Reitz * (B) bdrv_replace_child_noperm() calls drained_end() on the old 16278e442810SMax Reitz * child's parents as many times as the child is quiesced. This 16288e442810SMax Reitz * means it will call drained_end() on parent-node-2 once. 16298e442810SMax Reitz * Because parent-node-2 is no longer quiesced at this point, this 16308e442810SMax Reitz * will fail. 16318e442810SMax Reitz * 16328e442810SMax Reitz * bdrv_replace_child_noperm() therefore must call drained_end() on 16338e442810SMax Reitz * the parent only if it really is still drained because the child is 16348e442810SMax Reitz * drained. 16352afdc790SMax Reitz * 16362afdc790SMax Reitz * If removing child from parent-node-2 was successful (as it should 16372afdc790SMax Reitz * be), test_drop_backing_job_commit() will then also remove the child 16382afdc790SMax Reitz * from parent-node-0. 16392afdc790SMax Reitz * 16402afdc790SMax Reitz * With an old version of our drain infrastructure ((A) above), that 16412afdc790SMax Reitz * resulted in the following flow: 16422afdc790SMax Reitz * 16432afdc790SMax Reitz * 1. child attempts to leave its drained section. The call recurses 16442afdc790SMax Reitz * to its parents. 16452afdc790SMax Reitz * 16462afdc790SMax Reitz * 2. parent-node-2 leaves the drained section. Polling in 16472afdc790SMax Reitz * bdrv_drain_invoke() will schedule job_exit(). 16482afdc790SMax Reitz * 16492afdc790SMax Reitz * 3. parent-node-1 leaves the drained section. Polling in 16502afdc790SMax Reitz * bdrv_drain_invoke() will run job_exit(), thus disconnecting 16512afdc790SMax Reitz * parent-node-0 from the child node. 16522afdc790SMax Reitz * 16532afdc790SMax Reitz * 4. bdrv_parent_drained_end() uses a QLIST_FOREACH_SAFE() loop to 16542afdc790SMax Reitz * iterate over the parents. Thus, it now accesses the BdrvChild 16552afdc790SMax Reitz * object that used to connect parent-node-0 and the child node. 16562afdc790SMax Reitz * However, that object no longer exists, so it accesses a dangling 16572afdc790SMax Reitz * pointer. 16582afdc790SMax Reitz * 16592afdc790SMax Reitz * The solution is to only poll once when running a bdrv_drained_end() 16602afdc790SMax Reitz * operation, specifically at the end when all drained_end() 16612afdc790SMax Reitz * operations for all involved nodes have been scheduled. 16622afdc790SMax Reitz * Note that this also solves (A) above, thus hiding (B). 16638e442810SMax Reitz */ 16648e442810SMax Reitz static void test_blockjob_commit_by_drained_end(void) 16658e442810SMax Reitz { 16668e442810SMax Reitz BlockDriverState *bs_child, *bs_parents[3]; 16678e442810SMax Reitz TestDropBackingBlockJob *job; 16688e442810SMax Reitz bool job_has_completed = false; 16698e442810SMax Reitz int i; 16708e442810SMax Reitz 16718e442810SMax Reitz bs_child = bdrv_new_open_driver(&bdrv_test, "child-node", BDRV_O_RDWR, 16728e442810SMax Reitz &error_abort); 16738e442810SMax Reitz 16748e442810SMax Reitz for (i = 0; i < 3; i++) { 16758e442810SMax Reitz char name[32]; 16768e442810SMax Reitz snprintf(name, sizeof(name), "parent-node-%i", i); 16778e442810SMax Reitz bs_parents[i] = bdrv_new_open_driver(&bdrv_test, name, BDRV_O_RDWR, 16788e442810SMax Reitz &error_abort); 16798e442810SMax Reitz bdrv_set_backing_hd(bs_parents[i], bs_child, &error_abort); 16808e442810SMax Reitz } 16818e442810SMax Reitz 16828e442810SMax Reitz job = block_job_create("job", &test_drop_backing_job_driver, NULL, 16838e442810SMax Reitz bs_parents[2], 0, BLK_PERM_ALL, 0, 0, NULL, NULL, 16848e442810SMax Reitz &error_abort); 16851b177bbeSVladimir Sementsov-Ogievskiy job->bs = bs_parents[2]; 16868e442810SMax Reitz 16872afdc790SMax Reitz job->detach_also = bs_parents[0]; 16888e442810SMax Reitz job->did_complete = &job_has_completed; 16898e442810SMax Reitz 16908e442810SMax Reitz job_start(&job->common.job); 16918e442810SMax Reitz 16928e442810SMax Reitz job->should_complete = true; 16938e442810SMax Reitz bdrv_drained_begin(bs_child); 16948e442810SMax Reitz g_assert(!job_has_completed); 16958e442810SMax Reitz bdrv_drained_end(bs_child); 16968e442810SMax Reitz g_assert(job_has_completed); 16978e442810SMax Reitz 16988e442810SMax Reitz bdrv_unref(bs_parents[0]); 16998e442810SMax Reitz bdrv_unref(bs_parents[1]); 17008e442810SMax Reitz bdrv_unref(bs_parents[2]); 17018e442810SMax Reitz bdrv_unref(bs_child); 17028e442810SMax Reitz } 17038e442810SMax Reitz 17049746b35cSMax Reitz 17059746b35cSMax Reitz typedef struct TestSimpleBlockJob { 17069746b35cSMax Reitz BlockJob common; 17079746b35cSMax Reitz bool should_complete; 17089746b35cSMax Reitz bool *did_complete; 17099746b35cSMax Reitz } TestSimpleBlockJob; 17109746b35cSMax Reitz 17119746b35cSMax Reitz static int coroutine_fn test_simple_job_run(Job *job, Error **errp) 17129746b35cSMax Reitz { 17139746b35cSMax Reitz TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job); 17149746b35cSMax Reitz 17159746b35cSMax Reitz while (!s->should_complete) { 17169746b35cSMax Reitz job_sleep_ns(job, 0); 17179746b35cSMax Reitz } 17189746b35cSMax Reitz 17199746b35cSMax Reitz return 0; 17209746b35cSMax Reitz } 17219746b35cSMax Reitz 17229746b35cSMax Reitz static void test_simple_job_clean(Job *job) 17239746b35cSMax Reitz { 17249746b35cSMax Reitz TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job); 17259746b35cSMax Reitz *s->did_complete = true; 17269746b35cSMax Reitz } 17279746b35cSMax Reitz 17289746b35cSMax Reitz static const BlockJobDriver test_simple_job_driver = { 17299746b35cSMax Reitz .job_driver = { 17309746b35cSMax Reitz .instance_size = sizeof(TestSimpleBlockJob), 17319746b35cSMax Reitz .free = block_job_free, 17329746b35cSMax Reitz .user_resume = block_job_user_resume, 17339746b35cSMax Reitz .run = test_simple_job_run, 17349746b35cSMax Reitz .clean = test_simple_job_clean, 17359746b35cSMax Reitz }, 17369746b35cSMax Reitz }; 17379746b35cSMax Reitz 17389746b35cSMax Reitz static int drop_intermediate_poll_update_filename(BdrvChild *child, 17399746b35cSMax Reitz BlockDriverState *new_base, 17409746b35cSMax Reitz const char *filename, 17419746b35cSMax Reitz Error **errp) 17429746b35cSMax Reitz { 17439746b35cSMax Reitz /* 17449746b35cSMax Reitz * We are free to poll here, which may change the block graph, if 17459746b35cSMax Reitz * it is not drained. 17469746b35cSMax Reitz */ 17479746b35cSMax Reitz 17489746b35cSMax Reitz /* If the job is not drained: Complete it, schedule job_exit() */ 17499746b35cSMax Reitz aio_poll(qemu_get_current_aio_context(), false); 17509746b35cSMax Reitz /* If the job is not drained: Run job_exit(), finish the job */ 17519746b35cSMax Reitz aio_poll(qemu_get_current_aio_context(), false); 17529746b35cSMax Reitz 17539746b35cSMax Reitz return 0; 17549746b35cSMax Reitz } 17559746b35cSMax Reitz 17569746b35cSMax Reitz /** 17579746b35cSMax Reitz * Test a poll in the midst of bdrv_drop_intermediate(). 17589746b35cSMax Reitz * 1759bd86fb99SMax Reitz * bdrv_drop_intermediate() calls BdrvChildClass.update_filename(), 17609746b35cSMax Reitz * which can yield or poll. This may lead to graph changes, unless 17619746b35cSMax Reitz * the whole subtree in question is drained. 17629746b35cSMax Reitz * 17639746b35cSMax Reitz * We test this on the following graph: 17649746b35cSMax Reitz * 17659746b35cSMax Reitz * Job 17669746b35cSMax Reitz * 17679746b35cSMax Reitz * | 17689746b35cSMax Reitz * job-node 17699746b35cSMax Reitz * | 17709746b35cSMax Reitz * v 17719746b35cSMax Reitz * 17729746b35cSMax Reitz * job-node 17739746b35cSMax Reitz * 17749746b35cSMax Reitz * | 17759746b35cSMax Reitz * backing 17769746b35cSMax Reitz * | 17779746b35cSMax Reitz * v 17789746b35cSMax Reitz * 17799746b35cSMax Reitz * node-2 --chain--> node-1 --chain--> node-0 17809746b35cSMax Reitz * 17819746b35cSMax Reitz * We drop node-1 with bdrv_drop_intermediate(top=node-1, base=node-0). 17829746b35cSMax Reitz * 17839746b35cSMax Reitz * This first updates node-2's backing filename by invoking 17849746b35cSMax Reitz * drop_intermediate_poll_update_filename(), which polls twice. This 17859746b35cSMax Reitz * causes the job to finish, which in turns causes the job-node to be 17869746b35cSMax Reitz * deleted. 17879746b35cSMax Reitz * 17889746b35cSMax Reitz * bdrv_drop_intermediate() uses a QLIST_FOREACH_SAFE() loop, so it 17899746b35cSMax Reitz * already has a pointer to the BdrvChild edge between job-node and 17909746b35cSMax Reitz * node-1. When it tries to handle that edge, we probably get a 17919746b35cSMax Reitz * segmentation fault because the object no longer exists. 17929746b35cSMax Reitz * 17939746b35cSMax Reitz * 17949746b35cSMax Reitz * The solution is for bdrv_drop_intermediate() to drain top's 17959746b35cSMax Reitz * subtree. This prevents graph changes from happening just because 1796bd86fb99SMax Reitz * BdrvChildClass.update_filename() yields or polls. Thus, the block 17979746b35cSMax Reitz * job is paused during that drained section and must finish before or 17989746b35cSMax Reitz * after. 17999746b35cSMax Reitz * 18009746b35cSMax Reitz * (In addition, bdrv_replace_child() must keep the job paused.) 18019746b35cSMax Reitz */ 18029746b35cSMax Reitz static void test_drop_intermediate_poll(void) 18039746b35cSMax Reitz { 1804bd86fb99SMax Reitz static BdrvChildClass chain_child_class; 18059746b35cSMax Reitz BlockDriverState *chain[3]; 18069746b35cSMax Reitz TestSimpleBlockJob *job; 18079746b35cSMax Reitz BlockDriverState *job_node; 18089746b35cSMax Reitz bool job_has_completed = false; 18099746b35cSMax Reitz int i; 18109746b35cSMax Reitz int ret; 18119746b35cSMax Reitz 181225191e5fSMax Reitz chain_child_class = child_of_bds; 1813bd86fb99SMax Reitz chain_child_class.update_filename = drop_intermediate_poll_update_filename; 18149746b35cSMax Reitz 18159746b35cSMax Reitz for (i = 0; i < 3; i++) { 18169746b35cSMax Reitz char name[32]; 18179746b35cSMax Reitz snprintf(name, 32, "node-%i", i); 18189746b35cSMax Reitz 18199746b35cSMax Reitz chain[i] = bdrv_new_open_driver(&bdrv_test, name, 0, &error_abort); 18209746b35cSMax Reitz } 18219746b35cSMax Reitz 18229746b35cSMax Reitz job_node = bdrv_new_open_driver(&bdrv_test, "job-node", BDRV_O_RDWR, 18239746b35cSMax Reitz &error_abort); 18249746b35cSMax Reitz bdrv_set_backing_hd(job_node, chain[1], &error_abort); 18259746b35cSMax Reitz 18269746b35cSMax Reitz /* 18279746b35cSMax Reitz * Establish the chain last, so the chain links are the first 18289746b35cSMax Reitz * elements in the BDS.parents lists 18299746b35cSMax Reitz */ 18309746b35cSMax Reitz for (i = 0; i < 3; i++) { 18319746b35cSMax Reitz if (i) { 18329746b35cSMax Reitz /* Takes the reference to chain[i - 1] */ 18339746b35cSMax Reitz chain[i]->backing = bdrv_attach_child(chain[i], chain[i - 1], 1834bd86fb99SMax Reitz "chain", &chain_child_class, 183525191e5fSMax Reitz BDRV_CHILD_COW, &error_abort); 18369746b35cSMax Reitz } 18379746b35cSMax Reitz } 18389746b35cSMax Reitz 18399746b35cSMax Reitz job = block_job_create("job", &test_simple_job_driver, NULL, job_node, 18409746b35cSMax Reitz 0, BLK_PERM_ALL, 0, 0, NULL, NULL, &error_abort); 18419746b35cSMax Reitz 18429746b35cSMax Reitz /* The job has a reference now */ 18439746b35cSMax Reitz bdrv_unref(job_node); 18449746b35cSMax Reitz 18459746b35cSMax Reitz job->did_complete = &job_has_completed; 18469746b35cSMax Reitz 18479746b35cSMax Reitz job_start(&job->common.job); 18489746b35cSMax Reitz job->should_complete = true; 18499746b35cSMax Reitz 18509746b35cSMax Reitz g_assert(!job_has_completed); 18519746b35cSMax Reitz ret = bdrv_drop_intermediate(chain[1], chain[0], NULL); 18529746b35cSMax Reitz g_assert(ret == 0); 18539746b35cSMax Reitz g_assert(job_has_completed); 18549746b35cSMax Reitz 18559746b35cSMax Reitz bdrv_unref(chain[2]); 18569746b35cSMax Reitz } 18579746b35cSMax Reitz 18580513f984SMax Reitz 18590513f984SMax Reitz typedef struct BDRVReplaceTestState { 18600513f984SMax Reitz bool was_drained; 18610513f984SMax Reitz bool was_undrained; 18620513f984SMax Reitz bool has_read; 18630513f984SMax Reitz 18640513f984SMax Reitz int drain_count; 18650513f984SMax Reitz 18660513f984SMax Reitz bool yield_before_read; 18670513f984SMax Reitz Coroutine *io_co; 18680513f984SMax Reitz Coroutine *drain_co; 18690513f984SMax Reitz } BDRVReplaceTestState; 18700513f984SMax Reitz 18710513f984SMax Reitz static void bdrv_replace_test_close(BlockDriverState *bs) 18720513f984SMax Reitz { 18730513f984SMax Reitz } 18740513f984SMax Reitz 18750513f984SMax Reitz /** 18760513f984SMax Reitz * If @bs has a backing file: 18770513f984SMax Reitz * Yield if .yield_before_read is true (and wait for drain_begin to 18780513f984SMax Reitz * wake us up). 18790513f984SMax Reitz * Forward the read to bs->backing. Set .has_read to true. 18800513f984SMax Reitz * If drain_begin has woken us, wake it in turn. 18810513f984SMax Reitz * 18820513f984SMax Reitz * Otherwise: 18830513f984SMax Reitz * Set .has_read to true and return success. 18840513f984SMax Reitz */ 18850513f984SMax Reitz static int coroutine_fn bdrv_replace_test_co_preadv(BlockDriverState *bs, 1886f7ef38ddSVladimir Sementsov-Ogievskiy int64_t offset, 1887f7ef38ddSVladimir Sementsov-Ogievskiy int64_t bytes, 18880513f984SMax Reitz QEMUIOVector *qiov, 1889f7ef38ddSVladimir Sementsov-Ogievskiy BdrvRequestFlags flags) 18900513f984SMax Reitz { 18910513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 18920513f984SMax Reitz 18930513f984SMax Reitz if (bs->backing) { 18940513f984SMax Reitz int ret; 18950513f984SMax Reitz 18960513f984SMax Reitz g_assert(!s->drain_count); 18970513f984SMax Reitz 18980513f984SMax Reitz s->io_co = qemu_coroutine_self(); 18990513f984SMax Reitz if (s->yield_before_read) { 19000513f984SMax Reitz s->yield_before_read = false; 19010513f984SMax Reitz qemu_coroutine_yield(); 19020513f984SMax Reitz } 19030513f984SMax Reitz s->io_co = NULL; 19040513f984SMax Reitz 1905fae2681aSVladimir Sementsov-Ogievskiy ret = bdrv_co_preadv(bs->backing, offset, bytes, qiov, 0); 19060513f984SMax Reitz s->has_read = true; 19070513f984SMax Reitz 19080513f984SMax Reitz /* Wake up drain_co if it runs */ 19090513f984SMax Reitz if (s->drain_co) { 19100513f984SMax Reitz aio_co_wake(s->drain_co); 19110513f984SMax Reitz } 19120513f984SMax Reitz 19130513f984SMax Reitz return ret; 19140513f984SMax Reitz } 19150513f984SMax Reitz 19160513f984SMax Reitz s->has_read = true; 19170513f984SMax Reitz return 0; 19180513f984SMax Reitz } 19190513f984SMax Reitz 19200513f984SMax Reitz /** 19210513f984SMax Reitz * If .drain_count is 0, wake up .io_co if there is one; and set 19220513f984SMax Reitz * .was_drained. 19230513f984SMax Reitz * Increment .drain_count. 19240513f984SMax Reitz */ 19250513f984SMax Reitz static void coroutine_fn bdrv_replace_test_co_drain_begin(BlockDriverState *bs) 19260513f984SMax Reitz { 19270513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 19280513f984SMax Reitz 19290513f984SMax Reitz if (!s->drain_count) { 19300513f984SMax Reitz /* Keep waking io_co up until it is done */ 19310513f984SMax Reitz s->drain_co = qemu_coroutine_self(); 19320513f984SMax Reitz while (s->io_co) { 19330513f984SMax Reitz aio_co_wake(s->io_co); 19340513f984SMax Reitz s->io_co = NULL; 19350513f984SMax Reitz qemu_coroutine_yield(); 19360513f984SMax Reitz } 19370513f984SMax Reitz s->drain_co = NULL; 19380513f984SMax Reitz 19390513f984SMax Reitz s->was_drained = true; 19400513f984SMax Reitz } 19410513f984SMax Reitz s->drain_count++; 19420513f984SMax Reitz } 19430513f984SMax Reitz 19440513f984SMax Reitz /** 19450513f984SMax Reitz * Reduce .drain_count, set .was_undrained once it reaches 0. 19460513f984SMax Reitz * If .drain_count reaches 0 and the node has a backing file, issue a 19470513f984SMax Reitz * read request. 19480513f984SMax Reitz */ 19490513f984SMax Reitz static void coroutine_fn bdrv_replace_test_co_drain_end(BlockDriverState *bs) 19500513f984SMax Reitz { 19510513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 19520513f984SMax Reitz 19530513f984SMax Reitz g_assert(s->drain_count > 0); 19540513f984SMax Reitz if (!--s->drain_count) { 19550513f984SMax Reitz int ret; 19560513f984SMax Reitz 19570513f984SMax Reitz s->was_undrained = true; 19580513f984SMax Reitz 19590513f984SMax Reitz if (bs->backing) { 19600513f984SMax Reitz char data; 19610513f984SMax Reitz QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, &data, 1); 19620513f984SMax Reitz 19630513f984SMax Reitz /* Queue a read request post-drain */ 19640513f984SMax Reitz ret = bdrv_replace_test_co_preadv(bs, 0, 1, &qiov, 0); 19650513f984SMax Reitz g_assert(ret >= 0); 19660513f984SMax Reitz } 19670513f984SMax Reitz } 19680513f984SMax Reitz } 19690513f984SMax Reitz 19700513f984SMax Reitz static BlockDriver bdrv_replace_test = { 19710513f984SMax Reitz .format_name = "replace_test", 19720513f984SMax Reitz .instance_size = sizeof(BDRVReplaceTestState), 19730513f984SMax Reitz 19740513f984SMax Reitz .bdrv_close = bdrv_replace_test_close, 19750513f984SMax Reitz .bdrv_co_preadv = bdrv_replace_test_co_preadv, 19760513f984SMax Reitz 19770513f984SMax Reitz .bdrv_co_drain_begin = bdrv_replace_test_co_drain_begin, 19780513f984SMax Reitz .bdrv_co_drain_end = bdrv_replace_test_co_drain_end, 19790513f984SMax Reitz 198069dca43dSMax Reitz .bdrv_child_perm = bdrv_default_perms, 19810513f984SMax Reitz }; 19820513f984SMax Reitz 19830513f984SMax Reitz static void coroutine_fn test_replace_child_mid_drain_read_co(void *opaque) 19840513f984SMax Reitz { 19850513f984SMax Reitz int ret; 19860513f984SMax Reitz char data; 19870513f984SMax Reitz 19880513f984SMax Reitz ret = blk_co_pread(opaque, 0, 1, &data, 0); 19890513f984SMax Reitz g_assert(ret >= 0); 19900513f984SMax Reitz } 19910513f984SMax Reitz 19920513f984SMax Reitz /** 19930513f984SMax Reitz * We test two things: 19940513f984SMax Reitz * (1) bdrv_replace_child_noperm() must not undrain the parent if both 19950513f984SMax Reitz * children are drained. 19960513f984SMax Reitz * (2) bdrv_replace_child_noperm() must never flush I/O requests to a 19970513f984SMax Reitz * drained child. If the old child is drained, it must flush I/O 19980513f984SMax Reitz * requests after the new one has been attached. If the new child 19990513f984SMax Reitz * is drained, it must flush I/O requests before the old one is 20000513f984SMax Reitz * detached. 20010513f984SMax Reitz * 20020513f984SMax Reitz * To do so, we create one parent node and two child nodes; then 20030513f984SMax Reitz * attach one of the children (old_child_bs) to the parent, then 20040513f984SMax Reitz * drain both old_child_bs and new_child_bs according to 20050513f984SMax Reitz * old_drain_count and new_drain_count, respectively, and finally 20060513f984SMax Reitz * we invoke bdrv_replace_node() to replace old_child_bs by 20070513f984SMax Reitz * new_child_bs. 20080513f984SMax Reitz * 20090513f984SMax Reitz * The test block driver we use here (bdrv_replace_test) has a read 20100513f984SMax Reitz * function that: 20110513f984SMax Reitz * - For the parent node, can optionally yield, and then forwards the 20120513f984SMax Reitz * read to bdrv_preadv(), 20130513f984SMax Reitz * - For the child node, just returns immediately. 20140513f984SMax Reitz * 20150513f984SMax Reitz * If the read yields, the drain_begin function will wake it up. 20160513f984SMax Reitz * 20170513f984SMax Reitz * The drain_end function issues a read on the parent once it is fully 20180513f984SMax Reitz * undrained (which simulates requests starting to come in again). 20190513f984SMax Reitz */ 20200513f984SMax Reitz static void do_test_replace_child_mid_drain(int old_drain_count, 20210513f984SMax Reitz int new_drain_count) 20220513f984SMax Reitz { 20230513f984SMax Reitz BlockBackend *parent_blk; 20240513f984SMax Reitz BlockDriverState *parent_bs; 20250513f984SMax Reitz BlockDriverState *old_child_bs, *new_child_bs; 20260513f984SMax Reitz BDRVReplaceTestState *parent_s; 20270513f984SMax Reitz BDRVReplaceTestState *old_child_s, *new_child_s; 20280513f984SMax Reitz Coroutine *io_co; 20290513f984SMax Reitz int i; 20300513f984SMax Reitz 20310513f984SMax Reitz parent_bs = bdrv_new_open_driver(&bdrv_replace_test, "parent", 0, 20320513f984SMax Reitz &error_abort); 20330513f984SMax Reitz parent_s = parent_bs->opaque; 20340513f984SMax Reitz 20350513f984SMax Reitz parent_blk = blk_new(qemu_get_aio_context(), 20360513f984SMax Reitz BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL); 20370513f984SMax Reitz blk_insert_bs(parent_blk, parent_bs, &error_abort); 20380513f984SMax Reitz 20390513f984SMax Reitz old_child_bs = bdrv_new_open_driver(&bdrv_replace_test, "old-child", 0, 20400513f984SMax Reitz &error_abort); 20410513f984SMax Reitz new_child_bs = bdrv_new_open_driver(&bdrv_replace_test, "new-child", 0, 20420513f984SMax Reitz &error_abort); 20430513f984SMax Reitz old_child_s = old_child_bs->opaque; 20440513f984SMax Reitz new_child_s = new_child_bs->opaque; 20450513f984SMax Reitz 20460513f984SMax Reitz /* So that we can read something */ 20470513f984SMax Reitz parent_bs->total_sectors = 1; 20480513f984SMax Reitz old_child_bs->total_sectors = 1; 20490513f984SMax Reitz new_child_bs->total_sectors = 1; 20500513f984SMax Reitz 20510513f984SMax Reitz bdrv_ref(old_child_bs); 20520513f984SMax Reitz parent_bs->backing = bdrv_attach_child(parent_bs, old_child_bs, "child", 205325191e5fSMax Reitz &child_of_bds, BDRV_CHILD_COW, 205425191e5fSMax Reitz &error_abort); 20550513f984SMax Reitz 20560513f984SMax Reitz for (i = 0; i < old_drain_count; i++) { 20570513f984SMax Reitz bdrv_drained_begin(old_child_bs); 20580513f984SMax Reitz } 20590513f984SMax Reitz for (i = 0; i < new_drain_count; i++) { 20600513f984SMax Reitz bdrv_drained_begin(new_child_bs); 20610513f984SMax Reitz } 20620513f984SMax Reitz 20630513f984SMax Reitz if (!old_drain_count) { 20640513f984SMax Reitz /* 20650513f984SMax Reitz * Start a read operation that will yield, so it will not 20660513f984SMax Reitz * complete before the node is drained. 20670513f984SMax Reitz */ 20680513f984SMax Reitz parent_s->yield_before_read = true; 20690513f984SMax Reitz io_co = qemu_coroutine_create(test_replace_child_mid_drain_read_co, 20700513f984SMax Reitz parent_blk); 20710513f984SMax Reitz qemu_coroutine_enter(io_co); 20720513f984SMax Reitz } 20730513f984SMax Reitz 20740513f984SMax Reitz /* If we have started a read operation, it should have yielded */ 20750513f984SMax Reitz g_assert(!parent_s->has_read); 20760513f984SMax Reitz 20770513f984SMax Reitz /* Reset drained status so we can see what bdrv_replace_node() does */ 20780513f984SMax Reitz parent_s->was_drained = false; 20790513f984SMax Reitz parent_s->was_undrained = false; 20800513f984SMax Reitz 20810513f984SMax Reitz g_assert(parent_bs->quiesce_counter == old_drain_count); 20820513f984SMax Reitz bdrv_replace_node(old_child_bs, new_child_bs, &error_abort); 20830513f984SMax Reitz g_assert(parent_bs->quiesce_counter == new_drain_count); 20840513f984SMax Reitz 20850513f984SMax Reitz if (!old_drain_count && !new_drain_count) { 20860513f984SMax Reitz /* 20870513f984SMax Reitz * From undrained to undrained drains and undrains the parent, 20880513f984SMax Reitz * because bdrv_replace_node() contains a drained section for 20890513f984SMax Reitz * @old_child_bs. 20900513f984SMax Reitz */ 20910513f984SMax Reitz g_assert(parent_s->was_drained && parent_s->was_undrained); 20920513f984SMax Reitz } else if (!old_drain_count && new_drain_count) { 20930513f984SMax Reitz /* 20940513f984SMax Reitz * From undrained to drained should drain the parent and keep 20950513f984SMax Reitz * it that way. 20960513f984SMax Reitz */ 20970513f984SMax Reitz g_assert(parent_s->was_drained && !parent_s->was_undrained); 20980513f984SMax Reitz } else if (old_drain_count && !new_drain_count) { 20990513f984SMax Reitz /* 21000513f984SMax Reitz * From drained to undrained should undrain the parent and 21010513f984SMax Reitz * keep it that way. 21020513f984SMax Reitz */ 21030513f984SMax Reitz g_assert(!parent_s->was_drained && parent_s->was_undrained); 21040513f984SMax Reitz } else /* if (old_drain_count && new_drain_count) */ { 21050513f984SMax Reitz /* 21060513f984SMax Reitz * From drained to drained must not undrain the parent at any 21070513f984SMax Reitz * point 21080513f984SMax Reitz */ 21090513f984SMax Reitz g_assert(!parent_s->was_drained && !parent_s->was_undrained); 21100513f984SMax Reitz } 21110513f984SMax Reitz 21120513f984SMax Reitz if (!old_drain_count || !new_drain_count) { 21130513f984SMax Reitz /* 21140513f984SMax Reitz * If !old_drain_count, we have started a read request before 21150513f984SMax Reitz * bdrv_replace_node(). If !new_drain_count, the parent must 21160513f984SMax Reitz * have been undrained at some point, and 21170513f984SMax Reitz * bdrv_replace_test_co_drain_end() starts a read request 21180513f984SMax Reitz * then. 21190513f984SMax Reitz */ 21200513f984SMax Reitz g_assert(parent_s->has_read); 21210513f984SMax Reitz } else { 21220513f984SMax Reitz /* 21230513f984SMax Reitz * If the parent was never undrained, there is no way to start 21240513f984SMax Reitz * a read request. 21250513f984SMax Reitz */ 21260513f984SMax Reitz g_assert(!parent_s->has_read); 21270513f984SMax Reitz } 21280513f984SMax Reitz 21290513f984SMax Reitz /* A drained child must have not received any request */ 21300513f984SMax Reitz g_assert(!(old_drain_count && old_child_s->has_read)); 21310513f984SMax Reitz g_assert(!(new_drain_count && new_child_s->has_read)); 21320513f984SMax Reitz 21330513f984SMax Reitz for (i = 0; i < new_drain_count; i++) { 21340513f984SMax Reitz bdrv_drained_end(new_child_bs); 21350513f984SMax Reitz } 21360513f984SMax Reitz for (i = 0; i < old_drain_count; i++) { 21370513f984SMax Reitz bdrv_drained_end(old_child_bs); 21380513f984SMax Reitz } 21390513f984SMax Reitz 21400513f984SMax Reitz /* 21410513f984SMax Reitz * By now, bdrv_replace_test_co_drain_end() must have been called 21420513f984SMax Reitz * at some point while the new child was attached to the parent. 21430513f984SMax Reitz */ 21440513f984SMax Reitz g_assert(parent_s->has_read); 21450513f984SMax Reitz g_assert(new_child_s->has_read); 21460513f984SMax Reitz 21470513f984SMax Reitz blk_unref(parent_blk); 21480513f984SMax Reitz bdrv_unref(parent_bs); 21490513f984SMax Reitz bdrv_unref(old_child_bs); 21500513f984SMax Reitz bdrv_unref(new_child_bs); 21510513f984SMax Reitz } 21520513f984SMax Reitz 21530513f984SMax Reitz static void test_replace_child_mid_drain(void) 21540513f984SMax Reitz { 21550513f984SMax Reitz int old_drain_count, new_drain_count; 21560513f984SMax Reitz 21570513f984SMax Reitz for (old_drain_count = 0; old_drain_count < 2; old_drain_count++) { 21580513f984SMax Reitz for (new_drain_count = 0; new_drain_count < 2; new_drain_count++) { 21590513f984SMax Reitz do_test_replace_child_mid_drain(old_drain_count, new_drain_count); 21600513f984SMax Reitz } 21610513f984SMax Reitz } 21620513f984SMax Reitz } 21630513f984SMax Reitz 2164881cfd17SKevin Wolf int main(int argc, char **argv) 2165881cfd17SKevin Wolf { 2166bb675689SKevin Wolf int ret; 2167bb675689SKevin Wolf 2168881cfd17SKevin Wolf bdrv_init(); 2169881cfd17SKevin Wolf qemu_init_main_loop(&error_abort); 2170881cfd17SKevin Wolf 2171881cfd17SKevin Wolf g_test_init(&argc, &argv, NULL); 2172bb675689SKevin Wolf qemu_event_init(&done_event, false); 2173881cfd17SKevin Wolf 2174881cfd17SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all); 217586e1c840SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain); 2176d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain_subtree", 2177d2a85d0fSKevin Wolf test_drv_cb_drain_subtree); 2178881cfd17SKevin Wolf 21796d0252f2SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain_all", 21806d0252f2SKevin Wolf test_drv_cb_co_drain_all); 21810582eb10SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain", test_drv_cb_co_drain); 21820582eb10SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain_subtree", 21830582eb10SKevin Wolf test_drv_cb_co_drain_subtree); 21840582eb10SKevin Wolf 21850582eb10SKevin Wolf 218689a6ceabSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all); 218789a6ceabSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain); 2188d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain_subtree", 2189d2a85d0fSKevin Wolf test_quiesce_drain_subtree); 219089a6ceabSKevin Wolf 21916d0252f2SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain_all", 21926d0252f2SKevin Wolf test_quiesce_co_drain_all); 21930582eb10SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain", test_quiesce_co_drain); 21940582eb10SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain_subtree", 21950582eb10SKevin Wolf test_quiesce_co_drain_subtree); 21960582eb10SKevin Wolf 21976c429a6aSKevin Wolf g_test_add_func("/bdrv-drain/nested", test_nested); 219827e64474SKevin Wolf g_test_add_func("/bdrv-drain/multiparent", test_multiparent); 219919f7a7e5SKevin Wolf 220019f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/graph-change/drain_subtree", 220119f7a7e5SKevin Wolf test_graph_change_drain_subtree); 220219f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/graph-change/drain_all", 220319f7a7e5SKevin Wolf test_graph_change_drain_all); 22046c429a6aSKevin Wolf 2205bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain_all", test_iothread_drain_all); 2206bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain", test_iothread_drain); 2207bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain_subtree", 2208bb675689SKevin Wolf test_iothread_drain_subtree); 2209bb675689SKevin Wolf 22107253220dSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all); 22117253220dSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain); 2212d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain_subtree", 2213d2a85d0fSKevin Wolf test_blockjob_drain_subtree); 22147253220dSKevin Wolf 2215d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain_all", 2216d49725afSKevin Wolf test_blockjob_error_drain_all); 2217d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain", 2218d49725afSKevin Wolf test_blockjob_error_drain); 2219d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain_subtree", 2220d49725afSKevin Wolf test_blockjob_error_drain_subtree); 2221d49725afSKevin Wolf 2222f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain_all", 2223f62c1729SKevin Wolf test_blockjob_iothread_drain_all); 2224f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain", 2225f62c1729SKevin Wolf test_blockjob_iothread_drain); 2226f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain_subtree", 2227f62c1729SKevin Wolf test_blockjob_iothread_drain_subtree); 2228f62c1729SKevin Wolf 2229d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_all", 2230d49725afSKevin Wolf test_blockjob_iothread_error_drain_all); 2231d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain", 2232d49725afSKevin Wolf test_blockjob_iothread_error_drain); 2233d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_subtree", 2234d49725afSKevin Wolf test_blockjob_iothread_error_drain_subtree); 2235d49725afSKevin Wolf 2236ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/deletion/drain", test_delete_by_drain); 223719f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain_all", test_detach_by_drain_all); 2238ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain", test_detach_by_drain); 2239ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain_subtree", test_detach_by_drain_subtree); 2240231281abSKevin Wolf g_test_add_func("/bdrv-drain/detach/parent_cb", test_detach_by_parent_cb); 224157320ca9SKevin Wolf g_test_add_func("/bdrv-drain/detach/driver_cb", test_detach_by_driver_cb); 22424c8158e3SMax Reitz 2243b994c5bcSKevin Wolf g_test_add_func("/bdrv-drain/attach/drain", test_append_to_drained); 2244b994c5bcSKevin Wolf 2245247d2737SKevin Wolf g_test_add_func("/bdrv-drain/set_aio_context", test_set_aio_context); 2246247d2737SKevin Wolf 22478e442810SMax Reitz g_test_add_func("/bdrv-drain/blockjob/commit_by_drained_end", 22488e442810SMax Reitz test_blockjob_commit_by_drained_end); 22498e442810SMax Reitz 22509746b35cSMax Reitz g_test_add_func("/bdrv-drain/bdrv_drop_intermediate/poll", 22519746b35cSMax Reitz test_drop_intermediate_poll); 22529746b35cSMax Reitz 22530513f984SMax Reitz g_test_add_func("/bdrv-drain/replace_child/mid-drain", 22540513f984SMax Reitz test_replace_child_mid_drain); 22550513f984SMax Reitz 2256bb675689SKevin Wolf ret = g_test_run(); 2257bb675689SKevin Wolf qemu_event_destroy(&done_event); 2258bb675689SKevin Wolf return ret; 2259881cfd17SKevin Wolf } 2260