qemu/tests/qtest/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/error.h"
  17#include "qapi/qmp/qdict.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 "qapi/qapi-visit-sockets.h"
  24#include "qapi/qobject-input-visitor.h"
  25#include "qapi/qobject-output-visitor.h"
  26#include "crypto/tlscredspsk.h"
  27#include "qapi/qmp/qlist.h"
  28
  29#include "migration-helpers.h"
  30#include "tests/migration/migration-test.h"
  31#ifdef CONFIG_GNUTLS
  32# include "tests/unit/crypto-tls-psk-helpers.h"
  33# ifdef CONFIG_TASN1
  34#  include "tests/unit/crypto-tls-x509-helpers.h"
  35# endif /* CONFIG_TASN1 */
  36#endif /* CONFIG_GNUTLS */
  37
  38/* For dirty ring test; so far only x86_64 is supported */
  39#if defined(__linux__) && defined(HOST_X86_64)
  40#include "linux/kvm.h"
  41#endif
  42
  43/* TODO actually test the results and get rid of this */
  44#define qtest_qmp_discard_response(...) qobject_unref(qtest_qmp(__VA_ARGS__))
  45
  46unsigned start_address;
  47unsigned end_address;
  48static bool uffd_feature_thread_id;
  49
  50/*
  51 * Dirtylimit stop working if dirty page rate error
  52 * value less than DIRTYLIMIT_TOLERANCE_RANGE
  53 */
  54#define DIRTYLIMIT_TOLERANCE_RANGE  25  /* MB/s */
  55
  56#if defined(__linux__)
  57#include <sys/syscall.h>
  58#include <sys/vfs.h>
  59#endif
  60
  61#if defined(__linux__) && defined(__NR_userfaultfd) && defined(CONFIG_EVENTFD)
  62#include <sys/eventfd.h>
  63#include <sys/ioctl.h>
  64#include <linux/userfaultfd.h>
  65
  66static bool ufd_version_check(void)
  67{
  68    struct uffdio_api api_struct;
  69    uint64_t ioctl_mask;
  70
  71    int ufd = syscall(__NR_userfaultfd, O_CLOEXEC);
  72
  73    if (ufd == -1) {
  74        g_test_message("Skipping test: userfaultfd not available");
  75        return false;
  76    }
  77
  78    api_struct.api = UFFD_API;
  79    api_struct.features = 0;
  80    if (ioctl(ufd, UFFDIO_API, &api_struct)) {
  81        g_test_message("Skipping test: UFFDIO_API failed");
  82        return false;
  83    }
  84    uffd_feature_thread_id = api_struct.features & UFFD_FEATURE_THREAD_ID;
  85
  86    ioctl_mask = (__u64)1 << _UFFDIO_REGISTER |
  87                 (__u64)1 << _UFFDIO_UNREGISTER;
  88    if ((api_struct.ioctls & ioctl_mask) != ioctl_mask) {
  89        g_test_message("Skipping test: Missing userfault feature");
  90        return false;
  91    }
  92
  93    return true;
  94}
  95
  96#else
  97static bool ufd_version_check(void)
  98{
  99    g_test_message("Skipping test: Userfault not available (builtdtime)");
 100    return false;
 101}
 102
 103#endif
 104
 105static const char *tmpfs;
 106
 107/* The boot file modifies memory area in [start_address, end_address)
 108 * repeatedly. It outputs a 'B' at a fixed rate while it's still running.
 109 */
 110#include "tests/migration/i386/a-b-bootblock.h"
 111#include "tests/migration/aarch64/a-b-kernel.h"
 112#include "tests/migration/s390x/a-b-bios.h"
 113
 114static void init_bootfile(const char *bootpath, void *content, size_t len)
 115{
 116    FILE *bootfile = fopen(bootpath, "wb");
 117
 118    g_assert_cmpint(fwrite(content, len, 1, bootfile), ==, 1);
 119    fclose(bootfile);
 120}
 121
 122/*
 123 * Wait for some output in the serial output file,
 124 * we get an 'A' followed by an endless string of 'B's
 125 * but on the destination we won't have the A.
 126 */
 127static void wait_for_serial(const char *side)
 128{
 129    g_autofree char *serialpath = g_strdup_printf("%s/%s", tmpfs, side);
 130    FILE *serialfile = fopen(serialpath, "r");
 131    const char *arch = qtest_get_arch();
 132    int started = (strcmp(side, "src_serial") == 0 &&
 133                   strcmp(arch, "ppc64") == 0) ? 0 : 1;
 134
 135    do {
 136        int readvalue = fgetc(serialfile);
 137
 138        if (!started) {
 139            /* SLOF prints its banner before starting test,
 140             * to ignore it, mark the start of the test with '_',
 141             * ignore all characters until this marker
 142             */
 143            switch (readvalue) {
 144            case '_':
 145                started = 1;
 146                break;
 147            case EOF:
 148                fseek(serialfile, 0, SEEK_SET);
 149                usleep(1000);
 150                break;
 151            }
 152            continue;
 153        }
 154        switch (readvalue) {
 155        case 'A':
 156            /* Fine */
 157            break;
 158
 159        case 'B':
 160            /* It's alive! */
 161            fclose(serialfile);
 162            return;
 163
 164        case EOF:
 165            started = (strcmp(side, "src_serial") == 0 &&
 166                       strcmp(arch, "ppc64") == 0) ? 0 : 1;
 167            fseek(serialfile, 0, SEEK_SET);
 168            usleep(1000);
 169            break;
 170
 171        default:
 172            fprintf(stderr, "Unexpected %d on %s serial\n", readvalue, side);
 173            g_assert_not_reached();
 174        }
 175    } while (true);
 176}
 177
 178/*
 179 * It's tricky to use qemu's migration event capability with qtest,
 180 * events suddenly appearing confuse the qmp()/hmp() responses.
 181 */
 182
 183static int64_t read_ram_property_int(QTestState *who, const char *property)
 184{
 185    QDict *rsp_return, *rsp_ram;
 186    int64_t result;
 187
 188    rsp_return = migrate_query_not_failed(who);
 189    if (!qdict_haskey(rsp_return, "ram")) {
 190        /* Still in setup */
 191        result = 0;
 192    } else {
 193        rsp_ram = qdict_get_qdict(rsp_return, "ram");
 194        result = qdict_get_try_int(rsp_ram, property, 0);
 195    }
 196    qobject_unref(rsp_return);
 197    return result;
 198}
 199
 200static int64_t read_migrate_property_int(QTestState *who, const char *property)
 201{
 202    QDict *rsp_return;
 203    int64_t result;
 204
 205    rsp_return = migrate_query_not_failed(who);
 206    result = qdict_get_try_int(rsp_return, property, 0);
 207    qobject_unref(rsp_return);
 208    return result;
 209}
 210
 211static uint64_t get_migration_pass(QTestState *who)
 212{
 213    return read_ram_property_int(who, "dirty-sync-count");
 214}
 215
 216static void read_blocktime(QTestState *who)
 217{
 218    QDict *rsp_return;
 219
 220    rsp_return = migrate_query_not_failed(who);
 221    g_assert(qdict_haskey(rsp_return, "postcopy-blocktime"));
 222    qobject_unref(rsp_return);
 223}
 224
 225static void wait_for_migration_pass(QTestState *who)
 226{
 227    uint64_t initial_pass = get_migration_pass(who);
 228    uint64_t pass;
 229
 230    /* Wait for the 1st sync */
 231    while (!got_stop && !initial_pass) {
 232        usleep(1000);
 233        initial_pass = get_migration_pass(who);
 234    }
 235
 236    do {
 237        usleep(1000);
 238        pass = get_migration_pass(who);
 239    } while (pass == initial_pass && !got_stop);
 240}
 241
 242static void check_guests_ram(QTestState *who)
 243{
 244    /* Our ASM test will have been incrementing one byte from each page from
 245     * start_address to < end_address in order. This gives us a constraint
 246     * that any page's byte should be equal or less than the previous pages
 247     * byte (mod 256); and they should all be equal except for one transition
 248     * at the point where we meet the incrementer. (We're running this with
 249     * the guest stopped).
 250     */
 251    unsigned address;
 252    uint8_t first_byte;
 253    uint8_t last_byte;
 254    bool hit_edge = false;
 255    int bad = 0;
 256
 257    qtest_memread(who, start_address, &first_byte, 1);
 258    last_byte = first_byte;
 259
 260    for (address = start_address + TEST_MEM_PAGE_SIZE; address < end_address;
 261         address += TEST_MEM_PAGE_SIZE)
 262    {
 263        uint8_t b;
 264        qtest_memread(who, address, &b, 1);
 265        if (b != last_byte) {
 266            if (((b + 1) % 256) == last_byte && !hit_edge) {
 267                /* This is OK, the guest stopped at the point of
 268                 * incrementing the previous page but didn't get
 269                 * to us yet.
 270                 */
 271                hit_edge = true;
 272                last_byte = b;
 273            } else {
 274                bad++;
 275                if (bad <= 10) {
 276                    fprintf(stderr, "Memory content inconsistency at %x"
 277                            " first_byte = %x last_byte = %x current = %x"
 278                            " hit_edge = %x\n",
 279                            address, first_byte, last_byte, b, hit_edge);
 280                }
 281            }
 282        }
 283    }
 284    if (bad >= 10) {
 285        fprintf(stderr, "and in another %d pages", bad - 10);
 286    }
 287    g_assert(bad == 0);
 288}
 289
 290static void cleanup(const char *filename)
 291{
 292    g_autofree char *path = g_strdup_printf("%s/%s", tmpfs, filename);
 293
 294    unlink(path);
 295}
 296
 297static char *SocketAddress_to_str(SocketAddress *addr)
 298{
 299    switch (addr->type) {
 300    case SOCKET_ADDRESS_TYPE_INET:
 301        return g_strdup_printf("tcp:%s:%s",
 302                               addr->u.inet.host,
 303                               addr->u.inet.port);
 304    case SOCKET_ADDRESS_TYPE_UNIX:
 305        return g_strdup_printf("unix:%s",
 306                               addr->u.q_unix.path);
 307    case SOCKET_ADDRESS_TYPE_FD:
 308        return g_strdup_printf("fd:%s", addr->u.fd.str);
 309    case SOCKET_ADDRESS_TYPE_VSOCK:
 310        return g_strdup_printf("tcp:%s:%s",
 311                               addr->u.vsock.cid,
 312                               addr->u.vsock.port);
 313    default:
 314        return g_strdup("unknown address type");
 315    }
 316}
 317
 318static char *migrate_get_socket_address(QTestState *who, const char *parameter)
 319{
 320    QDict *rsp;
 321    char *result;
 322    SocketAddressList *addrs;
 323    Visitor *iv = NULL;
 324    QObject *object;
 325
 326    rsp = migrate_query(who);
 327    object = qdict_get(rsp, parameter);
 328
 329    iv = qobject_input_visitor_new(object);
 330    visit_type_SocketAddressList(iv, NULL, &addrs, &error_abort);
 331    visit_free(iv);
 332
 333    /* we are only using a single address */
 334    result = SocketAddress_to_str(addrs->value);
 335
 336    qapi_free_SocketAddressList(addrs);
 337    qobject_unref(rsp);
 338    return result;
 339}
 340
 341static long long migrate_get_parameter_int(QTestState *who,
 342                                           const char *parameter)
 343{
 344    QDict *rsp;
 345    long long result;
 346
 347    rsp = wait_command(who, "{ 'execute': 'query-migrate-parameters' }");
 348    result = qdict_get_int(rsp, parameter);
 349    qobject_unref(rsp);
 350    return result;
 351}
 352
 353static void migrate_check_parameter_int(QTestState *who, const char *parameter,
 354                                        long long value)
 355{
 356    long long result;
 357
 358    result = migrate_get_parameter_int(who, parameter);
 359    g_assert_cmpint(result, ==, value);
 360}
 361
 362static void migrate_set_parameter_int(QTestState *who, const char *parameter,
 363                                      long long value)
 364{
 365    QDict *rsp;
 366
 367    rsp = qtest_qmp(who,
 368                    "{ 'execute': 'migrate-set-parameters',"
 369                    "'arguments': { %s: %lld } }",
 370                    parameter, value);
 371    g_assert(qdict_haskey(rsp, "return"));
 372    qobject_unref(rsp);
 373    migrate_check_parameter_int(who, parameter, value);
 374}
 375
 376static char *migrate_get_parameter_str(QTestState *who,
 377                                       const char *parameter)
 378{
 379    QDict *rsp;
 380    char *result;
 381
 382    rsp = wait_command(who, "{ 'execute': 'query-migrate-parameters' }");
 383    result = g_strdup(qdict_get_str(rsp, parameter));
 384    qobject_unref(rsp);
 385    return result;
 386}
 387
 388static void migrate_check_parameter_str(QTestState *who, const char *parameter,
 389                                        const char *value)
 390{
 391    g_autofree char *result = migrate_get_parameter_str(who, parameter);
 392    g_assert_cmpstr(result, ==, value);
 393}
 394
 395static void migrate_set_parameter_str(QTestState *who, const char *parameter,
 396                                      const char *value)
 397{
 398    QDict *rsp;
 399
 400    rsp = qtest_qmp(who,
 401                    "{ 'execute': 'migrate-set-parameters',"
 402                    "'arguments': { %s: %s } }",
 403                    parameter, value);
 404    g_assert(qdict_haskey(rsp, "return"));
 405    qobject_unref(rsp);
 406    migrate_check_parameter_str(who, parameter, value);
 407}
 408
 409static void migrate_ensure_non_converge(QTestState *who)
 410{
 411    /* Can't converge with 1ms downtime + 30 mbs bandwidth limit */
 412    migrate_set_parameter_int(who, "max-bandwidth", 30 * 1000 * 1000);
 413    migrate_set_parameter_int(who, "downtime-limit", 1);
 414}
 415
 416static void migrate_ensure_converge(QTestState *who)
 417{
 418    /* Should converge with 30s downtime + 1 gbs bandwidth limit */
 419    migrate_set_parameter_int(who, "max-bandwidth", 1 * 1000 * 1000 * 1000);
 420    migrate_set_parameter_int(who, "downtime-limit", 30 * 1000);
 421}
 422
 423static void migrate_pause(QTestState *who)
 424{
 425    QDict *rsp;
 426
 427    rsp = wait_command(who, "{ 'execute': 'migrate-pause' }");
 428    qobject_unref(rsp);
 429}
 430
 431static void migrate_continue(QTestState *who, const char *state)
 432{
 433    QDict *rsp;
 434
 435    rsp = wait_command(who,
 436                       "{ 'execute': 'migrate-continue',"
 437                       "  'arguments': { 'state': %s } }",
 438                       state);
 439    qobject_unref(rsp);
 440}
 441
 442static void migrate_recover(QTestState *who, const char *uri)
 443{
 444    QDict *rsp;
 445
 446    rsp = wait_command(who,
 447                       "{ 'execute': 'migrate-recover', "
 448                       "  'id': 'recover-cmd', "
 449                       "  'arguments': { 'uri': %s } }",
 450                       uri);
 451    qobject_unref(rsp);
 452}
 453
 454static void migrate_cancel(QTestState *who)
 455{
 456    QDict *rsp;
 457
 458    rsp = wait_command(who, "{ 'execute': 'migrate_cancel' }");
 459    qobject_unref(rsp);
 460}
 461
 462static void migrate_set_capability(QTestState *who, const char *capability,
 463                                   bool value)
 464{
 465    QDict *rsp;
 466
 467    rsp = qtest_qmp(who,
 468                    "{ 'execute': 'migrate-set-capabilities',"
 469                    "'arguments': { "
 470                    "'capabilities': [ { "
 471                    "'capability': %s, 'state': %i } ] } }",
 472                    capability, value);
 473    g_assert(qdict_haskey(rsp, "return"));
 474    qobject_unref(rsp);
 475}
 476
 477static void migrate_postcopy_start(QTestState *from, QTestState *to)
 478{
 479    QDict *rsp;
 480
 481    rsp = wait_command(from, "{ 'execute': 'migrate-start-postcopy' }");
 482    qobject_unref(rsp);
 483
 484    if (!got_stop) {
 485        qtest_qmp_eventwait(from, "STOP");
 486    }
 487
 488    qtest_qmp_eventwait(to, "RESUME");
 489}
 490
 491typedef struct {
 492    /*
 493     * QTEST_LOG=1 may override this.  When QTEST_LOG=1, we always dump errors
 494     * unconditionally, because it means the user would like to be verbose.
 495     */
 496    bool hide_stderr;
 497    bool use_shmem;
 498    /* only launch the target process */
 499    bool only_target;
 500    /* Use dirty ring if true; dirty logging otherwise */
 501    bool use_dirty_ring;
 502    const char *opts_source;
 503    const char *opts_target;
 504} MigrateStart;
 505
 506/*
 507 * A hook that runs after the src and dst QEMUs have been
 508 * created, but before the migration is started. This can
 509 * be used to set migration parameters and capabilities.
 510 *
 511 * Returns: NULL, or a pointer to opaque state to be
 512 *          later passed to the TestMigrateFinishHook
 513 */
 514typedef void * (*TestMigrateStartHook)(QTestState *from,
 515                                       QTestState *to);
 516
 517/*
 518 * A hook that runs after the migration has finished,
 519 * regardless of whether it succeeded or failed, but
 520 * before QEMU has terminated (unless it self-terminated
 521 * due to migration error)
 522 *
 523 * @opaque is a pointer to state previously returned
 524 * by the TestMigrateStartHook if any, or NULL.
 525 */
 526typedef void (*TestMigrateFinishHook)(QTestState *from,
 527                                      QTestState *to,
 528                                      void *opaque);
 529
 530typedef struct {
 531    /* Optional: fine tune start parameters */
 532    MigrateStart start;
 533
 534    /* Required: the URI for the dst QEMU to listen on */
 535    const char *listen_uri;
 536
 537    /*
 538     * Optional: the URI for the src QEMU to connect to
 539     * If NULL, then it will query the dst QEMU for its actual
 540     * listening address and use that as the connect address.
 541     * This allows for dynamically picking a free TCP port.
 542     */
 543    const char *connect_uri;
 544
 545    /* Optional: callback to run at start to set migration parameters */
 546    TestMigrateStartHook start_hook;
 547    /* Optional: callback to run at finish to cleanup */
 548    TestMigrateFinishHook finish_hook;
 549
 550    /*
 551     * Optional: normally we expect the migration process to complete.
 552     *
 553     * There can be a variety of reasons and stages in which failure
 554     * can happen during tests.
 555     *
 556     * If a failure is expected to happen at time of establishing
 557     * the connection, then MIG_TEST_FAIL will indicate that the dst
 558     * QEMU is expected to stay running and accept future migration
 559     * connections.
 560     *
 561     * If a failure is expected to happen while processing the
 562     * migration stream, then MIG_TEST_FAIL_DEST_QUIT_ERR will indicate
 563     * that the dst QEMU is expected to quit with non-zero exit status
 564     */
 565    enum {
 566        /* This test should succeed, the default */
 567        MIG_TEST_SUCCEED = 0,
 568        /* This test should fail, dest qemu should keep alive */
 569        MIG_TEST_FAIL,
 570        /* This test should fail, dest qemu should fail with abnormal status */
 571        MIG_TEST_FAIL_DEST_QUIT_ERR,
 572    } result;
 573
 574    /* Optional: set number of migration passes to wait for */
 575    unsigned int iterations;
 576
 577    /* Postcopy specific fields */
 578    void *postcopy_data;
 579    bool postcopy_preempt;
 580} MigrateCommon;
 581
 582static int test_migrate_start(QTestState **from, QTestState **to,
 583                              const char *uri, MigrateStart *args)
 584{
 585    g_autofree gchar *arch_source = NULL;
 586    g_autofree gchar *arch_target = NULL;
 587    g_autofree gchar *cmd_source = NULL;
 588    g_autofree gchar *cmd_target = NULL;
 589    const gchar *ignore_stderr;
 590    g_autofree char *bootpath = NULL;
 591    g_autofree char *shmem_opts = NULL;
 592    g_autofree char *shmem_path = NULL;
 593    const char *arch = qtest_get_arch();
 594    const char *machine_opts = NULL;
 595    const char *memory_size;
 596
 597    if (args->use_shmem) {
 598        if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
 599            g_test_skip("/dev/shm is not supported");
 600            return -1;
 601        }
 602    }
 603
 604    got_stop = false;
 605    bootpath = g_strdup_printf("%s/bootsect", tmpfs);
 606    if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
 607        /* the assembled x86 boot sector should be exactly one sector large */
 608        assert(sizeof(x86_bootsect) == 512);
 609        init_bootfile(bootpath, x86_bootsect, sizeof(x86_bootsect));
 610        memory_size = "150M";
 611        arch_source = g_strdup_printf("-drive file=%s,format=raw", bootpath);
 612        arch_target = g_strdup(arch_source);
 613        start_address = X86_TEST_MEM_START;
 614        end_address = X86_TEST_MEM_END;
 615    } else if (g_str_equal(arch, "s390x")) {
 616        init_bootfile(bootpath, s390x_elf, sizeof(s390x_elf));
 617        memory_size = "128M";
 618        arch_source = g_strdup_printf("-bios %s", bootpath);
 619        arch_target = g_strdup(arch_source);
 620        start_address = S390_TEST_MEM_START;
 621        end_address = S390_TEST_MEM_END;
 622    } else if (strcmp(arch, "ppc64") == 0) {
 623        machine_opts = "vsmt=8";
 624        memory_size = "256M";
 625        start_address = PPC_TEST_MEM_START;
 626        end_address = PPC_TEST_MEM_END;
 627        arch_source = g_strdup_printf("-nodefaults "
 628                                      "-prom-env 'use-nvramrc?=true' -prom-env "
 629                                      "'nvramrc=hex .\" _\" begin %x %x "
 630                                      "do i c@ 1 + i c! 1000 +loop .\" B\" 0 "
 631                                      "until'", end_address, start_address);
 632        arch_target = g_strdup("");
 633    } else if (strcmp(arch, "aarch64") == 0) {
 634        init_bootfile(bootpath, aarch64_kernel, sizeof(aarch64_kernel));
 635        machine_opts = "virt,gic-version=max";
 636        memory_size = "150M";
 637        arch_source = g_strdup_printf("-cpu max "
 638                                      "-kernel %s",
 639                                      bootpath);
 640        arch_target = g_strdup(arch_source);
 641        start_address = ARM_TEST_MEM_START;
 642        end_address = ARM_TEST_MEM_END;
 643
 644        g_assert(sizeof(aarch64_kernel) <= ARM_TEST_MAX_KERNEL_SIZE);
 645    } else {
 646        g_assert_not_reached();
 647    }
 648
 649    if (!getenv("QTEST_LOG") && args->hide_stderr) {
 650        ignore_stderr = "2>/dev/null";
 651    } else {
 652        ignore_stderr = "";
 653    }
 654
 655    if (args->use_shmem) {
 656        shmem_path = g_strdup_printf("/dev/shm/qemu-%d", getpid());
 657        shmem_opts = g_strdup_printf(
 658            "-object memory-backend-file,id=mem0,size=%s"
 659            ",mem-path=%s,share=on -numa node,memdev=mem0",
 660            memory_size, shmem_path);
 661    } else {
 662        shmem_path = NULL;
 663        shmem_opts = g_strdup("");
 664    }
 665
 666    cmd_source = g_strdup_printf("-accel kvm%s -accel tcg%s%s "
 667                                 "-name source,debug-threads=on "
 668                                 "-m %s "
 669                                 "-serial file:%s/src_serial "
 670                                 "%s %s %s %s",
 671                                 args->use_dirty_ring ?
 672                                 ",dirty-ring-size=4096" : "",
 673                                 machine_opts ? " -machine " : "",
 674                                 machine_opts ? machine_opts : "",
 675                                 memory_size, tmpfs,
 676                                 arch_source, shmem_opts,
 677                                 args->opts_source ? args->opts_source : "",
 678                                 ignore_stderr);
 679    if (!args->only_target) {
 680        *from = qtest_init(cmd_source);
 681    }
 682
 683    cmd_target = g_strdup_printf("-accel kvm%s -accel tcg%s%s "
 684                                 "-name target,debug-threads=on "
 685                                 "-m %s "
 686                                 "-serial file:%s/dest_serial "
 687                                 "-incoming %s "
 688                                 "%s %s %s %s",
 689                                 args->use_dirty_ring ?
 690                                 ",dirty-ring-size=4096" : "",
 691                                 machine_opts ? " -machine " : "",
 692                                 machine_opts ? machine_opts : "",
 693                                 memory_size, tmpfs, uri,
 694                                 arch_target, shmem_opts,
 695                                 args->opts_target ? args->opts_target : "",
 696                                 ignore_stderr);
 697    *to = qtest_init(cmd_target);
 698
 699    /*
 700     * Remove shmem file immediately to avoid memory leak in test failed case.
 701     * It's valid becase QEMU has already opened this file
 702     */
 703    if (args->use_shmem) {
 704        unlink(shmem_path);
 705    }
 706
 707    return 0;
 708}
 709
 710static void test_migrate_end(QTestState *from, QTestState *to, bool test_dest)
 711{
 712    unsigned char dest_byte_a, dest_byte_b, dest_byte_c, dest_byte_d;
 713
 714    qtest_quit(from);
 715
 716    if (test_dest) {
 717        qtest_memread(to, start_address, &dest_byte_a, 1);
 718
 719        /* Destination still running, wait for a byte to change */
 720        do {
 721            qtest_memread(to, start_address, &dest_byte_b, 1);
 722            usleep(1000 * 10);
 723        } while (dest_byte_a == dest_byte_b);
 724
 725        qtest_qmp_discard_response(to, "{ 'execute' : 'stop'}");
 726
 727        /* With it stopped, check nothing changes */
 728        qtest_memread(to, start_address, &dest_byte_c, 1);
 729        usleep(1000 * 200);
 730        qtest_memread(to, start_address, &dest_byte_d, 1);
 731        g_assert_cmpint(dest_byte_c, ==, dest_byte_d);
 732
 733        check_guests_ram(to);
 734    }
 735
 736    qtest_quit(to);
 737
 738    cleanup("bootsect");
 739    cleanup("migsocket");
 740    cleanup("src_serial");
 741    cleanup("dest_serial");
 742}
 743
 744#ifdef CONFIG_GNUTLS
 745struct TestMigrateTLSPSKData {
 746    char *workdir;
 747    char *workdiralt;
 748    char *pskfile;
 749    char *pskfilealt;
 750};
 751
 752static void *
 753test_migrate_tls_psk_start_common(QTestState *from,
 754                                  QTestState *to,
 755                                  bool mismatch)
 756{
 757    struct TestMigrateTLSPSKData *data =
 758        g_new0(struct TestMigrateTLSPSKData, 1);
 759    QDict *rsp;
 760
 761    data->workdir = g_strdup_printf("%s/tlscredspsk0", tmpfs);
 762    data->pskfile = g_strdup_printf("%s/%s", data->workdir,
 763                                    QCRYPTO_TLS_CREDS_PSKFILE);
 764    mkdir(data->workdir, 0700);
 765    test_tls_psk_init(data->pskfile);
 766
 767    if (mismatch) {
 768        data->workdiralt = g_strdup_printf("%s/tlscredspskalt0", tmpfs);
 769        data->pskfilealt = g_strdup_printf("%s/%s", data->workdiralt,
 770                                           QCRYPTO_TLS_CREDS_PSKFILE);
 771        mkdir(data->workdiralt, 0700);
 772        test_tls_psk_init_alt(data->pskfilealt);
 773    }
 774
 775    rsp = wait_command(from,
 776                       "{ 'execute': 'object-add',"
 777                       "  'arguments': { 'qom-type': 'tls-creds-psk',"
 778                       "                 'id': 'tlscredspsk0',"
 779                       "                 'endpoint': 'client',"
 780                       "                 'dir': %s,"
 781                       "                 'username': 'qemu'} }",
 782                       data->workdir);
 783    qobject_unref(rsp);
 784
 785    rsp = wait_command(to,
 786                       "{ 'execute': 'object-add',"
 787                       "  'arguments': { 'qom-type': 'tls-creds-psk',"
 788                       "                 'id': 'tlscredspsk0',"
 789                       "                 'endpoint': 'server',"
 790                       "                 'dir': %s } }",
 791                       mismatch ? data->workdiralt : data->workdir);
 792    qobject_unref(rsp);
 793
 794    migrate_set_parameter_str(from, "tls-creds", "tlscredspsk0");
 795    migrate_set_parameter_str(to, "tls-creds", "tlscredspsk0");
 796
 797    return data;
 798}
 799
 800static void *
 801test_migrate_tls_psk_start_match(QTestState *from,
 802                                 QTestState *to)
 803{
 804    return test_migrate_tls_psk_start_common(from, to, false);
 805}
 806
 807static void *
 808test_migrate_tls_psk_start_mismatch(QTestState *from,
 809                                    QTestState *to)
 810{
 811    return test_migrate_tls_psk_start_common(from, to, true);
 812}
 813
 814static void
 815test_migrate_tls_psk_finish(QTestState *from,
 816                            QTestState *to,
 817                            void *opaque)
 818{
 819    struct TestMigrateTLSPSKData *data = opaque;
 820
 821    test_tls_psk_cleanup(data->pskfile);
 822    if (data->pskfilealt) {
 823        test_tls_psk_cleanup(data->pskfilealt);
 824    }
 825    rmdir(data->workdir);
 826    if (data->workdiralt) {
 827        rmdir(data->workdiralt);
 828    }
 829
 830    g_free(data->workdiralt);
 831    g_free(data->pskfilealt);
 832    g_free(data->workdir);
 833    g_free(data->pskfile);
 834    g_free(data);
 835}
 836
 837#ifdef CONFIG_TASN1
 838typedef struct {
 839    char *workdir;
 840    char *keyfile;
 841    char *cacert;
 842    char *servercert;
 843    char *serverkey;
 844    char *clientcert;
 845    char *clientkey;
 846} TestMigrateTLSX509Data;
 847
 848typedef struct {
 849    bool verifyclient;
 850    bool clientcert;
 851    bool hostileclient;
 852    bool authzclient;
 853    const char *certhostname;
 854    const char *certipaddr;
 855} TestMigrateTLSX509;
 856
 857static void *
 858test_migrate_tls_x509_start_common(QTestState *from,
 859                                   QTestState *to,
 860                                   TestMigrateTLSX509 *args)
 861{
 862    TestMigrateTLSX509Data *data = g_new0(TestMigrateTLSX509Data, 1);
 863    QDict *rsp;
 864
 865    data->workdir = g_strdup_printf("%s/tlscredsx5090", tmpfs);
 866    data->keyfile = g_strdup_printf("%s/key.pem", data->workdir);
 867
 868    data->cacert = g_strdup_printf("%s/ca-cert.pem", data->workdir);
 869    data->serverkey = g_strdup_printf("%s/server-key.pem", data->workdir);
 870    data->servercert = g_strdup_printf("%s/server-cert.pem", data->workdir);
 871    if (args->clientcert) {
 872        data->clientkey = g_strdup_printf("%s/client-key.pem", data->workdir);
 873        data->clientcert = g_strdup_printf("%s/client-cert.pem", data->workdir);
 874    }
 875
 876    mkdir(data->workdir, 0700);
 877
 878    test_tls_init(data->keyfile);
 879    g_assert(link(data->keyfile, data->serverkey) == 0);
 880    if (args->clientcert) {
 881        g_assert(link(data->keyfile, data->clientkey) == 0);
 882    }
 883
 884    TLS_ROOT_REQ_SIMPLE(cacertreq, data->cacert);
 885    if (args->clientcert) {
 886        TLS_CERT_REQ_SIMPLE_CLIENT(servercertreq, cacertreq,
 887                                   args->hostileclient ?
 888                                   QCRYPTO_TLS_TEST_CLIENT_HOSTILE_NAME :
 889                                   QCRYPTO_TLS_TEST_CLIENT_NAME,
 890                                   data->clientcert);
 891    }
 892
 893    TLS_CERT_REQ_SIMPLE_SERVER(clientcertreq, cacertreq,
 894                               data->servercert,
 895                               args->certhostname,
 896                               args->certipaddr);
 897
 898    rsp = wait_command(from,
 899                       "{ 'execute': 'object-add',"
 900                       "  'arguments': { 'qom-type': 'tls-creds-x509',"
 901                       "                 'id': 'tlscredsx509client0',"
 902                       "                 'endpoint': 'client',"
 903                       "                 'dir': %s,"
 904                       "                 'sanity-check': true,"
 905                       "                 'verify-peer': true} }",
 906                       data->workdir);
 907    qobject_unref(rsp);
 908    migrate_set_parameter_str(from, "tls-creds", "tlscredsx509client0");
 909    if (args->certhostname) {
 910        migrate_set_parameter_str(from, "tls-hostname", args->certhostname);
 911    }
 912
 913    rsp = wait_command(to,
 914                       "{ 'execute': 'object-add',"
 915                       "  'arguments': { 'qom-type': 'tls-creds-x509',"
 916                       "                 'id': 'tlscredsx509server0',"
 917                       "                 'endpoint': 'server',"
 918                       "                 'dir': %s,"
 919                       "                 'sanity-check': true,"
 920                       "                 'verify-peer': %i} }",
 921                       data->workdir, args->verifyclient);
 922    qobject_unref(rsp);
 923    migrate_set_parameter_str(to, "tls-creds", "tlscredsx509server0");
 924
 925    if (args->authzclient) {
 926        rsp = wait_command(to,
 927                           "{ 'execute': 'object-add',"
 928                           "  'arguments': { 'qom-type': 'authz-simple',"
 929                           "                 'id': 'tlsauthz0',"
 930                           "                 'identity': %s} }",
 931                           "CN=" QCRYPTO_TLS_TEST_CLIENT_NAME);
 932        migrate_set_parameter_str(to, "tls-authz", "tlsauthz0");
 933    }
 934
 935    return data;
 936}
 937
 938/*
 939 * The normal case: match server's cert hostname against
 940 * whatever host we were telling QEMU to connect to (if any)
 941 */
 942static void *
 943test_migrate_tls_x509_start_default_host(QTestState *from,
 944                                         QTestState *to)
 945{
 946    TestMigrateTLSX509 args = {
 947        .verifyclient = true,
 948        .clientcert = true,
 949        .certipaddr = "127.0.0.1"
 950    };
 951    return test_migrate_tls_x509_start_common(from, to, &args);
 952}
 953
 954/*
 955 * The unusual case: the server's cert is different from
 956 * the address we're telling QEMU to connect to (if any),
 957 * so we must give QEMU an explicit hostname to validate
 958 */
 959static void *
 960test_migrate_tls_x509_start_override_host(QTestState *from,
 961                                          QTestState *to)
 962{
 963    TestMigrateTLSX509 args = {
 964        .verifyclient = true,
 965        .clientcert = true,
 966        .certhostname = "qemu.org",
 967    };
 968    return test_migrate_tls_x509_start_common(from, to, &args);
 969}
 970
 971/*
 972 * The unusual case: the server's cert is different from
 973 * the address we're telling QEMU to connect to, and so we
 974 * expect the client to reject the server
 975 */
 976static void *
 977test_migrate_tls_x509_start_mismatch_host(QTestState *from,
 978                                          QTestState *to)
 979{
 980    TestMigrateTLSX509 args = {
 981        .verifyclient = true,
 982        .clientcert = true,
 983        .certipaddr = "10.0.0.1",
 984    };
 985    return test_migrate_tls_x509_start_common(from, to, &args);
 986}
 987
 988static void *
 989test_migrate_tls_x509_start_friendly_client(QTestState *from,
 990                                            QTestState *to)
 991{
 992    TestMigrateTLSX509 args = {
 993        .verifyclient = true,
 994        .clientcert = true,
 995        .authzclient = true,
 996        .certipaddr = "127.0.0.1",
 997    };
 998    return test_migrate_tls_x509_start_common(from, to, &args);
 999}
