/*
 * Block tests for iothreads
 *
 * Copyright (c) 2018 Kevin Wolf <kwolf@redhat.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "block/block.h"
#include "block/blockjob_int.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qemu/main-loop.h"
#include "iothread.h"

static int coroutine_fn bdrv_test_co_prwv(BlockDriverState *bs,
                                          uint64_t offset, uint64_t bytes,
                                          QEMUIOVector *qiov, int flags)
{
    return 0;
}

static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
                                              int64_t offset, int bytes)
{
    return 0;
}

static int coroutine_fn
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
                      PreallocMode prealloc, Error **errp)
{
    return 0;
}

static int coroutine_fn bdrv_test_co_block_status(BlockDriverState *bs,
                                                  bool want_zero,
                                                  int64_t offset, int64_t count,
                                                  int64_t *pnum, int64_t *map,
                                                  BlockDriverState **file)
{
    *pnum = count;
    return 0;
}

static BlockDriver bdrv_test = {
    .format_name            = "test",
    .instance_size          = 1,

    .bdrv_co_preadv         = bdrv_test_co_prwv,
    .bdrv_co_pwritev        = bdrv_test_co_prwv,
    .bdrv_co_pdiscard       = bdrv_test_co_pdiscard,
    .bdrv_co_truncate       = bdrv_test_co_truncate,
    .bdrv_co_block_status   = bdrv_test_co_block_status,
};

static void test_sync_op_pread(BdrvChild *c)
{
    uint8_t buf[512];
    int ret;

    /* Success */
    ret = bdrv_pread(c, 0, buf, sizeof(buf));
    g_assert_cmpint(ret, ==, 512);

    /* Early error: Negative offset */
    ret = bdrv_pread(c, -2, buf, sizeof(buf));
    g_assert_cmpint(ret, ==, -EIO);
}

static void test_sync_op_pwrite(BdrvChild *c)
{
    uint8_t buf[512];
    int ret;

    /* Success */
    ret = bdrv_pwrite(c, 0, buf, sizeof(buf));
    g_assert_cmpint(ret, ==, 512);

    /* Early error: Negative offset */
    ret = bdrv_pwrite(c, -2, buf, sizeof(buf));
    g_assert_cmpint(ret, ==, -EIO);
}

static void test_sync_op_blk_pread(BlockBackend *blk)
{
    uint8_t buf[512];
    int ret;

    /* Success */
    ret = blk_pread(blk, 0, buf, sizeof(buf));
    g_assert_cmpint(ret, ==, 512);

    /* Early error: Negative offset */
    ret = blk_pread(blk, -2, buf, sizeof(buf));
    g_assert_cmpint(ret, ==, -EIO);
}

static void test_sync_op_blk_pwrite(BlockBackend *blk)
{
    uint8_t buf[512];
    int ret;

    /* Success */
    ret = blk_pwrite(blk, 0, buf, sizeof(buf), 0);
    g_assert_cmpint(ret, ==, 512);

    /* Early error: Negative offset */
    ret = blk_pwrite(blk, -2, buf, sizeof(buf), 0);
    g_assert_cmpint(ret, ==, -EIO);
}

static void test_sync_op_load_vmstate(BdrvChild *c)
{
    uint8_t buf[512];
    int ret;

    /* Error: Driver does not support snapshots */
    ret = bdrv_load_vmstate(c->bs, buf, 0, sizeof(buf));
    g_assert_cmpint(ret, ==, -ENOTSUP);
}

static void test_sync_op_save_vmstate(BdrvChild *c)
{
    uint8_t buf[512];
    int ret;

    /* Error: Driver does not support snapshots */
    ret = bdrv_save_vmstate(c->bs, buf, 0, sizeof(buf));
    g_assert_cmpint(ret, ==, -ENOTSUP);
}

