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