2 * Block node draining tests
4 * Copyright (c) 2017 Kevin Wolf <kwolf@redhat.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 #include "qemu/osdep.h"
26 #include "block/block.h"
27 #include "sysemu/block-backend.h"
28 #include "qapi/error.h"
30 typedef struct BDRVTestState
{
34 static void coroutine_fn
bdrv_test_co_drain_begin(BlockDriverState
*bs
)
36 BDRVTestState
*s
= bs
->opaque
;
40 static void coroutine_fn
bdrv_test_co_drain_end(BlockDriverState
*bs
)
42 BDRVTestState
*s
= bs
->opaque
;
46 static void bdrv_test_close(BlockDriverState
*bs
)
48 BDRVTestState
*s
= bs
->opaque
;
49 g_assert_cmpint(s
->drain_count
, >, 0);
52 static int coroutine_fn
bdrv_test_co_preadv(BlockDriverState
*bs
,
53 uint64_t offset
, uint64_t bytes
,
54 QEMUIOVector
*qiov
, int flags
)
56 /* We want this request to stay until the polling loop in drain waits for
57 * it to complete. We need to sleep a while as bdrv_drain_invoke() comes
58 * first and polls its result, too, but it shouldn't accidentally complete
59 * this request yet. */
60 qemu_co_sleep_ns(QEMU_CLOCK_REALTIME
, 100000);
65 static BlockDriver bdrv_test
= {
66 .format_name
= "test",
67 .instance_size
= sizeof(BDRVTestState
),
69 .bdrv_close
= bdrv_test_close
,
70 .bdrv_co_preadv
= bdrv_test_co_preadv
,
72 .bdrv_co_drain_begin
= bdrv_test_co_drain_begin
,
73 .bdrv_co_drain_end
= bdrv_test_co_drain_end
,
75 .bdrv_child_perm
= bdrv_format_default_perms
,
78 static void aio_ret_cb(void *opaque
, int ret
)
80 int *aio_ret
= opaque
;
89 static void do_drain_begin(enum drain_type drain_type
, BlockDriverState
*bs
)
92 case BDRV_DRAIN_ALL
: bdrv_drain_all_begin(); break;
93 case BDRV_DRAIN
: bdrv_drained_begin(bs
); break;
94 default: g_assert_not_reached();
98 static void do_drain_end(enum drain_type drain_type
, BlockDriverState
*bs
)
100 switch (drain_type
) {
101 case BDRV_DRAIN_ALL
: bdrv_drain_all_end(); break;
102 case BDRV_DRAIN
: bdrv_drained_end(bs
); break;
103 default: g_assert_not_reached();
107 static void test_drv_cb_common(enum drain_type drain_type
, bool recursive
)
110 BlockDriverState
*bs
, *backing
;
111 BDRVTestState
*s
, *backing_s
;
120 qemu_iovec_init_external(&qiov
, &iov
, 1);
122 blk
= blk_new(BLK_PERM_ALL
, BLK_PERM_ALL
);
123 bs
= bdrv_new_open_driver(&bdrv_test
, "test-node", BDRV_O_RDWR
,
126 blk_insert_bs(blk
, bs
, &error_abort
);
128 backing
= bdrv_new_open_driver(&bdrv_test
, "backing", 0, &error_abort
);
129 backing_s
= backing
->opaque
;
130 bdrv_set_backing_hd(bs
, backing
, &error_abort
);
132 /* Simple bdrv_drain_all_begin/end pair, check that CBs are called */
133 g_assert_cmpint(s
->drain_count
, ==, 0);
134 g_assert_cmpint(backing_s
->drain_count
, ==, 0);
136 do_drain_begin(drain_type
, bs
);
138 g_assert_cmpint(s
->drain_count
, ==, 1);
139 g_assert_cmpint(backing_s
->drain_count
, ==, !!recursive
);
141 do_drain_end(drain_type
, bs
);
143 g_assert_cmpint(s
->drain_count
, ==, 0);
144 g_assert_cmpint(backing_s
->drain_count
, ==, 0);
146 /* Now do the same while a request is pending */
147 aio_ret
= -EINPROGRESS
;
148 acb
= blk_aio_preadv(blk
, 0, &qiov
, 0, aio_ret_cb
, &aio_ret
);
149 g_assert(acb
!= NULL
);
150 g_assert_cmpint(aio_ret
, ==, -EINPROGRESS
);
152 g_assert_cmpint(s
->drain_count
, ==, 0);
153 g_assert_cmpint(backing_s
->drain_count
, ==, 0);
155 do_drain_begin(drain_type
, bs
);
157 g_assert_cmpint(aio_ret
, ==, 0);
158 g_assert_cmpint(s
->drain_count
, ==, 1);
159 g_assert_cmpint(backing_s
->drain_count
, ==, !!recursive
);
161 do_drain_end(drain_type
, bs
);
163 g_assert_cmpint(s
->drain_count
, ==, 0);
164 g_assert_cmpint(backing_s
->drain_count
, ==, 0);
171 static void test_drv_cb_drain_all(void)
173 test_drv_cb_common(BDRV_DRAIN_ALL
, true);
176 static void test_drv_cb_drain(void)
178 test_drv_cb_common(BDRV_DRAIN
, false);
181 static void test_quiesce_common(enum drain_type drain_type
, bool recursive
)
184 BlockDriverState
*bs
, *backing
;
186 blk
= blk_new(BLK_PERM_ALL
, BLK_PERM_ALL
);
187 bs
= bdrv_new_open_driver(&bdrv_test
, "test-node", BDRV_O_RDWR
,
189 blk_insert_bs(blk
, bs
, &error_abort
);
191 backing
= bdrv_new_open_driver(&bdrv_test
, "backing", 0, &error_abort
);
192 bdrv_set_backing_hd(bs
, backing
, &error_abort
);
194 g_assert_cmpint(bs
->quiesce_counter
, ==, 0);
195 g_assert_cmpint(backing
->quiesce_counter
, ==, 0);
197 do_drain_begin(drain_type
, bs
);
199 g_assert_cmpint(bs
->quiesce_counter
, ==, 1);
200 g_assert_cmpint(backing
->quiesce_counter
, ==, !!recursive
);
202 do_drain_end(drain_type
, bs
);
204 g_assert_cmpint(bs
->quiesce_counter
, ==, 0);
205 g_assert_cmpint(backing
->quiesce_counter
, ==, 0);
212 static void test_quiesce_drain_all(void)
214 // XXX drain_all doesn't quiesce
215 //test_quiesce_common(BDRV_DRAIN_ALL, true);
218 static void test_quiesce_drain(void)
220 test_quiesce_common(BDRV_DRAIN
, false);
223 int main(int argc
, char **argv
)
226 qemu_init_main_loop(&error_abort
);
228 g_test_init(&argc
, &argv
, NULL
);
230 g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all
);
231 g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain
);
233 g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all
);
234 g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain
);