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 41*7bce1c29SKevin Wolf static void coroutine_fn sleep_in_drain_begin(void *opaque) 42*7bce1c29SKevin Wolf { 43*7bce1c29SKevin Wolf BlockDriverState *bs = opaque; 44*7bce1c29SKevin Wolf 45*7bce1c29SKevin Wolf qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000); 46*7bce1c29SKevin Wolf bdrv_dec_in_flight(bs); 47*7bce1c29SKevin Wolf } 48*7bce1c29SKevin Wolf 49881cfd17SKevin Wolf static void coroutine_fn bdrv_test_co_drain_begin(BlockDriverState *bs) 50881cfd17SKevin Wolf { 51881cfd17SKevin Wolf BDRVTestState *s = bs->opaque; 52881cfd17SKevin Wolf s->drain_count++; 5357320ca9SKevin Wolf if (s->sleep_in_drain_begin) { 54*7bce1c29SKevin Wolf Coroutine *co = qemu_coroutine_create(sleep_in_drain_begin, bs); 55*7bce1c29SKevin Wolf bdrv_inc_in_flight(bs); 56*7bce1c29SKevin Wolf aio_co_enter(bdrv_get_aio_context(bs), co); 5757320ca9SKevin Wolf } 58881cfd17SKevin Wolf } 59881cfd17SKevin Wolf 60881cfd17SKevin Wolf static void coroutine_fn bdrv_test_co_drain_end(BlockDriverState *bs) 61881cfd17SKevin Wolf { 62881cfd17SKevin Wolf BDRVTestState *s = bs->opaque; 63881cfd17SKevin Wolf s->drain_count--; 64881cfd17SKevin Wolf } 65881cfd17SKevin Wolf 66881cfd17SKevin Wolf static void bdrv_test_close(BlockDriverState *bs) 67881cfd17SKevin Wolf { 68881cfd17SKevin Wolf BDRVTestState *s = bs->opaque; 69881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, >, 0); 70881cfd17SKevin Wolf } 71881cfd17SKevin Wolf 72bb675689SKevin Wolf static void co_reenter_bh(void *opaque) 73bb675689SKevin Wolf { 74bb675689SKevin Wolf aio_co_wake(opaque); 75bb675689SKevin Wolf } 76bb675689SKevin Wolf 77881cfd17SKevin Wolf static int coroutine_fn bdrv_test_co_preadv(BlockDriverState *bs, 78f7ef38ddSVladimir Sementsov-Ogievskiy int64_t offset, int64_t bytes, 79f7ef38ddSVladimir Sementsov-Ogievskiy QEMUIOVector *qiov, 80f7ef38ddSVladimir Sementsov-Ogievskiy BdrvRequestFlags flags) 81881cfd17SKevin Wolf { 82bb675689SKevin Wolf BDRVTestState *s = bs->opaque; 83bb675689SKevin Wolf 84881cfd17SKevin Wolf /* We want this request to stay until the polling loop in drain waits for 85881cfd17SKevin Wolf * it to complete. We need to sleep a while as bdrv_drain_invoke() comes 86881cfd17SKevin Wolf * first and polls its result, too, but it shouldn't accidentally complete 87881cfd17SKevin Wolf * this request yet. */ 88881cfd17SKevin Wolf qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000); 89881cfd17SKevin Wolf 90bb675689SKevin Wolf if (s->bh_indirection_ctx) { 91bb675689SKevin Wolf aio_bh_schedule_oneshot(s->bh_indirection_ctx, co_reenter_bh, 92bb675689SKevin Wolf qemu_coroutine_self()); 93bb675689SKevin Wolf qemu_coroutine_yield(); 94bb675689SKevin Wolf } 95bb675689SKevin Wolf 96881cfd17SKevin Wolf return 0; 97881cfd17SKevin Wolf } 98881cfd17SKevin Wolf 999746b35cSMax Reitz static int bdrv_test_change_backing_file(BlockDriverState *bs, 1009746b35cSMax Reitz const char *backing_file, 1019746b35cSMax Reitz const char *backing_fmt) 1029746b35cSMax Reitz { 1039746b35cSMax Reitz return 0; 1049746b35cSMax Reitz } 1059746b35cSMax Reitz 106881cfd17SKevin Wolf static BlockDriver bdrv_test = { 107881cfd17SKevin Wolf .format_name = "test", 108881cfd17SKevin Wolf .instance_size = sizeof(BDRVTestState), 10925f78d9eSVladimir Sementsov-Ogievskiy .supports_backing = true, 110881cfd17SKevin Wolf 111881cfd17SKevin Wolf .bdrv_close = bdrv_test_close, 112881cfd17SKevin Wolf .bdrv_co_preadv = bdrv_test_co_preadv, 113881cfd17SKevin Wolf 114881cfd17SKevin Wolf .bdrv_co_drain_begin = bdrv_test_co_drain_begin, 115881cfd17SKevin Wolf .bdrv_co_drain_end = bdrv_test_co_drain_end, 11686e1c840SKevin Wolf 117e5d8a406SMax Reitz .bdrv_child_perm = bdrv_default_perms, 1189746b35cSMax Reitz 1199746b35cSMax Reitz .bdrv_change_backing_file = bdrv_test_change_backing_file, 120881cfd17SKevin Wolf }; 121881cfd17SKevin Wolf 122881cfd17SKevin Wolf static void aio_ret_cb(void *opaque, int ret) 123881cfd17SKevin Wolf { 124881cfd17SKevin Wolf int *aio_ret = opaque; 125881cfd17SKevin Wolf *aio_ret = ret; 126881cfd17SKevin Wolf } 127881cfd17SKevin Wolf 1280582eb10SKevin Wolf typedef struct CallInCoroutineData { 1290582eb10SKevin Wolf void (*entry)(void); 1300582eb10SKevin Wolf bool done; 1310582eb10SKevin Wolf } CallInCoroutineData; 1320582eb10SKevin Wolf 1330582eb10SKevin Wolf static coroutine_fn void call_in_coroutine_entry(void *opaque) 1340582eb10SKevin Wolf { 1350582eb10SKevin Wolf CallInCoroutineData *data = opaque; 1360582eb10SKevin Wolf 1370582eb10SKevin Wolf data->entry(); 1380582eb10SKevin Wolf data->done = true; 1390582eb10SKevin Wolf } 1400582eb10SKevin Wolf 1410582eb10SKevin Wolf static void call_in_coroutine(void (*entry)(void)) 1420582eb10SKevin Wolf { 1430582eb10SKevin Wolf Coroutine *co; 1440582eb10SKevin Wolf CallInCoroutineData data = { 1450582eb10SKevin Wolf .entry = entry, 1460582eb10SKevin Wolf .done = false, 1470582eb10SKevin Wolf }; 1480582eb10SKevin Wolf 1490582eb10SKevin Wolf co = qemu_coroutine_create(call_in_coroutine_entry, &data); 1500582eb10SKevin Wolf qemu_coroutine_enter(co); 1510582eb10SKevin Wolf while (!data.done) { 1520582eb10SKevin Wolf aio_poll(qemu_get_aio_context(), true); 1530582eb10SKevin Wolf } 1540582eb10SKevin Wolf } 1550582eb10SKevin Wolf 15686e1c840SKevin Wolf enum drain_type { 15786e1c840SKevin Wolf BDRV_DRAIN_ALL, 15886e1c840SKevin Wolf BDRV_DRAIN, 159d2a85d0fSKevin Wolf BDRV_SUBTREE_DRAIN, 1606c429a6aSKevin Wolf DRAIN_TYPE_MAX, 16186e1c840SKevin Wolf }; 16286e1c840SKevin Wolf 16386e1c840SKevin Wolf static void do_drain_begin(enum drain_type drain_type, BlockDriverState *bs) 16486e1c840SKevin Wolf { 16586e1c840SKevin Wolf switch (drain_type) { 16686e1c840SKevin Wolf case BDRV_DRAIN_ALL: bdrv_drain_all_begin(); break; 16786e1c840SKevin Wolf case BDRV_DRAIN: bdrv_drained_begin(bs); break; 168d2a85d0fSKevin Wolf case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_begin(bs); break; 16986e1c840SKevin Wolf default: g_assert_not_reached(); 17086e1c840SKevin Wolf } 17186e1c840SKevin Wolf } 17286e1c840SKevin Wolf 17386e1c840SKevin Wolf static void do_drain_end(enum drain_type drain_type, BlockDriverState *bs) 17486e1c840SKevin Wolf { 17586e1c840SKevin Wolf switch (drain_type) { 17686e1c840SKevin Wolf case BDRV_DRAIN_ALL: bdrv_drain_all_end(); break; 17786e1c840SKevin Wolf case BDRV_DRAIN: bdrv_drained_end(bs); break; 178d2a85d0fSKevin Wolf case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_end(bs); break; 17986e1c840SKevin Wolf default: g_assert_not_reached(); 18086e1c840SKevin Wolf } 18186e1c840SKevin Wolf } 18286e1c840SKevin Wolf 183f62c1729SKevin Wolf static void do_drain_begin_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_begin(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 194f62c1729SKevin Wolf static void do_drain_end_unlocked(enum drain_type drain_type, BlockDriverState *bs) 195f62c1729SKevin Wolf { 196f62c1729SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 197f62c1729SKevin Wolf aio_context_acquire(bdrv_get_aio_context(bs)); 198f62c1729SKevin Wolf } 199f62c1729SKevin Wolf do_drain_end(drain_type, bs); 200f62c1729SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 201f62c1729SKevin Wolf aio_context_release(bdrv_get_aio_context(bs)); 202f62c1729SKevin Wolf } 203f62c1729SKevin Wolf } 204f62c1729SKevin Wolf 20586e1c840SKevin Wolf static void test_drv_cb_common(enum drain_type drain_type, bool recursive) 206881cfd17SKevin Wolf { 207881cfd17SKevin Wolf BlockBackend *blk; 20886e1c840SKevin Wolf BlockDriverState *bs, *backing; 20986e1c840SKevin Wolf BDRVTestState *s, *backing_s; 210881cfd17SKevin Wolf BlockAIOCB *acb; 211881cfd17SKevin Wolf int aio_ret; 212881cfd17SKevin Wolf 213405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0); 214881cfd17SKevin Wolf 215d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 216881cfd17SKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 217881cfd17SKevin Wolf &error_abort); 218881cfd17SKevin Wolf s = bs->opaque; 219881cfd17SKevin Wolf blk_insert_bs(blk, bs, &error_abort); 220881cfd17SKevin Wolf 22186e1c840SKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 22286e1c840SKevin Wolf backing_s = backing->opaque; 22386e1c840SKevin Wolf bdrv_set_backing_hd(bs, backing, &error_abort); 22486e1c840SKevin Wolf 225881cfd17SKevin Wolf /* Simple bdrv_drain_all_begin/end pair, check that CBs are called */ 226881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 22786e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 22886e1c840SKevin Wolf 22986e1c840SKevin Wolf do_drain_begin(drain_type, bs); 23086e1c840SKevin Wolf 231881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 1); 23286e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, !!recursive); 23386e1c840SKevin Wolf 23486e1c840SKevin Wolf do_drain_end(drain_type, bs); 23586e1c840SKevin Wolf 236881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 23786e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 238881cfd17SKevin Wolf 239881cfd17SKevin Wolf /* Now do the same while a request is pending */ 240881cfd17SKevin Wolf aio_ret = -EINPROGRESS; 241881cfd17SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret); 242881cfd17SKevin Wolf g_assert(acb != NULL); 243881cfd17SKevin Wolf g_assert_cmpint(aio_ret, ==, -EINPROGRESS); 244881cfd17SKevin Wolf 245881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 24686e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 24786e1c840SKevin Wolf 24886e1c840SKevin Wolf do_drain_begin(drain_type, bs); 24986e1c840SKevin Wolf 250881cfd17SKevin Wolf g_assert_cmpint(aio_ret, ==, 0); 251881cfd17SKevin Wolf g_assert_cmpint(s->drain_count, ==, 1); 25286e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, !!recursive); 253881cfd17SKevin Wolf 25486e1c840SKevin Wolf do_drain_end(drain_type, bs); 25586e1c840SKevin Wolf 25686e1c840SKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 25786e1c840SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 25886e1c840SKevin Wolf 25986e1c840SKevin Wolf bdrv_unref(backing); 260881cfd17SKevin Wolf bdrv_unref(bs); 261881cfd17SKevin Wolf blk_unref(blk); 262881cfd17SKevin Wolf } 263881cfd17SKevin Wolf 26486e1c840SKevin Wolf static void test_drv_cb_drain_all(void) 26586e1c840SKevin Wolf { 26686e1c840SKevin Wolf test_drv_cb_common(BDRV_DRAIN_ALL, true); 26786e1c840SKevin Wolf } 26886e1c840SKevin Wolf 26986e1c840SKevin Wolf static void test_drv_cb_drain(void) 27086e1c840SKevin Wolf { 27186e1c840SKevin Wolf test_drv_cb_common(BDRV_DRAIN, false); 27286e1c840SKevin Wolf } 27386e1c840SKevin Wolf 274d2a85d0fSKevin Wolf static void test_drv_cb_drain_subtree(void) 275d2a85d0fSKevin Wolf { 276d2a85d0fSKevin Wolf test_drv_cb_common(BDRV_SUBTREE_DRAIN, true); 277d2a85d0fSKevin Wolf } 278d2a85d0fSKevin Wolf 2796d0252f2SKevin Wolf static void test_drv_cb_co_drain_all(void) 2806d0252f2SKevin Wolf { 2816d0252f2SKevin Wolf call_in_coroutine(test_drv_cb_drain_all); 2826d0252f2SKevin Wolf } 2836d0252f2SKevin Wolf 2840582eb10SKevin Wolf static void test_drv_cb_co_drain(void) 2850582eb10SKevin Wolf { 2860582eb10SKevin Wolf call_in_coroutine(test_drv_cb_drain); 2870582eb10SKevin Wolf } 2880582eb10SKevin Wolf 2890582eb10SKevin Wolf static void test_drv_cb_co_drain_subtree(void) 2900582eb10SKevin Wolf { 2910582eb10SKevin Wolf call_in_coroutine(test_drv_cb_drain_subtree); 2920582eb10SKevin Wolf } 2930582eb10SKevin Wolf 29489a6ceabSKevin Wolf static void test_quiesce_common(enum drain_type drain_type, bool recursive) 29589a6ceabSKevin Wolf { 29689a6ceabSKevin Wolf BlockBackend *blk; 29789a6ceabSKevin Wolf BlockDriverState *bs, *backing; 29889a6ceabSKevin Wolf 299d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 30089a6ceabSKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 30189a6ceabSKevin Wolf &error_abort); 30289a6ceabSKevin Wolf blk_insert_bs(blk, bs, &error_abort); 30389a6ceabSKevin Wolf 30489a6ceabSKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 30589a6ceabSKevin Wolf bdrv_set_backing_hd(bs, backing, &error_abort); 30689a6ceabSKevin Wolf 30789a6ceabSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 30889a6ceabSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 30989a6ceabSKevin Wolf 31089a6ceabSKevin Wolf do_drain_begin(drain_type, bs); 31189a6ceabSKevin Wolf 31289a6ceabSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 1); 31389a6ceabSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, !!recursive); 31489a6ceabSKevin Wolf 31589a6ceabSKevin Wolf do_drain_end(drain_type, bs); 31689a6ceabSKevin Wolf 31789a6ceabSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 31889a6ceabSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 31989a6ceabSKevin Wolf 32089a6ceabSKevin Wolf bdrv_unref(backing); 32189a6ceabSKevin Wolf bdrv_unref(bs); 32289a6ceabSKevin Wolf blk_unref(blk); 32389a6ceabSKevin Wolf } 32489a6ceabSKevin Wolf 32589a6ceabSKevin Wolf static void test_quiesce_drain_all(void) 32689a6ceabSKevin Wolf { 32779ab8b21SKevin Wolf test_quiesce_common(BDRV_DRAIN_ALL, true); 32889a6ceabSKevin Wolf } 32989a6ceabSKevin Wolf 33089a6ceabSKevin Wolf static void test_quiesce_drain(void) 33189a6ceabSKevin Wolf { 33289a6ceabSKevin Wolf test_quiesce_common(BDRV_DRAIN, false); 33389a6ceabSKevin Wolf } 33489a6ceabSKevin Wolf 335d2a85d0fSKevin Wolf static void test_quiesce_drain_subtree(void) 336d2a85d0fSKevin Wolf { 337d2a85d0fSKevin Wolf test_quiesce_common(BDRV_SUBTREE_DRAIN, true); 338d2a85d0fSKevin Wolf } 339d2a85d0fSKevin Wolf 3406d0252f2SKevin Wolf static void test_quiesce_co_drain_all(void) 3416d0252f2SKevin Wolf { 3426d0252f2SKevin Wolf call_in_coroutine(test_quiesce_drain_all); 3436d0252f2SKevin Wolf } 3446d0252f2SKevin Wolf 3450582eb10SKevin Wolf static void test_quiesce_co_drain(void) 3460582eb10SKevin Wolf { 3470582eb10SKevin Wolf call_in_coroutine(test_quiesce_drain); 3480582eb10SKevin Wolf } 3490582eb10SKevin Wolf 3500582eb10SKevin Wolf static void test_quiesce_co_drain_subtree(void) 3510582eb10SKevin Wolf { 3520582eb10SKevin Wolf call_in_coroutine(test_quiesce_drain_subtree); 3530582eb10SKevin Wolf } 3540582eb10SKevin Wolf 3556c429a6aSKevin Wolf static void test_nested(void) 3566c429a6aSKevin Wolf { 3576c429a6aSKevin Wolf BlockBackend *blk; 3586c429a6aSKevin Wolf BlockDriverState *bs, *backing; 3596c429a6aSKevin Wolf BDRVTestState *s, *backing_s; 3606c429a6aSKevin Wolf enum drain_type outer, inner; 3616c429a6aSKevin Wolf 362d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 3636c429a6aSKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 3646c429a6aSKevin Wolf &error_abort); 3656c429a6aSKevin Wolf s = bs->opaque; 3666c429a6aSKevin Wolf blk_insert_bs(blk, bs, &error_abort); 3676c429a6aSKevin Wolf 3686c429a6aSKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 3696c429a6aSKevin Wolf backing_s = backing->opaque; 3706c429a6aSKevin Wolf bdrv_set_backing_hd(bs, backing, &error_abort); 3716c429a6aSKevin Wolf 3726c429a6aSKevin Wolf for (outer = 0; outer < DRAIN_TYPE_MAX; outer++) { 3736c429a6aSKevin Wolf for (inner = 0; inner < DRAIN_TYPE_MAX; inner++) { 37479ab8b21SKevin Wolf int backing_quiesce = (outer != BDRV_DRAIN) + 3756c429a6aSKevin Wolf (inner != BDRV_DRAIN); 3766c429a6aSKevin Wolf 3776c429a6aSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 3786c429a6aSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 3796c429a6aSKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 3806c429a6aSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 3816c429a6aSKevin Wolf 3826c429a6aSKevin Wolf do_drain_begin(outer, bs); 3836c429a6aSKevin Wolf do_drain_begin(inner, bs); 3846c429a6aSKevin Wolf 38579ab8b21SKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 2); 3866c429a6aSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, backing_quiesce); 3876c429a6aSKevin Wolf g_assert_cmpint(s->drain_count, ==, 2); 38879ab8b21SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, backing_quiesce); 3896c429a6aSKevin Wolf 3906c429a6aSKevin Wolf do_drain_end(inner, bs); 3916c429a6aSKevin Wolf do_drain_end(outer, bs); 3926c429a6aSKevin Wolf 3936c429a6aSKevin Wolf g_assert_cmpint(bs->quiesce_counter, ==, 0); 3946c429a6aSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 3956c429a6aSKevin Wolf g_assert_cmpint(s->drain_count, ==, 0); 3966c429a6aSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 3976c429a6aSKevin Wolf } 3986c429a6aSKevin Wolf } 3996c429a6aSKevin Wolf 4006c429a6aSKevin Wolf bdrv_unref(backing); 4016c429a6aSKevin Wolf bdrv_unref(bs); 4026c429a6aSKevin Wolf blk_unref(blk); 4036c429a6aSKevin Wolf } 4046c429a6aSKevin Wolf 40527e64474SKevin Wolf static void test_multiparent(void) 40627e64474SKevin Wolf { 40727e64474SKevin Wolf BlockBackend *blk_a, *blk_b; 40827e64474SKevin Wolf BlockDriverState *bs_a, *bs_b, *backing; 40927e64474SKevin Wolf BDRVTestState *a_s, *b_s, *backing_s; 41027e64474SKevin Wolf 411d861ab3aSKevin Wolf blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 41227e64474SKevin Wolf bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, 41327e64474SKevin Wolf &error_abort); 41427e64474SKevin Wolf a_s = bs_a->opaque; 41527e64474SKevin Wolf blk_insert_bs(blk_a, bs_a, &error_abort); 41627e64474SKevin Wolf 417d861ab3aSKevin Wolf blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 41827e64474SKevin Wolf bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, 41927e64474SKevin Wolf &error_abort); 42027e64474SKevin Wolf b_s = bs_b->opaque; 42127e64474SKevin Wolf blk_insert_bs(blk_b, bs_b, &error_abort); 42227e64474SKevin Wolf 42327e64474SKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 42427e64474SKevin Wolf backing_s = backing->opaque; 42527e64474SKevin Wolf bdrv_set_backing_hd(bs_a, backing, &error_abort); 42627e64474SKevin Wolf bdrv_set_backing_hd(bs_b, backing, &error_abort); 42727e64474SKevin Wolf 42827e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 42927e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 43027e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 43127e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 43227e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 43327e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 43427e64474SKevin Wolf 43527e64474SKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); 43627e64474SKevin Wolf 43727e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 43827e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 43927e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 1); 44027e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 44127e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 44227e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 1); 44327e64474SKevin Wolf 44427e64474SKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); 44527e64474SKevin Wolf 44627e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 2); 44727e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 2); 44827e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 2); 44927e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 2); 45027e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 2); 45127e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 2); 45227e64474SKevin Wolf 45327e64474SKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); 45427e64474SKevin Wolf 45527e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 45627e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 45727e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 1); 45827e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 45927e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 46027e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 1); 46127e64474SKevin Wolf 46227e64474SKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 46327e64474SKevin Wolf 46427e64474SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 46527e64474SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 46627e64474SKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 46727e64474SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 46827e64474SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 46927e64474SKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 47027e64474SKevin Wolf 47127e64474SKevin Wolf bdrv_unref(backing); 47227e64474SKevin Wolf bdrv_unref(bs_a); 47327e64474SKevin Wolf bdrv_unref(bs_b); 47427e64474SKevin Wolf blk_unref(blk_a); 47527e64474SKevin Wolf blk_unref(blk_b); 47627e64474SKevin Wolf } 47727e64474SKevin Wolf 47819f7a7e5SKevin Wolf static void test_graph_change_drain_subtree(void) 479acebcf8dSKevin Wolf { 480acebcf8dSKevin Wolf BlockBackend *blk_a, *blk_b; 481acebcf8dSKevin Wolf BlockDriverState *bs_a, *bs_b, *backing; 482acebcf8dSKevin Wolf BDRVTestState *a_s, *b_s, *backing_s; 483acebcf8dSKevin Wolf 484d861ab3aSKevin Wolf blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 485acebcf8dSKevin Wolf bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, 486acebcf8dSKevin Wolf &error_abort); 487acebcf8dSKevin Wolf a_s = bs_a->opaque; 488acebcf8dSKevin Wolf blk_insert_bs(blk_a, bs_a, &error_abort); 489acebcf8dSKevin Wolf 490d861ab3aSKevin Wolf blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 491acebcf8dSKevin Wolf bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, 492acebcf8dSKevin Wolf &error_abort); 493acebcf8dSKevin Wolf b_s = bs_b->opaque; 494acebcf8dSKevin Wolf blk_insert_bs(blk_b, bs_b, &error_abort); 495acebcf8dSKevin Wolf 496acebcf8dSKevin Wolf backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort); 497acebcf8dSKevin Wolf backing_s = backing->opaque; 498acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_a, backing, &error_abort); 499acebcf8dSKevin Wolf 500acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 501acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 502acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 503acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 504acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 505acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 506acebcf8dSKevin Wolf 507acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); 508acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); 509acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); 510acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); 511acebcf8dSKevin Wolf do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); 512acebcf8dSKevin Wolf 513acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_b, backing, &error_abort); 514acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 5); 515acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 5); 516acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 5); 517acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 5); 518acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 5); 519acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 5); 520acebcf8dSKevin Wolf 521acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_b, NULL, &error_abort); 522acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 3); 523acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 2); 524acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 3); 525acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 3); 526acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 2); 527acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 3); 528acebcf8dSKevin Wolf 529acebcf8dSKevin Wolf bdrv_set_backing_hd(bs_b, backing, &error_abort); 530acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 5); 531acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 5); 532acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 5); 533acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 5); 534acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 5); 535acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 5); 536acebcf8dSKevin Wolf 537acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); 538acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); 539acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 540acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 541acebcf8dSKevin Wolf do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); 542acebcf8dSKevin Wolf 543acebcf8dSKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 544acebcf8dSKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 545acebcf8dSKevin Wolf g_assert_cmpint(backing->quiesce_counter, ==, 0); 546acebcf8dSKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 547acebcf8dSKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 548acebcf8dSKevin Wolf g_assert_cmpint(backing_s->drain_count, ==, 0); 549acebcf8dSKevin Wolf 550acebcf8dSKevin Wolf bdrv_unref(backing); 551acebcf8dSKevin Wolf bdrv_unref(bs_a); 552acebcf8dSKevin Wolf bdrv_unref(bs_b); 553acebcf8dSKevin Wolf blk_unref(blk_a); 554acebcf8dSKevin Wolf blk_unref(blk_b); 555acebcf8dSKevin Wolf } 556acebcf8dSKevin Wolf 55719f7a7e5SKevin Wolf static void test_graph_change_drain_all(void) 55819f7a7e5SKevin Wolf { 55919f7a7e5SKevin Wolf BlockBackend *blk_a, *blk_b; 56019f7a7e5SKevin Wolf BlockDriverState *bs_a, *bs_b; 56119f7a7e5SKevin Wolf BDRVTestState *a_s, *b_s; 56219f7a7e5SKevin Wolf 56319f7a7e5SKevin Wolf /* Create node A with a BlockBackend */ 564d861ab3aSKevin Wolf blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 56519f7a7e5SKevin Wolf bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, 56619f7a7e5SKevin Wolf &error_abort); 56719f7a7e5SKevin Wolf a_s = bs_a->opaque; 56819f7a7e5SKevin Wolf blk_insert_bs(blk_a, bs_a, &error_abort); 56919f7a7e5SKevin Wolf 57019f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 0); 57119f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 0); 57219f7a7e5SKevin Wolf 57319f7a7e5SKevin Wolf /* Call bdrv_drain_all_begin() */ 57419f7a7e5SKevin Wolf bdrv_drain_all_begin(); 57519f7a7e5SKevin Wolf 57619f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 57719f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 57819f7a7e5SKevin Wolf 57919f7a7e5SKevin Wolf /* Create node B with a BlockBackend */ 580d861ab3aSKevin Wolf blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 58119f7a7e5SKevin Wolf bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, 58219f7a7e5SKevin Wolf &error_abort); 58319f7a7e5SKevin Wolf b_s = bs_b->opaque; 58419f7a7e5SKevin Wolf blk_insert_bs(blk_b, bs_b, &error_abort); 58519f7a7e5SKevin Wolf 58619f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 58719f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 58819f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 58919f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 59019f7a7e5SKevin Wolf 59119f7a7e5SKevin Wolf /* Unref and finally delete node A */ 59219f7a7e5SKevin Wolf blk_unref(blk_a); 59319f7a7e5SKevin Wolf 59419f7a7e5SKevin Wolf g_assert_cmpint(bs_a->quiesce_counter, ==, 1); 59519f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 59619f7a7e5SKevin Wolf g_assert_cmpint(a_s->drain_count, ==, 1); 59719f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 59819f7a7e5SKevin Wolf 59919f7a7e5SKevin Wolf bdrv_unref(bs_a); 60019f7a7e5SKevin Wolf 60119f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 1); 60219f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 1); 60319f7a7e5SKevin Wolf 60419f7a7e5SKevin Wolf /* End the drained section */ 60519f7a7e5SKevin Wolf bdrv_drain_all_end(); 60619f7a7e5SKevin Wolf 60719f7a7e5SKevin Wolf g_assert_cmpint(bs_b->quiesce_counter, ==, 0); 60819f7a7e5SKevin Wolf g_assert_cmpint(b_s->drain_count, ==, 0); 6091a6d3bd2SGreg Kurz g_assert_cmpint(qemu_get_aio_context()->external_disable_cnt, ==, 0); 61019f7a7e5SKevin Wolf 61119f7a7e5SKevin Wolf bdrv_unref(bs_b); 61219f7a7e5SKevin Wolf blk_unref(blk_b); 61319f7a7e5SKevin Wolf } 61419f7a7e5SKevin Wolf 615bb675689SKevin Wolf struct test_iothread_data { 616bb675689SKevin Wolf BlockDriverState *bs; 617bb675689SKevin Wolf enum drain_type drain_type; 618bb675689SKevin Wolf int *aio_ret; 619bb675689SKevin Wolf }; 620bb675689SKevin Wolf 621bb675689SKevin Wolf static void test_iothread_drain_entry(void *opaque) 622bb675689SKevin Wolf { 623bb675689SKevin Wolf struct test_iothread_data *data = opaque; 624bb675689SKevin Wolf 625bb675689SKevin Wolf aio_context_acquire(bdrv_get_aio_context(data->bs)); 626bb675689SKevin Wolf do_drain_begin(data->drain_type, data->bs); 627bb675689SKevin Wolf g_assert_cmpint(*data->aio_ret, ==, 0); 628bb675689SKevin Wolf do_drain_end(data->drain_type, data->bs); 629bb675689SKevin Wolf aio_context_release(bdrv_get_aio_context(data->bs)); 630bb675689SKevin Wolf 631bb675689SKevin Wolf qemu_event_set(&done_event); 632bb675689SKevin Wolf } 633bb675689SKevin Wolf 634bb675689SKevin Wolf static void test_iothread_aio_cb(void *opaque, int ret) 635bb675689SKevin Wolf { 636bb675689SKevin Wolf int *aio_ret = opaque; 637bb675689SKevin Wolf *aio_ret = ret; 638bb675689SKevin Wolf qemu_event_set(&done_event); 639bb675689SKevin Wolf } 640bb675689SKevin Wolf 641ecc1a5c7SKevin Wolf static void test_iothread_main_thread_bh(void *opaque) 642ecc1a5c7SKevin Wolf { 643ecc1a5c7SKevin Wolf struct test_iothread_data *data = opaque; 644ecc1a5c7SKevin Wolf 645ecc1a5c7SKevin Wolf /* Test that the AioContext is not yet locked in a random BH that is 646ecc1a5c7SKevin Wolf * executed during drain, otherwise this would deadlock. */ 647ecc1a5c7SKevin Wolf aio_context_acquire(bdrv_get_aio_context(data->bs)); 648ecc1a5c7SKevin Wolf bdrv_flush(data->bs); 649ecc1a5c7SKevin Wolf aio_context_release(bdrv_get_aio_context(data->bs)); 650ecc1a5c7SKevin Wolf } 651ecc1a5c7SKevin Wolf 652bb675689SKevin Wolf /* 653bb675689SKevin Wolf * Starts an AIO request on a BDS that runs in the AioContext of iothread 1. 654bb675689SKevin Wolf * The request involves a BH on iothread 2 before it can complete. 655bb675689SKevin Wolf * 656bb675689SKevin Wolf * @drain_thread = 0 means that do_drain_begin/end are called from the main 657bb675689SKevin Wolf * thread, @drain_thread = 1 means that they are called from iothread 1. Drain 658bb675689SKevin Wolf * for this BDS cannot be called from iothread 2 because only the main thread 659bb675689SKevin Wolf * may do cross-AioContext polling. 660bb675689SKevin Wolf */ 661bb675689SKevin Wolf static void test_iothread_common(enum drain_type drain_type, int drain_thread) 662bb675689SKevin Wolf { 663bb675689SKevin Wolf BlockBackend *blk; 664bb675689SKevin Wolf BlockDriverState *bs; 665bb675689SKevin Wolf BDRVTestState *s; 666bb675689SKevin Wolf BlockAIOCB *acb; 667bb675689SKevin Wolf int aio_ret; 668bb675689SKevin Wolf struct test_iothread_data data; 669bb675689SKevin Wolf 670bb675689SKevin Wolf IOThread *a = iothread_new(); 671bb675689SKevin Wolf IOThread *b = iothread_new(); 672bb675689SKevin Wolf AioContext *ctx_a = iothread_get_aio_context(a); 673bb675689SKevin Wolf AioContext *ctx_b = iothread_get_aio_context(b); 674bb675689SKevin Wolf 675405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0); 676bb675689SKevin Wolf 677bb675689SKevin Wolf /* bdrv_drain_all() may only be called from the main loop thread */ 678bb675689SKevin Wolf if (drain_type == BDRV_DRAIN_ALL && drain_thread != 0) { 679bb675689SKevin Wolf goto out; 680bb675689SKevin Wolf } 681bb675689SKevin Wolf 682d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 683bb675689SKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 684bb675689SKevin Wolf &error_abort); 685bb675689SKevin Wolf s = bs->opaque; 686bb675689SKevin Wolf blk_insert_bs(blk, bs, &error_abort); 687cf312932SKevin Wolf blk_set_disable_request_queuing(blk, true); 688bb675689SKevin Wolf 68997896a48SKevin Wolf blk_set_aio_context(blk, ctx_a, &error_abort); 690bb675689SKevin Wolf aio_context_acquire(ctx_a); 691bb675689SKevin Wolf 692bb675689SKevin Wolf s->bh_indirection_ctx = ctx_b; 693bb675689SKevin Wolf 694bb675689SKevin Wolf aio_ret = -EINPROGRESS; 695dd353157SKevin Wolf qemu_event_reset(&done_event); 696dd353157SKevin Wolf 697bb675689SKevin Wolf if (drain_thread == 0) { 698bb675689SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, test_iothread_aio_cb, &aio_ret); 699bb675689SKevin Wolf } else { 700bb675689SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret); 701bb675689SKevin Wolf } 702bb675689SKevin Wolf g_assert(acb != NULL); 703bb675689SKevin Wolf g_assert_cmpint(aio_ret, ==, -EINPROGRESS); 704bb675689SKevin Wolf 705bb675689SKevin Wolf aio_context_release(ctx_a); 706bb675689SKevin Wolf 707bb675689SKevin Wolf data = (struct test_iothread_data) { 708bb675689SKevin Wolf .bs = bs, 709bb675689SKevin Wolf .drain_type = drain_type, 710bb675689SKevin Wolf .aio_ret = &aio_ret, 711bb675689SKevin Wolf }; 712bb675689SKevin Wolf 713bb675689SKevin Wolf switch (drain_thread) { 714bb675689SKevin Wolf case 0: 715bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 716bb675689SKevin Wolf aio_context_acquire(ctx_a); 717bb675689SKevin Wolf } 718bb675689SKevin Wolf 719ecc1a5c7SKevin Wolf aio_bh_schedule_oneshot(ctx_a, test_iothread_main_thread_bh, &data); 720ecc1a5c7SKevin Wolf 721bb675689SKevin Wolf /* The request is running on the IOThread a. Draining its block device 722bb675689SKevin Wolf * will make sure that it has completed as far as the BDS is concerned, 723bb675689SKevin Wolf * but the drain in this thread can continue immediately after 724bb675689SKevin Wolf * bdrv_dec_in_flight() and aio_ret might be assigned only slightly 725bb675689SKevin Wolf * later. */ 726bb675689SKevin Wolf do_drain_begin(drain_type, bs); 727bb675689SKevin Wolf g_assert_cmpint(bs->in_flight, ==, 0); 728bb675689SKevin Wolf 729bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 730bb675689SKevin Wolf aio_context_release(ctx_a); 731bb675689SKevin Wolf } 732bb675689SKevin Wolf qemu_event_wait(&done_event); 733bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 734bb675689SKevin Wolf aio_context_acquire(ctx_a); 735bb675689SKevin Wolf } 736bb675689SKevin Wolf 737bb675689SKevin Wolf g_assert_cmpint(aio_ret, ==, 0); 738bb675689SKevin Wolf do_drain_end(drain_type, bs); 739bb675689SKevin Wolf 740bb675689SKevin Wolf if (drain_type != BDRV_DRAIN_ALL) { 741bb675689SKevin Wolf aio_context_release(ctx_a); 742bb675689SKevin Wolf } 743bb675689SKevin Wolf break; 744bb675689SKevin Wolf case 1: 745bb675689SKevin Wolf aio_bh_schedule_oneshot(ctx_a, test_iothread_drain_entry, &data); 746bb675689SKevin Wolf qemu_event_wait(&done_event); 747bb675689SKevin Wolf break; 748bb675689SKevin Wolf default: 749bb675689SKevin Wolf g_assert_not_reached(); 750bb675689SKevin Wolf } 751bb675689SKevin Wolf 752bb675689SKevin Wolf aio_context_acquire(ctx_a); 75397896a48SKevin Wolf blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort); 754bb675689SKevin Wolf aio_context_release(ctx_a); 755bb675689SKevin Wolf 756bb675689SKevin Wolf bdrv_unref(bs); 757bb675689SKevin Wolf blk_unref(blk); 758bb675689SKevin Wolf 759bb675689SKevin Wolf out: 760bb675689SKevin Wolf iothread_join(a); 761bb675689SKevin Wolf iothread_join(b); 762bb675689SKevin Wolf } 763bb675689SKevin Wolf 764bb675689SKevin Wolf static void test_iothread_drain_all(void) 765bb675689SKevin Wolf { 766bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN_ALL, 0); 767bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN_ALL, 1); 768bb675689SKevin Wolf } 769bb675689SKevin Wolf 770bb675689SKevin Wolf static void test_iothread_drain(void) 771bb675689SKevin Wolf { 772bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN, 0); 773bb675689SKevin Wolf test_iothread_common(BDRV_DRAIN, 1); 774bb675689SKevin Wolf } 775bb675689SKevin Wolf 776bb675689SKevin Wolf static void test_iothread_drain_subtree(void) 777bb675689SKevin Wolf { 778bb675689SKevin Wolf test_iothread_common(BDRV_SUBTREE_DRAIN, 0); 779bb675689SKevin Wolf test_iothread_common(BDRV_SUBTREE_DRAIN, 1); 780bb675689SKevin Wolf } 781bb675689SKevin Wolf 7827253220dSKevin Wolf 7837253220dSKevin Wolf typedef struct TestBlockJob { 7847253220dSKevin Wolf BlockJob common; 7851b177bbeSVladimir Sementsov-Ogievskiy BlockDriverState *bs; 786d49725afSKevin Wolf int run_ret; 787d49725afSKevin Wolf int prepare_ret; 788d8b3afd5SKevin Wolf bool running; 7897253220dSKevin Wolf bool should_complete; 7907253220dSKevin Wolf } TestBlockJob; 7917253220dSKevin Wolf 792ae23dde9SKevin Wolf static int test_job_prepare(Job *job) 793ae23dde9SKevin Wolf { 794ae23dde9SKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 795ae23dde9SKevin Wolf 796ae23dde9SKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 7971b177bbeSVladimir Sementsov-Ogievskiy bdrv_flush(s->bs); 798d49725afSKevin Wolf return s->prepare_ret; 799d49725afSKevin Wolf } 800d49725afSKevin Wolf 801d49725afSKevin Wolf static void test_job_commit(Job *job) 802d49725afSKevin Wolf { 803d49725afSKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 804d49725afSKevin Wolf 805d49725afSKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 8061b177bbeSVladimir Sementsov-Ogievskiy bdrv_flush(s->bs); 807d49725afSKevin Wolf } 808d49725afSKevin Wolf 809d49725afSKevin Wolf static void test_job_abort(Job *job) 810d49725afSKevin Wolf { 811d49725afSKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 812d49725afSKevin Wolf 813d49725afSKevin Wolf /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ 8141b177bbeSVladimir Sementsov-Ogievskiy bdrv_flush(s->bs); 815ae23dde9SKevin Wolf } 816ae23dde9SKevin Wolf 817f67432a2SJohn Snow static int coroutine_fn test_job_run(Job *job, Error **errp) 8187253220dSKevin Wolf { 819f67432a2SJohn Snow TestBlockJob *s = container_of(job, TestBlockJob, common.job); 8207253220dSKevin Wolf 821d8b3afd5SKevin Wolf /* We are running the actual job code past the pause point in 822d8b3afd5SKevin Wolf * job_co_entry(). */ 823d8b3afd5SKevin Wolf s->running = true; 824d8b3afd5SKevin Wolf 8252e1795b5SKevin Wolf job_transition_to_ready(&s->common.job); 8267253220dSKevin Wolf while (!s->should_complete) { 8275599c162SKevin Wolf /* Avoid job_sleep_ns() because it marks the job as !busy. We want to 8285599c162SKevin Wolf * emulate some actual activity (probably some I/O) here so that drain 8295599c162SKevin Wolf * has to wait for this activity to stop. */ 830d8b3afd5SKevin Wolf qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000); 831d8b3afd5SKevin Wolf 83289bd0305SKevin Wolf job_pause_point(&s->common.job); 8337253220dSKevin Wolf } 8347253220dSKevin Wolf 835d49725afSKevin Wolf return s->run_ret; 8367253220dSKevin Wolf } 8377253220dSKevin Wolf 8383453d972SKevin Wolf static void test_job_complete(Job *job, Error **errp) 8397253220dSKevin Wolf { 8403453d972SKevin Wolf TestBlockJob *s = container_of(job, TestBlockJob, common.job); 8417253220dSKevin Wolf s->should_complete = true; 8427253220dSKevin Wolf } 8437253220dSKevin Wolf 8447253220dSKevin Wolf BlockJobDriver test_job_driver = { 84533e9e9bdSKevin Wolf .job_driver = { 8467253220dSKevin Wolf .instance_size = sizeof(TestBlockJob), 84780fa2c75SKevin Wolf .free = block_job_free, 848b15de828SKevin Wolf .user_resume = block_job_user_resume, 849f67432a2SJohn Snow .run = test_job_run, 8507253220dSKevin Wolf .complete = test_job_complete, 851ae23dde9SKevin Wolf .prepare = test_job_prepare, 852d49725afSKevin Wolf .commit = test_job_commit, 853d49725afSKevin Wolf .abort = test_job_abort, 8543453d972SKevin Wolf }, 8557253220dSKevin Wolf }; 8567253220dSKevin Wolf 857d49725afSKevin Wolf enum test_job_result { 858d49725afSKevin Wolf TEST_JOB_SUCCESS, 859d49725afSKevin Wolf TEST_JOB_FAIL_RUN, 860d49725afSKevin Wolf TEST_JOB_FAIL_PREPARE, 861d49725afSKevin Wolf }; 862d49725afSKevin Wolf 863d8b3afd5SKevin Wolf enum test_job_drain_node { 864d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC, 865d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_CHILD, 866d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_PARENT, 867d8b3afd5SKevin Wolf }; 868d8b3afd5SKevin Wolf 869d8b3afd5SKevin Wolf static void test_blockjob_common_drain_node(enum drain_type drain_type, 870d8b3afd5SKevin Wolf bool use_iothread, 871d8b3afd5SKevin Wolf enum test_job_result result, 872d8b3afd5SKevin Wolf enum test_job_drain_node drain_node) 8737253220dSKevin Wolf { 8747253220dSKevin Wolf BlockBackend *blk_src, *blk_target; 875d8b3afd5SKevin Wolf BlockDriverState *src, *src_backing, *src_overlay, *target, *drain_bs; 8767253220dSKevin Wolf BlockJob *job; 877d49725afSKevin Wolf TestBlockJob *tjob; 878f62c1729SKevin Wolf IOThread *iothread = NULL; 879f62c1729SKevin Wolf AioContext *ctx; 8807253220dSKevin Wolf int ret; 8817253220dSKevin Wolf 8827253220dSKevin Wolf src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR, 8837253220dSKevin Wolf &error_abort); 884d8b3afd5SKevin Wolf src_backing = bdrv_new_open_driver(&bdrv_test, "source-backing", 885d8b3afd5SKevin Wolf BDRV_O_RDWR, &error_abort); 886d8b3afd5SKevin Wolf src_overlay = bdrv_new_open_driver(&bdrv_test, "source-overlay", 887d8b3afd5SKevin Wolf BDRV_O_RDWR, &error_abort); 888d8b3afd5SKevin Wolf 889d8b3afd5SKevin Wolf bdrv_set_backing_hd(src_overlay, src, &error_abort); 890d8b3afd5SKevin Wolf bdrv_unref(src); 891d8b3afd5SKevin Wolf bdrv_set_backing_hd(src, src_backing, &error_abort); 892d8b3afd5SKevin Wolf bdrv_unref(src_backing); 893d8b3afd5SKevin Wolf 894d861ab3aSKevin Wolf blk_src = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 895d8b3afd5SKevin Wolf blk_insert_bs(blk_src, src_overlay, &error_abort); 896d8b3afd5SKevin Wolf 897d8b3afd5SKevin Wolf switch (drain_node) { 898d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC: 899d8b3afd5SKevin Wolf drain_bs = src; 900d8b3afd5SKevin Wolf break; 901d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC_CHILD: 902d8b3afd5SKevin Wolf drain_bs = src_backing; 903d8b3afd5SKevin Wolf break; 904d8b3afd5SKevin Wolf case TEST_JOB_DRAIN_SRC_PARENT: 905d8b3afd5SKevin Wolf drain_bs = src_overlay; 906d8b3afd5SKevin Wolf break; 907d8b3afd5SKevin Wolf default: 908d8b3afd5SKevin Wolf g_assert_not_reached(); 909d8b3afd5SKevin Wolf } 9107253220dSKevin Wolf 911f62c1729SKevin Wolf if (use_iothread) { 912f62c1729SKevin Wolf iothread = iothread_new(); 913f62c1729SKevin Wolf ctx = iothread_get_aio_context(iothread); 91497896a48SKevin Wolf blk_set_aio_context(blk_src, ctx, &error_abort); 915f62c1729SKevin Wolf } else { 916f62c1729SKevin Wolf ctx = qemu_get_aio_context(); 917f62c1729SKevin Wolf } 918f62c1729SKevin Wolf 9197253220dSKevin Wolf target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR, 9207253220dSKevin Wolf &error_abort); 921d861ab3aSKevin Wolf blk_target = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 9227253220dSKevin Wolf blk_insert_bs(blk_target, target, &error_abort); 923132ada80SKevin Wolf blk_set_allow_aio_context_change(blk_target, true); 9247253220dSKevin Wolf 925f62c1729SKevin Wolf aio_context_acquire(ctx); 926d49725afSKevin Wolf tjob = block_job_create("job0", &test_job_driver, NULL, src, 927d49725afSKevin Wolf 0, BLK_PERM_ALL, 92875859b94SJohn Snow 0, 0, NULL, NULL, &error_abort); 9291b177bbeSVladimir Sementsov-Ogievskiy tjob->bs = src; 930d49725afSKevin Wolf job = &tjob->common; 9317253220dSKevin Wolf block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort); 932d49725afSKevin Wolf 933d49725afSKevin Wolf switch (result) { 934d49725afSKevin Wolf case TEST_JOB_SUCCESS: 935d49725afSKevin Wolf break; 936d49725afSKevin Wolf case TEST_JOB_FAIL_RUN: 937d49725afSKevin Wolf tjob->run_ret = -EIO; 938d49725afSKevin Wolf break; 939d49725afSKevin Wolf case TEST_JOB_FAIL_PREPARE: 940d49725afSKevin Wolf tjob->prepare_ret = -EIO; 941d49725afSKevin Wolf break; 942d49725afSKevin Wolf } 9436f592e5aSEmanuele Giuseppe Esposito aio_context_release(ctx); 944d49725afSKevin Wolf 945da01ff7fSKevin Wolf job_start(&job->job); 9467253220dSKevin Wolf 947d8b3afd5SKevin Wolf if (use_iothread) { 948d8b3afd5SKevin Wolf /* job_co_entry() is run in the I/O thread, wait for the actual job 949d8b3afd5SKevin Wolf * code to start (we don't want to catch the job in the pause point in 950d8b3afd5SKevin Wolf * job_co_entry(). */ 951d8b3afd5SKevin Wolf while (!tjob->running) { 952d8b3afd5SKevin Wolf aio_poll(qemu_get_aio_context(), false); 953d8b3afd5SKevin Wolf } 954d8b3afd5SKevin Wolf } 955d8b3afd5SKevin Wolf 956191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 957da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 958da01ff7fSKevin Wolf g_assert_false(job->job.paused); 959d8b3afd5SKevin Wolf g_assert_true(tjob->running); 9605599c162SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 961191e7af3SEmanuele Giuseppe Esposito } 9627253220dSKevin Wolf 963d8b3afd5SKevin Wolf do_drain_begin_unlocked(drain_type, drain_bs); 9647253220dSKevin Wolf 965191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 9667253220dSKevin Wolf if (drain_type == BDRV_DRAIN_ALL) { 96781193349SKevin Wolf /* bdrv_drain_all() drains both src and target */ 968da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 2); 9697253220dSKevin Wolf } else { 970da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 1); 9717253220dSKevin Wolf } 97289bd0305SKevin Wolf g_assert_true(job->job.paused); 973da01ff7fSKevin Wolf g_assert_false(job->job.busy); /* The job is paused */ 974191e7af3SEmanuele Giuseppe Esposito } 9757253220dSKevin Wolf 976d8b3afd5SKevin Wolf do_drain_end_unlocked(drain_type, drain_bs); 977f62c1729SKevin Wolf 978f62c1729SKevin Wolf if (use_iothread) { 979191e7af3SEmanuele Giuseppe Esposito /* 980191e7af3SEmanuele Giuseppe Esposito * Here we are waiting for the paused status to change, 981191e7af3SEmanuele Giuseppe Esposito * so don't bother protecting the read every time. 982191e7af3SEmanuele Giuseppe Esposito * 983191e7af3SEmanuele Giuseppe Esposito * paused is reset in the I/O thread, wait for it 984191e7af3SEmanuele Giuseppe Esposito */ 985f62c1729SKevin Wolf while (job->job.paused) { 986f62c1729SKevin Wolf aio_poll(qemu_get_aio_context(), false); 987f62c1729SKevin Wolf } 988f62c1729SKevin Wolf } 9897253220dSKevin Wolf 990191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 991da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 992da01ff7fSKevin Wolf g_assert_false(job->job.paused); 99389bd0305SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 994191e7af3SEmanuele Giuseppe Esposito } 9957253220dSKevin Wolf 996132ada80SKevin Wolf do_drain_begin_unlocked(drain_type, target); 9977253220dSKevin Wolf 998191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 9997253220dSKevin Wolf if (drain_type == BDRV_DRAIN_ALL) { 100081193349SKevin Wolf /* bdrv_drain_all() drains both src and target */ 1001da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 2); 10027253220dSKevin Wolf } else { 1003da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 1); 10047253220dSKevin Wolf } 100589bd0305SKevin Wolf g_assert_true(job->job.paused); 1006da01ff7fSKevin Wolf g_assert_false(job->job.busy); /* The job is paused */ 1007191e7af3SEmanuele Giuseppe Esposito } 10087253220dSKevin Wolf 1009132ada80SKevin Wolf do_drain_end_unlocked(drain_type, target); 10107253220dSKevin Wolf 1011f62c1729SKevin Wolf if (use_iothread) { 1012191e7af3SEmanuele Giuseppe Esposito /* 1013191e7af3SEmanuele Giuseppe Esposito * Here we are waiting for the paused status to change, 1014191e7af3SEmanuele Giuseppe Esposito * so don't bother protecting the read every time. 1015191e7af3SEmanuele Giuseppe Esposito * 1016191e7af3SEmanuele Giuseppe Esposito * paused is reset in the I/O thread, wait for it 1017191e7af3SEmanuele Giuseppe Esposito */ 1018f62c1729SKevin Wolf while (job->job.paused) { 1019f62c1729SKevin Wolf aio_poll(qemu_get_aio_context(), false); 1020f62c1729SKevin Wolf } 1021f62c1729SKevin Wolf } 1022f62c1729SKevin Wolf 1023191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 1024da01ff7fSKevin Wolf g_assert_cmpint(job->job.pause_count, ==, 0); 1025da01ff7fSKevin Wolf g_assert_false(job->job.paused); 10265599c162SKevin Wolf g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ 1027191e7af3SEmanuele Giuseppe Esposito } 10287253220dSKevin Wolf 1029191e7af3SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 1030191e7af3SEmanuele Giuseppe Esposito ret = job_complete_sync_locked(&job->job, &error_abort); 1031191e7af3SEmanuele Giuseppe Esposito } 1032d49725afSKevin Wolf g_assert_cmpint(ret, ==, (result == TEST_JOB_SUCCESS ? 0 : -EIO)); 10337253220dSKevin Wolf 10346f592e5aSEmanuele Giuseppe Esposito aio_context_acquire(ctx); 1035f62c1729SKevin Wolf if (use_iothread) { 103697896a48SKevin Wolf blk_set_aio_context(blk_src, qemu_get_aio_context(), &error_abort); 1037ad943dcbSKevin Wolf assert(blk_get_aio_context(blk_target) == qemu_get_aio_context()); 1038f62c1729SKevin Wolf } 1039f62c1729SKevin Wolf aio_context_release(ctx); 1040f62c1729SKevin Wolf 10417253220dSKevin Wolf blk_unref(blk_src); 10427253220dSKevin Wolf blk_unref(blk_target); 1043d8b3afd5SKevin Wolf bdrv_unref(src_overlay); 10447253220dSKevin Wolf bdrv_unref(target); 1045f62c1729SKevin Wolf 1046f62c1729SKevin Wolf if (iothread) { 1047f62c1729SKevin Wolf iothread_join(iothread); 1048f62c1729SKevin Wolf } 10497253220dSKevin Wolf } 10507253220dSKevin Wolf 1051d8b3afd5SKevin Wolf static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, 1052d8b3afd5SKevin Wolf enum test_job_result result) 1053d8b3afd5SKevin Wolf { 1054d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1055d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC); 1056d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1057d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_CHILD); 1058d8b3afd5SKevin Wolf if (drain_type == BDRV_SUBTREE_DRAIN) { 1059d8b3afd5SKevin Wolf test_blockjob_common_drain_node(drain_type, use_iothread, result, 1060d8b3afd5SKevin Wolf TEST_JOB_DRAIN_SRC_PARENT); 1061d8b3afd5SKevin Wolf } 1062d8b3afd5SKevin Wolf } 1063d8b3afd5SKevin Wolf 10647253220dSKevin Wolf static void test_blockjob_drain_all(void) 10657253220dSKevin Wolf { 1066d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_SUCCESS); 10677253220dSKevin Wolf } 10687253220dSKevin Wolf 10697253220dSKevin Wolf static void test_blockjob_drain(void) 10707253220dSKevin Wolf { 1071d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_SUCCESS); 10727253220dSKevin Wolf } 10737253220dSKevin Wolf 1074d2a85d0fSKevin Wolf static void test_blockjob_drain_subtree(void) 1075d2a85d0fSKevin Wolf { 1076d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_SUCCESS); 1077d49725afSKevin Wolf } 1078d49725afSKevin Wolf 1079d49725afSKevin Wolf static void test_blockjob_error_drain_all(void) 1080d49725afSKevin Wolf { 1081d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_RUN); 1082d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_PREPARE); 1083d49725afSKevin Wolf } 1084d49725afSKevin Wolf 1085d49725afSKevin Wolf static void test_blockjob_error_drain(void) 1086d49725afSKevin Wolf { 1087d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_RUN); 1088d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_PREPARE); 1089d49725afSKevin Wolf } 1090d49725afSKevin Wolf 1091d49725afSKevin Wolf static void test_blockjob_error_drain_subtree(void) 1092d49725afSKevin Wolf { 1093d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_RUN); 1094d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_PREPARE); 1095f62c1729SKevin Wolf } 1096f62c1729SKevin Wolf 1097f62c1729SKevin Wolf static void test_blockjob_iothread_drain_all(void) 1098f62c1729SKevin Wolf { 1099d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_SUCCESS); 1100f62c1729SKevin Wolf } 1101f62c1729SKevin Wolf 1102f62c1729SKevin Wolf static void test_blockjob_iothread_drain(void) 1103f62c1729SKevin Wolf { 1104d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_SUCCESS); 1105f62c1729SKevin Wolf } 1106f62c1729SKevin Wolf 1107f62c1729SKevin Wolf static void test_blockjob_iothread_drain_subtree(void) 1108f62c1729SKevin Wolf { 1109d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_SUCCESS); 1110d49725afSKevin Wolf } 1111d49725afSKevin Wolf 1112d49725afSKevin Wolf static void test_blockjob_iothread_error_drain_all(void) 1113d49725afSKevin Wolf { 1114d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_RUN); 1115d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_PREPARE); 1116d49725afSKevin Wolf } 1117d49725afSKevin Wolf 1118d49725afSKevin Wolf static void test_blockjob_iothread_error_drain(void) 1119d49725afSKevin Wolf { 1120d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_RUN); 1121d49725afSKevin Wolf test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_PREPARE); 1122d49725afSKevin Wolf } 1123d49725afSKevin Wolf 1124d49725afSKevin Wolf static void test_blockjob_iothread_error_drain_subtree(void) 1125d49725afSKevin Wolf { 1126d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_RUN); 1127d49725afSKevin Wolf test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_PREPARE); 1128d2a85d0fSKevin Wolf } 1129d2a85d0fSKevin Wolf 11304c8158e3SMax Reitz 11314c8158e3SMax Reitz typedef struct BDRVTestTopState { 11324c8158e3SMax Reitz BdrvChild *wait_child; 11334c8158e3SMax Reitz } BDRVTestTopState; 11344c8158e3SMax Reitz 11354c8158e3SMax Reitz static void bdrv_test_top_close(BlockDriverState *bs) 11364c8158e3SMax Reitz { 11374c8158e3SMax Reitz BdrvChild *c, *next_c; 11384c8158e3SMax Reitz QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) { 11394c8158e3SMax Reitz bdrv_unref_child(bs, c); 11404c8158e3SMax Reitz } 11414c8158e3SMax Reitz } 11424c8158e3SMax Reitz 11434c8158e3SMax Reitz static int coroutine_fn bdrv_test_top_co_preadv(BlockDriverState *bs, 1144f7ef38ddSVladimir Sementsov-Ogievskiy int64_t offset, int64_t bytes, 1145f7ef38ddSVladimir Sementsov-Ogievskiy QEMUIOVector *qiov, 1146f7ef38ddSVladimir Sementsov-Ogievskiy BdrvRequestFlags flags) 11474c8158e3SMax Reitz { 11484c8158e3SMax Reitz BDRVTestTopState *tts = bs->opaque; 11494c8158e3SMax Reitz return bdrv_co_preadv(tts->wait_child, offset, bytes, qiov, flags); 11504c8158e3SMax Reitz } 11514c8158e3SMax Reitz 11524c8158e3SMax Reitz static BlockDriver bdrv_test_top_driver = { 11534c8158e3SMax Reitz .format_name = "test_top_driver", 11544c8158e3SMax Reitz .instance_size = sizeof(BDRVTestTopState), 11554c8158e3SMax Reitz 11564c8158e3SMax Reitz .bdrv_close = bdrv_test_top_close, 11574c8158e3SMax Reitz .bdrv_co_preadv = bdrv_test_top_co_preadv, 11584c8158e3SMax Reitz 115969dca43dSMax Reitz .bdrv_child_perm = bdrv_default_perms, 11604c8158e3SMax Reitz }; 11614c8158e3SMax Reitz 11624c8158e3SMax Reitz typedef struct TestCoDeleteByDrainData { 11634c8158e3SMax Reitz BlockBackend *blk; 11644c8158e3SMax Reitz bool detach_instead_of_delete; 11654c8158e3SMax Reitz bool done; 11664c8158e3SMax Reitz } TestCoDeleteByDrainData; 11674c8158e3SMax Reitz 11684c8158e3SMax Reitz static void coroutine_fn test_co_delete_by_drain(void *opaque) 11694c8158e3SMax Reitz { 11704c8158e3SMax Reitz TestCoDeleteByDrainData *dbdd = opaque; 11714c8158e3SMax Reitz BlockBackend *blk = dbdd->blk; 11724c8158e3SMax Reitz BlockDriverState *bs = blk_bs(blk); 11734c8158e3SMax Reitz BDRVTestTopState *tts = bs->opaque; 11744c8158e3SMax Reitz void *buffer = g_malloc(65536); 1175405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buffer, 65536); 11764c8158e3SMax Reitz 11774c8158e3SMax Reitz /* Pretend some internal write operation from parent to child. 11784c8158e3SMax Reitz * Important: We have to read from the child, not from the parent! 11794c8158e3SMax Reitz * Draining works by first propagating it all up the tree to the 11804c8158e3SMax Reitz * root and then waiting for drainage from root to the leaves 11814c8158e3SMax Reitz * (protocol nodes). If we have a request waiting on the root, 11824c8158e3SMax Reitz * everything will be drained before we go back down the tree, but 11834c8158e3SMax Reitz * we do not want that. We want to be in the middle of draining 11844c8158e3SMax Reitz * when this following requests returns. */ 11854c8158e3SMax Reitz bdrv_co_preadv(tts->wait_child, 0, 65536, &qiov, 0); 11864c8158e3SMax Reitz 11874c8158e3SMax Reitz g_assert_cmpint(bs->refcnt, ==, 1); 11884c8158e3SMax Reitz 11894c8158e3SMax Reitz if (!dbdd->detach_instead_of_delete) { 11904c8158e3SMax Reitz blk_unref(blk); 11914c8158e3SMax Reitz } else { 11924c8158e3SMax Reitz BdrvChild *c, *next_c; 11934c8158e3SMax Reitz QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) { 11944c8158e3SMax Reitz bdrv_unref_child(bs, c); 11954c8158e3SMax Reitz } 11964c8158e3SMax Reitz } 11974c8158e3SMax Reitz 11984c8158e3SMax Reitz dbdd->done = true; 11997b43db3cSMarc-André Lureau g_free(buffer); 12004c8158e3SMax Reitz } 12014c8158e3SMax Reitz 12024c8158e3SMax Reitz /** 12034c8158e3SMax Reitz * Test what happens when some BDS has some children, you drain one of 12044c8158e3SMax Reitz * them and this results in the BDS being deleted. 12054c8158e3SMax Reitz * 12064c8158e3SMax Reitz * If @detach_instead_of_delete is set, the BDS is not going to be 12074c8158e3SMax Reitz * deleted but will only detach all of its children. 12084c8158e3SMax Reitz */ 1209ebd31837SKevin Wolf static void do_test_delete_by_drain(bool detach_instead_of_delete, 1210ebd31837SKevin Wolf enum drain_type drain_type) 12114c8158e3SMax Reitz { 12124c8158e3SMax Reitz BlockBackend *blk; 12134c8158e3SMax Reitz BlockDriverState *bs, *child_bs, *null_bs; 12144c8158e3SMax Reitz BDRVTestTopState *tts; 12154c8158e3SMax Reitz TestCoDeleteByDrainData dbdd; 12164c8158e3SMax Reitz Coroutine *co; 12174c8158e3SMax Reitz 12184c8158e3SMax Reitz bs = bdrv_new_open_driver(&bdrv_test_top_driver, "top", BDRV_O_RDWR, 12194c8158e3SMax Reitz &error_abort); 12204c8158e3SMax Reitz bs->total_sectors = 65536 >> BDRV_SECTOR_BITS; 12214c8158e3SMax Reitz tts = bs->opaque; 12224c8158e3SMax Reitz 12234c8158e3SMax Reitz null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 12244c8158e3SMax Reitz &error_abort); 1225a16be3cdSMax Reitz bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, 1226a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 12274c8158e3SMax Reitz 12284c8158e3SMax Reitz /* This child will be the one to pass to requests through to, and 12294c8158e3SMax Reitz * it will stall until a drain occurs */ 12304c8158e3SMax Reitz child_bs = bdrv_new_open_driver(&bdrv_test, "child", BDRV_O_RDWR, 12314c8158e3SMax Reitz &error_abort); 12324c8158e3SMax Reitz child_bs->total_sectors = 65536 >> BDRV_SECTOR_BITS; 12334c8158e3SMax Reitz /* Takes our reference to child_bs */ 1234a16be3cdSMax Reitz tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child", 1235a16be3cdSMax Reitz &child_of_bds, 1236a16be3cdSMax Reitz BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY, 1237a16be3cdSMax Reitz &error_abort); 12384c8158e3SMax Reitz 12394c8158e3SMax Reitz /* This child is just there to be deleted 12404c8158e3SMax Reitz * (for detach_instead_of_delete == true) */ 12414c8158e3SMax Reitz null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 12424c8158e3SMax Reitz &error_abort); 1243a16be3cdSMax Reitz bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, BDRV_CHILD_DATA, 1244a16be3cdSMax Reitz &error_abort); 12454c8158e3SMax Reitz 1246d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 12474c8158e3SMax Reitz blk_insert_bs(blk, bs, &error_abort); 12484c8158e3SMax Reitz 12494c8158e3SMax Reitz /* Referenced by blk now */ 12504c8158e3SMax Reitz bdrv_unref(bs); 12514c8158e3SMax Reitz 12524c8158e3SMax Reitz g_assert_cmpint(bs->refcnt, ==, 1); 12534c8158e3SMax Reitz g_assert_cmpint(child_bs->refcnt, ==, 1); 12544c8158e3SMax Reitz g_assert_cmpint(null_bs->refcnt, ==, 1); 12554c8158e3SMax Reitz 12564c8158e3SMax Reitz 12574c8158e3SMax Reitz dbdd = (TestCoDeleteByDrainData){ 12584c8158e3SMax Reitz .blk = blk, 12594c8158e3SMax Reitz .detach_instead_of_delete = detach_instead_of_delete, 12604c8158e3SMax Reitz .done = false, 12614c8158e3SMax Reitz }; 12624c8158e3SMax Reitz co = qemu_coroutine_create(test_co_delete_by_drain, &dbdd); 12634c8158e3SMax Reitz qemu_coroutine_enter(co); 12644c8158e3SMax Reitz 12654c8158e3SMax Reitz /* Drain the child while the read operation is still pending. 12664c8158e3SMax Reitz * This should result in the operation finishing and 12674c8158e3SMax Reitz * test_co_delete_by_drain() resuming. Thus, @bs will be deleted 12684c8158e3SMax Reitz * and the coroutine will exit while this drain operation is still 12694c8158e3SMax Reitz * in progress. */ 1270ebd31837SKevin Wolf switch (drain_type) { 1271ebd31837SKevin Wolf case BDRV_DRAIN: 12724c8158e3SMax Reitz bdrv_ref(child_bs); 12734c8158e3SMax Reitz bdrv_drain(child_bs); 12744c8158e3SMax Reitz bdrv_unref(child_bs); 1275ebd31837SKevin Wolf break; 1276ebd31837SKevin Wolf case BDRV_SUBTREE_DRAIN: 1277ebd31837SKevin Wolf /* Would have to ref/unref bs here for !detach_instead_of_delete, but 1278ebd31837SKevin Wolf * then the whole test becomes pointless because the graph changes 1279ebd31837SKevin Wolf * don't occur during the drain any more. */ 1280ebd31837SKevin Wolf assert(detach_instead_of_delete); 1281ebd31837SKevin Wolf bdrv_subtree_drained_begin(bs); 1282ebd31837SKevin Wolf bdrv_subtree_drained_end(bs); 1283ebd31837SKevin Wolf break; 128419f7a7e5SKevin Wolf case BDRV_DRAIN_ALL: 128519f7a7e5SKevin Wolf bdrv_drain_all_begin(); 128619f7a7e5SKevin Wolf bdrv_drain_all_end(); 128719f7a7e5SKevin Wolf break; 1288ebd31837SKevin Wolf default: 1289ebd31837SKevin Wolf g_assert_not_reached(); 1290ebd31837SKevin Wolf } 12914c8158e3SMax Reitz 12924c8158e3SMax Reitz while (!dbdd.done) { 12934c8158e3SMax Reitz aio_poll(qemu_get_aio_context(), true); 12944c8158e3SMax Reitz } 12954c8158e3SMax Reitz 12964c8158e3SMax Reitz if (detach_instead_of_delete) { 12974c8158e3SMax Reitz /* Here, the reference has not passed over to the coroutine, 12984c8158e3SMax Reitz * so we have to delete the BB ourselves */ 12994c8158e3SMax Reitz blk_unref(blk); 13004c8158e3SMax Reitz } 13014c8158e3SMax Reitz } 13024c8158e3SMax Reitz 13034c8158e3SMax Reitz static void test_delete_by_drain(void) 13044c8158e3SMax Reitz { 1305ebd31837SKevin Wolf do_test_delete_by_drain(false, BDRV_DRAIN); 13064c8158e3SMax Reitz } 13074c8158e3SMax Reitz 130819f7a7e5SKevin Wolf static void test_detach_by_drain_all(void) 130919f7a7e5SKevin Wolf { 131019f7a7e5SKevin Wolf do_test_delete_by_drain(true, BDRV_DRAIN_ALL); 131119f7a7e5SKevin Wolf } 131219f7a7e5SKevin Wolf 13134c8158e3SMax Reitz static void test_detach_by_drain(void) 13144c8158e3SMax Reitz { 1315ebd31837SKevin Wolf do_test_delete_by_drain(true, BDRV_DRAIN); 1316ebd31837SKevin Wolf } 1317ebd31837SKevin Wolf 1318ebd31837SKevin Wolf static void test_detach_by_drain_subtree(void) 1319ebd31837SKevin Wolf { 1320ebd31837SKevin Wolf do_test_delete_by_drain(true, BDRV_SUBTREE_DRAIN); 13214c8158e3SMax Reitz } 13224c8158e3SMax Reitz 13234c8158e3SMax Reitz 1324231281abSKevin Wolf struct detach_by_parent_data { 1325231281abSKevin Wolf BlockDriverState *parent_b; 1326231281abSKevin Wolf BdrvChild *child_b; 1327231281abSKevin Wolf BlockDriverState *c; 1328231281abSKevin Wolf BdrvChild *child_c; 132957320ca9SKevin Wolf bool by_parent_cb; 1330231281abSKevin Wolf }; 133157320ca9SKevin Wolf static struct detach_by_parent_data detach_by_parent_data; 1332231281abSKevin Wolf 133357320ca9SKevin Wolf static void detach_indirect_bh(void *opaque) 1334231281abSKevin Wolf { 1335231281abSKevin Wolf struct detach_by_parent_data *data = opaque; 1336231281abSKevin Wolf 1337231281abSKevin Wolf bdrv_unref_child(data->parent_b, data->child_b); 1338231281abSKevin Wolf 1339231281abSKevin Wolf bdrv_ref(data->c); 1340231281abSKevin Wolf data->child_c = bdrv_attach_child(data->parent_b, data->c, "PB-C", 1341a16be3cdSMax Reitz &child_of_bds, BDRV_CHILD_DATA, 1342a16be3cdSMax Reitz &error_abort); 1343231281abSKevin Wolf } 1344231281abSKevin Wolf 134557320ca9SKevin Wolf static void detach_by_parent_aio_cb(void *opaque, int ret) 134657320ca9SKevin Wolf { 134757320ca9SKevin Wolf struct detach_by_parent_data *data = &detach_by_parent_data; 134857320ca9SKevin Wolf 134957320ca9SKevin Wolf g_assert_cmpint(ret, ==, 0); 135057320ca9SKevin Wolf if (data->by_parent_cb) { 135157320ca9SKevin Wolf detach_indirect_bh(data); 135257320ca9SKevin Wolf } 135357320ca9SKevin Wolf } 135457320ca9SKevin Wolf 135557320ca9SKevin Wolf static void detach_by_driver_cb_drained_begin(BdrvChild *child) 135657320ca9SKevin Wolf { 135757320ca9SKevin Wolf aio_bh_schedule_oneshot(qemu_get_current_aio_context(), 135857320ca9SKevin Wolf detach_indirect_bh, &detach_by_parent_data); 1359a16be3cdSMax Reitz child_of_bds.drained_begin(child); 136057320ca9SKevin Wolf } 136157320ca9SKevin Wolf 1362bd86fb99SMax Reitz static BdrvChildClass detach_by_driver_cb_class; 136357320ca9SKevin Wolf 1364231281abSKevin Wolf /* 1365231281abSKevin Wolf * Initial graph: 1366231281abSKevin Wolf * 1367231281abSKevin Wolf * PA PB 1368231281abSKevin Wolf * \ / \ 1369231281abSKevin Wolf * A B C 1370231281abSKevin Wolf * 137157320ca9SKevin Wolf * by_parent_cb == true: Test that parent callbacks don't poll 137257320ca9SKevin Wolf * 137357320ca9SKevin Wolf * PA has a pending write request whose callback changes the child nodes of 137457320ca9SKevin Wolf * PB: It removes B and adds C instead. The subtree of PB is drained, which 137557320ca9SKevin Wolf * will indirectly drain the write request, too. 137657320ca9SKevin Wolf * 137757320ca9SKevin Wolf * by_parent_cb == false: Test that bdrv_drain_invoke() doesn't poll 137857320ca9SKevin Wolf * 1379bd86fb99SMax Reitz * PA's BdrvChildClass has a .drained_begin callback that schedules a BH 138057320ca9SKevin Wolf * that does the same graph change. If bdrv_drain_invoke() calls it, the 138157320ca9SKevin Wolf * state is messed up, but if it is only polled in the single 138257320ca9SKevin Wolf * BDRV_POLL_WHILE() at the end of the drain, this should work fine. 1383231281abSKevin Wolf */ 138457320ca9SKevin Wolf static void test_detach_indirect(bool by_parent_cb) 1385231281abSKevin Wolf { 1386231281abSKevin Wolf BlockBackend *blk; 1387231281abSKevin Wolf BlockDriverState *parent_a, *parent_b, *a, *b, *c; 1388231281abSKevin Wolf BdrvChild *child_a, *child_b; 1389231281abSKevin Wolf BlockAIOCB *acb; 1390231281abSKevin Wolf 1391405d8fe0SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0); 1392231281abSKevin Wolf 139357320ca9SKevin Wolf if (!by_parent_cb) { 1394a16be3cdSMax Reitz detach_by_driver_cb_class = child_of_bds; 1395bd86fb99SMax Reitz detach_by_driver_cb_class.drained_begin = 139657320ca9SKevin Wolf detach_by_driver_cb_drained_begin; 139757320ca9SKevin Wolf } 139857320ca9SKevin Wolf 1399231281abSKevin Wolf /* Create all involved nodes */ 1400231281abSKevin Wolf parent_a = bdrv_new_open_driver(&bdrv_test, "parent-a", BDRV_O_RDWR, 1401231281abSKevin Wolf &error_abort); 1402231281abSKevin Wolf parent_b = bdrv_new_open_driver(&bdrv_test, "parent-b", 0, 1403231281abSKevin Wolf &error_abort); 1404231281abSKevin Wolf 1405231281abSKevin Wolf a = bdrv_new_open_driver(&bdrv_test, "a", BDRV_O_RDWR, &error_abort); 1406231281abSKevin Wolf b = bdrv_new_open_driver(&bdrv_test, "b", BDRV_O_RDWR, &error_abort); 1407231281abSKevin Wolf c = bdrv_new_open_driver(&bdrv_test, "c", BDRV_O_RDWR, &error_abort); 1408231281abSKevin Wolf 1409231281abSKevin Wolf /* blk is a BB for parent-a */ 1410d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 1411231281abSKevin Wolf blk_insert_bs(blk, parent_a, &error_abort); 1412231281abSKevin Wolf bdrv_unref(parent_a); 1413231281abSKevin Wolf 141457320ca9SKevin Wolf /* If we want to get bdrv_drain_invoke() to call aio_poll(), the driver 141557320ca9SKevin Wolf * callback must not return immediately. */ 141657320ca9SKevin Wolf if (!by_parent_cb) { 141757320ca9SKevin Wolf BDRVTestState *s = parent_a->opaque; 141857320ca9SKevin Wolf s->sleep_in_drain_begin = true; 141957320ca9SKevin Wolf } 142057320ca9SKevin Wolf 1421231281abSKevin Wolf /* Set child relationships */ 1422231281abSKevin Wolf bdrv_ref(b); 1423231281abSKevin Wolf bdrv_ref(a); 1424a16be3cdSMax Reitz child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_of_bds, 1425a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 142625191e5fSMax Reitz child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_of_bds, 142725191e5fSMax Reitz BDRV_CHILD_COW, &error_abort); 1428231281abSKevin Wolf 1429231281abSKevin Wolf bdrv_ref(a); 143057320ca9SKevin Wolf bdrv_attach_child(parent_a, a, "PA-A", 1431a16be3cdSMax Reitz by_parent_cb ? &child_of_bds : &detach_by_driver_cb_class, 1432a16be3cdSMax Reitz BDRV_CHILD_DATA, &error_abort); 1433231281abSKevin Wolf 1434231281abSKevin Wolf g_assert_cmpint(parent_a->refcnt, ==, 1); 1435231281abSKevin Wolf g_assert_cmpint(parent_b->refcnt, ==, 1); 1436231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 3); 1437231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 2); 1438231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 1); 1439231281abSKevin Wolf 1440231281abSKevin Wolf g_assert(QLIST_FIRST(&parent_b->children) == child_a); 1441231281abSKevin Wolf g_assert(QLIST_NEXT(child_a, next) == child_b); 1442231281abSKevin Wolf g_assert(QLIST_NEXT(child_b, next) == NULL); 1443231281abSKevin Wolf 1444231281abSKevin Wolf /* Start the evil write request */ 144557320ca9SKevin Wolf detach_by_parent_data = (struct detach_by_parent_data) { 1446231281abSKevin Wolf .parent_b = parent_b, 1447231281abSKevin Wolf .child_b = child_b, 1448231281abSKevin Wolf .c = c, 144957320ca9SKevin Wolf .by_parent_cb = by_parent_cb, 1450231281abSKevin Wolf }; 145157320ca9SKevin Wolf acb = blk_aio_preadv(blk, 0, &qiov, 0, detach_by_parent_aio_cb, NULL); 1452231281abSKevin Wolf g_assert(acb != NULL); 1453231281abSKevin Wolf 1454231281abSKevin Wolf /* Drain and check the expected result */ 1455231281abSKevin Wolf bdrv_subtree_drained_begin(parent_b); 1456231281abSKevin Wolf 145757320ca9SKevin Wolf g_assert(detach_by_parent_data.child_c != NULL); 1458231281abSKevin Wolf 1459231281abSKevin Wolf g_assert_cmpint(parent_a->refcnt, ==, 1); 1460231281abSKevin Wolf g_assert_cmpint(parent_b->refcnt, ==, 1); 1461231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 3); 1462231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 1); 1463231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 2); 1464231281abSKevin Wolf 146557320ca9SKevin Wolf g_assert(QLIST_FIRST(&parent_b->children) == detach_by_parent_data.child_c); 146657320ca9SKevin Wolf g_assert(QLIST_NEXT(detach_by_parent_data.child_c, next) == child_a); 1467231281abSKevin Wolf g_assert(QLIST_NEXT(child_a, next) == NULL); 1468231281abSKevin Wolf 1469231281abSKevin Wolf g_assert_cmpint(parent_a->quiesce_counter, ==, 1); 1470231281abSKevin Wolf g_assert_cmpint(parent_b->quiesce_counter, ==, 1); 1471231281abSKevin Wolf g_assert_cmpint(a->quiesce_counter, ==, 1); 1472231281abSKevin Wolf g_assert_cmpint(b->quiesce_counter, ==, 0); 1473231281abSKevin Wolf g_assert_cmpint(c->quiesce_counter, ==, 1); 1474231281abSKevin Wolf 1475231281abSKevin Wolf bdrv_subtree_drained_end(parent_b); 1476231281abSKevin Wolf 1477231281abSKevin Wolf bdrv_unref(parent_b); 1478231281abSKevin Wolf blk_unref(blk); 1479231281abSKevin Wolf 1480231281abSKevin Wolf g_assert_cmpint(a->refcnt, ==, 1); 1481231281abSKevin Wolf g_assert_cmpint(b->refcnt, ==, 1); 1482231281abSKevin Wolf g_assert_cmpint(c->refcnt, ==, 1); 1483231281abSKevin Wolf bdrv_unref(a); 1484231281abSKevin Wolf bdrv_unref(b); 1485231281abSKevin Wolf bdrv_unref(c); 1486231281abSKevin Wolf } 1487231281abSKevin Wolf 148857320ca9SKevin Wolf static void test_detach_by_parent_cb(void) 148957320ca9SKevin Wolf { 149057320ca9SKevin Wolf test_detach_indirect(true); 149157320ca9SKevin Wolf } 149257320ca9SKevin Wolf 149357320ca9SKevin Wolf static void test_detach_by_driver_cb(void) 149457320ca9SKevin Wolf { 149557320ca9SKevin Wolf test_detach_indirect(false); 149657320ca9SKevin Wolf } 1497231281abSKevin Wolf 1498b994c5bcSKevin Wolf static void test_append_to_drained(void) 1499b994c5bcSKevin Wolf { 1500b994c5bcSKevin Wolf BlockBackend *blk; 1501b994c5bcSKevin Wolf BlockDriverState *base, *overlay; 1502b994c5bcSKevin Wolf BDRVTestState *base_s, *overlay_s; 1503b994c5bcSKevin Wolf 1504d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); 1505b994c5bcSKevin Wolf base = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort); 1506b994c5bcSKevin Wolf base_s = base->opaque; 1507b994c5bcSKevin Wolf blk_insert_bs(blk, base, &error_abort); 1508b994c5bcSKevin Wolf 1509b994c5bcSKevin Wolf overlay = bdrv_new_open_driver(&bdrv_test, "overlay", BDRV_O_RDWR, 1510b994c5bcSKevin Wolf &error_abort); 1511b994c5bcSKevin Wolf overlay_s = overlay->opaque; 1512b994c5bcSKevin Wolf 1513b994c5bcSKevin Wolf do_drain_begin(BDRV_DRAIN, base); 1514b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 1); 1515b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 1); 1516b994c5bcSKevin Wolf g_assert_cmpint(base->in_flight, ==, 0); 1517b994c5bcSKevin Wolf 1518b994c5bcSKevin Wolf bdrv_append(overlay, base, &error_abort); 1519b994c5bcSKevin Wolf g_assert_cmpint(base->in_flight, ==, 0); 1520b994c5bcSKevin Wolf g_assert_cmpint(overlay->in_flight, ==, 0); 1521b994c5bcSKevin Wolf 1522b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 1); 1523b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 1); 1524b994c5bcSKevin Wolf g_assert_cmpint(overlay->quiesce_counter, ==, 1); 1525b994c5bcSKevin Wolf g_assert_cmpint(overlay_s->drain_count, ==, 1); 1526b994c5bcSKevin Wolf 1527b994c5bcSKevin Wolf do_drain_end(BDRV_DRAIN, base); 1528b994c5bcSKevin Wolf 1529b994c5bcSKevin Wolf g_assert_cmpint(base->quiesce_counter, ==, 0); 1530b994c5bcSKevin Wolf g_assert_cmpint(base_s->drain_count, ==, 0); 1531b994c5bcSKevin Wolf g_assert_cmpint(overlay->quiesce_counter, ==, 0); 1532b994c5bcSKevin Wolf g_assert_cmpint(overlay_s->drain_count, ==, 0); 1533b994c5bcSKevin Wolf 1534ae9d4417SVladimir Sementsov-Ogievskiy bdrv_unref(overlay); 1535b994c5bcSKevin Wolf bdrv_unref(base); 1536b994c5bcSKevin Wolf blk_unref(blk); 1537b994c5bcSKevin Wolf } 1538b994c5bcSKevin Wolf 1539247d2737SKevin Wolf static void test_set_aio_context(void) 1540247d2737SKevin Wolf { 1541247d2737SKevin Wolf BlockDriverState *bs; 1542247d2737SKevin Wolf IOThread *a = iothread_new(); 1543247d2737SKevin Wolf IOThread *b = iothread_new(); 1544247d2737SKevin Wolf AioContext *ctx_a = iothread_get_aio_context(a); 1545247d2737SKevin Wolf AioContext *ctx_b = iothread_get_aio_context(b); 1546247d2737SKevin Wolf 1547247d2737SKevin Wolf bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, 1548247d2737SKevin Wolf &error_abort); 1549247d2737SKevin Wolf 1550247d2737SKevin Wolf bdrv_drained_begin(bs); 1551142e6907SEmanuele Giuseppe Esposito bdrv_try_change_aio_context(bs, ctx_a, NULL, &error_abort); 1552247d2737SKevin Wolf 1553247d2737SKevin Wolf aio_context_acquire(ctx_a); 1554247d2737SKevin Wolf bdrv_drained_end(bs); 1555247d2737SKevin Wolf 1556247d2737SKevin Wolf bdrv_drained_begin(bs); 1557142e6907SEmanuele Giuseppe Esposito bdrv_try_change_aio_context(bs, ctx_b, NULL, &error_abort); 1558247d2737SKevin Wolf aio_context_release(ctx_a); 1559247d2737SKevin Wolf aio_context_acquire(ctx_b); 1560142e6907SEmanuele Giuseppe Esposito bdrv_try_change_aio_context(bs, qemu_get_aio_context(), NULL, &error_abort); 1561247d2737SKevin Wolf aio_context_release(ctx_b); 1562247d2737SKevin Wolf bdrv_drained_end(bs); 1563247d2737SKevin Wolf 1564247d2737SKevin Wolf bdrv_unref(bs); 1565247d2737SKevin Wolf iothread_join(a); 1566247d2737SKevin Wolf iothread_join(b); 1567247d2737SKevin Wolf } 1568247d2737SKevin Wolf 15698e442810SMax Reitz 15708e442810SMax Reitz typedef struct TestDropBackingBlockJob { 15718e442810SMax Reitz BlockJob common; 15728e442810SMax Reitz bool should_complete; 15738e442810SMax Reitz bool *did_complete; 15742afdc790SMax Reitz BlockDriverState *detach_also; 15751b177bbeSVladimir Sementsov-Ogievskiy BlockDriverState *bs; 15768e442810SMax Reitz } TestDropBackingBlockJob; 15778e442810SMax Reitz 15788e442810SMax Reitz static int coroutine_fn test_drop_backing_job_run(Job *job, Error **errp) 15798e442810SMax Reitz { 15808e442810SMax Reitz TestDropBackingBlockJob *s = 15818e442810SMax Reitz container_of(job, TestDropBackingBlockJob, common.job); 15828e442810SMax Reitz 15838e442810SMax Reitz while (!s->should_complete) { 15848e442810SMax Reitz job_sleep_ns(job, 0); 15858e442810SMax Reitz } 15868e442810SMax Reitz 15878e442810SMax Reitz return 0; 15888e442810SMax Reitz } 15898e442810SMax Reitz 15908e442810SMax Reitz static void test_drop_backing_job_commit(Job *job) 15918e442810SMax Reitz { 15928e442810SMax Reitz TestDropBackingBlockJob *s = 15938e442810SMax Reitz container_of(job, TestDropBackingBlockJob, common.job); 15948e442810SMax Reitz 15951b177bbeSVladimir Sementsov-Ogievskiy bdrv_set_backing_hd(s->bs, NULL, &error_abort); 15962afdc790SMax Reitz bdrv_set_backing_hd(s->detach_also, NULL, &error_abort); 15978e442810SMax Reitz 15988e442810SMax Reitz *s->did_complete = true; 15998e442810SMax Reitz } 16008e442810SMax Reitz 16018e442810SMax Reitz static const BlockJobDriver test_drop_backing_job_driver = { 16028e442810SMax Reitz .job_driver = { 16038e442810SMax Reitz .instance_size = sizeof(TestDropBackingBlockJob), 16048e442810SMax Reitz .free = block_job_free, 16058e442810SMax Reitz .user_resume = block_job_user_resume, 16068e442810SMax Reitz .run = test_drop_backing_job_run, 16078e442810SMax Reitz .commit = test_drop_backing_job_commit, 16088e442810SMax Reitz } 16098e442810SMax Reitz }; 16108e442810SMax Reitz 16118e442810SMax Reitz /** 16128e442810SMax Reitz * Creates a child node with three parent nodes on it, and then runs a 16138e442810SMax Reitz * block job on the final one, parent-node-2. 16148e442810SMax Reitz * 16158e442810SMax Reitz * The job is then asked to complete before a section where the child 16168e442810SMax Reitz * is drained. 16178e442810SMax Reitz * 16188e442810SMax Reitz * Ending this section will undrain the child's parents, first 16198e442810SMax Reitz * parent-node-2, then parent-node-1, then parent-node-0 -- the parent 16208e442810SMax Reitz * list is in reverse order of how they were added. Ending the drain 16218e442810SMax Reitz * on parent-node-2 will resume the job, thus completing it and 16228e442810SMax Reitz * scheduling job_exit(). 16238e442810SMax Reitz * 16248e442810SMax Reitz * Ending the drain on parent-node-1 will poll the AioContext, which 16258e442810SMax Reitz * lets job_exit() and thus test_drop_backing_job_commit() run. That 16262afdc790SMax Reitz * function first removes the child as parent-node-2's backing file. 16278e442810SMax Reitz * 16288e442810SMax Reitz * In old (and buggy) implementations, there are two problems with 16298e442810SMax Reitz * that: 16308e442810SMax Reitz * (A) bdrv_drain_invoke() polls for every node that leaves the 16318e442810SMax Reitz * drained section. This means that job_exit() is scheduled 16328e442810SMax Reitz * before the child has left the drained section. Its 16338e442810SMax Reitz * quiesce_counter is therefore still 1 when it is removed from 16348e442810SMax Reitz * parent-node-2. 16358e442810SMax Reitz * 16368e442810SMax Reitz * (B) bdrv_replace_child_noperm() calls drained_end() on the old 16378e442810SMax Reitz * child's parents as many times as the child is quiesced. This 16388e442810SMax Reitz * means it will call drained_end() on parent-node-2 once. 16398e442810SMax Reitz * Because parent-node-2 is no longer quiesced at this point, this 16408e442810SMax Reitz * will fail. 16418e442810SMax Reitz * 16428e442810SMax Reitz * bdrv_replace_child_noperm() therefore must call drained_end() on 16438e442810SMax Reitz * the parent only if it really is still drained because the child is 16448e442810SMax Reitz * drained. 16452afdc790SMax Reitz * 16462afdc790SMax Reitz * If removing child from parent-node-2 was successful (as it should 16472afdc790SMax Reitz * be), test_drop_backing_job_commit() will then also remove the child 16482afdc790SMax Reitz * from parent-node-0. 16492afdc790SMax Reitz * 16502afdc790SMax Reitz * With an old version of our drain infrastructure ((A) above), that 16512afdc790SMax Reitz * resulted in the following flow: 16522afdc790SMax Reitz * 16532afdc790SMax Reitz * 1. child attempts to leave its drained section. The call recurses 16542afdc790SMax Reitz * to its parents. 16552afdc790SMax Reitz * 16562afdc790SMax Reitz * 2. parent-node-2 leaves the drained section. Polling in 16572afdc790SMax Reitz * bdrv_drain_invoke() will schedule job_exit(). 16582afdc790SMax Reitz * 16592afdc790SMax Reitz * 3. parent-node-1 leaves the drained section. Polling in 16602afdc790SMax Reitz * bdrv_drain_invoke() will run job_exit(), thus disconnecting 16612afdc790SMax Reitz * parent-node-0 from the child node. 16622afdc790SMax Reitz * 16632afdc790SMax Reitz * 4. bdrv_parent_drained_end() uses a QLIST_FOREACH_SAFE() loop to 16642afdc790SMax Reitz * iterate over the parents. Thus, it now accesses the BdrvChild 16652afdc790SMax Reitz * object that used to connect parent-node-0 and the child node. 16662afdc790SMax Reitz * However, that object no longer exists, so it accesses a dangling 16672afdc790SMax Reitz * pointer. 16682afdc790SMax Reitz * 16692afdc790SMax Reitz * The solution is to only poll once when running a bdrv_drained_end() 16702afdc790SMax Reitz * operation, specifically at the end when all drained_end() 16712afdc790SMax Reitz * operations for all involved nodes have been scheduled. 16722afdc790SMax Reitz * Note that this also solves (A) above, thus hiding (B). 16738e442810SMax Reitz */ 16748e442810SMax Reitz static void test_blockjob_commit_by_drained_end(void) 16758e442810SMax Reitz { 16768e442810SMax Reitz BlockDriverState *bs_child, *bs_parents[3]; 16778e442810SMax Reitz TestDropBackingBlockJob *job; 16788e442810SMax Reitz bool job_has_completed = false; 16798e442810SMax Reitz int i; 16808e442810SMax Reitz 16818e442810SMax Reitz bs_child = bdrv_new_open_driver(&bdrv_test, "child-node", BDRV_O_RDWR, 16828e442810SMax Reitz &error_abort); 16838e442810SMax Reitz 16848e442810SMax Reitz for (i = 0; i < 3; i++) { 16858e442810SMax Reitz char name[32]; 16868e442810SMax Reitz snprintf(name, sizeof(name), "parent-node-%i", i); 16878e442810SMax Reitz bs_parents[i] = bdrv_new_open_driver(&bdrv_test, name, BDRV_O_RDWR, 16888e442810SMax Reitz &error_abort); 16898e442810SMax Reitz bdrv_set_backing_hd(bs_parents[i], bs_child, &error_abort); 16908e442810SMax Reitz } 16918e442810SMax Reitz 16928e442810SMax Reitz job = block_job_create("job", &test_drop_backing_job_driver, NULL, 16938e442810SMax Reitz bs_parents[2], 0, BLK_PERM_ALL, 0, 0, NULL, NULL, 16948e442810SMax Reitz &error_abort); 16951b177bbeSVladimir Sementsov-Ogievskiy job->bs = bs_parents[2]; 16968e442810SMax Reitz 16972afdc790SMax Reitz job->detach_also = bs_parents[0]; 16988e442810SMax Reitz job->did_complete = &job_has_completed; 16998e442810SMax Reitz 17008e442810SMax Reitz job_start(&job->common.job); 17018e442810SMax Reitz 17028e442810SMax Reitz job->should_complete = true; 17038e442810SMax Reitz bdrv_drained_begin(bs_child); 17048e442810SMax Reitz g_assert(!job_has_completed); 17058e442810SMax Reitz bdrv_drained_end(bs_child); 17068e442810SMax Reitz g_assert(job_has_completed); 17078e442810SMax Reitz 17088e442810SMax Reitz bdrv_unref(bs_parents[0]); 17098e442810SMax Reitz bdrv_unref(bs_parents[1]); 17108e442810SMax Reitz bdrv_unref(bs_parents[2]); 17118e442810SMax Reitz bdrv_unref(bs_child); 17128e442810SMax Reitz } 17138e442810SMax Reitz 17149746b35cSMax Reitz 17159746b35cSMax Reitz typedef struct TestSimpleBlockJob { 17169746b35cSMax Reitz BlockJob common; 17179746b35cSMax Reitz bool should_complete; 17189746b35cSMax Reitz bool *did_complete; 17199746b35cSMax Reitz } TestSimpleBlockJob; 17209746b35cSMax Reitz 17219746b35cSMax Reitz static int coroutine_fn test_simple_job_run(Job *job, Error **errp) 17229746b35cSMax Reitz { 17239746b35cSMax Reitz TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job); 17249746b35cSMax Reitz 17259746b35cSMax Reitz while (!s->should_complete) { 17269746b35cSMax Reitz job_sleep_ns(job, 0); 17279746b35cSMax Reitz } 17289746b35cSMax Reitz 17299746b35cSMax Reitz return 0; 17309746b35cSMax Reitz } 17319746b35cSMax Reitz 17329746b35cSMax Reitz static void test_simple_job_clean(Job *job) 17339746b35cSMax Reitz { 17349746b35cSMax Reitz TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job); 17359746b35cSMax Reitz *s->did_complete = true; 17369746b35cSMax Reitz } 17379746b35cSMax Reitz 17389746b35cSMax Reitz static const BlockJobDriver test_simple_job_driver = { 17399746b35cSMax Reitz .job_driver = { 17409746b35cSMax Reitz .instance_size = sizeof(TestSimpleBlockJob), 17419746b35cSMax Reitz .free = block_job_free, 17429746b35cSMax Reitz .user_resume = block_job_user_resume, 17439746b35cSMax Reitz .run = test_simple_job_run, 17449746b35cSMax Reitz .clean = test_simple_job_clean, 17459746b35cSMax Reitz }, 17469746b35cSMax Reitz }; 17479746b35cSMax Reitz 17489746b35cSMax Reitz static int drop_intermediate_poll_update_filename(BdrvChild *child, 17499746b35cSMax Reitz BlockDriverState *new_base, 17509746b35cSMax Reitz const char *filename, 17519746b35cSMax Reitz Error **errp) 17529746b35cSMax Reitz { 17539746b35cSMax Reitz /* 17549746b35cSMax Reitz * We are free to poll here, which may change the block graph, if 17559746b35cSMax Reitz * it is not drained. 17569746b35cSMax Reitz */ 17579746b35cSMax Reitz 17589746b35cSMax Reitz /* If the job is not drained: Complete it, schedule job_exit() */ 17599746b35cSMax Reitz aio_poll(qemu_get_current_aio_context(), false); 17609746b35cSMax Reitz /* If the job is not drained: Run job_exit(), finish the job */ 17619746b35cSMax Reitz aio_poll(qemu_get_current_aio_context(), false); 17629746b35cSMax Reitz 17639746b35cSMax Reitz return 0; 17649746b35cSMax Reitz } 17659746b35cSMax Reitz 17669746b35cSMax Reitz /** 17679746b35cSMax Reitz * Test a poll in the midst of bdrv_drop_intermediate(). 17689746b35cSMax Reitz * 1769bd86fb99SMax Reitz * bdrv_drop_intermediate() calls BdrvChildClass.update_filename(), 17709746b35cSMax Reitz * which can yield or poll. This may lead to graph changes, unless 17719746b35cSMax Reitz * the whole subtree in question is drained. 17729746b35cSMax Reitz * 17739746b35cSMax Reitz * We test this on the following graph: 17749746b35cSMax Reitz * 17759746b35cSMax Reitz * Job 17769746b35cSMax Reitz * 17779746b35cSMax Reitz * | 17789746b35cSMax Reitz * job-node 17799746b35cSMax Reitz * | 17809746b35cSMax Reitz * v 17819746b35cSMax Reitz * 17829746b35cSMax Reitz * job-node 17839746b35cSMax Reitz * 17849746b35cSMax Reitz * | 17859746b35cSMax Reitz * backing 17869746b35cSMax Reitz * | 17879746b35cSMax Reitz * v 17889746b35cSMax Reitz * 17899746b35cSMax Reitz * node-2 --chain--> node-1 --chain--> node-0 17909746b35cSMax Reitz * 17919746b35cSMax Reitz * We drop node-1 with bdrv_drop_intermediate(top=node-1, base=node-0). 17929746b35cSMax Reitz * 17939746b35cSMax Reitz * This first updates node-2's backing filename by invoking 17949746b35cSMax Reitz * drop_intermediate_poll_update_filename(), which polls twice. This 17959746b35cSMax Reitz * causes the job to finish, which in turns causes the job-node to be 17969746b35cSMax Reitz * deleted. 17979746b35cSMax Reitz * 17989746b35cSMax Reitz * bdrv_drop_intermediate() uses a QLIST_FOREACH_SAFE() loop, so it 17999746b35cSMax Reitz * already has a pointer to the BdrvChild edge between job-node and 18009746b35cSMax Reitz * node-1. When it tries to handle that edge, we probably get a 18019746b35cSMax Reitz * segmentation fault because the object no longer exists. 18029746b35cSMax Reitz * 18039746b35cSMax Reitz * 18049746b35cSMax Reitz * The solution is for bdrv_drop_intermediate() to drain top's 18059746b35cSMax Reitz * subtree. This prevents graph changes from happening just because 1806bd86fb99SMax Reitz * BdrvChildClass.update_filename() yields or polls. Thus, the block 18079746b35cSMax Reitz * job is paused during that drained section and must finish before or 18089746b35cSMax Reitz * after. 18099746b35cSMax Reitz * 18109746b35cSMax Reitz * (In addition, bdrv_replace_child() must keep the job paused.) 18119746b35cSMax Reitz */ 18129746b35cSMax Reitz static void test_drop_intermediate_poll(void) 18139746b35cSMax Reitz { 1814bd86fb99SMax Reitz static BdrvChildClass chain_child_class; 18159746b35cSMax Reitz BlockDriverState *chain[3]; 18169746b35cSMax Reitz TestSimpleBlockJob *job; 18179746b35cSMax Reitz BlockDriverState *job_node; 18189746b35cSMax Reitz bool job_has_completed = false; 18199746b35cSMax Reitz int i; 18209746b35cSMax Reitz int ret; 18219746b35cSMax Reitz 182225191e5fSMax Reitz chain_child_class = child_of_bds; 1823bd86fb99SMax Reitz chain_child_class.update_filename = drop_intermediate_poll_update_filename; 18249746b35cSMax Reitz 18259746b35cSMax Reitz for (i = 0; i < 3; i++) { 18269746b35cSMax Reitz char name[32]; 18279746b35cSMax Reitz snprintf(name, 32, "node-%i", i); 18289746b35cSMax Reitz 18299746b35cSMax Reitz chain[i] = bdrv_new_open_driver(&bdrv_test, name, 0, &error_abort); 18309746b35cSMax Reitz } 18319746b35cSMax Reitz 18329746b35cSMax Reitz job_node = bdrv_new_open_driver(&bdrv_test, "job-node", BDRV_O_RDWR, 18339746b35cSMax Reitz &error_abort); 18349746b35cSMax Reitz bdrv_set_backing_hd(job_node, chain[1], &error_abort); 18359746b35cSMax Reitz 18369746b35cSMax Reitz /* 18379746b35cSMax Reitz * Establish the chain last, so the chain links are the first 18389746b35cSMax Reitz * elements in the BDS.parents lists 18399746b35cSMax Reitz */ 18409746b35cSMax Reitz for (i = 0; i < 3; i++) { 18419746b35cSMax Reitz if (i) { 18429746b35cSMax Reitz /* Takes the reference to chain[i - 1] */ 18435bb04747SVladimir Sementsov-Ogievskiy bdrv_attach_child(chain[i], chain[i - 1], "chain", 18445bb04747SVladimir Sementsov-Ogievskiy &chain_child_class, BDRV_CHILD_COW, &error_abort); 18459746b35cSMax Reitz } 18469746b35cSMax Reitz } 18479746b35cSMax Reitz 18489746b35cSMax Reitz job = block_job_create("job", &test_simple_job_driver, NULL, job_node, 18499746b35cSMax Reitz 0, BLK_PERM_ALL, 0, 0, NULL, NULL, &error_abort); 18509746b35cSMax Reitz 18519746b35cSMax Reitz /* The job has a reference now */ 18529746b35cSMax Reitz bdrv_unref(job_node); 18539746b35cSMax Reitz 18549746b35cSMax Reitz job->did_complete = &job_has_completed; 18559746b35cSMax Reitz 18569746b35cSMax Reitz job_start(&job->common.job); 18579746b35cSMax Reitz job->should_complete = true; 18589746b35cSMax Reitz 18599746b35cSMax Reitz g_assert(!job_has_completed); 18609746b35cSMax Reitz ret = bdrv_drop_intermediate(chain[1], chain[0], NULL); 18619746b35cSMax Reitz g_assert(ret == 0); 18629746b35cSMax Reitz g_assert(job_has_completed); 18639746b35cSMax Reitz 18649746b35cSMax Reitz bdrv_unref(chain[2]); 18659746b35cSMax Reitz } 18669746b35cSMax Reitz 18670513f984SMax Reitz 18680513f984SMax Reitz typedef struct BDRVReplaceTestState { 18690513f984SMax Reitz bool was_drained; 18700513f984SMax Reitz bool was_undrained; 18710513f984SMax Reitz bool has_read; 18720513f984SMax Reitz 18730513f984SMax Reitz int drain_count; 18740513f984SMax Reitz 18750513f984SMax Reitz bool yield_before_read; 18760513f984SMax Reitz Coroutine *io_co; 18770513f984SMax Reitz Coroutine *drain_co; 18780513f984SMax Reitz } BDRVReplaceTestState; 18790513f984SMax Reitz 18800513f984SMax Reitz static void bdrv_replace_test_close(BlockDriverState *bs) 18810513f984SMax Reitz { 18820513f984SMax Reitz } 18830513f984SMax Reitz 18840513f984SMax Reitz /** 18850513f984SMax Reitz * If @bs has a backing file: 18860513f984SMax Reitz * Yield if .yield_before_read is true (and wait for drain_begin to 18870513f984SMax Reitz * wake us up). 18880513f984SMax Reitz * Forward the read to bs->backing. Set .has_read to true. 18890513f984SMax Reitz * If drain_begin has woken us, wake it in turn. 18900513f984SMax Reitz * 18910513f984SMax Reitz * Otherwise: 18920513f984SMax Reitz * Set .has_read to true and return success. 18930513f984SMax Reitz */ 18940513f984SMax Reitz static int coroutine_fn bdrv_replace_test_co_preadv(BlockDriverState *bs, 1895f7ef38ddSVladimir Sementsov-Ogievskiy int64_t offset, 1896f7ef38ddSVladimir Sementsov-Ogievskiy int64_t bytes, 18970513f984SMax Reitz QEMUIOVector *qiov, 1898f7ef38ddSVladimir Sementsov-Ogievskiy BdrvRequestFlags flags) 18990513f984SMax Reitz { 19000513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 19010513f984SMax Reitz 19020513f984SMax Reitz if (bs->backing) { 19030513f984SMax Reitz int ret; 19040513f984SMax Reitz 19050513f984SMax Reitz g_assert(!s->drain_count); 19060513f984SMax Reitz 19070513f984SMax Reitz s->io_co = qemu_coroutine_self(); 19080513f984SMax Reitz if (s->yield_before_read) { 19090513f984SMax Reitz s->yield_before_read = false; 19100513f984SMax Reitz qemu_coroutine_yield(); 19110513f984SMax Reitz } 19120513f984SMax Reitz s->io_co = NULL; 19130513f984SMax Reitz 1914fae2681aSVladimir Sementsov-Ogievskiy ret = bdrv_co_preadv(bs->backing, offset, bytes, qiov, 0); 19150513f984SMax Reitz s->has_read = true; 19160513f984SMax Reitz 19170513f984SMax Reitz /* Wake up drain_co if it runs */ 19180513f984SMax Reitz if (s->drain_co) { 19190513f984SMax Reitz aio_co_wake(s->drain_co); 19200513f984SMax Reitz } 19210513f984SMax Reitz 19220513f984SMax Reitz return ret; 19230513f984SMax Reitz } 19240513f984SMax Reitz 19250513f984SMax Reitz s->has_read = true; 19260513f984SMax Reitz return 0; 19270513f984SMax Reitz } 19280513f984SMax Reitz 1929*7bce1c29SKevin Wolf static void coroutine_fn bdrv_replace_test_drain_co(void *opaque) 1930*7bce1c29SKevin Wolf { 1931*7bce1c29SKevin Wolf BlockDriverState *bs = opaque; 1932*7bce1c29SKevin Wolf BDRVReplaceTestState *s = bs->opaque; 1933*7bce1c29SKevin Wolf 1934*7bce1c29SKevin Wolf /* Keep waking io_co up until it is done */ 1935*7bce1c29SKevin Wolf while (s->io_co) { 1936*7bce1c29SKevin Wolf aio_co_wake(s->io_co); 1937*7bce1c29SKevin Wolf s->io_co = NULL; 1938*7bce1c29SKevin Wolf qemu_coroutine_yield(); 1939*7bce1c29SKevin Wolf } 1940*7bce1c29SKevin Wolf s->drain_co = NULL; 1941*7bce1c29SKevin Wolf bdrv_dec_in_flight(bs); 1942*7bce1c29SKevin Wolf } 1943*7bce1c29SKevin Wolf 19440513f984SMax Reitz /** 19450513f984SMax Reitz * If .drain_count is 0, wake up .io_co if there is one; and set 19460513f984SMax Reitz * .was_drained. 19470513f984SMax Reitz * Increment .drain_count. 19480513f984SMax Reitz */ 19490513f984SMax Reitz static void coroutine_fn bdrv_replace_test_co_drain_begin(BlockDriverState *bs) 19500513f984SMax Reitz { 19510513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 19520513f984SMax Reitz 19530513f984SMax Reitz if (!s->drain_count) { 1954*7bce1c29SKevin Wolf s->drain_co = qemu_coroutine_create(bdrv_replace_test_drain_co, bs); 1955*7bce1c29SKevin Wolf bdrv_inc_in_flight(bs); 1956*7bce1c29SKevin Wolf aio_co_enter(bdrv_get_aio_context(bs), s->drain_co); 19570513f984SMax Reitz s->was_drained = true; 19580513f984SMax Reitz } 19590513f984SMax Reitz s->drain_count++; 19600513f984SMax Reitz } 19610513f984SMax Reitz 1962*7bce1c29SKevin Wolf static void coroutine_fn bdrv_replace_test_read_entry(void *opaque) 1963*7bce1c29SKevin Wolf { 1964*7bce1c29SKevin Wolf BlockDriverState *bs = opaque; 1965*7bce1c29SKevin Wolf char data; 1966*7bce1c29SKevin Wolf QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, &data, 1); 1967*7bce1c29SKevin Wolf int ret; 1968*7bce1c29SKevin Wolf 1969*7bce1c29SKevin Wolf /* Queue a read request post-drain */ 1970*7bce1c29SKevin Wolf ret = bdrv_replace_test_co_preadv(bs, 0, 1, &qiov, 0); 1971*7bce1c29SKevin Wolf g_assert(ret >= 0); 1972*7bce1c29SKevin Wolf bdrv_dec_in_flight(bs); 1973*7bce1c29SKevin Wolf } 1974*7bce1c29SKevin Wolf 19750513f984SMax Reitz /** 19760513f984SMax Reitz * Reduce .drain_count, set .was_undrained once it reaches 0. 19770513f984SMax Reitz * If .drain_count reaches 0 and the node has a backing file, issue a 19780513f984SMax Reitz * read request. 19790513f984SMax Reitz */ 19800513f984SMax Reitz static void coroutine_fn bdrv_replace_test_co_drain_end(BlockDriverState *bs) 19810513f984SMax Reitz { 19820513f984SMax Reitz BDRVReplaceTestState *s = bs->opaque; 19830513f984SMax Reitz 19840513f984SMax Reitz g_assert(s->drain_count > 0); 19850513f984SMax Reitz if (!--s->drain_count) { 19860513f984SMax Reitz s->was_undrained = true; 19870513f984SMax Reitz 19880513f984SMax Reitz if (bs->backing) { 1989*7bce1c29SKevin Wolf Coroutine *co = qemu_coroutine_create(bdrv_replace_test_read_entry, 1990*7bce1c29SKevin Wolf bs); 1991*7bce1c29SKevin Wolf bdrv_inc_in_flight(bs); 1992*7bce1c29SKevin Wolf aio_co_enter(bdrv_get_aio_context(bs), co); 19930513f984SMax Reitz } 19940513f984SMax Reitz } 19950513f984SMax Reitz } 19960513f984SMax Reitz 19970513f984SMax Reitz static BlockDriver bdrv_replace_test = { 19980513f984SMax Reitz .format_name = "replace_test", 19990513f984SMax Reitz .instance_size = sizeof(BDRVReplaceTestState), 20009ebfc111SVladimir Sementsov-Ogievskiy .supports_backing = true, 20010513f984SMax Reitz 20020513f984SMax Reitz .bdrv_close = bdrv_replace_test_close, 20030513f984SMax Reitz .bdrv_co_preadv = bdrv_replace_test_co_preadv, 20040513f984SMax Reitz 20050513f984SMax Reitz .bdrv_co_drain_begin = bdrv_replace_test_co_drain_begin, 20060513f984SMax Reitz .bdrv_co_drain_end = bdrv_replace_test_co_drain_end, 20070513f984SMax Reitz 200869dca43dSMax Reitz .bdrv_child_perm = bdrv_default_perms, 20090513f984SMax Reitz }; 20100513f984SMax Reitz 20110513f984SMax Reitz static void coroutine_fn test_replace_child_mid_drain_read_co(void *opaque) 20120513f984SMax Reitz { 20130513f984SMax Reitz int ret; 20140513f984SMax Reitz char data; 20150513f984SMax Reitz 20160513f984SMax Reitz ret = blk_co_pread(opaque, 0, 1, &data, 0); 20170513f984SMax Reitz g_assert(ret >= 0); 20180513f984SMax Reitz } 20190513f984SMax Reitz 20200513f984SMax Reitz /** 20210513f984SMax Reitz * We test two things: 20220513f984SMax Reitz * (1) bdrv_replace_child_noperm() must not undrain the parent if both 20230513f984SMax Reitz * children are drained. 20240513f984SMax Reitz * (2) bdrv_replace_child_noperm() must never flush I/O requests to a 20250513f984SMax Reitz * drained child. If the old child is drained, it must flush I/O 20260513f984SMax Reitz * requests after the new one has been attached. If the new child 20270513f984SMax Reitz * is drained, it must flush I/O requests before the old one is 20280513f984SMax Reitz * detached. 20290513f984SMax Reitz * 20300513f984SMax Reitz * To do so, we create one parent node and two child nodes; then 20310513f984SMax Reitz * attach one of the children (old_child_bs) to the parent, then 20320513f984SMax Reitz * drain both old_child_bs and new_child_bs according to 20330513f984SMax Reitz * old_drain_count and new_drain_count, respectively, and finally 20340513f984SMax Reitz * we invoke bdrv_replace_node() to replace old_child_bs by 20350513f984SMax Reitz * new_child_bs. 20360513f984SMax Reitz * 20370513f984SMax Reitz * The test block driver we use here (bdrv_replace_test) has a read 20380513f984SMax Reitz * function that: 20390513f984SMax Reitz * - For the parent node, can optionally yield, and then forwards the 20400513f984SMax Reitz * read to bdrv_preadv(), 20410513f984SMax Reitz * - For the child node, just returns immediately. 20420513f984SMax Reitz * 20430513f984SMax Reitz * If the read yields, the drain_begin function will wake it up. 20440513f984SMax Reitz * 20450513f984SMax Reitz * The drain_end function issues a read on the parent once it is fully 20460513f984SMax Reitz * undrained (which simulates requests starting to come in again). 20470513f984SMax Reitz */ 20480513f984SMax Reitz static void do_test_replace_child_mid_drain(int old_drain_count, 20490513f984SMax Reitz int new_drain_count) 20500513f984SMax Reitz { 20510513f984SMax Reitz BlockBackend *parent_blk; 20520513f984SMax Reitz BlockDriverState *parent_bs; 20530513f984SMax Reitz BlockDriverState *old_child_bs, *new_child_bs; 20540513f984SMax Reitz BDRVReplaceTestState *parent_s; 20550513f984SMax Reitz BDRVReplaceTestState *old_child_s, *new_child_s; 20560513f984SMax Reitz Coroutine *io_co; 20570513f984SMax Reitz int i; 20580513f984SMax Reitz 20590513f984SMax Reitz parent_bs = bdrv_new_open_driver(&bdrv_replace_test, "parent", 0, 20600513f984SMax Reitz &error_abort); 20610513f984SMax Reitz parent_s = parent_bs->opaque; 20620513f984SMax Reitz 20630513f984SMax Reitz parent_blk = blk_new(qemu_get_aio_context(), 20640513f984SMax Reitz BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL); 20650513f984SMax Reitz blk_insert_bs(parent_blk, parent_bs, &error_abort); 20660513f984SMax Reitz 20670513f984SMax Reitz old_child_bs = bdrv_new_open_driver(&bdrv_replace_test, "old-child", 0, 20680513f984SMax Reitz &error_abort); 20690513f984SMax Reitz new_child_bs = bdrv_new_open_driver(&bdrv_replace_test, "new-child", 0, 20700513f984SMax Reitz &error_abort); 20710513f984SMax Reitz old_child_s = old_child_bs->opaque; 20720513f984SMax Reitz new_child_s = new_child_bs->opaque; 20730513f984SMax Reitz 20740513f984SMax Reitz /* So that we can read something */ 20750513f984SMax Reitz parent_bs->total_sectors = 1; 20760513f984SMax Reitz old_child_bs->total_sectors = 1; 20770513f984SMax Reitz new_child_bs->total_sectors = 1; 20780513f984SMax Reitz 20790513f984SMax Reitz bdrv_ref(old_child_bs); 20805bb04747SVladimir Sementsov-Ogievskiy bdrv_attach_child(parent_bs, old_child_bs, "child", &child_of_bds, 20815bb04747SVladimir Sementsov-Ogievskiy BDRV_CHILD_COW, &error_abort); 20820513f984SMax Reitz 20830513f984SMax Reitz for (i = 0; i < old_drain_count; i++) { 20840513f984SMax Reitz bdrv_drained_begin(old_child_bs); 20850513f984SMax Reitz } 20860513f984SMax Reitz for (i = 0; i < new_drain_count; i++) { 20870513f984SMax Reitz bdrv_drained_begin(new_child_bs); 20880513f984SMax Reitz } 20890513f984SMax Reitz 20900513f984SMax Reitz if (!old_drain_count) { 20910513f984SMax Reitz /* 20920513f984SMax Reitz * Start a read operation that will yield, so it will not 20930513f984SMax Reitz * complete before the node is drained. 20940513f984SMax Reitz */ 20950513f984SMax Reitz parent_s->yield_before_read = true; 20960513f984SMax Reitz io_co = qemu_coroutine_create(test_replace_child_mid_drain_read_co, 20970513f984SMax Reitz parent_blk); 20980513f984SMax Reitz qemu_coroutine_enter(io_co); 20990513f984SMax Reitz } 21000513f984SMax Reitz 21010513f984SMax Reitz /* If we have started a read operation, it should have yielded */ 21020513f984SMax Reitz g_assert(!parent_s->has_read); 21030513f984SMax Reitz 21040513f984SMax Reitz /* Reset drained status so we can see what bdrv_replace_node() does */ 21050513f984SMax Reitz parent_s->was_drained = false; 21060513f984SMax Reitz parent_s->was_undrained = false; 21070513f984SMax Reitz 21080513f984SMax Reitz g_assert(parent_bs->quiesce_counter == old_drain_count); 21090513f984SMax Reitz bdrv_replace_node(old_child_bs, new_child_bs, &error_abort); 21100513f984SMax Reitz g_assert(parent_bs->quiesce_counter == new_drain_count); 21110513f984SMax Reitz 21120513f984SMax Reitz if (!old_drain_count && !new_drain_count) { 21130513f984SMax Reitz /* 21140513f984SMax Reitz * From undrained to undrained drains and undrains the parent, 21150513f984SMax Reitz * because bdrv_replace_node() contains a drained section for 21160513f984SMax Reitz * @old_child_bs. 21170513f984SMax Reitz */ 21180513f984SMax Reitz g_assert(parent_s->was_drained && parent_s->was_undrained); 21190513f984SMax Reitz } else if (!old_drain_count && new_drain_count) { 21200513f984SMax Reitz /* 21210513f984SMax Reitz * From undrained to drained should drain the parent and keep 21220513f984SMax Reitz * it that way. 21230513f984SMax Reitz */ 21240513f984SMax Reitz g_assert(parent_s->was_drained && !parent_s->was_undrained); 21250513f984SMax Reitz } else if (old_drain_count && !new_drain_count) { 21260513f984SMax Reitz /* 21270513f984SMax Reitz * From drained to undrained should undrain the parent and 21280513f984SMax Reitz * keep it that way. 21290513f984SMax Reitz */ 21300513f984SMax Reitz g_assert(!parent_s->was_drained && parent_s->was_undrained); 21310513f984SMax Reitz } else /* if (old_drain_count && new_drain_count) */ { 21320513f984SMax Reitz /* 21330513f984SMax Reitz * From drained to drained must not undrain the parent at any 21340513f984SMax Reitz * point 21350513f984SMax Reitz */ 21360513f984SMax Reitz g_assert(!parent_s->was_drained && !parent_s->was_undrained); 21370513f984SMax Reitz } 21380513f984SMax Reitz 21390513f984SMax Reitz if (!old_drain_count || !new_drain_count) { 21400513f984SMax Reitz /* 21410513f984SMax Reitz * If !old_drain_count, we have started a read request before 21420513f984SMax Reitz * bdrv_replace_node(). If !new_drain_count, the parent must 21430513f984SMax Reitz * have been undrained at some point, and 21440513f984SMax Reitz * bdrv_replace_test_co_drain_end() starts a read request 21450513f984SMax Reitz * then. 21460513f984SMax Reitz */ 21470513f984SMax Reitz g_assert(parent_s->has_read); 21480513f984SMax Reitz } else { 21490513f984SMax Reitz /* 21500513f984SMax Reitz * If the parent was never undrained, there is no way to start 21510513f984SMax Reitz * a read request. 21520513f984SMax Reitz */ 21530513f984SMax Reitz g_assert(!parent_s->has_read); 21540513f984SMax Reitz } 21550513f984SMax Reitz 21560513f984SMax Reitz /* A drained child must have not received any request */ 21570513f984SMax Reitz g_assert(!(old_drain_count && old_child_s->has_read)); 21580513f984SMax Reitz g_assert(!(new_drain_count && new_child_s->has_read)); 21590513f984SMax Reitz 21600513f984SMax Reitz for (i = 0; i < new_drain_count; i++) { 21610513f984SMax Reitz bdrv_drained_end(new_child_bs); 21620513f984SMax Reitz } 21630513f984SMax Reitz for (i = 0; i < old_drain_count; i++) { 21640513f984SMax Reitz bdrv_drained_end(old_child_bs); 21650513f984SMax Reitz } 21660513f984SMax Reitz 21670513f984SMax Reitz /* 21680513f984SMax Reitz * By now, bdrv_replace_test_co_drain_end() must have been called 21690513f984SMax Reitz * at some point while the new child was attached to the parent. 21700513f984SMax Reitz */ 21710513f984SMax Reitz g_assert(parent_s->has_read); 21720513f984SMax Reitz g_assert(new_child_s->has_read); 21730513f984SMax Reitz 21740513f984SMax Reitz blk_unref(parent_blk); 21750513f984SMax Reitz bdrv_unref(parent_bs); 21760513f984SMax Reitz bdrv_unref(old_child_bs); 21770513f984SMax Reitz bdrv_unref(new_child_bs); 21780513f984SMax Reitz } 21790513f984SMax Reitz 21800513f984SMax Reitz static void test_replace_child_mid_drain(void) 21810513f984SMax Reitz { 21820513f984SMax Reitz int old_drain_count, new_drain_count; 21830513f984SMax Reitz 21840513f984SMax Reitz for (old_drain_count = 0; old_drain_count < 2; old_drain_count++) { 21850513f984SMax Reitz for (new_drain_count = 0; new_drain_count < 2; new_drain_count++) { 21860513f984SMax Reitz do_test_replace_child_mid_drain(old_drain_count, new_drain_count); 21870513f984SMax Reitz } 21880513f984SMax Reitz } 21890513f984SMax Reitz } 21900513f984SMax Reitz 2191881cfd17SKevin Wolf int main(int argc, char **argv) 2192881cfd17SKevin Wolf { 2193bb675689SKevin Wolf int ret; 2194bb675689SKevin Wolf 2195881cfd17SKevin Wolf bdrv_init(); 2196881cfd17SKevin Wolf qemu_init_main_loop(&error_abort); 2197881cfd17SKevin Wolf 2198881cfd17SKevin Wolf g_test_init(&argc, &argv, NULL); 2199bb675689SKevin Wolf qemu_event_init(&done_event, false); 2200881cfd17SKevin Wolf 2201881cfd17SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all); 220286e1c840SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain); 2203d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/drain_subtree", 2204d2a85d0fSKevin Wolf test_drv_cb_drain_subtree); 2205881cfd17SKevin Wolf 22066d0252f2SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain_all", 22076d0252f2SKevin Wolf test_drv_cb_co_drain_all); 22080582eb10SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain", test_drv_cb_co_drain); 22090582eb10SKevin Wolf g_test_add_func("/bdrv-drain/driver-cb/co/drain_subtree", 22100582eb10SKevin Wolf test_drv_cb_co_drain_subtree); 22110582eb10SKevin Wolf 22120582eb10SKevin Wolf 221389a6ceabSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all); 221489a6ceabSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain); 2215d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/quiesce/drain_subtree", 2216d2a85d0fSKevin Wolf test_quiesce_drain_subtree); 221789a6ceabSKevin Wolf 22186d0252f2SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain_all", 22196d0252f2SKevin Wolf test_quiesce_co_drain_all); 22200582eb10SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain", test_quiesce_co_drain); 22210582eb10SKevin Wolf g_test_add_func("/bdrv-drain/quiesce/co/drain_subtree", 22220582eb10SKevin Wolf test_quiesce_co_drain_subtree); 22230582eb10SKevin Wolf 22246c429a6aSKevin Wolf g_test_add_func("/bdrv-drain/nested", test_nested); 222527e64474SKevin Wolf g_test_add_func("/bdrv-drain/multiparent", test_multiparent); 222619f7a7e5SKevin Wolf 222719f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/graph-change/drain_subtree", 222819f7a7e5SKevin Wolf test_graph_change_drain_subtree); 222919f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/graph-change/drain_all", 223019f7a7e5SKevin Wolf test_graph_change_drain_all); 22316c429a6aSKevin Wolf 2232bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain_all", test_iothread_drain_all); 2233bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain", test_iothread_drain); 2234bb675689SKevin Wolf g_test_add_func("/bdrv-drain/iothread/drain_subtree", 2235bb675689SKevin Wolf test_iothread_drain_subtree); 2236bb675689SKevin Wolf 22377253220dSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all); 22387253220dSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain); 2239d2a85d0fSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/drain_subtree", 2240d2a85d0fSKevin Wolf test_blockjob_drain_subtree); 22417253220dSKevin Wolf 2242d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain_all", 2243d49725afSKevin Wolf test_blockjob_error_drain_all); 2244d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain", 2245d49725afSKevin Wolf test_blockjob_error_drain); 2246d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/error/drain_subtree", 2247d49725afSKevin Wolf test_blockjob_error_drain_subtree); 2248d49725afSKevin Wolf 2249f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain_all", 2250f62c1729SKevin Wolf test_blockjob_iothread_drain_all); 2251f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain", 2252f62c1729SKevin Wolf test_blockjob_iothread_drain); 2253f62c1729SKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/drain_subtree", 2254f62c1729SKevin Wolf test_blockjob_iothread_drain_subtree); 2255f62c1729SKevin Wolf 2256d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_all", 2257d49725afSKevin Wolf test_blockjob_iothread_error_drain_all); 2258d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain", 2259d49725afSKevin Wolf test_blockjob_iothread_error_drain); 2260d49725afSKevin Wolf g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_subtree", 2261d49725afSKevin Wolf test_blockjob_iothread_error_drain_subtree); 2262d49725afSKevin Wolf 2263ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/deletion/drain", test_delete_by_drain); 226419f7a7e5SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain_all", test_detach_by_drain_all); 2265ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain", test_detach_by_drain); 2266ebd31837SKevin Wolf g_test_add_func("/bdrv-drain/detach/drain_subtree", test_detach_by_drain_subtree); 2267231281abSKevin Wolf g_test_add_func("/bdrv-drain/detach/parent_cb", test_detach_by_parent_cb); 226857320ca9SKevin Wolf g_test_add_func("/bdrv-drain/detach/driver_cb", test_detach_by_driver_cb); 22694c8158e3SMax Reitz 2270b994c5bcSKevin Wolf g_test_add_func("/bdrv-drain/attach/drain", test_append_to_drained); 2271b994c5bcSKevin Wolf 2272247d2737SKevin Wolf g_test_add_func("/bdrv-drain/set_aio_context", test_set_aio_context); 2273247d2737SKevin Wolf 22748e442810SMax Reitz g_test_add_func("/bdrv-drain/blockjob/commit_by_drained_end", 22758e442810SMax Reitz test_blockjob_commit_by_drained_end); 22768e442810SMax Reitz 22779746b35cSMax Reitz g_test_add_func("/bdrv-drain/bdrv_drop_intermediate/poll", 22789746b35cSMax Reitz test_drop_intermediate_poll); 22799746b35cSMax Reitz 22800513f984SMax Reitz g_test_add_func("/bdrv-drain/replace_child/mid-drain", 22810513f984SMax Reitz test_replace_child_mid_drain); 22820513f984SMax Reitz 2283bb675689SKevin Wolf ret = g_test_run(); 2284bb675689SKevin Wolf qemu_event_destroy(&done_event); 2285bb675689SKevin Wolf return ret; 2286881cfd17SKevin Wolf } 2287