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 WITH_JOB_LOCK_GUARD() {
586 job_complete_sync_locked(&tjob->common.job, &error_abort);
587 }
588 aio_context_acquire(ctx);
589 blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
590 aio_context_release(ctx);
591
592 bdrv_unref(bs);
593 blk_unref(blk);
594}
595
596
597
598
599
600
601
602
603
604
605
606
607
608static void test_propagate_basic(void)
609{
610 IOThread *iothread = iothread_new();
611 AioContext *ctx = iothread_get_aio_context(iothread);
612 AioContext *main_ctx;
613 BlockBackend *blk;
614 BlockDriverState *bs_a, *bs_b, *bs_verify;
615 QDict *options;
616
617
618
619
620
621
622 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL & ~BLK_PERM_RESIZE,
623 BLK_PERM_ALL);
624 bs_a = bdrv_new_open_driver(&bdrv_test, "bs_a", BDRV_O_RDWR, &error_abort);
625 blk_insert_bs(blk, bs_a, &error_abort);
626
627
628 bs_b = bdrv_new_open_driver(&bdrv_test, "bs_b", BDRV_O_RDWR, &error_abort);
629
630
631 options = qdict_new();
632 qdict_put_str(options, "driver", "blkverify");
633 qdict_put_str(options, "test", "bs_a");
634 qdict_put_str(options, "raw", "bs_b");
635
636 bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
637
638
639 blk_set_aio_context(blk, ctx, &error_abort);
640 g_assert(blk_get_aio_context(blk) == ctx);
641 g_assert(bdrv_get_aio_context(bs_a) == ctx);
642 g_assert(bdrv_get_aio_context(bs_verify) == ctx);
643 g_assert(bdrv_get_aio_context(bs_b) == ctx);
644
645
646 main_ctx = qemu_get_aio_context();
647 aio_context_acquire(ctx);
648 blk_set_aio_context(blk, main_ctx, &error_abort);
649 aio_context_release(ctx);
650 g_assert(blk_get_aio_context(blk) == main_ctx);
651 g_assert(bdrv_get_aio_context(bs_a) == main_ctx);
652 g_assert(bdrv_get_aio_context(bs_verify) == main_ctx);
653 g_assert(bdrv_get_aio_context(bs_b) == main_ctx);
654
655 bdrv_unref(bs_verify);
656 bdrv_unref(bs_b);
657 bdrv_unref(bs_a);
658 blk_unref(blk);
659}
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674static void test_propagate_diamond(void)
675{
676 IOThread *iothread = iothread_new();
677 AioContext *ctx = iothread_get_aio_context(iothread);
678 AioContext *main_ctx;
679 BlockBackend *blk;
680 BlockDriverState *bs_a, *bs_b, *bs_c, *bs_verify;
681 QDict *options;
682
683
684 bs_a = bdrv_new_open_driver(&bdrv_test, "bs_a", BDRV_O_RDWR, &error_abort);
685
686
687 options = qdict_new();
688 qdict_put_str(options, "driver", "raw");
689 qdict_put_str(options, "file", "bs_a");
690 qdict_put_str(options, "node-name", "bs_b");
691 bs_b = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
692
693 options = qdict_new();
694 qdict_put_str(options, "driver", "raw");
695 qdict_put_str(options, "file", "bs_a");
696 qdict_put_str(options, "node-name", "bs_c");
697 bs_c = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
698
699
700 options = qdict_new();
701 qdict_put_str(options, "driver", "blkverify");
702 qdict_put_str(options, "test", "bs_b");
703 qdict_put_str(options, "raw", "bs_c");
704
705 bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
706
707
708
709
710
711 blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL & ~BLK_PERM_RESIZE,
712 BLK_PERM_ALL);
713 blk_insert_bs(blk, bs_verify, &error_abort);
714
715
716 blk_set_aio_context(blk, ctx, &error_abort);
717 g_assert(blk_get_aio_context(blk) == ctx);
718 g_assert(bdrv_get_aio_context(bs_verify) == ctx);
719 g_assert(bdrv_get_aio_context(bs_a) == ctx);
720 g_assert(bdrv_get_aio_context(bs_b) == ctx);
721 g_assert(bdrv_get_aio_context(bs_c) == ctx);
722
723
724 main_ctx = qemu_get_aio_context();
725 aio_context_acquire(ctx);
726 blk_set_aio_context(blk, main_ctx, &error_abort);
727 aio_context_release(ctx);
728 g_assert(blk_get_aio_context(blk) == main_ctx);
729 g_assert(bdrv_get_aio_context(bs_verify) == main_ctx);
730 g_assert(bdrv_get_aio_context(bs_a) == main_ctx);
731 g_assert(bdrv_get_aio_context(bs_b) == main_ctx);
732 g_assert(bdrv_get_aio_context(bs_c) == main_ctx);
733
734 blk_unref(blk);
735 bdrv_unref(bs_verify);
736 bdrv_unref(bs_c);
737 bdrv_unref(bs_b);
738 bdrv_unref(bs_a);
739}
740
741static void test_propagate_mirror(void)
742{
743 IOThread *iothread = iothread_new();
744 AioContext *ctx = iothread_get_aio_context(iothread);
745 AioContext *main_ctx = qemu_get_aio_context();
746 BlockDriverState *src, *target, *filter;
747 BlockBackend *blk;
748 Job *job;
749 Error *local_err = NULL;
750
751
752 src = bdrv_new_open_driver(&bdrv_test, "src", BDRV_O_RDWR, &error_abort);
753 target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR,
754 &error_abort);
755
756
757 mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0,
758 MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false,
759 BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
760 false, "filter_node", MIRROR_COPY_MODE_BACKGROUND,
761 &error_abort);
762 WITH_JOB_LOCK_GUARD() {
763 job = job_get_locked("job0");
764 }
765 filter = bdrv_find_node("filter_node");
766
767
768 bdrv_try_change_aio_context(src, ctx, NULL, &error_abort);
769 g_assert(bdrv_get_aio_context(src) == ctx);
770 g_assert(bdrv_get_aio_context(target) == ctx);
771 g_assert(bdrv_get_aio_context(filter) == ctx);
772 g_assert(job->aio_context == ctx);
773
774
775 aio_context_acquire(ctx);
776 bdrv_try_change_aio_context(target, main_ctx, NULL, &error_abort);
777 aio_context_release(ctx);
778 g_assert(bdrv_get_aio_context(src) == main_ctx);
779 g_assert(bdrv_get_aio_context(target) == main_ctx);
780 g_assert(bdrv_get_aio_context(filter) == main_ctx);
781
782
783 blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
784 blk_insert_bs(blk, src, &error_abort);
785
786 bdrv_try_change_aio_context(target, ctx, NULL, &local_err);
787 error_free_or_abort(&local_err);
788
789 g_assert(blk_get_aio_context(blk) == main_ctx);
790 g_assert(bdrv_get_aio_context(src) == main_ctx);
791 g_assert(bdrv_get_aio_context(target) == main_ctx);
792 g_assert(bdrv_get_aio_context(filter) == main_ctx);
793
794
795 aio_context_acquire(ctx);
796 blk_set_allow_aio_context_change(blk, true);
797 bdrv_try_change_aio_context(target, ctx, NULL, &error_abort);
798 aio_context_release(ctx);
799
800 g_assert(blk_get_aio_context(blk) == ctx);
801 g_assert(bdrv_get_aio_context(src) == ctx);
802 g_assert(bdrv_get_aio_context(target) == ctx);
803 g_assert(bdrv_get_aio_context(filter) == ctx);
804
805 job_cancel_sync_all();
806
807 aio_context_acquire(ctx);
808 blk_set_aio_context(blk, main_ctx, &error_abort);
809 bdrv_try_change_aio_context(target, main_ctx, NULL, &error_abort);
810 aio_context_release(ctx);
811
812 blk_unref(blk);
813 bdrv_unref(src);
814 bdrv_unref(target);
815}
816
817static void test_attach_second_node(void)
818{
819 IOThread *iothread = iothread_new();
820 AioContext *ctx = iothread_get_aio_context(iothread);
821 AioContext *main_ctx = qemu_get_aio_context();
822 BlockBackend *blk;
823 BlockDriverState *bs, *filter;
824 QDict *options;
825
826 blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL);
827 bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
828 blk_insert_bs(blk, bs, &error_abort);
829
830 options = qdict_new();
831 qdict_put_str(options, "driver", "raw");
832 qdict_put_str(options, "file", "base");
833
834 filter = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
835 g_assert(blk_get_aio_context(blk) == ctx);
836 g_assert(bdrv_get_aio_context(bs) == ctx);
837 g_assert(bdrv_get_aio_context(filter) == ctx);
838
839 aio_context_acquire(ctx);
840 blk_set_aio_context(blk, main_ctx, &error_abort);
841 aio_context_release(ctx);
842 g_assert(blk_get_aio_context(blk) == main_ctx);
843 g_assert(bdrv_get_aio_context(bs) == main_ctx);
844 g_assert(bdrv_get_aio_context(filter) == main_ctx);
845
846 bdrv_unref(filter);
847 bdrv_unref(bs);
848 blk_unref(blk);
849}
850
851static void test_attach_preserve_blk_ctx(void)
852{
853 IOThread *iothread = iothread_new();
854 AioContext *ctx = iothread_get_aio_context(iothread);
855 BlockBackend *blk;
856 BlockDriverState *bs;
857
858 blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL);
859 bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
860 bs->total_sectors = 65536 / BDRV_SECTOR_SIZE;
861
862
863 blk_insert_bs(blk, bs, &error_abort);
864 g_assert(blk_get_aio_context(blk) == ctx);
865 g_assert(bdrv_get_aio_context(bs) == ctx);
866
867
868 aio_context_acquire(ctx);
869 blk_remove_bs(blk);
870 aio_context_release(ctx);
871 g_assert(blk_get_aio_context(blk) == ctx);
872 g_assert(bdrv_get_aio_context(bs) == qemu_get_aio_context());
873
874
875 blk_insert_bs(blk, bs, &error_abort);
876 g_assert(blk_get_aio_context(blk) == ctx);
877 g_assert(bdrv_get_aio_context(bs) == ctx);
878
879 aio_context_acquire(ctx);
880 blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
881 aio_context_release(ctx);
882 bdrv_unref(bs);
883 blk_unref(blk);
884}
885
886int main(int argc, char **argv)
887{
888 int i;
889
890 bdrv_init();
891 qemu_init_main_loop(&error_abort);
892
893 g_test_init(&argc, &argv, NULL);
894
895 for (i = 0; i < ARRAY_SIZE(sync_op_tests); i++) {
896 const SyncOpTest *t = &sync_op_tests[i];
897 g_test_add_data_func(t->name, t, test_sync_op);
898 }
899
900 g_test_add_func("/attach/blockjob", test_attach_blockjob);
901 g_test_add_func("/attach/second_node", test_attach_second_node);
902 g_test_add_func("/attach/preserve_blk_ctx", test_attach_preserve_blk_ctx);
903 g_test_add_func("/propagate/basic", test_propagate_basic);
904 g_test_add_func("/propagate/diamond", test_propagate_diamond);
905 g_test_add_func("/propagate/mirror", test_propagate_mirror);
906
907 return g_test_run();
908}
909