/*
 * QTest testcase for the vhost-user
 *
 * Copyright (c) 2014 Virtual Open Systems Sarl.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"

#include "libqtest-single.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/range.h"
#include "qemu/sockets.h"
#include "chardev/char-fe.h"
#include "qemu/memfd.h"
#include "qemu/module.h"
#include "sysemu/sysemu.h"
#include "libqos/libqos.h"
#include "libqos/pci-pc.h"
#include "libqos/virtio-pci.h"

#include "libqos/malloc-pc.h"
#include "libqos/qgraph_internal.h"
#include "hw/virtio/virtio-net.h"

#include "standard-headers/linux/vhost_types.h"
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/virtio_net.h"
#include "standard-headers/linux/virtio_gpio.h"

#ifdef CONFIG_LINUX
#include <sys/vfs.h>
#endif


#define QEMU_CMD_MEM    " -m %d -object memory-backend-file,id=mem,size=%dM," \
                        "mem-path=%s,share=on -numa node,memdev=mem"
#define QEMU_CMD_MEMFD  " -m %d -object memory-backend-memfd,id=mem,size=%dM," \
                        " -numa node,memdev=mem"
#define QEMU_CMD_CHR    " -chardev socket,id=%s,path=%s%s"
#define QEMU_CMD_NETDEV " -netdev vhost-user,id=hs0,chardev=%s,vhostforce=on"

#define HUGETLBFS_MAGIC       0x958458f6

/*********** FROM hw/virtio/vhost-user.c *************************************/

#define VHOST_MEMORY_MAX_NREGIONS    8
#define VHOST_MAX_VIRTQUEUES    0x100

#define VHOST_USER_F_PROTOCOL_FEATURES 30
#define VIRTIO_F_VERSION_1 32

#define VHOST_USER_PROTOCOL_F_MQ 0
#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
#define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN   6
#define VHOST_USER_PROTOCOL_F_CONFIG 9

#define VHOST_LOG_PAGE 0x1000

typedef enum VhostUserRequest {
    VHOST_USER_NONE = 0,
    VHOST_USER_GET_FEATURES = 1,
    VHOST_USER_SET_FEATURES = 2,
    VHOST_USER_SET_OWNER = 3,
    VHOST_USER_RESET_OWNER = 4,
    VHOST_USER_SET_MEM_TABLE = 5,
    VHOST_USER_SET_LOG_BASE = 6,
    VHOST_USER_SET_LOG_FD = 7,
    VHOST_USER_SET_VRING_NUM = 8,
    VHOST_USER_SET_VRING_ADDR = 9,
    VHOST_USER_SET_VRING_BASE = 10,
    VHOST_USER_GET_VRING_BASE = 11,
    VHOST_USER_SET_VRING_KICK = 12,
    VHOST_USER_SET_VRING_CALL = 13,
    VHOST_USER_SET_VRING_ERR = 14,
    VHOST_USER_GET_PROTOCOL_FEATURES = 15,
    VHOST_USER_SET_PROTOCOL_FEATURES = 16,
    VHOST_USER_GET_QUEUE_NUM = 17,
    VHOST_USER_SET_VRING_ENABLE = 18,
    VHOST_USER_GET_CONFIG = 24,
    VHOST_USER_SET_CONFIG = 25,
    VHOST_USER_MAX
} VhostUserRequest;

typedef struct VhostUserMemoryRegion {
    uint64_t guest_phys_addr;
    uint64_t memory_size;
    uint64_t userspace_addr;
    uint64_t mmap_offset;
} VhostUserMemoryRegion;

typedef struct VhostUserMemory {
    uint32_t nregions;
    uint32_t padding;
    VhostUserMemoryRegion regions[VHOST_MEMORY_MAX_NREGIONS];
} VhostUserMemory;

typedef struct VhostUserLog {
    uint64_t mmap_size;
    uint64_t mmap_offset;
} VhostUserLog;

typedef struct VhostUserMsg {
    VhostUserRequest request;

#define VHOST_USER_VERSION_MASK     (0x3)
#define VHOST_USER_REPLY_MASK       (0x1<<2)
    uint32_t flags;
    uint32_t size; /* the following payload size */
    union {
#define VHOST_USER_VRING_IDX_MASK   (0xff)
#define VHOST_USER_VRING_NOFD_MASK  (0x1<<8)
        uint64_t u64;
        struct vhost_vring_state state;
        struct vhost_vring_addr addr;
        VhostUserMemory memory;
        VhostUserLog log;
    } payload;
} QEMU_PACKED VhostUserMsg;

