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