]> git.proxmox.com Git - mirror_qemu.git/blame - tests/test-bdrv-drain.c
test-bdrv-drain: bdrv_drain() works with cross-AioContext events
[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
0582eb10
KW
236static void test_drv_cb_co_drain(void)
237{
238 call_in_coroutine(test_drv_cb_drain);
239}
240
241static void test_drv_cb_co_drain_subtree(void)
242{
243 call_in_coroutine(test_drv_cb_drain_subtree);
244}
245
89a6ceab
KW
246static void test_quiesce_common(enum drain_type drain_type, bool recursive)
247{
248 BlockBackend *blk;
249 BlockDriverState *bs, *backing;
250
251 blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
252 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
253 &error_abort);
254 blk_insert_bs(blk, bs, &error_abort);
255
256 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
257 bdrv_set_backing_hd(bs, backing, &error_abort);
258
259 g_assert_cmpint(bs->quiesce_counter, ==, 0);
260 g_assert_cmpint(backing->quiesce_counter, ==, 0);
261
262 do_drain_begin(drain_type, bs);
263
264 g_assert_cmpint(bs->quiesce_counter, ==, 1);
265 g_assert_cmpint(backing->quiesce_counter, ==, !!recursive);
266
267 do_drain_end(drain_type, bs);
268
269 g_assert_cmpint(bs->quiesce_counter, ==, 0);
270 g_assert_cmpint(backing->quiesce_counter, ==, 0);
271
272 bdrv_unref(backing);
273 bdrv_unref(bs);
274 blk_unref(blk);
275}
276
277static void test_quiesce_drain_all(void)
278{
279 // XXX drain_all doesn't quiesce
280 //test_quiesce_common(BDRV_DRAIN_ALL, true);
281}
282
283static void test_quiesce_drain(void)
284{
285 test_quiesce_common(BDRV_DRAIN, false);
286}
287
d2a85d0f
KW
288static void test_quiesce_drain_subtree(void)
289{
290 test_quiesce_common(BDRV_SUBTREE_DRAIN, true);
291}
292
0582eb10
KW
293static void test_quiesce_co_drain(void)
294{
295 call_in_coroutine(test_quiesce_drain);
296}
297
298static void test_quiesce_co_drain_subtree(void)
299{
300 call_in_coroutine(test_quiesce_drain_subtree);
301}
302
6c429a6a
KW
303static void test_nested(void)
304{
305 BlockBackend *blk;
306 BlockDriverState *bs, *backing;
307 BDRVTestState *s, *backing_s;
308 enum drain_type outer, inner;
309
310 blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
311 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
312 &error_abort);
313 s = bs->opaque;
314 blk_insert_bs(blk, bs, &error_abort);
315
316 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
317 backing_s = backing->opaque;
318 bdrv_set_backing_hd(bs, backing, &error_abort);
319
320 for (outer = 0; outer < DRAIN_TYPE_MAX; outer++) {
321 for (inner = 0; inner < DRAIN_TYPE_MAX; inner++) {
322 /* XXX bdrv_drain_all() doesn't increase the quiesce_counter */
323 int bs_quiesce = (outer != BDRV_DRAIN_ALL) +
324 (inner != BDRV_DRAIN_ALL);
d2a85d0f
KW
325 int backing_quiesce = (outer == BDRV_SUBTREE_DRAIN) +
326 (inner == BDRV_SUBTREE_DRAIN);
6c429a6a
KW
327 int backing_cb_cnt = (outer != BDRV_DRAIN) +
328 (inner != BDRV_DRAIN);
329
330 g_assert_cmpint(bs->quiesce_counter, ==, 0);
331 g_assert_cmpint(backing->quiesce_counter, ==, 0);
332 g_assert_cmpint(s->drain_count, ==, 0);
333 g_assert_cmpint(backing_s->drain_count, ==, 0);
334
335 do_drain_begin(outer, bs);
336 do_drain_begin(inner, bs);
337
338 g_assert_cmpint(bs->quiesce_counter, ==, bs_quiesce);
339 g_assert_cmpint(backing->quiesce_counter, ==, backing_quiesce);
340 g_assert_cmpint(s->drain_count, ==, 2);
341 g_assert_cmpint(backing_s->drain_count, ==, backing_cb_cnt);
342
343 do_drain_end(inner, bs);
344 do_drain_end(outer, bs);
345
346 g_assert_cmpint(bs->quiesce_counter, ==, 0);
347 g_assert_cmpint(backing->quiesce_counter, ==, 0);
348 g_assert_cmpint(s->drain_count, ==, 0);
349 g_assert_cmpint(backing_s->drain_count, ==, 0);
350 }
351 }
352
353 bdrv_unref(backing);
354 bdrv_unref(bs);
355 blk_unref(blk);
356}
357
27e64474
KW
358static void test_multiparent(void)
359{
360 BlockBackend *blk_a, *blk_b;
361 BlockDriverState *bs_a, *bs_b, *backing;
362 BDRVTestState *a_s, *b_s, *backing_s;
363
364 blk_a = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
365 bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR,
366 &error_abort);
367 a_s = bs_a->opaque;
368 blk_insert_bs(blk_a, bs_a, &error_abort);
369
370 blk_b = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
371 bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR,
372 &error_abort);
373 b_s = bs_b->opaque;
374 blk_insert_bs(blk_b, bs_b, &error_abort);
375
376 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
377 backing_s = backing->opaque;
378 bdrv_set_backing_hd(bs_a, backing, &error_abort);
379 bdrv_set_backing_hd(bs_b, backing, &error_abort);
380
381 g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
382 g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
383 g_assert_cmpint(backing->quiesce_counter, ==, 0);
384 g_assert_cmpint(a_s->drain_count, ==, 0);
385 g_assert_cmpint(b_s->drain_count, ==, 0);
386 g_assert_cmpint(backing_s->drain_count, ==, 0);
387
388 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
389
390 g_assert_cmpint(bs_a->quiesce_counter, ==, 1);
391 g_assert_cmpint(bs_b->quiesce_counter, ==, 1);
392 g_assert_cmpint(backing->quiesce_counter, ==, 1);
393 g_assert_cmpint(a_s->drain_count, ==, 1);
394 g_assert_cmpint(b_s->drain_count, ==, 1);
395 g_assert_cmpint(backing_s->drain_count, ==, 1);
396
397 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b);
398
399 g_assert_cmpint(bs_a->quiesce_counter, ==, 2);
400 g_assert_cmpint(bs_b->quiesce_counter, ==, 2);
401 g_assert_cmpint(backing->quiesce_counter, ==, 2);
402 g_assert_cmpint(a_s->drain_count, ==, 2);
403 g_assert_cmpint(b_s->drain_count, ==, 2);
404 g_assert_cmpint(backing_s->drain_count, ==, 2);
405
406 do_drain_end(BDRV_SUBTREE_DRAIN, bs_b);
407
408 g_assert_cmpint(bs_a->quiesce_counter, ==, 1);
409 g_assert_cmpint(bs_b->quiesce_counter, ==, 1);
410 g_assert_cmpint(backing->quiesce_counter, ==, 1);
411 g_assert_cmpint(a_s->drain_count, ==, 1);
412 g_assert_cmpint(b_s->drain_count, ==, 1);
413 g_assert_cmpint(backing_s->drain_count, ==, 1);
414
415 do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
416
417 g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
418 g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
419 g_assert_cmpint(backing->quiesce_counter, ==, 0);
420 g_assert_cmpint(a_s->drain_count, ==, 0);
421 g_assert_cmpint(b_s->drain_count, ==, 0);
422 g_assert_cmpint(backing_s->drain_count, ==, 0);
423
424 bdrv_unref(backing);
425 bdrv_unref(bs_a);
426 bdrv_unref(bs_b);
427 blk_unref(blk_a);
428 blk_unref(blk_b);
429}
430
acebcf8d
KW
431static void test_graph_change(void)
432{
433 BlockBackend *blk_a, *blk_b;
434 BlockDriverState *bs_a, *bs_b, *backing;
435 BDRVTestState *a_s, *b_s, *backing_s;
436
437 blk_a = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
438 bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR,
439 &error_abort);
440 a_s = bs_a->opaque;
441 blk_insert_bs(blk_a, bs_a, &error_abort);
442
443 blk_b = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
444 bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR,
445 &error_abort);
446 b_s = bs_b->opaque;
447 blk_insert_bs(blk_b, bs_b, &error_abort);
448
449 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
450 backing_s = backing->opaque;
451 bdrv_set_backing_hd(bs_a, backing, &error_abort);
452
453 g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
454 g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
455 g_assert_cmpint(backing->quiesce_counter, ==, 0);
456 g_assert_cmpint(a_s->drain_count, ==, 0);
457 g_assert_cmpint(b_s->drain_count, ==, 0);
458 g_assert_cmpint(backing_s->drain_count, ==, 0);
459
460 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
461 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
462 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a);
463 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b);
464 do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b);
465
466 bdrv_set_backing_hd(bs_b, backing, &error_abort);
467 g_assert_cmpint(bs_a->quiesce_counter, ==, 5);
468 g_assert_cmpint(bs_b->quiesce_counter, ==, 5);
469 g_assert_cmpint(backing->quiesce_counter, ==, 5);
470 g_assert_cmpint(a_s->drain_count, ==, 5);
471 g_assert_cmpint(b_s->drain_count, ==, 5);
472 g_assert_cmpint(backing_s->drain_count, ==, 5);
473
474 bdrv_set_backing_hd(bs_b, NULL, &error_abort);
475 g_assert_cmpint(bs_a->quiesce_counter, ==, 3);
476 g_assert_cmpint(bs_b->quiesce_counter, ==, 2);
477 g_assert_cmpint(backing->quiesce_counter, ==, 3);
478 g_assert_cmpint(a_s->drain_count, ==, 3);
479 g_assert_cmpint(b_s->drain_count, ==, 2);
480 g_assert_cmpint(backing_s->drain_count, ==, 3);
481
482 bdrv_set_backing_hd(bs_b, backing, &error_abort);
483 g_assert_cmpint(bs_a->quiesce_counter, ==, 5);
484 g_assert_cmpint(bs_b->quiesce_counter, ==, 5);
485 g_assert_cmpint(backing->quiesce_counter, ==, 5);
486 g_assert_cmpint(a_s->drain_count, ==, 5);
487 g_assert_cmpint(b_s->drain_count, ==, 5);
488 g_assert_cmpint(backing_s->drain_count, ==, 5);
489
490 do_drain_end(BDRV_SUBTREE_DRAIN, bs_b);
491 do_drain_end(BDRV_SUBTREE_DRAIN, bs_b);
492 do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
493 do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
494 do_drain_end(BDRV_SUBTREE_DRAIN, bs_a);
495
496 g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
497 g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
498 g_assert_cmpint(backing->quiesce_counter, ==, 0);
499 g_assert_cmpint(a_s->drain_count, ==, 0);
500 g_assert_cmpint(b_s->drain_count, ==, 0);
501 g_assert_cmpint(backing_s->drain_count, ==, 0);
502
503 bdrv_unref(backing);
504 bdrv_unref(bs_a);
505 bdrv_unref(bs_b);
506 blk_unref(blk_a);
507 blk_unref(blk_b);
508}
509
bb675689
KW
510struct test_iothread_data {
511 BlockDriverState *bs;
512 enum drain_type drain_type;
513 int *aio_ret;
514};
515
516static void test_iothread_drain_entry(void *opaque)
517{
518 struct test_iothread_data *data = opaque;
519
520 aio_context_acquire(bdrv_get_aio_context(data->bs));
521 do_drain_begin(data->drain_type, data->bs);
522 g_assert_cmpint(*data->aio_ret, ==, 0);
523 do_drain_end(data->drain_type, data->bs);
524 aio_context_release(bdrv_get_aio_context(data->bs));
525
526 qemu_event_set(&done_event);
527}
528
529static void test_iothread_aio_cb(void *opaque, int ret)
530{
531 int *aio_ret = opaque;
532 *aio_ret = ret;
533 qemu_event_set(&done_event);
534}
535
536/*
537 * Starts an AIO request on a BDS that runs in the AioContext of iothread 1.
538 * The request involves a BH on iothread 2 before it can complete.
539 *
540 * @drain_thread = 0 means that do_drain_begin/end are called from the main
541 * thread, @drain_thread = 1 means that they are called from iothread 1. Drain
542 * for this BDS cannot be called from iothread 2 because only the main thread
543 * may do cross-AioContext polling.
544 */
545static void test_iothread_common(enum drain_type drain_type, int drain_thread)
546{
547 BlockBackend *blk;
548 BlockDriverState *bs;
549 BDRVTestState *s;
550 BlockAIOCB *acb;
551 int aio_ret;
552 struct test_iothread_data data;
553
554 IOThread *a = iothread_new();
555 IOThread *b = iothread_new();
556 AioContext *ctx_a = iothread_get_aio_context(a);
557 AioContext *ctx_b = iothread_get_aio_context(b);
558
559 QEMUIOVector qiov;
560 struct iovec iov = {
561 .iov_base = NULL,
562 .iov_len = 0,
563 };
564 qemu_iovec_init_external(&qiov, &iov, 1);
565
566 /* bdrv_drain_all() may only be called from the main loop thread */
567 if (drain_type == BDRV_DRAIN_ALL && drain_thread != 0) {
568 goto out;
569 }
570
571 blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
572 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
573 &error_abort);
574 s = bs->opaque;
575 blk_insert_bs(blk, bs, &error_abort);
576
577 blk_set_aio_context(blk, ctx_a);
578 aio_context_acquire(ctx_a);
579
580 s->bh_indirection_ctx = ctx_b;
581
582 aio_ret = -EINPROGRESS;
583 if (drain_thread == 0) {
584 acb = blk_aio_preadv(blk, 0, &qiov, 0, test_iothread_aio_cb, &aio_ret);
585 } else {
586 acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret);
587 }
588 g_assert(acb != NULL);
589 g_assert_cmpint(aio_ret, ==, -EINPROGRESS);
590
591 aio_context_release(ctx_a);
592
593 data = (struct test_iothread_data) {
594 .bs = bs,
595 .drain_type = drain_type,
596 .aio_ret = &aio_ret,
597 };
598
599 switch (drain_thread) {
600 case 0:
601 if (drain_type != BDRV_DRAIN_ALL) {
602 aio_context_acquire(ctx_a);
603 }
604
605 /* The request is running on the IOThread a. Draining its block device
606 * will make sure that it has completed as far as the BDS is concerned,
607 * but the drain in this thread can continue immediately after
608 * bdrv_dec_in_flight() and aio_ret might be assigned only slightly
609 * later. */
610 qemu_event_reset(&done_event);
611 do_drain_begin(drain_type, bs);
612 g_assert_cmpint(bs->in_flight, ==, 0);
613
614 if (drain_type != BDRV_DRAIN_ALL) {
615 aio_context_release(ctx_a);
616 }
617 qemu_event_wait(&done_event);
618 if (drain_type != BDRV_DRAIN_ALL) {
619 aio_context_acquire(ctx_a);
620 }
621
622 g_assert_cmpint(aio_ret, ==, 0);
623 do_drain_end(drain_type, bs);
624
625 if (drain_type != BDRV_DRAIN_ALL) {
626 aio_context_release(ctx_a);
627 }
628 break;
629 case 1:
630 qemu_event_reset(&done_event);
631 aio_bh_schedule_oneshot(ctx_a, test_iothread_drain_entry, &data);
632 qemu_event_wait(&done_event);
633 break;
634 default:
635 g_assert_not_reached();
636 }
637
638 aio_context_acquire(ctx_a);
639 blk_set_aio_context(blk, qemu_get_aio_context());
640 aio_context_release(ctx_a);
641
642 bdrv_unref(bs);
643 blk_unref(blk);
644
645out:
646 iothread_join(a);
647 iothread_join(b);
648}
649
650static void test_iothread_drain_all(void)
651{
652 test_iothread_common(BDRV_DRAIN_ALL, 0);
653 test_iothread_common(BDRV_DRAIN_ALL, 1);
654}
655
656static void test_iothread_drain(void)
657{
658 test_iothread_common(BDRV_DRAIN, 0);
659 test_iothread_common(BDRV_DRAIN, 1);
660}
661
662static void test_iothread_drain_subtree(void)
663{
664 test_iothread_common(BDRV_SUBTREE_DRAIN, 0);
665 test_iothread_common(BDRV_SUBTREE_DRAIN, 1);
666}
667
7253220d
KW
668
669typedef struct TestBlockJob {
670 BlockJob common;
671 bool should_complete;
672} TestBlockJob;
673
1908a559 674static void test_job_completed(Job *job, void *opaque)
7253220d 675{
1266c9b9 676 job_completed(job, 0, NULL);
7253220d
KW
677}
678
679static void coroutine_fn test_job_start(void *opaque)
680{
681 TestBlockJob *s = opaque;
682
2e1795b5 683 job_transition_to_ready(&s->common.job);
7253220d 684 while (!s->should_complete) {
5d43e86e 685 job_sleep_ns(&s->common.job, 100000);
7253220d
KW
686 }
687
1908a559 688 job_defer_to_main_loop(&s->common.job, test_job_completed, NULL);
7253220d
KW
689}
690
3453d972 691static void test_job_complete(Job *job, Error **errp)
7253220d 692{
3453d972 693 TestBlockJob *s = container_of(job, TestBlockJob, common.job);
7253220d
KW
694 s->should_complete = true;
695}
696
697BlockJobDriver test_job_driver = {
33e9e9bd
KW
698 .job_driver = {
699 .instance_size = sizeof(TestBlockJob),
80fa2c75 700 .free = block_job_free,
b15de828 701 .user_resume = block_job_user_resume,
b69f777d 702 .drain = block_job_drain,
da01ff7f 703 .start = test_job_start,
3453d972 704 .complete = test_job_complete,
33e9e9bd 705 },
7253220d
KW
706};
707
708static void test_blockjob_common(enum drain_type drain_type)
709{
710 BlockBackend *blk_src, *blk_target;
711 BlockDriverState *src, *target;
712 BlockJob *job;
713 int ret;
714
715 src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR,
716 &error_abort);
717 blk_src = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
718 blk_insert_bs(blk_src, src, &error_abort);
719
720 target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR,
721 &error_abort);
722 blk_target = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
723 blk_insert_bs(blk_target, target, &error_abort);
724
75859b94
JS
725 job = block_job_create("job0", &test_job_driver, NULL, src, 0, BLK_PERM_ALL,
726 0, 0, NULL, NULL, &error_abort);
7253220d 727 block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort);
da01ff7f 728 job_start(&job->job);
7253220d 729
da01ff7f
KW
730 g_assert_cmpint(job->job.pause_count, ==, 0);
731 g_assert_false(job->job.paused);
5d43e86e 732 g_assert_false(job->job.busy); /* We're in job_sleep_ns() */
7253220d
KW
733
734 do_drain_begin(drain_type, src);
735
736 if (drain_type == BDRV_DRAIN_ALL) {
81193349 737 /* bdrv_drain_all() drains both src and target */
da01ff7f 738 g_assert_cmpint(job->job.pause_count, ==, 2);
7253220d 739 } else {
da01ff7f 740 g_assert_cmpint(job->job.pause_count, ==, 1);
7253220d
KW
741 }
742 /* XXX We don't wait until the job is actually paused. Is this okay? */
da01ff7f
KW
743 /* g_assert_true(job->job.paused); */
744 g_assert_false(job->job.busy); /* The job is paused */
7253220d
KW
745
746 do_drain_end(drain_type, src);
747
da01ff7f
KW
748 g_assert_cmpint(job->job.pause_count, ==, 0);
749 g_assert_false(job->job.paused);
5d43e86e 750 g_assert_false(job->job.busy); /* We're in job_sleep_ns() */
7253220d
KW
751
752 do_drain_begin(drain_type, target);
753
754 if (drain_type == BDRV_DRAIN_ALL) {
81193349 755 /* bdrv_drain_all() drains both src and target */
da01ff7f 756 g_assert_cmpint(job->job.pause_count, ==, 2);
7253220d 757 } else {
da01ff7f 758 g_assert_cmpint(job->job.pause_count, ==, 1);
7253220d
KW
759 }
760 /* XXX We don't wait until the job is actually paused. Is this okay? */
da01ff7f
KW
761 /* g_assert_true(job->job.paused); */
762 g_assert_false(job->job.busy); /* The job is paused */
7253220d
KW
763
764 do_drain_end(drain_type, target);
765
da01ff7f
KW
766 g_assert_cmpint(job->job.pause_count, ==, 0);
767 g_assert_false(job->job.paused);
5d43e86e 768 g_assert_false(job->job.busy); /* We're in job_sleep_ns() */
7253220d 769
3d70ff53 770 ret = job_complete_sync(&job->job, &error_abort);
7253220d
KW
771 g_assert_cmpint(ret, ==, 0);
772
773 blk_unref(blk_src);
774 blk_unref(blk_target);
775 bdrv_unref(src);
776 bdrv_unref(target);
777}
778
779static void test_blockjob_drain_all(void)
780{
781 test_blockjob_common(BDRV_DRAIN_ALL);
782}
783
784static void test_blockjob_drain(void)
785{
786 test_blockjob_common(BDRV_DRAIN);
787}
788
d2a85d0f
KW
789static void test_blockjob_drain_subtree(void)
790{
791 test_blockjob_common(BDRV_SUBTREE_DRAIN);
792}
793
881cfd17
KW
794int main(int argc, char **argv)
795{
bb675689
KW
796 int ret;
797
881cfd17
KW
798 bdrv_init();
799 qemu_init_main_loop(&error_abort);
800
801 g_test_init(&argc, &argv, NULL);
bb675689 802 qemu_event_init(&done_event, false);
881cfd17
KW
803
804 g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all);
86e1c840 805 g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain);
d2a85d0f
KW
806 g_test_add_func("/bdrv-drain/driver-cb/drain_subtree",
807 test_drv_cb_drain_subtree);
881cfd17 808
0582eb10
KW
809 // XXX bdrv_drain_all() doesn't work in coroutine context
810 g_test_add_func("/bdrv-drain/driver-cb/co/drain", test_drv_cb_co_drain);
811 g_test_add_func("/bdrv-drain/driver-cb/co/drain_subtree",
812 test_drv_cb_co_drain_subtree);
813
814
89a6ceab
KW
815 g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all);
816 g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain);
d2a85d0f
KW
817 g_test_add_func("/bdrv-drain/quiesce/drain_subtree",
818 test_quiesce_drain_subtree);
89a6ceab 819
0582eb10
KW
820 // XXX bdrv_drain_all() doesn't work in coroutine context
821 g_test_add_func("/bdrv-drain/quiesce/co/drain", test_quiesce_co_drain);
822 g_test_add_func("/bdrv-drain/quiesce/co/drain_subtree",
823 test_quiesce_co_drain_subtree);
824
6c429a6a 825 g_test_add_func("/bdrv-drain/nested", test_nested);
27e64474 826 g_test_add_func("/bdrv-drain/multiparent", test_multiparent);
acebcf8d 827 g_test_add_func("/bdrv-drain/graph-change", test_graph_change);
6c429a6a 828
bb675689
KW
829 g_test_add_func("/bdrv-drain/iothread/drain_all", test_iothread_drain_all);
830 g_test_add_func("/bdrv-drain/iothread/drain", test_iothread_drain);
831 g_test_add_func("/bdrv-drain/iothread/drain_subtree",
832 test_iothread_drain_subtree);
833
7253220d
KW
834 g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all);
835 g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain);
d2a85d0f
KW
836 g_test_add_func("/bdrv-drain/blockjob/drain_subtree",
837 test_blockjob_drain_subtree);
7253220d 838
bb675689
KW
839 ret = g_test_run();
840 qemu_event_destroy(&done_event);
841 return ret;
881cfd17 842}