static VhostUserMsg m __attribute__ ((unused));
#define VHOST_USER_HDR_SIZE (sizeof(m.request) \
                            + sizeof(m.flags) \
                            + sizeof(m.size))

#define VHOST_USER_PAYLOAD_SIZE (sizeof(m) - VHOST_USER_HDR_SIZE)

/* The version of the protocol we support */
#define VHOST_USER_VERSION    (0x1)
/*****************************************************************************/

enum {
    TEST_FLAGS_OK,
    TEST_FLAGS_DISCONNECT,
    TEST_FLAGS_BAD,
    TEST_FLAGS_END,
};

enum {
    VHOST_USER_NET,
    VHOST_USER_GPIO,
};

typedef struct TestServer {
    gchar *socket_path;
    gchar *mig_path;
    gchar *chr_name;
    gchar *tmpfs;
    CharBackend chr;
    int fds_num;
    int fds[VHOST_MEMORY_MAX_NREGIONS];
    VhostUserMemory memory;
    GMainContext *context;
    GMainLoop *loop;
    GThread *thread;
    GMutex data_mutex;
    GCond data_cond;
    int log_fd;
    uint64_t rings;
    bool test_fail;
    int test_flags;
    int queues;
    struct vhost_user_ops *vu_ops;
} TestServer;

struct vhost_user_ops {
    /* Device types. */
    int type;
    void (*append_opts)(TestServer *s, GString *cmd_line,
            const char *chr_opts);

    /* VHOST-USER commands. */
    uint64_t (*get_features)(TestServer *s);
    void (*set_features)(TestServer *s, CharBackend *chr,
                         VhostUserMsg *msg);
    void (*get_protocol_features)(TestServer *s,
                                  CharBackend *chr, VhostUserMsg *msg);
};

static const char *init_hugepagefs(void);
static TestServer *test_server_new(const gchar *name,
        struct vhost_user_ops *ops);
static void test_server_free(TestServer *server);
static void test_server_listen(TestServer *server);

enum test_memfd {
    TEST_MEMFD_AUTO,
    TEST_MEMFD_YES,
    TEST_MEMFD_NO,
};

static void append_vhost_net_opts(TestServer *s, GString *cmd_line,
                             const char *chr_opts)
{
    g_string_append_printf(cmd_line, QEMU_CMD_CHR QEMU_CMD_NETDEV,
                           s->chr_name, s->socket_path,
                           chr_opts, s->chr_name);
}

/*
 * For GPIO there are no other magic devices we need to add (like
 * block or netdev) so all we need to worry about is the vhost-user
 * chardev socket.
 */
static void append_vhost_gpio_opts(TestServer *s, GString *cmd_line,
                             const char *chr_opts)
{
    g_string_append_printf(cmd_line, QEMU_CMD_CHR,
                           s->chr_name, s->socket_path,
                           chr_opts);
}

static void append_mem_opts(TestServer *server, GString *cmd_line,
                            int size, enum test_memfd memfd)
{
    if (memfd == TEST_MEMFD_AUTO) {
        memfd = qemu_memfd_check(MFD_ALLOW_SEALING) ? TEST_MEMFD_YES
                                                    : TEST_MEMFD_NO;
    }

    if (memfd == TEST_MEMFD_YES) {
        g_string_append_printf(cmd_line, QEMU_CMD_MEMFD, size, size);
    } else {
        const char *root = init_hugepagefs() ? : server->tmpfs;

        g_string_append_printf(cmd_line, QEMU_CMD_MEM, size, size, root);
    }
}

static bool wait_for_fds(TestServer *s)
{
    gint64 end_time;
    bool got_region;
    int i;

    g_mutex_lock(&s->data_mutex);

    end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
    while (!s->fds_num) {
        if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
            /* timeout has passed */
            g_assert(s->fds_num);
            break;
        }
    }

    /* check for sanity */
    g_assert_cmpint(s->fds_num, >, 0);
    g_assert_cmpint(s->fds_num, ==, s->memory.nregions);

    g_mutex_unlock(&s->data_mutex);

    got_region = false;
    for (i = 0; i < s->memory.nregions; ++i) {
        VhostUserMemoryRegion *reg = &s->memory.regions[i];
        if (reg->guest_phys_addr == 0) {
            got_region = true;
            break;
        }
    }
    if (!got_region) {
        g_test_skip("No memory at address 0x0");
    }
    return got_region;
}