static void test_sync_op_pdiscard(BdrvChild *c)
{
    int ret;

    /* Normal success path */
    c->bs->open_flags |= BDRV_O_UNMAP;
    ret = bdrv_pdiscard(c, 0, 512);
    g_assert_cmpint(ret, ==, 0);

    /* Early success: UNMAP not supported */
    c->bs->open_flags &= ~BDRV_O_UNMAP;
    ret = bdrv_pdiscard(c, 0, 512);
    g_assert_cmpint(ret, ==, 0);

    /* Early error: Negative offset */
    ret = bdrv_pdiscard(c, -2, 512);
    g_assert_cmpint(ret, ==, -EIO);
}

static void test_sync_op_blk_pdiscard(BlockBackend *blk)
{
    int ret;

    /* Early success: UNMAP not supported */
    ret = blk_pdiscard(blk, 0, 512);
    g_assert_cmpint(ret, ==, 0);

    /* Early error: Negative offset */
    ret = blk_pdiscard(blk, -2, 512);
    g_assert_cmpint(ret, ==, -EIO);
}

static void test_sync_op_truncate(BdrvChild *c)
{
    int ret;

    /* Normal success path */
    ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
    g_assert_cmpint(ret, ==, 0);

    /* Early error: Negative offset */
    ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, NULL);
    g_assert_cmpint(ret, ==, -EINVAL);

    /* Error: Read-only image */
    c->bs->read_only = true;
    c->bs->open_flags &= ~BDRV_O_RDWR;

    ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
    g_assert_cmpint(ret, ==, -EACCES);

    c->bs->read_only = false;
    c->bs->open_flags |= BDRV_O_RDWR;
}

static void test_sync_op_block_status(BdrvChild *c)
{
    int ret;
    int64_t n;

    /* Normal success path */
    ret = bdrv_is_allocated(c->bs, 0, 65536, &n);
    g_assert_cmpint(ret, ==, 0);

    /* Early success: No driver support */
    bdrv_test.bdrv_co_block_status = NULL;
    ret = bdrv_is_allocated(c->bs, 0, 65536, &n);
    g_assert_cmpint(ret, ==, 1);

    /* Early success: bytes = 0 */
    ret = bdrv_is_allocated(c->bs, 0, 0, &n);
    g_assert_cmpint(ret, ==, 0);

    /* Early success: Offset > image size*/
    ret = bdrv_is_allocated(c->bs, 0x1000000, 0x1000000, &n);
    g_assert_cmpint(ret, ==, 0);
}

static void test_sync_op_flush(BdrvChild *c)
{
    int ret;

    /* Normal success path */
    ret = bdrv_flush(c->bs);
    g_assert_cmpint(ret, ==, 0);

    /* Early success: Read-only image */
    c->bs->read_only = true;
    c->bs->open_flags &= ~BDRV_O_RDWR;

    ret = bdrv_flush(c->bs);
    g_assert_cmpint(ret, ==, 0);

    c->bs->read_only = false;
    c->bs->open_flags |= BDRV_O_RDWR;
}

static void test_sync_op_blk_flush(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);
    int ret;

    /* Normal success path */
    ret = blk_flush(blk);
    g_assert_cmpint(ret, ==, 0);

    /* Early success: Read-only image */
    bs->read_only = true;
    bs->open_flags &= ~BDRV_O_RDWR;

    ret = blk_flush(blk);
    g_assert_cmpint(ret, ==, 0);

    bs->read_only = false;
    bs->open_flags |= BDRV_O_RDWR;
}

static void test_sync_op_check(BdrvChild *c)
{
    BdrvCheckResult result;
    int ret;

    /* Error: Driver does not implement check */
    ret = bdrv_check(c->bs, &result, 0);
    g_assert_cmpint(ret, ==, -ENOTSUP);
}

static void test_sync_op_invalidate_cache(BdrvChild *c)
{
    /* Early success: Image is not inactive */
    bdrv_invalidate_cache(c->bs, NULL);
}


typedef struct SyncOpTest {
    const char *name;
    void (*fn)(BdrvChild *c);
    void (*blkfn)(BlockBackend *blk);
} SyncOpTest;

