Example #1
0
static void test_migrate(void)
{
    char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
    QTestState *from, *to;

    test_migrate_start(&from, &to, uri, false);

    migrate_set_capability(from, "postcopy-ram", "true");
    migrate_set_capability(to, "postcopy-ram", "true");
    migrate_set_capability(to, "postcopy-blocktime", "true");

    /* We want to pick a speed slow enough that the test completes
     * quickly, but that it doesn't complete precopy even on a slow
     * machine, so also set the downtime.
     */
    migrate_set_parameter(from, "max-bandwidth", "100000000");
    migrate_set_parameter(from, "downtime-limit", "1");

    /* Wait for the first serial output from the source */
    wait_for_serial("src_serial");

    migrate(from, uri);

    wait_for_migration_pass(from);

    migrate_start_postcopy(from);

    if (!got_stop) {
        qtest_qmp_eventwait(from, "STOP");
    }

    qtest_qmp_eventwait(to, "RESUME");

    wait_for_serial("dest_serial");
    wait_for_migration_complete(from);

    if (uffd_feature_thread_id) {
        read_blocktime(to);
    }
    g_free(uri);

    test_migrate_end(from, to, true);
}
Example #2
0
void qpci_unplug_acpi_device_test(QTestState *qts, const char *id, uint8_t slot)
{
    QDict *response;

    response = qtest_qmp(qts, "{'execute': 'device_del',"
                              " 'arguments': {'id': %s}}", id);
    g_assert(response);
    g_assert(!qdict_haskey(response, "error"));
    qobject_unref(response);

    qtest_outb(qts, ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot);

    qtest_qmp_eventwait(qts, "DEVICE_DELETED");
}
Example #3
0
File: libqos.c Project: stweil/qemu
void migrate(QOSState *from, QOSState *to, const char *uri)
{
    const char *st;
    QDict *rsp, *sub;
    bool running;

    set_context(from);

    /* Is the machine currently running? */
    rsp = qmp_execute(from->qts, "query-status");
    g_assert(qdict_haskey(rsp, "return"));
    sub = qdict_get_qdict(rsp, "return");
    g_assert(qdict_haskey(sub, "running"));
    running = qdict_get_bool(sub, "running");
    qobject_unref(rsp);

    /* Issue the migrate command. */
    rsp = qtest_qmp(from->qts,
                    "{ 'execute': 'migrate', 'arguments': { 'uri': %s }}",
                    uri);
    g_assert(qdict_haskey(rsp, "return"));
    qobject_unref(rsp);

    /* Wait for STOP event, but only if we were running: */
    if (running) {
        qtest_qmp_eventwait(from->qts, "STOP");
    }

    /* If we were running, we can wait for an event. */
    if (running) {
        migrate_allocator(from->alloc, to->alloc);
        set_context(to);
        qtest_qmp_eventwait(to->qts, "RESUME");
        return;
    }

    /* Otherwise, we need to wait: poll until migration is completed. */
    while (1) {
        rsp = qmp_execute(from->qts, "query-migrate");
        g_assert(qdict_haskey(rsp, "return"));
        sub = qdict_get_qdict(rsp, "return");
        g_assert(qdict_haskey(sub, "status"));
        st = qdict_get_str(sub, "status");

        /* "setup", "active", "completed", "failed", "cancelled" */
        if (strcmp(st, "completed") == 0) {
            qobject_unref(rsp);
            break;
        }

        if ((strcmp(st, "setup") == 0) || (strcmp(st, "active") == 0)) {
            qobject_unref(rsp);
            g_usleep(5000);
            continue;
        }

        fprintf(stderr, "Migration did not complete, status: %s\n", st);
        g_assert_not_reached();
    }

    migrate_allocator(from->alloc, to->alloc);
    set_context(to);
}
Example #4
0
static void test_migrate(void)
{
    TestServer *s = test_server_new("src");
    TestServer *dest = test_server_new("dest");
    char *uri = g_strdup_printf("%s%s", "unix:", dest->mig_path);
    QTestState *from, *to;
    GSource *source;
    gchar *cmd, *tmp;
    QDict *rsp;
    guint8 *log;
    guint64 size;

    test_server_listen(s);
    test_server_listen(dest);

    cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, "", "");
    from = qtest_start(cmd);
    g_free(cmd);

    init_virtio_dev(from, s, 1u << VIRTIO_NET_F_MAC);
    if (!wait_for_fds(s)) {
        goto exit;
    }

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

    tmp = g_strdup_printf(" -incoming %s", uri);
    cmd = get_qemu_cmd(dest, 2, TEST_MEMFD_AUTO, root, "", tmp);
    g_free(tmp);
    to = qtest_init(cmd);
    g_free(cmd);
    init_virtio_dev(to, dest, 1u << VIRTIO_NET_F_MAC);

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

    /* slow down migration to have time to fiddle with log */
    /* TODO: qtest could learn to break on some places */
    rsp = qmp("{ 'execute': 'migrate_set_speed',"
              "'arguments': { 'value': 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_speed',"
              "'arguments': { 'value': 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);

    uninit_virtio_dev(dest);
    qtest_quit(to);

    g_source_destroy(source);
    g_source_unref(source);

exit:
    uninit_virtio_dev(s);

    test_server_free(dest);
    qtest_quit(from);
    test_server_free(s);
    g_free(uri);
}