static void read_guest_mem_server(QTestState *qts, TestServer *s)
{
    uint8_t *guest_mem;
    int i, j;
    size_t size;

    g_mutex_lock(&s->data_mutex);

    /* iterate all regions */
    for (i = 0; i < s->fds_num; i++) {

        /* We'll check only the region statring at 0x0*/
        if (s->memory.regions[i].guest_phys_addr != 0x0) {
            continue;
        }

        g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024);

        size = s->memory.regions[i].memory_size +
            s->memory.regions[i].mmap_offset;

        guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
                         MAP_SHARED, s->fds[i], 0);

        g_assert(guest_mem != MAP_FAILED);
        guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem));

        for (j = 0; j < 1024; j++) {
            uint32_t a = qtest_readb(qts, s->memory.regions[i].guest_phys_addr + j);
            uint32_t b = guest_mem[j];

            g_assert_cmpint(a, ==, b);
        }

        munmap(guest_mem, s->memory.regions[i].memory_size);
    }

    g_mutex_unlock(&s->data_mutex);
}

static void *thread_function(void *data)
{
    GMainLoop *loop = data;
    g_main_loop_run(loop);
    return NULL;
}

static int chr_can_read(void *opaque)
{
    return VHOST_USER_HDR_SIZE;
}

static void chr_read(void *opaque, const uint8_t *buf, int size)
{
    g_autoptr(GError) err = NULL;
    TestServer *s = opaque;
    CharBackend *chr = &s->chr;
    VhostUserMsg msg;
    uint8_t *p = (uint8_t *) &msg;
    int fd = -1;

    if (s->test_fail) {
        qemu_chr_fe_disconnect(chr);
        /* now switch to non-failure */
        s->test_fail = false;
    }

    if (size != VHOST_USER_HDR_SIZE) {
        qos_printf("%s: Wrong message size received %d\n", __func__, size);
        return;
    }

    g_mutex_lock(&s->data_mutex);
    memcpy(p, buf, VHOST_USER_HDR_SIZE);

    if (msg.size) {
        p += VHOST_USER_HDR_SIZE;
        size = qemu_chr_fe_read_all(chr, p, msg.size);
        if (size != msg.size) {
            qos_printf("%s: Wrong message size received %d != %d\n",
                       __func__, size, msg.size);
            return;
        }
    }

    switch (msg.request) {
    case VHOST_USER_GET_FEATURES:
        /* Mandatory for tests to define get_features */
        g_assert(s->vu_ops->get_features);

        /* send back features to qemu */
        msg.flags |= VHOST_USER_REPLY_MASK;
        msg.size = sizeof(m.payload.u64);

        if (s->test_flags >= TEST_FLAGS_BAD) {
            msg.payload.u64 = 0;
            s->test_flags = TEST_FLAGS_END;
        } else {
            msg.payload.u64 = s->vu_ops->get_features(s);
        }

        qemu_chr_fe_write_all(chr, (uint8_t *) &msg,
                              VHOST_USER_HDR_SIZE + msg.size);
        break;

    case VHOST_USER_SET_FEATURES:
        if (s->vu_ops->set_features) {
            s->vu_ops->set_features(s, chr, &msg);
        }
        break;

    case VHOST_USER_SET_OWNER:
        /*
         * We don't need to do anything here, the remote is just
         * letting us know it is in charge. Just log it.
         */
        qos_printf("set_owner: start of session\n");
        break;

    case VHOST_USER_GET_PROTOCOL_FEATURES:
        if (s->vu_ops->get_protocol_features) {
            s->vu_ops->get_protocol_features(s, chr, &msg);
        }
        break;

    case VHOST_USER_GET_CONFIG:
        /*
         * Treat GET_CONFIG as a NOP and just reply and let the guest
         * consider we have updated its memory. Tests currently don't
         * require working configs.
         */
        msg.flags |= VHOST_USER_REPLY_MASK;
        p = (uint8_t *) &msg;
        qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
        break;

    case VHOST_USER_SET_PROTOCOL_FEATURES:
        /*
         * We did set VHOST_USER_F_PROTOCOL_FEATURES so its valid for
         * the remote end to send this. There is no handshake reply so
         * just log the details for debugging.
         */
        qos_printf("set_protocol_features: 0x%"PRIx64 "\n", msg.payload.u64);
        break;

        /*
         * A real vhost-user backend would actually set the size and
         * address of the vrings but we can simply report them.
         */
    case VHOST_USER_SET_VRING_NUM:
        qos_printf("set_vring_num: %d/%d\n",
                   msg.payload.state.index, msg.payload.state.num);
        break;
    case VHOST_USER_SET_VRING_ADDR:
        qos_printf("set_vring_addr: 0x%"PRIx64"/0x%"PRIx64"/0x%"PRIx64"\n",
                   msg.payload.addr.avail_user_addr,
                   msg.payload.addr.desc_user_addr,
                   msg.payload.addr.used_user_addr);
        break;

    case VHOST_USER_GET_VRING_BASE:
        /* send back vring base to qemu */
        msg.flags |= VHOST_USER_REPLY_MASK;
        msg.size = sizeof(m.payload.state);
        msg.payload.state.num = 0;
        p = (uint8_t *) &msg;
        qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);

        assert(msg.payload.state.index < s->queues * 2);
        s->rings &= ~(0x1ULL << msg.payload.state.index);
        g_cond_broadcast(&s->data_cond);
        break;

    case VHOST_USER_SET_MEM_TABLE:
        /* received the mem table */
        memcpy(&s->memory, &msg.payload.memory, sizeof(msg.payload.memory));
        s->fds_num = qemu_chr_fe_get_msgfds(chr, s->fds,
                                            G_N_ELEMENTS(s->fds));

        /* signal the test that it can continue */
        g_cond_broadcast(&s->data_cond);
        break;

    case VHOST_USER_SET_VRING_KICK:
    case VHOST_USER_SET_VRING_CALL:
        /* consume the fd */
        qemu_chr_fe_get_msgfds(chr, &fd, 1);
        /*
         * This is a non-blocking eventfd.
         * The receive function forces it to be blocking,
         * so revert it back to non-blocking.
         */
        g_unix_set_fd_nonblocking(fd, true, &err);
        g_assert_no_error(err);
        break;

    case VHOST_USER_SET_LOG_BASE:
        if (s->log_fd != -1) {
            close(s->log_fd);
            s->log_fd = -1;
        }
        qemu_chr_fe_get_msgfds(chr, &s->log_fd, 1);
        msg.flags |= VHOST_USER_REPLY_MASK;
        msg.size = 0;
        p = (uint8_t *) &msg;
        qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE);

        g_cond_broadcast(&s->data_cond);
        break;

    case VHOST_USER_SET_VRING_BASE:
        assert(msg.payload.state.index < s->queues * 2);
        s->rings |= 0x1ULL << msg.payload.state.index;
        g_cond_broadcast(&s->data_cond);
        break;

    case VHOST_USER_GET_QUEUE_NUM:
        msg.flags |= VHOST_USER_REPLY_MASK;
        msg.size = sizeof(m.payload.u64);
        msg.payload.u64 = s->queues;
        p = (uint8_t *) &msg;
        qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
        break;

    case VHOST_USER_SET_VRING_ENABLE:
        /*
         * Another case we ignore as we don't need to respond. With a
         * fully functioning vhost-user we would enable/disable the
         * vring monitoring.
         */
        qos_printf("set_vring(%d)=%s\n", msg.payload.state.index,
                   msg.payload.state.num ? "enabled" : "disabled");
        break;

    default:
        qos_printf("vhost-user: un-handled message: %d\n", msg.request);
        break;
    }

    g_mutex_unlock(&s->data_mutex);
}