const SyncOpTest sync_op_tests[] = {
    {
        .name   = "/sync-op/pread",
        .fn     = test_sync_op_pread,
        .blkfn  = test_sync_op_blk_pread,
    }, {
        .name   = "/sync-op/pwrite",
        .fn     = test_sync_op_pwrite,
        .blkfn  = test_sync_op_blk_pwrite,
    }, {
        .name   = "/sync-op/load_vmstate",
        .fn     = test_sync_op_load_vmstate,
    }, {
        .name   = "/sync-op/save_vmstate",
        .fn     = test_sync_op_save_vmstate,
    }, {
        .name   = "/sync-op/pdiscard",
        .fn     = test_sync_op_pdiscard,
        .blkfn  = test_sync_op_blk_pdiscard,
    }, {
        .name   = "/sync-op/truncate",
        .fn     = test_sync_op_truncate,
    }, {
        .name   = "/sync-op/block_status",
        .fn     = test_sync_op_block_status,
    }, {
        .name   = "/sync-op/flush",
        .fn     = test_sync_op_flush,
        .blkfn  = test_sync_op_blk_flush,
    }, {
        .name   = "/sync-op/check",
        .fn     = test_sync_op_check,
    }, {
        .name   = "/sync-op/invalidate_cache",
        .fn     = test_sync_op_invalidate_cache,
    },
};

/* Test synchronous operations that run in a different iothread, so we have to
 * poll for the coroutine there to return. */
static void test_sync_op(const void *opaque)
{
    const SyncOpTest *t = opaque;
    IOThread *iothread = iothread_new();
    AioContext *ctx = iothread_get_aio_context(iothread);
    BlockBackend *blk;
    BlockDriverState *bs;
    BdrvChild *c;

    blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
    bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
    bs->total_sectors = 65536 / BDRV_SECTOR_SIZE;
    blk_insert_bs(blk, bs, &error_abort);
    c = QLIST_FIRST(&bs->parents);

    blk_set_aio_context(blk, ctx, &error_abort);
    aio_context_acquire(ctx);
    t->fn(c);
    if (t->blkfn) {
        t->blkfn(blk);
    }
    blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
    aio_context_release(ctx);

    bdrv_unref(bs);
    blk_unref(blk);
}

typedef struct TestBlockJob {
    BlockJob common;
    bool should_complete;
    int n;
} TestBlockJob;

static int test_job_prepare(Job *job)
{
    g_assert(qemu_get_current_aio_context() == qemu_get_aio_context());
    return 0;
}

static int coroutine_fn test_job_run(Job *job, Error **errp)
{
    TestBlockJob *s = container_of(job, TestBlockJob, common.job);

    job_transition_to_ready(&s->common.job);
    while (!s->should_complete) {
        s->n++;
        g_assert(qemu_get_current_aio_context() == job->aio_context);

        /* Avoid job_sleep_ns() because it marks the job as !busy. We want to
         * emulate some actual activity (probably some I/O) here so that the
         * drain involved in AioContext switches has to wait for this activity
         * to stop. */
        qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000);

        job_pause_point(&s->common.job);
    }

    g_assert(qemu_get_current_aio_context() == job->aio_context);
    return 0;
}

static void test_job_complete(Job *job, Error **errp)
{
    TestBlockJob *s = container_of(job, TestBlockJob, common.job);
    s->should_complete = true;
}

BlockJobDriver test_job_driver = {
    .job_driver = {
        .instance_size  = sizeof(TestBlockJob),
        .free           = block_job_free,
        .user_resume    = block_job_user_resume,
        .run            = test_job_run,
        .complete       = test_job_complete,
        .prepare        = test_job_prepare,
    },
};

