qemu/tests/migration-test.c
<<
>>
Prefs
   1/*
   2 * QTest testcase for migration
   3 *
   4 * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
   5 *   based on the vhost-user-test.c that is:
   6 *      Copyright (c) 2014 Virtual Open Systems Sarl.
   7 *
   8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
   9 * See the COPYING file in the top-level directory.
  10 *
  11 */
  12
  13#include "qemu/osdep.h"
  14
  15#include "libqtest.h"
  16#include "qapi/qmp/qdict.h"
  17#include "qapi/qmp/qjson.h"
  18#include "qemu/module.h"
  19#include "qemu/option.h"
  20#include "qemu/range.h"
  21#include "qemu/sockets.h"
  22#include "chardev/char.h"
  23#include "sysemu/sysemu.h"
  24#include "qapi/qapi-visit-sockets.h"
  25#include "qapi/qobject-input-visitor.h"
  26#include "qapi/qobject-output-visitor.h"
  27
  28#include "migration/migration-test.h"
  29
  30/* TODO actually test the results and get rid of this */
  31#define qtest_qmp_discard_response(...) qobject_unref(qtest_qmp(__VA_ARGS__))
  32
  33unsigned start_address;
  34unsigned end_address;
  35bool got_stop;
  36static bool uffd_feature_thread_id;
  37
  38#if defined(__linux__)
  39#include <sys/syscall.h>
  40#include <sys/vfs.h>
  41#endif
  42
  43#if defined(__linux__) && defined(__NR_userfaultfd) && defined(CONFIG_EVENTFD)
  44#include <sys/eventfd.h>
  45#include <sys/ioctl.h>
  46#include <linux/userfaultfd.h>
  47
  48static bool ufd_version_check(void)
  49{
  50    struct uffdio_api api_struct;
  51    uint64_t ioctl_mask;
  52
  53    int ufd = syscall(__NR_userfaultfd, O_CLOEXEC);
  54
  55    if (ufd == -1) {
  56        g_test_message("Skipping test: userfaultfd not available");
  57        return false;
  58    }
  59
  60    api_struct.api = UFFD_API;
  61    api_struct.features = 0;
  62    if (ioctl(ufd, UFFDIO_API, &api_struct)) {
  63        g_test_message("Skipping test: UFFDIO_API failed");
  64        return false;
  65    }
  66    uffd_feature_thread_id = api_struct.features & UFFD_FEATURE_THREAD_ID;
  67
  68    ioctl_mask = (__u64)1 << _UFFDIO_REGISTER |
  69                 (__u64)1 << _UFFDIO_UNREGISTER;
  70    if ((api_struct.ioctls & ioctl_mask) != ioctl_mask) {
  71        g_test_message("Skipping test: Missing userfault feature");
  72        return false;
  73    }
  74
  75    return true;
  76}
  77
  78#else
  79static bool ufd_version_check(void)
  80{
  81    g_test_message("Skipping test: Userfault not available (builtdtime)");
  82    return false;
  83}
  84
  85#endif
  86
  87static const char *tmpfs;
  88
  89/* The boot file modifies memory area in [start_address, end_address)
  90 * repeatedly. It outputs a 'B' at a fixed rate while it's still running.
  91 */
  92#include "tests/migration/i386/a-b-bootblock.h"
  93#include "tests/migration/aarch64/a-b-kernel.h"
  94#include "tests/migration/s390x/a-b-bios.h"
  95
  96static void init_bootfile(const char *bootpath, void *content, size_t len)
  97{
  98    FILE *bootfile = fopen(bootpath, "wb");
  99
 100    g_assert_cmpint(fwrite(content, len, 1, bootfile), ==, 1);
 101    fclose(bootfile);
 102}
 103
 104/*
 105 * Wait for some output in the serial output file,
 106 * we get an 'A' followed by an endless string of 'B's
 107 * but on the destination we won't have the A.
 108 */
 109static void wait_for_serial(const char *side)
 110{
 111    char *serialpath = g_strdup_printf("%s/%s", tmpfs, side);
 112    FILE *serialfile = fopen(serialpath, "r");
 113    const char *arch = qtest_get_arch();
 114    int started = (strcmp(side, "src_serial") == 0 &&
 115                   strcmp(arch, "ppc64") == 0) ? 0 : 1;
 116
 117    g_free(serialpath);
 118    do {
 119        int readvalue = fgetc(serialfile);
 120
 121        if (!started) {
 122            /* SLOF prints its banner before starting test,
 123             * to ignore it, mark the start of the test with '_',
 124             * ignore all characters until this marker
 125             */
 126            switch (readvalue) {
 127            case '_':
 128                started = 1;
 129                break;
 130            case EOF:
 131                fseek(serialfile, 0, SEEK_SET);
 132                usleep(1000);
 133                break;
 134            }
 135            continue;
 136        }
 137        switch (readvalue) {
 138        case 'A':
 139            /* Fine */
 140            break;
 141
 142        case 'B':
 143            /* It's alive! */
 144            fclose(serialfile);
 145            return;
 146
 147        case EOF:
 148            started = (strcmp(side, "src_serial") == 0 &&
 149                       strcmp(arch, "ppc64") == 0) ? 0 : 1;
 150            fseek(serialfile, 0, SEEK_SET);
 151            usleep(1000);
 152            break;
 153
 154        default:
 155            fprintf(stderr, "Unexpected %d on %s serial\n", readvalue, side);
 156            g_assert_not_reached();
 157        }
 158    } while (true);
 159}
 160
 161static void stop_cb(void *opaque, const char *name, QDict *data)
 162{
 163    if (!strcmp(name, "STOP")) {
 164        got_stop = true;
 165    }
 166}
 167
 168/*
 169 * Events can get in the way of responses we are actually waiting for.
 170 */
 171GCC_FMT_ATTR(3, 4)
 172static QDict *wait_command_fd(QTestState *who, int fd, const char *command, ...)
 173{
 174    va_list ap;
 175
 176    va_start(ap, command);
 177    qtest_qmp_vsend_fds(who, &fd, 1, command, ap);
 178    va_end(ap);
 179
 180    return qtest_qmp_receive_success(who, stop_cb, NULL);
 181}
 182
 183/*
 184 * Events can get in the way of responses we are actually waiting for.
 185 */
 186GCC_FMT_ATTR(2, 3)
 187static QDict *wait_command(QTestState *who, const char *command, ...)
 188{
 189    va_list ap;
 190
 191    va_start(ap, command);
 192    qtest_qmp_vsend(who, command, ap);
 193    va_end(ap);
 194
 195    return qtest_qmp_receive_success(who, stop_cb, NULL);
 196}
 197
 198/*
 199 * Note: caller is responsible to free the returned object via
 200 * qobject_unref() after use
 201 */
 202static QDict *migrate_query(QTestState *who)
 203{
 204    return wait_command(who, "{ 'execute': 'query-migrate' }");
 205}
 206
 207/*
 208 * Note: caller is responsible to free the returned object via
 209 * g_free() after use
 210 */
 211static gchar *migrate_query_status(QTestState *who)
 212{
 213    QDict *rsp_return = migrate_query(who);
 214    gchar *status = g_strdup(qdict_get_str(rsp_return, "status"));
 215
 216    g_assert(status);
 217    qobject_unref(rsp_return);
 218
 219    return status;
 220}
 221
 222/*
 223 * It's tricky to use qemu's migration event capability with qtest,
 224 * events suddenly appearing confuse the qmp()/hmp() responses.
 225 */
 226
 227static int64_t read_ram_property_int(QTestState *who, const char *property)
 228{
 229    QDict *rsp_return, *rsp_ram;
 230    int64_t result;
 231
 232    rsp_return = migrate_query(who);
 233    if (!qdict_haskey(rsp_return, "ram")) {
 234        /* Still in setup */
 235        result = 0;
 236    } else {
 237        rsp_ram = qdict_get_qdict(rsp_return, "ram");
 238        result = qdict_get_try_int(rsp_ram, property, 0);
 239    }
 240    qobject_unref(rsp_return);
 241    return result;
 242}
 243
 244static uint64_t get_migration_pass(QTestState *who)
 245{
 246    return read_ram_property_int(who, "dirty-sync-count");
 247}
 248
 249static void read_blocktime(QTestState *who)
 250{
 251    QDict *rsp_return;
 252
 253    rsp_return = migrate_query(who);
 254    g_assert(qdict_haskey(rsp_return, "postcopy-blocktime"));
 255    qobject_unref(rsp_return);
 256}
 257
 258static void wait_for_migration_status(QTestState *who,
 259                                      const char *goal)
 260{
 261    while (true) {
 262        bool completed;
 263        char *status;
 264
 265        status = migrate_query_status(who);
 266        completed = strcmp(status, goal) == 0;
 267        g_assert_cmpstr(status, !=,  "failed");
 268        g_free(status);
 269        if (completed) {
 270            return;
 271        }
 272        usleep(1000);
 273    }
 274}
 275
 276static void wait_for_migration_complete(QTestState *who)
 277{
 278    wait_for_migration_status(who, "completed");
 279}
 280
 281static void wait_for_migration_pass(QTestState *who)
 282{
 283    uint64_t initial_pass = get_migration_pass(who);
 284    uint64_t pass;
 285
 286    /* Wait for the 1st sync */
 287    while (!got_stop && !initial_pass) {
 288        usleep(1000);
 289        initial_pass = get_migration_pass(who);
 290    }
 291
 292    do {
 293        usleep(1000);
 294        pass = get_migration_pass(who);
 295    } while (pass == initial_pass && !got_stop);
 296}
 297
 298static void check_guests_ram(QTestState *who)
 299{
 300    /* Our ASM test will have been incrementing one byte from each page from
 301     * start_address to < end_address in order. This gives us a constraint
 302     * that any page's byte should be equal or less than the previous pages
 303     * byte (mod 256); and they should all be equal except for one transition
 304     * at the point where we meet the incrementer. (We're running this with
 305     * the guest stopped).
 306     */
 307    unsigned address;
 308    uint8_t first_byte;
 309    uint8_t last_byte;
 310    bool hit_edge = false;
 311    int bad = 0;
 312
 313    qtest_memread(who, start_address, &first_byte, 1);
 314    last_byte = first_byte;
 315
 316    for (address = start_address + TEST_MEM_PAGE_SIZE; address < end_address;
 317         address += TEST_MEM_PAGE_SIZE)
 318    {
 319        uint8_t b;
 320        qtest_memread(who, address, &b, 1);
 321        if (b != last_byte) {
 322            if (((b + 1) % 256) == last_byte && !hit_edge) {
 323                /* This is OK, the guest stopped at the point of
 324                 * incrementing the previous page but didn't get
 325                 * to us yet.
 326                 */
 327                hit_edge = true;
 328                last_byte = b;
 329            } else {
 330                bad++;
 331                if (bad <= 10) {
 332                    fprintf(stderr, "Memory content inconsistency at %x"
 333                            " first_byte = %x last_byte = %x current = %x"
 334                            " hit_edge = %x\n",
 335                            address, first_byte, last_byte, b, hit_edge);
 336                }
 337            }
 338        }
 339    }
 340    if (bad >= 10) {
 341        fprintf(stderr, "and in another %d pages", bad - 10);
 342    }
 343    g_assert(bad == 0);
 344}
 345
 346static void cleanup(const char *filename)
 347{
 348    char *path = g_strdup_printf("%s/%s", tmpfs, filename);
 349
 350    unlink(path);
 351    g_free(path);
 352}
 353
 354static char *get_shmem_opts(const char *mem_size, const char *shmem_path)
 355{
 356    return g_strdup_printf("-object memory-backend-file,id=mem0,size=%s"
 357                           ",mem-path=%s,share=on -numa node,memdev=mem0",
 358                           mem_size, shmem_path);
 359}
 360
 361static char *SocketAddress_to_str(SocketAddress *addr)
 362{
 363    switch (addr->type) {
 364    case SOCKET_ADDRESS_TYPE_INET:
 365        return g_strdup_printf("tcp:%s:%s",
 366                               addr->u.inet.host,
 367                               addr->u.inet.port);
 368    case SOCKET_ADDRESS_TYPE_UNIX:
 369        return g_strdup_printf("unix:%s",
 370                               addr->u.q_unix.path);
 371    case SOCKET_ADDRESS_TYPE_FD:
 372        return g_strdup_printf("fd:%s", addr->u.fd.str);
 373    case SOCKET_ADDRESS_TYPE_VSOCK:
 374        return g_strdup_printf("tcp:%s:%s",
 375                               addr->u.vsock.cid,
 376                               addr->u.vsock.port);
 377    default:
 378        return g_strdup("unknown address type");
 379    }
 380}
 381
 382static char *migrate_get_socket_address(QTestState *who, const char *parameter)
 383{
 384    QDict *rsp;
 385    char *result;
 386    Error *local_err = NULL;
 387    SocketAddressList *addrs;
 388    Visitor *iv = NULL;
 389    QObject *object;
 390
 391    rsp = migrate_query(who);
 392    object = qdict_get(rsp, parameter);
 393
 394    iv = qobject_input_visitor_new(object);
 395    visit_type_SocketAddressList(iv, NULL, &addrs, &local_err);
 396    visit_free(iv);
 397
 398    /* we are only using a single address */
 399    result = SocketAddress_to_str(addrs->value);
 400
 401    qapi_free_SocketAddressList(addrs);
 402    qobject_unref(rsp);
 403    return result;
 404}
 405
 406static long long migrate_get_parameter_int(QTestState *who,
 407                                           const char *parameter)
 408{
 409    QDict *rsp;
 410    long long result;
 411
 412    rsp = wait_command(who, "{ 'execute': 'query-migrate-parameters' }");
 413    result = qdict_get_int(rsp, parameter);
 414    qobject_unref(rsp);
 415    return result;
 416}
 417
 418static void migrate_check_parameter_int(QTestState *who, const char *parameter,
 419                                        long long value)
 420{
 421    long long result;
 422
 423    result = migrate_get_parameter_int(who, parameter);
 424    g_assert_cmpint(result, ==, value);
 425}
 426
 427static void migrate_set_parameter_int(QTestState *who, const char *parameter,
 428                                      long long value)
 429{
 430    QDict *rsp;
 431
 432    rsp = qtest_qmp(who,
 433                    "{ 'execute': 'migrate-set-parameters',"
 434                    "'arguments': { %s: %lld } }",
 435                    parameter, value);
 436    g_assert(qdict_haskey(rsp, "return"));
 437    qobject_unref(rsp);
 438    migrate_check_parameter_int(who, parameter, value);
 439}
 440
 441static void migrate_pause(QTestState *who)
 442{
 443    QDict *rsp;
 444
 445    rsp = wait_command(who, "{ 'execute': 'migrate-pause' }");
 446    qobject_unref(rsp);
 447}
 448
 449static void migrate_recover(QTestState *who, const char *uri)
 450{
 451    QDict *rsp;
 452
 453    rsp = wait_command(who,
 454                       "{ 'execute': 'migrate-recover', "
 455                       "  'id': 'recover-cmd', "
 456                       "  'arguments': { 'uri': %s } }",
 457                       uri);
 458    qobject_unref(rsp);
 459}
 460
 461static void migrate_set_capability(QTestState *who, const char *capability,
 462                                   bool value)
 463{
 464    QDict *rsp;
 465
 466    rsp = qtest_qmp(who,
 467                    "{ 'execute': 'migrate-set-capabilities',"
 468                    "'arguments': { "
 469                    "'capabilities': [ { "
 470                    "'capability': %s, 'state': %i } ] } }",
 471                    capability, value);
 472    g_assert(qdict_haskey(rsp, "return"));
 473    qobject_unref(rsp);
 474}
 475
 476/*
 477 * Send QMP command "migrate".
 478 * Arguments are built from @fmt... (formatted like
 479 * qobject_from_jsonf_nofail()) with "uri": @uri spliced in.
 480 */
 481GCC_FMT_ATTR(3, 4)
 482static void migrate(QTestState *who, const char *uri, const char *fmt, ...)
 483{
 484    va_list ap;
 485    QDict *args, *rsp;
 486
 487    va_start(ap, fmt);
 488    args = qdict_from_vjsonf_nofail(fmt, ap);
 489    va_end(ap);
 490
 491    g_assert(!qdict_haskey(args, "uri"));
 492    qdict_put_str(args, "uri", uri);
 493
 494    rsp = qmp("{ 'execute': 'migrate', 'arguments': %p}", args);
 495
 496    g_assert(qdict_haskey(rsp, "return"));
 497    qobject_unref(rsp);
 498}
 499
 500static void migrate_postcopy_start(QTestState *from, QTestState *to)
 501{
 502    QDict *rsp;
 503
 504    rsp = wait_command(from, "{ 'execute': 'migrate-start-postcopy' }");
 505    qobject_unref(rsp);
 506
 507    if (!got_stop) {
 508        qtest_qmp_eventwait(from, "STOP");
 509    }
 510
 511    qtest_qmp_eventwait(to, "RESUME");
 512}
 513
 514static int test_migrate_start(QTestState **from, QTestState **to,
 515                               const char *uri, bool hide_stderr,
 516                               bool use_shmem)
 517{
 518    gchar *cmd_src, *cmd_dst;
 519    char *bootpath = NULL;
 520    char *extra_opts = NULL;
 521    char *shmem_path = NULL;
 522    const char *arch = qtest_get_arch();
 523    const char *accel = "kvm:tcg";
 524
 525    if (use_shmem) {
 526        if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
 527            g_test_skip("/dev/shm is not supported");
 528            return -1;
 529        }
 530        shmem_path = g_strdup_printf("/dev/shm/qemu-%d", getpid());
 531    }
 532
 533    got_stop = false;
 534    bootpath = g_strdup_printf("%s/bootsect", tmpfs);
 535    if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
 536        /* the assembled x86 boot sector should be exactly one sector large */
 537        assert(sizeof(x86_bootsect) == 512);
 538        init_bootfile(bootpath, x86_bootsect, sizeof(x86_bootsect));
 539        extra_opts = use_shmem ? get_shmem_opts("150M", shmem_path) : NULL;
 540        cmd_src = g_strdup_printf("-machine accel=%s -m 150M"
 541                                  " -name source,debug-threads=on"
 542                                  " -serial file:%s/src_serial"
 543                                  " -drive file=%s,format=raw %s",
 544                                  accel, tmpfs, bootpath,
 545                                  extra_opts ? extra_opts : "");
 546        cmd_dst = g_strdup_printf("-machine accel=%s -m 150M"
 547                                  " -name target,debug-threads=on"
 548                                  " -serial file:%s/dest_serial"
 549                                  " -drive file=%s,format=raw"
 550                                  " -incoming %s %s",
 551                                  accel, tmpfs, bootpath, uri,
 552                                  extra_opts ? extra_opts : "");
 553        start_address = X86_TEST_MEM_START;
 554        end_address = X86_TEST_MEM_END;
 555    } else if (g_str_equal(arch, "s390x")) {
 556        init_bootfile(bootpath, s390x_elf, sizeof(s390x_elf));
 557        extra_opts = use_shmem ? get_shmem_opts("128M", shmem_path) : NULL;
 558        cmd_src = g_strdup_printf("-machine accel=%s -m 128M"
 559                                  " -name source,debug-threads=on"
 560                                  " -serial file:%s/src_serial -bios %s %s",
 561                                  accel, tmpfs, bootpath,
 562                                  extra_opts ? extra_opts : "");
 563        cmd_dst = g_strdup_printf("-machine accel=%s -m 128M"
 564                                  " -name target,debug-threads=on"
 565                                  " -serial file:%s/dest_serial -bios %s"
 566                                  " -incoming %s %s",
 567                                  accel, tmpfs, bootpath, uri,
 568                                  extra_opts ? extra_opts : "");
 569        start_address = S390_TEST_MEM_START;
 570        end_address = S390_TEST_MEM_END;
 571    } else if (strcmp(arch, "ppc64") == 0) {
 572        extra_opts = use_shmem ? get_shmem_opts("256M", shmem_path) : NULL;
 573        cmd_src = g_strdup_printf("-machine accel=%s -m 256M -nodefaults"
 574                                  " -name source,debug-threads=on"
 575                                  " -serial file:%s/src_serial"
 576                                  " -prom-env 'use-nvramrc?=true' -prom-env "
 577                                  "'nvramrc=hex .\" _\" begin %x %x "
 578                                  "do i c@ 1 + i c! 1000 +loop .\" B\" 0 "
 579                                  "until' %s",  accel, tmpfs, end_address,
 580                                  start_address, extra_opts ? extra_opts : "");
 581        cmd_dst = g_strdup_printf("-machine accel=%s -m 256M"
 582                                  " -name target,debug-threads=on"
 583                                  " -serial file:%s/dest_serial"
 584                                  " -incoming %s %s",
 585                                  accel, tmpfs, uri,
 586                                  extra_opts ? extra_opts : "");
 587
 588        start_address = PPC_TEST_MEM_START;
 589        end_address = PPC_TEST_MEM_END;
 590    } else if (strcmp(arch, "aarch64") == 0) {
 591        init_bootfile(bootpath, aarch64_kernel, sizeof(aarch64_kernel));
 592        extra_opts = use_shmem ? get_shmem_opts("150M", shmem_path) : NULL;
 593        cmd_src = g_strdup_printf("-machine virt,accel=%s,gic-version=max "
 594                                  "-name vmsource,debug-threads=on -cpu max "
 595                                  "-m 150M -serial file:%s/src_serial "
 596                                  "-kernel %s %s",
 597                                  accel, tmpfs, bootpath,
 598                                  extra_opts ? extra_opts : "");
 599        cmd_dst = g_strdup_printf("-machine virt,accel=%s,gic-version=max "
 600                                  "-name vmdest,debug-threads=on -cpu max "
 601                                  "-m 150M -serial file:%s/dest_serial "
 602                                  "-kernel %s "
 603                                  "-incoming %s %s",
 604                                  accel, tmpfs, bootpath, uri,
 605                                  extra_opts ? extra_opts : "");
 606
 607        start_address = ARM_TEST_MEM_START;
 608        end_address = ARM_TEST_MEM_END;
 609
 610        g_assert(sizeof(aarch64_kernel) <= ARM_TEST_MAX_KERNEL_SIZE);
 611    } else {
 612        g_assert_not_reached();
 613    }
 614
 615    g_free(bootpath);
 616    g_free(extra_opts);
 617
 618    if (hide_stderr) {
 619        gchar *tmp;
 620        tmp = g_strdup_printf("%s 2>/dev/null", cmd_src);
 621        g_free(cmd_src);
 622        cmd_src = tmp;
 623
 624        tmp = g_strdup_printf("%s 2>/dev/null", cmd_dst);
 625        g_free(cmd_dst);
 626        cmd_dst = tmp;
 627    }
 628
 629    *from = qtest_start(cmd_src);
 630    g_free(cmd_src);
 631
 632    *to = qtest_init(cmd_dst);
 633    g_free(cmd_dst);
 634
 635    /*
 636     * Remove shmem file immediately to avoid memory leak in test failed case.
 637     * It's valid becase QEMU has already opened this file
 638     */
 639    if (use_shmem) {
 640        unlink(shmem_path);
 641        g_free(shmem_path);
 642    }
 643
 644    return 0;
 645}
 646
 647static void test_migrate_end(QTestState *from, QTestState *to, bool test_dest)
 648{
 649    unsigned char dest_byte_a, dest_byte_b, dest_byte_c, dest_byte_d;
 650
 651    qtest_quit(from);
 652
 653    if (test_dest) {
 654        qtest_memread(to, start_address, &dest_byte_a, 1);
 655
 656        /* Destination still running, wait for a byte to change */
 657        do {
 658            qtest_memread(to, start_address, &dest_byte_b, 1);
 659            usleep(1000 * 10);
 660        } while (dest_byte_a == dest_byte_b);
 661
 662        qtest_qmp_discard_response(to, "{ 'execute' : 'stop'}");
 663
 664        /* With it stopped, check nothing changes */
 665        qtest_memread(to, start_address, &dest_byte_c, 1);
 666        usleep(1000 * 200);
 667        qtest_memread(to, start_address, &dest_byte_d, 1);
 668        g_assert_cmpint(dest_byte_c, ==, dest_byte_d);
 669
 670        check_guests_ram(to);
 671    }
 672
 673    qtest_quit(to);
 674
 675    cleanup("bootsect");
 676    cleanup("migsocket");
 677    cleanup("src_serial");
 678    cleanup("dest_serial");
 679}
 680
 681static void deprecated_set_downtime(QTestState *who, const double value)
 682{
 683    QDict *rsp;
 684
 685    rsp = qtest_qmp(who,
 686                    "{ 'execute': 'migrate_set_downtime',"
 687                    " 'arguments': { 'value': %f } }", value);
 688    g_assert(qdict_haskey(rsp, "return"));
 689    qobject_unref(rsp);
 690    migrate_check_parameter_int(who, "downtime-limit", value * 1000);
 691}
 692
 693static void deprecated_set_speed(QTestState *who, long long value)
 694{
 695    QDict *rsp;
 696
 697    rsp = qtest_qmp(who, "{ 'execute': 'migrate_set_speed',"
 698                          "'arguments': { 'value': %lld } }", value);
 699    g_assert(qdict_haskey(rsp, "return"));
 700    qobject_unref(rsp);
 701    migrate_check_parameter_int(who, "max-bandwidth", value);
 702}
 703
 704static void deprecated_set_cache_size(QTestState *who, long long value)
 705{
 706    QDict *rsp;
 707
 708    rsp = qtest_qmp(who, "{ 'execute': 'migrate-set-cache-size',"
 709                         "'arguments': { 'value': %lld } }", value);
 710    g_assert(qdict_haskey(rsp, "return"));
 711    qobject_unref(rsp);
 712    migrate_check_parameter_int(who, "xbzrle-cache-size", value);
 713}
 714
 715static void test_deprecated(void)
 716{
 717    QTestState *from;
 718
 719    from = qtest_start("-machine none");
 720
 721    deprecated_set_downtime(from, 0.12345);
 722    deprecated_set_speed(from, 12345);
 723    deprecated_set_cache_size(from, 4096);
 724
 725    qtest_quit(from);
 726}
 727
 728static int migrate_postcopy_prepare(QTestState **from_ptr,
 729                                     QTestState **to_ptr,
 730                                     bool hide_error)
 731{
 732    char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
 733    QTestState *from, *to;
 734
 735    if (test_migrate_start(&from, &to, uri, hide_error, false)) {
 736        return -1;
 737    }
 738
 739    migrate_set_capability(from, "postcopy-ram", true);
 740    migrate_set_capability(to, "postcopy-ram", true);
 741    migrate_set_capability(to, "postcopy-blocktime", true);
 742
 743    /* We want to pick a speed slow enough that the test completes
 744     * quickly, but that it doesn't complete precopy even on a slow
 745     * machine, so also set the downtime.
 746     */
 747    migrate_set_parameter_int(from, "max-bandwidth", 100000000);
 748    migrate_set_parameter_int(from, "downtime-limit", 1);
 749
 750    /* Wait for the first serial output from the source */
 751    wait_for_serial("src_serial");
 752
 753    migrate(from, uri, "{}");
 754    g_free(uri);
 755
 756    wait_for_migration_pass(from);
 757
 758    *from_ptr = from;
 759    *to_ptr = to;
 760
 761    return 0;
 762}
 763
 764static void migrate_postcopy_complete(QTestState *from, QTestState *to)
 765{
 766    wait_for_migration_complete(from);
 767
 768    /* Make sure we get at least one "B" on destination */
 769    wait_for_serial("dest_serial");
 770
 771    if (uffd_feature_thread_id) {
 772        read_blocktime(to);
 773    }
 774
 775    test_migrate_end(from, to, true);
 776}
 777
 778static void test_postcopy(void)
 779{
 780    QTestState *from, *to;
 781
 782    if (migrate_postcopy_prepare(&from, &to, false)) {
 783        return;
 784    }
 785    migrate_postcopy_start(from, to);
 786    migrate_postcopy_complete(from, to);
 787}
 788
 789static void test_postcopy_recovery(void)
 790{
 791    QTestState *from, *to;
 792    char *uri;
 793
 794    if (migrate_postcopy_prepare(&from, &to, true)) {
 795        return;
 796    }
 797
 798    /* Turn postcopy speed down, 4K/s is slow enough on any machines */
 799    migrate_set_parameter_int(from, "max-postcopy-bandwidth", 4096);
 800
 801    /* Now we start the postcopy */
 802    migrate_postcopy_start(from, to);
 803
 804    /*
 805     * Wait until postcopy is really started; we can only run the
 806     * migrate-pause command during a postcopy
 807     */
 808    wait_for_migration_status(from, "postcopy-active");
 809
 810    /*
 811     * Manually stop the postcopy migration. This emulates a network
 812     * failure with the migration socket
 813     */
 814    migrate_pause(from);
 815
 816    /*
 817     * Wait for destination side to reach postcopy-paused state.  The
 818     * migrate-recover command can only succeed if destination machine
 819     * is in the paused state
 820     */
 821    wait_for_migration_status(to, "postcopy-paused");
 822
 823    /*
 824     * Create a new socket to emulate a new channel that is different
 825     * from the broken migration channel; tell the destination to
 826     * listen to the new port
 827     */
 828    uri = g_strdup_printf("unix:%s/migsocket-recover", tmpfs);
 829    migrate_recover(to, uri);
 830
 831    /*
 832     * Try to rebuild the migration channel using the resume flag and
 833     * the newly created channel
 834     */
 835    wait_for_migration_status(from, "postcopy-paused");
 836    migrate(from, uri, "{'resume': true}");
 837    g_free(uri);
 838
 839    /* Restore the postcopy bandwidth to unlimited */
 840    migrate_set_parameter_int(from, "max-postcopy-bandwidth", 0);
 841
 842    migrate_postcopy_complete(from, to);
 843}
 844
 845static void test_baddest(void)
 846{
 847    QTestState *from, *to;
 848    QDict *rsp_return;
 849    char *status;
 850    bool failed;
 851
 852    if (test_migrate_start(&from, &to, "tcp:0:0", true, false)) {
 853        return;
 854    }
 855    migrate(from, "tcp:0:0", "{}");
 856    do {
 857        status = migrate_query_status(from);
 858        g_assert(!strcmp(status, "setup") || !(strcmp(status, "failed")));
 859        failed = !strcmp(status, "failed");
 860        g_free(status);
 861    } while (!failed);
 862
 863    /* Is the machine currently running? */
 864    rsp_return = wait_command(from, "{ 'execute': 'query-status' }");
 865    g_assert(qdict_haskey(rsp_return, "running"));
 866    g_assert(qdict_get_bool(rsp_return, "running"));
 867    qobject_unref(rsp_return);
 868
 869    test_migrate_end(from, to, false);
 870}
 871
 872static void test_precopy_unix(void)
 873{
 874    char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
 875    QTestState *from, *to;
 876
 877    if (test_migrate_start(&from, &to, uri, false, false)) {
 878        return;
 879    }
 880
 881    /* We want to pick a speed slow enough that the test completes
 882     * quickly, but that it doesn't complete precopy even on a slow
 883     * machine, so also set the downtime.
 884     */
 885    /* 1 ms should make it not converge*/
 886    migrate_set_parameter_int(from, "downtime-limit", 1);
 887    /* 1GB/s */
 888    migrate_set_parameter_int(from, "max-bandwidth", 1000000000);
 889
 890    /* Wait for the first serial output from the source */
 891    wait_for_serial("src_serial");
 892
 893    migrate(from, uri, "{}");
 894
 895    wait_for_migration_pass(from);
 896
 897    /* 300 ms should converge */
 898    migrate_set_parameter_int(from, "downtime-limit", 300);
 899
 900    if (!got_stop) {
 901        qtest_qmp_eventwait(from, "STOP");
 902    }
 903
 904    qtest_qmp_eventwait(to, "RESUME");
 905
 906    wait_for_serial("dest_serial");
 907    wait_for_migration_complete(from);
 908
 909    test_migrate_end(from, to, true);
 910    g_free(uri);
 911}
 912
 913#if 0
 914/* Currently upset on aarch64 TCG */
 915static void test_ignore_shared(void)
 916{
 917    char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
 918    QTestState *from, *to;
 919
 920    if (test_migrate_start(&from, &to, uri, false, true)) {
 921        return;
 922    }
 923
 924    migrate_set_capability(from, "x-ignore-shared", true);
 925    migrate_set_capability(to, "x-ignore-shared", true);
 926
 927    /* Wait for the first serial output from the source */
 928    wait_for_serial("src_serial");
 929
 930    migrate(from, uri, "{}");
 931
 932    wait_for_migration_pass(from);
 933
 934    if (!got_stop) {
 935        qtest_qmp_eventwait(from, "STOP");
 936    }
 937
 938    qtest_qmp_eventwait(to, "RESUME");
 939
 940    wait_for_serial("dest_serial");
 941    wait_for_migration_complete(from);
 942
 943    /* Check whether shared RAM has been really skipped */
 944    g_assert_cmpint(read_ram_property_int(from, "transferred"), <, 1024 * 1024);
 945
 946    test_migrate_end(from, to, true);
 947    g_free(uri);
 948}
 949#endif
 950
 951static void test_xbzrle(const char *uri)
 952{
 953    QTestState *from, *to;
 954
 955    if (test_migrate_start(&from, &to, uri, false, false)) {
 956        return;
 957    }
 958
 959    /*
 960     * We want to pick a speed slow enough that the test completes
 961     * quickly, but that it doesn't complete precopy even on a slow
 962     * machine, so also set the downtime.
 963     */
 964    /* 1 ms should make it not converge*/
 965    migrate_set_parameter_int(from, "downtime-limit", 1);
 966    /* 1GB/s */
 967    migrate_set_parameter_int(from, "max-bandwidth", 1000000000);
 968
 969    migrate_set_parameter_int(from, "xbzrle-cache-size", 33554432);
 970
 971    migrate_set_capability(from, "xbzrle", "true");
 972    migrate_set_capability(to, "xbzrle", "true");
 973    /* Wait for the first serial output from the source */
 974    wait_for_serial("src_serial");
 975
 976    migrate(from, uri, "{}");
 977
 978    wait_for_migration_pass(from);
 979
 980    /* 300ms should converge */
 981    migrate_set_parameter_int(from, "downtime-limit", 300);
 982
 983    if (!got_stop) {
 984        qtest_qmp_eventwait(from, "STOP");
 985    }
 986    qtest_qmp_eventwait(to, "RESUME");
 987
 988    wait_for_serial("dest_serial");
 989    wait_for_migration_complete(from);
 990
 991    test_migrate_end(from, to, true);
 992}
 993
 994static void test_xbzrle_unix(void)
 995{
 996    char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
 997
 998    test_xbzrle(uri);
 999    g_free(uri);
1000}
1001
1002static void test_precopy_tcp(void)
1003{
1004    char *uri;
1005    QTestState *from, *to;
1006
1007    if (test_migrate_start(&from, &to, "tcp:127.0.0.1:0", false, false)) {
1008        return;
1009    }
1010
1011    /*
1012     * We want to pick a speed slow enough that the test completes
1013     * quickly, but that it doesn't complete precopy even on a slow
1014     * machine, so also set the downtime.
1015     */
1016    /* 1 ms should make it not converge*/
1017    migrate_set_parameter_int(from, "downtime-limit", 1);
1018    /* 1GB/s */
1019    migrate_set_parameter_int(from, "max-bandwidth", 1000000000);
1020
1021    /* Wait for the first serial output from the source */
1022    wait_for_serial("src_serial");
1023
1024    uri = migrate_get_socket_address(to, "socket-address");
1025
1026    migrate(from, uri, "{}");
1027
1028    wait_for_migration_pass(from);
1029
1030    /* 300ms should converge */
1031    migrate_set_parameter_int(from, "downtime-limit", 300);
1032
1033    if (!got_stop) {
1034        qtest_qmp_eventwait(from, "STOP");
1035    }
1036    qtest_qmp_eventwait(to, "RESUME");
1037
1038    wait_for_serial("dest_serial");
1039    wait_for_migration_complete(from);
1040
1041    test_migrate_end(from, to, true);
1042    g_free(uri);
1043}
1044
1045static void test_migrate_fd_proto(void)
1046{
1047    QTestState *from, *to;
1048    int ret;
1049    int pair[2];
1050    QDict *rsp;
1051    const char *error_desc;
1052
1053    if (test_migrate_start(&from, &to, "defer", false, false)) {
1054        return;
1055    }
1056
1057    /*
1058     * We want to pick a speed slow enough that the test completes
1059     * quickly, but that it doesn't complete precopy even on a slow
1060     * machine, so also set the downtime.
1061     */
1062    /* 1 ms should make it not converge */
1063    migrate_set_parameter_int(from, "downtime-limit", 1);
1064    /* 1GB/s */
1065    migrate_set_parameter_int(from, "max-bandwidth", 1000000000);
1066
1067    /* Wait for the first serial output from the source */
1068    wait_for_serial("src_serial");
1069
1070    /* Create two connected sockets for migration */
1071    ret = socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
1072    g_assert_cmpint(ret, ==, 0);
1073
1074    /* Send the 1st socket to the target */
1075    rsp = wait_command_fd(to, pair[0],
1076                          "{ 'execute': 'getfd',"
1077                          "  'arguments': { 'fdname': 'fd-mig' }}");
1078    qobject_unref(rsp);
1079    close(pair[0]);
1080
1081    /* Start incoming migration from the 1st socket */
1082    rsp = wait_command(to, "{ 'execute': 'migrate-incoming',"
1083                           "  'arguments': { 'uri': 'fd:fd-mig' }}");
1084    qobject_unref(rsp);
1085
1086    /* Send the 2nd socket to the target */
1087    rsp = wait_command_fd(from, pair[1],
1088                          "{ 'execute': 'getfd',"
1089                          "  'arguments': { 'fdname': 'fd-mig' }}");
1090    qobject_unref(rsp);
1091    close(pair[1]);
1092
1093    /* Start migration to the 2nd socket*/
1094    migrate(from, "fd:fd-mig", "{}");
1095
1096    wait_for_migration_pass(from);
1097
1098    /* 300ms should converge */
1099    migrate_set_parameter_int(from, "downtime-limit", 300);
1100
1101    if (!got_stop) {
1102        qtest_qmp_eventwait(from, "STOP");
1103    }
1104    qtest_qmp_eventwait(to, "RESUME");
1105
1106    /* Test closing fds */
1107    /* We assume, that QEMU removes named fd from its list,
1108     * so this should fail */
1109    rsp = qtest_qmp(from, "{ 'execute': 'closefd',"
1110                          "  'arguments': { 'fdname': 'fd-mig' }}");
1111    g_assert_true(qdict_haskey(rsp, "error"));
1112    error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
1113    g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
1114    qobject_unref(rsp);
1115
1116    rsp = qtest_qmp(to, "{ 'execute': 'closefd',"
1117                        "  'arguments': { 'fdname': 'fd-mig' }}");
1118    g_assert_true(qdict_haskey(rsp, "error"));
1119    error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
1120    g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
1121    qobject_unref(rsp);
1122
1123    /* Complete migration */
1124    wait_for_serial("dest_serial");
1125    wait_for_migration_complete(from);
1126    test_migrate_end(from, to, true);
1127}
1128
1129int main(int argc, char **argv)
1130{
1131    char template[] = "/tmp/migration-test-XXXXXX";
1132    int ret;
1133
1134    g_test_init(&argc, &argv, NULL);
1135
1136    if (!ufd_version_check()) {
1137        return g_test_run();
1138    }
1139
1140    /*
1141     * On ppc64, the test only works with kvm-hv, but not with kvm-pr and TCG
1142     * is touchy due to race conditions on dirty bits (especially on PPC for
1143     * some reason)
1144     */
1145    if (g_str_equal(qtest_get_arch(), "ppc64") &&
1146        access("/sys/module/kvm_hv", F_OK)) {
1147        g_test_message("Skipping test: kvm_hv not available");
1148        return g_test_run();
1149    }
1150
1151    /*
1152     * Similar to ppc64, s390x seems to be touchy with TCG, so disable it
1153     * there until the problems are resolved
1154     */
1155    if (g_str_equal(qtest_get_arch(), "s390x")) {
1156#if defined(HOST_S390X)
1157        if (access("/dev/kvm", R_OK | W_OK)) {
1158            g_test_message("Skipping test: kvm not available");
1159            return g_test_run();
1160        }
1161#else
1162        g_test_message("Skipping test: Need s390x host to work properly");
1163        return g_test_run();
1164#endif
1165    }
1166
1167    tmpfs = mkdtemp(template);
1168    if (!tmpfs) {
1169        g_test_message("mkdtemp on path (%s): %s", template, strerror(errno));
1170    }
1171    g_assert(tmpfs);
1172
1173    module_call_init(MODULE_INIT_QOM);
1174
1175    qtest_add_func("/migration/postcopy/unix", test_postcopy);
1176    qtest_add_func("/migration/postcopy/recovery", test_postcopy_recovery);
1177    qtest_add_func("/migration/deprecated", test_deprecated);
1178    qtest_add_func("/migration/bad_dest", test_baddest);
1179    qtest_add_func("/migration/precopy/unix", test_precopy_unix);
1180    qtest_add_func("/migration/precopy/tcp", test_precopy_tcp);
1181    /* qtest_add_func("/migration/ignore_shared", test_ignore_shared); */
1182    qtest_add_func("/migration/xbzrle/unix", test_xbzrle_unix);
1183    qtest_add_func("/migration/fd_proto", test_migrate_fd_proto);
1184
1185    ret = g_test_run();
1186
1187    g_assert_cmpint(ret, ==, 0);
1188
1189    ret = rmdir(tmpfs);
1190    if (ret != 0) {
1191        g_test_message("unable to rmdir: path (%s): %s",
1192                       tmpfs, strerror(errno));
1193    }
1194
1195    return ret;
1196}
1197