static const char *init_hugepagefs(void)
{
#ifdef CONFIG_LINUX
    static const char *hugepagefs;
    const char *path = getenv("QTEST_HUGETLBFS_PATH");
    struct statfs fs;
    int ret;

    if (hugepagefs) {
        return hugepagefs;
    }
    if (!path) {
        return NULL;
    }

    if (access(path, R_OK | W_OK | X_OK)) {
        qos_printf("access on path (%s): %s", path, strerror(errno));
        g_test_fail();
        return NULL;
    }

    do {
        ret = statfs(path, &fs);
    } while (ret != 0 && errno == EINTR);

    if (ret != 0) {
        qos_printf("statfs on path (%s): %s", path, strerror(errno));
        g_test_fail();
        return NULL;
    }

    if (fs.f_type != HUGETLBFS_MAGIC) {
        qos_printf("Warning: path not on HugeTLBFS: %s", path);
        g_test_fail();
        return NULL;
    }

    hugepagefs = path;
    return hugepagefs;
#else
    return NULL;
#endif
}

static TestServer *test_server_new(const gchar *name,
        struct vhost_user_ops *ops)
{
    TestServer *server = g_new0(TestServer, 1);
    g_autofree const char *tmpfs = NULL;
    GError *err = NULL;

    server->context = g_main_context_new();
    server->loop = g_main_loop_new(server->context, FALSE);