1000
1001static void *
1002test_migrate_tls_x509_start_hostile_client(QTestState *from,
1003                                           QTestState *to)
1004{
1005    TestMigrateTLSX509 args = {
1006        .verifyclient = true,
1007        .clientcert = true,
1008        .hostileclient = true,
1009        .authzclient = true,
1010        .certipaddr = "127.0.0.1",
1011    };
1012    return test_migrate_tls_x509_start_common(from, to, &args);
1013}
1014
1015/*
1016 * The case with no client certificate presented,
1017 * and no server verification
1018 */
1019static void *
1020test_migrate_tls_x509_start_allow_anon_client(QTestState *from,
1021                                              QTestState *to)
1022{
1023    TestMigrateTLSX509 args = {
1024        .certipaddr = "127.0.0.1",
1025    };
1026    return test_migrate_tls_x509_start_common(from, to, &args);
1027}
1028
1029/*
1030 * The case with no client certificate presented,
1031 * and server verification rejecting
1032 */
1033static void *
1034test_migrate_tls_x509_start_reject_anon_client(QTestState *from,
1035                                               QTestState *to)
1036{
1037    TestMigrateTLSX509 args = {
1038        .verifyclient = true,
1039        .certipaddr = "127.0.0.1",
1040    };
1041    return test_migrate_tls_x509_start_common(from, to, &args);
1042}
1043
1044static void
1045test_migrate_tls_x509_finish(QTestState *from,
1046                             QTestState *to,
1047                             void *opaque)
1048{
1049    TestMigrateTLSX509Data *data = opaque;
1050
1051    test_tls_cleanup(data->keyfile);
1052    unlink(data->cacert);
1053    unlink(data->servercert);
1054    unlink(data->serverkey);
1055    unlink(data->clientcert);
1056    unlink(data->clientkey);
1057    rmdir(data->workdir);
1058
1059    g_free(data->workdir);
1060    g_free(data->keyfile);
1061    g_free(data);
1062}
1063#endif /* CONFIG_TASN1 */
1064#endif /* CONFIG_GNUTLS */
1065
1066static int migrate_postcopy_prepare(QTestState **from_ptr,
1067                                    QTestState **to_ptr,
1068                                    MigrateCommon *args)
1069{
1070    g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1071    QTestState *from, *to;
1072
1073    if (test_migrate_start(&from, &to, uri, &args->start)) {
1074        return -1;
1075    }
1076
1077    if (args->start_hook) {
1078        args->postcopy_data = args->start_hook(from, to);
1079    }
1080
1081    migrate_set_capability(from, "postcopy-ram", true);
1082    migrate_set_capability(to, "postcopy-ram", true);
1083    migrate_set_capability(to, "postcopy-blocktime", true);
1084
1085    if (args->postcopy_preempt) {
1086        migrate_set_capability(from, "postcopy-preempt", true);
1087        migrate_set_capability(to, "postcopy-preempt", true);
1088    }
1089
1090    migrate_ensure_non_converge(from);
1091
1092    /* Wait for the first serial output from the source */
1093    wait_for_serial("src_serial");
1094
1095    migrate_qmp(from, uri, "{}");
1096
1097    wait_for_migration_pass(from);
1098
1099    *from_ptr = from;
1100    *to_ptr = to;
1101
1102    return 0;
1103}
1104
1105static void migrate_postcopy_complete(QTestState *from, QTestState *to,
1106                                      MigrateCommon *args)
1107{
1108    wait_for_migration_complete(from);
1109
1110    /* Make sure we get at least one "B" on destination */
1111    wait_for_serial("dest_serial");
1112
1113    if (uffd_feature_thread_id) {
1114        read_blocktime(to);
1115    }
1116
1117    if (args->finish_hook) {
1118        args->finish_hook(from, to, args->postcopy_data);
1119        args->postcopy_data = NULL;
1120    }
1121
1122    test_migrate_end(from, to, true);
1123}
1124
1125static void test_postcopy_common(MigrateCommon *args)
1126{
1127    QTestState *from, *to;
1128
1129    if (migrate_postcopy_prepare(&from, &to, args)) {
1130        return;
1131    }
1132    migrate_postcopy_start(from, to);
1133    migrate_postcopy_complete(from, to, args);
1134}
1135
1136static void test_postcopy(void)
1137{
1138    MigrateCommon args = { };
1139
1140    test_postcopy_common(&args);
1141}
1142
1143static void test_postcopy_preempt(void)
1144{
1145    MigrateCommon args = {
1146        .postcopy_preempt = true,
1147    };
1148
1149    test_postcopy_common(&args);
1150}
1151
1152#ifdef CONFIG_GNUTLS
1153static void test_postcopy_tls_psk(void)
1154{
1155    MigrateCommon args = {
1156        .start_hook = test_migrate_tls_psk_start_match,
1157        .finish_hook = test_migrate_tls_psk_finish,
1158    };
1159
1160    test_postcopy_common(&args);
1161}
1162
1163static void test_postcopy_preempt_tls_psk(void)
1164{
1165    MigrateCommon args = {
1166        .postcopy_preempt = true,
1167        .start_hook = test_migrate_tls_psk_start_match,
1168        .finish_hook = test_migrate_tls_psk_finish,
1169    };
1170
1171    test_postcopy_common(&args);
1172}
1173#endif
1174
1175static void test_postcopy_recovery_common(MigrateCommon *args)
1176{
1177    QTestState *from, *to;
1178    g_autofree char *uri = NULL;
1179
1180    /* Always hide errors for postcopy recover tests since they're expected */
1181    args->start.hide_stderr = true;
1182
1183    if (migrate_postcopy_prepare(&from, &to, args)) {
1184        return;
1185    }
1186
1187    /* Turn postcopy speed down, 4K/s is slow enough on any machines */
1188    migrate_set_parameter_int(from, "max-postcopy-bandwidth", 4096);
1189
1190    /* Now we start the postcopy */
1191    migrate_postcopy_start(from, to);
1192
1193    /*
1194     * Wait until postcopy is really started; we can only run the
1195     * migrate-pause command during a postcopy
1196     */
1197    wait_for_migration_status(from, "postcopy-active", NULL);
1198
1199    /*
1200     * Manually stop the postcopy migration. This emulates a network
1201     * failure with the migration socket
1202     */
1203    migrate_pause(from);
1204
1205    /*
1206     * Wait for destination side to reach postcopy-paused state.  The
1207     * migrate-recover command can only succeed if destination machine
1208     * is in the paused state
1209     */
1210    wait_for_migration_status(to, "postcopy-paused",
1211                              (const char * []) { "failed", "active",
1212                                                  "completed", NULL });
1213
1214    /*
1215     * Create a new socket to emulate a new channel that is different
1216     * from the broken migration channel; tell the destination to
1217     * listen to the new port
1218     */
1219    uri = g_strdup_printf("unix:%s/migsocket-recover", tmpfs);
1220    migrate_recover(to, uri);
1221
1222    /*
1223     * Try to rebuild the migration channel using the resume flag and
1224     * the newly created channel
1225     */
1226    wait_for_migration_status(from, "postcopy-paused",
1227                              (const char * []) { "failed", "active",
1228                                                  "completed", NULL });
1229    migrate_qmp(from, uri, "{'resume': true}");
1230
1231    /* Restore the postcopy bandwidth to unlimited */
1232    migrate_set_parameter_int(from, "max-postcopy-bandwidth", 0);
1233
1234    migrate_postcopy_complete(from, to, args);
1235}
1236
1237static void test_postcopy_recovery(void)
1238{
1239    MigrateCommon args = { };
1240
1241    test_postcopy_recovery_common(&args);
1242}
1243
1244#ifdef CONFIG_GNUTLS
1245static void test_postcopy_recovery_tls_psk(void)
1246{
1247    MigrateCommon args = {
1248        .start_hook = test_migrate_tls_psk_start_match,
1249        .finish_hook = test_migrate_tls_psk_finish,
1250    };
1251
1252    test_postcopy_recovery_common(&args);
1253}
1254#endif
1255
1256static void test_postcopy_preempt_recovery(void)
1257{
1258    MigrateCommon args = {
1259        .postcopy_preempt = true,
1260    };
1261
1262    test_postcopy_recovery_common(&args);
1263}
1264
1265#ifdef CONFIG_GNUTLS
1266/* This contains preempt+recovery+tls test altogether */
1267static void test_postcopy_preempt_all(void)
1268{
1269    MigrateCommon args = {
1270        .postcopy_preempt = true,
1271        .start_hook = test_migrate_tls_psk_start_match,
1272        .finish_hook = test_migrate_tls_psk_finish,
1273    };
1274
1275    test_postcopy_recovery_common(&args);
1276}
1277#endif
1278
1279static void test_baddest(void)
1280{
1281    MigrateStart args = {
1282        .hide_stderr = true
1283    };
1284    QTestState *from, *to;
1285
1286    if (test_migrate_start(&from, &to, "tcp:127.0.0.1:0", &args)) {
1287        return;
1288    }
1289    migrate_qmp(from, "tcp:127.0.0.1:0", "{}");
1290    wait_for_migration_fail(from, false);
1291    test_migrate_end(from, to, false);
1292}
1293
1294static void test_precopy_common(MigrateCommon *args)
1295{
1296    QTestState *from, *to;
1297    void *data_hook = NULL;
1298
1299    if (test_migrate_start(&from, &to, args->listen_uri, &args->start)) {
1300        return;
1301    }
1302
1303    migrate_ensure_non_converge(from);
1304
1305    if (args->start_hook) {
1306        data_hook = args->start_hook(from, to);
1307    }
1308
1309    /* Wait for the first serial output from the source */
1310    if (args->result == MIG_TEST_SUCCEED) {
1311        wait_for_serial("src_serial");
1312    }
1313
1314    if (!args->connect_uri) {
1315        g_autofree char *local_connect_uri =
1316            migrate_get_socket_address(to, "socket-address");
1317        migrate_qmp(from, local_connect_uri, "{}");
1318    } else {
1319        migrate_qmp(from, args->connect_uri, "{}");
1320    }
1321
1322
1323    if (args->result != MIG_TEST_SUCCEED) {
1324        bool allow_active = args->result == MIG_TEST_FAIL;
1325        wait_for_migration_fail(from, allow_active);
1326
1327        if (args->result == MIG_TEST_FAIL_DEST_QUIT_ERR) {
1328            qtest_set_expected_status(to, 1);
1329        }
1330    } else {
1331        if (args->iterations) {
1332            while (args->iterations--) {
1333                wait_for_migration_pass(from);
1334            }
1335        } else {
1336            wait_for_migration_pass(from);
1337        }
1338
1339        migrate_ensure_converge(from);
1340
1341        /* We do this first, as it has a timeout to stop us
1342         * hanging forever if migration didn't converge */
1343        wait_for_migration_complete(from);
1344
1345        if (!got_stop) {
1346            qtest_qmp_eventwait(from, "STOP");
1347        }
1348
1349        qtest_qmp_eventwait(to, "RESUME");
1350
1351        wait_for_serial("dest_serial");
1352    }
1353
1354    if (args->finish_hook) {
1355        args->finish_hook(from, to, data_hook);
1356    }
1357
1358    test_migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
1359}
1360
1361static void test_precopy_unix_plain(void)
1362{
1363    g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1364    MigrateCommon args = {
1365        .listen_uri = uri,
1366        .connect_uri = uri,
1367    };
1368
1369    test_precopy_common(&args);
1370}
1371
1372
1373static void test_precopy_unix_dirty_ring(void)
1374{
1375    g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1376    MigrateCommon args = {
1377        .start = {
1378            .use_dirty_ring = true,
1379        },
1380        .listen_uri = uri,
1381        .connect_uri = uri,
1382    };
1383
1384    test_precopy_common(&args);
1385}
1386
1387#ifdef CONFIG_GNUTLS
1388static void test_precopy_unix_tls_psk(void)
1389{
1390    g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1391    MigrateCommon args = {
1392        .connect_uri = uri,
1393        .listen_uri = uri,
1394        .start_hook = test_migrate_tls_psk_start_match,
1395        .finish_hook = test_migrate_tls_psk_finish,
1396    };
1397
1398    test_precopy_common(&args);
1399}
1400
1401#ifdef CONFIG_TASN1
1402static void test_precopy_unix_tls_x509_default_host(void)
1403{
1404    g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1405    MigrateCommon args = {
1406        .start = {
1407            .hide_stderr = true,
1408        },
1409        .connect_uri = uri,
1410        .listen_uri = uri,
1411        .start_hook = test_migrate_tls_x509_start_default_host,
1412        .finish_hook = test_migrate_tls_x509_finish,
1413        .result = MIG_TEST_FAIL_DEST_QUIT_ERR,
1414    };
1415
1416    test_precopy_common(&args);
1417}
1418
1419static void test_precopy_unix_tls_x509_override_host(void)
1420{
1421    g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1422    MigrateCommon args = {
1423        .connect_uri = uri,
1424        .listen_uri = uri,
1425        .start_hook = test_migrate_tls_x509_start_override_host,
1426        .finish_hook = test_migrate_tls_x509_finish,
1427    };
1428
1429    test_precopy_common(&args);
1430}
1431#endif /* CONFIG_TASN1 */
1432#endif /* CONFIG_GNUTLS */
1433
1434#if 0
1435/* Currently upset on aarch64 TCG */
1436static void test_ignore_shared(void)
1437{
1438    g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1439    QTestState *from, *to;
1440
1441    if (test_migrate_start(&from, &to, uri, false, true, NULL, NULL)) {
1442        return;
1443    }
1444
1445    migrate_set_capability(from, "x-ignore-shared", true);
1446    migrate_set_capability(to, "x-ignore-shared", true);
1447
1448    /* Wait for the first serial output from the source */
1449    wait_for_serial("src_serial");
1450
1451    migrate_qmp(from, uri, "{}");
1452
1453    wait_for_migration_pass(from);
1454
1455    if (!got_stop) {
1456        qtest_qmp_eventwait(from, "STOP");
1457    }
1458
1459    qtest_qmp_eventwait(to, "RESUME");
1460
1461    wait_for_serial("dest_serial");
1462    wait_for_migration_complete(from);
1463
1464    /* Check whether shared RAM has been really skipped */
1465    g_assert_cmpint(read_ram_property_int(from, "transferred"), <, 1024 * 1024);
1466
1467    test_migrate_end(from, to, true);
1468}
1469#endif
1470
1471static void *
1472test_migrate_xbzrle_start(QTestState *from,
1473                          QTestState *to)
1474{
1475    migrate_set_parameter_int(from, "xbzrle-cache-size", 33554432);
1476
1477    migrate_set_capability(from, "xbzrle", true);
1478    migrate_set_capability(to, "xbzrle", true);
1479
1480    return NULL;
1481}
1482
1483static void test_precopy_unix_xbzrle(void)
1484{
1485    g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1486    MigrateCommon args = {
1487        .connect_uri = uri,
1488        .listen_uri = uri,
1489
1490        .start_hook = test_migrate_xbzrle_start,
1491
1492        .iterations = 2,
1493    };
1494
1495    test_precopy_common(&args);
1496}
1497
1498static void test_precopy_tcp_plain(void)
1499{
1500    MigrateCommon args = {
1501        .listen_uri = "tcp:127.0.0.1:0",
1502    };
1503
1504    test_precopy_common(&args);
1505}
1506
1507#ifdef CONFIG_GNUTLS
1508static void test_precopy_tcp_tls_psk_match(void)
1509{
1510    MigrateCommon args = {
1511        .listen_uri = "tcp:127.0.0.1:0",
1512        .start_hook = test_migrate_tls_psk_start_match,
1513        .finish_hook = test_migrate_tls_psk_finish,
1514    };
1515
1516    test_precopy_common(&args);
1517}
1518
1519static void test_precopy_tcp_tls_psk_mismatch(void)
1520{
1521    MigrateCommon args = {
1522        .start = {
1523            .hide_stderr = true,
1524        },
1525        .listen_uri = "tcp:127.0.0.1:0",
1526        .start_hook = test_migrate_tls_psk_start_mismatch,
1527        .finish_hook = test_migrate_tls_psk_finish,
1528        .result = MIG_TEST_FAIL,
1529    };
1530
1531    test_precopy_common(&args);
1532}
1533
1534#ifdef CONFIG_TASN1
1535static void test_precopy_tcp_tls_x509_default_host(void)
1536{
1537    MigrateCommon args = {
1538        .listen_uri = "tcp:127.0.0.1:0",
1539        .start_hook = test_migrate_tls_x509_start_default_host,
1540        .finish_hook = test_migrate_tls_x509_finish,
1541    };
1542
1543    test_precopy_common(&args);
1544}
1545
1546static void test_precopy_tcp_tls_x509_override_host(void)
1547{
1548    MigrateCommon args = {
1549        .listen_uri = "tcp:127.0.0.1:0",
1550        .start_hook = test_migrate_tls_x509_start_override_host,
1551        .finish_hook = test_migrate_tls_x509_finish,
1552    };
1553
1554    test_precopy_common(&args);
1555}
1556
1557static void test_precopy_tcp_tls_x509_mismatch_host(void)
1558{
1559    MigrateCommon args = {
1560        .start = {
1561            .hide_stderr = true,
1562        },
1563        .listen_uri = "tcp:127.0.0.1:0",
1564        .start_hook = test_migrate_tls_x509_start_mismatch_host,
1565        .finish_hook = test_migrate_tls_x509_finish,
1566        .result = MIG_TEST_FAIL_DEST_QUIT_ERR,
1567    };
1568
1569    test_precopy_common(&args);
1570}
1571
1572static void test_precopy_tcp_tls_x509_friendly_client(void)
1573{
1574    MigrateCommon args = {
1575        .listen_uri = "tcp:127.0.0.1:0",
1576        .start_hook = test_migrate_tls_x509_start_friendly_client,
1577        .finish_hook = test_migrate_tls_x509_finish,
1578    };
1579
1580    test_precopy_common(&args);
1581}
1582
1583static void test_precopy_tcp_tls_x509_hostile_client(void)
1584{
1585    MigrateCommon args = {
1586        .start = {
1587            .hide_stderr = true,
1588        },
1589        .listen_uri = "tcp:127.0.0.1:0",
1590        .start_hook = test_migrate_tls_x509_start_hostile_client,
1591        .finish_hook = test_migrate_tls_x509_finish,
1592        .result = MIG_TEST_FAIL,
1593    };
1594
1595    test_precopy_common(&args);
1596}
1597
1598static void test_precopy_tcp_tls_x509_allow_anon_client(void)
1599{
1600    MigrateCommon args = {
1601        .listen_uri = "tcp:127.0.0.1:0",
1602        .start_hook = test_migrate_tls_x509_start_allow_anon_client,
1603        .finish_hook = test_migrate_tls_x509_finish,
1604    };
1605
1606    test_precopy_common(&args);
1607}
1608
1609static void test_precopy_tcp_tls_x509_reject_anon_client(void)
1610{
1611    MigrateCommon args = {
1612        .start = {
1613            .hide_stderr = true,
1614        },
1615        .listen_uri = "tcp:127.0.0.1:0",
1616        .start_hook = test_migrate_tls_x509_start_reject_anon_client,
1617        .finish_hook = test_migrate_tls_x509_finish,
1618        .result = MIG_TEST_FAIL,
1619    };
1620
1621    test_precopy_common(&args);
1622}
1623#endif /* CONFIG_TASN1 */
1624#endif /* CONFIG_GNUTLS */
1625
1626static void *test_migrate_fd_start_hook(QTestState *from,
1627                                        QTestState *to)
1628{
1629    QDict *rsp;
1630    int ret;
1631    int pair[2];
1632
1633    /* Create two connected sockets for migration */
1634    ret = socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
1635    g_assert_cmpint(ret, ==, 0);
1636
1637    /* Send the 1st socket to the target */
1638    rsp = wait_command_fd(to, pair[0],
1639                          "{ 'execute': 'getfd',"
1640                          "  'arguments': { 'fdname': 'fd-mig' }}");
1641    qobject_unref(rsp);
1642    close(pair[0]);
1643
1644    /* Start incoming migration from the 1st socket */
1645    rsp = wait_command(to, "{ 'execute': 'migrate-incoming',"
1646                           "  'arguments': { 'uri': 'fd:fd-mig' }}");
1647    qobject_unref(rsp);
1648
1649    /* Send the 2nd socket to the target */
1650    rsp = wait_command_fd(from, pair[1],
1651                          "{ 'execute': 'getfd',"
1652                          "  'arguments': { 'fdname': 'fd-mig' }}");
1653    qobject_unref(rsp);
1654    close(pair[1]);
1655
1656    return NULL;
1657}
1658
1659static void test_migrate_fd_finish_hook(QTestState *from,
1660                                        QTestState *to,
1661                                        void *opaque)
1662{
1663    QDict *rsp;
1664    const char *error_desc;
1665
1666    /* Test closing fds */
1667    /* We assume, that QEMU removes named fd from its list,
1668     * so this should fail */
1669    rsp = qtest_qmp(from, "{ 'execute': 'closefd',"
1670                          "  'arguments': { 'fdname': 'fd-mig' }}");
1671    g_assert_true(qdict_haskey(rsp, "error"));
1672    error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
1673    g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
1674    qobject_unref(rsp);
1675
1676    rsp = qtest_qmp(to, "{ 'execute': 'closefd',"
1677                        "  'arguments': { 'fdname': 'fd-mig' }}");
1678    g_assert_true(qdict_haskey(rsp, "error"));
1679    error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
1680    g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
1681    qobject_unref(rsp);
1682}
1683
1684static void test_migrate_fd_proto(void)
1685{
1686    MigrateCommon args = {
1687        .listen_uri = "defer",
1688        .connect_uri = "fd:fd-mig",
1689        .start_hook = test_migrate_fd_start_hook,
1690        .finish_hook = test_migrate_fd_finish_hook
1691    };
1692    test_precopy_common(&args);
1693}
1694
1695static void do_test_validate_uuid(MigrateStart *args, bool should_fail)
1696{
1697    g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1698    QTestState *from, *to;
1699
1700    if (test_migrate_start(&from, &to, uri, args)) {
1701        return;
1702    }
1703
1704    /*
1705     * UUID validation is at the begin of migration. So, the main process of
1706     * migration is not interesting for us here. Thus, set huge downtime for
1707     * very fast migration.
1708     */
1709    migrate_set_parameter_int(from, "downtime-limit", 1000000);
1710    migrate_set_capability(from, "validate-uuid", true);
1711
1712    /* Wait for the first serial output from the source */
1713    wait_for_serial("src_serial");
1714
1715    migrate_qmp(from, uri, "{}");
1716
1717    if (should_fail) {
1718        qtest_set_expected_status(to, 1);
1719        wait_for_migration_fail(from, true);
1720    } else {
1721        wait_for_migration_complete(from);
1722    }
1723
1724    test_migrate_end(from, to, false);
1725}
1726
1727static void test_validate_uuid(void)
1728{
1729    MigrateStart args = {
1730        .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
1731        .opts_target = "-uuid 11111111-1111-1111-1111-111111111111",
1732    };
1733
1734    do_test_validate_uuid(&args, false);
1735}
1736
1737static void test_validate_uuid_error(void)
1738{
1739    MigrateStart args = {
1740        .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
1741        .opts_target = "-uuid 22222222-2222-2222-2222-222222222222",
1742        .hide_stderr = true,
1743    };
1744
1745    do_test_validate_uuid(&args, true);
1746}
1747
1748static void test_validate_uuid_src_not_set(void)
1749{
1750    MigrateStart args = {
1751        .opts_target = "-uuid 22222222-2222-2222-2222-222222222222",
1752        .hide_stderr = true,
1753    };
1754
1755    do_test_validate_uuid(&args, false);
1756}
1757
1758static void test_validate_uuid_dst_not_set(void)
1759{
1760    MigrateStart args = {
1761        .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
1762        .hide_stderr = true,
1763    };
1764
1765    do_test_validate_uuid(&args, false);
1766}
1767
1768static void test_migrate_auto_converge(void)
1769{
1770    g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1771    MigrateStart args = {};
1772    QTestState *from, *to;
1773    int64_t percentage;
1774
1775    /*
1776     * We want the test to be stable and as fast as possible.
1777     * E.g., with 1Gb/s bandwith migration may pass without throttling,
1778     * so we need to decrease a bandwidth.
1779     */
1780    const int64_t init_pct = 5, inc_pct = 50, max_pct = 95;
1781
1782    if (test_migrate_start(&from, &to, uri, &args)) {
1783        return;
1784    }
1785
1786    migrate_set_capability(from, "auto-converge", true);
1787    migrate_set_parameter_int(from, "cpu-throttle-initial", init_pct);
1788    migrate_set_parameter_int(from, "cpu-throttle-increment", inc_pct);
1789    migrate_set_parameter_int(from, "max-cpu-throttle", max_pct);
1790
1791    /*
1792     * Set the initial parameters so that the migration could not converge
1793     * without throttling.
1794     */
1795    migrate_ensure_non_converge(from);
1796
1797    /* To check remaining size after precopy */
1798    migrate_set_capability(from, "pause-before-switchover", true);
1799
1800    /* Wait for the first serial output from the source */
1801    wait_for_serial("src_serial");
1802
1803    migrate_qmp(from, uri, "{}");
1804
1805    /* Wait for throttling begins */
1806    percentage = 0;
1807    while (percentage == 0) {
1808        percentage = read_migrate_property_int(from, "cpu-throttle-percentage");
1809        usleep(100);
1810        g_assert_false(got_stop);
1811    }
1812    /* The first percentage of throttling should be equal to init_pct */
1813    g_assert_cmpint(percentage, ==, init_pct);
1814    /* Now, when we tested that throttling works, let it converge */
1815    migrate_ensure_converge(from);
1816
1817    /*
1818     * Wait for pre-switchover status to check last throttle percentage
1819     * and remaining. These values will be zeroed later
1820     */
1821    wait_for_migration_status(from, "pre-switchover", NULL);
1822
1823    /* The final percentage of throttling shouldn't be greater than max_pct */
1824    percentage = read_migrate_property_int(from, "cpu-throttle-percentage");
1825    g_assert_cmpint(percentage, <=, max_pct);
1826    migrate_continue(from, "pre-switchover");
1827
1828    qtest_qmp_eventwait(to, "RESUME");
1829
1830    wait_for_serial("dest_serial");
1831    wait_for_migration_complete(from);
1832
1833    test_migrate_end(from, to, true);
1834}
1835
1836static void *
1837test_migrate_precopy_tcp_multifd_start_common(QTestState *from,
1838                                              QTestState *to,
1839                                              const char *method)
1840{
1841    QDict *rsp;
1842
1843    migrate_set_parameter_int(from, "multifd-channels", 16);
1844    migrate_set_parameter_int(to, "multifd-channels", 16);
1845
1846    migrate_set_parameter_str(from, "multifd-compression", method);
1847    migrate_set_parameter_str(to, "multifd-compression", method);
1848
1849    migrate_set_capability(from, "multifd", true);
1850    migrate_set_capability(to, "multifd", true);
1851
1852    /* Start incoming migration from the 1st socket */
1853    rsp = wait_command(to, "{ 'execute': 'migrate-incoming',"
1854                           "  'arguments': { 'uri': 'tcp:127.0.0.1:0' }}");
1855    qobject_unref(rsp);
1856
1857    return NULL;
1858}
1859
1860static void *
1861test_migrate_precopy_tcp_multifd_start(QTestState *from,
1862                                       QTestState *to)
1863{
1864    return test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
1865}
1866
1867static void *
1868test_migrate_precopy_tcp_multifd_zlib_start(QTestState *from,
1869                                            QTestState *to)
1870{
1871    return test_migrate_precopy_tcp_multifd_start_common(from, to, "zlib");
1872}
1873
1874#ifdef CONFIG_ZSTD
1875static void *
1876test_migrate_precopy_tcp_multifd_zstd_start(QTestState *from,
1877                                            QTestState *to)
1878{
1879    return test_migrate_precopy_tcp_multifd_start_common(from, to, "zstd");
1880}
1881#endif /* CONFIG_ZSTD */
1882
1883static void test_multifd_tcp_none(void)
1884{
1885    MigrateCommon args = {
1886        .listen_uri = "defer",
1887        .start_hook = test_migrate_precopy_tcp_multifd_start,
1888    };
1889    test_precopy_common(&args);
1890}
1891
1892static void test_multifd_tcp_zlib(void)
1893{
1894    MigrateCommon args = {
1895        .listen_uri = "defer",
1896        .start_hook = test_migrate_precopy_tcp_multifd_zlib_start,
1897    };
1898    test_precopy_common(&args);
1899}
1900
1901#ifdef CONFIG_ZSTD
1902static void test_multifd_tcp_zstd(void)
1903{
1904    MigrateCommon args = {
1905        .listen_uri = "defer",
1906        .start_hook = test_migrate_precopy_tcp_multifd_zstd_start,
1907    };
1908    test_precopy_common(&args);
1909}
1910#endif
1911
1912#ifdef CONFIG_GNUTLS
1913static void *
1914test_migrate_multifd_tcp_tls_psk_start_match(QTestState *from,
1915                                             QTestState *to)
1916{
1917    test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
1918    return test_migrate_tls_psk_start_match(from, to);
1919}
1920
1921static void *
1922test_migrate_multifd_tcp_tls_psk_start_mismatch(QTestState *from,
1923                                                QTestState *to)
1924{
1925    test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
1926    return test_migrate_tls_psk_start_mismatch(from, to);
1927}
1928
1929#ifdef CONFIG_TASN1
1930static void *
1931test_migrate_multifd_tls_x509_start_default_host(QTestState *from,
1932                                                 QTestState *to)
1933{
1934    test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
1935    return test_migrate_tls_x509_start_default_host(from, to);
1936}
1937
1938static void *
1939test_migrate_multifd_tls_x509_start_override_host(QTestState *from,
1940                                                  QTestState *to)
1941{
1942    test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
1943    return test_migrate_tls_x509_start_override_host(from, to);
1944}
1945
1946static void *
1947test_migrate_multifd_tls_x509_start_mismatch_host(QTestState *from,
1948                                                  QTestState *to)
1949{
1950    test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
1951    return test_migrate_tls_x509_start_mismatch_host(from, to);
1952}
1953
1954static void *
1955test_migrate_multifd_tls_x509_start_allow_anon_client(QTestState *from,
1956                                                      QTestState *to)
1957{
1958    test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
1959    return test_migrate_tls_x509_start_allow_anon_client(from, to);
1960}
1961
1962static void *
1963test_migrate_multifd_tls_x509_start_reject_anon_client(QTestState *from,
1964                                                       QTestState *to)
1965{
1966    test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
1967    return test_migrate_tls_x509_start_reject_anon_client(from, to);
1968}
1969#endif /* CONFIG_TASN1 */
1970
1971static void test_multifd_tcp_tls_psk_match(void)
1972{
1973    MigrateCommon args = {
1974        .listen_uri = "defer",
1975        .start_hook = test_migrate_multifd_tcp_tls_psk_start_match,
1976        .finish_hook = test_migrate_tls_psk_finish,
1977    };
1978    test_precopy_common(&args);
1979}
1980
1981static void test_multifd_tcp_tls_psk_mismatch(void)
1982{
1983    MigrateCommon args = {
1984        .start = {
1985            .hide_stderr = true,
1986        },
1987        .listen_uri = "defer",
1988        .start_hook = test_migrate_multifd_tcp_tls_psk_start_mismatch,
1989        .finish_hook = test_migrate_tls_psk_finish,
1990        .result = MIG_TEST_FAIL,
1991    };
1992    test_precopy_common(&args);
1993}
1994
1995#ifdef CONFIG_TASN1
1996static void test_multifd_tcp_tls_x509_default_host(void)
1997{
1998    MigrateCommon args = {
1999        .listen_uri = "defer",
2000        .start_hook = test_migrate_multifd_tls_x509_start_default_host,
2001        .finish_hook = test_migrate_tls_x509_finish,
2002    };
2003    test_precopy_common(&args);
2004}
2005
2006static void test_multifd_tcp_tls_x509_override_host(void)
2007{
2008    MigrateCommon args = {
2009        .listen_uri = "defer",
2010        .start_hook = test_migrate_multifd_tls_x509_start_override_host,
2011        .finish_hook = test_migrate_tls_x509_finish,
2012    };
2013    test_precopy_common(&args);
2014}
2015
2016static void test_multifd_tcp_tls_x509_mismatch_host(void)
2017{
2018    /*
2019     * This has different behaviour to the non-multifd case.
2020     *
2021     * In non-multifd case when client aborts due to mismatched
2022     * cert host, the server has already started trying to load
2023     * migration state, and so it exits with I/O failure.
2024     *
2025     * In multifd case when client aborts due to mismatched
2026     * cert host, the server is still waiting for the other
2027     * multifd connections to arrive so hasn't started trying
2028     * to load migration state, and thus just aborts the migration
2029     * without exiting.
2030     */
2031    MigrateCommon args = {
2032        .start = {
2033            .hide_stderr = true,
2034        },
2035        .listen_uri = "defer",
2036        .start_hook = test_migrate_multifd_tls_x509_start_mismatch_host,
2037        .finish_hook = test_migrate_tls_x509_finish,
2038        .result = MIG_TEST_FAIL,
2039    };
2040    test_precopy_common(&args);
2041}
2042
2043static void test_multifd_tcp_tls_x509_allow_anon_client(void)
2044{
2045    MigrateCommon args = {
2046        .listen_uri = "defer",
2047        .start_hook = test_migrate_multifd_tls_x509_start_allow_anon_client,
2048        .finish_hook = test_migrate_tls_x509_finish,
2049    };
2050    test_precopy_common(&args);
2051}
2052
2053static void test_multifd_tcp_tls_x509_reject_anon_client(void)
2054{
2055    MigrateCommon args = {
2056        .start = {
2057            .hide_stderr = true,
2058        },
2059        .listen_uri = "defer",
2060        .start_hook = test_migrate_multifd_tls_x509_start_reject_anon_client,
2061        .finish_hook = test_migrate_tls_x509_finish,
2062        .result = MIG_TEST_FAIL,
2063    };
2064    test_precopy_common(&args);
2065}
2066#endif /* CONFIG_TASN1 */
2067#endif /* CONFIG_GNUTLS */
2068
2069/*
2070 * This test does:
2071 *  source               target
2072 *                       migrate_incoming
2073 *     migrate
2074 *     migrate_cancel
2075 *                       launch another target
2076 *     migrate
2077 *
2078 *  And see that it works
2079 */
2080static void test_multifd_tcp_cancel(void)
2081{
2082    MigrateStart args = {
2083        .hide_stderr = true,
2084    };
2085    QTestState *from, *to, *to2;
2086    QDict *rsp;
2087    g_autofree char *uri = NULL;
2088
2089    if (test_migrate_start(&from, &to, "defer", &args)) {
2090        return;
2091    }
2092
2093    migrate_ensure_non_converge(from);
2094
2095    migrate_set_parameter_int(from, "multifd-channels", 16);
2096    migrate_set_parameter_int(to, "multifd-channels", 16);
2097
2098    migrate_set_capability(from, "multifd", true);
2099    migrate_set_capability(to, "multifd", true);
2100
2101    /* Start incoming migration from the 1st socket */
2102    rsp = wait_command(to, "{ 'execute': 'migrate-incoming',"
2103                           "  'arguments': { 'uri': 'tcp:127.0.0.1:0' }}");
2104    qobject_unref(rsp);
2105
2106    /* Wait for the first serial output from the source */
2107    wait_for_serial("src_serial");
2108
2109    uri = migrate_get_socket_address(to, "socket-address");
2110
2111    migrate_qmp(from, uri, "{}");
2112
2113    wait_for_migration_pass(from);
2114
2115    migrate_cancel(from);
2116
2117    args = (MigrateStart){
2118        .only_target = true,
2119    };
2120
2121    if (test_migrate_start(&from, &to2, "defer", &args)) {
2122        return;
2123    }
2124
2125    migrate_set_parameter_int(to2, "multifd-channels", 16);
2126
2127    migrate_set_capability(to2, "multifd", true);
2128
2129    /* Start incoming migration from the 1st socket */
2130    rsp = wait_command(to2, "{ 'execute': 'migrate-incoming',"
2131                            "  'arguments': { 'uri': 'tcp:127.0.0.1:0' }}");
2132    qobject_unref(rsp);
2133
2134    g_free(uri);
2135    uri = migrate_get_socket_address(to2, "socket-address");
2136
2137    wait_for_migration_status(from, "cancelled", NULL);
2138
2139    migrate_ensure_converge(from);
2140
2141    migrate_qmp(from, uri, "{}");
2142
2143    wait_for_migration_pass(from);
2144
2145    if (!got_stop) {
2146        qtest_qmp_eventwait(from, "STOP");
2147    }
2148    qtest_qmp_eventwait(to2, "RESUME");
2149
2150    wait_for_serial("dest_serial");
2151    wait_for_migration_complete(from);
2152    test_migrate_end(from, to2, true);
2153}
2154
2155static void calc_dirty_rate(QTestState *who, uint64_t calc_time)
2156{
2157    qobject_unref(qmp_command(who,
2158                  "{ 'execute': 'calc-dirty-rate',"
2159                  "'arguments': { "
2160                  "'calc-time': %ld,"
2161                  "'mode': 'dirty-ring' }}",
2162                  calc_time));
2163}
2164
2165static QDict *query_dirty_rate(QTestState *who)
2166{
2167    return qmp_command(who, "{ 'execute': 'query-dirty-rate' }");
2168}
2169
2170static void dirtylimit_set_all(QTestState *who, uint64_t dirtyrate)
2171{
2172    qobject_unref(qmp_command(who,
2173                  "{ 'execute': 'set-vcpu-dirty-limit',"
2174                  "'arguments': { "
2175                  "'dirty-rate': %ld } }",
2176                  dirtyrate));
2177}
2178
2179static void cancel_vcpu_dirty_limit(QTestState *who)
2180{
2181    qobject_unref(qmp_command(who,
2182                  "{ 'execute': 'cancel-vcpu-dirty-limit' }"));
2183}
2184
2185static QDict *query_vcpu_dirty_limit(QTestState *who)
2186{
2187    QDict *rsp;
2188
2189    rsp = qtest_qmp(who, "{ 'execute': 'query-vcpu-dirty-limit' }");
2190    g_assert(!qdict_haskey(rsp, "error"));
2191    g_assert(qdict_haskey(rsp, "return"));
2192
2193    return rsp;
2194}
2195
2196static bool calc_dirtyrate_ready(QTestState *who)
2197{
2198    QDict *rsp_return;
2199    gchar *status;
2200
2201    rsp_return = query_dirty_rate(who);
2202    g_assert(rsp_return);
2203
2204    status = g_strdup(qdict_get_str(rsp_return, "status"));
2205    g_assert(status);
2206
2207    return g_strcmp0(status, "measuring");
2208}
2209
2210static void wait_for_calc_dirtyrate_complete(QTestState *who,
2211                                             int64_t time_s)
2212{
2213    int max_try_count = 10000;
2214    usleep(time_s * 1000000);
2215
2216    while (!calc_dirtyrate_ready(who) && max_try_count--) {
2217        usleep(1000);
2218    }
2219
2220    /*
2221     * Set the timeout with 10 s(max_try_count * 1000us),
2222     * if dirtyrate measurement not complete, fail test.
2223     */
2224    g_assert_cmpint(max_try_count, !=, 0);
2225}
2226
2227static int64_t get_dirty_rate(QTestState *who)
2228{
2229    QDict *rsp_return;
2230    gchar *status;
2231    QList *rates;
2232    const QListEntry *entry;
2233    QDict *rate;
2234    int64_t dirtyrate;
2235
2236    rsp_return = query_dirty_rate(who);
2237    g_assert(rsp_return);
2238
2239    status = g_strdup(qdict_get_str(rsp_return, "status"));
2240    g_assert(status);
2241    g_assert_cmpstr(status, ==, "measured");
2242
2243    rates = qdict_get_qlist(rsp_return, "vcpu-dirty-rate");
2244    g_assert(rates && !qlist_empty(rates));
2245
2246    entry = qlist_first(rates);
2247    g_assert(entry);
2248
2249    rate = qobject_to(QDict, qlist_entry_obj(entry));
2250    g_assert(rate);
2251
2252    dirtyrate = qdict_get_try_int(rate, "dirty-rate", -1);
2253
2254    qobject_unref(rsp_return);
2255    return dirtyrate;
2256}
2257
2258static int64_t get_limit_rate(QTestState *who)
2259{
2260    QDict *rsp_return;
2261    QList *rates;
2262    const QListEntry *entry;
2263    QDict *rate;
2264    int64_t dirtyrate;
2265
2266    rsp_return = query_vcpu_dirty_limit(who);
2267    g_assert(rsp_return);
2268
2269    rates = qdict_get_qlist(rsp_return, "return");
2270    g_assert(rates && !qlist_empty(rates));
2271
2272    entry = qlist_first(rates);
2273    g_assert(entry);
2274
2275    rate = qobject_to(QDict, qlist_entry_obj(entry));
2276    g_assert(rate);
2277
2278    dirtyrate = qdict_get_try_int(rate, "limit-rate", -1);
2279
2280    qobject_unref(rsp_return);
2281    return dirtyrate;
2282}
2283
2284static QTestState *dirtylimit_start_vm(void)
2285{
2286    QTestState *vm = NULL;
2287    g_autofree gchar *cmd = NULL;
2288    const char *arch = qtest_get_arch();
2289    g_autofree char *bootpath = NULL;
2290
2291    assert((strcmp(arch, "x86_64") == 0));
2292    bootpath = g_strdup_printf("%s/bootsect", tmpfs);
2293    assert(sizeof(x86_bootsect) == 512);
2294    init_bootfile(bootpath, x86_bootsect, sizeof(x86_bootsect));
2295
2296    cmd = g_strdup_printf("-accel kvm,dirty-ring-size=4096 "
2297                          "-name dirtylimit-test,debug-threads=on "
2298                          "-m 150M -smp 1 "
2299                          "-serial file:%s/vm_serial "
2300                          "-drive file=%s,format=raw ",
2301                          tmpfs, bootpath);
2302
2303    vm = qtest_init(cmd);
2304    return vm;
2305}
2306
2307static void dirtylimit_stop_vm(QTestState *vm)
2308{
2309    qtest_quit(vm);
2310    cleanup("bootsect");
2311    cleanup("vm_serial");
2312}
2313
2314static void test_vcpu_dirty_limit(void)
2315{
2316    QTestState *vm;
2317    int64_t origin_rate;
2318    int64_t quota_rate;
2319    int64_t rate ;
2320    int max_try_count = 20;
2321    int hit = 0;
2322
2323    /* Start vm for vcpu dirtylimit test */
2324    vm = dirtylimit_start_vm();
2325
2326    /* Wait for the first serial output from the vm*/
2327    wait_for_serial("vm_serial");
2328
2329    /* Do dirtyrate measurement with calc time equals 1s */
2330    calc_dirty_rate(vm, 1);
2331
2332    /* Sleep calc time and wait for calc dirtyrate complete */
2333    wait_for_calc_dirtyrate_complete(vm, 1);
2334
2335    /* Query original dirty page rate */
2336    origin_rate = get_dirty_rate(vm);
2337
2338    /* VM booted from bootsect should dirty memory steadily */
2339    assert(origin_rate != 0);
2340
2341    /* Setup quota dirty page rate at half of origin */
2342    quota_rate = origin_rate / 2;
2343
2344    /* Set dirtylimit */
2345    dirtylimit_set_all(vm, quota_rate);
2346
2347    /*
2348     * Check if set-vcpu-dirty-limit and query-vcpu-dirty-limit
2349     * works literally
2350     */
2351    g_assert_cmpint(quota_rate, ==, get_limit_rate(vm));
2352
2353    /* Sleep a bit to check if it take effect */
2354    usleep(2000000);
2355
2356    /*
2357     * Check if dirtylimit take effect realistically, set the
2358     * timeout with 20 s(max_try_count * 1s), if dirtylimit
2359     * doesn't take effect, fail test.
2360     */
2361    while (--max_try_count) {
2362        calc_dirty_rate(vm, 1);
2363        wait_for_calc_dirtyrate_complete(vm, 1);
2364        rate = get_dirty_rate(vm);
2365
2366        /*
2367         * Assume hitting if current rate is less
2368         * than quota rate (within accepting error)
2369         */
2370        if (rate < (quota_rate + DIRTYLIMIT_TOLERANCE_RANGE)) {
2371            hit = 1;
2372            break;
2373        }
2374    }
2375
2376    g_assert_cmpint(hit, ==, 1);
2377
2378    hit = 0;
2379    max_try_count = 20;
2380
2381    /* Check if dirtylimit cancellation take effect */
2382    cancel_vcpu_dirty_limit(vm);
2383    while (--max_try_count) {
2384        calc_dirty_rate(vm, 1);
2385        wait_for_calc_dirtyrate_complete(vm, 1);
2386        rate = get_dirty_rate(vm);
2387
2388        /*
2389         * Assume dirtylimit be canceled if current rate is
2390         * greater than quota rate (within accepting error)
2391         */
2392        if (rate > (quota_rate + DIRTYLIMIT_TOLERANCE_RANGE)) {
2393            hit = 1;
2394            break;
2395        }
2396    }
2397
2398    g_assert_cmpint(hit, ==, 1);
2399    dirtylimit_stop_vm(vm);
2400}
2401
2402static bool kvm_dirty_ring_supported(void)
2403{
2404#if defined(__linux__) && defined(HOST_X86_64)
2405    int ret, kvm_fd = open("/dev/kvm", O_RDONLY);
2406
2407    if (kvm_fd < 0) {
2408        return false;
2409    }
2410
2411    ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, KVM_CAP_DIRTY_LOG_RING);
2412    close(kvm_fd);
2413
2414    /* We test with 4096 slots */
2415    if (ret < 4096) {
2416        return false;
2417    }
2418
2419    return true;
2420#else
2421    return false;
2422#endif
2423}
2424
2425int main(int argc, char **argv)
2426{
2427    char template[] = "/tmp/migration-test-XXXXXX";
2428    const bool has_kvm = qtest_has_accel("kvm");
2429    const bool has_uffd = ufd_version_check();
2430    const char *arch = qtest_get_arch();
2431    int ret;
2432
2433    g_test_init(&argc, &argv, NULL);
2434
2435    /*
2436     * On ppc64, the test only works with kvm-hv, but not with kvm-pr and TCG
2437     * is touchy due to race conditions on dirty bits (especially on PPC for
2438     * some reason)
2439     */
2440    if (g_str_equal(arch, "ppc64") &&
2441        (!has_kvm || access("/sys/module/kvm_hv", F_OK))) {
2442        g_test_message("Skipping test: kvm_hv not available");
2443        return g_test_run();
2444    }
2445
2446    /*
2447     * Similar to ppc64, s390x seems to be touchy with TCG, so disable it
2448     * there until the problems are resolved
2449     */
2450    if (g_str_equal(arch, "s390x") && !has_kvm) {
2451        g_test_message("Skipping test: s390x host with KVM is required");
2452        return g_test_run();
2453    }
2454
2455    tmpfs = mkdtemp(template);
2456    if (!tmpfs) {
2457        g_test_message("mkdtemp on path (%s): %s", template, strerror(errno));
2458    }
2459    g_assert(tmpfs);
2460
2461    module_call_init(MODULE_INIT_QOM);
2462
2463    if (has_uffd) {
2464        qtest_add_func("/migration/postcopy/plain", test_postcopy);
2465        qtest_add_func("/migration/postcopy/recovery/plain",
2466                       test_postcopy_recovery);
2467        qtest_add_func("/migration/postcopy/preempt/plain", test_postcopy_preempt);
2468        qtest_add_func("/migration/postcopy/preempt/recovery/plain",
2469                       test_postcopy_preempt_recovery);
2470    }
2471
2472    qtest_add_func("/migration/bad_dest", test_baddest);
2473    qtest_add_func("/migration/precopy/unix/plain", test_precopy_unix_plain);
2474    qtest_add_func("/migration/precopy/unix/xbzrle", test_precopy_unix_xbzrle);
2475#ifdef CONFIG_GNUTLS
2476    qtest_add_func("/migration/precopy/unix/tls/psk",
2477                   test_precopy_unix_tls_psk);
2478
2479    if (has_uffd) {
2480        /*
2481         * NOTE: psk test is enough for postcopy, as other types of TLS
2482         * channels are tested under precopy.  Here what we want to test is the
2483         * general postcopy path that has TLS channel enabled.
2484         */
2485        qtest_add_func("/migration/postcopy/tls/psk", test_postcopy_tls_psk);
2486        qtest_add_func("/migration/postcopy/recovery/tls/psk",
2487                       test_postcopy_recovery_tls_psk);
2488        qtest_add_func("/migration/postcopy/preempt/tls/psk",
2489                       test_postcopy_preempt_tls_psk);
2490        qtest_add_func("/migration/postcopy/preempt/recovery/tls/psk",
2491                       test_postcopy_preempt_all);
2492    }
2493#ifdef CONFIG_TASN1
2494    qtest_add_func("/migration/precopy/unix/tls/x509/default-host",
2495                   test_precopy_unix_tls_x509_default_host);
2496    qtest_add_func("/migration/precopy/unix/tls/x509/override-host",
2497                   test_precopy_unix_tls_x509_override_host);
2498#endif /* CONFIG_TASN1 */
2499#endif /* CONFIG_GNUTLS */
2500
2501    qtest_add_func("/migration/precopy/tcp/plain", test_precopy_tcp_plain);
2502#ifdef CONFIG_GNUTLS
2503    qtest_add_func("/migration/precopy/tcp/tls/psk/match",
2504                   test_precopy_tcp_tls_psk_match);
2505    qtest_add_func("/migration/precopy/tcp/tls/psk/mismatch",
2506                   test_precopy_tcp_tls_psk_mismatch);
2507#ifdef CONFIG_TASN1
2508    qtest_add_func("/migration/precopy/tcp/tls/x509/default-host",
2509                   test_precopy_tcp_tls_x509_default_host);
2510    qtest_add_func("/migration/precopy/tcp/tls/x509/override-host",
2511                   test_precopy_tcp_tls_x509_override_host);
2512    qtest_add_func("/migration/precopy/tcp/tls/x509/mismatch-host",
2513                   test_precopy_tcp_tls_x509_mismatch_host);
2514    qtest_add_func("/migration/precopy/tcp/tls/x509/friendly-client",
2515                   test_precopy_tcp_tls_x509_friendly_client);
2516    qtest_add_func("/migration/precopy/tcp/tls/x509/hostile-client",
2517                   test_precopy_tcp_tls_x509_hostile_client);
2518    qtest_add_func("/migration/precopy/tcp/tls/x509/allow-anon-client",
2519                   test_precopy_tcp_tls_x509_allow_anon_client);
2520    qtest_add_func("/migration/precopy/tcp/tls/x509/reject-anon-client",
2521                   test_precopy_tcp_tls_x509_reject_anon_client);
2522#endif /* CONFIG_TASN1 */
2523#endif /* CONFIG_GNUTLS */
2524
2525    /* qtest_add_func("/migration/ignore_shared", test_ignore_shared); */
2526    qtest_add_func("/migration/fd_proto", test_migrate_fd_proto);
2527    qtest_add_func("/migration/validate_uuid", test_validate_uuid);
2528    qtest_add_func("/migration/validate_uuid_error", test_validate_uuid_error);
2529    qtest_add_func("/migration/validate_uuid_src_not_set",
2530                   test_validate_uuid_src_not_set);
2531    qtest_add_func("/migration/validate_uuid_dst_not_set",
2532                   test_validate_uuid_dst_not_set);
2533
2534    qtest_add_func("/migration/auto_converge", test_migrate_auto_converge);
2535    qtest_add_func("/migration/multifd/tcp/plain/none",
2536                   test_multifd_tcp_none);
2537    qtest_add_func("/migration/multifd/tcp/plain/cancel",
2538                   test_multifd_tcp_cancel);
2539    qtest_add_func("/migration/multifd/tcp/plain/zlib",
2540                   test_multifd_tcp_zlib);
2541#ifdef CONFIG_ZSTD
2542    qtest_add_func("/migration/multifd/tcp/plain/zstd",
2543                   test_multifd_tcp_zstd);
2544#endif
2545#ifdef CONFIG_GNUTLS
2546    qtest_add_func("/migration/multifd/tcp/tls/psk/match",
2547                   test_multifd_tcp_tls_psk_match);
2548    qtest_add_func("/migration/multifd/tcp/tls/psk/mismatch",
2549                   test_multifd_tcp_tls_psk_mismatch);
2550#ifdef CONFIG_TASN1
2551    qtest_add_func("/migration/multifd/tcp/tls/x509/default-host",
2552                   test_multifd_tcp_tls_x509_default_host);
2553    qtest_add_func("/migration/multifd/tcp/tls/x509/override-host",
2554                   test_multifd_tcp_tls_x509_override_host);
2555    qtest_add_func("/migration/multifd/tcp/tls/x509/mismatch-host",
2556                   test_multifd_tcp_tls_x509_mismatch_host);
2557    qtest_add_func("/migration/multifd/tcp/tls/x509/allow-anon-client",
2558                   test_multifd_tcp_tls_x509_allow_anon_client);
2559    qtest_add_func("/migration/multifd/tcp/tls/x509/reject-anon-client",
2560                   test_multifd_tcp_tls_x509_reject_anon_client);
2561#endif /* CONFIG_TASN1 */
2562#endif /* CONFIG_GNUTLS */
2563
2564    if (g_str_equal(arch, "x86_64") && has_kvm && kvm_dirty_ring_supported()) {
2565        qtest_add_func("/migration/dirty_ring",
2566                       test_precopy_unix_dirty_ring);
2567        qtest_add_func("/migration/vcpu_dirty_limit",
2568                       test_vcpu_dirty_limit);
2569    }
2570
2571    ret = g_test_run();
2572
2573    g_assert_cmpint(ret, ==, 0);
2574
2575    ret = rmdir(tmpfs);
2576    if (ret != 0) {
2577        g_test_message("unable to rmdir: path (%s): %s",
2578                       tmpfs, strerror(errno));
2579    }
2580
2581    return ret;
2582}
2583