static void test_attach_blockjob(void)
{
    IOThread *iothread = iothread_new();
    AioContext *ctx = iothread_get_aio_context(iothread);
    BlockBackend *blk;
    BlockDriverState *bs;
    TestBlockJob *tjob;

    blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
    bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
    blk_insert_bs(blk, bs, &error_abort);

    tjob = block_job_create("job0", &test_job_driver, NULL, bs,
                            0, BLK_PERM_ALL,
                            0, 0, NULL, NULL, &error_abort);
    job_start(&tjob->common.job);

    while (tjob->n == 0) {
        aio_poll(qemu_get_aio_context(), false);
    }

    blk_set_aio_context(blk, ctx, &error_abort);

    tjob->n = 0;
    while (tjob->n == 0) {
        aio_poll(qemu_get_aio_context(), false);
    }

    aio_context_acquire(ctx);
    blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
    aio_context_release(ctx);

    tjob->n = 0;
    while (tjob->n == 0) {
        aio_poll(qemu_get_aio_context(), false);
    }

    blk_set_aio_context(blk, ctx, &error_abort);

    tjob->n = 0;
    while (tjob->n == 0) {
        aio_poll(qemu_get_aio_context(), false);
    }

    aio_context_acquire(ctx);
    job_complete_sync(&tjob->common.job, &error_abort);
    blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
    aio_context_release(ctx);

    bdrv_unref(bs);
    blk_unref(blk);
}

/*
 * Test that changing the AioContext for one node in a tree (here through blk)
 * changes all other nodes as well:
 *
 *  blk
 *   |
 *   |  bs_verify [blkverify]
 *   |   /               \
 *   |  /                 \
 *  bs_a [bdrv_test]    bs_b [bdrv_test]
 *
 */
static void test_propagate_basic(void)
{
    IOThread *iothread = iothread_new();
    AioContext *ctx = iothread_get_aio_context(iothread);
    AioContext *main_ctx;
    BlockBackend *blk;
    BlockDriverState *bs_a, *bs_b, *bs_verify;
    QDict *options;

    /* Create bs_a and its BlockBackend */
    blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
    bs_a = bdrv_new_open_driver(&bdrv_test, "bs_a", BDRV_O_RDWR, &error_abort);
    blk_insert_bs(blk, bs_a, &error_abort);

    /* Create bs_b */
    bs_b = bdrv_new_open_driver(&bdrv_test, "bs_b", BDRV_O_RDWR, &error_abort);

    /* Create blkverify filter that references both bs_a and bs_b */
    options = qdict_new();
    qdict_put_str(options, "driver", "blkverify");
    qdict_put_str(options, "test", "bs_a");
    qdict_put_str(options, "raw", "bs_b");

    bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);

    /* Switch the AioContext */
    blk_set_aio_context(blk, ctx, &error_abort);
    g_assert(blk_get_aio_context(blk) == ctx);
    g_assert(bdrv_get_aio_context(bs_a) == ctx);
    g_assert(bdrv_get_aio_context(bs_verify) == ctx);
    g_assert(bdrv_get_aio_context(bs_b) == ctx);

    /* Switch the AioContext back */
    main_ctx = qemu_get_aio_context();
    aio_context_acquire(ctx);
    blk_set_aio_context(blk, main_ctx, &error_abort);
    aio_context_release(ctx);
    g_assert(blk_get_aio_context(blk) == main_ctx);
    g_assert(bdrv_get_aio_context(bs_a) == main_ctx);
    g_assert(bdrv_get_aio_context(bs_verify) == main_ctx);
    g_assert(bdrv_get_aio_context(bs_b) == main_ctx);

    bdrv_unref(bs_verify);
    bdrv_unref(bs_b);
    bdrv_unref(bs_a);
    blk_unref(blk);
}

/*
 * Test that diamonds in the graph don't lead to endless recursion:
 *
 *              blk
 *               |
 *      bs_verify [blkverify]
 *       /              \
 *      /                \
 *   bs_b [raw]         bs_c[raw]
 *      \                /
 *       \              /
 *       bs_a [bdrv_test]
 */
