1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "block/block_int.h"
27#include "block/blockjob_int.h"
28#include "sysemu/block-backend.h"
29#include "qapi/error.h"
30#include "qemu/main-loop.h"
31#include "iothread.h"
32
33static QemuEvent done_event;
34
35typedef struct BDRVTestState {
36 int drain_count;
37 AioContext *bh_indirection_ctx;
38 bool sleep_in_drain_begin;
39} BDRVTestState;
40
41static void coroutine_fn sleep_in_drain_begin(void *opaque)
42{
43 BlockDriverState *bs = opaque;
44
45 qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000);
46 bdrv_dec_in_flight(bs);
47}
48
49static void bdrv_test_drain_begin(BlockDriverState *bs)
50{
51 BDRVTestState *s = bs->opaque;
52 s->drain_count++;
53 if (s->sleep_in_drain_begin) {
54 Coroutine *co = qemu_coroutine_create(sleep_in_drain_begin, bs);
55 bdrv_inc_in_flight(bs);
56 aio_co_enter(bdrv_get_aio_context(bs), co);
57 }
58}
59
60static void bdrv_test_drain_end(BlockDriverState *bs)
61{
62 BDRVTestState *s = bs->opaque;
63 s->drain_count--;
64}
65
66static void bdrv_test_close(BlockDriverState *bs)
67{
68 BDRVTestState *s = bs->opaque;
69 g_assert_cmpint(s->drain_count, >, 0);
70}
71
72static void co_reenter_bh(void *opaque)
73{
74 aio_co_wake(opaque);
75}
76
77static int coroutine_fn bdrv_test_co_preadv(BlockDriverState *bs,
78 int64_t offset, int64_t bytes,
79 QEMUIOVector *qiov,
80 BdrvRequestFlags flags)
81{
82 BDRVTestState *s = bs->opaque;
83
84
85
86
87
88 qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000);
89
90 if (s->bh_indirection_ctx) {
91 aio_bh_schedule_oneshot(s->bh_indirection_ctx, co_reenter_bh,
92 qemu_coroutine_self());
93 qemu_coroutine_yield();
94 }
95
96 return 0;
97}
98
99static int bdrv_test_change_backing_file(BlockDriverState *bs,
100 const char *backing_file,
101 const char *backing_fmt)
102{
103 return 0;
104}
105
106static BlockDriver bdrv_test = {
107 .format_name = "test",
108 .instance_size = sizeof(BDRVTestState),
109 .supports_backing = true,
110
111 .bdrv_close = bdrv_test_close,
112 .bdrv_co_preadv = bdrv_test_co_preadv,
113
114 .bdrv_drain_begin = bdrv_test_drain_begin,
115 .bdrv_drain_end = bdrv_test_drain_end,
116
117 .bdrv_child_perm = bdrv_default_perms,
118
119 .bdrv_change_backing_file = bdrv_test_change_backing_file,
120};
121
122static void aio_ret_cb(void *opaque, int ret)
123{
124 int *aio_ret = opaque;
125 *aio_ret = ret;
126}
127
128typedef struct CallInCoroutineData {
129 void (*entry)(void);
130 bool done;
131} CallInCoroutineData;
132
133static coroutine_fn void call_in_coroutine_entry(void *opaque)
134{
135 CallInCoroutineData *data = opaque;
136
137 data->entry();
138 data->done = true;
139}
140
141static void call_in_coroutine(void (*entry)(void))
142{
143 Coroutine *co;
144 CallInCoroutineData data = {
145 .entry = entry,
146 .done = false,
147 };
148
149 co = qemu_coroutine_create(call_in_coroutine_entry, &data);
150 qemu_coroutine_enter(co);
151 while (!data.done) {
152 aio_poll(qemu_get_aio_context(), true);
153 }
154}
155
156enum drain_type {
157 BDRV_DRAIN_ALL,
158 BDRV_DRAIN,
159 DRAIN_TYPE_MAX,
160};
161
162static void do_drain_begin(enum drain_type drain_type, BlockDriverState *bs)
163{
164 switch (drain_type) {
165 case BDRV_DRAIN_ALL: bdrv_drain_all_begin(); break;
166 case BDRV_DRAIN: bdrv_drained_begin(bs); break;
167 default: g_assert_not_reached();
168 }
169}
170
171static void do_drain_end(enum drain_type drain_type, BlockDriverState *bs)
172{
173 switch (drain_type) {
174 case BDRV_DRAIN_ALL: bdrv_drain_all_end(); break;
175 case BDRV_DRAIN: bdrv_drained_end(bs); break;
176 default: g_assert_not_reached();
177 }
178}
179
180static void do_drain_begin_unlocked(enum drain_type drain_type, BlockDriverState *bs)
181{
182 if (drain_type != BDRV_DRAIN_ALL) {
183 aio_context_acquire(bdrv_get_aio_context(bs));
184 }
185 do_drain_begin(drain_type, bs);
186 if (drain_type != BDRV_DRAIN_ALL) {
187 aio_context_release(bdrv_get_aio_context(bs));
188 }
189}
190
191static void do_drain_end_unlocked(enum drain_type drain_type, BlockDriverState *bs)
192{
193 if (drain_type != BDRV_DRAIN_ALL) {
194 aio_context_acquire(bdrv_get_aio_context(bs));
195 }
196 do_drain_end(drain_type, bs);
197 if (drain_type != BDRV_DRAIN_ALL) {
198 aio_context_release(bdrv_get_aio_context(bs));
199 }
200}
201
202static void test_drv_cb_common(enum drain_type drain_type, bool recursive)
203{
204 BlockBackend *blk;
205 BlockDriverState *bs, *backing;
206 BDRVTestState *s, *backing_s;
207 BlockAIOCB *acb;
208 int aio_ret;
209
210 QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0);
211
212 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
213 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
214 &error_abort);
215 s = bs->opaque;
216 blk_insert_bs(blk, bs, &error_abort);
217
218 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
219 backing_s = backing->opaque;
220 bdrv_set_backing_hd(bs, backing, &error_abort);
221
222
223 g_assert_cmpint(s->drain_count, ==, 0);
224 g_assert_cmpint(backing_s->drain_count, ==, 0);
225
226 do_drain_begin(drain_type, bs);
227
228 g_assert_cmpint(s->drain_count, ==, 1);
229 g_assert_cmpint(backing_s->drain_count, ==, !!recursive);
230
231 do_drain_end(drain_type, bs);
232
233 g_assert_cmpint(s->drain_count, ==, 0);
234 g_assert_cmpint(backing_s->drain_count, ==, 0);
235
236
237 aio_ret = -EINPROGRESS;
238 acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret);
239 g_assert(acb != NULL);
240 g_assert_cmpint(aio_ret, ==, -EINPROGRESS);
241
242 g_assert_cmpint(s->drain_count, ==, 0);
243 g_assert_cmpint(backing_s->drain_count, ==, 0);
244
245 do_drain_begin(drain_type, bs);
246
247 g_assert_cmpint(aio_ret, ==, 0);
248 g_assert_cmpint(s->drain_count, ==, 1);
249 g_assert_cmpint(backing_s->drain_count, ==, !!recursive);
250
251 do_drain_end(drain_type, bs);
252
253 g_assert_cmpint(s->drain_count, ==, 0);
254 g_assert_cmpint(backing_s->drain_count, ==, 0);
255
256 bdrv_unref(backing);
257 bdrv_unref(bs);
258 blk_unref(blk);
259}
260
261static void test_drv_cb_drain_all(void)
262{
263 test_drv_cb_common(BDRV_DRAIN_ALL, true);
264}
265
266static void test_drv_cb_drain(void)
267{
268 test_drv_cb_common(BDRV_DRAIN, false);
269}
270
271static void test_drv_cb_co_drain_all(void)
272{
273 call_in_coroutine(test_drv_cb_drain_all);
274}
275
276static void test_drv_cb_co_drain(void)
277{
278 call_in_coroutine(test_drv_cb_drain);
279}
280
281static void test_quiesce_common(enum drain_type drain_type, bool recursive)
282{
283 BlockBackend *blk;
284 BlockDriverState *bs, *backing;
285
286 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
287 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
288 &error_abort);
289 blk_insert_bs(blk, bs, &error_abort);
290
291 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
292 bdrv_set_backing_hd(bs, backing, &error_abort);
293
294 g_assert_cmpint(bs->quiesce_counter, ==, 0);
295 g_assert_cmpint(backing->quiesce_counter, ==, 0);
296
297 do_drain_begin(drain_type, bs);
298
299 if (drain_type == BDRV_DRAIN_ALL) {
300 g_assert_cmpint(bs->quiesce_counter, ==, 2);
301 } else {
302 g_assert_cmpint(bs->quiesce_counter, ==, 1);
303 }
304 g_assert_cmpint(backing->quiesce_counter, ==, !!recursive);
305
306 do_drain_end(drain_type, bs);
307
308 g_assert_cmpint(bs->quiesce_counter, ==, 0);
309 g_assert_cmpint(backing->quiesce_counter, ==, 0);
310
311 bdrv_unref(backing);
312 bdrv_unref(bs);
313 blk_unref(blk);
314}
315
316static void test_quiesce_drain_all(void)
317{
318 test_quiesce_common(BDRV_DRAIN_ALL, true);
319}
320
321static void test_quiesce_drain(void)
322{
323 test_quiesce_common(BDRV_DRAIN, false);
324}
325
326static void test_quiesce_co_drain_all(void)
327{
328 call_in_coroutine(test_quiesce_drain_all);
329}
330
331static void test_quiesce_co_drain(void)
332{
333 call_in_coroutine(test_quiesce_drain);
334}
335
336static void test_nested(void)
337{
338 BlockBackend *blk;
339 BlockDriverState *bs, *backing;
340 BDRVTestState *s, *backing_s;
341 enum drain_type outer, inner;
342
343 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
344 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
345 &error_abort);
346 s = bs->opaque;
347 blk_insert_bs(blk, bs, &error_abort);
348
349 backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
350 backing_s = backing->opaque;
351 bdrv_set_backing_hd(bs, backing, &error_abort);
352
353 for (outer = 0; outer < DRAIN_TYPE_MAX; outer++) {
354 for (inner = 0; inner < DRAIN_TYPE_MAX; inner++) {
355 int backing_quiesce = (outer == BDRV_DRAIN_ALL) +
356 (inner == BDRV_DRAIN_ALL);
357
358 g_assert_cmpint(bs->quiesce_counter, ==, 0);
359 g_assert_cmpint(backing->quiesce_counter, ==, 0);
360 g_assert_cmpint(s->drain_count, ==, 0);
361 g_assert_cmpint(backing_s->drain_count, ==, 0);
362
363 do_drain_begin(outer, bs);
364 do_drain_begin(inner, bs);
365
366 g_assert_cmpint(bs->quiesce_counter, ==, 2 + !!backing_quiesce);
367 g_assert_cmpint(backing->quiesce_counter, ==, backing_quiesce);
368 g_assert_cmpint(s->drain_count, ==, 1);
369 g_assert_cmpint(backing_s->drain_count, ==, !!backing_quiesce);
370
371 do_drain_end(inner, bs);
372 do_drain_end(outer, bs);
373
374 g_assert_cmpint(bs->quiesce_counter, ==, 0);
375 g_assert_cmpint(backing->quiesce_counter, ==, 0);
376 g_assert_cmpint(s->drain_count, ==, 0);
377 g_assert_cmpint(backing_s->drain_count, ==, 0);
378 }
379 }
380
381 bdrv_unref(backing);
382 bdrv_unref(bs);
383 blk_unref(blk);
384}
385
386static void test_graph_change_drain_all(void)
387{
388 BlockBackend *blk_a, *blk_b;
389 BlockDriverState *bs_a, *bs_b;
390 BDRVTestState *a_s, *b_s;
391
392
393 blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
394 bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR,
395 &error_abort);
396 a_s = bs_a->opaque;
397 blk_insert_bs(blk_a, bs_a, &error_abort);
398
399 g_assert_cmpint(bs_a->quiesce_counter, ==, 0);
400 g_assert_cmpint(a_s->drain_count, ==, 0);
401
402
403 bdrv_drain_all_begin();
404
405 g_assert_cmpint(bs_a->quiesce_counter, ==, 1);
406 g_assert_cmpint(a_s->drain_count, ==, 1);
407
408
409 blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
410 bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR,
411 &error_abort);
412 b_s = bs_b->opaque;
413 blk_insert_bs(blk_b, bs_b, &error_abort);
414
415 g_assert_cmpint(bs_a->quiesce_counter, ==, 1);
416 g_assert_cmpint(bs_b->quiesce_counter, ==, 1);
417 g_assert_cmpint(a_s->drain_count, ==, 1);
418 g_assert_cmpint(b_s->drain_count, ==, 1);
419
420
421 blk_unref(blk_a);
422
423 g_assert_cmpint(bs_a->quiesce_counter, ==, 1);
424 g_assert_cmpint(bs_b->quiesce_counter, ==, 1);
425 g_assert_cmpint(a_s->drain_count, ==, 1);
426 g_assert_cmpint(b_s->drain_count, ==, 1);
427
428 bdrv_unref(bs_a);
429
430 g_assert_cmpint(bs_b->quiesce_counter, ==, 1);
431 g_assert_cmpint(b_s->drain_count, ==, 1);
432
433
434 bdrv_drain_all_end();
435
436 g_assert_cmpint(bs_b->quiesce_counter, ==, 0);
437 g_assert_cmpint(b_s->drain_count, ==, 0);
438 g_assert_cmpint(qemu_get_aio_context()->external_disable_cnt, ==, 0);
439
440 bdrv_unref(bs_b);
441 blk_unref(blk_b);
442}
443
444struct test_iothread_data {
445 BlockDriverState *bs;
446 enum drain_type drain_type;
447 int *aio_ret;
448};
449
450static void test_iothread_drain_entry(void *opaque)
451{
452 struct test_iothread_data *data = opaque;
453
454 aio_context_acquire(bdrv_get_aio_context(data->bs));
455 do_drain_begin(data->drain_type, data->bs);
456 g_assert_cmpint(*data->aio_ret, ==, 0);
457 do_drain_end(data->drain_type, data->bs);
458 aio_context_release(bdrv_get_aio_context(data->bs));
459
460 qemu_event_set(&done_event);
461}
462
463static void test_iothread_aio_cb(void *opaque, int ret)
464{
465 int *aio_ret = opaque;
466 *aio_ret = ret;
467 qemu_event_set(&done_event);
468}
469
470static void test_iothread_main_thread_bh(void *opaque)
471{
472 struct test_iothread_data *data = opaque;
473
474
475
476 aio_context_acquire(bdrv_get_aio_context(data->bs));
477 bdrv_flush(data->bs);
478 aio_context_release(bdrv_get_aio_context(data->bs));
479}
480
481
482
483
484
485
486
487
488
489
490static void test_iothread_common(enum drain_type drain_type, int drain_thread)
491{
492 BlockBackend *blk;
493 BlockDriverState *bs;
494 BDRVTestState *s;
495 BlockAIOCB *acb;
496 int aio_ret;
497 struct test_iothread_data data;
498
499 IOThread *a = iothread_new();
500 IOThread *b = iothread_new();
501 AioContext *ctx_a = iothread_get_aio_context(a);
502 AioContext *ctx_b = iothread_get_aio_context(b);
503
504 QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0);
505
506
507 if (drain_type == BDRV_DRAIN_ALL && drain_thread != 0) {
508 goto out;
509 }
510
511 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
512 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
513 &error_abort);
514 s = bs->opaque;
515 blk_insert_bs(blk, bs, &error_abort);
516 blk_set_disable_request_queuing(blk, true);
517
518 blk_set_aio_context(blk, ctx_a, &error_abort);
519 aio_context_acquire(ctx_a);
520
521 s->bh_indirection_ctx = ctx_b;
522
523 aio_ret = -EINPROGRESS;
524 qemu_event_reset(&done_event);
525
526 if (drain_thread == 0) {
527 acb = blk_aio_preadv(blk, 0, &qiov, 0, test_iothread_aio_cb, &aio_ret);
528 } else {
529 acb = blk_aio_preadv(blk, 0, &qiov, 0, aio_ret_cb, &aio_ret);
530 }
531 g_assert(acb != NULL);
532 g_assert_cmpint(aio_ret, ==, -EINPROGRESS);
533
534 aio_context_release(ctx_a);
535
536 data = (struct test_iothread_data) {
537 .bs = bs,
538 .drain_type = drain_type,
539 .aio_ret = &aio_ret,
540 };
541
542 switch (drain_thread) {
543 case 0:
544 if (drain_type != BDRV_DRAIN_ALL) {
545 aio_context_acquire(ctx_a);
546 }
547
548 aio_bh_schedule_oneshot(ctx_a, test_iothread_main_thread_bh, &data);
549
550
551
552
553
554
555 do_drain_begin(drain_type, bs);
556 g_assert_cmpint(bs->in_flight, ==, 0);
557
558 if (drain_type != BDRV_DRAIN_ALL) {
559 aio_context_release(ctx_a);
560 }
561 qemu_event_wait(&done_event);
562 if (drain_type != BDRV_DRAIN_ALL) {
563 aio_context_acquire(ctx_a);
564 }
565
566 g_assert_cmpint(aio_ret, ==, 0);
567 do_drain_end(drain_type, bs);
568
569 if (drain_type != BDRV_DRAIN_ALL) {
570 aio_context_release(ctx_a);
571 }
572 break;
573 case 1:
574 aio_bh_schedule_oneshot(ctx_a, test_iothread_drain_entry, &data);
575 qemu_event_wait(&done_event);
576 break;
577 default:
578 g_assert_not_reached();
579 }
580
581 aio_context_acquire(ctx_a);
582 blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
583 aio_context_release(ctx_a);
584
585 bdrv_unref(bs);
586 blk_unref(blk);
587
588out:
589 iothread_join(a);
590 iothread_join(b);
591}
592
593static void test_iothread_drain_all(void)
594{
595 test_iothread_common(BDRV_DRAIN_ALL, 0);
596 test_iothread_common(BDRV_DRAIN_ALL, 1);
597}
598
599static void test_iothread_drain(void)
600{
601 test_iothread_common(BDRV_DRAIN, 0);
602 test_iothread_common(BDRV_DRAIN, 1);
603}
604
605
606typedef struct TestBlockJob {
607 BlockJob common;
608 BlockDriverState *bs;
609 int run_ret;
610 int prepare_ret;
611 bool running;
612 bool should_complete;
613} TestBlockJob;
614
615static int test_job_prepare(Job *job)
616{
617 TestBlockJob *s = container_of(job, TestBlockJob, common.job);
618
619
620 bdrv_flush(s->bs);
621 return s->prepare_ret;
622}
623
624static void test_job_commit(Job *job)
625{
626 TestBlockJob *s = container_of(job, TestBlockJob, common.job);
627
628
629 bdrv_flush(s->bs);
630}
631
632static void test_job_abort(Job *job)
633{
634 TestBlockJob *s = container_of(job, TestBlockJob, common.job);
635
636
637 bdrv_flush(s->bs);
638}
639
640static int coroutine_fn test_job_run(Job *job, Error **errp)
641{
642 TestBlockJob *s = container_of(job, TestBlockJob, common.job);
643
644
645
646 s->running = true;
647
648 job_transition_to_ready(&s->common.job);
649 while (!s->should_complete) {
650
651
652
653 qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000);
654
655 job_pause_point(&s->common.job);
656 }
657
658 return s->run_ret;
659}
660
661static void test_job_complete(Job *job, Error **errp)
662{
663 TestBlockJob *s = container_of(job, TestBlockJob, common.job);
664 s->should_complete = true;
665}
666
667BlockJobDriver test_job_driver = {
668 .job_driver = {
669 .instance_size = sizeof(TestBlockJob),
670 .free = block_job_free,
671 .user_resume = block_job_user_resume,
672 .run = test_job_run,
673 .complete = test_job_complete,
674 .prepare = test_job_prepare,
675 .commit = test_job_commit,
676 .abort = test_job_abort,
677 },
678};
679
680enum test_job_result {
681 TEST_JOB_SUCCESS,
682 TEST_JOB_FAIL_RUN,
683 TEST_JOB_FAIL_PREPARE,
684};
685
686enum test_job_drain_node {
687 TEST_JOB_DRAIN_SRC,
688 TEST_JOB_DRAIN_SRC_CHILD,
689};
690
691static void test_blockjob_common_drain_node(enum drain_type drain_type,
692 bool use_iothread,
693 enum test_job_result result,
694 enum test_job_drain_node drain_node)
695{
696 BlockBackend *blk_src, *blk_target;
697 BlockDriverState *src, *src_backing, *src_overlay, *target, *drain_bs;
698 BlockJob *job;
699 TestBlockJob *tjob;
700 IOThread *iothread = NULL;
701 AioContext *ctx;
702 int ret;
703
704 src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR,
705 &error_abort);
706 src_backing = bdrv_new_open_driver(&bdrv_test, "source-backing",
707 BDRV_O_RDWR, &error_abort);
708 src_overlay = bdrv_new_open_driver(&bdrv_test, "source-overlay",
709 BDRV_O_RDWR, &error_abort);
710
711 bdrv_set_backing_hd(src_overlay, src, &error_abort);
712 bdrv_unref(src);
713 bdrv_set_backing_hd(src, src_backing, &error_abort);
714 bdrv_unref(src_backing);
715
716 blk_src = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
717 blk_insert_bs(blk_src, src_overlay, &error_abort);
718
719 switch (drain_node) {
720 case TEST_JOB_DRAIN_SRC:
721 drain_bs = src;
722 break;
723 case TEST_JOB_DRAIN_SRC_CHILD:
724 drain_bs = src_backing;
725 break;
726 default:
727 g_assert_not_reached();
728 }
729
730 if (use_iothread) {
731 iothread = iothread_new();
732 ctx = iothread_get_aio_context(iothread);
733 blk_set_aio_context(blk_src, ctx, &error_abort);
734 } else {
735 ctx = qemu_get_aio_context();
736 }
737
738 target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR,
739 &error_abort);
740 blk_target = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
741 blk_insert_bs(blk_target, target, &error_abort);
742 blk_set_allow_aio_context_change(blk_target, true);
743
744 aio_context_acquire(ctx);
745 tjob = block_job_create("job0", &test_job_driver, NULL, src,
746 0, BLK_PERM_ALL,
747 0, 0, NULL, NULL, &error_abort);
748 tjob->bs = src;
749 job = &tjob->common;
750 block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort);
751
752 switch (result) {
753 case TEST_JOB_SUCCESS:
754 break;
755 case TEST_JOB_FAIL_RUN:
756 tjob->run_ret = -EIO;
757 break;
758 case TEST_JOB_FAIL_PREPARE:
759 tjob->prepare_ret = -EIO;
760 break;
761 }
762 aio_context_release(ctx);
763
764 job_start(&job->job);
765
766 if (use_iothread) {
767
768
769
770 while (!tjob->running) {
771 aio_poll(qemu_get_aio_context(), false);
772 }
773 }
774
775 WITH_JOB_LOCK_GUARD() {
776 g_assert_cmpint(job->job.pause_count, ==, 0);
777 g_assert_false(job->job.paused);
778 g_assert_true(tjob->running);
779 g_assert_true(job->job.busy);
780 }
781
782 do_drain_begin_unlocked(drain_type, drain_bs);
783
784 WITH_JOB_LOCK_GUARD() {
785 if (drain_type == BDRV_DRAIN_ALL) {
786
787 g_assert_cmpint(job->job.pause_count, ==, 2);
788 } else {
789 g_assert_cmpint(job->job.pause_count, ==, 1);
790 }
791 g_assert_true(job->job.paused);
792 g_assert_false(job->job.busy);
793 }
794
795 do_drain_end_unlocked(drain_type, drain_bs);
796
797 if (use_iothread) {
798
799
800
801
802
803
804 while (job->job.paused) {
805 aio_poll(qemu_get_aio_context(), false);
806 }
807 }
808
809 WITH_JOB_LOCK_GUARD() {
810 g_assert_cmpint(job->job.pause_count, ==, 0);
811 g_assert_false(job->job.paused);
812 g_assert_true(job->job.busy);
813 }
814
815 do_drain_begin_unlocked(drain_type, target);
816
817 WITH_JOB_LOCK_GUARD() {
818 if (drain_type == BDRV_DRAIN_ALL) {
819
820 g_assert_cmpint(job->job.pause_count, ==, 2);
821 } else {
822 g_assert_cmpint(job->job.pause_count, ==, 1);
823 }
824 g_assert_true(job->job.paused);
825 g_assert_false(job->job.busy);
826 }
827
828 do_drain_end_unlocked(drain_type, target);
829
830 if (use_iothread) {
831
832
833
834
835
836
837 while (job->job.paused) {
838 aio_poll(qemu_get_aio_context(), false);
839 }
840 }
841
842 WITH_JOB_LOCK_GUARD() {
843 g_assert_cmpint(job->job.pause_count, ==, 0);
844 g_assert_false(job->job.paused);
845 g_assert_true(job->job.busy);
846 }
847
848 WITH_JOB_LOCK_GUARD() {
849 ret = job_complete_sync_locked(&job->job, &error_abort);
850 }
851 g_assert_cmpint(ret, ==, (result == TEST_JOB_SUCCESS ? 0 : -EIO));
852
853 aio_context_acquire(ctx);
854 if (use_iothread) {
855 blk_set_aio_context(blk_src, qemu_get_aio_context(), &error_abort);
856 assert(blk_get_aio_context(blk_target) == qemu_get_aio_context());
857 }
858 aio_context_release(ctx);
859
860 blk_unref(blk_src);
861 blk_unref(blk_target);
862 bdrv_unref(src_overlay);
863 bdrv_unref(target);
864
865 if (iothread) {
866 iothread_join(iothread);
867 }
868}
869
870static void test_blockjob_common(enum drain_type drain_type, bool use_iothread,
871 enum test_job_result result)
872{
873 test_blockjob_common_drain_node(drain_type, use_iothread, result,
874 TEST_JOB_DRAIN_SRC);
875 test_blockjob_common_drain_node(drain_type, use_iothread, result,
876 TEST_JOB_DRAIN_SRC_CHILD);
877}
878
879static void test_blockjob_drain_all(void)
880{
881 test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_SUCCESS);
882}
883
884static void test_blockjob_drain(void)
885{
886 test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_SUCCESS);
887}
888
889static void test_blockjob_error_drain_all(void)
890{
891 test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_RUN);
892 test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_PREPARE);
893}
894
895static void test_blockjob_error_drain(void)
896{
897 test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_RUN);
898 test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_PREPARE);
899}
900
901static void test_blockjob_iothread_drain_all(void)
902{
903 test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_SUCCESS);
904}
905
906static void test_blockjob_iothread_drain(void)
907{
908 test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_SUCCESS);
909}
910
911static void test_blockjob_iothread_error_drain_all(void)
912{
913 test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_RUN);
914 test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_PREPARE);
915}
916
917static void test_blockjob_iothread_error_drain(void)
918{
919 test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_RUN);
920 test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_PREPARE);
921}
922
923
924typedef struct BDRVTestTopState {
925 BdrvChild *wait_child;
926} BDRVTestTopState;
927
928static void bdrv_test_top_close(BlockDriverState *bs)
929{
930 BdrvChild *c, *next_c;
931 QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) {
932 bdrv_unref_child(bs, c);
933 }
934}
935
936static int coroutine_fn GRAPH_RDLOCK
937bdrv_test_top_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
938 QEMUIOVector *qiov, BdrvRequestFlags flags)
939{
940 BDRVTestTopState *tts = bs->opaque;
941 return bdrv_co_preadv(tts->wait_child, offset, bytes, qiov, flags);
942}
943
944static BlockDriver bdrv_test_top_driver = {
945 .format_name = "test_top_driver",
946 .instance_size = sizeof(BDRVTestTopState),
947
948 .bdrv_close = bdrv_test_top_close,
949 .bdrv_co_preadv = bdrv_test_top_co_preadv,
950
951 .bdrv_child_perm = bdrv_default_perms,
952};
953
954typedef struct TestCoDeleteByDrainData {
955 BlockBackend *blk;
956 bool detach_instead_of_delete;
957 bool done;
958} TestCoDeleteByDrainData;
959
960static void coroutine_fn test_co_delete_by_drain(void *opaque)
961{
962 TestCoDeleteByDrainData *dbdd = opaque;
963 BlockBackend *blk = dbdd->blk;
964 BlockDriverState *bs = blk_bs(blk);
965 BDRVTestTopState *tts = bs->opaque;
966 void *buffer = g_malloc(65536);
967 QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buffer, 65536);
968
969 GRAPH_RDLOCK_GUARD();
970
971
972
973
974
975
976
977
978
979 bdrv_co_preadv(tts->wait_child, 0, 65536, &qiov, 0);
980
981 g_assert_cmpint(bs->refcnt, ==, 1);
982
983 if (!dbdd->detach_instead_of_delete) {
984 blk_unref(blk);
985 } else {
986 BdrvChild *c, *next_c;
987 QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) {
988 bdrv_unref_child(bs, c);
989 }
990 }
991
992 dbdd->done = true;
993 g_free(buffer);
994}
995
996
997
998
999
1000
1001
1002
1003static void do_test_delete_by_drain(bool detach_instead_of_delete,
1004 enum drain_type drain_type)
1005{
1006 BlockBackend *blk;
1007 BlockDriverState *bs, *child_bs, *null_bs;
1008 BDRVTestTopState *tts;
1009 TestCoDeleteByDrainData dbdd;
1010 Coroutine *co;
1011
1012 bs = bdrv_new_open_driver(&bdrv_test_top_driver, "top", BDRV_O_RDWR,
1013 &error_abort);
1014 bs->total_sectors = 65536 >> BDRV_SECTOR_BITS;
1015 tts = bs->opaque;
1016
1017 null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
1018 &error_abort);
1019 bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds,
1020 BDRV_CHILD_DATA, &error_abort);
1021
1022
1023
1024 child_bs = bdrv_new_open_driver(&bdrv_test, "child", BDRV_O_RDWR,
1025 &error_abort);
1026 child_bs->total_sectors = 65536 >> BDRV_SECTOR_BITS;
1027
1028 tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child",
1029 &child_of_bds,
1030 BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY,
1031 &error_abort);
1032
1033
1034
1035 null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
1036 &error_abort);
1037 bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, BDRV_CHILD_DATA,
1038 &error_abort);
1039
1040 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
1041 blk_insert_bs(blk, bs, &error_abort);
1042
1043
1044 bdrv_unref(bs);
1045
1046 g_assert_cmpint(bs->refcnt, ==, 1);
1047 g_assert_cmpint(child_bs->refcnt, ==, 1);
1048 g_assert_cmpint(null_bs->refcnt, ==, 1);
1049
1050
1051 dbdd = (TestCoDeleteByDrainData){
1052 .blk = blk,
1053 .detach_instead_of_delete = detach_instead_of_delete,
1054 .done = false,
1055 };
1056 co = qemu_coroutine_create(test_co_delete_by_drain, &dbdd);
1057 qemu_coroutine_enter(co);
1058
1059
1060
1061
1062
1063
1064 switch (drain_type) {
1065 case BDRV_DRAIN:
1066 bdrv_ref(child_bs);
1067 bdrv_drain(child_bs);
1068 bdrv_unref(child_bs);
1069 break;
1070 case BDRV_DRAIN_ALL:
1071 bdrv_drain_all_begin();
1072 bdrv_drain_all_end();
1073 break;
1074 default:
1075 g_assert_not_reached();
1076 }
1077
1078 while (!dbdd.done) {
1079 aio_poll(qemu_get_aio_context(), true);
1080 }
1081
1082 if (detach_instead_of_delete) {
1083
1084
1085 blk_unref(blk);
1086 }
1087}
1088
1089static void test_delete_by_drain(void)
1090{
1091 do_test_delete_by_drain(false, BDRV_DRAIN);
1092}
1093
1094static void test_detach_by_drain_all(void)
1095{
1096 do_test_delete_by_drain(true, BDRV_DRAIN_ALL);
1097}
1098
1099static void test_detach_by_drain(void)
1100{
1101 do_test_delete_by_drain(true, BDRV_DRAIN);
1102}
1103
1104
1105struct detach_by_parent_data {
1106 BlockDriverState *parent_b;
1107 BdrvChild *child_b;
1108 BlockDriverState *c;
1109 BdrvChild *child_c;
1110 bool by_parent_cb;
1111 bool detach_on_drain;
1112};
1113static struct detach_by_parent_data detach_by_parent_data;
1114
1115static void detach_indirect_bh(void *opaque)
1116{
1117 struct detach_by_parent_data *data = opaque;
1118
1119 bdrv_dec_in_flight(data->child_b->bs);
1120 bdrv_unref_child(data->parent_b, data->child_b);
1121
1122 bdrv_ref(data->c);
1123 data->child_c = bdrv_attach_child(data->parent_b, data->c, "PB-C",
1124 &child_of_bds, BDRV_CHILD_DATA,
1125 &error_abort);
1126}
1127
1128static void detach_by_parent_aio_cb(void *opaque, int ret)
1129{
1130 struct detach_by_parent_data *data = &detach_by_parent_data;
1131
1132 g_assert_cmpint(ret, ==, 0);
1133 if (data->by_parent_cb) {
1134 bdrv_inc_in_flight(data->child_b->bs);
1135 detach_indirect_bh(data);
1136 }
1137}
1138
1139static void detach_by_driver_cb_drained_begin(BdrvChild *child)
1140{
1141 struct detach_by_parent_data *data = &detach_by_parent_data;
1142
1143 if (!data->detach_on_drain) {
1144 return;
1145 }
1146 data->detach_on_drain = false;
1147
1148 bdrv_inc_in_flight(data->child_b->bs);
1149 aio_bh_schedule_oneshot(qemu_get_current_aio_context(),
1150 detach_indirect_bh, &detach_by_parent_data);
1151 child_of_bds.drained_begin(child);
1152}
1153
1154static BdrvChildClass detach_by_driver_cb_class;
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176static void test_detach_indirect(bool by_parent_cb)
1177{
1178 BlockBackend *blk;
1179 BlockDriverState *parent_a, *parent_b, *a, *b, *c;
1180 BdrvChild *child_a, *child_b;
1181 BlockAIOCB *acb;
1182
1183 QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0);
1184
1185 if (!by_parent_cb) {
1186 detach_by_driver_cb_class = child_of_bds;
1187 detach_by_driver_cb_class.drained_begin =
1188 detach_by_driver_cb_drained_begin;
1189 detach_by_driver_cb_class.drained_end = NULL;
1190 detach_by_driver_cb_class.drained_poll = NULL;
1191 }
1192
1193 detach_by_parent_data = (struct detach_by_parent_data) {
1194 .detach_on_drain = false,
1195 };
1196
1197
1198 parent_a = bdrv_new_open_driver(&bdrv_test, "parent-a", BDRV_O_RDWR,
1199 &error_abort);
1200 parent_b = bdrv_new_open_driver(&bdrv_test, "parent-b", 0,
1201 &error_abort);
1202
1203 a = bdrv_new_open_driver(&bdrv_test, "a", BDRV_O_RDWR, &error_abort);
1204 b = bdrv_new_open_driver(&bdrv_test, "b", BDRV_O_RDWR, &error_abort);
1205 c = bdrv_new_open_driver(&bdrv_test, "c", BDRV_O_RDWR, &error_abort);
1206
1207
1208 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
1209 blk_insert_bs(blk, parent_a, &error_abort);
1210 bdrv_unref(parent_a);
1211
1212
1213
1214 if (!by_parent_cb) {
1215 BDRVTestState *s = parent_a->opaque;
1216 s->sleep_in_drain_begin = true;
1217 }
1218
1219
1220 bdrv_ref(b);
1221 bdrv_ref(a);
1222 child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_of_bds,
1223 BDRV_CHILD_DATA, &error_abort);
1224 child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_of_bds,
1225 BDRV_CHILD_COW, &error_abort);
1226
1227 bdrv_ref(a);
1228 bdrv_attach_child(parent_a, a, "PA-A",
1229 by_parent_cb ? &child_of_bds : &detach_by_driver_cb_class,
1230 BDRV_CHILD_DATA, &error_abort);
1231
1232 g_assert_cmpint(parent_a->refcnt, ==, 1);
1233 g_assert_cmpint(parent_b->refcnt, ==, 1);
1234 g_assert_cmpint(a->refcnt, ==, 3);
1235 g_assert_cmpint(b->refcnt, ==, 2);
1236 g_assert_cmpint(c->refcnt, ==, 1);
1237
1238 g_assert(QLIST_FIRST(&parent_b->children) == child_a);
1239 g_assert(QLIST_NEXT(child_a, next) == child_b);
1240 g_assert(QLIST_NEXT(child_b, next) == NULL);
1241
1242
1243 detach_by_parent_data = (struct detach_by_parent_data) {
1244 .parent_b = parent_b,
1245 .child_b = child_b,
1246 .c = c,
1247 .by_parent_cb = by_parent_cb,
1248 .detach_on_drain = true,
1249 };
1250 acb = blk_aio_preadv(blk, 0, &qiov, 0, detach_by_parent_aio_cb, NULL);
1251 g_assert(acb != NULL);
1252
1253
1254 bdrv_drained_begin(parent_b);
1255 bdrv_drained_begin(a);
1256 bdrv_drained_begin(b);
1257 bdrv_drained_begin(c);
1258
1259 g_assert(detach_by_parent_data.child_c != NULL);
1260
1261 g_assert_cmpint(parent_a->refcnt, ==, 1);
1262 g_assert_cmpint(parent_b->refcnt, ==, 1);
1263 g_assert_cmpint(a->refcnt, ==, 3);
1264 g_assert_cmpint(b->refcnt, ==, 1);
1265 g_assert_cmpint(c->refcnt, ==, 2);
1266
1267 g_assert(QLIST_FIRST(&parent_b->children) == detach_by_parent_data.child_c);
1268 g_assert(QLIST_NEXT(detach_by_parent_data.child_c, next) == child_a);
1269 g_assert(QLIST_NEXT(child_a, next) == NULL);
1270
1271 g_assert_cmpint(parent_a->quiesce_counter, ==, 1);
1272 g_assert_cmpint(parent_b->quiesce_counter, ==, 3);
1273 g_assert_cmpint(a->quiesce_counter, ==, 1);
1274 g_assert_cmpint(b->quiesce_counter, ==, 1);
1275 g_assert_cmpint(c->quiesce_counter, ==, 1);
1276
1277 bdrv_drained_end(parent_b);
1278 bdrv_drained_end(a);
1279 bdrv_drained_end(b);
1280 bdrv_drained_end(c);
1281
1282 bdrv_unref(parent_b);
1283 blk_unref(blk);
1284
1285 g_assert_cmpint(a->refcnt, ==, 1);
1286 g_assert_cmpint(b->refcnt, ==, 1);
1287 g_assert_cmpint(c->refcnt, ==, 1);
1288 bdrv_unref(a);
1289 bdrv_unref(b);
1290 bdrv_unref(c);
1291}
1292
1293static void test_detach_by_parent_cb(void)
1294{
1295 test_detach_indirect(true);
1296}
1297
1298static void test_detach_by_driver_cb(void)
1299{
1300 test_detach_indirect(false);
1301}
1302
1303static void test_append_to_drained(void)
1304{
1305 BlockBackend *blk;
1306 BlockDriverState *base, *overlay;
1307 BDRVTestState *base_s, *overlay_s;
1308
1309 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
1310 base = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
1311 base_s = base->opaque;
1312 blk_insert_bs(blk, base, &error_abort);
1313
1314 overlay = bdrv_new_open_driver(&bdrv_test, "overlay", BDRV_O_RDWR,
1315 &error_abort);
1316 overlay_s = overlay->opaque;
1317
1318 do_drain_begin(BDRV_DRAIN, base);
1319 g_assert_cmpint(base->quiesce_counter, ==, 1);
1320 g_assert_cmpint(base_s->drain_count, ==, 1);
1321 g_assert_cmpint(base->in_flight, ==, 0);
1322
1323 bdrv_append(overlay, base, &error_abort);
1324 g_assert_cmpint(base->in_flight, ==, 0);
1325 g_assert_cmpint(overlay->in_flight, ==, 0);
1326
1327 g_assert_cmpint(base->quiesce_counter, ==, 1);
1328 g_assert_cmpint(base_s->drain_count, ==, 1);
1329 g_assert_cmpint(overlay->quiesce_counter, ==, 1);
1330 g_assert_cmpint(overlay_s->drain_count, ==, 1);
1331
1332 do_drain_end(BDRV_DRAIN, base);
1333
1334 g_assert_cmpint(base->quiesce_counter, ==, 0);
1335 g_assert_cmpint(base_s->drain_count, ==, 0);
1336 g_assert_cmpint(overlay->quiesce_counter, ==, 0);
1337 g_assert_cmpint(overlay_s->drain_count, ==, 0);
1338
1339 bdrv_unref(overlay);
1340 bdrv_unref(base);
1341 blk_unref(blk);
1342}
1343
1344static void test_set_aio_context(void)
1345{
1346 BlockDriverState *bs;
1347 IOThread *a = iothread_new();
1348 IOThread *b = iothread_new();
1349 AioContext *ctx_a = iothread_get_aio_context(a);
1350 AioContext *ctx_b = iothread_get_aio_context(b);
1351
1352 bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
1353 &error_abort);
1354
1355 bdrv_drained_begin(bs);
1356 bdrv_try_change_aio_context(bs, ctx_a, NULL, &error_abort);
1357
1358 aio_context_acquire(ctx_a);
1359 bdrv_drained_end(bs);
1360
1361 bdrv_drained_begin(bs);
1362 bdrv_try_change_aio_context(bs, ctx_b, NULL, &error_abort);
1363 aio_context_release(ctx_a);
1364 aio_context_acquire(ctx_b);
1365 bdrv_try_change_aio_context(bs, qemu_get_aio_context(), NULL, &error_abort);
1366 aio_context_release(ctx_b);
1367 bdrv_drained_end(bs);
1368
1369 bdrv_unref(bs);
1370 iothread_join(a);
1371 iothread_join(b);
1372}
1373
1374
1375typedef struct TestDropBackingBlockJob {
1376 BlockJob common;
1377 bool should_complete;
1378 bool *did_complete;
1379 BlockDriverState *detach_also;
1380 BlockDriverState *bs;
1381} TestDropBackingBlockJob;
1382
1383static int coroutine_fn test_drop_backing_job_run(Job *job, Error **errp)
1384{
1385 TestDropBackingBlockJob *s =
1386 container_of(job, TestDropBackingBlockJob, common.job);
1387
1388 while (!s->should_complete) {
1389 job_sleep_ns(job, 0);
1390 }
1391
1392 return 0;
1393}
1394
1395static void test_drop_backing_job_commit(Job *job)
1396{
1397 TestDropBackingBlockJob *s =
1398 container_of(job, TestDropBackingBlockJob, common.job);
1399
1400 bdrv_set_backing_hd(s->bs, NULL, &error_abort);
1401 bdrv_set_backing_hd(s->detach_also, NULL, &error_abort);
1402
1403 *s->did_complete = true;
1404}
1405
1406static const BlockJobDriver test_drop_backing_job_driver = {
1407 .job_driver = {
1408 .instance_size = sizeof(TestDropBackingBlockJob),
1409 .free = block_job_free,
1410 .user_resume = block_job_user_resume,
1411 .run = test_drop_backing_job_run,
1412 .commit = test_drop_backing_job_commit,
1413 }
1414};
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479static void test_blockjob_commit_by_drained_end(void)
1480{
1481 BlockDriverState *bs_child, *bs_parents[3];
1482 TestDropBackingBlockJob *job;
1483 bool job_has_completed = false;
1484 int i;
1485
1486 bs_child = bdrv_new_open_driver(&bdrv_test, "child-node", BDRV_O_RDWR,
1487 &error_abort);
1488
1489 for (i = 0; i < 3; i++) {
1490 char name[32];
1491 snprintf(name, sizeof(name), "parent-node-%i", i);
1492 bs_parents[i] = bdrv_new_open_driver(&bdrv_test, name, BDRV_O_RDWR,
1493 &error_abort);
1494 bdrv_set_backing_hd(bs_parents[i], bs_child, &error_abort);
1495 }
1496
1497 job = block_job_create("job", &test_drop_backing_job_driver, NULL,
1498 bs_parents[2], 0, BLK_PERM_ALL, 0, 0, NULL, NULL,
1499 &error_abort);
1500 job->bs = bs_parents[2];
1501
1502 job->detach_also = bs_parents[0];
1503 job->did_complete = &job_has_completed;
1504
1505 job_start(&job->common.job);
1506
1507 job->should_complete = true;
1508 bdrv_drained_begin(bs_child);
1509 g_assert(!job_has_completed);
1510 bdrv_drained_end(bs_child);
1511 aio_poll(qemu_get_aio_context(), false);
1512 g_assert(job_has_completed);
1513
1514 bdrv_unref(bs_parents[0]);
1515 bdrv_unref(bs_parents[1]);
1516 bdrv_unref(bs_parents[2]);
1517 bdrv_unref(bs_child);
1518}
1519
1520
1521typedef struct TestSimpleBlockJob {
1522 BlockJob common;
1523 bool should_complete;
1524 bool *did_complete;
1525} TestSimpleBlockJob;
1526
1527static int coroutine_fn test_simple_job_run(Job *job, Error **errp)
1528{
1529 TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job);
1530
1531 while (!s->should_complete) {
1532 job_sleep_ns(job, 0);
1533 }
1534
1535 return 0;
1536}
1537
1538static void test_simple_job_clean(Job *job)
1539{
1540 TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job);
1541 *s->did_complete = true;
1542}
1543
1544static const BlockJobDriver test_simple_job_driver = {
1545 .job_driver = {
1546 .instance_size = sizeof(TestSimpleBlockJob),
1547 .free = block_job_free,
1548 .user_resume = block_job_user_resume,
1549 .run = test_simple_job_run,
1550 .clean = test_simple_job_clean,
1551 },
1552};
1553
1554static int drop_intermediate_poll_update_filename(BdrvChild *child,
1555 BlockDriverState *new_base,
1556 const char *filename,
1557 Error **errp)
1558{
1559
1560
1561
1562
1563
1564
1565 aio_poll(qemu_get_current_aio_context(), false);
1566
1567 aio_poll(qemu_get_current_aio_context(), false);
1568
1569 return 0;
1570}
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618static void test_drop_intermediate_poll(void)
1619{
1620 static BdrvChildClass chain_child_class;
1621 BlockDriverState *chain[3];
1622 TestSimpleBlockJob *job;
1623 BlockDriverState *job_node;
1624 bool job_has_completed = false;
1625 int i;
1626 int ret;
1627
1628 chain_child_class = child_of_bds;
1629 chain_child_class.update_filename = drop_intermediate_poll_update_filename;
1630
1631 for (i = 0; i < 3; i++) {
1632 char name[32];
1633 snprintf(name, 32, "node-%i", i);
1634
1635 chain[i] = bdrv_new_open_driver(&bdrv_test, name, 0, &error_abort);
1636 }
1637
1638 job_node = bdrv_new_open_driver(&bdrv_test, "job-node", BDRV_O_RDWR,
1639 &error_abort);
1640 bdrv_set_backing_hd(job_node, chain[1], &error_abort);
1641
1642
1643
1644
1645
1646 for (i = 0; i < 3; i++) {
1647 if (i) {
1648
1649 bdrv_attach_child(chain[i], chain[i - 1], "chain",
1650 &chain_child_class, BDRV_CHILD_COW, &error_abort);
1651 }
1652 }
1653
1654 job = block_job_create("job", &test_simple_job_driver, NULL, job_node,
1655 0, BLK_PERM_ALL, 0, 0, NULL, NULL, &error_abort);
1656
1657
1658 bdrv_unref(job_node);
1659
1660 job->did_complete = &job_has_completed;
1661
1662 job_start(&job->common.job);
1663 job->should_complete = true;
1664
1665 g_assert(!job_has_completed);
1666 ret = bdrv_drop_intermediate(chain[1], chain[0], NULL);
1667 aio_poll(qemu_get_aio_context(), false);
1668 g_assert(ret == 0);
1669 g_assert(job_has_completed);
1670
1671 bdrv_unref(chain[2]);
1672}
1673
1674
1675typedef struct BDRVReplaceTestState {
1676 bool setup_completed;
1677 bool was_drained;
1678 bool was_undrained;
1679 bool has_read;
1680
1681 int drain_count;
1682
1683 bool yield_before_read;
1684 Coroutine *io_co;
1685 Coroutine *drain_co;
1686} BDRVReplaceTestState;
1687
1688static void bdrv_replace_test_close(BlockDriverState *bs)
1689{
1690}
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702static int coroutine_fn GRAPH_RDLOCK
1703bdrv_replace_test_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
1704 QEMUIOVector *qiov, BdrvRequestFlags flags)
1705{
1706 BDRVReplaceTestState *s = bs->opaque;
1707
1708 if (bs->backing) {
1709 int ret;
1710
1711 g_assert(!s->drain_count);
1712
1713 s->io_co = qemu_coroutine_self();
1714 if (s->yield_before_read) {
1715 s->yield_before_read = false;
1716 qemu_coroutine_yield();
1717 }
1718 s->io_co = NULL;
1719
1720 ret = bdrv_co_preadv(bs->backing, offset, bytes, qiov, 0);
1721 s->has_read = true;
1722
1723
1724 if (s->drain_co) {
1725 aio_co_wake(s->drain_co);
1726 }
1727
1728 return ret;
1729 }
1730
1731 s->has_read = true;
1732 return 0;
1733}
1734
1735static void coroutine_fn bdrv_replace_test_drain_co(void *opaque)
1736{
1737 BlockDriverState *bs = opaque;
1738 BDRVReplaceTestState *s = bs->opaque;
1739
1740
1741 while (s->io_co) {
1742 aio_co_wake(s->io_co);
1743 s->io_co = NULL;
1744 qemu_coroutine_yield();
1745 }
1746 s->drain_co = NULL;
1747 bdrv_dec_in_flight(bs);
1748}
1749
1750
1751
1752
1753
1754
1755static void bdrv_replace_test_drain_begin(BlockDriverState *bs)
1756{
1757 BDRVReplaceTestState *s = bs->opaque;
1758
1759 if (!s->setup_completed) {
1760 return;
1761 }
1762
1763 if (!s->drain_count) {
1764 s->drain_co = qemu_coroutine_create(bdrv_replace_test_drain_co, bs);
1765 bdrv_inc_in_flight(bs);
1766 aio_co_enter(bdrv_get_aio_context(bs), s->drain_co);
1767 s->was_drained = true;
1768 }
1769 s->drain_count++;
1770}
1771
1772static void coroutine_fn bdrv_replace_test_read_entry(void *opaque)
1773{
1774 BlockDriverState *bs = opaque;
1775 char data;
1776 QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, &data, 1);
1777 int ret;
1778
1779
1780 bdrv_graph_co_rdlock();
1781 ret = bdrv_replace_test_co_preadv(bs, 0, 1, &qiov, 0);
1782 bdrv_graph_co_rdunlock();
1783
1784 g_assert(ret >= 0);
1785 bdrv_dec_in_flight(bs);
1786}
1787
1788
1789
1790
1791
1792
1793static void bdrv_replace_test_drain_end(BlockDriverState *bs)
1794{
1795 BDRVReplaceTestState *s = bs->opaque;
1796
1797 if (!s->setup_completed) {
1798 return;
1799 }
1800
1801 g_assert(s->drain_count > 0);
1802 if (!--s->drain_count) {
1803 s->was_undrained = true;
1804
1805 if (bs->backing) {
1806 Coroutine *co = qemu_coroutine_create(bdrv_replace_test_read_entry,
1807 bs);
1808 bdrv_inc_in_flight(bs);
1809 aio_co_enter(bdrv_get_aio_context(bs), co);
1810 }
1811 }
1812}
1813
1814static BlockDriver bdrv_replace_test = {
1815 .format_name = "replace_test",
1816 .instance_size = sizeof(BDRVReplaceTestState),
1817 .supports_backing = true,
1818
1819 .bdrv_close = bdrv_replace_test_close,
1820 .bdrv_co_preadv = bdrv_replace_test_co_preadv,
1821
1822 .bdrv_drain_begin = bdrv_replace_test_drain_begin,
1823 .bdrv_drain_end = bdrv_replace_test_drain_end,
1824
1825 .bdrv_child_perm = bdrv_default_perms,
1826};
1827
1828static void coroutine_fn test_replace_child_mid_drain_read_co(void *opaque)
1829{
1830 int ret;
1831 char data;
1832
1833 ret = blk_co_pread(opaque, 0, 1, &data, 0);
1834 g_assert(ret >= 0);
1835}
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865static void do_test_replace_child_mid_drain(int old_drain_count,
1866 int new_drain_count)
1867{
1868 BlockBackend *parent_blk;
1869 BlockDriverState *parent_bs;
1870 BlockDriverState *old_child_bs, *new_child_bs;
1871 BDRVReplaceTestState *parent_s;
1872 BDRVReplaceTestState *old_child_s, *new_child_s;
1873 Coroutine *io_co;
1874 int i;
1875
1876 parent_bs = bdrv_new_open_driver(&bdrv_replace_test, "parent", 0,
1877 &error_abort);
1878 parent_s = parent_bs->opaque;
1879
1880 parent_blk = blk_new(qemu_get_aio_context(),
1881 BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
1882 blk_insert_bs(parent_blk, parent_bs, &error_abort);
1883
1884 old_child_bs = bdrv_new_open_driver(&bdrv_replace_test, "old-child", 0,
1885 &error_abort);
1886 new_child_bs = bdrv_new_open_driver(&bdrv_replace_test, "new-child", 0,
1887 &error_abort);
1888 old_child_s = old_child_bs->opaque;
1889 new_child_s = new_child_bs->opaque;
1890
1891
1892 parent_bs->total_sectors = 1;
1893 old_child_bs->total_sectors = 1;
1894 new_child_bs->total_sectors = 1;
1895
1896 bdrv_ref(old_child_bs);
1897 bdrv_attach_child(parent_bs, old_child_bs, "child", &child_of_bds,
1898 BDRV_CHILD_COW, &error_abort);
1899 parent_s->setup_completed = true;
1900
1901 for (i = 0; i < old_drain_count; i++) {
1902 bdrv_drained_begin(old_child_bs);
1903 }
1904 for (i = 0; i < new_drain_count; i++) {
1905 bdrv_drained_begin(new_child_bs);
1906 }
1907
1908 if (!old_drain_count) {
1909
1910
1911
1912
1913 parent_s->yield_before_read = true;
1914 io_co = qemu_coroutine_create(test_replace_child_mid_drain_read_co,
1915 parent_blk);
1916 qemu_coroutine_enter(io_co);
1917 }
1918
1919
1920 g_assert(!parent_s->has_read);
1921
1922
1923 parent_s->was_drained = false;
1924 parent_s->was_undrained = false;
1925
1926 g_assert(parent_bs->quiesce_counter == old_drain_count);
1927 bdrv_replace_node(old_child_bs, new_child_bs, &error_abort);
1928 g_assert(parent_bs->quiesce_counter == new_drain_count);
1929
1930 if (!old_drain_count && !new_drain_count) {
1931
1932
1933
1934
1935
1936 g_assert(parent_s->was_drained && parent_s->was_undrained);
1937 } else if (!old_drain_count && new_drain_count) {
1938
1939
1940
1941
1942 g_assert(parent_s->was_drained && !parent_s->was_undrained);
1943 } else if (old_drain_count && !new_drain_count) {
1944
1945
1946
1947
1948 g_assert(!parent_s->was_drained && parent_s->was_undrained);
1949 } else {
1950
1951
1952
1953
1954 g_assert(!parent_s->was_drained && !parent_s->was_undrained);
1955 }
1956
1957 if (!old_drain_count || !new_drain_count) {
1958
1959
1960
1961
1962
1963
1964
1965 g_assert(parent_s->has_read);
1966 } else {
1967
1968
1969
1970
1971 g_assert(!parent_s->has_read);
1972 }
1973
1974
1975 g_assert(!(old_drain_count && old_child_s->has_read));
1976 g_assert(!(new_drain_count && new_child_s->has_read));
1977
1978 for (i = 0; i < new_drain_count; i++) {
1979 bdrv_drained_end(new_child_bs);
1980 }
1981 for (i = 0; i < old_drain_count; i++) {
1982 bdrv_drained_end(old_child_bs);
1983 }
1984
1985
1986
1987
1988
1989 g_assert(parent_s->has_read);
1990 g_assert(new_child_s->has_read);
1991
1992 blk_unref(parent_blk);
1993 bdrv_unref(parent_bs);
1994 bdrv_unref(old_child_bs);
1995 bdrv_unref(new_child_bs);
1996}
1997
1998static void test_replace_child_mid_drain(void)
1999{
2000 int old_drain_count, new_drain_count;
2001
2002 for (old_drain_count = 0; old_drain_count < 2; old_drain_count++) {
2003 for (new_drain_count = 0; new_drain_count < 2; new_drain_count++) {
2004 do_test_replace_child_mid_drain(old_drain_count, new_drain_count);
2005 }
2006 }
2007}
2008
2009int main(int argc, char **argv)
2010{
2011 int ret;
2012
2013 bdrv_init();
2014 qemu_init_main_loop(&error_abort);
2015
2016 g_test_init(&argc, &argv, NULL);
2017 qemu_event_init(&done_event, false);
2018
2019 g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_all);
2020 g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain);
2021
2022 g_test_add_func("/bdrv-drain/driver-cb/co/drain_all",
2023 test_drv_cb_co_drain_all);
2024 g_test_add_func("/bdrv-drain/driver-cb/co/drain", test_drv_cb_co_drain);
2025
2026 g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_all);
2027 g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain);
2028
2029 g_test_add_func("/bdrv-drain/quiesce/co/drain_all",
2030 test_quiesce_co_drain_all);
2031 g_test_add_func("/bdrv-drain/quiesce/co/drain", test_quiesce_co_drain);
2032
2033 g_test_add_func("/bdrv-drain/nested", test_nested);
2034
2035 g_test_add_func("/bdrv-drain/graph-change/drain_all",
2036 test_graph_change_drain_all);
2037
2038 g_test_add_func("/bdrv-drain/iothread/drain_all", test_iothread_drain_all);
2039 g_test_add_func("/bdrv-drain/iothread/drain", test_iothread_drain);
2040
2041 g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_all);
2042 g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain);
2043
2044 g_test_add_func("/bdrv-drain/blockjob/error/drain_all",
2045 test_blockjob_error_drain_all);
2046 g_test_add_func("/bdrv-drain/blockjob/error/drain",
2047 test_blockjob_error_drain);
2048
2049 g_test_add_func("/bdrv-drain/blockjob/iothread/drain_all",
2050 test_blockjob_iothread_drain_all);
2051 g_test_add_func("/bdrv-drain/blockjob/iothread/drain",
2052 test_blockjob_iothread_drain);
2053
2054 g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_all",
2055 test_blockjob_iothread_error_drain_all);
2056 g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain",
2057 test_blockjob_iothread_error_drain);
2058
2059 g_test_add_func("/bdrv-drain/deletion/drain", test_delete_by_drain);
2060 g_test_add_func("/bdrv-drain/detach/drain_all", test_detach_by_drain_all);
2061 g_test_add_func("/bdrv-drain/detach/drain", test_detach_by_drain);
2062 g_test_add_func("/bdrv-drain/detach/parent_cb", test_detach_by_parent_cb);
2063 g_test_add_func("/bdrv-drain/detach/driver_cb", test_detach_by_driver_cb);
2064
2065 g_test_add_func("/bdrv-drain/attach/drain", test_append_to_drained);
2066
2067 g_test_add_func("/bdrv-drain/set_aio_context", test_set_aio_context);
2068
2069 g_test_add_func("/bdrv-drain/blockjob/commit_by_drained_end",
2070 test_blockjob_commit_by_drained_end);
2071
2072 g_test_add_func("/bdrv-drain/bdrv_drop_intermediate/poll",
2073 test_drop_intermediate_poll);
2074
2075 g_test_add_func("/bdrv-drain/replace_child/mid-drain",
2076 test_replace_child_mid_drain);
2077
2078 ret = g_test_run();
2079 qemu_event_destroy(&done_event);
2080 return ret;
2081}
2082