    /* run the main loop thread so the chardev may operate */
    server->thread = g_thread_new(NULL, thread_function, server->loop);

    tmpfs = g_dir_make_tmp("vhost-test-XXXXXX", &err);
    if (!tmpfs) {
        g_test_message("Can't create temporary directory in %s: %s",
                       g_get_tmp_dir(), err->message);
        g_error_free(err);
    }
    g_assert(tmpfs);

    server->tmpfs = g_strdup(tmpfs);
    server->socket_path = g_strdup_printf("%s/%s.sock", tmpfs, name);
    server->mig_path = g_strdup_printf("%s/%s.mig", tmpfs, name);
    server->chr_name = g_strdup_printf("chr-%s", name);

    g_mutex_init(&server->data_mutex);
    g_cond_init(&server->data_cond);

    server->log_fd = -1;
    server->queues = 1;
    server->vu_ops = ops;

    return server;
}

static void chr_event(void *opaque, QEMUChrEvent event)
{
    TestServer *s = opaque;

    if (s->test_flags == TEST_FLAGS_END &&
        event == CHR_EVENT_CLOSED) {
        s->test_flags = TEST_FLAGS_OK;
    }
}

static void test_server_create_chr(TestServer *server, const gchar *opt)
{
    g_autofree gchar *chr_path = g_strdup_printf("unix:%s%s",
                                                 server->socket_path, opt);
    Chardev *chr;

    chr = qemu_chr_new(server->chr_name, chr_path, server->context);
    g_assert(chr);

    qemu_chr_fe_init(&server->chr, chr, &error_abort);
    qemu_chr_fe_set_handlers(&server->chr, chr_can_read, chr_read,
                             chr_event, NULL, server, server->context, true);
}

static void test_server_listen(TestServer *server)
{
    test_server_create_chr(server, ",server=on,wait=off");
}

static void test_server_free(TestServer *server)
{
    int i, ret;

    /* finish the helper thread and dispatch pending sources */
    g_main_loop_quit(server->loop);
    g_thread_join(server->thread);
    while (g_main_context_pending(NULL)) {
        g_main_context_iteration(NULL, TRUE);
    }

    unlink(server->socket_path);
    g_free(server->socket_path);

    unlink(server->mig_path);
    g_free(server->mig_path);

    ret = rmdir(server->tmpfs);
    if (ret != 0) {
        g_test_message("unable to rmdir: path (%s): %s",
                       server->tmpfs, strerror(errno));
    }
    g_free(server->tmpfs);

    qemu_chr_fe_deinit(&server->chr, true);

    for (i = 0; i < server->fds_num; i++) {
        close(server->fds[i]);
    }

    if (server->log_fd != -1) {
        close(server->log_fd);
    }

    g_free(server->chr_name);

    g_main_loop_unref(server->loop);
    g_main_context_unref(server->context);
    g_cond_clear(&server->data_cond);
    g_mutex_clear(&server->data_mutex);
    g_free(server);
}

static void wait_for_log_fd(TestServer *s)
{
    gint64 end_time;

    g_mutex_lock(&s->data_mutex);
    end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
    while (s->log_fd == -1) {
        if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
            /* timeout has passed */
            g_assert(s->log_fd != -1);
            break;
        }
    }

    g_mutex_unlock(&s->data_mutex);
}

static void write_guest_mem(TestServer *s, uint32_t seed)
{
    uint32_t *guest_mem;
    int i, j;
    size_t size;

    /* iterate all regions */
    for (i = 0; i < s->fds_num; i++) {

        /* We'll write only the region statring at 0x0 */
        if (s->memory.regions[i].guest_phys_addr != 0x0) {
            continue;
        }

        g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024);

        size = s->memory.regions[i].memory_size +
            s->memory.regions[i].mmap_offset;

        guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
                         MAP_SHARED, s->fds[i], 0);

        g_assert(guest_mem != MAP_FAILED);
        guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem));

        for (j = 0; j < 256; j++) {
            guest_mem[j] = seed + j;
        }

        munmap(guest_mem, s->memory.regions[i].memory_size);
        break;
    }
}