static void test_propagate_diamond(void)
{
    IOThread *iothread = iothread_new();
    AioContext *ctx = iothread_get_aio_context(iothread);
    AioContext *main_ctx;
    BlockBackend *blk;
    BlockDriverState *bs_a, *bs_b, *bs_c, *bs_verify;
    QDict *options;

    /* Create bs_a */
    bs_a = bdrv_new_open_driver(&bdrv_test, "bs_a", BDRV_O_RDWR, &error_abort);

    /* Create bs_b and bc_c */
    options = qdict_new();
    qdict_put_str(options, "driver", "raw");
    qdict_put_str(options, "file", "bs_a");
    qdict_put_str(options, "node-name", "bs_b");
    bs_b = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);

    options = qdict_new();
    qdict_put_str(options, "driver", "raw");
    qdict_put_str(options, "file", "bs_a");
    qdict_put_str(options, "node-name", "bs_c");
    bs_c = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);

    /* Create blkverify filter that references both bs_b and bs_c */
    options = qdict_new();
    qdict_put_str(options, "driver", "blkverify");
    qdict_put_str(options, "test", "bs_b");
    qdict_put_str(options, "raw", "bs_c");

    bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
    blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
    blk_insert_bs(blk, bs_verify, &error_abort);

    /* Switch the AioContext */
    blk_set_aio_context(blk, ctx, &error_abort);
    g_assert(blk_get_aio_context(blk) == ctx);
    g_assert(bdrv_get_aio_context(bs_verify) == ctx);
    g_assert(bdrv_get_aio_context(bs_a) == ctx);
    g_assert(bdrv_get_aio_context(bs_b) == ctx);
    g_assert(bdrv_get_aio_context(bs_c) == ctx);

    /* Switch the AioContext back */
    main_ctx = qemu_get_aio_context();
    aio_context_acquire(ctx);
    blk_set_aio_context(blk, main_ctx, &error_abort);
    aio_context_release(ctx);
    g_assert(blk_get_aio_context(blk) == main_ctx);
    g_assert(bdrv_get_aio_context(bs_verify) == main_ctx);
    g_assert(bdrv_get_aio_context(bs_a) == main_ctx);
    g_assert(bdrv_get_aio_context(bs_b) == main_ctx);
    g_assert(bdrv_get_aio_context(bs_c) == main_ctx);

    blk_unref(blk);
    bdrv_unref(bs_verify);
    bdrv_unref(bs_c);
    bdrv_unref(bs_b);
    bdrv_unref(bs_a);
}

static void test_propagate_mirror(void)
{
    IOThread *iothread = iothread_new();
    AioContext *ctx = iothread_get_aio_context(iothread);
    AioContext *main_ctx = qemu_get_aio_context();
    BlockDriverState *src, *target, *filter;
    BlockBackend *blk;
    Job *job;
    Error *local_err = NULL;

    /* Create src and target*/
    src = bdrv_new_open_driver(&bdrv_test, "src", BDRV_O_RDWR, &error_abort);
    target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR,
                                  &error_abort);

    /* Start a mirror job */
    mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0,
                 MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false,
                 BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
                 false, "filter_node", MIRROR_COPY_MODE_BACKGROUND,
                 &error_abort);
    job = job_get("job0");
    filter = bdrv_find_node("filter_node");

    /* Change the AioContext of src */
    bdrv_try_set_aio_context(src, ctx, &error_abort);
    g_assert(bdrv_get_aio_context(src) == ctx);
    g_assert(bdrv_get_aio_context(target) == ctx);
    g_assert(bdrv_get_aio_context(filter) == ctx);
    g_assert(job->aio_context == ctx);

    /* Change the AioContext of target */
    aio_context_acquire(ctx);
    bdrv_try_set_aio_context(target, main_ctx, &error_abort);
    aio_context_release(ctx);
    g_assert(bdrv_get_aio_context(src) == main_ctx);
    g_assert(bdrv_get_aio_context(target) == main_ctx);
    g_assert(bdrv_get_aio_context(filter) == main_ctx);

    /* With a BlockBackend on src, changing target must fail */
    blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
    blk_insert_bs(blk, src, &error_abort);

    bdrv_try_set_aio_context(target, ctx, &local_err);
    g_assert(local_err);
    error_free(local_err);

    g_assert(blk_get_aio_context(blk) == main_ctx);
    g_assert(bdrv_get_aio_context(src) == main_ctx);
    g_assert(bdrv_get_aio_context(target) == main_ctx);
    g_assert(bdrv_get_aio_context(filter) == main_ctx);

    /* ...unless we explicitly allow it */
    aio_context_acquire(ctx);
    blk_set_allow_aio_context_change(blk, true);
    bdrv_try_set_aio_context(target, ctx, &error_abort);
    aio_context_release(ctx);

    g_assert(blk_get_aio_context(blk) == ctx);
    g_assert(bdrv_get_aio_context(src) == ctx);
    g_assert(bdrv_get_aio_context(target) == ctx);
    g_assert(bdrv_get_aio_context(filter) == ctx);

    job_cancel_sync_all();

    aio_context_acquire(ctx);
    blk_set_aio_context(blk, main_ctx, &error_abort);
    bdrv_try_set_aio_context(target, main_ctx, &error_abort);
    aio_context_release(ctx);

    blk_unref(blk);
    bdrv_unref(src);
    bdrv_unref(target);
}

