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.h"
27#include "block/blockjob_int.h"
28#include "sysemu/block-backend.h"
29#include "qapi/error.h"
30#include "qapi/qmp/qdict.h"
31#include "qemu/main-loop.h"
32#include "iothread.h"
33
34static int coroutine_fn bdrv_test_co_preadv(BlockDriverState *bs,
35 int64_t offset, int64_t bytes,
36 QEMUIOVector *qiov,
37 BdrvRequestFlags flags)
38{
39 return 0;
40}
41
42static int coroutine_fn bdrv_test_co_pwritev(BlockDriverState *bs,
43 int64_t offset, int64_t bytes,
44 QEMUIOVector *qiov,
45 BdrvRequestFlags flags)
46{
47 return 0;
48}
49
50static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
51 int64_t offset, int64_t bytes)
52{
53 return 0;
54}
55
56static int coroutine_fn
57bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
58 PreallocMode prealloc, BdrvRequestFlags flags,
59 Error **errp)
60{
61 return 0;
62}
63
64static int coroutine_fn bdrv_test_co_block_status(BlockDriverState *bs,
65 bool want_zero,
66 int64_t offset, int64_t count,
67 int64_t *pnum, int64_t *map,
68 BlockDriverState **file)
69{
70 *pnum = count;
71 return 0;
72}
73
74static BlockDriver bdrv_test = {
75 .format_name = "test",
76 .instance_size = 1,
77
78 .bdrv_co_preadv = bdrv_test_co_preadv,
79 .bdrv_co_pwritev = bdrv_test_co_pwritev,
80 .bdrv_co_pdiscard = bdrv_test_co_pdiscard,
81 .bdrv_co_truncate = bdrv_test_co_truncate,
82 .bdrv_co_block_status = bdrv_test_co_block_status,
83};
84
85static void test_sync_op_pread(BdrvChild *c)
86{
87 uint8_t buf[512];
88 int ret;
89
90
91 ret = bdrv_pread(c, 0, sizeof(buf), buf, 0);
92 g_assert_cmpint(ret, ==, 0);
93
94
95 ret = bdrv_pread(c, -2, sizeof(buf), buf, 0);
96 g_assert_cmpint(ret, ==, -EIO);
97}
98
99static void test_sync_op_pwrite(BdrvChild *c)
100{
101 uint8_t buf[512] = { 0 };
102 int ret;
103
104
105 ret = bdrv_pwrite(c, 0, sizeof(buf), buf, 0);
106 g_assert_cmpint(ret, ==, 0);
107
108
109 ret = bdrv_pwrite(c, -2, sizeof(buf), buf, 0);
110 g_assert_cmpint(ret, ==, -EIO);
111}
112
113static void test_sync_op_blk_pread(BlockBackend *blk)
114{
115 uint8_t buf[512];
116 int ret;
117
118
119 ret = blk_pread(blk, 0, sizeof(buf), buf, 0);
120 g_assert_cmpint(ret, ==, 0);
121
122
123 ret = blk_pread(blk, -2, sizeof(buf), buf, 0);
124 g_assert_cmpint(ret, ==, -EIO);
125}
126
127static void test_sync_op_blk_pwrite(BlockBackend *blk)
128{
129 uint8_t buf[512] = { 0 };
130 int ret;
131
132
133 ret = blk_pwrite(blk, 0, sizeof(buf), buf, 0);
134 g_assert_cmpint(ret, ==, 0);
135
136
137 ret = blk_pwrite(blk, -2, sizeof(buf), buf, 0);
138 g_assert_cmpint(ret, ==, -EIO);
139}
140
141static void test_sync_op_blk_preadv(BlockBackend *blk)
142{
143 uint8_t buf[512];
144 QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, sizeof(buf));
145 int ret;
146
147
148 ret = blk_preadv(blk, 0, sizeof(buf), &qiov, 0);
149 g_assert_cmpint(ret, ==, 0);
150
151
152 ret = blk_preadv(blk, -2, sizeof(buf), &qiov, 0);
153 g_assert_cmpint(ret, ==, -EIO);
154}
155
156static void test_sync_op_blk_pwritev(BlockBackend *blk)
157{
158 uint8_t buf[512] = { 0 };
159 QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, sizeof(buf));
160 int ret;
161
162
163 ret = blk_pwritev(blk, 0, sizeof(buf), &qiov, 0);
164 g_assert_cmpint(ret, ==, 0);
165
166
167 ret = blk_pwritev(blk, -2, sizeof(buf), &qiov, 0);
168 g_assert_cmpint(ret, ==, -EIO);
169}
170
171static void test_sync_op_blk_preadv_part(BlockBackend *blk)
172{
173 uint8_t buf[512];
174 QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, sizeof(buf));
175 int ret;
176
177
178 ret = blk_preadv_part(blk, 0, sizeof(buf), &qiov, 0, 0);
179 g_assert_cmpint(ret, ==, 0);
180
181
182 ret = blk_preadv_part(blk, -2, sizeof(buf), &qiov, 0, 0);
183 g_assert_cmpint(ret, ==, -EIO);
184}
185
186static void test_sync_op_blk_pwritev_part(BlockBackend *blk)
187{
188 uint8_t buf[512] = { 0 };
189 QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, sizeof(buf));
190 int ret;
191
192
193 ret = blk_pwritev_part(blk, 0, sizeof(buf), &qiov, 0, 0);
194 g_assert_cmpint(ret, ==, 0);
195
196
197 ret = blk_pwritev_part(blk, -2, sizeof(buf), &qiov, 0, 0);
198 g_assert_cmpint(ret, ==, -EIO);
199}
200
201static void test_sync_op_blk_pwrite_compressed(BlockBackend *blk)
202{
203 uint8_t buf[512] = { 0 };
204 int ret;
205
206
207 ret = blk_pwrite_compressed(blk, 0, sizeof(buf), buf);
208 g_assert_cmpint(ret, ==, -ENOTSUP);
209
210
211 ret = blk_pwrite_compressed(blk, -2, sizeof(buf), buf);
212 g_assert_cmpint(ret, ==, -EIO);
213}
214
215static void test_sync_op_blk_pwrite_zeroes(BlockBackend *blk)
216{
217 int ret;
218
219
220 ret = blk_pwrite_zeroes(blk, 0, 512, 0);
221 g_assert_cmpint(ret, ==, 0);
222
223
224 ret = blk_pwrite_zeroes(blk, -2, 512, 0);
225 g_assert_cmpint(ret, ==, -EIO);
226}
227
228static void test_sync_op_load_vmstate(BdrvChild *c)
229{
230 uint8_t buf[512];
231 int ret;
232
233
234 ret = bdrv_load_vmstate(c->bs, buf, 0, sizeof(buf));
235 g_assert_cmpint(ret, ==, -ENOTSUP);
236}
237
238static void test_sync_op_save_vmstate(BdrvChild *c)
239{
240 uint8_t buf[512] = { 0 };
241 int ret;
242
243
244 ret = bdrv_save_vmstate(c->bs, buf, 0, sizeof(buf));
245 g_assert_cmpint(ret, ==, -ENOTSUP);
246}
247
248static void test_sync_op_pdiscard(BdrvChild *c)
249{
250 int ret;
251
252
253 c->bs->open_flags |= BDRV_O_UNMAP;
254 ret = bdrv_pdiscard(c, 0, 512);
255 g_assert_cmpint(ret, ==, 0);
256
257
258 c->bs->open_flags &= ~BDRV_O_UNMAP;
259 ret = bdrv_pdiscard(c, 0, 512);
260 g_assert_cmpint(ret, ==, 0);
261
262
263 ret = bdrv_pdiscard(c, -2, 512);
264 g_assert_cmpint(ret, ==, -EIO);
265}
266
267static void test_sync_op_blk_pdiscard(BlockBackend *blk)
268{
269 int ret;
270
271
272 ret = blk_pdiscard(blk, 0, 512);
273 g_assert_cmpint(ret, ==, 0);
274
275
276 ret = blk_pdiscard(blk, -2, 512);
277 g_assert_cmpint(ret, ==, -EIO);
278}
279
280static void test_sync_op_truncate(BdrvChild *c)
281{
282 int ret;
283
284
285 ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
286 g_assert_cmpint(ret, ==, 0);
287
288
289 ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, 0, NULL);
290 g_assert_cmpint(ret, ==, -EINVAL);
291
292
293 c->bs->open_flags &= ~BDRV_O_RDWR;
294
295 ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
296 g_assert_cmpint(ret, ==, -EACCES);
297
298 c->bs->open_flags |= BDRV_O_RDWR;
299}
300
301static void test_sync_op_blk_truncate(BlockBackend *blk)
302{
303 int ret;
304
305
306 ret = blk_truncate(blk, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
307 g_assert_cmpint(ret, ==, 0);
308
309
310 ret = blk_truncate(blk, -2, false, PREALLOC_MODE_OFF, 0, NULL);
311 g_assert_cmpint(ret, ==, -EINVAL);
312}
313
314static void test_sync_op_block_status(BdrvChild *c)
315{
316 int ret;
317 int64_t n;
318
319
320 ret = bdrv_is_allocated(c->bs, 0, 65536, &n);
321 g_assert_cmpint(ret, ==, 0);
322
323
324 bdrv_test.bdrv_co_block_status = NULL;
325 ret = bdrv_is_allocated(c->bs, 0, 65536, &n);
326 g_assert_cmpint(ret, ==, 1);
327
328
329 ret = bdrv_is_allocated(c->bs, 0, 0, &n);
330 g_assert_cmpint(ret, ==, 0);
331
332
333 ret = bdrv_is_allocated(c->bs, 0x1000000, 0x1000000, &n);
334 g_assert_cmpint(ret, ==, 0);
335}
336
337static void test_sync_op_flush(BdrvChild *c)
338{
339 int ret;
340
341
342 ret = bdrv_flush(c->bs);
343 g_assert_cmpint(ret, ==, 0);
344
345
346 c->bs->open_flags &= ~BDRV_O_RDWR;
347
348 ret = bdrv_flush(c->bs);
349 g_assert_cmpint(ret, ==, 0);
350
351 c->bs->open_flags |= BDRV_O_RDWR;
352}
353
354static void test_sync_op_blk_flush(BlockBackend *blk)
355{
356 BlockDriverState *bs = blk_bs(blk);
357 int ret;
358
359
360 ret = blk_flush(blk);
361 g_assert_cmpint(ret, ==, 0);
362
363
364 bs->open_flags &= ~BDRV_O_RDWR;
365
366 ret = blk_flush(blk);
367 g_assert_cmpint(ret, ==, 0);
368
369 bs->open_flags |= BDRV_O_RDWR;
370}
371
372static void test_sync_op_check(BdrvChild *c)
373{
374 BdrvCheckResult result;
375 int ret;
376
377
378 ret = bdrv_check(c->bs, &result, 0);
379 g_assert_cmpint(ret, ==, -ENOTSUP);
380}
381
382static void test_sync_op_activate(BdrvChild *c)
383{
384
385 bdrv_activate(c->bs, NULL);
386}
387
388
389typedef struct SyncOpTest {
390 const char *name;
391 void (*fn)(BdrvChild *c);
392 void (*blkfn)(BlockBackend *blk);
393} SyncOpTest;
394
395const SyncOpTest sync_op_tests[] = {
396 {
397 .name = "/sync-op/pread",
398 .fn = test_sync_op_pread,
399 .blkfn = test_sync_op_blk_pread,
400 }, {
401 .name = "/sync-op/pwrite",
402 .fn = test_sync_op_pwrite,
403 .blkfn = test_sync_op_blk_pwrite,
404 }, {
405 .name = "/sync-op/preadv",
406 .fn = NULL,
407 .blkfn = test_sync_op_blk_preadv,
408 }, {
409 .name = "/sync-op/pwritev",
410 .fn = NULL,
411 .blkfn = test_sync_op_blk_pwritev,
412 }, {
413 .name = "/sync-op/preadv_part",
414 .fn = NULL,
415 .blkfn = test_sync_op_blk_preadv_part,
416 }, {
417 .name = "/sync-op/pwritev_part",
418 .fn = NULL,
419 .blkfn = test_sync_op_blk_pwritev_part,
420 }, {
421 .name = "/sync-op/pwrite_compressed",
422 .fn = NULL,
423 .blkfn = test_sync_op_blk_pwrite_compressed,
424 }, {
425 .name = "/sync-op/pwrite_zeroes",
426 .fn = NULL,
427 .blkfn = test_sync_op_blk_pwrite_zeroes,
428 }, {
429 .name = "/sync-op/load_vmstate",
430 .fn = test_sync_op_load_vmstate,
431 }, {
432 .name = "/sync-op/save_vmstate",
433 .fn = test_sync_op_save_vmstate,
434 }, {
435 .name = "/sync-op/pdiscard",
436 .fn = test_sync_op_pdiscard,
437 .blkfn = test_sync_op_blk_pdiscard,
438 }, {
439 .name = "/sync-op/truncate",
440 .fn = test_sync_op_truncate,
441 .blkfn = test_sync_op_blk_truncate,
442 }, {
443 .name = "/sync-op/block_status",
444 .fn = test_sync_op_block_status,
445 }, {
446 .name = "/sync-op/flush",
447 .fn = test_sync_op_flush,
448 .blkfn = test_sync_op_blk_flush,
449 }, {
450 .name = "/sync-op/check",
451 .fn = test_sync_op_check,
452 }, {
453 .name = "/sync-op/activate",
454 .fn = test_sync_op_activate,
455 },
456};
457
458
459
460static void test_sync_op(const void *opaque)
461{
462 const SyncOpTest *t = opaque;
463 IOThread *iothread = iothread_new();
464 AioContext *ctx = iothread_get_aio_context(iothread);
465 BlockBackend *blk;
466 BlockDriverState *bs;
467 BdrvChild *c;
468
469 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
470 bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
471 bs->total_sectors = 65536 / BDRV_SECTOR_SIZE;
472 blk_insert_bs(blk, bs, &error_abort);
473 c = QLIST_FIRST(&bs->parents);
474
475 blk_set_aio_context(blk, ctx, &error_abort);
476 aio_context_acquire(ctx);
477 if (t->fn) {
478 t->fn(c);
479 }
480 if (t->blkfn) {
481 t->blkfn(blk);
482 }
483 blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
484 aio_context_release(ctx);
485
486 bdrv_unref(bs);
487 blk_unref(blk);
488}
489
490typedef struct TestBlockJob {
491 BlockJob common;
492 bool should_complete;
493 int n;
494} TestBlockJob;
495
496static int test_job_prepare(Job *job)
497{
498 g_assert(qemu_get_current_aio_context() == qemu_get_aio_context());
499 return 0;
500}
501
502static int coroutine_fn test_job_run(Job *job, Error **errp)
503{
504 TestBlockJob *s = container_of(job, TestBlockJob, common.job);
505
506 job_transition_to_ready(&s->common.job);
507 while (!s->should_complete) {
508 s->n++;
509 g_assert(qemu_get_current_aio_context() == job->aio_context);
510
511
512
513
514
515 qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000);
516
517 job_pause_point(&s->common.job);
518 }
519
520 g_assert(qemu_get_current_aio_context() == job->aio_context);
521 return 0;
522}
523
524static void test_job_complete(Job *job, Error **errp)
525{
526 TestBlockJob *s = container_of(job, TestBlockJob, common.job);
527 s->should_complete = true;
528}
529
530BlockJobDriver test_job_driver = {
531 .job_driver = {
532 .instance_size = sizeof(TestBlockJob),
533 .free = block_job_free,
534 .user_resume = block_job_user_resume,
535 .run = test_job_run,
536 .complete = test_job_complete,
537 .prepare = test_job_prepare,
538 },
539};
540
541static void test_attach_blockjob(void)
542{
543 IOThread *iothread = iothread_new();
544 AioContext *ctx = iothread_get_aio_context(iothread);
545 BlockBackend *blk;
546 BlockDriverState *bs;
547 TestBlockJob *tjob;
548
549 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
550 bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
551 blk_insert_bs(blk, bs, &error_abort);
552
553 tjob = block_job_create("job0", &test_job_driver, NULL, bs,
554 0, BLK_PERM_ALL,
555 0, 0, NULL, NULL, &error_abort);
556 job_start(&tjob->common.job);
557
558 while (tjob->n == 0) {
559 aio_poll(qemu_get_aio_context(), false);
560 }
561
562 blk_set_aio_context(blk, ctx, &error_abort);
563
564 tjob->n = 0;
565 while (tjob->n == 0) {
566 aio_poll(qemu_get_aio_context(), false);
567 }
568
569 aio_context_acquire(ctx);
570 blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
571 aio_context_release(ctx);
572
573 tjob->n = 0;
574 while (tjob->n == 0) {
575 aio_poll(qemu_get_aio_context(), false);
576 }
577
578 blk_set_aio_context(blk, ctx, &error_abort);
579
580 tjob->n = 0;
581 while (tjob->n == 0) {
582 aio_poll(qemu_get_aio_context(), false);
583 }
584
585 aio_context_acquire(ctx);
586 job_complete_sync(&tjob->common.job, &error_abort);
587 blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
588 aio_context_release(ctx);
589
590 bdrv_unref(bs);
591 blk_unref(blk);
592}
593
594
595
596
597
598
599
600
601
602
603
604
605
606static void test_propagate_basic(void)
607{
608 IOThread *iothread = iothread_new();
609 AioContext *ctx = iothread_get_aio_context(iothread);
610 AioContext *main_ctx;
611 BlockBackend *blk;
612 BlockDriverState *bs_a, *bs_b, *bs_verify;
613 QDict *options;
614
615
616
617
618
619
620 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL & ~BLK_PERM_RESIZE,
621 BLK_PERM_ALL);
622 bs_a = bdrv_new_open_driver(&bdrv_test, "bs_a", BDRV_O_RDWR, &error_abort);
623 blk_insert_bs(blk, bs_a, &error_abort);
624
625
626 bs_b = bdrv_new_open_driver(&bdrv_test, "bs_b", BDRV_O_RDWR, &error_abort);
627
628
629 options = qdict_new();
630 qdict_put_str(options, "driver", "blkverify");
631 qdict_put_str(options, "test", "bs_a");
632 qdict_put_str(options, "raw", "bs_b");
633
634 bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
635
636
637 blk_set_aio_context(blk, ctx, &error_abort);
638 g_assert(blk_get_aio_context(blk) == ctx);
639 g_assert(bdrv_get_aio_context(bs_a) == ctx);
640 g_assert(bdrv_get_aio_context(bs_verify) == ctx);
641 g_assert(bdrv_get_aio_context(bs_b) == ctx);
642
643
644 main_ctx = qemu_get_aio_context();
645 aio_context_acquire(ctx);
646 blk_set_aio_context(blk, main_ctx, &error_abort);
647 aio_context_release(ctx);
648 g_assert(blk_get_aio_context(blk) == main_ctx);
649 g_assert(bdrv_get_aio_context(bs_a) == main_ctx);
650 g_assert(bdrv_get_aio_context(bs_verify) == main_ctx);
651 g_assert(bdrv_get_aio_context(bs_b) == main_ctx);
652
653 bdrv_unref(bs_verify);
654 bdrv_unref(bs_b);
655 bdrv_unref(bs_a);
656 blk_unref(blk);
657}
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672static void test_propagate_diamond(void)
673{
674 IOThread *iothread = iothread_new();
675 AioContext *ctx = iothread_get_aio_context(iothread);
676 AioContext *main_ctx;
677 BlockBackend *blk;
678 BlockDriverState *bs_a, *bs_b, *bs_c, *bs_verify;
679 QDict *options;
680
681
682 bs_a = bdrv_new_open_driver(&bdrv_test, "bs_a", BDRV_O_RDWR, &error_abort);
683
684
685 options = qdict_new();
686 qdict_put_str(options, "driver", "raw");
687 qdict_put_str(options, "file", "bs_a");
688 qdict_put_str(options, "node-name", "bs_b");
689 bs_b = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
690
691 options = qdict_new();
692 qdict_put_str(options, "driver", "raw");
693 qdict_put_str(options, "file", "bs_a");
694 qdict_put_str(options, "node-name", "bs_c");
695 bs_c = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
696
697
698 options = qdict_new();
699 qdict_put_str(options, "driver", "blkverify");
700 qdict_put_str(options, "test", "bs_b");
701 qdict_put_str(options, "raw", "bs_c");
702
703 bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
704
705
706
707
708
709 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL & ~BLK_PERM_RESIZE,
710 BLK_PERM_ALL);
711 blk_insert_bs(blk, bs_verify, &error_abort);
712
713
714 blk_set_aio_context(blk, ctx, &error_abort);
715 g_assert(blk_get_aio_context(blk) == ctx);
716 g_assert(bdrv_get_aio_context(bs_verify) == ctx);
717 g_assert(bdrv_get_aio_context(bs_a) == ctx);
718 g_assert(bdrv_get_aio_context(bs_b) == ctx);
719 g_assert(bdrv_get_aio_context(bs_c) == ctx);
720
721
722 main_ctx = qemu_get_aio_context();
723 aio_context_acquire(ctx);
724 blk_set_aio_context(blk, main_ctx, &error_abort);
725 aio_context_release(ctx);
726 g_assert(blk_get_aio_context(blk) == main_ctx);
727 g_assert(bdrv_get_aio_context(bs_verify) == main_ctx);
728 g_assert(bdrv_get_aio_context(bs_a) == main_ctx);
729 g_assert(bdrv_get_aio_context(bs_b) == main_ctx);
730 g_assert(bdrv_get_aio_context(bs_c) == main_ctx);
731
732 blk_unref(blk);
733 bdrv_unref(bs_verify);
734 bdrv_unref(bs_c);
735 bdrv_unref(bs_b);
736 bdrv_unref(bs_a);
737}
738
739static void test_propagate_mirror(void)
740{
741 IOThread *iothread = iothread_new();
742 AioContext *ctx = iothread_get_aio_context(iothread);
743 AioContext *main_ctx = qemu_get_aio_context();
744 BlockDriverState *src, *target, *filter;
745 BlockBackend *blk;
746 Job *job;
747 Error *local_err = NULL;
748
749
750 src = bdrv_new_open_driver(&bdrv_test, "src", BDRV_O_RDWR, &error_abort);
751 target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR,
752 &error_abort);
753
754
755 mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0,
756 MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false,
757 BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
758 false, "filter_node", MIRROR_COPY_MODE_BACKGROUND,
759 &error_abort);
760 job = job_get("job0");
761 filter = bdrv_find_node("filter_node");
762
763
764 bdrv_try_set_aio_context(src, ctx, &error_abort);
765 g_assert(bdrv_get_aio_context(src) == ctx);
766 g_assert(bdrv_get_aio_context(target) == ctx);
767 g_assert(bdrv_get_aio_context(filter) == ctx);
768 g_assert(job->aio_context == ctx);
769
770
771 aio_context_acquire(ctx);
772 bdrv_try_set_aio_context(target, main_ctx, &error_abort);
773 aio_context_release(ctx);
774 g_assert(bdrv_get_aio_context(src) == main_ctx);
775 g_assert(bdrv_get_aio_context(target) == main_ctx);
776 g_assert(bdrv_get_aio_context(filter) == main_ctx);
777
778
779 blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
780 blk_insert_bs(blk, src, &error_abort);
781
782 bdrv_try_set_aio_context(target, ctx, &local_err);
783 error_free_or_abort(&local_err);
784
785 g_assert(blk_get_aio_context(blk) == main_ctx);
786 g_assert(bdrv_get_aio_context(src) == main_ctx);
787 g_assert(bdrv_get_aio_context(target) == main_ctx);
788 g_assert(bdrv_get_aio_context(filter) == main_ctx);
789
790
791 aio_context_acquire(ctx);
792 blk_set_allow_aio_context_change(blk, true);
793 bdrv_try_set_aio_context(target, ctx, &error_abort);
794 aio_context_release(ctx);
795
796 g_assert(blk_get_aio_context(blk) == ctx);
797 g_assert(bdrv_get_aio_context(src) == ctx);
798 g_assert(bdrv_get_aio_context(target) == ctx);
799 g_assert(bdrv_get_aio_context(filter) == ctx);
800
801 job_cancel_sync_all();
802
803 aio_context_acquire(ctx);
804 blk_set_aio_context(blk, main_ctx, &error_abort);
805 bdrv_try_set_aio_context(target, main_ctx, &error_abort);
806 aio_context_release(ctx);
807
808 blk_unref(blk);
809 bdrv_unref(src);
810 bdrv_unref(target);
811}
812
813static void test_attach_second_node(void)
814{
815 IOThread *iothread = iothread_new();
816 AioContext *ctx = iothread_get_aio_context(iothread);
817 AioContext *main_ctx = qemu_get_aio_context();
818 BlockBackend *blk;
819 BlockDriverState *bs, *filter;
820 QDict *options;
821
822 blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL);
823 bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
824 blk_insert_bs(blk, bs, &error_abort);
825
826 options = qdict_new();
827 qdict_put_str(options, "driver", "raw");
828 qdict_put_str(options, "file", "base");
829
830 filter = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
831 g_assert(blk_get_aio_context(blk) == ctx);
832 g_assert(bdrv_get_aio_context(bs) == ctx);
833 g_assert(bdrv_get_aio_context(filter) == ctx);
834
835 aio_context_acquire(ctx);
836 blk_set_aio_context(blk, main_ctx, &error_abort);
837 aio_context_release(ctx);
838 g_assert(blk_get_aio_context(blk) == main_ctx);
839 g_assert(bdrv_get_aio_context(bs) == main_ctx);
840 g_assert(bdrv_get_aio_context(filter) == main_ctx);
841
842 bdrv_unref(filter);
843 bdrv_unref(bs);
844 blk_unref(blk);
845}
846
847static void test_attach_preserve_blk_ctx(void)
848{
849 IOThread *iothread = iothread_new();
850 AioContext *ctx = iothread_get_aio_context(iothread);
851 BlockBackend *blk;
852 BlockDriverState *bs;
853
854 blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL);
855 bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
856 bs->total_sectors = 65536 / BDRV_SECTOR_SIZE;
857
858
859 blk_insert_bs(blk, bs, &error_abort);
860 g_assert(blk_get_aio_context(blk) == ctx);
861 g_assert(bdrv_get_aio_context(bs) == ctx);
862
863
864 aio_context_acquire(ctx);
865 blk_remove_bs(blk);
866 aio_context_release(ctx);
867 g_assert(blk_get_aio_context(blk) == ctx);
868 g_assert(bdrv_get_aio_context(bs) == qemu_get_aio_context());
869
870
871 blk_insert_bs(blk, bs, &error_abort);
872 g_assert(blk_get_aio_context(blk) == ctx);
873 g_assert(bdrv_get_aio_context(bs) == ctx);
874
875 aio_context_acquire(ctx);
876 blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
877 aio_context_release(ctx);
878 bdrv_unref(bs);
879 blk_unref(blk);
880}
881
882int main(int argc, char **argv)
883{
884 int i;
885
886 bdrv_init();
887 qemu_init_main_loop(&error_abort);
888
889 g_test_init(&argc, &argv, NULL);
890
891 for (i = 0; i < ARRAY_SIZE(sync_op_tests); i++) {
892 const SyncOpTest *t = &sync_op_tests[i];
893 g_test_add_data_func(t->name, t, test_sync_op);
894 }
895
896 g_test_add_func("/attach/blockjob", test_attach_blockjob);
897 g_test_add_func("/attach/second_node", test_attach_second_node);
898 g_test_add_func("/attach/preserve_blk_ctx", test_attach_preserve_blk_ctx);
899 g_test_add_func("/propagate/basic", test_propagate_basic);
900 g_test_add_func("/propagate/diamond", test_propagate_diamond);
901 g_test_add_func("/propagate/mirror", test_propagate_mirror);
902
903 return g_test_run();
904}
905