static guint64 get_log_size(TestServer *s)
{
    guint64 log_size = 0;
    int i;

    for (i = 0; i < s->memory.nregions; ++i) {
        VhostUserMemoryRegion *reg = &s->memory.regions[i];
        guint64 last = range_get_last(reg->guest_phys_addr,
                                       reg->memory_size);
        log_size = MAX(log_size, last / (8 * VHOST_LOG_PAGE) + 1);
    }

    return log_size;
}

typedef struct TestMigrateSource {
    GSource source;
    TestServer *src;
    TestServer *dest;
} TestMigrateSource;

static gboolean
test_migrate_source_check(GSource *source)
{
    TestMigrateSource *t = (TestMigrateSource *)source;
    gboolean overlap = t->src->rings && t->dest->rings;

    g_assert(!overlap);

    return FALSE;
}

GSourceFuncs test_migrate_source_funcs = {
    .check = test_migrate_source_check,
};

static void vhost_user_test_cleanup(void *s)
{
    TestServer *server = s;

    qos_invalidate_command_line();
    test_server_free(server);
}

static void *vhost_user_test_setup(GString *cmd_line, void *arg)
{
    TestServer *server = test_server_new("vhost-user-test", arg);
    test_server_listen(server);

    append_mem_opts(server, cmd_line, 256, TEST_MEMFD_AUTO);
    server->vu_ops->append_opts(server, cmd_line, "");

    g_test_queue_destroy(vhost_user_test_cleanup, server);

    return server;
}

static void *vhost_user_test_setup_memfd(GString *cmd_line, void *arg)
{
    TestServer *server = test_server_new("vhost-user-test", arg);
    test_server_listen(server);

    append_mem_opts(server, cmd_line, 256, TEST_MEMFD_YES);
    server->vu_ops->append_opts(server, cmd_line, "");

    g_test_queue_destroy(vhost_user_test_cleanup, server);

    return server;
}

static void test_read_guest_mem(void *obj, void *arg, QGuestAllocator *alloc)
{
    TestServer *server = arg;

    if (!wait_for_fds(server)) {
        return;
    }

    read_guest_mem_server(global_qtest, server);
}

static void test_migrate(void *obj, void *arg, QGuestAllocator *alloc)
{
    TestServer *s = arg;
    TestServer *dest;
    GString *dest_cmdline;
    char *uri;
    QTestState *to;
    GSource *source;
    QDict *rsp;
    guint8 *log;
    guint64 size;

    if (!wait_for_fds(s)) {
        return;
    }

    dest = test_server_new("dest", s->vu_ops);
    dest_cmdline = g_string_new(qos_get_current_command_line());
    uri = g_strdup_printf("%s%s", "unix:", dest->mig_path);

    size = get_log_size(s);
    g_assert_cmpint(size, ==, (256 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));

    test_server_listen(dest);
    g_string_append_printf(dest_cmdline, " -incoming %s", uri);
    append_mem_opts(dest, dest_cmdline, 256, TEST_MEMFD_AUTO);
    dest->vu_ops->append_opts(dest, dest_cmdline, "");
    to = qtest_init(dest_cmdline->str);

    /* This would be where you call qos_allocate_objects(to, NULL), if you want
     * to talk to the QVirtioNet object on the destination.
     */

    source = g_source_new(&test_migrate_source_funcs,
                          sizeof(TestMigrateSource));
    ((TestMigrateSource *)source)->src = s;
    ((TestMigrateSource *)source)->dest = dest;
    g_source_attach(source, s->context);

    /* slow down migration to have time to fiddle with log */
    /* TODO: qtest could learn to break on some places */
    rsp = qmp("{ 'execute': 'migrate-set-parameters',"
              "'arguments': { 'max-bandwidth': 10 } }");
    g_assert(qdict_haskey(rsp, "return"));
    qobject_unref(rsp);

    rsp = qmp("{ 'execute': 'migrate', 'arguments': { 'uri': %s } }", uri);
    g_assert(qdict_haskey(rsp, "return"));
    qobject_unref(rsp);

    wait_for_log_fd(s);

    log = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, s->log_fd, 0);
    g_assert(log != MAP_FAILED);

    /* modify first page */
    write_guest_mem(s, 0x42);
    log[0] = 1;
    munmap(log, size);

    /* speed things up */
    rsp = qmp("{ 'execute': 'migrate-set-parameters',"
              "'arguments': { 'max-bandwidth': 0 } }");
    g_assert(qdict_haskey(rsp, "return"));
    qobject_unref(rsp);

    qmp_eventwait("STOP");
    qtest_qmp_eventwait(to, "RESUME");

    g_assert(wait_for_fds(dest));
    read_guest_mem_server(to, dest);

    g_source_destroy(source);
    g_source_unref(source);

    qtest_quit(to);
    test_server_free(dest);
    g_free(uri);
    g_string_free(dest_cmdline, true);
}

