]> git.proxmox.com Git - mirror_qemu.git/blame - tests/test-bdrv-drain.c
block: Avoid unnecessary aio_poll() in AIO_WAIT_WHILE()
[mirror_qemu.git] / tests / test-bdrv-drain.c
CommitLineData
881cfd17
KW
1/*
2 * Block node draining tests
3 *
4 * Copyright (c) 2017 Kevin Wolf <kwolf@redhat.com>
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
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
22 * THE SOFTWARE.
23 */
24
25#include "qemu/osdep.h"
26#include "block/block.h"
7253220d 27#include "block/blockjob_int.h"
881cfd17
KW
28#include "sysemu/block-backend.h"
29#include "qapi/error.h"
bb675689
KW
30#include "iothread.h"
31
32static QemuEvent done_event;
881cfd17
KW
33
34typedef struct BDRVTestState {
35 int drain_count;
bb675689 36 AioContext *bh_indirection_ctx;
881cfd17
KW
37} BDRVTestState;
38
39static void coroutine_fn bdrv_test_co_drain_begin(BlockDriverState *bs)
40{
41 BDRVTestState *s = bs->opaque;
42 s->drain_count++;
43}
44
45static void coroutine_fn bdrv_test_co_drain_end(BlockDriverState *bs)
46{
47 BDRVTestState *s = bs->opaque;
48 s->drain_count--;
49}
50
51static void bdrv_test_close(BlockDriverState *bs)
52{
53 BDRVTestState *s = bs->opaque;
54 g_assert_cmpint(s->drain_count, >, 0);
55}
56
bb675689
KW
57static void co_reenter_bh(void *opaque)
58{
59 aio_co_wake(opaque);
60}
61
881cfd17
KW
62static int coroutine_fn bdrv_test_co_preadv(BlockDriverState *bs,
63 uint64_t offset, uint64_t bytes,
64 QEMUIOVector *qiov, int flags)
65{
bb675689
KW
66 BDRVTestState *s = bs->opaque;
67
881cfd17
KW
68 /* We want this request to stay until the polling loop in drain waits for
69 * it to complete. We need to sleep a while as bdrv_drain_invoke() comes
70 * first and polls its result, too, but it shouldn't accidentally complete
71 * this request yet. */
72 qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000);
73
bb675689
KW
74 if (s->bh_indirection_ctx) {
75 aio_bh_schedule_oneshot(s->bh_indirection_ctx, co_reenter_bh,
76 qemu_coroutine_self());
77 qemu_coroutine_yield();
78 }
79
881cfd17
KW
80 return 0;
81}
82
83static BlockDriver bdrv_test = {
84 .format_name = "test",
85 .instance_size = sizeof(BDRVTestState),
86
87 .bdrv_close = bdrv_test_close,
88 .bdrv_co_preadv = bdrv_test_co_preadv,
89
90 .bdrv_co_drain_begin = bdrv_test_co_drain_begin,
91 .bdrv_co_drain_end = bdrv_test_co_drain_end,
86e1c840
KW
92
93 .bdrv_child_perm = bdrv_format_default_perms,
881cfd17
KW
94};
95
96static void aio_ret_cb(void *opaque, int ret)
97{
98 int *aio_ret = opaque;
99 *aio_ret = ret;
100}
101
0582eb10
KW
102typedef struct CallInCoroutineData {
103 void (*entry)(void);
104 bool done;
105} CallInCoroutineData;
106
107static coroutine_fn void call_in_coroutine_entry(void *opaque)
108{
109 CallInCoroutineData *data = opaque;
110
111 data->entry();
112 data->done = true;
113}
114
115static void call_in_coroutine(void (*entry)(void))
116{
117 Coroutine *co;
118 CallInCoroutineData data = {
119 .entry = entry,
120 .done = false,
121 };
122
123 co = qemu_coroutine_create(call_in_coroutine_entry, &data);
124 qemu_coroutine_enter(co);
125 while (!data.done) {
126 aio_poll(qemu_get_aio_context(), true);
127 }
128}
129
86e1c840
KW
130enum drain_type {
131 BDRV_DRAIN_ALL,
132 BDRV_DRAIN,
d2a85d0f 133 BDRV_SUBTREE_DRAIN,
6c429a6a 134 DRAIN_TYPE_MAX,
86e1c840
KW
135};
136
137static void do_drain_begin(enum drain_type drain_type, BlockDriverState *bs)
138{
139 switch (drain_type) {
140 case BDRV_DRAIN_ALL: bdrv_drain_all_begin(); break;
141 case BDRV_DRAIN: bdrv_drained_begin(bs); break;
d2a85d0f 142 case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_begin(bs); break;
86e1c840
KW
143 default: g_assert_not_reached();
144 }
145}
146
147static void do_drain_end(enum drain_type drain_type, BlockDriverState *bs)
148{
149 switch (drain_type) {
150 case BDRV_DRAIN_ALL: bdrv_drain_all_end(); break;
151 case BDRV_DRAIN: bdrv_drained_end(bs); break;
d2a85d0f 152 case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_end(bs); break;
86e1c840
KW
153 default: g_assert_not_reached();
154 }
155}
156
157static void test_drv_cb_common(enum drain_type drain_type, bool recursive)
881cfd17
KW
158{
159 BlockBackend *blk;
86e1c840
KW
160 BlockDriverState *bs, *backing;
161 BDRVTestState *s, *backing_s;
881cfd17
KW
162 BlockAIOCB *acb;
163 int aio_ret;
164
165 QEMUIOVector qiov;
166 struct iovec iov = {
167 .iov_base = NULL,
168 .iov_len = 0,
169 };
170 qemu_iovec_init_external(&qiov, &iov, 1);
171
172 blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
173 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
174 &error_abort);
175 s = bs->opaque;
176 blk_insert_bs(blk, bs, &error_abort);
177
86e1c840
KW
178 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
179 backing_s = backing->opaque;
180 bdrv_set_backing_hd(bs, backing, &error_abort);
181
881cfd17
KW
182 /* Simple bdrv_drain_all_begin/end pair, check that CBs are called */
183 g_assert_cmpint(s->drain_count, ==, 0);
86e1c840
KW
184 g_assert_cmpint(backing_s->drain_count, ==, 0);
185
186 do_drain_begin(drain_type, bs);
187
881cfd17 188 g_assert_cmpint(s->drain_count, ==, 1);
86e1c840
KW
189 g_assert_cmpint(backing_s->drain_count, ==, !!recursive);
190
191 do_drain_end(drain_type, bs);
192
881cfd17 193 g_assert_cmpint(s->drain_count, ==, 0);
86e1c840 194 g_assert_cmpint(backing_s->drain_count, ==, 0);
881cfd17
KW
195
196 /* Now do the same while a request is pending */
197 aio_ret = -EINPROGRESS;
198 acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret);
199 g_assert(acb != NULL);
200 g_assert_cmpint(aio_ret, ==, -EINPROGRESS);
201
202 g_assert_cmpint(s->drain_count, ==, 0);
86e1c840
KW
203 g_assert_cmpint(backing_s->drain_count, ==, 0);
204
205 do_drain_begin(drain_type, bs);
206
881cfd17
KW
207 g_assert_cmpint(aio_ret, ==, 0);
208 g_assert_cmpint(s->drain_count, ==, 1);
86e1c840
KW
209 g_assert_cmpint(backing_s->drain_count, ==, !!recursive);
210
211 do_drain_end(drain_type, bs);
212
881cfd17 213 g_assert_cmpint(s->drain_count, ==, 0);
86e1c840 214 g_assert_cmpint(backing_s->drain_count, ==, 0);
881cfd17 215
86e1c840 216 bdrv_unref(backing);
881cfd17
KW
217 bdrv_unref(bs);
218 blk_unref(blk);
219}
220
86e1c840
KW
221static void test_drv_cb_drain_all(void)
222{
223 test_drv_cb_common(BDRV_DRAIN_ALL, true);
224}
225
226static void test_drv_cb_drain(void)
227{
228 test_drv_cb_common(BDRV_DRAIN, false);
229}
230
d2a85d0f
KW
231static void test_drv_cb_drain_subtree(void)
232{
233 test_drv_cb_common(BDRV_SUBTREE_DRAIN, true);
234}
235
6d0252f2
KW
236static void test_drv_cb_co_drain_all(void)
237{
238 call_in_coroutine(test_drv_cb_drain_all);
239}
240
0582eb10
KW
241static void test_drv_cb_co_drain(void)
242{
243 call_in_coroutine(test_drv_cb_drain);
244}
245
246static void test_drv_cb_co_drain_subtree(void)
247{
248 call_in_coroutine(test_drv_cb_drain_subtree);
249}
250
89a6ceab
KW
251static void test_quiesce_common(enum drain_type drain_type, bool recursive)
252{
253 BlockBackend *blk;
254 BlockDriverState *bs, *backing;
255
256 blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
257 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
258 &error_abort);
259 blk_insert_bs(blk, bs, &error_abort);
260
261 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
262 bdrv_set_backing_hd(bs, backing, &error_abort);
263
264 g_assert_cmpint(bs->quiesce_counter, ==, 0);
265 g_assert_cmpint(backing->quiesce_counter, ==, 0);
266
267 do_drain_begin(drain_type, bs);
268
269 g_assert_cmpint(bs->quiesce_counter, ==, 1);
270 g_assert_cmpint(backing->quiesce_counter, ==, !!recursive);
271
272 do_drain_end(drain_type, bs);
273
274 g_assert_cmpint(bs->quiesce_counter, ==, 0);
275 g_assert_cmpint(backing->quiesce_counter, ==, 0);
276
277 bdrv_unref(backing);
278 bdrv_unref(bs);
279 blk_unref(blk);
280}
281
282static void test_quiesce_drain_all(void)
283{
79ab8b21 284 test_quiesce_common(BDRV_DRAIN_ALL, true);
89a6ceab
KW
285}
286
287static void test_quiesce_drain(void)
288{
289 test_quiesce_common(BDRV_DRAIN, false);
290}
291
d2a85d0f
KW
292static void test_quiesce_drain_subtree(void)
293{
294 test_quiesce_common(BDRV_SUBTREE_DRAIN, true);
295}
296
6d0252f2
KW
297static void test_quiesce_co_drain_all(void)
298{
299 call_in_coroutine(test_quiesce_drain_all);
300}
301
0582eb10
KW
302static void test_quiesce_co_drain(void)
303{
304 call_in_coroutine(test_quiesce_drain);
305}
306
307static void test_quiesce_co_drain_subtree(void)
308{
309 call_in_coroutine(test_quiesce_drain_subtree);
310}
311
6c429a6a
KW
312static void test_nested(void)
313{
314 BlockBackend *blk;
315 BlockDriverState *bs, *backing;
316 BDRVTestState *s, *backing_s;
317 enum drain_type outer, inner;
318
319 blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
320 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
321 &error_abort);
322 s = bs->opaque;
323 blk_insert_bs(blk, bs, &error_abort);
324
325 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
326 backing_s = backing->opaque;
327 bdrv_set_backing_hd(bs, backing, &error_abort);
328
329 for (outer = 0; outer < DRAIN_TYPE_MAX; outer++) {
330 for (inner = 0; inner < DRAIN_TYPE_MAX; inner++) {
79ab8b21 331 int backing_quiesce = (outer != BDRV_DRAIN) +
6c429a6a
KW
332 (inner != BDRV_DRAIN);
333
334 g_assert_cmpint(bs->quiesce_counter, ==, 0);
335 g_assert_cmpint(backing->quiesce_counter, ==, 0);
336 g_assert_cmpint(s->drain_count, ==, 0);
337 g_assert_cmpint(backing_s->drain_count, ==, 0);
338
339 do_drain_begin(outer, bs);
340 do_drain_begin(inner, bs);
341
79ab8b21 342 g_assert_cmpint(bs->quiesce_counter, ==, 2);
6c429a6a
KW
343 g_assert_cmpint(backing->quiesce_counter, ==, backing_quiesce);
344 g_assert_cmpint(s->drain_count, ==, 2);
79ab8b21 345 g_assert_cmpint(backing_s->drain_count, ==, backing_quiesce);
6c429a6a
KW
346
347 do_drain_end(inner, bs);
348 do_drain_end(outer, bs);
349
350 g_assert_cmpint(bs->quiesce_counter, ==, 0);
351 g_assert_cmpint(backing->quiesce_counter, ==, 0);
352 g_assert_cmpint(s->drain_count, ==, 0);
353 g_assert_cmpint(backing_s->drain_count, ==, 0);
354 }
355 }
356
357 bdrv_unref(backing);
358 bdrv_unref(bs);
359 blk_unref(blk);
360}
361
27e64474
KW
362static void test_multiparent(void)
363{
364 BlockBackend *blk_a, *blk_b;
365 BlockDriverState *bs_a, *bs_b, *backing;
366 BDRVTestState *a_s, *b_s, *backing_s;
367
368 blk_a = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
369 bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR,
370 &error_abort);
371 a_s = bs_a->opaque;
372 blk_insert_bs(blk_a, bs_a, &error_abort);
373
374 blk_b = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
375 bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR,
376 &error_abort);
377 b_s = bs_b->opaque;
378 blk_insert_bs(blk_b, bs_b, &error_abort);
379
380 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
381 backing_s = backing->opaque;
382 bdrv_set_backing_hd(bs_a, backing, &error_abort);
383 bdrv_set_backing_hd(bs_b, backing, &error_abort);
384
385 g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
386 g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
387 g_assert_cmpint(backing->quiesce_counter, ==, 0);
388 g_assert_cmpint(a_s->drain_count, ==, 0);
389 g_assert_cmpint(b_s->drain_count, ==, 0);
390 g_assert_cmpint(backing_s->drain_count, ==, 0);
391
392 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
393
394 g_assert_cmpint(bs_a->quiesce_counter, ==, 1);
395 g_assert_cmpint(bs_b->quiesce_counter, ==, 1);
396 g_assert_cmpint(backing->quiesce_counter, ==, 1);
397 g_assert_cmpint(a_s->drain_count, ==, 1);
398 g_assert_cmpint(b_s->drain_count, ==, 1);
399 g_assert_cmpint(backing_s->drain_count, ==, 1);
400
401 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b);
402
403 g_assert_cmpint(bs_a->quiesce_counter, ==, 2);
404 g_assert_cmpint(bs_b->quiesce_counter, ==, 2);
405 g_assert_cmpint(backing->quiesce_counter, ==, 2);
406 g_assert_cmpint(a_s->drain_count, ==, 2);
407 g_assert_cmpint(b_s->drain_count, ==, 2);
408 g_assert_cmpint(backing_s->drain_count, ==, 2);
409
410 do_drain_end(BDRV_SUBTREE_DRAIN, bs_b);
411
412 g_assert_cmpint(bs_a->quiesce_counter, ==, 1);
413 g_assert_cmpint(bs_b->quiesce_counter, ==, 1);
414 g_assert_cmpint(backing->quiesce_counter, ==, 1);
415 g_assert_cmpint(a_s->drain_count, ==, 1);
416 g_assert_cmpint(b_s->drain_count, ==, 1);
417 g_assert_cmpint(backing_s->drain_count, ==, 1);
418
419 do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
420
421 g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
422 g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
423 g_assert_cmpint(backing->quiesce_counter, ==, 0);
424 g_assert_cmpint(a_s->drain_count, ==, 0);
425 g_assert_cmpint(b_s->drain_count, ==, 0);
426 g_assert_cmpint(backing_s->drain_count, ==, 0);
427
428 bdrv_unref(backing);
429 bdrv_unref(bs_a);
430 bdrv_unref(bs_b);
431 blk_unref(blk_a);
432 blk_unref(blk_b);
433}
434
acebcf8d
KW
435static void test_graph_change(void)
436{
437 BlockBackend *blk_a, *blk_b;
438 BlockDriverState *bs_a, *bs_b, *backing;
439 BDRVTestState *a_s, *b_s, *backing_s;
440
441 blk_a = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
442 bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR,
443 &error_abort);
444 a_s = bs_a->opaque;
445 blk_insert_bs(blk_a, bs_a, &error_abort);
446
447 blk_b = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
448 bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR,
449 &error_abort);
450 b_s = bs_b->opaque;
451 blk_insert_bs(blk_b, bs_b, &error_abort);
452
453 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
454 backing_s = backing->opaque;
455 bdrv_set_backing_hd(bs_a, backing, &error_abort);
456
457 g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
458 g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
459 g_assert_cmpint(backing->quiesce_counter, ==, 0);
460 g_assert_cmpint(a_s->drain_count, ==, 0);
461 g_assert_cmpint(b_s->drain_count, ==, 0);
462 g_assert_cmpint(backing_s->drain_count, ==, 0);
463
464 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
465 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
466 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
467 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b);
468 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b);
469
470 bdrv_set_backing_hd(bs_b, backing, &error_abort);
471 g_assert_cmpint(bs_a->quiesce_counter, ==, 5);
472 g_assert_cmpint(bs_b->quiesce_counter, ==, 5);
473 g_assert_cmpint(backing->quiesce_counter, ==, 5);
474 g_assert_cmpint(a_s->drain_count, ==, 5);
475 g_assert_cmpint(b_s->drain_count, ==, 5);
476 g_assert_cmpint(backing_s->drain_count, ==, 5);
477
478 bdrv_set_backing_hd(bs_b, NULL, &error_abort);
479 g_assert_cmpint(bs_a->quiesce_counter, ==, 3);
480 g_assert_cmpint(bs_b->quiesce_counter, ==, 2);
481 g_assert_cmpint(backing->quiesce_counter, ==, 3);
482 g_assert_cmpint(a_s->drain_count, ==, 3);
483 g_assert_cmpint(b_s->drain_count, ==, 2);
484 g_assert_cmpint(backing_s->drain_count, ==, 3);
485
486 bdrv_set_backing_hd(bs_b, backing, &error_abort);
487 g_assert_cmpint(bs_a->quiesce_counter, ==, 5);
488 g_assert_cmpint(bs_b->quiesce_counter, ==, 5);
489 g_assert_cmpint(backing->quiesce_counter, ==, 5);
490 g_assert_cmpint(a_s->drain_count, ==, 5);
491 g_assert_cmpint(b_s->drain_count, ==, 5);
492 g_assert_cmpint(backing_s->drain_count, ==, 5);
493
494 do_drain_end(BDRV_SUBTREE_DRAIN, bs_b);
495 do_drain_end(BDRV_SUBTREE_DRAIN, bs_b);
496 do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
497 do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
498 do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
499
500 g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
501 g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
502 g_assert_cmpint(backing->quiesce_counter, ==, 0);
503 g_assert_cmpint(a_s->drain_count, ==, 0);
504 g_assert_cmpint(b_s->drain_count, ==, 0);
505 g_assert_cmpint(backing_s->drain_count, ==, 0);
506
507 bdrv_unref(backing);
508 bdrv_unref(bs_a);
509 bdrv_unref(bs_b);
510 blk_unref(blk_a);
511 blk_unref(blk_b);
512}
513
bb675689
KW
514struct test_iothread_data {
515 BlockDriverState *bs;
516 enum drain_type drain_type;
517 int *aio_ret;
518};
519
520static void test_iothread_drain_entry(void *opaque)
521{
522 struct test_iothread_data *data = opaque;
523
524 aio_context_acquire(bdrv_get_aio_context(data->bs));
525 do_drain_begin(data->drain_type, data->bs);
526 g_assert_cmpint(*data->aio_ret, ==, 0);
527 do_drain_end(data->drain_type, data->bs);
528 aio_context_release(bdrv_get_aio_context(data->bs));
529
530 qemu_event_set(&done_event);
531}
532
533static void test_iothread_aio_cb(void *opaque, int ret)
534{
535 int *aio_ret = opaque;
536 *aio_ret = ret;
537 qemu_event_set(&done_event);
538}
539
540/*
541 * Starts an AIO request on a BDS that runs in the AioContext of iothread 1.
542 * The request involves a BH on iothread 2 before it can complete.
543 *
544 * @drain_thread = 0 means that do_drain_begin/end are called from the main
545 * thread, @drain_thread = 1 means that they are called from iothread 1. Drain
546 * for this BDS cannot be called from iothread 2 because only the main thread
547 * may do cross-AioContext polling.
548 */
549static void test_iothread_common(enum drain_type drain_type, int drain_thread)
550{
551 BlockBackend *blk;
552 BlockDriverState *bs;
553 BDRVTestState *s;
554 BlockAIOCB *acb;
555 int aio_ret;
556 struct test_iothread_data data;
557
558 IOThread *a = iothread_new();
559 IOThread *b = iothread_new();
560 AioContext *ctx_a = iothread_get_aio_context(a);
561 AioContext *ctx_b = iothread_get_aio_context(b);
562
563 QEMUIOVector qiov;
564 struct iovec iov = {
565 .iov_base = NULL,
566 .iov_len = 0,
567 };
568 qemu_iovec_init_external(&qiov, &iov, 1);
569
570 /* bdrv_drain_all() may only be called from the main loop thread */
571 if (drain_type == BDRV_DRAIN_ALL && drain_thread != 0) {
572 goto out;
573 }
574
575 blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
576 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
577 &error_abort);
578 s = bs->opaque;
579 blk_insert_bs(blk, bs, &error_abort);
580
581 blk_set_aio_context(blk, ctx_a);
582 aio_context_acquire(ctx_a);
583
584 s->bh_indirection_ctx = ctx_b;
585
586 aio_ret = -EINPROGRESS;
587 if (drain_thread == 0) {
588 acb = blk_aio_preadv(blk, 0, &qiov, 0, test_iothread_aio_cb, &aio_ret);
589 } else {
590 acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret);
591 }
592 g_assert(acb != NULL);
593 g_assert_cmpint(aio_ret, ==, -EINPROGRESS);
594
595 aio_context_release(ctx_a);
596
597 data = (struct test_iothread_data) {
598 .bs = bs,
599 .drain_type = drain_type,
600 .aio_ret = &aio_ret,
601 };
602
603 switch (drain_thread) {
604 case 0:
605 if (drain_type != BDRV_DRAIN_ALL) {
606 aio_context_acquire(ctx_a);
607 }
608
609 /* The request is running on the IOThread a. Draining its block device
610 * will make sure that it has completed as far as the BDS is concerned,
611 * but the drain in this thread can continue immediately after
612 * bdrv_dec_in_flight() and aio_ret might be assigned only slightly
613 * later. */
614 qemu_event_reset(&done_event);
615 do_drain_begin(drain_type, bs);
616 g_assert_cmpint(bs->in_flight, ==, 0);
617
618 if (drain_type != BDRV_DRAIN_ALL) {
619 aio_context_release(ctx_a);
620 }
621 qemu_event_wait(&done_event);
622 if (drain_type != BDRV_DRAIN_ALL) {
623 aio_context_acquire(ctx_a);
624 }
625
626 g_assert_cmpint(aio_ret, ==, 0);
627 do_drain_end(drain_type, bs);
628
629 if (drain_type != BDRV_DRAIN_ALL) {
630 aio_context_release(ctx_a);
631 }
632 break;
633 case 1:
634 qemu_event_reset(&done_event);
635 aio_bh_schedule_oneshot(ctx_a, test_iothread_drain_entry, &data);
636 qemu_event_wait(&done_event);
637 break;
638 default:
639 g_assert_not_reached();
640 }
641
642 aio_context_acquire(ctx_a);
643 blk_set_aio_context(blk, qemu_get_aio_context());
644 aio_context_release(ctx_a);
645
646 bdrv_unref(bs);
647 blk_unref(blk);
648
649out:
650 iothread_join(a);
651 iothread_join(b);
652}
653
654static void test_iothread_drain_all(void)
655{
656 test_iothread_common(BDRV_DRAIN_ALL, 0);
657 test_iothread_common(BDRV_DRAIN_ALL, 1);
658}
659
660static void test_iothread_drain(void)
661{
662 test_iothread_common(BDRV_DRAIN, 0);
663 test_iothread_common(BDRV_DRAIN, 1);
664}
665
666static void test_iothread_drain_subtree(void)
667{
668 test_iothread_common(BDRV_SUBTREE_DRAIN, 0);
669 test_iothread_common(BDRV_SUBTREE_DRAIN, 1);
670}
671
7253220d
KW
672
673typedef struct TestBlockJob {
674 BlockJob common;
675 bool should_complete;
676} TestBlockJob;
677
1908a559 678static void test_job_completed(Job *job, void *opaque)
7253220d 679{
1266c9b9 680 job_completed(job, 0, NULL);
7253220d
KW
681}
682
683static void coroutine_fn test_job_start(void *opaque)
684{
685 TestBlockJob *s = opaque;
686
2e1795b5 687 job_transition_to_ready(&s->common.job);
7253220d 688 while (!s->should_complete) {
5d43e86e 689 job_sleep_ns(&s->common.job, 100000);
7253220d
KW
690 }
691
1908a559 692 job_defer_to_main_loop(&s->common.job, test_job_completed, NULL);
7253220d
KW
693}
694
3453d972 695static void test_job_complete(Job *job, Error **errp)
7253220d 696{
3453d972 697 TestBlockJob *s = container_of(job, TestBlockJob, common.job);
7253220d
KW
698 s->should_complete = true;
699}
700
701BlockJobDriver test_job_driver = {
33e9e9bd
KW
702 .job_driver = {
703 .instance_size = sizeof(TestBlockJob),
80fa2c75 704 .free = block_job_free,
b15de828 705 .user_resume = block_job_user_resume,
b69f777d 706 .drain = block_job_drain,
da01ff7f 707 .start = test_job_start,
3453d972 708 .complete = test_job_complete,
33e9e9bd 709 },
7253220d
KW
710};
711
712static void test_blockjob_common(enum drain_type drain_type)
713{
714 BlockBackend *blk_src, *blk_target;
715 BlockDriverState *src, *target;
716 BlockJob *job;
717 int ret;
718
719 src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR,
720 &error_abort);
721 blk_src = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
722 blk_insert_bs(blk_src, src, &error_abort);
723
724 target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR,
725 &error_abort);
726 blk_target = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
727 blk_insert_bs(blk_target, target, &error_abort);
728
75859b94
JS
729 job = block_job_create("job0", &test_job_driver, NULL, src, 0, BLK_PERM_ALL,
730 0, 0, NULL, NULL, &error_abort);
7253220d 731 block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort);
da01ff7f 732 job_start(&job->job);
7253220d 733
da01ff7f
KW
734 g_assert_cmpint(job->job.pause_count, ==, 0);
735 g_assert_false(job->job.paused);
5d43e86e 736 g_assert_false(job->job.busy); /* We're in job_sleep_ns() */
7253220d
KW
737
738 do_drain_begin(drain_type, src);
739
740 if (drain_type == BDRV_DRAIN_ALL) {
81193349 741 /* bdrv_drain_all() drains both src and target */
da01ff7f 742 g_assert_cmpint(job->job.pause_count, ==, 2);
7253220d 743 } else {
da01ff7f 744 g_assert_cmpint(job->job.pause_count, ==, 1);
7253220d
KW
745 }
746 /* XXX We don't wait until the job is actually paused. Is this okay? */
da01ff7f
KW
747 /* g_assert_true(job->job.paused); */
748 g_assert_false(job->job.busy); /* The job is paused */
7253220d
KW
749
750 do_drain_end(drain_type, src);
751
da01ff7f
KW
752 g_assert_cmpint(job->job.pause_count, ==, 0);
753 g_assert_false(job->job.paused);
5d43e86e 754 g_assert_false(job->job.busy); /* We're in job_sleep_ns() */
7253220d
KW
755
756 do_drain_begin(drain_type, target);
757
758 if (drain_type == BDRV_DRAIN_ALL) {
81193349 759 /* bdrv_drain_all() drains both src and target */
da01ff7f 760 g_assert_cmpint(job->job.pause_count, ==, 2);
7253220d 761 } else {
da01ff7f 762 g_assert_cmpint(job->job.pause_count, ==, 1);
7253220d
KW
763 }
764 /* XXX We don't wait until the job is actually paused. Is this okay? */
da01ff7f
KW
765 /* g_assert_true(job->job.paused); */
766 g_assert_false(job->job.busy); /* The job is paused */
7253220d
KW
767
768 do_drain_end(drain_type, target);
769
da01ff7f
KW
770 g_assert_cmpint(job->job.pause_count, ==, 0);
771 g_assert_false(job->job.paused);
5d43e86e 772 g_assert_false(job->job.busy); /* We're in job_sleep_ns() */
7253220d 773
3d70ff53 774 ret = job_complete_sync(&job->job, &error_abort);
7253220d
KW
775 g_assert_cmpint(ret, ==, 0);
776
777 blk_unref(blk_src);
778 blk_unref(blk_target);
779 bdrv_unref(src);
780 bdrv_unref(target);
781}
782
783static void test_blockjob_drain_all(void)
784{
785 test_blockjob_common(BDRV_DRAIN_ALL);
786}
787
788static void test_blockjob_drain(void)
789{
790 test_blockjob_common(BDRV_DRAIN);
791}
792
d2a85d0f
KW
793static void test_blockjob_drain_subtree(void)
794{
795 test_blockjob_common(BDRV_SUBTREE_DRAIN);
796}
797
881cfd17
KW
798int main(int argc, char **argv)
799{
bb675689
KW
800 int ret;
801
881cfd17
KW
802 bdrv_init();
803 qemu_init_main_loop(&error_abort);
804
805 g_test_init(&argc, &argv, NULL);
bb675689 806 qemu_event_init(&done_event, false);
881cfd17
KW
807
808 g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all);
86e1c840 809 g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain);
d2a85d0f
KW
810 g_test_add_func("/bdrv-drain/driver-cb/drain_subtree",
811 test_drv_cb_drain_subtree);
881cfd17 812
6d0252f2
KW
813 g_test_add_func("/bdrv-drain/driver-cb/co/drain_all",
814 test_drv_cb_co_drain_all);
0582eb10
KW
815 g_test_add_func("/bdrv-drain/driver-cb/co/drain", test_drv_cb_co_drain);
816 g_test_add_func("/bdrv-drain/driver-cb/co/drain_subtree",
817 test_drv_cb_co_drain_subtree);
818
819
89a6ceab
KW
820 g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all);
821 g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain);
d2a85d0f
KW
822 g_test_add_func("/bdrv-drain/quiesce/drain_subtree",
823 test_quiesce_drain_subtree);
89a6ceab 824
6d0252f2
KW
825 g_test_add_func("/bdrv-drain/quiesce/co/drain_all",
826 test_quiesce_co_drain_all);
0582eb10
KW
827 g_test_add_func("/bdrv-drain/quiesce/co/drain", test_quiesce_co_drain);
828 g_test_add_func("/bdrv-drain/quiesce/co/drain_subtree",
829 test_quiesce_co_drain_subtree);
830
6c429a6a 831 g_test_add_func("/bdrv-drain/nested", test_nested);
27e64474 832 g_test_add_func("/bdrv-drain/multiparent", test_multiparent);
acebcf8d 833 g_test_add_func("/bdrv-drain/graph-change", test_graph_change);
6c429a6a 834
bb675689
KW
835 g_test_add_func("/bdrv-drain/iothread/drain_all", test_iothread_drain_all);
836 g_test_add_func("/bdrv-drain/iothread/drain", test_iothread_drain);
837 g_test_add_func("/bdrv-drain/iothread/drain_subtree",
838 test_iothread_drain_subtree);
839
7253220d
KW
840 g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all);
841 g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain);
d2a85d0f
KW
842 g_test_add_func("/bdrv-drain/blockjob/drain_subtree",
843 test_blockjob_drain_subtree);
7253220d 844
bb675689
KW
845 ret = g_test_run();
846 qemu_event_destroy(&done_event);
847 return ret;
881cfd17 848}