static void test_attach_second_node(void)
{
    IOThread *iothread = iothread_new();
    AioContext *ctx = iothread_get_aio_context(iothread);
    AioContext *main_ctx = qemu_get_aio_context();
    BlockBackend *blk;
    BlockDriverState *bs, *filter;
    QDict *options;

    blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL);
    bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
    blk_insert_bs(blk, bs, &error_abort);

    options = qdict_new();
    qdict_put_str(options, "driver", "raw");
    qdict_put_str(options, "file", "base");

    filter = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
    g_assert(blk_get_aio_context(blk) == ctx);
    g_assert(bdrv_get_aio_context(bs) == ctx);
    g_assert(bdrv_get_aio_context(filter) == ctx);

    aio_context_acquire(ctx);
    blk_set_aio_context(blk, main_ctx, &error_abort);
    aio_context_release(ctx);
    g_assert(blk_get_aio_context(blk) == main_ctx);
    g_assert(bdrv_get_aio_context(bs) == main_ctx);
    g_assert(bdrv_get_aio_context(filter) == main_ctx);

    bdrv_unref(filter);
    bdrv_unref(bs);
    blk_unref(blk);
}

static void test_attach_preserve_blk_ctx(void)
{
    IOThread *iothread = iothread_new();
    AioContext *ctx = iothread_get_aio_context(iothread);
    BlockBackend *blk;
    BlockDriverState *bs;

    blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL);
    bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
    bs->total_sectors = 65536 / BDRV_SECTOR_SIZE;

    /* Add node to BlockBackend that has an iothread context assigned */
    blk_insert_bs(blk, bs, &error_abort);
    g_assert(blk_get_aio_context(blk) == ctx);
    g_assert(bdrv_get_aio_context(bs) == ctx);

    /* Remove the node again */
    aio_context_acquire(ctx);
    blk_remove_bs(blk);
    aio_context_release(ctx);
    g_assert(blk_get_aio_context(blk) == ctx);
    g_assert(bdrv_get_aio_context(bs) == qemu_get_aio_context());

    /* Re-attach the node */
    blk_insert_bs(blk, bs, &error_abort);
    g_assert(blk_get_aio_context(blk) == ctx);
    g_assert(bdrv_get_aio_context(bs) == ctx);

    aio_context_acquire(ctx);
    blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
    aio_context_release(ctx);
    bdrv_unref(bs);
    blk_unref(blk);
}

int main(int argc, char **argv)
{
    int i;

    bdrv_init();
    qemu_init_main_loop(&error_abort);

    g_test_init(&argc, &argv, NULL);

    for (i = 0; i < ARRAY_SIZE(sync_op_tests); i++) {
        const SyncOpTest *t = &sync_op_tests[i];
        g_test_add_data_func(t->name, t, test_sync_op);
    }

    g_test_add_func("/attach/blockjob", test_attach_blockjob);
    g_test_add_func("/attach/second_node", test_attach_second_node);
    g_test_add_func("/attach/preserve_blk_ctx", test_attach_preserve_blk_ctx);
    g_test_add_func("/propagate/basic", test_propagate_basic);
    g_test_add_func("/propagate/diamond", test_propagate_diamond);
    g_test_add_func("/propagate/mirror", test_propagate_mirror);

    return g_test_run();
}
