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, 68881cfd17SKevin Wolf uint64_t offset, uint64_t bytes, 69881cfd17SKevin Wolf QEMUIOVector *qiov, int flags) 70881cfd17SKevin Wolf { 71bb675689SKevin Wolf BDRVTestState *s = bs->opaque; 72bb675689SKevin Wolf 73881cfd17SKevin Wolf /* We want this request to stay until the polling loop in drain waits for 74881cfd17SKevin Wolf * it to complete. We need to sleep a while as bdrv_drain_invoke() comes 75881cfd17SKevin Wolf * first and polls its result, too, but it shouldn't accidentally complete 76881cfd17SKevin Wolf * this request yet. */ 77881cfd17SKevin Wolf qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000); 78881cfd17SKevin Wolf 79bb675689SKevin Wolf if (s->bh_indirection_ctx) { 80bb675689SKevin Wolf aio_bh_schedule_oneshot(s->bh_indirection_ctx, co_reenter_bh, 81bb675689SKevin Wolf qemu_coroutine_self()); 82bb675689SKevin Wolf qemu_coroutine_yield(); 83bb675689SKevin Wolf } 84bb675689SKevin Wolf 85881cfd17SKevin Wolf return 0; 86881cfd17SKevin Wolf } 87881cfd17SKevin Wolf 889746b35cSMax Reitz static int bdrv_test_change_backing_file(BlockDriverState *bs, 899746b35cSMax Reitz const char *backing_file, 909746b35cSMax Reitz const char *backing_fmt) 919746b35cSMax Reitz { 929746b35cSMax Reitz return 0; 939746b35cSMax Reitz } 949746b35cSMax Reitz 95881cfd17SKevin Wolf static BlockDriver bdrv_test = { 96881cfd17SKevin Wolf .format_name = "test", 97881cfd17SKevin Wolf .instance_size = sizeof(BDRVTestState), 98*25f78d9eSVladimir Sementsov-Ogievskiy .supports_backing = true, 99881cfd17SKevin Wolf 100881cfd17SKevin Wolf .bdrv_close = bdrv_test_close, 101881cfd17SKevin Wolf .bdrv_co_preadv = bdrv_test_co_preadv, 102881cfd17SKevin Wolf 103881cfd17SKevin Wolf .bdrv_co_drain_begin = bdrv_test_co_drain_begin, 104881cfd17SKevin Wolf .bdrv_co_drain_end = bdrv_test_co_drain_end, 10586e1c840SKevin Wolf 106e5d8a406SMax Reitz .bdrv_child_perm = bdrv_default_perms, 1079746b35cSMax Reitz 1089746b35cSMax Reitz .bdrv_change_backing_file = bdrv_test_change_backing_file, 109881cfd17SKevin Wolf }; 110881cfd17SKevin Wolf 111881cfd17SKevin Wolf static void aio_ret_cb(void *opaque, int ret) 112881cfd17SKevin Wolf { 113881cfd17SKevin Wolf int *aio_ret = opaque; 114881cfd17SKevin Wolf *aio_ret = ret; 115881cfd17SKevin Wolf } 116881cfd17SKevin Wolf 1170582eb10SKevin Wolf typedef struct CallInCoroutineData { 1180582eb10SKevin Wolf void (*entry)(void); 1190582eb10SKevin Wolf bool done; 1200582eb10SKevin Wolf } CallInCoroutineData; 1210582eb10SKevin Wolf 1220582eb10SKevin Wolf static coroutine_fn void call_in_coroutine_entry(void *opaque) 1230582eb10SKevin Wolf { 1240582eb10SKevin Wolf CallInCoroutineData *data = opaque; 1250582eb10SKevin Wolf 1260582eb10SKevin Wolf data->entry(); 1270582eb10SKevin Wolf data->done = true; 1280582eb10SKevin Wolf } 1290582eb10SKevin Wolf 1300582eb10SKevin Wolf static void call_in_coroutine(void (*entry)(void)) 1310582eb10SKevin Wolf { 1320582eb10SKevin Wolf Coroutine *co; 1330582eb10SKevin Wolf CallInCoroutineData data = { 1340582eb10SKevin Wolf .entry = entry, 1350582eb10SKevin Wolf .done = false, 1360582eb10SKevin Wolf }; 1370582eb10SKevin Wolf 1380582eb10SKevin Wolf co = qemu_coroutine_create(call_in_coroutine_entry, &data); 1390582eb10SKevin Wolf qemu_coroutine_enter(co); 1400582eb10SKevin Wolf while (!data.done) { 1410582eb10SKevin Wolf aio_poll(qemu_get_aio_context(), true); 1420582eb10SKevin Wolf } 1430582eb10SKevin Wolf } 1440582eb10SKevin Wolf 14586e1c840SKevin Wolf enum drain_type { 14686e1c840SKevin Wolf BDRV_DRAIN_ALL, 14786e1c840SKevin Wolf BDRV_DRAIN, 148d2a85d0fSKevin Wolf BDRV_SUBTREE_DRAIN, 1496c429a6aSKevin Wolf DRAIN_TYPE_MAX, 15086e1c840SKevin Wolf }; 15186e1c840SKevin Wolf 15286e1c840SKevin Wolf static void do_drain_begin(enum drain_type drain_type, BlockDriverState *bs) 15386e1c840SKevin Wolf { 15486e1c840SKevin Wolf switch (drain_type) { 15586e1c840SKevin Wolf case BDRV_DRAIN_ALL: bdrv_drain_all_begin(); break; 15686e1c840SKevin Wolf case BDRV_DRAIN: bdrv_drained_begin(bs); break; 157d2a85d0fSKevin Wolf case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_begin(bs); break; 15886e1c840SKevin Wolf default: g_assert_not_reached(); 15986e1c840SKevin Wolf } 16086e1c840SKevin Wolf } 16186e1c840SKevin Wolf 16286e1c840SKevin Wolf static void do_drain_end(enum drain_type drain_type, BlockDriverState *bs) 16386e1c840SKevin Wolf { 16486e1c840SKevin Wolf switch (drain_type) { 16586e1c840SKevin Wolf case BDRV_DRAIN_ALL: bdrv_drain_all_end(); break; 16686e1c840SKevin Wolf case BDRV_DRAIN: bdrv_drained_end(bs); break; 167d2a85d0fSKevin Wolf case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_end(bs); break; 16886e1c840SKevin Wolf default: g_assert_not_reached(); 16986e1c840SKevin Wolf } 17086e1c840SKevin Wolf } 17186e1c840SKevin Wolf 172f62c1729SKevin Wolf static void do_drain_begin_unlocked(enum drain_type drain_type, BlockDriverState *bs) 173f62c1729SKevin Wolf { 174f62c1729SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 175f62c1729SKevin Wolf aio_context_acquire(bdrv_get_aio_context(bs)); 176f62c1729SKevin Wolf } 177f62c1729SKevin Wolf do_drain_begin(drain_type, bs); 178f62c1729SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 179f62c1729SKevin Wolf aio_context_release(bdrv_get_aio_context(bs)); 180f62c1729SKevin Wolf } 181f62c1729SKevin Wolf } 182f62c1729SKevin Wolf 183f62c1729SKevin Wolf static void do_drain_end_unlocked(enum drain_type drain_type, BlockDriverState *bs) 184f62c1729SKevin Wolf { 185f62c1729SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 186f62c1729SKevin Wolf aio_context_acquire(bdrv_get_aio_context(bs)); 187f62c1729SKevin Wolf } 188f62c1729SKevin Wolf do_drain_end(drain_type, bs); 189f62c1729SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 190f62c1729SKevin Wolf aio_context_release(bdrv_get_aio_context(bs)); 191f62c1729SKevin Wolf } 192f62c1729SKevin Wolf } 193f62c1729SKevin Wolf 19486e1c840SKevin Wolf static void test_drv_cb_common(enum drain_type drain_type, bool recursive) 195881cfd17SKevin Wolf { 196881cfd17SKevin Wolf BlockBackend *blk; 19786e1c840SKevin Wolf BlockDriverState *bs, *backing; 19886e1c840SKevin Wolf BDRVTestState *s, *backing_s; 199881cfd17SKevin Wolf BlockAIOCB *acb; 200881cfd17SKevin Wolf int aio_ret; 201881cfd17SKevin Wolf 202405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0); 203881cfd17SKevin Wolf 204d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 205881cfd17SKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 206881cfd17SKevin Wolf &error_abort); 207881cfd17SKevin Wolf s = bs->opaque; 208881cfd17SKevin Wolf blk_insert_bs(blk, bs, &error_abort); 209881cfd17SKevin Wolf 21086e1c840SKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 21186e1c840SKevin Wolf backing_s = backing->opaque; 21286e1c840SKevin Wolf bdrv_set_backing_hd(bs, backing, &error_abort); 21386e1c840SKevin Wolf 214881cfd17SKevin Wolf /* Simple bdrv_drain_all_begin/end pair, check that CBs are called */ 215881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 21686e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 21786e1c840SKevin Wolf 21886e1c840SKevin Wolf do_drain_begin(drain_type, bs); 21986e1c840SKevin Wolf 220881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 1); 22186e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, !!recursive); 22286e1c840SKevin Wolf 22386e1c840SKevin Wolf do_drain_end(drain_type, bs); 22486e1c840SKevin Wolf 225881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 22686e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 227881cfd17SKevin Wolf 228881cfd17SKevin Wolf /* Now do the same while a request is pending */ 229881cfd17SKevin Wolf aio_ret = -EINPROGRESS; 230881cfd17SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret); 231881cfd17SKevin Wolf g_assert(acb != NULL); 232881cfd17SKevin Wolf g_assert_cmpint(aio_ret, ==, -EINPROGRESS); 233881cfd17SKevin Wolf 234881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 23586e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 23686e1c840SKevin Wolf 23786e1c840SKevin Wolf do_drain_begin(drain_type, bs); 23886e1c840SKevin Wolf 239881cfd17SKevin Wolf g_assert_cmpint(aio_ret, ==, 0); 240881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 1); 24186e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, !!recursive); 242881cfd17SKevin Wolf 24386e1c840SKevin Wolf do_drain_end(drain_type, bs); 24486e1c840SKevin Wolf 24586e1c840SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 24686e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 24786e1c840SKevin Wolf 24886e1c840SKevin Wolf bdrv_unref(backing); 249881cfd17SKevin Wolf bdrv_unref(bs); 250881cfd17SKevin Wolf blk_unref(blk); 251881cfd17SKevin Wolf } 252881cfd17SKevin Wolf 25386e1c840SKevin Wolf static void test_drv_cb_drain_all(void) 25486e1c840SKevin Wolf { 25586e1c840SKevin Wolf test_drv_cb_common(BDRV_DRAIN_ALL, true); 25686e1c840SKevin Wolf } 25786e1c840SKevin Wolf 25886e1c840SKevin Wolf static void test_drv_cb_drain(void) 25986e1c840SKevin Wolf { 26086e1c840SKevin Wolf test_drv_cb_common(BDRV_DRAIN, false); 26186e1c840SKevin Wolf } 26286e1c840SKevin Wolf 263d2a85d0fSKevin Wolf static void test_drv_cb_drain_subtree(void) 264d2a85d0fSKevin Wolf { 265d2a85d0fSKevin Wolf test_drv_cb_common(BDRV_SUBTREE_DRAIN, true); 266d2a85d0fSKevin Wolf } 267d2a85d0fSKevin Wolf 2686d0252f2SKevin Wolf static void test_drv_cb_co_drain_all(void) 2696d0252f2SKevin Wolf { 2706d0252f2SKevin Wolf call_in_coroutine(test_drv_cb_drain_all); 2716d0252f2SKevin Wolf } 2726d0252f2SKevin Wolf 2730582eb10SKevin Wolf static void test_drv_cb_co_drain(void) 2740582eb10SKevin Wolf { 2750582eb10SKevin Wolf call_in_coroutine(test_drv_cb_drain); 2760582eb10SKevin Wolf } 2770582eb10SKevin Wolf 2780582eb10SKevin Wolf static void test_drv_cb_co_drain_subtree(void) 2790582eb10SKevin Wolf { 2800582eb10SKevin Wolf call_in_coroutine(test_drv_cb_drain_subtree); 2810582eb10SKevin Wolf } 2820582eb10SKevin Wolf 28389a6ceabSKevin Wolf static void test_quiesce_common(enum drain_type drain_type, bool recursive) 28489a6ceabSKevin Wolf { 28589a6ceabSKevin Wolf BlockBackend *blk; 28689a6ceabSKevin Wolf BlockDriverState *bs, *backing; 28789a6ceabSKevin Wolf 288d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 28989a6ceabSKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 29089a6ceabSKevin Wolf &error_abort); 29189a6ceabSKevin Wolf blk_insert_bs(blk, bs, &error_abort); 29289a6ceabSKevin Wolf 29389a6ceabSKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 29489a6ceabSKevin Wolf bdrv_set_backing_hd(bs, backing, &error_abort); 29589a6ceabSKevin Wolf 29689a6ceabSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 29789a6ceabSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 29889a6ceabSKevin Wolf 29989a6ceabSKevin Wolf do_drain_begin(drain_type, bs); 30089a6ceabSKevin Wolf 30189a6ceabSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 1); 30289a6ceabSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, !!recursive); 30389a6ceabSKevin Wolf 30489a6ceabSKevin Wolf do_drain_end(drain_type, bs); 30589a6ceabSKevin Wolf 30689a6ceabSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 30789a6ceabSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 30889a6ceabSKevin Wolf 30989a6ceabSKevin Wolf bdrv_unref(backing); 31089a6ceabSKevin Wolf bdrv_unref(bs); 31189a6ceabSKevin Wolf blk_unref(blk); 31289a6ceabSKevin Wolf } 31389a6ceabSKevin Wolf 31489a6ceabSKevin Wolf static void test_quiesce_drain_all(void) 31589a6ceabSKevin Wolf { 31679ab8b21SKevin Wolf test_quiesce_common(BDRV_DRAIN_ALL, true); 31789a6ceabSKevin Wolf } 31889a6ceabSKevin Wolf 31989a6ceabSKevin Wolf static void test_quiesce_drain(void) 32089a6ceabSKevin Wolf { 32189a6ceabSKevin Wolf test_quiesce_common(BDRV_DRAIN, false); 32289a6ceabSKevin Wolf } 32389a6ceabSKevin Wolf 324d2a85d0fSKevin Wolf static void test_quiesce_drain_subtree(void) 325d2a85d0fSKevin Wolf { 326d2a85d0fSKevin Wolf test_quiesce_common(BDRV_SUBTREE_DRAIN, true); 327d2a85d0fSKevin Wolf } 328d2a85d0fSKevin Wolf 3296d0252f2SKevin Wolf static void test_quiesce_co_drain_all(void) 3306d0252f2SKevin Wolf { 3316d0252f2SKevin Wolf call_in_coroutine(test_quiesce_drain_all); 3326d0252f2SKevin Wolf } 3336d0252f2SKevin Wolf 3340582eb10SKevin Wolf static void test_quiesce_co_drain(void) 3350582eb10SKevin Wolf { 3360582eb10SKevin Wolf call_in_coroutine(test_quiesce_drain); 3370582eb10SKevin Wolf } 3380582eb10SKevin Wolf 3390582eb10SKevin Wolf static void test_quiesce_co_drain_subtree(void) 3400582eb10SKevin Wolf { 3410582eb10SKevin Wolf call_in_coroutine(test_quiesce_drain_subtree); 3420582eb10SKevin Wolf } 3430582eb10SKevin Wolf 3446c429a6aSKevin Wolf static void test_nested(void) 3456c429a6aSKevin Wolf { 3466c429a6aSKevin Wolf BlockBackend *blk; 3476c429a6aSKevin Wolf BlockDriverState *bs, *backing; 3486c429a6aSKevin Wolf BDRVTestState *s, *backing_s; 3496c429a6aSKevin Wolf enum drain_type outer, inner; 3506c429a6aSKevin Wolf 351d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 3526c429a6aSKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 3536c429a6aSKevin Wolf &error_abort); 3546c429a6aSKevin Wolf s = bs->opaque; 3556c429a6aSKevin Wolf blk_insert_bs(blk, bs, &error_abort); 3566c429a6aSKevin Wolf 3576c429a6aSKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 3586c429a6aSKevin Wolf backing_s = backing->opaque; 3596c429a6aSKevin Wolf bdrv_set_backing_hd(bs, backing, &error_abort); 3606c429a6aSKevin Wolf 3616c429a6aSKevin Wolf for (outer = 0; outer < DRAIN_TYPE_MAX; outer++) { 3626c429a6aSKevin Wolf for (inner = 0; inner < DRAIN_TYPE_MAX; inner++) { 36379ab8b21SKevin Wolf int backing_quiesce = (outer != BDRV_DRAIN) + 3646c429a6aSKevin Wolf (inner != BDRV_DRAIN); 3656c429a6aSKevin Wolf 3666c429a6aSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 3676c429a6aSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 3686c429a6aSKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 3696c429a6aSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 3706c429a6aSKevin Wolf 3716c429a6aSKevin Wolf do_drain_begin(outer, bs); 3726c429a6aSKevin Wolf do_drain_begin(inner, bs); 3736c429a6aSKevin Wolf 37479ab8b21SKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 2); 3756c429a6aSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, backing_quiesce); 3766c429a6aSKevin Wolf g_assert_cmpint(s->drain_count, ==, 2); 37779ab8b21SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, backing_quiesce); 3786c429a6aSKevin Wolf 3796c429a6aSKevin Wolf do_drain_end(inner, bs); 3806c429a6aSKevin Wolf do_drain_end(outer, bs); 3816c429a6aSKevin Wolf 3826c429a6aSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 3836c429a6aSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 3846c429a6aSKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 3856c429a6aSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 3866c429a6aSKevin Wolf } 3876c429a6aSKevin Wolf } 3886c429a6aSKevin Wolf 3896c429a6aSKevin Wolf bdrv_unref(backing); 3906c429a6aSKevin Wolf bdrv_unref(bs); 3916c429a6aSKevin Wolf blk_unref(blk); 3926c429a6aSKevin Wolf } 3936c429a6aSKevin Wolf 39427e64474SKevin Wolf static void test_multiparent(void) 39527e64474SKevin Wolf { 39627e64474SKevin Wolf BlockBackend *blk_a, *blk_b; 39727e64474SKevin Wolf BlockDriverState *bs_a, *bs_b, *backing; 39827e64474SKevin Wolf BDRVTestState *a_s, *b_s, *backing_s; 39927e64474SKevin Wolf 400d861ab3aSKevin Wolf blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 40127e64474SKevin Wolf bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, 40227e64474SKevin Wolf &error_abort); 40327e64474SKevin Wolf a_s = bs_a->opaque; 40427e64474SKevin Wolf blk_insert_bs(blk_a, bs_a, &error_abort); 40527e64474SKevin Wolf 406d861ab3aSKevin Wolf blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 40727e64474SKevin Wolf bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, 40827e64474SKevin Wolf &error_abort); 40927e64474SKevin Wolf b_s = bs_b->opaque; 41027e64474SKevin Wolf blk_insert_bs(blk_b, bs_b, &error_abort); 41127e64474SKevin Wolf 41227e64474SKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 41327e64474SKevin Wolf backing_s = backing->opaque; 41427e64474SKevin Wolf bdrv_set_backing_hd(bs_a, backing, &error_abort); 41527e64474SKevin Wolf bdrv_set_backing_hd(bs_b, backing, &error_abort); 41627e64474SKevin Wolf 41727e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 41827e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 41927e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 42027e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 42127e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 42227e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 42327e64474SKevin Wolf 42427e64474SKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); 42527e64474SKevin Wolf 42627e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 42727e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 42827e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 1); 42927e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 43027e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 43127e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 1); 43227e64474SKevin Wolf 43327e64474SKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); 43427e64474SKevin Wolf 43527e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 2); 43627e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 2); 43727e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 2); 43827e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 2); 43927e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 2); 44027e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 2); 44127e64474SKevin Wolf 44227e64474SKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); 44327e64474SKevin Wolf 44427e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 44527e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 44627e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 1); 44727e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 44827e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 44927e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 1); 45027e64474SKevin Wolf 45127e64474SKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 45227e64474SKevin Wolf 45327e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 45427e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 45527e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 45627e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 45727e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 45827e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 45927e64474SKevin Wolf 46027e64474SKevin Wolf bdrv_unref(backing); 46127e64474SKevin Wolf bdrv_unref(bs_a); 46227e64474SKevin Wolf bdrv_unref(bs_b); 46327e64474SKevin Wolf blk_unref(blk_a); 46427e64474SKevin Wolf blk_unref(blk_b); 46527e64474SKevin Wolf } 46627e64474SKevin Wolf 46719f7a7e5SKevin Wolf static void test_graph_change_drain_subtree(void) 468acebcf8dSKevin Wolf { 469acebcf8dSKevin Wolf BlockBackend *blk_a, *blk_b; 470acebcf8dSKevin Wolf BlockDriverState *bs_a, *bs_b, *backing; 471acebcf8dSKevin Wolf BDRVTestState *a_s, *b_s, *backing_s; 472acebcf8dSKevin Wolf 473d861ab3aSKevin Wolf blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 474acebcf8dSKevin Wolf bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, 475acebcf8dSKevin Wolf &error_abort); 476acebcf8dSKevin Wolf a_s = bs_a->opaque; 477acebcf8dSKevin Wolf blk_insert_bs(blk_a, bs_a, &error_abort); 478acebcf8dSKevin Wolf 479d861ab3aSKevin Wolf blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 480acebcf8dSKevin Wolf bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, 481acebcf8dSKevin Wolf &error_abort); 482acebcf8dSKevin Wolf b_s = bs_b->opaque; 483acebcf8dSKevin Wolf blk_insert_bs(blk_b, bs_b, &error_abort); 484acebcf8dSKevin Wolf 485acebcf8dSKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 486acebcf8dSKevin Wolf backing_s = backing->opaque; 487acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_a, backing, &error_abort); 488acebcf8dSKevin Wolf 489acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 490acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 491acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 492acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 493acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 494acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 495acebcf8dSKevin Wolf 496acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); 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_b); 500acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); 501acebcf8dSKevin Wolf 502acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_b, backing, &error_abort); 503acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 5); 504acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 5); 505acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 5); 506acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 5); 507acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 5); 508acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 5); 509acebcf8dSKevin Wolf 510acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_b, NULL, &error_abort); 511acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 3); 512acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 2); 513acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 3); 514acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 3); 515acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 2); 516acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 3); 517acebcf8dSKevin Wolf 518acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_b, backing, &error_abort); 519acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 5); 520acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 5); 521acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 5); 522acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 5); 523acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 5); 524acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 5); 525acebcf8dSKevin Wolf 526acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); 527acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); 528acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 529acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 530acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 531acebcf8dSKevin Wolf 532acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 533acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 534acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 535acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 536acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 537acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 538acebcf8dSKevin Wolf 539acebcf8dSKevin Wolf bdrv_unref(backing); 540acebcf8dSKevin Wolf bdrv_unref(bs_a); 541acebcf8dSKevin Wolf bdrv_unref(bs_b); 542acebcf8dSKevin Wolf blk_unref(blk_a); 543acebcf8dSKevin Wolf blk_unref(blk_b); 544acebcf8dSKevin Wolf } 545acebcf8dSKevin Wolf 54619f7a7e5SKevin Wolf static void test_graph_change_drain_all(void) 54719f7a7e5SKevin Wolf { 54819f7a7e5SKevin Wolf BlockBackend *blk_a, *blk_b; 54919f7a7e5SKevin Wolf BlockDriverState *bs_a, *bs_b; 55019f7a7e5SKevin Wolf BDRVTestState *a_s, *b_s; 55119f7a7e5SKevin Wolf 55219f7a7e5SKevin Wolf /* Create node A with a BlockBackend */ 553d861ab3aSKevin Wolf blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 55419f7a7e5SKevin Wolf bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, 55519f7a7e5SKevin Wolf &error_abort); 55619f7a7e5SKevin Wolf a_s = bs_a->opaque; 55719f7a7e5SKevin Wolf blk_insert_bs(blk_a, bs_a, &error_abort); 55819f7a7e5SKevin Wolf 55919f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 56019f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 56119f7a7e5SKevin Wolf 56219f7a7e5SKevin Wolf /* Call bdrv_drain_all_begin() */ 56319f7a7e5SKevin Wolf bdrv_drain_all_begin(); 56419f7a7e5SKevin Wolf 56519f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 56619f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 56719f7a7e5SKevin Wolf 56819f7a7e5SKevin Wolf /* Create node B with a BlockBackend */ 569d861ab3aSKevin Wolf blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 57019f7a7e5SKevin Wolf bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, 57119f7a7e5SKevin Wolf &error_abort); 57219f7a7e5SKevin Wolf b_s = bs_b->opaque; 57319f7a7e5SKevin Wolf blk_insert_bs(blk_b, bs_b, &error_abort); 57419f7a7e5SKevin Wolf 57519f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 57619f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 57719f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 57819f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 57919f7a7e5SKevin Wolf 58019f7a7e5SKevin Wolf /* Unref and finally delete node A */ 58119f7a7e5SKevin Wolf blk_unref(blk_a); 58219f7a7e5SKevin Wolf 58319f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 58419f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 58519f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 58619f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 58719f7a7e5SKevin Wolf 58819f7a7e5SKevin Wolf bdrv_unref(bs_a); 58919f7a7e5SKevin Wolf 59019f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 59119f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 59219f7a7e5SKevin Wolf 59319f7a7e5SKevin Wolf /* End the drained section */ 59419f7a7e5SKevin Wolf bdrv_drain_all_end(); 59519f7a7e5SKevin Wolf 59619f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 59719f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 5981a6d3bd2SGreg Kurz g_assert_cmpint(qemu_get_aio_context()->external_disable_cnt, ==, 0); 59919f7a7e5SKevin Wolf 60019f7a7e5SKevin Wolf bdrv_unref(bs_b); 60119f7a7e5SKevin Wolf blk_unref(blk_b); 60219f7a7e5SKevin Wolf } 60319f7a7e5SKevin Wolf 604bb675689SKevin Wolf struct test_iothread_data { 605bb675689SKevin Wolf BlockDriverState *bs; 606bb675689SKevin Wolf enum drain_type drain_type; 607bb675689SKevin Wolf int *aio_ret; 608bb675689SKevin Wolf }; 609bb675689SKevin Wolf 610bb675689SKevin Wolf static void test_iothread_drain_entry(void *opaque) 611bb675689SKevin Wolf { 612bb675689SKevin Wolf struct test_iothread_data *data = opaque; 613bb675689SKevin Wolf 614bb675689SKevin Wolf aio_context_acquire(bdrv_get_aio_context(data->bs)); 615bb675689SKevin Wolf do_drain_begin(data->drain_type, data->bs); 616bb675689SKevin Wolf g_assert_cmpint(*data->aio_ret, ==, 0); 617bb675689SKevin Wolf do_drain_end(data->drain_type, data->bs); 618bb675689SKevin Wolf aio_context_release(bdrv_get_aio_context(data->bs)); 619bb675689SKevin Wolf 620bb675689SKevin Wolf qemu_event_set(&done_event); 621bb675689SKevin Wolf } 622bb675689SKevin Wolf 623bb675689SKevin Wolf static void test_iothread_aio_cb(void *opaque, int ret) 624bb675689SKevin Wolf { 625bb675689SKevin Wolf int *aio_ret = opaque; 626bb675689SKevin Wolf *aio_ret = ret; 627bb675689SKevin Wolf qemu_event_set(&done_event); 628bb675689SKevin Wolf } 629bb675689SKevin Wolf 630ecc1a5c7SKevin Wolf static void test_iothread_main_thread_bh(void *opaque) 631ecc1a5c7SKevin Wolf { 632ecc1a5c7SKevin Wolf struct test_iothread_data *data = opaque; 633ecc1a5c7SKevin Wolf 634ecc1a5c7SKevin Wolf /* Test that the AioContext is not yet locked in a random BH that is 635ecc1a5c7SKevin Wolf * executed during drain, otherwise this would deadlock. */ 636ecc1a5c7SKevin Wolf aio_context_acquire(bdrv_get_aio_context(data->bs)); 637ecc1a5c7SKevin Wolf bdrv_flush(data->bs); 638ecc1a5c7SKevin Wolf aio_context_release(bdrv_get_aio_context(data->bs)); 639ecc1a5c7SKevin Wolf } 640ecc1a5c7SKevin Wolf 641bb675689SKevin Wolf /* 642bb675689SKevin Wolf * Starts an AIO request on a BDS that runs in the AioContext of iothread 1. 643bb675689SKevin Wolf * The request involves a BH on iothread 2 before it can complete. 644bb675689SKevin Wolf * 645bb675689SKevin Wolf * @drain_thread = 0 means that do_drain_begin/end are called from the main 646bb675689SKevin Wolf * thread, @drain_thread = 1 means that they are called from iothread 1. Drain 647bb675689SKevin Wolf * for this BDS cannot be called from iothread 2 because only the main thread 648bb675689SKevin Wolf * may do cross-AioContext polling. 649bb675689SKevin Wolf */ 650bb675689SKevin Wolf static void test_iothread_common(enum drain_type drain_type, int drain_thread) 651bb675689SKevin Wolf { 652bb675689SKevin Wolf BlockBackend *blk; 653bb675689SKevin Wolf BlockDriverState *bs; 654bb675689SKevin Wolf BDRVTestState *s; 655bb675689SKevin Wolf BlockAIOCB *acb; 656bb675689SKevin Wolf int aio_ret; 657bb675689SKevin Wolf struct test_iothread_data data; 658bb675689SKevin Wolf 659bb675689SKevin Wolf IOThread *a = iothread_new(); 660bb675689SKevin Wolf IOThread *b = iothread_new(); 661bb675689SKevin Wolf AioContext *ctx_a = iothread_get_aio_context(a); 662bb675689SKevin Wolf AioContext *ctx_b = iothread_get_aio_context(b); 663bb675689SKevin Wolf 664405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0); 665bb675689SKevin Wolf 666bb675689SKevin Wolf /* bdrv_drain_all() may only be called from the main loop thread */ 667bb675689SKevin Wolf if (drain_type == BDRV_DRAIN_ALL && drain_thread != 0) { 668bb675689SKevin Wolf goto out; 669bb675689SKevin Wolf } 670bb675689SKevin Wolf 671d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 672bb675689SKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 673bb675689SKevin Wolf &error_abort); 674bb675689SKevin Wolf s = bs->opaque; 675bb675689SKevin Wolf blk_insert_bs(blk, bs, &error_abort); 676cf312932SKevin Wolf blk_set_disable_request_queuing(blk, true); 677bb675689SKevin Wolf 67897896a48SKevin Wolf blk_set_aio_context(blk, ctx_a, &error_abort); 679bb675689SKevin Wolf aio_context_acquire(ctx_a); 680bb675689SKevin Wolf 681bb675689SKevin Wolf s->bh_indirection_ctx = ctx_b; 682bb675689SKevin Wolf 683bb675689SKevin Wolf aio_ret = -EINPROGRESS; 684dd353157SKevin Wolf qemu_event_reset(&done_event); 685dd353157SKevin Wolf 686bb675689SKevin Wolf if (drain_thread == 0) { 687bb675689SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, test_iothread_aio_cb, &aio_ret); 688bb675689SKevin Wolf } else { 689bb675689SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret); 690bb675689SKevin Wolf } 691bb675689SKevin Wolf g_assert(acb != NULL); 692bb675689SKevin Wolf g_assert_cmpint(aio_ret, ==, -EINPROGRESS); 693bb675689SKevin Wolf 694bb675689SKevin Wolf aio_context_release(ctx_a); 695bb675689SKevin Wolf 696bb675689SKevin Wolf data = (struct test_iothread_data) { 697bb675689SKevin Wolf .bs = bs, 698bb675689SKevin Wolf .drain_type = drain_type, 699bb675689SKevin Wolf .aio_ret = &aio_ret, 700bb675689SKevin Wolf }; 701bb675689SKevin Wolf 702bb675689SKevin Wolf switch (drain_thread) { 703bb675689SKevin Wolf case 0: 704bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 705bb675689SKevin Wolf aio_context_acquire(ctx_a); 706bb675689SKevin Wolf } 707bb675689SKevin Wolf 708ecc1a5c7SKevin Wolf aio_bh_schedule_oneshot(ctx_a, test_iothread_main_thread_bh, &data); 709ecc1a5c7SKevin Wolf 710bb675689SKevin Wolf /* The request is running on the IOThread a. Draining its block device 711bb675689SKevin Wolf * will make sure that it has completed as far as the BDS is concerned, 712bb675689SKevin Wolf * but the drain in this thread can continue immediately after 713bb675689SKevin Wolf * bdrv_dec_in_flight() and aio_ret might be assigned only slightly 714bb675689SKevin Wolf * later. */ 715bb675689SKevin Wolf do_drain_begin(drain_type, bs); 716bb675689SKevin Wolf g_assert_cmpint(bs->in_flight, ==, 0); 717bb675689SKevin Wolf 718bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 719bb675689SKevin Wolf aio_context_release(ctx_a); 720bb675689SKevin Wolf } 721bb675689SKevin Wolf qemu_event_wait(&done_event); 722bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 723bb675689SKevin Wolf aio_context_acquire(ctx_a); 724bb675689SKevin Wolf } 725bb675689SKevin Wolf 726bb675689SKevin Wolf g_assert_cmpint(aio_ret, ==, 0); 727bb675689SKevin Wolf do_drain_end(drain_type, bs); 728bb675689SKevin Wolf 729bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 730bb675689SKevin Wolf aio_context_release(ctx_a); 731bb675689SKevin Wolf } 732bb675689SKevin Wolf break; 733bb675689SKevin Wolf case 1: 734bb675689SKevin Wolf aio_bh_schedule_oneshot(ctx_a, test_iothread_drain_entry, &data); 735bb675689SKevin Wolf qemu_event_wait(&done_event); 736bb675689SKevin Wolf break; 737bb675689SKevin Wolf default: 738bb675689SKevin Wolf g_assert_not_reached(); 739bb675689SKevin Wolf } 740bb675689SKevin Wolf 741bb675689SKevin Wolf aio_context_acquire(ctx_a); 74297896a48SKevin Wolf blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort); 743bb675689SKevin Wolf aio_context_release(ctx_a); 744bb675689SKevin Wolf 745bb675689SKevin Wolf bdrv_unref(bs); 746bb675689SKevin Wolf blk_unref(blk); 747bb675689SKevin Wolf 748bb675689SKevin Wolf out: 749bb675689SKevin Wolf iothread_join(a); 750bb675689SKevin Wolf iothread_join(b); 751bb675689SKevin Wolf } 752bb675689SKevin Wolf 753bb675689SKevin Wolf static void test_iothread_drain_all(void) 754bb675689SKevin Wolf { 755bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN_ALL, 0); 756bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN_ALL, 1); 757bb675689SKevin Wolf } 758bb675689SKevin Wolf 759bb675689SKevin Wolf static void test_iothread_drain(void) 760bb675689SKevin Wolf { 761bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN, 0); 762bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN, 1); 763bb675689SKevin Wolf } 764bb675689SKevin Wolf 765bb675689SKevin Wolf static void test_iothread_drain_subtree(void) 766bb675689SKevin Wolf { 767bb675689SKevin Wolf test_iothread_common(BDRV_SUBTREE_DRAIN, 0); 768bb675689SKevin Wolf test_iothread_common(BDRV_SUBTREE_DRAIN, 1); 769bb675689SKevin Wolf } 770bb675689SKevin Wolf 7717253220dSKevin Wolf 7727253220dSKevin Wolf typedef struct TestBlockJob { 7737253220dSKevin Wolf BlockJob common; 774d49725afSKevin Wolf int run_ret; 775d49725afSKevin Wolf int prepare_ret; 776d8b3afd5SKevin Wolf bool running; 7777253220dSKevin Wolf bool should_complete; 7787253220dSKevin Wolf } TestBlockJob; 7797253220dSKevin Wolf 780ae23dde9SKevin Wolf static int test_job_prepare(Job *job) 781ae23dde9SKevin Wolf { 782ae23dde9SKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 783ae23dde9SKevin Wolf 784ae23dde9SKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 785ae23dde9SKevin Wolf blk_flush(s->common.blk); 786d49725afSKevin Wolf return s->prepare_ret; 787d49725afSKevin Wolf } 788d49725afSKevin Wolf 789d49725afSKevin Wolf static void test_job_commit(Job *job) 790d49725afSKevin Wolf { 791d49725afSKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 792d49725afSKevin Wolf 793d49725afSKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 794d49725afSKevin Wolf blk_flush(s->common.blk); 795d49725afSKevin Wolf } 796d49725afSKevin Wolf 797d49725afSKevin Wolf static void test_job_abort(Job *job) 798d49725afSKevin Wolf { 799d49725afSKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 800d49725afSKevin Wolf 801d49725afSKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 802d49725afSKevin Wolf blk_flush(s->common.blk); 803ae23dde9SKevin Wolf } 804ae23dde9SKevin Wolf 805f67432a2SJohn Snow static int coroutine_fn test_job_run(Job *job, Error **errp) 8067253220dSKevin Wolf { 807f67432a2SJohn Snow TestBlockJob *s = container_of(job, TestBlockJob, common.job); 8087253220dSKevin Wolf 809d8b3afd5SKevin Wolf /* We are running the actual job code past the pause point in 810d8b3afd5SKevin Wolf * job_co_entry(). */ 811d8b3afd5SKevin Wolf s->running = true; 812d8b3afd5SKevin Wolf 8132e1795b5SKevin Wolf job_transition_to_ready(&s->common.job); 8147253220dSKevin Wolf while (!s->should_complete) { 8155599c162SKevin Wolf /* Avoid job_sleep_ns() because it marks the job as !busy. We want to 8165599c162SKevin Wolf * emulate some actual activity (probably some I/O) here so that drain 8175599c162SKevin Wolf * has to wait for this activity to stop. */ 818d8b3afd5SKevin Wolf qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000); 819d8b3afd5SKevin Wolf 82089bd0305SKevin Wolf job_pause_point(&s->common.job); 8217253220dSKevin Wolf } 8227253220dSKevin Wolf 823d49725afSKevin Wolf return s->run_ret; 8247253220dSKevin Wolf } 8257253220dSKevin Wolf 8263453d972SKevin Wolf static void test_job_complete(Job *job, Error **errp) 8277253220dSKevin Wolf { 8283453d972SKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 8297253220dSKevin Wolf s->should_complete = true; 8307253220dSKevin Wolf } 8317253220dSKevin Wolf 8327253220dSKevin Wolf BlockJobDriver test_job_driver = { 83333e9e9bdSKevin Wolf .job_driver = { 8347253220dSKevin Wolf .instance_size = sizeof(TestBlockJob), 83580fa2c75SKevin Wolf .free = block_job_free, 836b15de828SKevin Wolf .user_resume = block_job_user_resume, 837f67432a2SJohn Snow .run = test_job_run, 8387253220dSKevin Wolf .complete = test_job_complete, 839ae23dde9SKevin Wolf .prepare = test_job_prepare, 840d49725afSKevin Wolf .commit = test_job_commit, 841d49725afSKevin Wolf .abort = test_job_abort, 8423453d972SKevin Wolf }, 8437253220dSKevin Wolf }; 8447253220dSKevin Wolf 845d49725afSKevin Wolf enum test_job_result { 846d49725afSKevin Wolf TEST_JOB_SUCCESS, 847d49725afSKevin Wolf TEST_JOB_FAIL_RUN, 848d49725afSKevin Wolf TEST_JOB_FAIL_PREPARE, 849d49725afSKevin Wolf }; 850d49725afSKevin Wolf 851d8b3afd5SKevin Wolf enum test_job_drain_node { 852d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC, 853d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_CHILD, 854d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_PARENT, 855d8b3afd5SKevin Wolf }; 856d8b3afd5SKevin Wolf 857d8b3afd5SKevin Wolf static void test_blockjob_common_drain_node(enum drain_type drain_type, 858d8b3afd5SKevin Wolf bool use_iothread, 859d8b3afd5SKevin Wolf enum test_job_result result, 860d8b3afd5SKevin Wolf enum test_job_drain_node drain_node) 8617253220dSKevin Wolf { 8627253220dSKevin Wolf BlockBackend *blk_src, *blk_target; 863d8b3afd5SKevin Wolf BlockDriverState *src, *src_backing, *src_overlay, *target, *drain_bs; 8647253220dSKevin Wolf BlockJob *job; 865d49725afSKevin Wolf TestBlockJob *tjob; 866f62c1729SKevin Wolf IOThread *iothread = NULL; 867f62c1729SKevin Wolf AioContext *ctx; 8687253220dSKevin Wolf int ret; 8697253220dSKevin Wolf 8707253220dSKevin Wolf src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR, 8717253220dSKevin Wolf &error_abort); 872d8b3afd5SKevin Wolf src_backing = bdrv_new_open_driver(&bdrv_test, "source-backing", 873d8b3afd5SKevin Wolf BDRV_O_RDWR, &error_abort); 874d8b3afd5SKevin Wolf src_overlay = bdrv_new_open_driver(&bdrv_test, "source-overlay", 875d8b3afd5SKevin Wolf BDRV_O_RDWR, &error_abort); 876d8b3afd5SKevin Wolf 877d8b3afd5SKevin Wolf bdrv_set_backing_hd(src_overlay, src, &error_abort); 878d8b3afd5SKevin Wolf bdrv_unref(src); 879d8b3afd5SKevin Wolf bdrv_set_backing_hd(src, src_backing, &error_abort); 880d8b3afd5SKevin Wolf bdrv_unref(src_backing); 881d8b3afd5SKevin Wolf 882d861ab3aSKevin Wolf blk_src = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 883d8b3afd5SKevin Wolf blk_insert_bs(blk_src, src_overlay, &error_abort); 884d8b3afd5SKevin Wolf 885d8b3afd5SKevin Wolf switch (drain_node) { 886d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC: 887d8b3afd5SKevin Wolf drain_bs = src; 888d8b3afd5SKevin Wolf break; 889d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC_CHILD: 890d8b3afd5SKevin Wolf drain_bs = src_backing; 891d8b3afd5SKevin Wolf break; 892d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC_PARENT: 893d8b3afd5SKevin Wolf drain_bs = src_overlay; 894d8b3afd5SKevin Wolf break; 895d8b3afd5SKevin Wolf default: 896d8b3afd5SKevin Wolf g_assert_not_reached(); 897d8b3afd5SKevin Wolf } 8987253220dSKevin Wolf 899f62c1729SKevin Wolf if (use_iothread) { 900f62c1729SKevin Wolf iothread = iothread_new(); 901f62c1729SKevin Wolf ctx = iothread_get_aio_context(iothread); 90297896a48SKevin Wolf blk_set_aio_context(blk_src, ctx, &error_abort); 903f62c1729SKevin Wolf } else { 904f62c1729SKevin Wolf ctx = qemu_get_aio_context(); 905f62c1729SKevin Wolf } 906f62c1729SKevin Wolf 9077253220dSKevin Wolf target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR, 9087253220dSKevin Wolf &error_abort); 909d861ab3aSKevin Wolf blk_target = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 9107253220dSKevin Wolf blk_insert_bs(blk_target, target, &error_abort); 911132ada80SKevin Wolf blk_set_allow_aio_context_change(blk_target, true); 9127253220dSKevin Wolf 913f62c1729SKevin Wolf aio_context_acquire(ctx); 914d49725afSKevin Wolf tjob = block_job_create("job0", &test_job_driver, NULL, src, 915d49725afSKevin Wolf 0, BLK_PERM_ALL, 91675859b94SJohn Snow 0, 0, NULL, NULL, &error_abort); 917d49725afSKevin Wolf job = &tjob->common; 9187253220dSKevin Wolf block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort); 919d49725afSKevin Wolf 920d49725afSKevin Wolf switch (result) { 921d49725afSKevin Wolf case TEST_JOB_SUCCESS: 922d49725afSKevin Wolf break; 923d49725afSKevin Wolf case TEST_JOB_FAIL_RUN: 924d49725afSKevin Wolf tjob->run_ret = -EIO; 925d49725afSKevin Wolf break; 926d49725afSKevin Wolf case TEST_JOB_FAIL_PREPARE: 927d49725afSKevin Wolf tjob->prepare_ret = -EIO; 928d49725afSKevin Wolf break; 929d49725afSKevin Wolf } 930d49725afSKevin Wolf 931da01ff7fSKevin Wolf job_start(&job->job); 932f62c1729SKevin Wolf aio_context_release(ctx); 9337253220dSKevin Wolf 934d8b3afd5SKevin Wolf if (use_iothread) { 935d8b3afd5SKevin Wolf /* job_co_entry() is run in the I/O thread, wait for the actual job 936d8b3afd5SKevin Wolf * code to start (we don't want to catch the job in the pause point in 937d8b3afd5SKevin Wolf * job_co_entry(). */ 938d8b3afd5SKevin Wolf while (!tjob->running) { 939d8b3afd5SKevin Wolf aio_poll(qemu_get_aio_context(), false); 940d8b3afd5SKevin Wolf } 941d8b3afd5SKevin Wolf } 942d8b3afd5SKevin Wolf 943da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 944da01ff7fSKevin Wolf g_assert_false(job->job.paused); 945d8b3afd5SKevin Wolf g_assert_true(tjob->running); 9465599c162SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 9477253220dSKevin Wolf 948d8b3afd5SKevin Wolf do_drain_begin_unlocked(drain_type, drain_bs); 9497253220dSKevin Wolf 9507253220dSKevin Wolf if (drain_type == BDRV_DRAIN_ALL) { 95181193349SKevin Wolf /* bdrv_drain_all() drains both src and target */ 952da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 2); 9537253220dSKevin Wolf } else { 954da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 1); 9557253220dSKevin Wolf } 95689bd0305SKevin Wolf g_assert_true(job->job.paused); 957da01ff7fSKevin Wolf g_assert_false(job->job.busy); /* The job is paused */ 9587253220dSKevin Wolf 959d8b3afd5SKevin Wolf do_drain_end_unlocked(drain_type, drain_bs); 960f62c1729SKevin Wolf 961f62c1729SKevin Wolf if (use_iothread) { 962f62c1729SKevin Wolf /* paused is reset in the I/O thread, wait for it */ 963f62c1729SKevin Wolf while (job->job.paused) { 964f62c1729SKevin Wolf aio_poll(qemu_get_aio_context(), false); 965f62c1729SKevin Wolf } 966f62c1729SKevin Wolf } 9677253220dSKevin Wolf 968da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 969da01ff7fSKevin Wolf g_assert_false(job->job.paused); 97089bd0305SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 9717253220dSKevin Wolf 972132ada80SKevin Wolf do_drain_begin_unlocked(drain_type, target); 9737253220dSKevin Wolf 9747253220dSKevin Wolf if (drain_type == BDRV_DRAIN_ALL) { 97581193349SKevin Wolf /* bdrv_drain_all() drains both src and target */ 976da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 2); 9777253220dSKevin Wolf } else { 978da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 1); 9797253220dSKevin Wolf } 98089bd0305SKevin Wolf g_assert_true(job->job.paused); 981da01ff7fSKevin Wolf g_assert_false(job->job.busy); /* The job is paused */ 9827253220dSKevin Wolf 983132ada80SKevin Wolf do_drain_end_unlocked(drain_type, target); 9847253220dSKevin Wolf 985f62c1729SKevin Wolf if (use_iothread) { 986f62c1729SKevin Wolf /* paused is reset in the I/O thread, wait for it */ 987f62c1729SKevin Wolf while (job->job.paused) { 988f62c1729SKevin Wolf aio_poll(qemu_get_aio_context(), false); 989f62c1729SKevin Wolf } 990f62c1729SKevin Wolf } 991f62c1729SKevin Wolf 992da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 993da01ff7fSKevin Wolf g_assert_false(job->job.paused); 9945599c162SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 9957253220dSKevin Wolf 996f62c1729SKevin Wolf aio_context_acquire(ctx); 9973d70ff53SKevin Wolf ret = job_complete_sync(&job->job, &error_abort); 998d49725afSKevin Wolf g_assert_cmpint(ret, ==, (result == TEST_JOB_SUCCESS ? 0 : -EIO)); 9997253220dSKevin Wolf 1000f62c1729SKevin Wolf if (use_iothread) { 100197896a48SKevin Wolf blk_set_aio_context(blk_src, qemu_get_aio_context(), &error_abort); 1002ad943dcbSKevin Wolf assert(blk_get_aio_context(blk_target) == qemu_get_aio_context()); 1003f62c1729SKevin Wolf } 1004f62c1729SKevin Wolf aio_context_release(ctx); 1005f62c1729SKevin Wolf 10067253220dSKevin Wolf blk_unref(blk_src); 10077253220dSKevin Wolf blk_unref(blk_target); 1008d8b3afd5SKevin Wolf bdrv_unref(src_overlay); 10097253220dSKevin Wolf bdrv_unref(target); 1010f62c1729SKevin Wolf 1011f62c1729SKevin Wolf if (iothread) { 1012f62c1729SKevin Wolf iothread_join(iothread); 1013f62c1729SKevin Wolf } 10147253220dSKevin Wolf } 10157253220dSKevin Wolf 1016d8b3afd5SKevin Wolf static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, 1017d8b3afd5SKevin Wolf enum test_job_result result) 1018d8b3afd5SKevin Wolf { 1019d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1020d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC); 1021d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1022d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_CHILD); 1023d8b3afd5SKevin Wolf if (drain_type == BDRV_SUBTREE_DRAIN) { 1024d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1025d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_PARENT); 1026d8b3afd5SKevin Wolf } 1027d8b3afd5SKevin Wolf } 1028d8b3afd5SKevin Wolf 10297253220dSKevin Wolf static void test_blockjob_drain_all(void) 10307253220dSKevin Wolf { 1031d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_SUCCESS); 10327253220dSKevin Wolf } 10337253220dSKevin Wolf 10347253220dSKevin Wolf static void test_blockjob_drain(void) 10357253220dSKevin Wolf { 1036d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_SUCCESS); 10377253220dSKevin Wolf } 10387253220dSKevin Wolf 1039d2a85d0fSKevin Wolf static void test_blockjob_drain_subtree(void) 1040d2a85d0fSKevin Wolf { 1041d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_SUCCESS); 1042d49725afSKevin Wolf } 1043d49725afSKevin Wolf 1044d49725afSKevin Wolf static void test_blockjob_error_drain_all(void) 1045d49725afSKevin Wolf { 1046d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_RUN); 1047d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_PREPARE); 1048d49725afSKevin Wolf } 1049d49725afSKevin Wolf 1050d49725afSKevin Wolf static void test_blockjob_error_drain(void) 1051d49725afSKevin Wolf { 1052d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_RUN); 1053d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_PREPARE); 1054d49725afSKevin Wolf } 1055d49725afSKevin Wolf 1056d49725afSKevin Wolf static void test_blockjob_error_drain_subtree(void) 1057d49725afSKevin Wolf { 1058d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_RUN); 1059d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_PREPARE); 1060f62c1729SKevin Wolf } 1061f62c1729SKevin Wolf 1062f62c1729SKevin Wolf static void test_blockjob_iothread_drain_all(void) 1063f62c1729SKevin Wolf { 1064d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_SUCCESS); 1065f62c1729SKevin Wolf } 1066f62c1729SKevin Wolf 1067f62c1729SKevin Wolf static void test_blockjob_iothread_drain(void) 1068f62c1729SKevin Wolf { 1069d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_SUCCESS); 1070f62c1729SKevin Wolf } 1071f62c1729SKevin Wolf 1072f62c1729SKevin Wolf static void test_blockjob_iothread_drain_subtree(void) 1073f62c1729SKevin Wolf { 1074d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_SUCCESS); 1075d49725afSKevin Wolf } 1076d49725afSKevin Wolf 1077d49725afSKevin Wolf static void test_blockjob_iothread_error_drain_all(void) 1078d49725afSKevin Wolf { 1079d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_RUN); 1080d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_PREPARE); 1081d49725afSKevin Wolf } 1082d49725afSKevin Wolf 1083d49725afSKevin Wolf static void test_blockjob_iothread_error_drain(void) 1084d49725afSKevin Wolf { 1085d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_RUN); 1086d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_PREPARE); 1087d49725afSKevin Wolf } 1088d49725afSKevin Wolf 1089d49725afSKevin Wolf static void test_blockjob_iothread_error_drain_subtree(void) 1090d49725afSKevin Wolf { 1091d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_RUN); 1092d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_PREPARE); 1093d2a85d0fSKevin Wolf } 1094d2a85d0fSKevin Wolf 10954c8158e3SMax Reitz 10964c8158e3SMax Reitz typedef struct BDRVTestTopState { 10974c8158e3SMax Reitz BdrvChild *wait_child; 10984c8158e3SMax Reitz } BDRVTestTopState; 10994c8158e3SMax Reitz 11004c8158e3SMax Reitz static void bdrv_test_top_close(BlockDriverState *bs) 11014c8158e3SMax Reitz { 11024c8158e3SMax Reitz BdrvChild *c, *next_c; 11034c8158e3SMax Reitz QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) { 11044c8158e3SMax Reitz bdrv_unref_child(bs, c); 11054c8158e3SMax Reitz } 11064c8158e3SMax Reitz } 11074c8158e3SMax Reitz 11084c8158e3SMax Reitz static int coroutine_fn bdrv_test_top_co_preadv(BlockDriverState *bs, 11094c8158e3SMax Reitz uint64_t offset, uint64_t bytes, 11104c8158e3SMax Reitz QEMUIOVector *qiov, int flags) 11114c8158e3SMax Reitz { 11124c8158e3SMax Reitz BDRVTestTopState *tts = bs->opaque; 11134c8158e3SMax Reitz return bdrv_co_preadv(tts->wait_child, offset, bytes, qiov, flags); 11144c8158e3SMax Reitz } 11154c8158e3SMax Reitz 11164c8158e3SMax Reitz static BlockDriver bdrv_test_top_driver = { 11174c8158e3SMax Reitz .format_name = "test_top_driver", 11184c8158e3SMax Reitz .instance_size = sizeof(BDRVTestTopState), 11194c8158e3SMax Reitz 11204c8158e3SMax Reitz .bdrv_close = bdrv_test_top_close, 11214c8158e3SMax Reitz .bdrv_co_preadv = bdrv_test_top_co_preadv, 11224c8158e3SMax Reitz 112369dca43dSMax Reitz .bdrv_child_perm = bdrv_default_perms, 11244c8158e3SMax Reitz }; 11254c8158e3SMax Reitz 11264c8158e3SMax Reitz typedef struct TestCoDeleteByDrainData { 11274c8158e3SMax Reitz BlockBackend *blk; 11284c8158e3SMax Reitz bool detach_instead_of_delete; 11294c8158e3SMax Reitz bool done; 11304c8158e3SMax Reitz } TestCoDeleteByDrainData; 11314c8158e3SMax Reitz 11324c8158e3SMax Reitz static void coroutine_fn test_co_delete_by_drain(void *opaque) 11334c8158e3SMax Reitz { 11344c8158e3SMax Reitz TestCoDeleteByDrainData *dbdd = opaque; 11354c8158e3SMax Reitz BlockBackend *blk = dbdd->blk; 11364c8158e3SMax Reitz BlockDriverState *bs = blk_bs(blk); 11374c8158e3SMax Reitz BDRVTestTopState *tts = bs->opaque; 11384c8158e3SMax Reitz void *buffer = g_malloc(65536); 1139405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buffer, 65536); 11404c8158e3SMax Reitz 11414c8158e3SMax Reitz /* Pretend some internal write operation from parent to child. 11424c8158e3SMax Reitz * Important: We have to read from the child, not from the parent! 11434c8158e3SMax Reitz * Draining works by first propagating it all up the tree to the 11444c8158e3SMax Reitz * root and then waiting for drainage from root to the leaves 11454c8158e3SMax Reitz * (protocol nodes). If we have a request waiting on the root, 11464c8158e3SMax Reitz * everything will be drained before we go back down the tree, but 11474c8158e3SMax Reitz * we do not want that. We want to be in the middle of draining 11484c8158e3SMax Reitz * when this following requests returns. */ 11494c8158e3SMax Reitz bdrv_co_preadv(tts->wait_child, 0, 65536, &qiov, 0); 11504c8158e3SMax Reitz 11514c8158e3SMax Reitz g_assert_cmpint(bs->refcnt, ==, 1); 11524c8158e3SMax Reitz 11534c8158e3SMax Reitz if (!dbdd->detach_instead_of_delete) { 11544c8158e3SMax Reitz blk_unref(blk); 11554c8158e3SMax Reitz } else { 11564c8158e3SMax Reitz BdrvChild *c, *next_c; 11574c8158e3SMax Reitz QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) { 11584c8158e3SMax Reitz bdrv_unref_child(bs, c); 11594c8158e3SMax Reitz } 11604c8158e3SMax Reitz } 11614c8158e3SMax Reitz 11624c8158e3SMax Reitz dbdd->done = true; 11637b43db3cSMarc-André Lureau g_free(buffer); 11644c8158e3SMax Reitz } 11654c8158e3SMax Reitz 11664c8158e3SMax Reitz /** 11674c8158e3SMax Reitz * Test what happens when some BDS has some children, you drain one of 11684c8158e3SMax Reitz * them and this results in the BDS being deleted. 11694c8158e3SMax Reitz * 11704c8158e3SMax Reitz * If @detach_instead_of_delete is set, the BDS is not going to be 11714c8158e3SMax Reitz * deleted but will only detach all of its children. 11724c8158e3SMax Reitz */ 1173ebd31837SKevin Wolf static void do_test_delete_by_drain(bool detach_instead_of_delete, 1174ebd31837SKevin Wolf enum drain_type drain_type) 11754c8158e3SMax Reitz { 11764c8158e3SMax Reitz BlockBackend *blk; 11774c8158e3SMax Reitz BlockDriverState *bs, *child_bs, *null_bs; 11784c8158e3SMax Reitz BDRVTestTopState *tts; 11794c8158e3SMax Reitz TestCoDeleteByDrainData dbdd; 11804c8158e3SMax Reitz Coroutine *co; 11814c8158e3SMax Reitz 11824c8158e3SMax Reitz bs = bdrv_new_open_driver(&bdrv_test_top_driver, "top", BDRV_O_RDWR, 11834c8158e3SMax Reitz &error_abort); 11844c8158e3SMax Reitz bs->total_sectors = 65536 >> BDRV_SECTOR_BITS; 11854c8158e3SMax Reitz tts = bs->opaque; 11864c8158e3SMax Reitz 11874c8158e3SMax Reitz null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 11884c8158e3SMax Reitz &error_abort); 1189a16be3cdSMax Reitz bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, 1190a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 11914c8158e3SMax Reitz 11924c8158e3SMax Reitz /* This child will be the one to pass to requests through to, and 11934c8158e3SMax Reitz * it will stall until a drain occurs */ 11944c8158e3SMax Reitz child_bs = bdrv_new_open_driver(&bdrv_test, "child", BDRV_O_RDWR, 11954c8158e3SMax Reitz &error_abort); 11964c8158e3SMax Reitz child_bs->total_sectors = 65536 >> BDRV_SECTOR_BITS; 11974c8158e3SMax Reitz /* Takes our reference to child_bs */ 1198a16be3cdSMax Reitz tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child", 1199a16be3cdSMax Reitz &child_of_bds, 1200a16be3cdSMax Reitz BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY, 1201a16be3cdSMax Reitz &error_abort); 12024c8158e3SMax Reitz 12034c8158e3SMax Reitz /* This child is just there to be deleted 12044c8158e3SMax Reitz * (for detach_instead_of_delete == true) */ 12054c8158e3SMax Reitz null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 12064c8158e3SMax Reitz &error_abort); 1207a16be3cdSMax Reitz bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, BDRV_CHILD_DATA, 1208a16be3cdSMax Reitz &error_abort); 12094c8158e3SMax Reitz 1210d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 12114c8158e3SMax Reitz blk_insert_bs(blk, bs, &error_abort); 12124c8158e3SMax Reitz 12134c8158e3SMax Reitz /* Referenced by blk now */ 12144c8158e3SMax Reitz bdrv_unref(bs); 12154c8158e3SMax Reitz 12164c8158e3SMax Reitz g_assert_cmpint(bs->refcnt, ==, 1); 12174c8158e3SMax Reitz g_assert_cmpint(child_bs->refcnt, ==, 1); 12184c8158e3SMax Reitz g_assert_cmpint(null_bs->refcnt, ==, 1); 12194c8158e3SMax Reitz 12204c8158e3SMax Reitz 12214c8158e3SMax Reitz dbdd = (TestCoDeleteByDrainData){ 12224c8158e3SMax Reitz .blk = blk, 12234c8158e3SMax Reitz .detach_instead_of_delete = detach_instead_of_delete, 12244c8158e3SMax Reitz .done = false, 12254c8158e3SMax Reitz }; 12264c8158e3SMax Reitz co = qemu_coroutine_create(test_co_delete_by_drain, &dbdd); 12274c8158e3SMax Reitz qemu_coroutine_enter(co); 12284c8158e3SMax Reitz 12294c8158e3SMax Reitz /* Drain the child while the read operation is still pending. 12304c8158e3SMax Reitz * This should result in the operation finishing and 12314c8158e3SMax Reitz * test_co_delete_by_drain() resuming. Thus, @bs will be deleted 12324c8158e3SMax Reitz * and the coroutine will exit while this drain operation is still 12334c8158e3SMax Reitz * in progress. */ 1234ebd31837SKevin Wolf switch (drain_type) { 1235ebd31837SKevin Wolf case BDRV_DRAIN: 12364c8158e3SMax Reitz bdrv_ref(child_bs); 12374c8158e3SMax Reitz bdrv_drain(child_bs); 12384c8158e3SMax Reitz bdrv_unref(child_bs); 1239ebd31837SKevin Wolf break; 1240ebd31837SKevin Wolf case BDRV_SUBTREE_DRAIN: 1241ebd31837SKevin Wolf /* Would have to ref/unref bs here for !detach_instead_of_delete, but 1242ebd31837SKevin Wolf * then the whole test becomes pointless because the graph changes 1243ebd31837SKevin Wolf * don't occur during the drain any more. */ 1244ebd31837SKevin Wolf assert(detach_instead_of_delete); 1245ebd31837SKevin Wolf bdrv_subtree_drained_begin(bs); 1246ebd31837SKevin Wolf bdrv_subtree_drained_end(bs); 1247ebd31837SKevin Wolf break; 124819f7a7e5SKevin Wolf case BDRV_DRAIN_ALL: 124919f7a7e5SKevin Wolf bdrv_drain_all_begin(); 125019f7a7e5SKevin Wolf bdrv_drain_all_end(); 125119f7a7e5SKevin Wolf break; 1252ebd31837SKevin Wolf default: 1253ebd31837SKevin Wolf g_assert_not_reached(); 1254ebd31837SKevin Wolf } 12554c8158e3SMax Reitz 12564c8158e3SMax Reitz while (!dbdd.done) { 12574c8158e3SMax Reitz aio_poll(qemu_get_aio_context(), true); 12584c8158e3SMax Reitz } 12594c8158e3SMax Reitz 12604c8158e3SMax Reitz if (detach_instead_of_delete) { 12614c8158e3SMax Reitz /* Here, the reference has not passed over to the coroutine, 12624c8158e3SMax Reitz * so we have to delete the BB ourselves */ 12634c8158e3SMax Reitz blk_unref(blk); 12644c8158e3SMax Reitz } 12654c8158e3SMax Reitz } 12664c8158e3SMax Reitz 12674c8158e3SMax Reitz static void test_delete_by_drain(void) 12684c8158e3SMax Reitz { 1269ebd31837SKevin Wolf do_test_delete_by_drain(false, BDRV_DRAIN); 12704c8158e3SMax Reitz } 12714c8158e3SMax Reitz 127219f7a7e5SKevin Wolf static void test_detach_by_drain_all(void) 127319f7a7e5SKevin Wolf { 127419f7a7e5SKevin Wolf do_test_delete_by_drain(true, BDRV_DRAIN_ALL); 127519f7a7e5SKevin Wolf } 127619f7a7e5SKevin Wolf 12774c8158e3SMax Reitz static void test_detach_by_drain(void) 12784c8158e3SMax Reitz { 1279ebd31837SKevin Wolf do_test_delete_by_drain(true, BDRV_DRAIN); 1280ebd31837SKevin Wolf } 1281ebd31837SKevin Wolf 1282ebd31837SKevin Wolf static void test_detach_by_drain_subtree(void) 1283ebd31837SKevin Wolf { 1284ebd31837SKevin Wolf do_test_delete_by_drain(true, BDRV_SUBTREE_DRAIN); 12854c8158e3SMax Reitz } 12864c8158e3SMax Reitz 12874c8158e3SMax Reitz 1288231281abSKevin Wolf struct detach_by_parent_data { 1289231281abSKevin Wolf BlockDriverState *parent_b; 1290231281abSKevin Wolf BdrvChild *child_b; 1291231281abSKevin Wolf BlockDriverState *c; 1292231281abSKevin Wolf BdrvChild *child_c; 129357320ca9SKevin Wolf bool by_parent_cb; 1294231281abSKevin Wolf }; 129557320ca9SKevin Wolf static struct detach_by_parent_data detach_by_parent_data; 1296231281abSKevin Wolf 129757320ca9SKevin Wolf static void detach_indirect_bh(void *opaque) 1298231281abSKevin Wolf { 1299231281abSKevin Wolf struct detach_by_parent_data *data = opaque; 1300231281abSKevin Wolf 1301231281abSKevin Wolf bdrv_unref_child(data->parent_b, data->child_b); 1302231281abSKevin Wolf 1303231281abSKevin Wolf bdrv_ref(data->c); 1304231281abSKevin Wolf data->child_c = bdrv_attach_child(data->parent_b, data->c, "PB-C", 1305a16be3cdSMax Reitz &child_of_bds, BDRV_CHILD_DATA, 1306a16be3cdSMax Reitz &error_abort); 1307231281abSKevin Wolf } 1308231281abSKevin Wolf 130957320ca9SKevin Wolf static void detach_by_parent_aio_cb(void *opaque, int ret) 131057320ca9SKevin Wolf { 131157320ca9SKevin Wolf struct detach_by_parent_data *data = &detach_by_parent_data; 131257320ca9SKevin Wolf 131357320ca9SKevin Wolf g_assert_cmpint(ret, ==, 0); 131457320ca9SKevin Wolf if (data->by_parent_cb) { 131557320ca9SKevin Wolf detach_indirect_bh(data); 131657320ca9SKevin Wolf } 131757320ca9SKevin Wolf } 131857320ca9SKevin Wolf 131957320ca9SKevin Wolf static void detach_by_driver_cb_drained_begin(BdrvChild *child) 132057320ca9SKevin Wolf { 132157320ca9SKevin Wolf aio_bh_schedule_oneshot(qemu_get_current_aio_context(), 132257320ca9SKevin Wolf detach_indirect_bh, &detach_by_parent_data); 1323a16be3cdSMax Reitz child_of_bds.drained_begin(child); 132457320ca9SKevin Wolf } 132557320ca9SKevin Wolf 1326bd86fb99SMax Reitz static BdrvChildClass detach_by_driver_cb_class; 132757320ca9SKevin Wolf 1328231281abSKevin Wolf /* 1329231281abSKevin Wolf * Initial graph: 1330231281abSKevin Wolf * 1331231281abSKevin Wolf * PA PB 1332231281abSKevin Wolf * \ / \ 1333231281abSKevin Wolf * A B C 1334231281abSKevin Wolf * 133557320ca9SKevin Wolf * by_parent_cb == true: Test that parent callbacks don't poll 133657320ca9SKevin Wolf * 133757320ca9SKevin Wolf * PA has a pending write request whose callback changes the child nodes of 133857320ca9SKevin Wolf * PB: It removes B and adds C instead. The subtree of PB is drained, which 133957320ca9SKevin Wolf * will indirectly drain the write request, too. 134057320ca9SKevin Wolf * 134157320ca9SKevin Wolf * by_parent_cb == false: Test that bdrv_drain_invoke() doesn't poll 134257320ca9SKevin Wolf * 1343bd86fb99SMax Reitz * PA's BdrvChildClass has a .drained_begin callback that schedules a BH 134457320ca9SKevin Wolf * that does the same graph change. If bdrv_drain_invoke() calls it, the 134557320ca9SKevin Wolf * state is messed up, but if it is only polled in the single 134657320ca9SKevin Wolf * BDRV_POLL_WHILE() at the end of the drain, this should work fine. 1347231281abSKevin Wolf */ 134857320ca9SKevin Wolf static void test_detach_indirect(bool by_parent_cb) 1349231281abSKevin Wolf { 1350231281abSKevin Wolf BlockBackend *blk; 1351231281abSKevin Wolf BlockDriverState *parent_a, *parent_b, *a, *b, *c; 1352231281abSKevin Wolf BdrvChild *child_a, *child_b; 1353231281abSKevin Wolf BlockAIOCB *acb; 1354231281abSKevin Wolf 1355405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0); 1356231281abSKevin Wolf 135757320ca9SKevin Wolf if (!by_parent_cb) { 1358a16be3cdSMax Reitz detach_by_driver_cb_class = child_of_bds; 1359bd86fb99SMax Reitz detach_by_driver_cb_class.drained_begin = 136057320ca9SKevin Wolf detach_by_driver_cb_drained_begin; 136157320ca9SKevin Wolf } 136257320ca9SKevin Wolf 1363231281abSKevin Wolf /* Create all involved nodes */ 1364231281abSKevin Wolf parent_a = bdrv_new_open_driver(&bdrv_test, "parent-a", BDRV_O_RDWR, 1365231281abSKevin Wolf &error_abort); 1366231281abSKevin Wolf parent_b = bdrv_new_open_driver(&bdrv_test, "parent-b", 0, 1367231281abSKevin Wolf &error_abort); 1368231281abSKevin Wolf 1369231281abSKevin Wolf a = bdrv_new_open_driver(&bdrv_test, "a", BDRV_O_RDWR, &error_abort); 1370231281abSKevin Wolf b = bdrv_new_open_driver(&bdrv_test, "b", BDRV_O_RDWR, &error_abort); 1371231281abSKevin Wolf c = bdrv_new_open_driver(&bdrv_test, "c", BDRV_O_RDWR, &error_abort); 1372231281abSKevin Wolf 1373231281abSKevin Wolf /* blk is a BB for parent-a */ 1374d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 1375231281abSKevin Wolf blk_insert_bs(blk, parent_a, &error_abort); 1376231281abSKevin Wolf bdrv_unref(parent_a); 1377231281abSKevin Wolf 137857320ca9SKevin Wolf /* If we want to get bdrv_drain_invoke() to call aio_poll(), the driver 137957320ca9SKevin Wolf * callback must not return immediately. */ 138057320ca9SKevin Wolf if (!by_parent_cb) { 138157320ca9SKevin Wolf BDRVTestState *s = parent_a->opaque; 138257320ca9SKevin Wolf s->sleep_in_drain_begin = true; 138357320ca9SKevin Wolf } 138457320ca9SKevin Wolf 1385231281abSKevin Wolf /* Set child relationships */ 1386231281abSKevin Wolf bdrv_ref(b); 1387231281abSKevin Wolf bdrv_ref(a); 1388a16be3cdSMax Reitz child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_of_bds, 1389a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 139025191e5fSMax Reitz child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_of_bds, 139125191e5fSMax Reitz BDRV_CHILD_COW, &error_abort); 1392231281abSKevin Wolf 1393231281abSKevin Wolf bdrv_ref(a); 139457320ca9SKevin Wolf bdrv_attach_child(parent_a, a, "PA-A", 1395a16be3cdSMax Reitz by_parent_cb ? &child_of_bds : &detach_by_driver_cb_class, 1396a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 1397231281abSKevin Wolf 1398231281abSKevin Wolf g_assert_cmpint(parent_a->refcnt, ==, 1); 1399231281abSKevin Wolf g_assert_cmpint(parent_b->refcnt, ==, 1); 1400231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 3); 1401231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 2); 1402231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 1); 1403231281abSKevin Wolf 1404231281abSKevin Wolf g_assert(QLIST_FIRST(&parent_b->children) == child_a); 1405231281abSKevin Wolf g_assert(QLIST_NEXT(child_a, next) == child_b); 1406231281abSKevin Wolf g_assert(QLIST_NEXT(child_b, next) == NULL); 1407231281abSKevin Wolf 1408231281abSKevin Wolf /* Start the evil write request */ 140957320ca9SKevin Wolf detach_by_parent_data = (struct detach_by_parent_data) { 1410231281abSKevin Wolf .parent_b = parent_b, 1411231281abSKevin Wolf .child_b = child_b, 1412231281abSKevin Wolf .c = c, 141357320ca9SKevin Wolf .by_parent_cb = by_parent_cb, 1414231281abSKevin Wolf }; 141557320ca9SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, detach_by_parent_aio_cb, NULL); 1416231281abSKevin Wolf g_assert(acb != NULL); 1417231281abSKevin Wolf 1418231281abSKevin Wolf /* Drain and check the expected result */ 1419231281abSKevin Wolf bdrv_subtree_drained_begin(parent_b); 1420231281abSKevin Wolf 142157320ca9SKevin Wolf g_assert(detach_by_parent_data.child_c != NULL); 1422231281abSKevin Wolf 1423231281abSKevin Wolf g_assert_cmpint(parent_a->refcnt, ==, 1); 1424231281abSKevin Wolf g_assert_cmpint(parent_b->refcnt, ==, 1); 1425231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 3); 1426231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 1); 1427231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 2); 1428231281abSKevin Wolf 142957320ca9SKevin Wolf g_assert(QLIST_FIRST(&parent_b->children) == detach_by_parent_data.child_c); 143057320ca9SKevin Wolf g_assert(QLIST_NEXT(detach_by_parent_data.child_c, next) == child_a); 1431231281abSKevin Wolf g_assert(QLIST_NEXT(child_a, next) == NULL); 1432231281abSKevin Wolf 1433231281abSKevin Wolf g_assert_cmpint(parent_a->quiesce_counter, ==, 1); 1434231281abSKevin Wolf g_assert_cmpint(parent_b->quiesce_counter, ==, 1); 1435231281abSKevin Wolf g_assert_cmpint(a->quiesce_counter, ==, 1); 1436231281abSKevin Wolf g_assert_cmpint(b->quiesce_counter, ==, 0); 1437231281abSKevin Wolf g_assert_cmpint(c->quiesce_counter, ==, 1); 1438231281abSKevin Wolf 1439231281abSKevin Wolf bdrv_subtree_drained_end(parent_b); 1440231281abSKevin Wolf 1441231281abSKevin Wolf bdrv_unref(parent_b); 1442231281abSKevin Wolf blk_unref(blk); 1443231281abSKevin Wolf 1444231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 1); 1445231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 1); 1446231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 1); 1447231281abSKevin Wolf bdrv_unref(a); 1448231281abSKevin Wolf bdrv_unref(b); 1449231281abSKevin Wolf bdrv_unref(c); 1450231281abSKevin Wolf } 1451231281abSKevin Wolf 145257320ca9SKevin Wolf static void test_detach_by_parent_cb(void) 145357320ca9SKevin Wolf { 145457320ca9SKevin Wolf test_detach_indirect(true); 145557320ca9SKevin Wolf } 145657320ca9SKevin Wolf 145757320ca9SKevin Wolf static void test_detach_by_driver_cb(void) 145857320ca9SKevin Wolf { 145957320ca9SKevin Wolf test_detach_indirect(false); 146057320ca9SKevin Wolf } 1461231281abSKevin Wolf 1462b994c5bcSKevin Wolf static void test_append_to_drained(void) 1463b994c5bcSKevin Wolf { 1464b994c5bcSKevin Wolf BlockBackend *blk; 1465b994c5bcSKevin Wolf BlockDriverState *base, *overlay; 1466b994c5bcSKevin Wolf BDRVTestState *base_s, *overlay_s; 1467b994c5bcSKevin Wolf 1468d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 1469b994c5bcSKevin Wolf base = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort); 1470b994c5bcSKevin Wolf base_s = base->opaque; 1471b994c5bcSKevin Wolf blk_insert_bs(blk, base, &error_abort); 1472b994c5bcSKevin Wolf 1473b994c5bcSKevin Wolf overlay = bdrv_new_open_driver(&bdrv_test, "overlay", BDRV_O_RDWR, 1474b994c5bcSKevin Wolf &error_abort); 1475b994c5bcSKevin Wolf overlay_s = overlay->opaque; 1476b994c5bcSKevin Wolf 1477b994c5bcSKevin Wolf do_drain_begin(BDRV_DRAIN, base); 1478b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 1); 1479b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 1); 1480b994c5bcSKevin Wolf g_assert_cmpint(base->in_flight, ==, 0); 1481b994c5bcSKevin Wolf 1482b994c5bcSKevin Wolf bdrv_append(overlay, base, &error_abort); 1483b994c5bcSKevin Wolf g_assert_cmpint(base->in_flight, ==, 0); 1484b994c5bcSKevin Wolf g_assert_cmpint(overlay->in_flight, ==, 0); 1485b994c5bcSKevin Wolf 1486b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 1); 1487b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 1); 1488b994c5bcSKevin Wolf g_assert_cmpint(overlay->quiesce_counter, ==, 1); 1489b994c5bcSKevin Wolf g_assert_cmpint(overlay_s->drain_count, ==, 1); 1490b994c5bcSKevin Wolf 1491b994c5bcSKevin Wolf do_drain_end(BDRV_DRAIN, base); 1492b994c5bcSKevin Wolf 1493b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 0); 1494b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 0); 1495b994c5bcSKevin Wolf g_assert_cmpint(overlay->quiesce_counter, ==, 0); 1496b994c5bcSKevin Wolf g_assert_cmpint(overlay_s->drain_count, ==, 0); 1497b994c5bcSKevin Wolf 1498ae9d4417SVladimir Sementsov-Ogievskiy bdrv_unref(overlay); 1499b994c5bcSKevin Wolf bdrv_unref(base); 1500b994c5bcSKevin Wolf blk_unref(blk); 1501b994c5bcSKevin Wolf } 1502b994c5bcSKevin Wolf 1503247d2737SKevin Wolf static void test_set_aio_context(void) 1504247d2737SKevin Wolf { 1505247d2737SKevin Wolf BlockDriverState *bs; 1506247d2737SKevin Wolf IOThread *a = iothread_new(); 1507247d2737SKevin Wolf IOThread *b = iothread_new(); 1508247d2737SKevin Wolf AioContext *ctx_a = iothread_get_aio_context(a); 1509247d2737SKevin Wolf AioContext *ctx_b = iothread_get_aio_context(b); 1510247d2737SKevin Wolf 1511247d2737SKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 1512247d2737SKevin Wolf &error_abort); 1513247d2737SKevin Wolf 1514247d2737SKevin Wolf bdrv_drained_begin(bs); 151526bf15e4SKevin Wolf bdrv_try_set_aio_context(bs, ctx_a, &error_abort); 1516247d2737SKevin Wolf 1517247d2737SKevin Wolf aio_context_acquire(ctx_a); 1518247d2737SKevin Wolf bdrv_drained_end(bs); 1519247d2737SKevin Wolf 1520247d2737SKevin Wolf bdrv_drained_begin(bs); 152126bf15e4SKevin Wolf bdrv_try_set_aio_context(bs, ctx_b, &error_abort); 1522247d2737SKevin Wolf aio_context_release(ctx_a); 1523247d2737SKevin Wolf aio_context_acquire(ctx_b); 152426bf15e4SKevin Wolf bdrv_try_set_aio_context(bs, qemu_get_aio_context(), &error_abort); 1525247d2737SKevin Wolf aio_context_release(ctx_b); 1526247d2737SKevin Wolf bdrv_drained_end(bs); 1527247d2737SKevin Wolf 1528247d2737SKevin Wolf bdrv_unref(bs); 1529247d2737SKevin Wolf iothread_join(a); 1530247d2737SKevin Wolf iothread_join(b); 1531247d2737SKevin Wolf } 1532247d2737SKevin Wolf 15338e442810SMax Reitz 15348e442810SMax Reitz typedef struct TestDropBackingBlockJob { 15358e442810SMax Reitz BlockJob common; 15368e442810SMax Reitz bool should_complete; 15378e442810SMax Reitz bool *did_complete; 15382afdc790SMax Reitz BlockDriverState *detach_also; 15398e442810SMax Reitz } TestDropBackingBlockJob; 15408e442810SMax Reitz 15418e442810SMax Reitz static int coroutine_fn test_drop_backing_job_run(Job *job, Error **errp) 15428e442810SMax Reitz { 15438e442810SMax Reitz TestDropBackingBlockJob *s = 15448e442810SMax Reitz container_of(job, TestDropBackingBlockJob, common.job); 15458e442810SMax Reitz 15468e442810SMax Reitz while (!s->should_complete) { 15478e442810SMax Reitz job_sleep_ns(job, 0); 15488e442810SMax Reitz } 15498e442810SMax Reitz 15508e442810SMax Reitz return 0; 15518e442810SMax Reitz } 15528e442810SMax Reitz 15538e442810SMax Reitz static void test_drop_backing_job_commit(Job *job) 15548e442810SMax Reitz { 15558e442810SMax Reitz TestDropBackingBlockJob *s = 15568e442810SMax Reitz container_of(job, TestDropBackingBlockJob, common.job); 15578e442810SMax Reitz 15588e442810SMax Reitz bdrv_set_backing_hd(blk_bs(s->common.blk), NULL, &error_abort); 15592afdc790SMax Reitz bdrv_set_backing_hd(s->detach_also, NULL, &error_abort); 15608e442810SMax Reitz 15618e442810SMax Reitz *s->did_complete = true; 15628e442810SMax Reitz } 15638e442810SMax Reitz 15648e442810SMax Reitz static const BlockJobDriver test_drop_backing_job_driver = { 15658e442810SMax Reitz .job_driver = { 15668e442810SMax Reitz .instance_size = sizeof(TestDropBackingBlockJob), 15678e442810SMax Reitz .free = block_job_free, 15688e442810SMax Reitz .user_resume = block_job_user_resume, 15698e442810SMax Reitz .run = test_drop_backing_job_run, 15708e442810SMax Reitz .commit = test_drop_backing_job_commit, 15718e442810SMax Reitz } 15728e442810SMax Reitz }; 15738e442810SMax Reitz 15748e442810SMax Reitz /** 15758e442810SMax Reitz * Creates a child node with three parent nodes on it, and then runs a 15768e442810SMax Reitz * block job on the final one, parent-node-2. 15778e442810SMax Reitz * 15788e442810SMax Reitz * The job is then asked to complete before a section where the child 15798e442810SMax Reitz * is drained. 15808e442810SMax Reitz * 15818e442810SMax Reitz * Ending this section will undrain the child's parents, first 15828e442810SMax Reitz * parent-node-2, then parent-node-1, then parent-node-0 -- the parent 15838e442810SMax Reitz * list is in reverse order of how they were added. Ending the drain 15848e442810SMax Reitz * on parent-node-2 will resume the job, thus completing it and 15858e442810SMax Reitz * scheduling job_exit(). 15868e442810SMax Reitz * 15878e442810SMax Reitz * Ending the drain on parent-node-1 will poll the AioContext, which 15888e442810SMax Reitz * lets job_exit() and thus test_drop_backing_job_commit() run. That 15892afdc790SMax Reitz * function first removes the child as parent-node-2's backing file. 15908e442810SMax Reitz * 15918e442810SMax Reitz * In old (and buggy) implementations, there are two problems with 15928e442810SMax Reitz * that: 15938e442810SMax Reitz * (A) bdrv_drain_invoke() polls for every node that leaves the 15948e442810SMax Reitz * drained section. This means that job_exit() is scheduled 15958e442810SMax Reitz * before the child has left the drained section. Its 15968e442810SMax Reitz * quiesce_counter is therefore still 1 when it is removed from 15978e442810SMax Reitz * parent-node-2. 15988e442810SMax Reitz * 15998e442810SMax Reitz * (B) bdrv_replace_child_noperm() calls drained_end() on the old 16008e442810SMax Reitz * child's parents as many times as the child is quiesced. This 16018e442810SMax Reitz * means it will call drained_end() on parent-node-2 once. 16028e442810SMax Reitz * Because parent-node-2 is no longer quiesced at this point, this 16038e442810SMax Reitz * will fail. 16048e442810SMax Reitz * 16058e442810SMax Reitz * bdrv_replace_child_noperm() therefore must call drained_end() on 16068e442810SMax Reitz * the parent only if it really is still drained because the child is 16078e442810SMax Reitz * drained. 16082afdc790SMax Reitz * 16092afdc790SMax Reitz * If removing child from parent-node-2 was successful (as it should 16102afdc790SMax Reitz * be), test_drop_backing_job_commit() will then also remove the child 16112afdc790SMax Reitz * from parent-node-0. 16122afdc790SMax Reitz * 16132afdc790SMax Reitz * With an old version of our drain infrastructure ((A) above), that 16142afdc790SMax Reitz * resulted in the following flow: 16152afdc790SMax Reitz * 16162afdc790SMax Reitz * 1. child attempts to leave its drained section. The call recurses 16172afdc790SMax Reitz * to its parents. 16182afdc790SMax Reitz * 16192afdc790SMax Reitz * 2. parent-node-2 leaves the drained section. Polling in 16202afdc790SMax Reitz * bdrv_drain_invoke() will schedule job_exit(). 16212afdc790SMax Reitz * 16222afdc790SMax Reitz * 3. parent-node-1 leaves the drained section. Polling in 16232afdc790SMax Reitz * bdrv_drain_invoke() will run job_exit(), thus disconnecting 16242afdc790SMax Reitz * parent-node-0 from the child node. 16252afdc790SMax Reitz * 16262afdc790SMax Reitz * 4. bdrv_parent_drained_end() uses a QLIST_FOREACH_SAFE() loop to 16272afdc790SMax Reitz * iterate over the parents. Thus, it now accesses the BdrvChild 16282afdc790SMax Reitz * object that used to connect parent-node-0 and the child node. 16292afdc790SMax Reitz * However, that object no longer exists, so it accesses a dangling 16302afdc790SMax Reitz * pointer. 16312afdc790SMax Reitz * 16322afdc790SMax Reitz * The solution is to only poll once when running a bdrv_drained_end() 16332afdc790SMax Reitz * operation, specifically at the end when all drained_end() 16342afdc790SMax Reitz * operations for all involved nodes have been scheduled. 16352afdc790SMax Reitz * Note that this also solves (A) above, thus hiding (B). 16368e442810SMax Reitz */ 16378e442810SMax Reitz static void test_blockjob_commit_by_drained_end(void) 16388e442810SMax Reitz { 16398e442810SMax Reitz BlockDriverState *bs_child, *bs_parents[3]; 16408e442810SMax Reitz TestDropBackingBlockJob *job; 16418e442810SMax Reitz bool job_has_completed = false; 16428e442810SMax Reitz int i; 16438e442810SMax Reitz 16448e442810SMax Reitz bs_child = bdrv_new_open_driver(&bdrv_test, "child-node", BDRV_O_RDWR, 16458e442810SMax Reitz &error_abort); 16468e442810SMax Reitz 16478e442810SMax Reitz for (i = 0; i < 3; i++) { 16488e442810SMax Reitz char name[32]; 16498e442810SMax Reitz snprintf(name, sizeof(name), "parent-node-%i", i); 16508e442810SMax Reitz bs_parents[i] = bdrv_new_open_driver(&bdrv_test, name, BDRV_O_RDWR, 16518e442810SMax Reitz &error_abort); 16528e442810SMax Reitz bdrv_set_backing_hd(bs_parents[i], bs_child, &error_abort); 16538e442810SMax Reitz } 16548e442810SMax Reitz 16558e442810SMax Reitz job = block_job_create("job", &test_drop_backing_job_driver, NULL, 16568e442810SMax Reitz bs_parents[2], 0, BLK_PERM_ALL, 0, 0, NULL, NULL, 16578e442810SMax Reitz &error_abort); 16588e442810SMax Reitz 16592afdc790SMax Reitz job->detach_also = bs_parents[0]; 16608e442810SMax Reitz job->did_complete = &job_has_completed; 16618e442810SMax Reitz 16628e442810SMax Reitz job_start(&job->common.job); 16638e442810SMax Reitz 16648e442810SMax Reitz job->should_complete = true; 16658e442810SMax Reitz bdrv_drained_begin(bs_child); 16668e442810SMax Reitz g_assert(!job_has_completed); 16678e442810SMax Reitz bdrv_drained_end(bs_child); 16688e442810SMax Reitz g_assert(job_has_completed); 16698e442810SMax Reitz 16708e442810SMax Reitz bdrv_unref(bs_parents[0]); 16718e442810SMax Reitz bdrv_unref(bs_parents[1]); 16728e442810SMax Reitz bdrv_unref(bs_parents[2]); 16738e442810SMax Reitz bdrv_unref(bs_child); 16748e442810SMax Reitz } 16758e442810SMax Reitz 16769746b35cSMax Reitz 16779746b35cSMax Reitz typedef struct TestSimpleBlockJob { 16789746b35cSMax Reitz BlockJob common; 16799746b35cSMax Reitz bool should_complete; 16809746b35cSMax Reitz bool *did_complete; 16819746b35cSMax Reitz } TestSimpleBlockJob; 16829746b35cSMax Reitz 16839746b35cSMax Reitz static int coroutine_fn test_simple_job_run(Job *job, Error **errp) 16849746b35cSMax Reitz { 16859746b35cSMax Reitz TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job); 16869746b35cSMax Reitz 16879746b35cSMax Reitz while (!s->should_complete) { 16889746b35cSMax Reitz job_sleep_ns(job, 0); 16899746b35cSMax Reitz } 16909746b35cSMax Reitz 16919746b35cSMax Reitz return 0; 16929746b35cSMax Reitz } 16939746b35cSMax Reitz 16949746b35cSMax Reitz static void test_simple_job_clean(Job *job) 16959746b35cSMax Reitz { 16969746b35cSMax Reitz TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job); 16979746b35cSMax Reitz *s->did_complete = true; 16989746b35cSMax Reitz } 16999746b35cSMax Reitz 17009746b35cSMax Reitz static const BlockJobDriver test_simple_job_driver = { 17019746b35cSMax Reitz .job_driver = { 17029746b35cSMax Reitz .instance_size = sizeof(TestSimpleBlockJob), 17039746b35cSMax Reitz .free = block_job_free, 17049746b35cSMax Reitz .user_resume = block_job_user_resume, 17059746b35cSMax Reitz .run = test_simple_job_run, 17069746b35cSMax Reitz .clean = test_simple_job_clean, 17079746b35cSMax Reitz }, 17089746b35cSMax Reitz }; 17099746b35cSMax Reitz 17109746b35cSMax Reitz static int drop_intermediate_poll_update_filename(BdrvChild *child, 17119746b35cSMax Reitz BlockDriverState *new_base, 17129746b35cSMax Reitz const char *filename, 17139746b35cSMax Reitz Error **errp) 17149746b35cSMax Reitz { 17159746b35cSMax Reitz /* 17169746b35cSMax Reitz * We are free to poll here, which may change the block graph, if 17179746b35cSMax Reitz * it is not drained. 17189746b35cSMax Reitz */ 17199746b35cSMax Reitz 17209746b35cSMax Reitz /* If the job is not drained: Complete it, schedule job_exit() */ 17219746b35cSMax Reitz aio_poll(qemu_get_current_aio_context(), false); 17229746b35cSMax Reitz /* If the job is not drained: Run job_exit(), finish the job */ 17239746b35cSMax Reitz aio_poll(qemu_get_current_aio_context(), false); 17249746b35cSMax Reitz 17259746b35cSMax Reitz return 0; 17269746b35cSMax Reitz } 17279746b35cSMax Reitz 17289746b35cSMax Reitz /** 17299746b35cSMax Reitz * Test a poll in the midst of bdrv_drop_intermediate(). 17309746b35cSMax Reitz * 1731bd86fb99SMax Reitz * bdrv_drop_intermediate() calls BdrvChildClass.update_filename(), 17329746b35cSMax Reitz * which can yield or poll. This may lead to graph changes, unless 17339746b35cSMax Reitz * the whole subtree in question is drained. 17349746b35cSMax Reitz * 17359746b35cSMax Reitz * We test this on the following graph: 17369746b35cSMax Reitz * 17379746b35cSMax Reitz * Job 17389746b35cSMax Reitz * 17399746b35cSMax Reitz * | 17409746b35cSMax Reitz * job-node 17419746b35cSMax Reitz * | 17429746b35cSMax Reitz * v 17439746b35cSMax Reitz * 17449746b35cSMax Reitz * job-node 17459746b35cSMax Reitz * 17469746b35cSMax Reitz * | 17479746b35cSMax Reitz * backing 17489746b35cSMax Reitz * | 17499746b35cSMax Reitz * v 17509746b35cSMax Reitz * 17519746b35cSMax Reitz * node-2 --chain--> node-1 --chain--> node-0 17529746b35cSMax Reitz * 17539746b35cSMax Reitz * We drop node-1 with bdrv_drop_intermediate(top=node-1, base=node-0). 17549746b35cSMax Reitz * 17559746b35cSMax Reitz * This first updates node-2's backing filename by invoking 17569746b35cSMax Reitz * drop_intermediate_poll_update_filename(), which polls twice. This 17579746b35cSMax Reitz * causes the job to finish, which in turns causes the job-node to be 17589746b35cSMax Reitz * deleted. 17599746b35cSMax Reitz * 17609746b35cSMax Reitz * bdrv_drop_intermediate() uses a QLIST_FOREACH_SAFE() loop, so it 17619746b35cSMax Reitz * already has a pointer to the BdrvChild edge between job-node and 17629746b35cSMax Reitz * node-1. When it tries to handle that edge, we probably get a 17639746b35cSMax Reitz * segmentation fault because the object no longer exists. 17649746b35cSMax Reitz * 17659746b35cSMax Reitz * 17669746b35cSMax Reitz * The solution is for bdrv_drop_intermediate() to drain top's 17679746b35cSMax Reitz * subtree. This prevents graph changes from happening just because 1768bd86fb99SMax Reitz * BdrvChildClass.update_filename() yields or polls. Thus, the block 17699746b35cSMax Reitz * job is paused during that drained section and must finish before or 17709746b35cSMax Reitz * after. 17719746b35cSMax Reitz * 17729746b35cSMax Reitz * (In addition, bdrv_replace_child() must keep the job paused.) 17739746b35cSMax Reitz */ 17749746b35cSMax Reitz static void test_drop_intermediate_poll(void) 17759746b35cSMax Reitz { 1776bd86fb99SMax Reitz static BdrvChildClass chain_child_class; 17779746b35cSMax Reitz BlockDriverState *chain[3]; 17789746b35cSMax Reitz TestSimpleBlockJob *job; 17799746b35cSMax Reitz BlockDriverState *job_node; 17809746b35cSMax Reitz bool job_has_completed = false; 17819746b35cSMax Reitz int i; 17829746b35cSMax Reitz int ret; 17839746b35cSMax Reitz 178425191e5fSMax Reitz chain_child_class = child_of_bds; 1785bd86fb99SMax Reitz chain_child_class.update_filename = drop_intermediate_poll_update_filename; 17869746b35cSMax Reitz 17879746b35cSMax Reitz for (i = 0; i < 3; i++) { 17889746b35cSMax Reitz char name[32]; 17899746b35cSMax Reitz snprintf(name, 32, "node-%i", i); 17909746b35cSMax Reitz 17919746b35cSMax Reitz chain[i] = bdrv_new_open_driver(&bdrv_test, name, 0, &error_abort); 17929746b35cSMax Reitz } 17939746b35cSMax Reitz 17949746b35cSMax Reitz job_node = bdrv_new_open_driver(&bdrv_test, "job-node", BDRV_O_RDWR, 17959746b35cSMax Reitz &error_abort); 17969746b35cSMax Reitz bdrv_set_backing_hd(job_node, chain[1], &error_abort); 17979746b35cSMax Reitz 17989746b35cSMax Reitz /* 17999746b35cSMax Reitz * Establish the chain last, so the chain links are the first 18009746b35cSMax Reitz * elements in the BDS.parents lists 18019746b35cSMax Reitz */ 18029746b35cSMax Reitz for (i = 0; i < 3; i++) { 18039746b35cSMax Reitz if (i) { 18049746b35cSMax Reitz /* Takes the reference to chain[i - 1] */ 18059746b35cSMax Reitz chain[i]->backing = bdrv_attach_child(chain[i], chain[i - 1], 1806bd86fb99SMax Reitz "chain", &chain_child_class, 180725191e5fSMax Reitz BDRV_CHILD_COW, &error_abort); 18089746b35cSMax Reitz } 18099746b35cSMax Reitz } 18109746b35cSMax Reitz 18119746b35cSMax Reitz job = block_job_create("job", &test_simple_job_driver, NULL, job_node, 18129746b35cSMax Reitz 0, BLK_PERM_ALL, 0, 0, NULL, NULL, &error_abort); 18139746b35cSMax Reitz 18149746b35cSMax Reitz /* The job has a reference now */ 18159746b35cSMax Reitz bdrv_unref(job_node); 18169746b35cSMax Reitz 18179746b35cSMax Reitz job->did_complete = &job_has_completed; 18189746b35cSMax Reitz 18199746b35cSMax Reitz job_start(&job->common.job); 18209746b35cSMax Reitz job->should_complete = true; 18219746b35cSMax Reitz 18229746b35cSMax Reitz g_assert(!job_has_completed); 18239746b35cSMax Reitz ret = bdrv_drop_intermediate(chain[1], chain[0], NULL); 18249746b35cSMax Reitz g_assert(ret == 0); 18259746b35cSMax Reitz g_assert(job_has_completed); 18269746b35cSMax Reitz 18279746b35cSMax Reitz bdrv_unref(chain[2]); 18289746b35cSMax Reitz } 18299746b35cSMax Reitz 18300513f984SMax Reitz 18310513f984SMax Reitz typedef struct BDRVReplaceTestState { 18320513f984SMax Reitz bool was_drained; 18330513f984SMax Reitz bool was_undrained; 18340513f984SMax Reitz bool has_read; 18350513f984SMax Reitz 18360513f984SMax Reitz int drain_count; 18370513f984SMax Reitz 18380513f984SMax Reitz bool yield_before_read; 18390513f984SMax Reitz Coroutine *io_co; 18400513f984SMax Reitz Coroutine *drain_co; 18410513f984SMax Reitz } BDRVReplaceTestState; 18420513f984SMax Reitz 18430513f984SMax Reitz static void bdrv_replace_test_close(BlockDriverState *bs) 18440513f984SMax Reitz { 18450513f984SMax Reitz } 18460513f984SMax Reitz 18470513f984SMax Reitz /** 18480513f984SMax Reitz * If @bs has a backing file: 18490513f984SMax Reitz * Yield if .yield_before_read is true (and wait for drain_begin to 18500513f984SMax Reitz * wake us up). 18510513f984SMax Reitz * Forward the read to bs->backing. Set .has_read to true. 18520513f984SMax Reitz * If drain_begin has woken us, wake it in turn. 18530513f984SMax Reitz * 18540513f984SMax Reitz * Otherwise: 18550513f984SMax Reitz * Set .has_read to true and return success. 18560513f984SMax Reitz */ 18570513f984SMax Reitz static int coroutine_fn bdrv_replace_test_co_preadv(BlockDriverState *bs, 18580513f984SMax Reitz uint64_t offset, 18590513f984SMax Reitz uint64_t bytes, 18600513f984SMax Reitz QEMUIOVector *qiov, 18610513f984SMax Reitz int flags) 18620513f984SMax Reitz { 18630513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 18640513f984SMax Reitz 18650513f984SMax Reitz if (bs->backing) { 18660513f984SMax Reitz int ret; 18670513f984SMax Reitz 18680513f984SMax Reitz g_assert(!s->drain_count); 18690513f984SMax Reitz 18700513f984SMax Reitz s->io_co = qemu_coroutine_self(); 18710513f984SMax Reitz if (s->yield_before_read) { 18720513f984SMax Reitz s->yield_before_read = false; 18730513f984SMax Reitz qemu_coroutine_yield(); 18740513f984SMax Reitz } 18750513f984SMax Reitz s->io_co = NULL; 18760513f984SMax Reitz 1877fae2681aSVladimir Sementsov-Ogievskiy ret = bdrv_co_preadv(bs->backing, offset, bytes, qiov, 0); 18780513f984SMax Reitz s->has_read = true; 18790513f984SMax Reitz 18800513f984SMax Reitz /* Wake up drain_co if it runs */ 18810513f984SMax Reitz if (s->drain_co) { 18820513f984SMax Reitz aio_co_wake(s->drain_co); 18830513f984SMax Reitz } 18840513f984SMax Reitz 18850513f984SMax Reitz return ret; 18860513f984SMax Reitz } 18870513f984SMax Reitz 18880513f984SMax Reitz s->has_read = true; 18890513f984SMax Reitz return 0; 18900513f984SMax Reitz } 18910513f984SMax Reitz 18920513f984SMax Reitz /** 18930513f984SMax Reitz * If .drain_count is 0, wake up .io_co if there is one; and set 18940513f984SMax Reitz * .was_drained. 18950513f984SMax Reitz * Increment .drain_count. 18960513f984SMax Reitz */ 18970513f984SMax Reitz static void coroutine_fn bdrv_replace_test_co_drain_begin(BlockDriverState *bs) 18980513f984SMax Reitz { 18990513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 19000513f984SMax Reitz 19010513f984SMax Reitz if (!s->drain_count) { 19020513f984SMax Reitz /* Keep waking io_co up until it is done */ 19030513f984SMax Reitz s->drain_co = qemu_coroutine_self(); 19040513f984SMax Reitz while (s->io_co) { 19050513f984SMax Reitz aio_co_wake(s->io_co); 19060513f984SMax Reitz s->io_co = NULL; 19070513f984SMax Reitz qemu_coroutine_yield(); 19080513f984SMax Reitz } 19090513f984SMax Reitz s->drain_co = NULL; 19100513f984SMax Reitz 19110513f984SMax Reitz s->was_drained = true; 19120513f984SMax Reitz } 19130513f984SMax Reitz s->drain_count++; 19140513f984SMax Reitz } 19150513f984SMax Reitz 19160513f984SMax Reitz /** 19170513f984SMax Reitz * Reduce .drain_count, set .was_undrained once it reaches 0. 19180513f984SMax Reitz * If .drain_count reaches 0 and the node has a backing file, issue a 19190513f984SMax Reitz * read request. 19200513f984SMax Reitz */ 19210513f984SMax Reitz static void coroutine_fn bdrv_replace_test_co_drain_end(BlockDriverState *bs) 19220513f984SMax Reitz { 19230513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 19240513f984SMax Reitz 19250513f984SMax Reitz g_assert(s->drain_count > 0); 19260513f984SMax Reitz if (!--s->drain_count) { 19270513f984SMax Reitz int ret; 19280513f984SMax Reitz 19290513f984SMax Reitz s->was_undrained = true; 19300513f984SMax Reitz 19310513f984SMax Reitz if (bs->backing) { 19320513f984SMax Reitz char data; 19330513f984SMax Reitz QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, &data, 1); 19340513f984SMax Reitz 19350513f984SMax Reitz /* Queue a read request post-drain */ 19360513f984SMax Reitz ret = bdrv_replace_test_co_preadv(bs, 0, 1, &qiov, 0); 19370513f984SMax Reitz g_assert(ret >= 0); 19380513f984SMax Reitz } 19390513f984SMax Reitz } 19400513f984SMax Reitz } 19410513f984SMax Reitz 19420513f984SMax Reitz static BlockDriver bdrv_replace_test = { 19430513f984SMax Reitz .format_name = "replace_test", 19440513f984SMax Reitz .instance_size = sizeof(BDRVReplaceTestState), 19450513f984SMax Reitz 19460513f984SMax Reitz .bdrv_close = bdrv_replace_test_close, 19470513f984SMax Reitz .bdrv_co_preadv = bdrv_replace_test_co_preadv, 19480513f984SMax Reitz 19490513f984SMax Reitz .bdrv_co_drain_begin = bdrv_replace_test_co_drain_begin, 19500513f984SMax Reitz .bdrv_co_drain_end = bdrv_replace_test_co_drain_end, 19510513f984SMax Reitz 195269dca43dSMax Reitz .bdrv_child_perm = bdrv_default_perms, 19530513f984SMax Reitz }; 19540513f984SMax Reitz 19550513f984SMax Reitz static void coroutine_fn test_replace_child_mid_drain_read_co(void *opaque) 19560513f984SMax Reitz { 19570513f984SMax Reitz int ret; 19580513f984SMax Reitz char data; 19590513f984SMax Reitz 19600513f984SMax Reitz ret = blk_co_pread(opaque, 0, 1, &data, 0); 19610513f984SMax Reitz g_assert(ret >= 0); 19620513f984SMax Reitz } 19630513f984SMax Reitz 19640513f984SMax Reitz /** 19650513f984SMax Reitz * We test two things: 19660513f984SMax Reitz * (1) bdrv_replace_child_noperm() must not undrain the parent if both 19670513f984SMax Reitz * children are drained. 19680513f984SMax Reitz * (2) bdrv_replace_child_noperm() must never flush I/O requests to a 19690513f984SMax Reitz * drained child. If the old child is drained, it must flush I/O 19700513f984SMax Reitz * requests after the new one has been attached. If the new child 19710513f984SMax Reitz * is drained, it must flush I/O requests before the old one is 19720513f984SMax Reitz * detached. 19730513f984SMax Reitz * 19740513f984SMax Reitz * To do so, we create one parent node and two child nodes; then 19750513f984SMax Reitz * attach one of the children (old_child_bs) to the parent, then 19760513f984SMax Reitz * drain both old_child_bs and new_child_bs according to 19770513f984SMax Reitz * old_drain_count and new_drain_count, respectively, and finally 19780513f984SMax Reitz * we invoke bdrv_replace_node() to replace old_child_bs by 19790513f984SMax Reitz * new_child_bs. 19800513f984SMax Reitz * 19810513f984SMax Reitz * The test block driver we use here (bdrv_replace_test) has a read 19820513f984SMax Reitz * function that: 19830513f984SMax Reitz * - For the parent node, can optionally yield, and then forwards the 19840513f984SMax Reitz * read to bdrv_preadv(), 19850513f984SMax Reitz * - For the child node, just returns immediately. 19860513f984SMax Reitz * 19870513f984SMax Reitz * If the read yields, the drain_begin function will wake it up. 19880513f984SMax Reitz * 19890513f984SMax Reitz * The drain_end function issues a read on the parent once it is fully 19900513f984SMax Reitz * undrained (which simulates requests starting to come in again). 19910513f984SMax Reitz */ 19920513f984SMax Reitz static void do_test_replace_child_mid_drain(int old_drain_count, 19930513f984SMax Reitz int new_drain_count) 19940513f984SMax Reitz { 19950513f984SMax Reitz BlockBackend *parent_blk; 19960513f984SMax Reitz BlockDriverState *parent_bs; 19970513f984SMax Reitz BlockDriverState *old_child_bs, *new_child_bs; 19980513f984SMax Reitz BDRVReplaceTestState *parent_s; 19990513f984SMax Reitz BDRVReplaceTestState *old_child_s, *new_child_s; 20000513f984SMax Reitz Coroutine *io_co; 20010513f984SMax Reitz int i; 20020513f984SMax Reitz 20030513f984SMax Reitz parent_bs = bdrv_new_open_driver(&bdrv_replace_test, "parent", 0, 20040513f984SMax Reitz &error_abort); 20050513f984SMax Reitz parent_s = parent_bs->opaque; 20060513f984SMax Reitz 20070513f984SMax Reitz parent_blk = blk_new(qemu_get_aio_context(), 20080513f984SMax Reitz BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL); 20090513f984SMax Reitz blk_insert_bs(parent_blk, parent_bs, &error_abort); 20100513f984SMax Reitz 20110513f984SMax Reitz old_child_bs = bdrv_new_open_driver(&bdrv_replace_test, "old-child", 0, 20120513f984SMax Reitz &error_abort); 20130513f984SMax Reitz new_child_bs = bdrv_new_open_driver(&bdrv_replace_test, "new-child", 0, 20140513f984SMax Reitz &error_abort); 20150513f984SMax Reitz old_child_s = old_child_bs->opaque; 20160513f984SMax Reitz new_child_s = new_child_bs->opaque; 20170513f984SMax Reitz 20180513f984SMax Reitz /* So that we can read something */ 20190513f984SMax Reitz parent_bs->total_sectors = 1; 20200513f984SMax Reitz old_child_bs->total_sectors = 1; 20210513f984SMax Reitz new_child_bs->total_sectors = 1; 20220513f984SMax Reitz 20230513f984SMax Reitz bdrv_ref(old_child_bs); 20240513f984SMax Reitz parent_bs->backing = bdrv_attach_child(parent_bs, old_child_bs, "child", 202525191e5fSMax Reitz &child_of_bds, BDRV_CHILD_COW, 202625191e5fSMax Reitz &error_abort); 20270513f984SMax Reitz 20280513f984SMax Reitz for (i = 0; i < old_drain_count; i++) { 20290513f984SMax Reitz bdrv_drained_begin(old_child_bs); 20300513f984SMax Reitz } 20310513f984SMax Reitz for (i = 0; i < new_drain_count; i++) { 20320513f984SMax Reitz bdrv_drained_begin(new_child_bs); 20330513f984SMax Reitz } 20340513f984SMax Reitz 20350513f984SMax Reitz if (!old_drain_count) { 20360513f984SMax Reitz /* 20370513f984SMax Reitz * Start a read operation that will yield, so it will not 20380513f984SMax Reitz * complete before the node is drained. 20390513f984SMax Reitz */ 20400513f984SMax Reitz parent_s->yield_before_read = true; 20410513f984SMax Reitz io_co = qemu_coroutine_create(test_replace_child_mid_drain_read_co, 20420513f984SMax Reitz parent_blk); 20430513f984SMax Reitz qemu_coroutine_enter(io_co); 20440513f984SMax Reitz } 20450513f984SMax Reitz 20460513f984SMax Reitz /* If we have started a read operation, it should have yielded */ 20470513f984SMax Reitz g_assert(!parent_s->has_read); 20480513f984SMax Reitz 20490513f984SMax Reitz /* Reset drained status so we can see what bdrv_replace_node() does */ 20500513f984SMax Reitz parent_s->was_drained = false; 20510513f984SMax Reitz parent_s->was_undrained = false; 20520513f984SMax Reitz 20530513f984SMax Reitz g_assert(parent_bs->quiesce_counter == old_drain_count); 20540513f984SMax Reitz bdrv_replace_node(old_child_bs, new_child_bs, &error_abort); 20550513f984SMax Reitz g_assert(parent_bs->quiesce_counter == new_drain_count); 20560513f984SMax Reitz 20570513f984SMax Reitz if (!old_drain_count && !new_drain_count) { 20580513f984SMax Reitz /* 20590513f984SMax Reitz * From undrained to undrained drains and undrains the parent, 20600513f984SMax Reitz * because bdrv_replace_node() contains a drained section for 20610513f984SMax Reitz * @old_child_bs. 20620513f984SMax Reitz */ 20630513f984SMax Reitz g_assert(parent_s->was_drained && parent_s->was_undrained); 20640513f984SMax Reitz } else if (!old_drain_count && new_drain_count) { 20650513f984SMax Reitz /* 20660513f984SMax Reitz * From undrained to drained should drain the parent and keep 20670513f984SMax Reitz * it that way. 20680513f984SMax Reitz */ 20690513f984SMax Reitz g_assert(parent_s->was_drained && !parent_s->was_undrained); 20700513f984SMax Reitz } else if (old_drain_count && !new_drain_count) { 20710513f984SMax Reitz /* 20720513f984SMax Reitz * From drained to undrained should undrain the parent and 20730513f984SMax Reitz * keep it that way. 20740513f984SMax Reitz */ 20750513f984SMax Reitz g_assert(!parent_s->was_drained && parent_s->was_undrained); 20760513f984SMax Reitz } else /* if (old_drain_count && new_drain_count) */ { 20770513f984SMax Reitz /* 20780513f984SMax Reitz * From drained to drained must not undrain the parent at any 20790513f984SMax Reitz * point 20800513f984SMax Reitz */ 20810513f984SMax Reitz g_assert(!parent_s->was_drained && !parent_s->was_undrained); 20820513f984SMax Reitz } 20830513f984SMax Reitz 20840513f984SMax Reitz if (!old_drain_count || !new_drain_count) { 20850513f984SMax Reitz /* 20860513f984SMax Reitz * If !old_drain_count, we have started a read request before 20870513f984SMax Reitz * bdrv_replace_node(). If !new_drain_count, the parent must 20880513f984SMax Reitz * have been undrained at some point, and 20890513f984SMax Reitz * bdrv_replace_test_co_drain_end() starts a read request 20900513f984SMax Reitz * then. 20910513f984SMax Reitz */ 20920513f984SMax Reitz g_assert(parent_s->has_read); 20930513f984SMax Reitz } else { 20940513f984SMax Reitz /* 20950513f984SMax Reitz * If the parent was never undrained, there is no way to start 20960513f984SMax Reitz * a read request. 20970513f984SMax Reitz */ 20980513f984SMax Reitz g_assert(!parent_s->has_read); 20990513f984SMax Reitz } 21000513f984SMax Reitz 21010513f984SMax Reitz /* A drained child must have not received any request */ 21020513f984SMax Reitz g_assert(!(old_drain_count && old_child_s->has_read)); 21030513f984SMax Reitz g_assert(!(new_drain_count && new_child_s->has_read)); 21040513f984SMax Reitz 21050513f984SMax Reitz for (i = 0; i < new_drain_count; i++) { 21060513f984SMax Reitz bdrv_drained_end(new_child_bs); 21070513f984SMax Reitz } 21080513f984SMax Reitz for (i = 0; i < old_drain_count; i++) { 21090513f984SMax Reitz bdrv_drained_end(old_child_bs); 21100513f984SMax Reitz } 21110513f984SMax Reitz 21120513f984SMax Reitz /* 21130513f984SMax Reitz * By now, bdrv_replace_test_co_drain_end() must have been called 21140513f984SMax Reitz * at some point while the new child was attached to the parent. 21150513f984SMax Reitz */ 21160513f984SMax Reitz g_assert(parent_s->has_read); 21170513f984SMax Reitz g_assert(new_child_s->has_read); 21180513f984SMax Reitz 21190513f984SMax Reitz blk_unref(parent_blk); 21200513f984SMax Reitz bdrv_unref(parent_bs); 21210513f984SMax Reitz bdrv_unref(old_child_bs); 21220513f984SMax Reitz bdrv_unref(new_child_bs); 21230513f984SMax Reitz } 21240513f984SMax Reitz 21250513f984SMax Reitz static void test_replace_child_mid_drain(void) 21260513f984SMax Reitz { 21270513f984SMax Reitz int old_drain_count, new_drain_count; 21280513f984SMax Reitz 21290513f984SMax Reitz for (old_drain_count = 0; old_drain_count < 2; old_drain_count++) { 21300513f984SMax Reitz for (new_drain_count = 0; new_drain_count < 2; new_drain_count++) { 21310513f984SMax Reitz do_test_replace_child_mid_drain(old_drain_count, new_drain_count); 21320513f984SMax Reitz } 21330513f984SMax Reitz } 21340513f984SMax Reitz } 21350513f984SMax Reitz 2136881cfd17SKevin Wolf int main(int argc, char **argv) 2137881cfd17SKevin Wolf { 2138bb675689SKevin Wolf int ret; 2139bb675689SKevin Wolf 2140881cfd17SKevin Wolf bdrv_init(); 2141881cfd17SKevin Wolf qemu_init_main_loop(&error_abort); 2142881cfd17SKevin Wolf 2143881cfd17SKevin Wolf g_test_init(&argc, &argv, NULL); 2144bb675689SKevin Wolf qemu_event_init(&done_event, false); 2145881cfd17SKevin Wolf 2146881cfd17SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all); 214786e1c840SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain); 2148d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain_subtree", 2149d2a85d0fSKevin Wolf test_drv_cb_drain_subtree); 2150881cfd17SKevin Wolf 21516d0252f2SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain_all", 21526d0252f2SKevin Wolf test_drv_cb_co_drain_all); 21530582eb10SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain", test_drv_cb_co_drain); 21540582eb10SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain_subtree", 21550582eb10SKevin Wolf test_drv_cb_co_drain_subtree); 21560582eb10SKevin Wolf 21570582eb10SKevin Wolf 215889a6ceabSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all); 215989a6ceabSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain); 2160d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain_subtree", 2161d2a85d0fSKevin Wolf test_quiesce_drain_subtree); 216289a6ceabSKevin Wolf 21636d0252f2SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain_all", 21646d0252f2SKevin Wolf test_quiesce_co_drain_all); 21650582eb10SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain", test_quiesce_co_drain); 21660582eb10SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain_subtree", 21670582eb10SKevin Wolf test_quiesce_co_drain_subtree); 21680582eb10SKevin Wolf 21696c429a6aSKevin Wolf g_test_add_func("/bdrv-drain/nested", test_nested); 217027e64474SKevin Wolf g_test_add_func("/bdrv-drain/multiparent", test_multiparent); 217119f7a7e5SKevin Wolf 217219f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/graph-change/drain_subtree", 217319f7a7e5SKevin Wolf test_graph_change_drain_subtree); 217419f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/graph-change/drain_all", 217519f7a7e5SKevin Wolf test_graph_change_drain_all); 21766c429a6aSKevin Wolf 2177bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain_all", test_iothread_drain_all); 2178bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain", test_iothread_drain); 2179bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain_subtree", 2180bb675689SKevin Wolf test_iothread_drain_subtree); 2181bb675689SKevin Wolf 21827253220dSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all); 21837253220dSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain); 2184d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain_subtree", 2185d2a85d0fSKevin Wolf test_blockjob_drain_subtree); 21867253220dSKevin Wolf 2187d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain_all", 2188d49725afSKevin Wolf test_blockjob_error_drain_all); 2189d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain", 2190d49725afSKevin Wolf test_blockjob_error_drain); 2191d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain_subtree", 2192d49725afSKevin Wolf test_blockjob_error_drain_subtree); 2193d49725afSKevin Wolf 2194f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain_all", 2195f62c1729SKevin Wolf test_blockjob_iothread_drain_all); 2196f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain", 2197f62c1729SKevin Wolf test_blockjob_iothread_drain); 2198f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain_subtree", 2199f62c1729SKevin Wolf test_blockjob_iothread_drain_subtree); 2200f62c1729SKevin Wolf 2201d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_all", 2202d49725afSKevin Wolf test_blockjob_iothread_error_drain_all); 2203d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain", 2204d49725afSKevin Wolf test_blockjob_iothread_error_drain); 2205d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_subtree", 2206d49725afSKevin Wolf test_blockjob_iothread_error_drain_subtree); 2207d49725afSKevin Wolf 2208ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/deletion/drain", test_delete_by_drain); 220919f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain_all", test_detach_by_drain_all); 2210ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain", test_detach_by_drain); 2211ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain_subtree", test_detach_by_drain_subtree); 2212231281abSKevin Wolf g_test_add_func("/bdrv-drain/detach/parent_cb", test_detach_by_parent_cb); 221357320ca9SKevin Wolf g_test_add_func("/bdrv-drain/detach/driver_cb", test_detach_by_driver_cb); 22144c8158e3SMax Reitz 2215b994c5bcSKevin Wolf g_test_add_func("/bdrv-drain/attach/drain", test_append_to_drained); 2216b994c5bcSKevin Wolf 2217247d2737SKevin Wolf g_test_add_func("/bdrv-drain/set_aio_context", test_set_aio_context); 2218247d2737SKevin Wolf 22198e442810SMax Reitz g_test_add_func("/bdrv-drain/blockjob/commit_by_drained_end", 22208e442810SMax Reitz test_blockjob_commit_by_drained_end); 22218e442810SMax Reitz 22229746b35cSMax Reitz g_test_add_func("/bdrv-drain/bdrv_drop_intermediate/poll", 22239746b35cSMax Reitz test_drop_intermediate_poll); 22249746b35cSMax Reitz 22250513f984SMax Reitz g_test_add_func("/bdrv-drain/replace_child/mid-drain", 22260513f984SMax Reitz test_replace_child_mid_drain); 22270513f984SMax Reitz 2228bb675689SKevin Wolf ret = g_test_run(); 2229bb675689SKevin Wolf qemu_event_destroy(&done_event); 2230bb675689SKevin Wolf return ret; 2231881cfd17SKevin Wolf } 2232