static void wait_for_rings_started(TestServer *s, size_t count)
{
    gint64 end_time;

    g_mutex_lock(&s->data_mutex);
    end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
    while (ctpop64(s->rings) != count) {
        if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
            /* timeout has passed */
            g_assert_cmpint(ctpop64(s->rings), ==, count);
            break;
        }
    }

    g_mutex_unlock(&s->data_mutex);
}

static inline void test_server_connect(TestServer *server)
{
    test_server_create_chr(server, ",reconnect=1");
}

static gboolean
reconnect_cb(gpointer user_data)
{
    TestServer *s = user_data;

    qemu_chr_fe_disconnect(&s->chr);

    return FALSE;
}

static gpointer
connect_thread(gpointer data)
{
    TestServer *s = data;

    /* wait for qemu to start before first try, to avoid extra warnings */
    g_usleep(G_USEC_PER_SEC);
    test_server_connect(s);

    return NULL;
}

static void *vhost_user_test_setup_reconnect(GString *cmd_line, void *arg)
{
    TestServer *s = test_server_new("reconnect", arg);

    g_thread_new("connect", connect_thread, s);
    append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
    s->vu_ops->append_opts(s, cmd_line, ",server=on");

    g_test_queue_destroy(vhost_user_test_cleanup, s);

    return s;
}

static void test_reconnect(void *obj, void *arg, QGuestAllocator *alloc)
{
    TestServer *s = arg;
    GSource *src;

    if (!wait_for_fds(s)) {
        return;
    }

    wait_for_rings_started(s, 2);

    /* reconnect */
    s->fds_num = 0;
    s->rings = 0;
    src = g_idle_source_new();
    g_source_set_callback(src, reconnect_cb, s, NULL);
    g_source_attach(src, s->context);
    g_source_unref(src);
    g_assert(wait_for_fds(s));
    wait_for_rings_started(s, 2);
}

static void *vhost_user_test_setup_connect_fail(GString *cmd_line, void *arg)
{
    TestServer *s = test_server_new("connect-fail", arg);

    s->test_fail = true;

    g_thread_new("connect", connect_thread, s);
    append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
    s->vu_ops->append_opts(s, cmd_line, ",server=on");

    g_test_queue_destroy(vhost_user_test_cleanup, s);

    return s;
}

static void *vhost_user_test_setup_flags_mismatch(GString *cmd_line, void *arg)
{
    TestServer *s = test_server_new("flags-mismatch", arg);

    s->test_flags = TEST_FLAGS_DISCONNECT;

    g_thread_new("connect", connect_thread, s);
    append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
    s->vu_ops->append_opts(s, cmd_line, ",server=on");

    g_test_queue_destroy(vhost_user_test_cleanup, s);

    return s;
}

static void test_vhost_user_started(void *obj, void *arg, QGuestAllocator *alloc)
{
    TestServer *s = arg;

    if (!wait_for_fds(s)) {
        return;
    }
    wait_for_rings_started(s, 2);
}

static void *vhost_user_test_setup_multiqueue(GString *cmd_line, void *arg)
{
    TestServer *s = vhost_user_test_setup(cmd_line, arg);

    s->queues = 2;
    g_string_append_printf(cmd_line,
                           " -set netdev.hs0.queues=%d"
                           " -global virtio-net-pci.vectors=%d",
                           s->queues, s->queues * 2 + 2);

    return s;
}

static void test_multiqueue(void *obj, void *arg, QGuestAllocator *alloc)
{
    TestServer *s = arg;

    wait_for_rings_started(s, s->queues * 2);
}


static uint64_t vu_net_get_features(TestServer *s)
{
    uint64_t features = 0x1ULL << VHOST_F_LOG_ALL |
        0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES;

    if (s->queues > 1) {
        features |= 0x1ULL << VIRTIO_NET_F_MQ;
    }

    return features;
}

static void vu_net_set_features(TestServer *s, CharBackend *chr,
                                VhostUserMsg *msg)
{
    g_assert(msg->payload.u64 & (0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES));
    if (s->test_flags == TEST_FLAGS_DISCONNECT) {
        qemu_chr_fe_disconnect(chr);
        s->test_flags = TEST_FLAGS_BAD;
    }
}

static void vu_net_get_protocol_features(TestServer *s, CharBackend *chr,
        VhostUserMsg *msg)
{
    /* send back features to qemu */
    msg->flags |= VHOST_USER_REPLY_MASK;
    msg->size = sizeof(m.payload.u64);
    msg->payload.u64 = 1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD;
    msg->payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_CROSS_ENDIAN;
    if (s->queues > 1) {
        msg->payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_MQ;
    }
    qemu_chr_fe_write_all(chr, (uint8_t *)msg, VHOST_USER_HDR_SIZE + msg->size);
}

/* Each VHOST-USER device should have its ops structure defined. */
static struct vhost_user_ops g_vu_net_ops = {
    .type = VHOST_USER_NET,

    .append_opts = append_vhost_net_opts,

    .get_features = vu_net_get_features,
    .set_features = vu_net_set_features,
    .get_protocol_features = vu_net_get_protocol_features,
};

static void register_vhost_user_test(void)
{
    QOSGraphTestOptions opts = {
        .before = vhost_user_test_setup,
        .subprocess = true,
        .arg = &g_vu_net_ops,
    };

    qemu_add_opts(&qemu_chardev_opts);

    qos_add_test("vhost-user/read-guest-mem/memfile",
                 "virtio-net",
                 test_read_guest_mem, &opts);

    if (qemu_memfd_check(MFD_ALLOW_SEALING)) {
        opts.before = vhost_user_test_setup_memfd;
        qos_add_test("vhost-user/read-guest-mem/memfd",
                     "virtio-net",
                     test_read_guest_mem, &opts);
    }

    qos_add_test("vhost-user/migrate",
                 "virtio-net",
                 test_migrate, &opts);

    opts.before = vhost_user_test_setup_reconnect;
    qos_add_test("vhost-user/reconnect", "virtio-net",
                 test_reconnect, &opts);

    opts.before = vhost_user_test_setup_connect_fail;
    qos_add_test("vhost-user/connect-fail", "virtio-net",
                 test_vhost_user_started, &opts);

    opts.before = vhost_user_test_setup_flags_mismatch;
    qos_add_test("vhost-user/flags-mismatch", "virtio-net",
                 test_vhost_user_started, &opts);

    opts.before = vhost_user_test_setup_multiqueue;
    opts.edge.extra_device_opts = "mq=on";
    qos_add_test("vhost-user/multiqueue",
                 "virtio-net",
                 test_multiqueue, &opts);
}
libqos_init(register_vhost_user_test);

static uint64_t vu_gpio_get_features(TestServer *s)
{
    return 0x1ULL << VIRTIO_F_VERSION_1 |
        0x1ULL << VIRTIO_GPIO_F_IRQ |
        0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
}

/*
 * This stub can't handle all the message types but we should reply
 * that we support VHOST_USER_PROTOCOL_F_CONFIG as gpio would use it
 * talking to a read vhost-user daemon.
 */
static void vu_gpio_get_protocol_features(TestServer *s, CharBackend *chr,
                                          VhostUserMsg *msg)
{
    /* send back features to qemu */
    msg->flags |= VHOST_USER_REPLY_MASK;
    msg->size = sizeof(m.payload.u64);
    msg->payload.u64 = 1ULL << VHOST_USER_PROTOCOL_F_CONFIG;

    qemu_chr_fe_write_all(chr, (uint8_t *)msg, VHOST_USER_HDR_SIZE + msg->size);
}

static struct vhost_user_ops g_vu_gpio_ops = {
    .type = VHOST_USER_GPIO,

    .append_opts = append_vhost_gpio_opts,

    .get_features = vu_gpio_get_features,
    .set_features = vu_net_set_features,
    .get_protocol_features = vu_gpio_get_protocol_features,
};

static void register_vhost_gpio_test(void)
{
    QOSGraphTestOptions opts = {
        .before = vhost_user_test_setup,
        .subprocess = true,
        .arg = &g_vu_gpio_ops,
    };

    qemu_add_opts(&qemu_chardev_opts);

    qos_add_test("read-guest-mem/memfile",
                 "vhost-user-gpio", test_read_guest_mem, &opts);
}
libqos_init(register_vhost_gpio_test);
