Merge remote-tracking branch 'qemu-project/master'
[qemu/ar7.git] / tests / qtest / migration-test.c
blob70b606b888642a909ee292cf18ee9251789c1f85
1 /*
2 * QTest testcase for migration
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.
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.
13 #include "qemu/osdep.h"
15 #include "libqtest.h"
16 #include "qapi/qmp/qdict.h"
17 #include "qemu/module.h"
18 #include "qemu/option.h"
19 #include "qemu/range.h"
20 #include "qemu/sockets.h"
21 #include "chardev/char.h"
22 #include "crypto/tlscredspsk.h"
23 #include "qapi/qmp/qlist.h"
24 #include "ppc-util.h"
26 #include "migration-helpers.h"
27 #include "tests/migration/migration-test.h"
28 #ifdef CONFIG_GNUTLS
29 # include "tests/unit/crypto-tls-psk-helpers.h"
30 # ifdef CONFIG_TASN1
31 # include "tests/unit/crypto-tls-x509-helpers.h"
32 # endif /* CONFIG_TASN1 */
33 #endif /* CONFIG_GNUTLS */
35 /* For dirty ring test; so far only x86_64 is supported */
36 #if defined(__linux__) && defined(HOST_X86_64)
37 #include "linux/kvm.h"
38 #endif
40 unsigned start_address;
41 unsigned end_address;
42 static bool uffd_feature_thread_id;
43 static QTestMigrationState src_state;
44 static QTestMigrationState dst_state;
47 * An initial 3 MB offset is used as that corresponds
48 * to ~1 sec of data transfer with our bandwidth setting.
50 #define MAGIC_OFFSET_BASE (3 * 1024 * 1024)
52 * A further 1k is added to ensure we're not a multiple
53 * of TEST_MEM_PAGE_SIZE, thus avoid clash with writes
54 * from the migration guest workload.
56 #define MAGIC_OFFSET_SHUFFLE 1024
57 #define MAGIC_OFFSET (MAGIC_OFFSET_BASE + MAGIC_OFFSET_SHUFFLE)
58 #define MAGIC_MARKER 0xFEED12345678CAFEULL
61 * Dirtylimit stop working if dirty page rate error
62 * value less than DIRTYLIMIT_TOLERANCE_RANGE
64 #define DIRTYLIMIT_TOLERANCE_RANGE 25 /* MB/s */
66 #define ANALYZE_SCRIPT "scripts/analyze-migration.py"
67 #define VMSTATE_CHECKER_SCRIPT "scripts/vmstate-static-checker.py"
69 #define QEMU_VM_FILE_MAGIC 0x5145564d
70 #define FILE_TEST_FILENAME "migfile"
71 #define FILE_TEST_OFFSET 0x1000
72 #define FILE_TEST_MARKER 'X'
73 #define QEMU_ENV_SRC "QTEST_QEMU_BINARY_SRC"
74 #define QEMU_ENV_DST "QTEST_QEMU_BINARY_DST"
76 typedef enum PostcopyRecoveryFailStage {
78 * "no failure" must be 0 as it's the default. OTOH, real failure
79 * cases must be >0 to make sure they trigger by a "if" test.
81 POSTCOPY_FAIL_NONE = 0,
82 POSTCOPY_FAIL_CHANNEL_ESTABLISH,
83 POSTCOPY_FAIL_RECOVERY,
84 POSTCOPY_FAIL_MAX
85 } PostcopyRecoveryFailStage;
87 #if defined(__linux__)
88 #include <sys/syscall.h>
89 #include <sys/vfs.h>
90 #endif
92 #if defined(__linux__) && defined(__NR_userfaultfd) && defined(CONFIG_EVENTFD)
93 #include <sys/eventfd.h>
94 #include <sys/ioctl.h>
95 #include "qemu/userfaultfd.h"
97 static bool ufd_version_check(void)
99 struct uffdio_api api_struct;
100 uint64_t ioctl_mask;
102 int ufd = uffd_open(O_CLOEXEC);
104 if (ufd == -1) {
105 g_test_message("Skipping test: userfaultfd not available");
106 return false;
109 api_struct.api = UFFD_API;
110 api_struct.features = 0;
111 if (ioctl(ufd, UFFDIO_API, &api_struct)) {
112 g_test_message("Skipping test: UFFDIO_API failed");
113 return false;
115 uffd_feature_thread_id = api_struct.features & UFFD_FEATURE_THREAD_ID;
117 ioctl_mask = 1ULL << _UFFDIO_REGISTER |
118 1ULL << _UFFDIO_UNREGISTER;
119 if ((api_struct.ioctls & ioctl_mask) != ioctl_mask) {
120 g_test_message("Skipping test: Missing userfault feature");
121 return false;
124 return true;
127 #else
128 static bool ufd_version_check(void)
130 g_test_message("Skipping test: Userfault not available (builtdtime)");
131 return false;
134 #endif
136 static char *tmpfs;
137 static char *bootpath;
139 /* The boot file modifies memory area in [start_address, end_address)
140 * repeatedly. It outputs a 'B' at a fixed rate while it's still running.
142 #include "tests/migration/i386/a-b-bootblock.h"
143 #include "tests/migration/aarch64/a-b-kernel.h"
144 #include "tests/migration/ppc64/a-b-kernel.h"
145 #include "tests/migration/s390x/a-b-bios.h"
147 static void bootfile_create(char *dir, bool suspend_me)
149 const char *arch = qtest_get_arch();
150 unsigned char *content;
151 size_t len;
153 bootpath = g_strdup_printf("%s/bootsect", dir);
154 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
155 /* the assembled x86 boot sector should be exactly one sector large */
156 g_assert(sizeof(x86_bootsect) == 512);
157 x86_bootsect[SYM_suspend_me - SYM_start] = suspend_me;
158 content = x86_bootsect;
159 len = sizeof(x86_bootsect);
160 } else if (g_str_equal(arch, "s390x")) {
161 content = s390x_elf;
162 len = sizeof(s390x_elf);
163 } else if (strcmp(arch, "ppc64") == 0) {
164 content = ppc64_kernel;
165 len = sizeof(ppc64_kernel);
166 } else if (strcmp(arch, "aarch64") == 0) {
167 content = aarch64_kernel;
168 len = sizeof(aarch64_kernel);
169 g_assert(sizeof(aarch64_kernel) <= ARM_TEST_MAX_KERNEL_SIZE);
170 } else {
171 g_assert_not_reached();
174 FILE *bootfile = fopen(bootpath, "wb");
176 g_assert_cmpint(fwrite(content, len, 1, bootfile), ==, 1);
177 fclose(bootfile);
180 static void bootfile_delete(void)
182 unlink(bootpath);
183 g_free(bootpath);
184 bootpath = NULL;
188 * Wait for some output in the serial output file,
189 * we get an 'A' followed by an endless string of 'B's
190 * but on the destination we won't have the A (unless we enabled suspend/resume)
192 static void wait_for_serial(const char *side)
194 g_autofree char *serialpath = g_strdup_printf("%s/%s", tmpfs, side);
195 FILE *serialfile = fopen(serialpath, "r");
197 do {
198 int readvalue = fgetc(serialfile);
200 switch (readvalue) {
201 case 'A':
202 /* Fine */
203 break;
205 case 'B':
206 /* It's alive! */
207 fclose(serialfile);
208 return;
210 case EOF:
211 fseek(serialfile, 0, SEEK_SET);
212 usleep(1000);
213 break;
215 default:
216 fprintf(stderr, "Unexpected %d on %s serial\n", readvalue, side);
217 g_assert_not_reached();
219 } while (true);
222 static void wait_for_stop(QTestState *who, QTestMigrationState *state)
224 if (!state->stop_seen) {
225 qtest_qmp_eventwait(who, "STOP");
229 static void wait_for_resume(QTestState *who, QTestMigrationState *state)
231 if (!state->resume_seen) {
232 qtest_qmp_eventwait(who, "RESUME");
236 static void wait_for_suspend(QTestState *who, QTestMigrationState *state)
238 if (state->suspend_me && !state->suspend_seen) {
239 qtest_qmp_eventwait(who, "SUSPEND");
244 * It's tricky to use qemu's migration event capability with qtest,
245 * events suddenly appearing confuse the qmp()/hmp() responses.
248 static int64_t read_ram_property_int(QTestState *who, const char *property)
250 QDict *rsp_return, *rsp_ram;
251 int64_t result;
253 rsp_return = migrate_query_not_failed(who);
254 if (!qdict_haskey(rsp_return, "ram")) {
255 /* Still in setup */
256 result = 0;
257 } else {
258 rsp_ram = qdict_get_qdict(rsp_return, "ram");
259 result = qdict_get_try_int(rsp_ram, property, 0);
261 qobject_unref(rsp_return);
262 return result;
265 static int64_t read_migrate_property_int(QTestState *who, const char *property)
267 QDict *rsp_return;
268 int64_t result;
270 rsp_return = migrate_query_not_failed(who);
271 result = qdict_get_try_int(rsp_return, property, 0);
272 qobject_unref(rsp_return);
273 return result;
276 static uint64_t get_migration_pass(QTestState *who)
278 return read_ram_property_int(who, "dirty-sync-count");
281 static void read_blocktime(QTestState *who)
283 QDict *rsp_return;
285 rsp_return = migrate_query_not_failed(who);
286 g_assert(qdict_haskey(rsp_return, "postcopy-blocktime"));
287 qobject_unref(rsp_return);
291 * Wait for two changes in the migration pass count, but bail if we stop.
293 static void wait_for_migration_pass(QTestState *who)
295 uint64_t pass, prev_pass = 0, changes = 0;
297 while (changes < 2 && !src_state.stop_seen && !src_state.suspend_seen) {
298 usleep(1000);
299 pass = get_migration_pass(who);
300 changes += (pass != prev_pass);
301 prev_pass = pass;
305 static void check_guests_ram(QTestState *who)
307 /* Our ASM test will have been incrementing one byte from each page from
308 * start_address to < end_address in order. This gives us a constraint
309 * that any page's byte should be equal or less than the previous pages
310 * byte (mod 256); and they should all be equal except for one transition
311 * at the point where we meet the incrementer. (We're running this with
312 * the guest stopped).
314 unsigned address;
315 uint8_t first_byte;
316 uint8_t last_byte;
317 bool hit_edge = false;
318 int bad = 0;
320 qtest_memread(who, start_address, &first_byte, 1);
321 last_byte = first_byte;
323 for (address = start_address + TEST_MEM_PAGE_SIZE; address < end_address;
324 address += TEST_MEM_PAGE_SIZE)
326 uint8_t b;
327 qtest_memread(who, address, &b, 1);
328 if (b != last_byte) {
329 if (((b + 1) % 256) == last_byte && !hit_edge) {
330 /* This is OK, the guest stopped at the point of
331 * incrementing the previous page but didn't get
332 * to us yet.
334 hit_edge = true;
335 last_byte = b;
336 } else {
337 bad++;
338 if (bad <= 10) {
339 fprintf(stderr, "Memory content inconsistency at %x"
340 " first_byte = %x last_byte = %x current = %x"
341 " hit_edge = %x\n",
342 address, first_byte, last_byte, b, hit_edge);
347 if (bad >= 10) {
348 fprintf(stderr, "and in another %d pages", bad - 10);
350 g_assert(bad == 0);
353 static void cleanup(const char *filename)
355 g_autofree char *path = g_strdup_printf("%s/%s", tmpfs, filename);
357 unlink(path);
360 static long long migrate_get_parameter_int(QTestState *who,
361 const char *parameter)
363 QDict *rsp;
364 long long result;
366 rsp = qtest_qmp_assert_success_ref(
367 who, "{ 'execute': 'query-migrate-parameters' }");
368 result = qdict_get_int(rsp, parameter);
369 qobject_unref(rsp);
370 return result;
373 static void migrate_check_parameter_int(QTestState *who, const char *parameter,
374 long long value)
376 long long result;
378 result = migrate_get_parameter_int(who, parameter);
379 g_assert_cmpint(result, ==, value);
382 static void migrate_set_parameter_int(QTestState *who, const char *parameter,
383 long long value)
385 qtest_qmp_assert_success(who,
386 "{ 'execute': 'migrate-set-parameters',"
387 "'arguments': { %s: %lld } }",
388 parameter, value);
389 migrate_check_parameter_int(who, parameter, value);
392 static char *migrate_get_parameter_str(QTestState *who,
393 const char *parameter)
395 QDict *rsp;
396 char *result;
398 rsp = qtest_qmp_assert_success_ref(
399 who, "{ 'execute': 'query-migrate-parameters' }");
400 result = g_strdup(qdict_get_str(rsp, parameter));
401 qobject_unref(rsp);
402 return result;
405 static void migrate_check_parameter_str(QTestState *who, const char *parameter,
406 const char *value)
408 g_autofree char *result = migrate_get_parameter_str(who, parameter);
409 g_assert_cmpstr(result, ==, value);
412 static void migrate_set_parameter_str(QTestState *who, const char *parameter,
413 const char *value)
415 qtest_qmp_assert_success(who,
416 "{ 'execute': 'migrate-set-parameters',"
417 "'arguments': { %s: %s } }",
418 parameter, value);
419 migrate_check_parameter_str(who, parameter, value);
422 static long long migrate_get_parameter_bool(QTestState *who,
423 const char *parameter)
425 QDict *rsp;
426 int result;
428 rsp = qtest_qmp_assert_success_ref(
429 who, "{ 'execute': 'query-migrate-parameters' }");
430 result = qdict_get_bool(rsp, parameter);
431 qobject_unref(rsp);
432 return !!result;
435 static void migrate_check_parameter_bool(QTestState *who, const char *parameter,
436 int value)
438 int result;
440 result = migrate_get_parameter_bool(who, parameter);
441 g_assert_cmpint(result, ==, value);
444 static void migrate_set_parameter_bool(QTestState *who, const char *parameter,
445 int value)
447 qtest_qmp_assert_success(who,
448 "{ 'execute': 'migrate-set-parameters',"
449 "'arguments': { %s: %i } }",
450 parameter, value);
451 migrate_check_parameter_bool(who, parameter, value);
454 static void migrate_ensure_non_converge(QTestState *who)
456 /* Can't converge with 1ms downtime + 3 mbs bandwidth limit */
457 migrate_set_parameter_int(who, "max-bandwidth", 3 * 1000 * 1000);
458 migrate_set_parameter_int(who, "downtime-limit", 1);
461 static void migrate_ensure_converge(QTestState *who)
463 /* Should converge with 30s downtime + 1 gbs bandwidth limit */
464 migrate_set_parameter_int(who, "max-bandwidth", 1 * 1000 * 1000 * 1000);
465 migrate_set_parameter_int(who, "downtime-limit", 30 * 1000);
469 * Our goal is to ensure that we run a single full migration
470 * iteration, and also dirty memory, ensuring that at least
471 * one further iteration is required.
473 * We can't directly synchronize with the start of a migration
474 * so we have to apply some tricks monitoring memory that is
475 * transferred.
477 * Initially we set the migration bandwidth to an insanely
478 * low value, with tiny max downtime too. This basically
479 * guarantees migration will never complete.
481 * This will result in a test that is unacceptably slow though,
482 * so we can't let the entire migration pass run at this speed.
483 * Our intent is to let it run just long enough that we can
484 * prove data prior to the marker has been transferred *AND*
485 * also prove this transferred data is dirty again.
487 * Before migration starts, we write a 64-bit magic marker
488 * into a fixed location in the src VM RAM.
490 * Then watch dst memory until the marker appears. This is
491 * proof that start_address -> MAGIC_OFFSET_BASE has been
492 * transferred.
494 * Finally we go back to the source and read a byte just
495 * before the marker until we see it flip in value. This
496 * is proof that start_address -> MAGIC_OFFSET_BASE
497 * is now dirty again.
499 * IOW, we're guaranteed at least a 2nd migration pass
500 * at this point.
502 * We can now let migration run at full speed to finish
503 * the test
505 static void migrate_prepare_for_dirty_mem(QTestState *from)
508 * The guest workflow iterates from start_address to
509 * end_address, writing 1 byte every TEST_MEM_PAGE_SIZE
510 * bytes.
512 * IOW, if we write to mem at a point which is NOT
513 * a multiple of TEST_MEM_PAGE_SIZE, our write won't
514 * conflict with the migration workflow.
516 * We put in a marker here, that we'll use to determine
517 * when the data has been transferred to the dst.
519 qtest_writeq(from, start_address + MAGIC_OFFSET, MAGIC_MARKER);
522 static void migrate_wait_for_dirty_mem(QTestState *from,
523 QTestState *to)
525 uint64_t watch_address = start_address + MAGIC_OFFSET_BASE;
526 uint64_t marker_address = start_address + MAGIC_OFFSET;
527 uint8_t watch_byte;
530 * Wait for the MAGIC_MARKER to get transferred, as an
531 * indicator that a migration pass has made some known
532 * amount of progress.
534 do {
535 usleep(1000 * 10);
536 } while (qtest_readq(to, marker_address) != MAGIC_MARKER);
539 /* If suspended, src only iterates once, and watch_byte may never change */
540 if (src_state.suspend_me) {
541 return;
545 * Now ensure that already transferred bytes are
546 * dirty again from the guest workload. Note the
547 * guest byte value will wrap around and by chance
548 * match the original watch_byte. This is harmless
549 * as we'll eventually see a different value if we
550 * keep watching
552 watch_byte = qtest_readb(from, watch_address);
553 do {
554 usleep(1000 * 10);
555 } while (qtest_readb(from, watch_address) == watch_byte);
559 static void migrate_pause(QTestState *who)
561 qtest_qmp_assert_success(who, "{ 'execute': 'migrate-pause' }");
564 static void migrate_continue(QTestState *who, const char *state)
566 qtest_qmp_assert_success(who,
567 "{ 'execute': 'migrate-continue',"
568 " 'arguments': { 'state': %s } }",
569 state);
572 static void migrate_recover(QTestState *who, const char *uri)
574 qtest_qmp_assert_success(who,
575 "{ 'execute': 'migrate-recover', "
576 " 'id': 'recover-cmd', "
577 " 'arguments': { 'uri': %s } }",
578 uri);
581 static void migrate_cancel(QTestState *who)
583 qtest_qmp_assert_success(who, "{ 'execute': 'migrate_cancel' }");
586 static void migrate_postcopy_start(QTestState *from, QTestState *to)
588 qtest_qmp_assert_success(from, "{ 'execute': 'migrate-start-postcopy' }");
590 wait_for_stop(from, &src_state);
591 qtest_qmp_eventwait(to, "RESUME");
594 typedef struct {
596 * QTEST_LOG=1 may override this. When QTEST_LOG=1, we always dump errors
597 * unconditionally, because it means the user would like to be verbose.
599 bool hide_stderr;
600 bool use_shmem;
601 /* only launch the target process */
602 bool only_target;
603 /* Use dirty ring if true; dirty logging otherwise */
604 bool use_dirty_ring;
605 const char *opts_source;
606 const char *opts_target;
607 /* suspend the src before migrating to dest. */
608 bool suspend_me;
609 } MigrateStart;
612 * A hook that runs after the src and dst QEMUs have been
613 * created, but before the migration is started. This can
614 * be used to set migration parameters and capabilities.
616 * Returns: NULL, or a pointer to opaque state to be
617 * later passed to the TestMigrateFinishHook
619 typedef void * (*TestMigrateStartHook)(QTestState *from,
620 QTestState *to);
623 * A hook that runs after the migration has finished,
624 * regardless of whether it succeeded or failed, but
625 * before QEMU has terminated (unless it self-terminated
626 * due to migration error)
628 * @opaque is a pointer to state previously returned
629 * by the TestMigrateStartHook if any, or NULL.
631 typedef void (*TestMigrateFinishHook)(QTestState *from,
632 QTestState *to,
633 void *opaque);
635 typedef struct {
636 /* Optional: fine tune start parameters */
637 MigrateStart start;
639 /* Required: the URI for the dst QEMU to listen on */
640 const char *listen_uri;
643 * Optional: the URI for the src QEMU to connect to
644 * If NULL, then it will query the dst QEMU for its actual
645 * listening address and use that as the connect address.
646 * This allows for dynamically picking a free TCP port.
648 const char *connect_uri;
651 * Optional: JSON-formatted list of src QEMU URIs. If a port is
652 * defined as '0' in any QDict key a value of '0' will be
653 * automatically converted to the correct destination port.
655 const char *connect_channels;
657 /* Optional: callback to run at start to set migration parameters */
658 TestMigrateStartHook start_hook;
659 /* Optional: callback to run at finish to cleanup */
660 TestMigrateFinishHook finish_hook;
663 * Optional: normally we expect the migration process to complete.
665 * There can be a variety of reasons and stages in which failure
666 * can happen during tests.
668 * If a failure is expected to happen at time of establishing
669 * the connection, then MIG_TEST_FAIL will indicate that the dst
670 * QEMU is expected to stay running and accept future migration
671 * connections.
673 * If a failure is expected to happen while processing the
674 * migration stream, then MIG_TEST_FAIL_DEST_QUIT_ERR will indicate
675 * that the dst QEMU is expected to quit with non-zero exit status
677 enum {
678 /* This test should succeed, the default */
679 MIG_TEST_SUCCEED = 0,
680 /* This test should fail, dest qemu should keep alive */
681 MIG_TEST_FAIL,
682 /* This test should fail, dest qemu should fail with abnormal status */
683 MIG_TEST_FAIL_DEST_QUIT_ERR,
684 /* The QMP command for this migration should fail with an error */
685 MIG_TEST_QMP_ERROR,
686 } result;
689 * Optional: set number of migration passes to wait for, if live==true.
690 * If zero, then merely wait for a few MB of dirty data
692 unsigned int iterations;
695 * Optional: whether the guest CPUs should be running during a precopy
696 * migration test. We used to always run with live but it took much
697 * longer so we reduced live tests to only the ones that have solid
698 * reason to be tested live-only. For each of the new test cases for
699 * precopy please provide justifications to use live explicitly (please
700 * refer to existing ones with live=true), or use live=off by default.
702 bool live;
704 /* Postcopy specific fields */
705 void *postcopy_data;
706 bool postcopy_preempt;
707 PostcopyRecoveryFailStage postcopy_recovery_fail_stage;
708 } MigrateCommon;
710 static int test_migrate_start(QTestState **from, QTestState **to,
711 const char *uri, MigrateStart *args)
713 g_autofree gchar *arch_source = NULL;
714 g_autofree gchar *arch_target = NULL;
715 /* options for source and target */
716 g_autofree gchar *arch_opts = NULL;
717 g_autofree gchar *cmd_source = NULL;
718 g_autofree gchar *cmd_target = NULL;
719 const gchar *ignore_stderr;
720 g_autofree char *shmem_opts = NULL;
721 g_autofree char *shmem_path = NULL;
722 const char *kvm_opts = NULL;
723 const char *arch = qtest_get_arch();
724 const char *memory_size;
725 const char *machine_alias, *machine_opts = "";
726 g_autofree char *machine = NULL;
728 if (args->use_shmem) {
729 if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
730 g_test_skip("/dev/shm is not supported");
731 return -1;
735 dst_state = (QTestMigrationState) { };
736 src_state = (QTestMigrationState) { };
737 bootfile_create(tmpfs, args->suspend_me);
738 src_state.suspend_me = args->suspend_me;
740 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
741 memory_size = "150M";
743 if (g_str_equal(arch, "i386")) {
744 machine_alias = "pc";
745 } else {
746 machine_alias = "q35";
748 arch_opts = g_strdup_printf(
749 "-drive if=none,id=d0,file=%s,format=raw "
750 "-device ide-hd,drive=d0,secs=1,cyls=1,heads=1", bootpath);
751 start_address = X86_TEST_MEM_START;
752 end_address = X86_TEST_MEM_END;
753 } else if (g_str_equal(arch, "s390x")) {
754 memory_size = "128M";
755 machine_alias = "s390-ccw-virtio";
756 arch_opts = g_strdup_printf("-bios %s", bootpath);
757 start_address = S390_TEST_MEM_START;
758 end_address = S390_TEST_MEM_END;
759 } else if (strcmp(arch, "ppc64") == 0) {
760 memory_size = "256M";
761 start_address = PPC_TEST_MEM_START;
762 end_address = PPC_TEST_MEM_END;
763 machine_alias = "pseries";
764 machine_opts = "vsmt=8";
765 arch_opts = g_strdup_printf(
766 "-nodefaults -machine " PSERIES_DEFAULT_CAPABILITIES " "
767 "-bios %s", bootpath);
768 } else if (strcmp(arch, "aarch64") == 0) {
769 memory_size = "150M";
770 machine_alias = "virt";
771 machine_opts = "gic-version=3";
772 arch_opts = g_strdup_printf("-cpu max -kernel %s", bootpath);
773 start_address = ARM_TEST_MEM_START;
774 end_address = ARM_TEST_MEM_END;
775 } else {
776 g_assert_not_reached();
779 if (!getenv("QTEST_LOG") && args->hide_stderr) {
780 #ifndef _WIN32
781 ignore_stderr = "2>/dev/null";
782 #else
784 * On Windows the QEMU executable is created via CreateProcess() and
785 * IO redirection does not work, so don't bother adding IO redirection
786 * to the command line.
788 ignore_stderr = "";
789 #endif
790 } else {
791 ignore_stderr = "";
794 if (args->use_shmem) {
795 shmem_path = g_strdup_printf("/dev/shm/qemu-%d", getpid());
796 shmem_opts = g_strdup_printf(
797 "-object memory-backend-file,id=mem0,size=%s"
798 ",mem-path=%s,share=on -numa node,memdev=mem0",
799 memory_size, shmem_path);
802 if (args->use_dirty_ring) {
803 kvm_opts = ",dirty-ring-size=4096";
806 if (!qtest_has_machine(machine_alias)) {
807 g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
808 g_test_skip(msg);
809 return -1;
812 machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
813 QEMU_ENV_DST);
815 g_test_message("Using machine type: %s", machine);
817 cmd_source = g_strdup_printf("-accel kvm%s -accel tcg "
818 "-machine %s,%s "
819 "-name source,debug-threads=on "
820 "-m %s "
821 "-serial file:%s/src_serial "
822 "%s %s %s %s %s",
823 kvm_opts ? kvm_opts : "",
824 machine, machine_opts,
825 memory_size, tmpfs,
826 arch_opts ? arch_opts : "",
827 arch_source ? arch_source : "",
828 shmem_opts ? shmem_opts : "",
829 args->opts_source ? args->opts_source : "",
830 ignore_stderr);
831 if (!args->only_target) {
832 *from = qtest_init_with_env(QEMU_ENV_SRC, cmd_source);
833 qtest_qmp_set_event_callback(*from,
834 migrate_watch_for_events,
835 &src_state);
838 cmd_target = g_strdup_printf("-accel kvm%s -accel tcg "
839 "-machine %s,%s "
840 "-name target,debug-threads=on "
841 "-m %s "
842 "-serial file:%s/dest_serial "
843 "-incoming %s "
844 "%s %s %s %s %s",
845 kvm_opts ? kvm_opts : "",
846 machine, machine_opts,
847 memory_size, tmpfs, uri,
848 arch_opts ? arch_opts : "",
849 arch_target ? arch_target : "",
850 shmem_opts ? shmem_opts : "",
851 args->opts_target ? args->opts_target : "",
852 ignore_stderr);
853 *to = qtest_init_with_env(QEMU_ENV_DST, cmd_target);
854 qtest_qmp_set_event_callback(*to,
855 migrate_watch_for_events,
856 &dst_state);
859 * Remove shmem file immediately to avoid memory leak in test failed case.
860 * It's valid because QEMU has already opened this file
862 if (args->use_shmem) {
863 unlink(shmem_path);
867 * Always enable migration events. Libvirt always uses it, let's try
868 * to mimic as closer as that.
870 migrate_set_capability(*from, "events", true);
871 migrate_set_capability(*to, "events", true);
873 return 0;
876 static void test_migrate_end(QTestState *from, QTestState *to, bool test_dest)
878 unsigned char dest_byte_a, dest_byte_b, dest_byte_c, dest_byte_d;
880 qtest_quit(from);
882 if (test_dest) {
883 qtest_memread(to, start_address, &dest_byte_a, 1);
885 /* Destination still running, wait for a byte to change */
886 do {
887 qtest_memread(to, start_address, &dest_byte_b, 1);
888 usleep(1000 * 10);
889 } while (dest_byte_a == dest_byte_b);
891 qtest_qmp_assert_success(to, "{ 'execute' : 'stop'}");
893 /* With it stopped, check nothing changes */
894 qtest_memread(to, start_address, &dest_byte_c, 1);
895 usleep(1000 * 200);
896 qtest_memread(to, start_address, &dest_byte_d, 1);
897 g_assert_cmpint(dest_byte_c, ==, dest_byte_d);
899 check_guests_ram(to);
902 qtest_quit(to);
904 cleanup("migsocket");
905 cleanup("src_serial");
906 cleanup("dest_serial");
907 cleanup(FILE_TEST_FILENAME);
910 #ifdef CONFIG_GNUTLS
911 struct TestMigrateTLSPSKData {
912 char *workdir;
913 char *workdiralt;
914 char *pskfile;
915 char *pskfilealt;
918 static void *
919 test_migrate_tls_psk_start_common(QTestState *from,
920 QTestState *to,
921 bool mismatch)
923 struct TestMigrateTLSPSKData *data =
924 g_new0(struct TestMigrateTLSPSKData, 1);
926 data->workdir = g_strdup_printf("%s/tlscredspsk0", tmpfs);
927 data->pskfile = g_strdup_printf("%s/%s", data->workdir,
928 QCRYPTO_TLS_CREDS_PSKFILE);
929 g_mkdir_with_parents(data->workdir, 0700);
930 test_tls_psk_init(data->pskfile);
932 if (mismatch) {
933 data->workdiralt = g_strdup_printf("%s/tlscredspskalt0", tmpfs);
934 data->pskfilealt = g_strdup_printf("%s/%s", data->workdiralt,
935 QCRYPTO_TLS_CREDS_PSKFILE);
936 g_mkdir_with_parents(data->workdiralt, 0700);
937 test_tls_psk_init_alt(data->pskfilealt);
940 qtest_qmp_assert_success(from,
941 "{ 'execute': 'object-add',"
942 " 'arguments': { 'qom-type': 'tls-creds-psk',"
943 " 'id': 'tlscredspsk0',"
944 " 'endpoint': 'client',"
945 " 'dir': %s,"
946 " 'username': 'qemu'} }",
947 data->workdir);
949 qtest_qmp_assert_success(to,
950 "{ 'execute': 'object-add',"
951 " 'arguments': { 'qom-type': 'tls-creds-psk',"
952 " 'id': 'tlscredspsk0',"
953 " 'endpoint': 'server',"
954 " 'dir': %s } }",
955 mismatch ? data->workdiralt : data->workdir);
957 migrate_set_parameter_str(from, "tls-creds", "tlscredspsk0");
958 migrate_set_parameter_str(to, "tls-creds", "tlscredspsk0");
960 return data;
963 static void *
964 test_migrate_tls_psk_start_match(QTestState *from,
965 QTestState *to)
967 return test_migrate_tls_psk_start_common(from, to, false);
970 static void *
971 test_migrate_tls_psk_start_mismatch(QTestState *from,
972 QTestState *to)
974 return test_migrate_tls_psk_start_common(from, to, true);
977 static void
978 test_migrate_tls_psk_finish(QTestState *from,
979 QTestState *to,
980 void *opaque)
982 struct TestMigrateTLSPSKData *data = opaque;
984 test_tls_psk_cleanup(data->pskfile);
985 if (data->pskfilealt) {
986 test_tls_psk_cleanup(data->pskfilealt);
988 rmdir(data->workdir);
989 if (data->workdiralt) {
990 rmdir(data->workdiralt);
993 g_free(data->workdiralt);
994 g_free(data->pskfilealt);
995 g_free(data->workdir);
996 g_free(data->pskfile);
997 g_free(data);
1000 #ifdef CONFIG_TASN1
1001 typedef struct {
1002 char *workdir;
1003 char *keyfile;
1004 char *cacert;
1005 char *servercert;
1006 char *serverkey;
1007 char *clientcert;
1008 char *clientkey;
1009 } TestMigrateTLSX509Data;
1011 typedef struct {
1012 bool verifyclient;
1013 bool clientcert;
1014 bool hostileclient;
1015 bool authzclient;
1016 const char *certhostname;
1017 const char *certipaddr;
1018 } TestMigrateTLSX509;
1020 static void *
1021 test_migrate_tls_x509_start_common(QTestState *from,
1022 QTestState *to,
1023 TestMigrateTLSX509 *args)
1025 TestMigrateTLSX509Data *data = g_new0(TestMigrateTLSX509Data, 1);
1027 data->workdir = g_strdup_printf("%s/tlscredsx5090", tmpfs);
1028 data->keyfile = g_strdup_printf("%s/key.pem", data->workdir);
1030 data->cacert = g_strdup_printf("%s/ca-cert.pem", data->workdir);
1031 data->serverkey = g_strdup_printf("%s/server-key.pem", data->workdir);
1032 data->servercert = g_strdup_printf("%s/server-cert.pem", data->workdir);
1033 if (args->clientcert) {
1034 data->clientkey = g_strdup_printf("%s/client-key.pem", data->workdir);
1035 data->clientcert = g_strdup_printf("%s/client-cert.pem", data->workdir);
1038 g_mkdir_with_parents(data->workdir, 0700);
1040 test_tls_init(data->keyfile);
1041 #ifndef _WIN32
1042 g_assert(link(data->keyfile, data->serverkey) == 0);
1043 #else
1044 g_assert(CreateHardLink(data->serverkey, data->keyfile, NULL) != 0);
1045 #endif
1046 if (args->clientcert) {
1047 #ifndef _WIN32
1048 g_assert(link(data->keyfile, data->clientkey) == 0);
1049 #else
1050 g_assert(CreateHardLink(data->clientkey, data->keyfile, NULL) != 0);
1051 #endif
1054 TLS_ROOT_REQ_SIMPLE(cacertreq, data->cacert);
1055 if (args->clientcert) {
1056 TLS_CERT_REQ_SIMPLE_CLIENT(servercertreq, cacertreq,
1057 args->hostileclient ?
1058 QCRYPTO_TLS_TEST_CLIENT_HOSTILE_NAME :
1059 QCRYPTO_TLS_TEST_CLIENT_NAME,
1060 data->clientcert);
1063 TLS_CERT_REQ_SIMPLE_SERVER(clientcertreq, cacertreq,
1064 data->servercert,
1065 args->certhostname,
1066 args->certipaddr);
1068 qtest_qmp_assert_success(from,
1069 "{ 'execute': 'object-add',"
1070 " 'arguments': { 'qom-type': 'tls-creds-x509',"
1071 " 'id': 'tlscredsx509client0',"
1072 " 'endpoint': 'client',"
1073 " 'dir': %s,"
1074 " 'sanity-check': true,"
1075 " 'verify-peer': true} }",
1076 data->workdir);
1077 migrate_set_parameter_str(from, "tls-creds", "tlscredsx509client0");
1078 if (args->certhostname) {
1079 migrate_set_parameter_str(from, "tls-hostname", args->certhostname);
1082 qtest_qmp_assert_success(to,
1083 "{ 'execute': 'object-add',"
1084 " 'arguments': { 'qom-type': 'tls-creds-x509',"
1085 " 'id': 'tlscredsx509server0',"
1086 " 'endpoint': 'server',"
1087 " 'dir': %s,"
1088 " 'sanity-check': true,"
1089 " 'verify-peer': %i} }",
1090 data->workdir, args->verifyclient);
1091 migrate_set_parameter_str(to, "tls-creds", "tlscredsx509server0");
1093 if (args->authzclient) {
1094 qtest_qmp_assert_success(to,
1095 "{ 'execute': 'object-add',"
1096 " 'arguments': { 'qom-type': 'authz-simple',"
1097 " 'id': 'tlsauthz0',"
1098 " 'identity': %s} }",
1099 "CN=" QCRYPTO_TLS_TEST_CLIENT_NAME);
1100 migrate_set_parameter_str(to, "tls-authz", "tlsauthz0");
1103 return data;
1107 * The normal case: match server's cert hostname against
1108 * whatever host we were telling QEMU to connect to (if any)
1110 static void *
1111 test_migrate_tls_x509_start_default_host(QTestState *from,
1112 QTestState *to)
1114 TestMigrateTLSX509 args = {
1115 .verifyclient = true,
1116 .clientcert = true,
1117 .certipaddr = "127.0.0.1"
1119 return test_migrate_tls_x509_start_common(from, to, &args);
1123 * The unusual case: the server's cert is different from
1124 * the address we're telling QEMU to connect to (if any),
1125 * so we must give QEMU an explicit hostname to validate
1127 static void *
1128 test_migrate_tls_x509_start_override_host(QTestState *from,
1129 QTestState *to)
1131 TestMigrateTLSX509 args = {
1132 .verifyclient = true,
1133 .clientcert = true,
1134 .certhostname = "qemu.org",
1136 return test_migrate_tls_x509_start_common(from, to, &args);
1140 * The unusual case: the server's cert is different from
1141 * the address we're telling QEMU to connect to, and so we
1142 * expect the client to reject the server
1144 static void *
1145 test_migrate_tls_x509_start_mismatch_host(QTestState *from,
1146 QTestState *to)
1148 TestMigrateTLSX509 args = {
1149 .verifyclient = true,
1150 .clientcert = true,
1151 .certipaddr = "10.0.0.1",
1153 return test_migrate_tls_x509_start_common(from, to, &args);
1156 static void *
1157 test_migrate_tls_x509_start_friendly_client(QTestState *from,
1158 QTestState *to)
1160 TestMigrateTLSX509 args = {
1161 .verifyclient = true,
1162 .clientcert = true,
1163 .authzclient = true,
1164 .certipaddr = "127.0.0.1",
1166 return test_migrate_tls_x509_start_common(from, to, &args);
1169 static void *
1170 test_migrate_tls_x509_start_hostile_client(QTestState *from,
1171 QTestState *to)
1173 TestMigrateTLSX509 args = {
1174 .verifyclient = true,
1175 .clientcert = true,
1176 .hostileclient = true,
1177 .authzclient = true,
1178 .certipaddr = "127.0.0.1",
1180 return test_migrate_tls_x509_start_common(from, to, &args);
1184 * The case with no client certificate presented,
1185 * and no server verification
1187 static void *
1188 test_migrate_tls_x509_start_allow_anon_client(QTestState *from,
1189 QTestState *to)
1191 TestMigrateTLSX509 args = {
1192 .certipaddr = "127.0.0.1",
1194 return test_migrate_tls_x509_start_common(from, to, &args);
1198 * The case with no client certificate presented,
1199 * and server verification rejecting
1201 static void *
1202 test_migrate_tls_x509_start_reject_anon_client(QTestState *from,
1203 QTestState *to)
1205 TestMigrateTLSX509 args = {
1206 .verifyclient = true,
1207 .certipaddr = "127.0.0.1",
1209 return test_migrate_tls_x509_start_common(from, to, &args);
1212 static void
1213 test_migrate_tls_x509_finish(QTestState *from,
1214 QTestState *to,
1215 void *opaque)
1217 TestMigrateTLSX509Data *data = opaque;
1219 test_tls_cleanup(data->keyfile);
1220 g_free(data->keyfile);
1222 unlink(data->cacert);
1223 g_free(data->cacert);
1224 unlink(data->servercert);
1225 g_free(data->servercert);
1226 unlink(data->serverkey);
1227 g_free(data->serverkey);
1229 if (data->clientcert) {
1230 unlink(data->clientcert);
1231 g_free(data->clientcert);
1233 if (data->clientkey) {
1234 unlink(data->clientkey);
1235 g_free(data->clientkey);
1238 rmdir(data->workdir);
1239 g_free(data->workdir);
1241 g_free(data);
1243 #endif /* CONFIG_TASN1 */
1244 #endif /* CONFIG_GNUTLS */
1246 static int migrate_postcopy_prepare(QTestState **from_ptr,
1247 QTestState **to_ptr,
1248 MigrateCommon *args)
1250 QTestState *from, *to;
1252 if (test_migrate_start(&from, &to, "defer", &args->start)) {
1253 return -1;
1256 if (args->start_hook) {
1257 args->postcopy_data = args->start_hook(from, to);
1260 migrate_set_capability(from, "postcopy-ram", true);
1261 migrate_set_capability(to, "postcopy-ram", true);
1262 migrate_set_capability(to, "postcopy-blocktime", true);
1264 if (args->postcopy_preempt) {
1265 migrate_set_capability(from, "postcopy-preempt", true);
1266 migrate_set_capability(to, "postcopy-preempt", true);
1269 migrate_ensure_non_converge(from);
1271 migrate_prepare_for_dirty_mem(from);
1272 qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming',"
1273 " 'arguments': { "
1274 " 'channels': [ { 'channel-type': 'main',"
1275 " 'addr': { 'transport': 'socket',"
1276 " 'type': 'inet',"
1277 " 'host': '127.0.0.1',"
1278 " 'port': '0' } } ] } }");
1280 /* Wait for the first serial output from the source */
1281 wait_for_serial("src_serial");
1282 wait_for_suspend(from, &src_state);
1284 migrate_qmp(from, to, NULL, NULL, "{}");
1286 migrate_wait_for_dirty_mem(from, to);
1288 *from_ptr = from;
1289 *to_ptr = to;
1291 return 0;
1294 static void migrate_postcopy_complete(QTestState *from, QTestState *to,
1295 MigrateCommon *args)
1297 wait_for_migration_complete(from);
1299 if (args->start.suspend_me) {
1300 /* wakeup succeeds only if guest is suspended */
1301 qtest_qmp_assert_success(to, "{'execute': 'system_wakeup'}");
1304 /* Make sure we get at least one "B" on destination */
1305 wait_for_serial("dest_serial");
1307 if (uffd_feature_thread_id) {
1308 read_blocktime(to);
1311 if (args->finish_hook) {
1312 args->finish_hook(from, to, args->postcopy_data);
1313 args->postcopy_data = NULL;
1316 test_migrate_end(from, to, true);
1319 static void test_postcopy_common(MigrateCommon *args)
1321 QTestState *from, *to;
1323 if (migrate_postcopy_prepare(&from, &to, args)) {
1324 return;
1326 migrate_postcopy_start(from, to);
1327 migrate_postcopy_complete(from, to, args);
1330 static void test_postcopy(void)
1332 MigrateCommon args = { };
1334 test_postcopy_common(&args);
1337 static void test_postcopy_suspend(void)
1339 MigrateCommon args = {
1340 .start.suspend_me = true,
1343 test_postcopy_common(&args);
1346 static void test_postcopy_preempt(void)
1348 MigrateCommon args = {
1349 .postcopy_preempt = true,
1352 test_postcopy_common(&args);
1355 #ifdef CONFIG_GNUTLS
1356 static void test_postcopy_tls_psk(void)
1358 MigrateCommon args = {
1359 .start_hook = test_migrate_tls_psk_start_match,
1360 .finish_hook = test_migrate_tls_psk_finish,
1363 test_postcopy_common(&args);
1366 static void test_postcopy_preempt_tls_psk(void)
1368 MigrateCommon args = {
1369 .postcopy_preempt = true,
1370 .start_hook = test_migrate_tls_psk_start_match,
1371 .finish_hook = test_migrate_tls_psk_finish,
1374 test_postcopy_common(&args);
1376 #endif
1378 static void wait_for_postcopy_status(QTestState *one, const char *status)
1380 wait_for_migration_status(one, status,
1381 (const char * []) { "failed", "active",
1382 "completed", NULL });
1385 static void postcopy_recover_fail(QTestState *from, QTestState *to,
1386 PostcopyRecoveryFailStage stage)
1388 #ifndef _WIN32
1389 bool fail_early = (stage == POSTCOPY_FAIL_CHANNEL_ESTABLISH);
1390 int ret, pair1[2], pair2[2];
1391 char c;
1393 g_assert(stage > POSTCOPY_FAIL_NONE && stage < POSTCOPY_FAIL_MAX);
1395 /* Create two unrelated socketpairs */
1396 ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair1);
1397 g_assert_cmpint(ret, ==, 0);
1399 ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair2);
1400 g_assert_cmpint(ret, ==, 0);
1403 * Give the guests unpaired ends of the sockets, so they'll all blocked
1404 * at reading. This mimics a wrong channel established.
1406 qtest_qmp_fds_assert_success(from, &pair1[0], 1,
1407 "{ 'execute': 'getfd',"
1408 " 'arguments': { 'fdname': 'fd-mig' }}");
1409 qtest_qmp_fds_assert_success(to, &pair2[0], 1,
1410 "{ 'execute': 'getfd',"
1411 " 'arguments': { 'fdname': 'fd-mig' }}");
1414 * Write the 1st byte as QEMU_VM_COMMAND (0x8) for the dest socket, to
1415 * emulate the 1st byte of a real recovery, but stops from there to
1416 * keep dest QEMU in RECOVER. This is needed so that we can kick off
1417 * the recover process on dest QEMU (by triggering the G_IO_IN event).
1419 * NOTE: this trick is not needed on src QEMUs, because src doesn't
1420 * rely on an pre-existing G_IO_IN event, so it will always trigger the
1421 * upcoming recovery anyway even if it can read nothing.
1423 #define QEMU_VM_COMMAND 0x08
1424 c = QEMU_VM_COMMAND;
1425 ret = send(pair2[1], &c, 1, 0);
1426 g_assert_cmpint(ret, ==, 1);
1428 if (stage == POSTCOPY_FAIL_CHANNEL_ESTABLISH) {
1430 * This will make src QEMU to fail at an early stage when trying to
1431 * resume later, where it shouldn't reach RECOVER stage at all.
1433 close(pair1[1]);
1436 migrate_recover(to, "fd:fd-mig");
1437 migrate_qmp(from, to, "fd:fd-mig", NULL, "{'resume': true}");
1440 * Source QEMU has an extra RECOVER_SETUP phase, dest doesn't have it.
1441 * Make sure it appears along the way.
1443 migration_event_wait(from, "postcopy-recover-setup");
1445 if (fail_early) {
1447 * When fails at reconnection, src QEMU will automatically goes
1448 * back to PAUSED state. Making sure there is an event in this
1449 * case: Libvirt relies on this to detect early reconnection
1450 * errors.
1452 migration_event_wait(from, "postcopy-paused");
1453 } else {
1455 * We want to test "fail later" at RECOVER stage here. Make sure
1456 * both QEMU instances will go into RECOVER stage first, then test
1457 * kicking them out using migrate-pause.
1459 * Explicitly check the RECOVER event on src, that's what Libvirt
1460 * relies on, rather than polling.
1462 migration_event_wait(from, "postcopy-recover");
1463 wait_for_postcopy_status(from, "postcopy-recover");
1465 /* Need an explicit kick on src QEMU in this case */
1466 migrate_pause(from);
1470 * For all failure cases, we'll reach such states on both sides now.
1471 * Check them.
1473 wait_for_postcopy_status(from, "postcopy-paused");
1474 wait_for_postcopy_status(to, "postcopy-recover");
1477 * Kick dest QEMU out too. This is normally not needed in reality
1478 * because when the channel is shutdown it should also happen on src.
1479 * However here we used separate socket pairs so we need to do that
1480 * explicitly.
1482 migrate_pause(to);
1483 wait_for_postcopy_status(to, "postcopy-paused");
1485 close(pair1[0]);
1486 close(pair2[0]);
1487 close(pair2[1]);
1489 if (stage != POSTCOPY_FAIL_CHANNEL_ESTABLISH) {
1490 close(pair1[1]);
1492 #endif
1495 static void test_postcopy_recovery_common(MigrateCommon *args)
1497 QTestState *from, *to;
1498 g_autofree char *uri = NULL;
1500 /* Always hide errors for postcopy recover tests since they're expected */
1501 args->start.hide_stderr = true;
1503 if (migrate_postcopy_prepare(&from, &to, args)) {
1504 return;
1507 /* Turn postcopy speed down, 4K/s is slow enough on any machines */
1508 migrate_set_parameter_int(from, "max-postcopy-bandwidth", 4096);
1510 /* Now we start the postcopy */
1511 migrate_postcopy_start(from, to);
1514 * Wait until postcopy is really started; we can only run the
1515 * migrate-pause command during a postcopy
1517 wait_for_migration_status(from, "postcopy-active", NULL);
1520 * Manually stop the postcopy migration. This emulates a network
1521 * failure with the migration socket
1523 migrate_pause(from);
1526 * Wait for destination side to reach postcopy-paused state. The
1527 * migrate-recover command can only succeed if destination machine
1528 * is in the paused state
1530 wait_for_postcopy_status(to, "postcopy-paused");
1531 wait_for_postcopy_status(from, "postcopy-paused");
1533 if (args->postcopy_recovery_fail_stage) {
1535 * Test when a wrong socket specified for recover, and then the
1536 * ability to kick it out, and continue with a correct socket.
1538 postcopy_recover_fail(from, to, args->postcopy_recovery_fail_stage);
1539 /* continue with a good recovery */
1543 * Create a new socket to emulate a new channel that is different
1544 * from the broken migration channel; tell the destination to
1545 * listen to the new port
1547 uri = g_strdup_printf("unix:%s/migsocket-recover", tmpfs);
1548 migrate_recover(to, uri);
1551 * Try to rebuild the migration channel using the resume flag and
1552 * the newly created channel
1554 migrate_qmp(from, to, uri, NULL, "{'resume': true}");
1556 /* Restore the postcopy bandwidth to unlimited */
1557 migrate_set_parameter_int(from, "max-postcopy-bandwidth", 0);
1559 migrate_postcopy_complete(from, to, args);
1562 static void test_postcopy_recovery(void)
1564 MigrateCommon args = { };
1566 test_postcopy_recovery_common(&args);
1569 static void test_postcopy_recovery_fail_handshake(void)
1571 MigrateCommon args = {
1572 .postcopy_recovery_fail_stage = POSTCOPY_FAIL_RECOVERY,
1575 test_postcopy_recovery_common(&args);
1578 static void test_postcopy_recovery_fail_reconnect(void)
1580 MigrateCommon args = {
1581 .postcopy_recovery_fail_stage = POSTCOPY_FAIL_CHANNEL_ESTABLISH,
1584 test_postcopy_recovery_common(&args);
1587 #ifdef CONFIG_GNUTLS
1588 static void test_postcopy_recovery_tls_psk(void)
1590 MigrateCommon args = {
1591 .start_hook = test_migrate_tls_psk_start_match,
1592 .finish_hook = test_migrate_tls_psk_finish,
1595 test_postcopy_recovery_common(&args);
1597 #endif
1599 static void test_postcopy_preempt_recovery(void)
1601 MigrateCommon args = {
1602 .postcopy_preempt = true,
1605 test_postcopy_recovery_common(&args);
1608 #ifdef CONFIG_GNUTLS
1609 /* This contains preempt+recovery+tls test altogether */
1610 static void test_postcopy_preempt_all(void)
1612 MigrateCommon args = {
1613 .postcopy_preempt = true,
1614 .start_hook = test_migrate_tls_psk_start_match,
1615 .finish_hook = test_migrate_tls_psk_finish,
1618 test_postcopy_recovery_common(&args);
1621 #endif
1623 static void test_baddest(void)
1625 MigrateStart args = {
1626 .hide_stderr = true
1628 QTestState *from, *to;
1630 if (test_migrate_start(&from, &to, "tcp:127.0.0.1:0", &args)) {
1631 return;
1633 migrate_qmp(from, to, "tcp:127.0.0.1:0", NULL, "{}");
1634 wait_for_migration_fail(from, false);
1635 test_migrate_end(from, to, false);
1638 #ifndef _WIN32
1639 static void test_analyze_script(void)
1641 MigrateStart args = {
1642 .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
1644 QTestState *from, *to;
1645 g_autofree char *uri = NULL;
1646 g_autofree char *file = NULL;
1647 int pid, wstatus;
1648 const char *python = g_getenv("PYTHON");
1650 if (!python) {
1651 g_test_skip("PYTHON variable not set");
1652 return;
1655 /* dummy url */
1656 if (test_migrate_start(&from, &to, "tcp:127.0.0.1:0", &args)) {
1657 return;
1661 * Setting these two capabilities causes the "configuration"
1662 * vmstate to include subsections for them. The script needs to
1663 * parse those subsections properly.
1665 migrate_set_capability(from, "validate-uuid", true);
1666 migrate_set_capability(from, "x-ignore-shared", true);
1668 file = g_strdup_printf("%s/migfile", tmpfs);
1669 uri = g_strdup_printf("exec:cat > %s", file);
1671 migrate_ensure_converge(from);
1672 migrate_qmp(from, to, uri, NULL, "{}");
1673 wait_for_migration_complete(from);
1675 pid = fork();
1676 if (!pid) {
1677 close(1);
1678 open("/dev/null", O_WRONLY);
1679 execl(python, python, ANALYZE_SCRIPT, "-f", file, NULL);
1680 g_assert_not_reached();
1683 g_assert(waitpid(pid, &wstatus, 0) == pid);
1684 if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
1685 g_test_message("Failed to analyze the migration stream");
1686 g_test_fail();
1688 test_migrate_end(from, to, false);
1689 cleanup("migfile");
1692 static void test_vmstate_checker_script(void)
1694 g_autofree gchar *cmd_src = NULL;
1695 g_autofree gchar *cmd_dst = NULL;
1696 g_autofree gchar *vmstate_src = NULL;
1697 g_autofree gchar *vmstate_dst = NULL;
1698 const char *machine_alias, *machine_opts = "";
1699 g_autofree char *machine = NULL;
1700 const char *arch = qtest_get_arch();
1701 int pid, wstatus;
1702 const char *python = g_getenv("PYTHON");
1704 if (!getenv(QEMU_ENV_SRC) && !getenv(QEMU_ENV_DST)) {
1705 g_test_skip("Test needs two different QEMU versions");
1706 return;
1709 if (!python) {
1710 g_test_skip("PYTHON variable not set");
1711 return;
1714 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
1715 if (g_str_equal(arch, "i386")) {
1716 machine_alias = "pc";
1717 } else {
1718 machine_alias = "q35";
1720 } else if (g_str_equal(arch, "s390x")) {
1721 machine_alias = "s390-ccw-virtio";
1722 } else if (strcmp(arch, "ppc64") == 0) {
1723 machine_alias = "pseries";
1724 } else if (strcmp(arch, "aarch64") == 0) {
1725 machine_alias = "virt";
1726 } else {
1727 g_assert_not_reached();
1730 if (!qtest_has_machine(machine_alias)) {
1731 g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
1732 g_test_skip(msg);
1733 return;
1736 machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
1737 QEMU_ENV_DST);
1739 vmstate_src = g_strdup_printf("%s/vmstate-src", tmpfs);
1740 vmstate_dst = g_strdup_printf("%s/vmstate-dst", tmpfs);
1742 cmd_dst = g_strdup_printf("-machine %s,%s -dump-vmstate %s",
1743 machine, machine_opts, vmstate_dst);
1744 cmd_src = g_strdup_printf("-machine %s,%s -dump-vmstate %s",
1745 machine, machine_opts, vmstate_src);
1747 qtest_init_with_env_no_handshake(QEMU_ENV_SRC, cmd_src);
1748 qtest_init_with_env_no_handshake(QEMU_ENV_DST, cmd_dst);
1750 pid = fork();
1751 if (!pid) {
1752 close(1);
1753 open("/dev/null", O_WRONLY);
1754 execl(python, python, VMSTATE_CHECKER_SCRIPT,
1755 "-s", vmstate_src,
1756 "-d", vmstate_dst,
1757 NULL);
1758 g_assert_not_reached();
1761 g_assert(waitpid(pid, &wstatus, 0) == pid);
1762 if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
1763 g_test_message("Failed to run vmstate-static-checker.py");
1764 g_test_fail();
1767 cleanup("vmstate-src");
1768 cleanup("vmstate-dst");
1770 #endif
1772 static void test_precopy_common(MigrateCommon *args)
1774 QTestState *from, *to;
1775 void *data_hook = NULL;
1777 if (test_migrate_start(&from, &to, args->listen_uri, &args->start)) {
1778 return;
1781 if (args->start_hook) {
1782 data_hook = args->start_hook(from, to);
1785 /* Wait for the first serial output from the source */
1786 if (args->result == MIG_TEST_SUCCEED) {
1787 wait_for_serial("src_serial");
1788 wait_for_suspend(from, &src_state);
1791 if (args->live) {
1792 migrate_ensure_non_converge(from);
1793 migrate_prepare_for_dirty_mem(from);
1794 } else {
1796 * Testing non-live migration, we allow it to run at
1797 * full speed to ensure short test case duration.
1798 * For tests expected to fail, we don't need to
1799 * change anything.
1801 if (args->result == MIG_TEST_SUCCEED) {
1802 qtest_qmp_assert_success(from, "{ 'execute' : 'stop'}");
1803 wait_for_stop(from, &src_state);
1804 migrate_ensure_converge(from);
1808 if (args->result == MIG_TEST_QMP_ERROR) {
1809 migrate_qmp_fail(from, args->connect_uri, args->connect_channels, "{}");
1810 goto finish;
1813 migrate_qmp(from, to, args->connect_uri, args->connect_channels, "{}");
1815 if (args->result != MIG_TEST_SUCCEED) {
1816 bool allow_active = args->result == MIG_TEST_FAIL;
1817 wait_for_migration_fail(from, allow_active);
1819 if (args->result == MIG_TEST_FAIL_DEST_QUIT_ERR) {
1820 qtest_set_expected_status(to, EXIT_FAILURE);
1822 } else {
1823 if (args->live) {
1825 * For initial iteration(s) we must do a full pass,
1826 * but for the final iteration, we need only wait
1827 * for some dirty mem before switching to converge
1829 while (args->iterations > 1) {
1830 wait_for_migration_pass(from);
1831 args->iterations--;
1833 migrate_wait_for_dirty_mem(from, to);
1835 migrate_ensure_converge(from);
1838 * We do this first, as it has a timeout to stop us
1839 * hanging forever if migration didn't converge
1841 wait_for_migration_complete(from);
1843 wait_for_stop(from, &src_state);
1845 } else {
1846 wait_for_migration_complete(from);
1848 * Must wait for dst to finish reading all incoming
1849 * data on the socket before issuing 'cont' otherwise
1850 * it'll be ignored
1852 wait_for_migration_complete(to);
1854 qtest_qmp_assert_success(to, "{ 'execute' : 'cont'}");
1857 wait_for_resume(to, &dst_state);
1859 if (args->start.suspend_me) {
1860 /* wakeup succeeds only if guest is suspended */
1861 qtest_qmp_assert_success(to, "{'execute': 'system_wakeup'}");
1864 wait_for_serial("dest_serial");
1867 finish:
1868 if (args->finish_hook) {
1869 args->finish_hook(from, to, data_hook);
1872 test_migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
1875 static void file_dirty_offset_region(void)
1877 g_autofree char *path = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
1878 size_t size = FILE_TEST_OFFSET;
1879 g_autofree char *data = g_new0(char, size);
1881 memset(data, FILE_TEST_MARKER, size);
1882 g_assert(g_file_set_contents(path, data, size, NULL));
1885 static void file_check_offset_region(void)
1887 g_autofree char *path = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
1888 size_t size = FILE_TEST_OFFSET;
1889 g_autofree char *expected = g_new0(char, size);
1890 g_autofree char *actual = NULL;
1891 uint64_t *stream_start;
1894 * Ensure the skipped offset region's data has not been touched
1895 * and the migration stream starts at the right place.
1898 memset(expected, FILE_TEST_MARKER, size);
1900 g_assert(g_file_get_contents(path, &actual, NULL, NULL));
1901 g_assert(!memcmp(actual, expected, size));
1903 stream_start = (uint64_t *)(actual + size);
1904 g_assert_cmpint(cpu_to_be64(*stream_start) >> 32, ==, QEMU_VM_FILE_MAGIC);
1907 static void test_file_common(MigrateCommon *args, bool stop_src)
1909 QTestState *from, *to;
1910 void *data_hook = NULL;
1911 bool check_offset = false;
1913 if (test_migrate_start(&from, &to, args->listen_uri, &args->start)) {
1914 return;
1918 * File migration is never live. We can keep the source VM running
1919 * during migration, but the destination will not be running
1920 * concurrently.
1922 g_assert_false(args->live);
1924 if (g_strrstr(args->connect_uri, "offset=")) {
1925 check_offset = true;
1927 * This comes before the start_hook because it's equivalent to
1928 * a management application creating the file and writing to
1929 * it so hooks should expect the file to be already present.
1931 file_dirty_offset_region();
1934 if (args->start_hook) {
1935 data_hook = args->start_hook(from, to);
1938 migrate_ensure_converge(from);
1939 wait_for_serial("src_serial");
1941 if (stop_src) {
1942 qtest_qmp_assert_success(from, "{ 'execute' : 'stop'}");
1943 wait_for_stop(from, &src_state);
1946 if (args->result == MIG_TEST_QMP_ERROR) {
1947 migrate_qmp_fail(from, args->connect_uri, NULL, "{}");
1948 goto finish;
1951 migrate_qmp(from, to, args->connect_uri, NULL, "{}");
1952 wait_for_migration_complete(from);
1955 * We need to wait for the source to finish before starting the
1956 * destination.
1958 migrate_incoming_qmp(to, args->connect_uri, "{}");
1959 wait_for_migration_complete(to);
1961 if (stop_src) {
1962 qtest_qmp_assert_success(to, "{ 'execute' : 'cont'}");
1964 wait_for_resume(to, &dst_state);
1966 wait_for_serial("dest_serial");
1968 if (check_offset) {
1969 file_check_offset_region();
1972 finish:
1973 if (args->finish_hook) {
1974 args->finish_hook(from, to, data_hook);
1977 test_migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
1980 static void test_precopy_unix_plain(void)
1982 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1983 MigrateCommon args = {
1984 .listen_uri = uri,
1985 .connect_uri = uri,
1987 * The simplest use case of precopy, covering smoke tests of
1988 * get-dirty-log dirty tracking.
1990 .live = true,
1993 test_precopy_common(&args);
1996 static void test_precopy_unix_suspend_live(void)
1998 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1999 MigrateCommon args = {
2000 .listen_uri = uri,
2001 .connect_uri = uri,
2003 * despite being live, the test is fast because the src
2004 * suspends immediately.
2006 .live = true,
2007 .start.suspend_me = true,
2010 test_precopy_common(&args);
2013 static void test_precopy_unix_suspend_notlive(void)
2015 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2016 MigrateCommon args = {
2017 .listen_uri = uri,
2018 .connect_uri = uri,
2019 .start.suspend_me = true,
2022 test_precopy_common(&args);
2025 static void test_precopy_unix_dirty_ring(void)
2027 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2028 MigrateCommon args = {
2029 .start = {
2030 .use_dirty_ring = true,
2032 .listen_uri = uri,
2033 .connect_uri = uri,
2035 * Besides the precopy/unix basic test, cover dirty ring interface
2036 * rather than get-dirty-log.
2038 .live = true,
2041 test_precopy_common(&args);
2044 #ifdef CONFIG_GNUTLS
2045 static void test_precopy_unix_tls_psk(void)
2047 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2048 MigrateCommon args = {
2049 .connect_uri = uri,
2050 .listen_uri = uri,
2051 .start_hook = test_migrate_tls_psk_start_match,
2052 .finish_hook = test_migrate_tls_psk_finish,
2055 test_precopy_common(&args);
2058 #ifdef CONFIG_TASN1
2059 static void test_precopy_unix_tls_x509_default_host(void)
2061 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2062 MigrateCommon args = {
2063 .start = {
2064 .hide_stderr = true,
2066 .connect_uri = uri,
2067 .listen_uri = uri,
2068 .start_hook = test_migrate_tls_x509_start_default_host,
2069 .finish_hook = test_migrate_tls_x509_finish,
2070 .result = MIG_TEST_FAIL_DEST_QUIT_ERR,
2073 test_precopy_common(&args);
2076 static void test_precopy_unix_tls_x509_override_host(void)
2078 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2079 MigrateCommon args = {
2080 .connect_uri = uri,
2081 .listen_uri = uri,
2082 .start_hook = test_migrate_tls_x509_start_override_host,
2083 .finish_hook = test_migrate_tls_x509_finish,
2086 test_precopy_common(&args);
2088 #endif /* CONFIG_TASN1 */
2089 #endif /* CONFIG_GNUTLS */
2091 #if 0
2092 /* Currently upset on aarch64 TCG */
2093 static void test_ignore_shared(void)
2095 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2096 QTestState *from, *to;
2098 if (test_migrate_start(&from, &to, uri, false, true, NULL, NULL)) {
2099 return;
2102 migrate_ensure_non_converge(from);
2103 migrate_prepare_for_dirty_mem(from);
2105 migrate_set_capability(from, "x-ignore-shared", true);
2106 migrate_set_capability(to, "x-ignore-shared", true);
2108 /* Wait for the first serial output from the source */
2109 wait_for_serial("src_serial");
2111 migrate_qmp(from, to, uri, NULL, "{}");
2113 migrate_wait_for_dirty_mem(from, to);
2115 wait_for_stop(from, &src_state);
2117 qtest_qmp_eventwait(to, "RESUME");
2119 wait_for_serial("dest_serial");
2120 wait_for_migration_complete(from);
2122 /* Check whether shared RAM has been really skipped */
2123 g_assert_cmpint(read_ram_property_int(from, "transferred"), <, 1024 * 1024);
2125 test_migrate_end(from, to, true);
2127 #endif
2129 static void *
2130 test_migrate_xbzrle_start(QTestState *from,
2131 QTestState *to)
2133 migrate_set_parameter_int(from, "xbzrle-cache-size", 33554432);
2135 migrate_set_capability(from, "xbzrle", true);
2136 migrate_set_capability(to, "xbzrle", true);
2138 return NULL;
2141 static void test_precopy_unix_xbzrle(void)
2143 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2144 MigrateCommon args = {
2145 .connect_uri = uri,
2146 .listen_uri = uri,
2147 .start_hook = test_migrate_xbzrle_start,
2148 .iterations = 2,
2150 * XBZRLE needs pages to be modified when doing the 2nd+ round
2151 * iteration to have real data pushed to the stream.
2153 .live = true,
2156 test_precopy_common(&args);
2159 static void test_precopy_file(void)
2161 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2162 FILE_TEST_FILENAME);
2163 MigrateCommon args = {
2164 .connect_uri = uri,
2165 .listen_uri = "defer",
2168 test_file_common(&args, true);
2171 #ifndef _WIN32
2172 static void fdset_add_fds(QTestState *qts, const char *file, int flags,
2173 int num_fds, bool direct_io)
2175 for (int i = 0; i < num_fds; i++) {
2176 int fd;
2178 #ifdef O_DIRECT
2179 /* only secondary channels can use direct-io */
2180 if (direct_io && i != 0) {
2181 flags |= O_DIRECT;
2183 #endif
2185 fd = open(file, flags, 0660);
2186 assert(fd != -1);
2188 qtest_qmp_fds_assert_success(qts, &fd, 1, "{'execute': 'add-fd', "
2189 "'arguments': {'fdset-id': 1}}");
2190 close(fd);
2194 static void *file_offset_fdset_start_hook(QTestState *from, QTestState *to)
2196 g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
2198 fdset_add_fds(from, file, O_WRONLY, 1, false);
2199 fdset_add_fds(to, file, O_RDONLY, 1, false);
2201 return NULL;
2204 static void test_precopy_file_offset_fdset(void)
2206 g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d",
2207 FILE_TEST_OFFSET);
2208 MigrateCommon args = {
2209 .connect_uri = uri,
2210 .listen_uri = "defer",
2211 .start_hook = file_offset_fdset_start_hook,
2214 test_file_common(&args, false);
2216 #endif
2218 static void test_precopy_file_offset(void)
2220 g_autofree char *uri = g_strdup_printf("file:%s/%s,offset=%d", tmpfs,
2221 FILE_TEST_FILENAME,
2222 FILE_TEST_OFFSET);
2223 MigrateCommon args = {
2224 .connect_uri = uri,
2225 .listen_uri = "defer",
2228 test_file_common(&args, false);
2231 static void test_precopy_file_offset_bad(void)
2233 /* using a value not supported by qemu_strtosz() */
2234 g_autofree char *uri = g_strdup_printf("file:%s/%s,offset=0x20M",
2235 tmpfs, FILE_TEST_FILENAME);
2236 MigrateCommon args = {
2237 .connect_uri = uri,
2238 .listen_uri = "defer",
2239 .result = MIG_TEST_QMP_ERROR,
2242 test_file_common(&args, false);
2245 static void *test_mode_reboot_start(QTestState *from, QTestState *to)
2247 migrate_set_parameter_str(from, "mode", "cpr-reboot");
2248 migrate_set_parameter_str(to, "mode", "cpr-reboot");
2250 migrate_set_capability(from, "x-ignore-shared", true);
2251 migrate_set_capability(to, "x-ignore-shared", true);
2253 return NULL;
2256 static void *migrate_mapped_ram_start(QTestState *from, QTestState *to)
2258 migrate_set_capability(from, "mapped-ram", true);
2259 migrate_set_capability(to, "mapped-ram", true);
2261 return NULL;
2264 static void test_mode_reboot(void)
2266 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2267 FILE_TEST_FILENAME);
2268 MigrateCommon args = {
2269 .start.use_shmem = true,
2270 .connect_uri = uri,
2271 .listen_uri = "defer",
2272 .start_hook = test_mode_reboot_start
2275 test_file_common(&args, true);
2278 static void test_precopy_file_mapped_ram_live(void)
2280 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2281 FILE_TEST_FILENAME);
2282 MigrateCommon args = {
2283 .connect_uri = uri,
2284 .listen_uri = "defer",
2285 .start_hook = migrate_mapped_ram_start,
2288 test_file_common(&args, false);
2291 static void test_precopy_file_mapped_ram(void)
2293 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2294 FILE_TEST_FILENAME);
2295 MigrateCommon args = {
2296 .connect_uri = uri,
2297 .listen_uri = "defer",
2298 .start_hook = migrate_mapped_ram_start,
2301 test_file_common(&args, true);
2304 static void *migrate_multifd_mapped_ram_start(QTestState *from, QTestState *to)
2306 migrate_mapped_ram_start(from, to);
2308 migrate_set_parameter_int(from, "multifd-channels", 4);
2309 migrate_set_parameter_int(to, "multifd-channels", 4);
2311 migrate_set_capability(from, "multifd", true);
2312 migrate_set_capability(to, "multifd", true);
2314 return NULL;
2317 static void test_multifd_file_mapped_ram_live(void)
2319 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2320 FILE_TEST_FILENAME);
2321 MigrateCommon args = {
2322 .connect_uri = uri,
2323 .listen_uri = "defer",
2324 .start_hook = migrate_multifd_mapped_ram_start,
2327 test_file_common(&args, false);
2330 static void test_multifd_file_mapped_ram(void)
2332 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2333 FILE_TEST_FILENAME);
2334 MigrateCommon args = {
2335 .connect_uri = uri,
2336 .listen_uri = "defer",
2337 .start_hook = migrate_multifd_mapped_ram_start,
2340 test_file_common(&args, true);
2343 static void *multifd_mapped_ram_dio_start(QTestState *from, QTestState *to)
2345 migrate_multifd_mapped_ram_start(from, to);
2347 migrate_set_parameter_bool(from, "direct-io", true);
2348 migrate_set_parameter_bool(to, "direct-io", true);
2350 return NULL;
2353 static void test_multifd_file_mapped_ram_dio(void)
2355 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2356 FILE_TEST_FILENAME);
2357 MigrateCommon args = {
2358 .connect_uri = uri,
2359 .listen_uri = "defer",
2360 .start_hook = multifd_mapped_ram_dio_start,
2363 if (!probe_o_direct_support(tmpfs)) {
2364 g_test_skip("Filesystem does not support O_DIRECT");
2365 return;
2368 test_file_common(&args, true);
2371 #ifndef _WIN32
2372 static void multifd_mapped_ram_fdset_end(QTestState *from, QTestState *to,
2373 void *opaque)
2375 QDict *resp;
2376 QList *fdsets;
2379 * Remove the fdsets after migration, otherwise a second migration
2380 * would fail due fdset reuse.
2382 qtest_qmp_assert_success(from, "{'execute': 'remove-fd', "
2383 "'arguments': { 'fdset-id': 1}}");
2386 * Make sure no fdsets are left after migration, otherwise a
2387 * second migration would fail due fdset reuse.
2389 resp = qtest_qmp(from, "{'execute': 'query-fdsets', "
2390 "'arguments': {}}");
2391 g_assert(qdict_haskey(resp, "return"));
2392 fdsets = qdict_get_qlist(resp, "return");
2393 g_assert(fdsets && qlist_empty(fdsets));
2396 static void *multifd_mapped_ram_fdset_dio(QTestState *from, QTestState *to)
2398 g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
2400 fdset_add_fds(from, file, O_WRONLY, 2, true);
2401 fdset_add_fds(to, file, O_RDONLY, 2, true);
2403 migrate_multifd_mapped_ram_start(from, to);
2404 migrate_set_parameter_bool(from, "direct-io", true);
2405 migrate_set_parameter_bool(to, "direct-io", true);
2407 return NULL;
2410 static void *multifd_mapped_ram_fdset(QTestState *from, QTestState *to)
2412 g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
2414 fdset_add_fds(from, file, O_WRONLY, 2, false);
2415 fdset_add_fds(to, file, O_RDONLY, 2, false);
2417 migrate_multifd_mapped_ram_start(from, to);
2419 return NULL;
2422 static void test_multifd_file_mapped_ram_fdset(void)
2424 g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d",
2425 FILE_TEST_OFFSET);
2426 MigrateCommon args = {
2427 .connect_uri = uri,
2428 .listen_uri = "defer",
2429 .start_hook = multifd_mapped_ram_fdset,
2430 .finish_hook = multifd_mapped_ram_fdset_end,
2433 test_file_common(&args, true);
2436 static void test_multifd_file_mapped_ram_fdset_dio(void)
2438 g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d",
2439 FILE_TEST_OFFSET);
2440 MigrateCommon args = {
2441 .connect_uri = uri,
2442 .listen_uri = "defer",
2443 .start_hook = multifd_mapped_ram_fdset_dio,
2444 .finish_hook = multifd_mapped_ram_fdset_end,
2447 if (!probe_o_direct_support(tmpfs)) {
2448 g_test_skip("Filesystem does not support O_DIRECT");
2449 return;
2452 test_file_common(&args, true);
2454 #endif /* !_WIN32 */
2456 static void test_precopy_tcp_plain(void)
2458 MigrateCommon args = {
2459 .listen_uri = "tcp:127.0.0.1:0",
2462 test_precopy_common(&args);
2465 static void *test_migrate_switchover_ack_start(QTestState *from, QTestState *to)
2468 migrate_set_capability(from, "return-path", true);
2469 migrate_set_capability(to, "return-path", true);
2471 migrate_set_capability(from, "switchover-ack", true);
2472 migrate_set_capability(to, "switchover-ack", true);
2474 return NULL;
2477 static void test_precopy_tcp_switchover_ack(void)
2479 MigrateCommon args = {
2480 .listen_uri = "tcp:127.0.0.1:0",
2481 .start_hook = test_migrate_switchover_ack_start,
2483 * Source VM must be running in order to consider the switchover ACK
2484 * when deciding to do switchover or not.
2486 .live = true,
2489 test_precopy_common(&args);
2492 #ifdef CONFIG_GNUTLS
2493 static void test_precopy_tcp_tls_psk_match(void)
2495 MigrateCommon args = {
2496 .listen_uri = "tcp:127.0.0.1:0",
2497 .start_hook = test_migrate_tls_psk_start_match,
2498 .finish_hook = test_migrate_tls_psk_finish,
2501 test_precopy_common(&args);
2504 static void test_precopy_tcp_tls_psk_mismatch(void)
2506 MigrateCommon args = {
2507 .start = {
2508 .hide_stderr = true,
2510 .listen_uri = "tcp:127.0.0.1:0",
2511 .start_hook = test_migrate_tls_psk_start_mismatch,
2512 .finish_hook = test_migrate_tls_psk_finish,
2513 .result = MIG_TEST_FAIL,
2516 test_precopy_common(&args);
2519 #ifdef CONFIG_TASN1
2520 static void test_precopy_tcp_tls_x509_default_host(void)
2522 MigrateCommon args = {
2523 .listen_uri = "tcp:127.0.0.1:0",
2524 .start_hook = test_migrate_tls_x509_start_default_host,
2525 .finish_hook = test_migrate_tls_x509_finish,
2528 test_precopy_common(&args);
2531 static void test_precopy_tcp_tls_x509_override_host(void)
2533 MigrateCommon args = {
2534 .listen_uri = "tcp:127.0.0.1:0",
2535 .start_hook = test_migrate_tls_x509_start_override_host,
2536 .finish_hook = test_migrate_tls_x509_finish,
2539 test_precopy_common(&args);
2542 static void test_precopy_tcp_tls_x509_mismatch_host(void)
2544 MigrateCommon args = {
2545 .start = {
2546 .hide_stderr = true,
2548 .listen_uri = "tcp:127.0.0.1:0",
2549 .start_hook = test_migrate_tls_x509_start_mismatch_host,
2550 .finish_hook = test_migrate_tls_x509_finish,
2551 .result = MIG_TEST_FAIL_DEST_QUIT_ERR,
2554 test_precopy_common(&args);
2557 static void test_precopy_tcp_tls_x509_friendly_client(void)
2559 MigrateCommon args = {
2560 .listen_uri = "tcp:127.0.0.1:0",
2561 .start_hook = test_migrate_tls_x509_start_friendly_client,
2562 .finish_hook = test_migrate_tls_x509_finish,
2565 test_precopy_common(&args);
2568 static void test_precopy_tcp_tls_x509_hostile_client(void)
2570 MigrateCommon args = {
2571 .start = {
2572 .hide_stderr = true,
2574 .listen_uri = "tcp:127.0.0.1:0",
2575 .start_hook = test_migrate_tls_x509_start_hostile_client,
2576 .finish_hook = test_migrate_tls_x509_finish,
2577 .result = MIG_TEST_FAIL,
2580 test_precopy_common(&args);
2583 static void test_precopy_tcp_tls_x509_allow_anon_client(void)
2585 MigrateCommon args = {
2586 .listen_uri = "tcp:127.0.0.1:0",
2587 .start_hook = test_migrate_tls_x509_start_allow_anon_client,
2588 .finish_hook = test_migrate_tls_x509_finish,
2591 test_precopy_common(&args);
2594 static void test_precopy_tcp_tls_x509_reject_anon_client(void)
2596 MigrateCommon args = {
2597 .start = {
2598 .hide_stderr = true,
2600 .listen_uri = "tcp:127.0.0.1:0",
2601 .start_hook = test_migrate_tls_x509_start_reject_anon_client,
2602 .finish_hook = test_migrate_tls_x509_finish,
2603 .result = MIG_TEST_FAIL,
2606 test_precopy_common(&args);
2608 #endif /* CONFIG_TASN1 */
2609 #endif /* CONFIG_GNUTLS */
2611 #ifndef _WIN32
2612 static void *test_migrate_fd_start_hook(QTestState *from,
2613 QTestState *to)
2615 int ret;
2616 int pair[2];
2618 /* Create two connected sockets for migration */
2619 ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
2620 g_assert_cmpint(ret, ==, 0);
2622 /* Send the 1st socket to the target */
2623 qtest_qmp_fds_assert_success(to, &pair[0], 1,
2624 "{ 'execute': 'getfd',"
2625 " 'arguments': { 'fdname': 'fd-mig' }}");
2626 close(pair[0]);
2628 /* Start incoming migration from the 1st socket */
2629 migrate_incoming_qmp(to, "fd:fd-mig", "{}");
2631 /* Send the 2nd socket to the target */
2632 qtest_qmp_fds_assert_success(from, &pair[1], 1,
2633 "{ 'execute': 'getfd',"
2634 " 'arguments': { 'fdname': 'fd-mig' }}");
2635 close(pair[1]);
2637 return NULL;
2640 static void test_migrate_fd_finish_hook(QTestState *from,
2641 QTestState *to,
2642 void *opaque)
2644 QDict *rsp;
2645 const char *error_desc;
2647 /* Test closing fds */
2648 /* We assume, that QEMU removes named fd from its list,
2649 * so this should fail */
2650 rsp = qtest_qmp(from, "{ 'execute': 'closefd',"
2651 " 'arguments': { 'fdname': 'fd-mig' }}");
2652 g_assert_true(qdict_haskey(rsp, "error"));
2653 error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
2654 g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
2655 qobject_unref(rsp);
2657 rsp = qtest_qmp(to, "{ 'execute': 'closefd',"
2658 " 'arguments': { 'fdname': 'fd-mig' }}");
2659 g_assert_true(qdict_haskey(rsp, "error"));
2660 error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
2661 g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
2662 qobject_unref(rsp);
2665 static void test_migrate_precopy_fd_socket(void)
2667 MigrateCommon args = {
2668 .listen_uri = "defer",
2669 .connect_uri = "fd:fd-mig",
2670 .start_hook = test_migrate_fd_start_hook,
2671 .finish_hook = test_migrate_fd_finish_hook
2673 test_precopy_common(&args);
2676 static void *migrate_precopy_fd_file_start(QTestState *from, QTestState *to)
2678 g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
2679 int src_flags = O_CREAT | O_RDWR;
2680 int dst_flags = O_CREAT | O_RDWR;
2681 int fds[2];
2683 fds[0] = open(file, src_flags, 0660);
2684 assert(fds[0] != -1);
2686 fds[1] = open(file, dst_flags, 0660);
2687 assert(fds[1] != -1);
2690 qtest_qmp_fds_assert_success(to, &fds[0], 1,
2691 "{ 'execute': 'getfd',"
2692 " 'arguments': { 'fdname': 'fd-mig' }}");
2694 qtest_qmp_fds_assert_success(from, &fds[1], 1,
2695 "{ 'execute': 'getfd',"
2696 " 'arguments': { 'fdname': 'fd-mig' }}");
2698 close(fds[0]);
2699 close(fds[1]);
2701 return NULL;
2704 static void test_migrate_precopy_fd_file(void)
2706 MigrateCommon args = {
2707 .listen_uri = "defer",
2708 .connect_uri = "fd:fd-mig",
2709 .start_hook = migrate_precopy_fd_file_start,
2710 .finish_hook = test_migrate_fd_finish_hook
2712 test_file_common(&args, true);
2714 #endif /* _WIN32 */
2716 static void do_test_validate_uuid(MigrateStart *args, bool should_fail)
2718 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2719 QTestState *from, *to;
2721 if (test_migrate_start(&from, &to, uri, args)) {
2722 return;
2726 * UUID validation is at the begin of migration. So, the main process of
2727 * migration is not interesting for us here. Thus, set huge downtime for
2728 * very fast migration.
2730 migrate_set_parameter_int(from, "downtime-limit", 1000000);
2731 migrate_set_capability(from, "validate-uuid", true);
2733 /* Wait for the first serial output from the source */
2734 wait_for_serial("src_serial");
2736 migrate_qmp(from, to, uri, NULL, "{}");
2738 if (should_fail) {
2739 qtest_set_expected_status(to, EXIT_FAILURE);
2740 wait_for_migration_fail(from, true);
2741 } else {
2742 wait_for_migration_complete(from);
2745 test_migrate_end(from, to, false);
2748 static void test_validate_uuid(void)
2750 MigrateStart args = {
2751 .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
2752 .opts_target = "-uuid 11111111-1111-1111-1111-111111111111",
2755 do_test_validate_uuid(&args, false);
2758 static void test_validate_uuid_error(void)
2760 MigrateStart args = {
2761 .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
2762 .opts_target = "-uuid 22222222-2222-2222-2222-222222222222",
2763 .hide_stderr = true,
2766 do_test_validate_uuid(&args, true);
2769 static void test_validate_uuid_src_not_set(void)
2771 MigrateStart args = {
2772 .opts_target = "-uuid 22222222-2222-2222-2222-222222222222",
2773 .hide_stderr = true,
2776 do_test_validate_uuid(&args, false);
2779 static void test_validate_uuid_dst_not_set(void)
2781 MigrateStart args = {
2782 .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
2783 .hide_stderr = true,
2786 do_test_validate_uuid(&args, false);
2789 static void do_test_validate_uri_channel(MigrateCommon *args)
2791 QTestState *from, *to;
2793 if (test_migrate_start(&from, &to, args->listen_uri, &args->start)) {
2794 return;
2797 /* Wait for the first serial output from the source */
2798 wait_for_serial("src_serial");
2801 * 'uri' and 'channels' validation is checked even before the migration
2802 * starts.
2804 migrate_qmp_fail(from, args->connect_uri, args->connect_channels, "{}");
2805 test_migrate_end(from, to, false);
2808 static void test_validate_uri_channels_both_set(void)
2810 MigrateCommon args = {
2811 .start = {
2812 .hide_stderr = true,
2814 .listen_uri = "defer",
2815 .connect_uri = "tcp:127.0.0.1:0",
2816 .connect_channels = "[ { 'channel-type': 'main',"
2817 " 'addr': { 'transport': 'socket',"
2818 " 'type': 'inet',"
2819 " 'host': '127.0.0.1',"
2820 " 'port': '0' } } ]",
2823 do_test_validate_uri_channel(&args);
2826 static void test_validate_uri_channels_none_set(void)
2828 MigrateCommon args = {
2829 .start = {
2830 .hide_stderr = true,
2832 .listen_uri = "defer",
2835 do_test_validate_uri_channel(&args);
2839 * The way auto_converge works, we need to do too many passes to
2840 * run this test. Auto_converge logic is only run once every
2841 * three iterations, so:
2843 * - 3 iterations without auto_converge enabled
2844 * - 3 iterations with pct = 5
2845 * - 3 iterations with pct = 30
2846 * - 3 iterations with pct = 55
2847 * - 3 iterations with pct = 80
2848 * - 3 iterations with pct = 95 (max(95, 80 + 25))
2850 * To make things even worse, we need to run the initial stage at
2851 * 3MB/s so we enter autoconverge even when host is (over)loaded.
2853 static void test_migrate_auto_converge(void)
2855 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2856 MigrateStart args = {};
2857 QTestState *from, *to;
2858 int64_t percentage;
2861 * We want the test to be stable and as fast as possible.
2862 * E.g., with 1Gb/s bandwidth migration may pass without throttling,
2863 * so we need to decrease a bandwidth.
2865 const int64_t init_pct = 5, inc_pct = 25, max_pct = 95;
2867 if (test_migrate_start(&from, &to, uri, &args)) {
2868 return;
2871 migrate_set_capability(from, "auto-converge", true);
2872 migrate_set_parameter_int(from, "cpu-throttle-initial", init_pct);
2873 migrate_set_parameter_int(from, "cpu-throttle-increment", inc_pct);
2874 migrate_set_parameter_int(from, "max-cpu-throttle", max_pct);
2877 * Set the initial parameters so that the migration could not converge
2878 * without throttling.
2880 migrate_ensure_non_converge(from);
2882 /* To check remaining size after precopy */
2883 migrate_set_capability(from, "pause-before-switchover", true);
2885 /* Wait for the first serial output from the source */
2886 wait_for_serial("src_serial");
2888 migrate_qmp(from, to, uri, NULL, "{}");
2890 /* Wait for throttling begins */
2891 percentage = 0;
2892 do {
2893 percentage = read_migrate_property_int(from, "cpu-throttle-percentage");
2894 if (percentage != 0) {
2895 break;
2897 usleep(20);
2898 g_assert_false(src_state.stop_seen);
2899 } while (true);
2900 /* The first percentage of throttling should be at least init_pct */
2901 g_assert_cmpint(percentage, >=, init_pct);
2902 /* Now, when we tested that throttling works, let it converge */
2903 migrate_ensure_converge(from);
2906 * Wait for pre-switchover status to check last throttle percentage
2907 * and remaining. These values will be zeroed later
2909 wait_for_migration_status(from, "pre-switchover", NULL);
2911 /* The final percentage of throttling shouldn't be greater than max_pct */
2912 percentage = read_migrate_property_int(from, "cpu-throttle-percentage");
2913 g_assert_cmpint(percentage, <=, max_pct);
2914 migrate_continue(from, "pre-switchover");
2916 qtest_qmp_eventwait(to, "RESUME");
2918 wait_for_serial("dest_serial");
2919 wait_for_migration_complete(from);
2921 test_migrate_end(from, to, true);
2924 static void *
2925 test_migrate_precopy_tcp_multifd_start_common(QTestState *from,
2926 QTestState *to,
2927 const char *method)
2929 migrate_set_parameter_int(from, "multifd-channels", 16);
2930 migrate_set_parameter_int(to, "multifd-channels", 16);
2932 migrate_set_parameter_str(from, "multifd-compression", method);
2933 migrate_set_parameter_str(to, "multifd-compression", method);
2935 migrate_set_capability(from, "multifd", true);
2936 migrate_set_capability(to, "multifd", true);
2938 /* Start incoming migration from the 1st socket */
2939 migrate_incoming_qmp(to, "tcp:127.0.0.1:0", "{}");
2941 return NULL;
2944 static void *
2945 test_migrate_precopy_tcp_multifd_start(QTestState *from,
2946 QTestState *to)
2948 return test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
2951 static void *
2952 test_migrate_precopy_tcp_multifd_start_zero_page_legacy(QTestState *from,
2953 QTestState *to)
2955 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
2956 migrate_set_parameter_str(from, "zero-page-detection", "legacy");
2957 return NULL;
2960 static void *
2961 test_migration_precopy_tcp_multifd_start_no_zero_page(QTestState *from,
2962 QTestState *to)
2964 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
2965 migrate_set_parameter_str(from, "zero-page-detection", "none");
2966 return NULL;
2969 static void *
2970 test_migrate_precopy_tcp_multifd_zlib_start(QTestState *from,
2971 QTestState *to)
2974 * Overloading this test to also check that set_parameter does not error.
2975 * This is also done in the tests for the other compression methods.
2977 migrate_set_parameter_int(from, "multifd-zlib-level", 2);
2978 migrate_set_parameter_int(to, "multifd-zlib-level", 2);
2980 return test_migrate_precopy_tcp_multifd_start_common(from, to, "zlib");
2983 #ifdef CONFIG_ZSTD
2984 static void *
2985 test_migrate_precopy_tcp_multifd_zstd_start(QTestState *from,
2986 QTestState *to)
2988 migrate_set_parameter_int(from, "multifd-zstd-level", 2);
2989 migrate_set_parameter_int(to, "multifd-zstd-level", 2);
2991 return test_migrate_precopy_tcp_multifd_start_common(from, to, "zstd");
2993 #endif /* CONFIG_ZSTD */
2995 #ifdef CONFIG_QPL
2996 static void *
2997 test_migrate_precopy_tcp_multifd_qpl_start(QTestState *from,
2998 QTestState *to)
3000 return test_migrate_precopy_tcp_multifd_start_common(from, to, "qpl");
3002 #endif /* CONFIG_QPL */
3003 #ifdef CONFIG_UADK
3004 static void *
3005 test_migrate_precopy_tcp_multifd_uadk_start(QTestState *from,
3006 QTestState *to)
3008 return test_migrate_precopy_tcp_multifd_start_common(from, to, "uadk");
3010 #endif /* CONFIG_UADK */
3012 static void test_multifd_tcp_uri_none(void)
3014 MigrateCommon args = {
3015 .listen_uri = "defer",
3016 .start_hook = test_migrate_precopy_tcp_multifd_start,
3018 * Multifd is more complicated than most of the features, it
3019 * directly takes guest page buffers when sending, make sure
3020 * everything will work alright even if guest page is changing.
3022 .live = true,
3024 test_precopy_common(&args);
3027 static void test_multifd_tcp_zero_page_legacy(void)
3029 MigrateCommon args = {
3030 .listen_uri = "defer",
3031 .start_hook = test_migrate_precopy_tcp_multifd_start_zero_page_legacy,
3033 * Multifd is more complicated than most of the features, it
3034 * directly takes guest page buffers when sending, make sure
3035 * everything will work alright even if guest page is changing.
3037 .live = true,
3039 test_precopy_common(&args);
3042 static void test_multifd_tcp_no_zero_page(void)
3044 MigrateCommon args = {
3045 .listen_uri = "defer",
3046 .start_hook = test_migration_precopy_tcp_multifd_start_no_zero_page,
3048 * Multifd is more complicated than most of the features, it
3049 * directly takes guest page buffers when sending, make sure
3050 * everything will work alright even if guest page is changing.
3052 .live = true,
3054 test_precopy_common(&args);
3057 static void test_multifd_tcp_channels_none(void)
3059 MigrateCommon args = {
3060 .listen_uri = "defer",
3061 .start_hook = test_migrate_precopy_tcp_multifd_start,
3062 .live = true,
3063 .connect_channels = "[ { 'channel-type': 'main',"
3064 " 'addr': { 'transport': 'socket',"
3065 " 'type': 'inet',"
3066 " 'host': '127.0.0.1',"
3067 " 'port': '0' } } ]",
3069 test_precopy_common(&args);
3072 static void test_multifd_tcp_zlib(void)
3074 MigrateCommon args = {
3075 .listen_uri = "defer",
3076 .start_hook = test_migrate_precopy_tcp_multifd_zlib_start,
3078 test_precopy_common(&args);
3081 #ifdef CONFIG_ZSTD
3082 static void test_multifd_tcp_zstd(void)
3084 MigrateCommon args = {
3085 .listen_uri = "defer",
3086 .start_hook = test_migrate_precopy_tcp_multifd_zstd_start,
3088 test_precopy_common(&args);
3090 #endif
3092 #ifdef CONFIG_QPL
3093 static void test_multifd_tcp_qpl(void)
3095 MigrateCommon args = {
3096 .listen_uri = "defer",
3097 .start_hook = test_migrate_precopy_tcp_multifd_qpl_start,
3099 test_precopy_common(&args);
3101 #endif
3103 #ifdef CONFIG_UADK
3104 static void test_multifd_tcp_uadk(void)
3106 MigrateCommon args = {
3107 .listen_uri = "defer",
3108 .start_hook = test_migrate_precopy_tcp_multifd_uadk_start,
3110 test_precopy_common(&args);
3112 #endif
3114 #ifdef CONFIG_GNUTLS
3115 static void *
3116 test_migrate_multifd_tcp_tls_psk_start_match(QTestState *from,
3117 QTestState *to)
3119 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3120 return test_migrate_tls_psk_start_match(from, to);
3123 static void *
3124 test_migrate_multifd_tcp_tls_psk_start_mismatch(QTestState *from,
3125 QTestState *to)
3127 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3128 return test_migrate_tls_psk_start_mismatch(from, to);
3131 #ifdef CONFIG_TASN1
3132 static void *
3133 test_migrate_multifd_tls_x509_start_default_host(QTestState *from,
3134 QTestState *to)
3136 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3137 return test_migrate_tls_x509_start_default_host(from, to);
3140 static void *
3141 test_migrate_multifd_tls_x509_start_override_host(QTestState *from,
3142 QTestState *to)
3144 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3145 return test_migrate_tls_x509_start_override_host(from, to);
3148 static void *
3149 test_migrate_multifd_tls_x509_start_mismatch_host(QTestState *from,
3150 QTestState *to)
3152 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3153 return test_migrate_tls_x509_start_mismatch_host(from, to);
3156 static void *
3157 test_migrate_multifd_tls_x509_start_allow_anon_client(QTestState *from,
3158 QTestState *to)
3160 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3161 return test_migrate_tls_x509_start_allow_anon_client(from, to);
3164 static void *
3165 test_migrate_multifd_tls_x509_start_reject_anon_client(QTestState *from,
3166 QTestState *to)
3168 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3169 return test_migrate_tls_x509_start_reject_anon_client(from, to);
3171 #endif /* CONFIG_TASN1 */
3173 static void test_multifd_tcp_tls_psk_match(void)
3175 MigrateCommon args = {
3176 .listen_uri = "defer",
3177 .start_hook = test_migrate_multifd_tcp_tls_psk_start_match,
3178 .finish_hook = test_migrate_tls_psk_finish,
3180 test_precopy_common(&args);
3183 static void test_multifd_tcp_tls_psk_mismatch(void)
3185 MigrateCommon args = {
3186 .start = {
3187 .hide_stderr = true,
3189 .listen_uri = "defer",
3190 .start_hook = test_migrate_multifd_tcp_tls_psk_start_mismatch,
3191 .finish_hook = test_migrate_tls_psk_finish,
3192 .result = MIG_TEST_FAIL,
3194 test_precopy_common(&args);
3197 #ifdef CONFIG_TASN1
3198 static void test_multifd_tcp_tls_x509_default_host(void)
3200 MigrateCommon args = {
3201 .listen_uri = "defer",
3202 .start_hook = test_migrate_multifd_tls_x509_start_default_host,
3203 .finish_hook = test_migrate_tls_x509_finish,
3205 test_precopy_common(&args);
3208 static void test_multifd_tcp_tls_x509_override_host(void)
3210 MigrateCommon args = {
3211 .listen_uri = "defer",
3212 .start_hook = test_migrate_multifd_tls_x509_start_override_host,
3213 .finish_hook = test_migrate_tls_x509_finish,
3215 test_precopy_common(&args);
3218 static void test_multifd_tcp_tls_x509_mismatch_host(void)
3221 * This has different behaviour to the non-multifd case.
3223 * In non-multifd case when client aborts due to mismatched
3224 * cert host, the server has already started trying to load
3225 * migration state, and so it exits with I/O failure.
3227 * In multifd case when client aborts due to mismatched
3228 * cert host, the server is still waiting for the other
3229 * multifd connections to arrive so hasn't started trying
3230 * to load migration state, and thus just aborts the migration
3231 * without exiting.
3233 MigrateCommon args = {
3234 .start = {
3235 .hide_stderr = true,
3237 .listen_uri = "defer",
3238 .start_hook = test_migrate_multifd_tls_x509_start_mismatch_host,
3239 .finish_hook = test_migrate_tls_x509_finish,
3240 .result = MIG_TEST_FAIL,
3242 test_precopy_common(&args);
3245 static void test_multifd_tcp_tls_x509_allow_anon_client(void)
3247 MigrateCommon args = {
3248 .listen_uri = "defer",
3249 .start_hook = test_migrate_multifd_tls_x509_start_allow_anon_client,
3250 .finish_hook = test_migrate_tls_x509_finish,
3252 test_precopy_common(&args);
3255 static void test_multifd_tcp_tls_x509_reject_anon_client(void)
3257 MigrateCommon args = {
3258 .start = {
3259 .hide_stderr = true,
3261 .listen_uri = "defer",
3262 .start_hook = test_migrate_multifd_tls_x509_start_reject_anon_client,
3263 .finish_hook = test_migrate_tls_x509_finish,
3264 .result = MIG_TEST_FAIL,
3266 test_precopy_common(&args);
3268 #endif /* CONFIG_TASN1 */
3269 #endif /* CONFIG_GNUTLS */
3272 * This test does:
3273 * source target
3274 * migrate_incoming
3275 * migrate
3276 * migrate_cancel
3277 * launch another target
3278 * migrate
3280 * And see that it works
3282 static void test_multifd_tcp_cancel(void)
3284 MigrateStart args = {
3285 .hide_stderr = true,
3287 QTestState *from, *to, *to2;
3289 if (test_migrate_start(&from, &to, "defer", &args)) {
3290 return;
3293 migrate_ensure_non_converge(from);
3294 migrate_prepare_for_dirty_mem(from);
3296 migrate_set_parameter_int(from, "multifd-channels", 16);
3297 migrate_set_parameter_int(to, "multifd-channels", 16);
3299 migrate_set_capability(from, "multifd", true);
3300 migrate_set_capability(to, "multifd", true);
3302 /* Start incoming migration from the 1st socket */
3303 migrate_incoming_qmp(to, "tcp:127.0.0.1:0", "{}");
3305 /* Wait for the first serial output from the source */
3306 wait_for_serial("src_serial");
3308 migrate_qmp(from, to, NULL, NULL, "{}");
3310 migrate_wait_for_dirty_mem(from, to);
3312 migrate_cancel(from);
3314 /* Make sure QEMU process "to" exited */
3315 qtest_set_expected_status(to, EXIT_FAILURE);
3316 qtest_wait_qemu(to);
3318 args = (MigrateStart){
3319 .only_target = true,
3322 if (test_migrate_start(&from, &to2, "defer", &args)) {
3323 return;
3326 migrate_set_parameter_int(to2, "multifd-channels", 16);
3328 migrate_set_capability(to2, "multifd", true);
3330 /* Start incoming migration from the 1st socket */
3331 migrate_incoming_qmp(to2, "tcp:127.0.0.1:0", "{}");
3333 wait_for_migration_status(from, "cancelled", NULL);
3335 migrate_ensure_non_converge(from);
3337 migrate_qmp(from, to2, NULL, NULL, "{}");
3339 migrate_wait_for_dirty_mem(from, to2);
3341 migrate_ensure_converge(from);
3343 wait_for_stop(from, &src_state);
3344 qtest_qmp_eventwait(to2, "RESUME");
3346 wait_for_serial("dest_serial");
3347 wait_for_migration_complete(from);
3348 test_migrate_end(from, to2, true);
3351 static void calc_dirty_rate(QTestState *who, uint64_t calc_time)
3353 qtest_qmp_assert_success(who,
3354 "{ 'execute': 'calc-dirty-rate',"
3355 "'arguments': { "
3356 "'calc-time': %" PRIu64 ","
3357 "'mode': 'dirty-ring' }}",
3358 calc_time);
3361 static QDict *query_dirty_rate(QTestState *who)
3363 return qtest_qmp_assert_success_ref(who,
3364 "{ 'execute': 'query-dirty-rate' }");
3367 static void dirtylimit_set_all(QTestState *who, uint64_t dirtyrate)
3369 qtest_qmp_assert_success(who,
3370 "{ 'execute': 'set-vcpu-dirty-limit',"
3371 "'arguments': { "
3372 "'dirty-rate': %" PRIu64 " } }",
3373 dirtyrate);
3376 static void cancel_vcpu_dirty_limit(QTestState *who)
3378 qtest_qmp_assert_success(who,
3379 "{ 'execute': 'cancel-vcpu-dirty-limit' }");
3382 static QDict *query_vcpu_dirty_limit(QTestState *who)
3384 QDict *rsp;
3386 rsp = qtest_qmp(who, "{ 'execute': 'query-vcpu-dirty-limit' }");
3387 g_assert(!qdict_haskey(rsp, "error"));
3388 g_assert(qdict_haskey(rsp, "return"));
3390 return rsp;
3393 static bool calc_dirtyrate_ready(QTestState *who)
3395 QDict *rsp_return;
3396 gchar *status;
3398 rsp_return = query_dirty_rate(who);
3399 g_assert(rsp_return);
3401 status = g_strdup(qdict_get_str(rsp_return, "status"));
3402 g_assert(status);
3404 return g_strcmp0(status, "measuring");
3407 static void wait_for_calc_dirtyrate_complete(QTestState *who,
3408 int64_t time_s)
3410 int max_try_count = 10000;
3411 usleep(time_s * 1000000);
3413 while (!calc_dirtyrate_ready(who) && max_try_count--) {
3414 usleep(1000);
3418 * Set the timeout with 10 s(max_try_count * 1000us),
3419 * if dirtyrate measurement not complete, fail test.
3421 g_assert_cmpint(max_try_count, !=, 0);
3424 static int64_t get_dirty_rate(QTestState *who)
3426 QDict *rsp_return;
3427 gchar *status;
3428 QList *rates;
3429 const QListEntry *entry;
3430 QDict *rate;
3431 int64_t dirtyrate;
3433 rsp_return = query_dirty_rate(who);
3434 g_assert(rsp_return);
3436 status = g_strdup(qdict_get_str(rsp_return, "status"));
3437 g_assert(status);
3438 g_assert_cmpstr(status, ==, "measured");
3440 rates = qdict_get_qlist(rsp_return, "vcpu-dirty-rate");
3441 g_assert(rates && !qlist_empty(rates));
3443 entry = qlist_first(rates);
3444 g_assert(entry);
3446 rate = qobject_to(QDict, qlist_entry_obj(entry));
3447 g_assert(rate);
3449 dirtyrate = qdict_get_try_int(rate, "dirty-rate", -1);
3451 qobject_unref(rsp_return);
3452 return dirtyrate;
3455 static int64_t get_limit_rate(QTestState *who)
3457 QDict *rsp_return;
3458 QList *rates;
3459 const QListEntry *entry;
3460 QDict *rate;
3461 int64_t dirtyrate;
3463 rsp_return = query_vcpu_dirty_limit(who);
3464 g_assert(rsp_return);
3466 rates = qdict_get_qlist(rsp_return, "return");
3467 g_assert(rates && !qlist_empty(rates));
3469 entry = qlist_first(rates);
3470 g_assert(entry);
3472 rate = qobject_to(QDict, qlist_entry_obj(entry));
3473 g_assert(rate);
3475 dirtyrate = qdict_get_try_int(rate, "limit-rate", -1);
3477 qobject_unref(rsp_return);
3478 return dirtyrate;
3481 static QTestState *dirtylimit_start_vm(void)
3483 QTestState *vm = NULL;
3484 g_autofree gchar *cmd = NULL;
3486 bootfile_create(tmpfs, false);
3487 cmd = g_strdup_printf("-accel kvm,dirty-ring-size=4096 "
3488 "-name dirtylimit-test,debug-threads=on "
3489 "-m 150M -smp 1 "
3490 "-serial file:%s/vm_serial "
3491 "-drive file=%s,format=raw ",
3492 tmpfs, bootpath);
3494 vm = qtest_init(cmd);
3495 return vm;
3498 static void dirtylimit_stop_vm(QTestState *vm)
3500 qtest_quit(vm);
3501 cleanup("vm_serial");
3504 static void test_vcpu_dirty_limit(void)
3506 QTestState *vm;
3507 int64_t origin_rate;
3508 int64_t quota_rate;
3509 int64_t rate ;
3510 int max_try_count = 20;
3511 int hit = 0;
3513 /* Start vm for vcpu dirtylimit test */
3514 vm = dirtylimit_start_vm();
3516 /* Wait for the first serial output from the vm*/
3517 wait_for_serial("vm_serial");
3519 /* Do dirtyrate measurement with calc time equals 1s */
3520 calc_dirty_rate(vm, 1);
3522 /* Sleep calc time and wait for calc dirtyrate complete */
3523 wait_for_calc_dirtyrate_complete(vm, 1);
3525 /* Query original dirty page rate */
3526 origin_rate = get_dirty_rate(vm);
3528 /* VM booted from bootsect should dirty memory steadily */
3529 assert(origin_rate != 0);
3531 /* Setup quota dirty page rate at half of origin */
3532 quota_rate = origin_rate / 2;
3534 /* Set dirtylimit */
3535 dirtylimit_set_all(vm, quota_rate);
3538 * Check if set-vcpu-dirty-limit and query-vcpu-dirty-limit
3539 * works literally
3541 g_assert_cmpint(quota_rate, ==, get_limit_rate(vm));
3543 /* Sleep a bit to check if it take effect */
3544 usleep(2000000);
3547 * Check if dirtylimit take effect realistically, set the
3548 * timeout with 20 s(max_try_count * 1s), if dirtylimit
3549 * doesn't take effect, fail test.
3551 while (--max_try_count) {
3552 calc_dirty_rate(vm, 1);
3553 wait_for_calc_dirtyrate_complete(vm, 1);
3554 rate = get_dirty_rate(vm);
3557 * Assume hitting if current rate is less
3558 * than quota rate (within accepting error)
3560 if (rate < (quota_rate + DIRTYLIMIT_TOLERANCE_RANGE)) {
3561 hit = 1;
3562 break;
3566 g_assert_cmpint(hit, ==, 1);
3568 hit = 0;
3569 max_try_count = 20;
3571 /* Check if dirtylimit cancellation take effect */
3572 cancel_vcpu_dirty_limit(vm);
3573 while (--max_try_count) {
3574 calc_dirty_rate(vm, 1);
3575 wait_for_calc_dirtyrate_complete(vm, 1);
3576 rate = get_dirty_rate(vm);
3579 * Assume dirtylimit be canceled if current rate is
3580 * greater than quota rate (within accepting error)
3582 if (rate > (quota_rate + DIRTYLIMIT_TOLERANCE_RANGE)) {
3583 hit = 1;
3584 break;
3588 g_assert_cmpint(hit, ==, 1);
3589 dirtylimit_stop_vm(vm);
3592 static void migrate_dirty_limit_wait_showup(QTestState *from,
3593 const int64_t period,
3594 const int64_t value)
3596 /* Enable dirty limit capability */
3597 migrate_set_capability(from, "dirty-limit", true);
3599 /* Set dirty limit parameters */
3600 migrate_set_parameter_int(from, "x-vcpu-dirty-limit-period", period);
3601 migrate_set_parameter_int(from, "vcpu-dirty-limit", value);
3603 /* Make sure migrate can't converge */
3604 migrate_ensure_non_converge(from);
3606 /* To check limit rate after precopy */
3607 migrate_set_capability(from, "pause-before-switchover", true);
3609 /* Wait for the serial output from the source */
3610 wait_for_serial("src_serial");
3614 * This test does:
3615 * source destination
3616 * start vm
3617 * start incoming vm
3618 * migrate
3619 * wait dirty limit to begin
3620 * cancel migrate
3621 * cancellation check
3622 * restart incoming vm
3623 * migrate
3624 * wait dirty limit to begin
3625 * wait pre-switchover event
3626 * convergence condition check
3628 * And see if dirty limit migration works correctly.
3629 * This test case involves many passes, so it runs in slow mode only.
3631 static void test_migrate_dirty_limit(void)
3633 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
3634 QTestState *from, *to;
3635 int64_t remaining;
3636 uint64_t throttle_us_per_full;
3638 * We want the test to be stable and as fast as possible.
3639 * E.g., with 1Gb/s bandwidth migration may pass without dirty limit,
3640 * so we need to decrease a bandwidth.
3642 const int64_t dirtylimit_period = 1000, dirtylimit_value = 50;
3643 const int64_t max_bandwidth = 400000000; /* ~400Mb/s */
3644 const int64_t downtime_limit = 250; /* 250ms */
3646 * We migrate through unix-socket (> 500Mb/s).
3647 * Thus, expected migration speed ~= bandwidth limit (< 500Mb/s).
3648 * So, we can predict expected_threshold
3650 const int64_t expected_threshold = max_bandwidth * downtime_limit / 1000;
3651 int max_try_count = 10;
3652 MigrateCommon args = {
3653 .start = {
3654 .hide_stderr = true,
3655 .use_dirty_ring = true,
3657 .listen_uri = uri,
3658 .connect_uri = uri,
3661 /* Start src, dst vm */
3662 if (test_migrate_start(&from, &to, args.listen_uri, &args.start)) {
3663 return;
3666 /* Prepare for dirty limit migration and wait src vm show up */
3667 migrate_dirty_limit_wait_showup(from, dirtylimit_period, dirtylimit_value);
3669 /* Start migrate */
3670 migrate_qmp(from, to, args.connect_uri, NULL, "{}");
3672 /* Wait for dirty limit throttle begin */
3673 throttle_us_per_full = 0;
3674 while (throttle_us_per_full == 0) {
3675 throttle_us_per_full =
3676 read_migrate_property_int(from, "dirty-limit-throttle-time-per-round");
3677 usleep(100);
3678 g_assert_false(src_state.stop_seen);
3681 /* Now cancel migrate and wait for dirty limit throttle switch off */
3682 migrate_cancel(from);
3683 wait_for_migration_status(from, "cancelled", NULL);
3685 /* Check if dirty limit throttle switched off, set timeout 1ms */
3686 do {
3687 throttle_us_per_full =
3688 read_migrate_property_int(from, "dirty-limit-throttle-time-per-round");
3689 usleep(100);
3690 g_assert_false(src_state.stop_seen);
3691 } while (throttle_us_per_full != 0 && --max_try_count);
3693 /* Assert dirty limit is not in service */
3694 g_assert_cmpint(throttle_us_per_full, ==, 0);
3696 args = (MigrateCommon) {
3697 .start = {
3698 .only_target = true,
3699 .use_dirty_ring = true,
3701 .listen_uri = uri,
3702 .connect_uri = uri,
3705 /* Restart dst vm, src vm already show up so we needn't wait anymore */
3706 if (test_migrate_start(&from, &to, args.listen_uri, &args.start)) {
3707 return;
3710 /* Start migrate */
3711 migrate_qmp(from, to, args.connect_uri, NULL, "{}");
3713 /* Wait for dirty limit throttle begin */
3714 throttle_us_per_full = 0;
3715 while (throttle_us_per_full == 0) {
3716 throttle_us_per_full =
3717 read_migrate_property_int(from, "dirty-limit-throttle-time-per-round");
3718 usleep(100);
3719 g_assert_false(src_state.stop_seen);
3723 * The dirty limit rate should equals the return value of
3724 * query-vcpu-dirty-limit if dirty limit cap set
3726 g_assert_cmpint(dirtylimit_value, ==, get_limit_rate(from));
3728 /* Now, we have tested if dirty limit works, let it converge */
3729 migrate_set_parameter_int(from, "downtime-limit", downtime_limit);
3730 migrate_set_parameter_int(from, "max-bandwidth", max_bandwidth);
3733 * Wait for pre-switchover status to check if migration
3734 * satisfy the convergence condition
3736 wait_for_migration_status(from, "pre-switchover", NULL);
3738 remaining = read_ram_property_int(from, "remaining");
3739 g_assert_cmpint(remaining, <,
3740 (expected_threshold + expected_threshold / 100));
3742 migrate_continue(from, "pre-switchover");
3744 qtest_qmp_eventwait(to, "RESUME");
3746 wait_for_serial("dest_serial");
3747 wait_for_migration_complete(from);
3749 test_migrate_end(from, to, true);
3752 static bool kvm_dirty_ring_supported(void)
3754 #if defined(__linux__) && defined(HOST_X86_64)
3755 int ret, kvm_fd = open("/dev/kvm", O_RDONLY);
3757 if (kvm_fd < 0) {
3758 return false;
3761 ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, KVM_CAP_DIRTY_LOG_RING);
3762 close(kvm_fd);
3764 /* We test with 4096 slots */
3765 if (ret < 4096) {
3766 return false;
3769 return true;
3770 #else
3771 return false;
3772 #endif
3775 int main(int argc, char **argv)
3777 bool has_kvm, has_tcg;
3778 bool has_uffd, is_x86;
3779 const char *arch;
3780 g_autoptr(GError) err = NULL;
3781 const char *qemu_src = getenv(QEMU_ENV_SRC);
3782 const char *qemu_dst = getenv(QEMU_ENV_DST);
3783 int ret;
3785 g_test_init(&argc, &argv, NULL);
3788 * The default QTEST_QEMU_BINARY must always be provided because
3789 * that is what helpers use to query the accel type and
3790 * architecture.
3792 if (qemu_src && qemu_dst) {
3793 g_test_message("Only one of %s, %s is allowed",
3794 QEMU_ENV_SRC, QEMU_ENV_DST);
3795 exit(1);
3798 has_kvm = qtest_has_accel("kvm");
3799 has_tcg = qtest_has_accel("tcg");
3801 if (!has_tcg && !has_kvm) {
3802 g_test_skip("No KVM or TCG accelerator available");
3803 return 0;
3806 has_uffd = ufd_version_check();
3807 arch = qtest_get_arch();
3808 is_x86 = !strcmp(arch, "i386") || !strcmp(arch, "x86_64");
3810 tmpfs = g_dir_make_tmp("migration-test-XXXXXX", &err);
3811 if (!tmpfs) {
3812 g_test_message("Can't create temporary directory in %s: %s",
3813 g_get_tmp_dir(), err->message);
3815 g_assert(tmpfs);
3817 module_call_init(MODULE_INIT_QOM);
3819 migration_test_add("/migration/bad_dest", test_baddest);
3820 #ifndef _WIN32
3821 migration_test_add("/migration/analyze-script", test_analyze_script);
3822 migration_test_add("/migration/vmstate-checker-script",
3823 test_vmstate_checker_script);
3824 #endif
3826 if (is_x86) {
3827 migration_test_add("/migration/precopy/unix/suspend/live",
3828 test_precopy_unix_suspend_live);
3829 migration_test_add("/migration/precopy/unix/suspend/notlive",
3830 test_precopy_unix_suspend_notlive);
3833 if (has_uffd) {
3834 migration_test_add("/migration/postcopy/plain", test_postcopy);
3835 migration_test_add("/migration/postcopy/recovery/plain",
3836 test_postcopy_recovery);
3837 migration_test_add("/migration/postcopy/preempt/plain",
3838 test_postcopy_preempt);
3839 migration_test_add("/migration/postcopy/preempt/recovery/plain",
3840 test_postcopy_preempt_recovery);
3841 migration_test_add("/migration/postcopy/recovery/double-failures/handshake",
3842 test_postcopy_recovery_fail_handshake);
3843 migration_test_add("/migration/postcopy/recovery/double-failures/reconnect",
3844 test_postcopy_recovery_fail_reconnect);
3845 if (is_x86) {
3846 migration_test_add("/migration/postcopy/suspend",
3847 test_postcopy_suspend);
3851 migration_test_add("/migration/precopy/unix/plain",
3852 test_precopy_unix_plain);
3853 migration_test_add("/migration/precopy/unix/xbzrle",
3854 test_precopy_unix_xbzrle);
3855 migration_test_add("/migration/precopy/file",
3856 test_precopy_file);
3857 migration_test_add("/migration/precopy/file/offset",
3858 test_precopy_file_offset);
3859 #ifndef _WIN32
3860 migration_test_add("/migration/precopy/file/offset/fdset",
3861 test_precopy_file_offset_fdset);
3862 #endif
3863 migration_test_add("/migration/precopy/file/offset/bad",
3864 test_precopy_file_offset_bad);
3867 * Our CI system has problems with shared memory.
3868 * Don't run this test until we find a workaround.
3870 if (getenv("QEMU_TEST_FLAKY_TESTS")) {
3871 migration_test_add("/migration/mode/reboot", test_mode_reboot);
3874 migration_test_add("/migration/precopy/file/mapped-ram",
3875 test_precopy_file_mapped_ram);
3876 migration_test_add("/migration/precopy/file/mapped-ram/live",
3877 test_precopy_file_mapped_ram_live);
3879 migration_test_add("/migration/multifd/file/mapped-ram",
3880 test_multifd_file_mapped_ram);
3881 migration_test_add("/migration/multifd/file/mapped-ram/live",
3882 test_multifd_file_mapped_ram_live);
3884 migration_test_add("/migration/multifd/file/mapped-ram/dio",
3885 test_multifd_file_mapped_ram_dio);
3887 #ifndef _WIN32
3888 migration_test_add("/migration/multifd/file/mapped-ram/fdset",
3889 test_multifd_file_mapped_ram_fdset);
3890 migration_test_add("/migration/multifd/file/mapped-ram/fdset/dio",
3891 test_multifd_file_mapped_ram_fdset_dio);
3892 #endif
3894 #ifdef CONFIG_GNUTLS
3895 migration_test_add("/migration/precopy/unix/tls/psk",
3896 test_precopy_unix_tls_psk);
3898 if (has_uffd) {
3900 * NOTE: psk test is enough for postcopy, as other types of TLS
3901 * channels are tested under precopy. Here what we want to test is the
3902 * general postcopy path that has TLS channel enabled.
3904 migration_test_add("/migration/postcopy/tls/psk",
3905 test_postcopy_tls_psk);
3906 migration_test_add("/migration/postcopy/recovery/tls/psk",
3907 test_postcopy_recovery_tls_psk);
3908 migration_test_add("/migration/postcopy/preempt/tls/psk",
3909 test_postcopy_preempt_tls_psk);
3910 migration_test_add("/migration/postcopy/preempt/recovery/tls/psk",
3911 test_postcopy_preempt_all);
3913 #ifdef CONFIG_TASN1
3914 migration_test_add("/migration/precopy/unix/tls/x509/default-host",
3915 test_precopy_unix_tls_x509_default_host);
3916 migration_test_add("/migration/precopy/unix/tls/x509/override-host",
3917 test_precopy_unix_tls_x509_override_host);
3918 #endif /* CONFIG_TASN1 */
3919 #endif /* CONFIG_GNUTLS */
3921 migration_test_add("/migration/precopy/tcp/plain", test_precopy_tcp_plain);
3923 migration_test_add("/migration/precopy/tcp/plain/switchover-ack",
3924 test_precopy_tcp_switchover_ack);
3926 #ifdef CONFIG_GNUTLS
3927 migration_test_add("/migration/precopy/tcp/tls/psk/match",
3928 test_precopy_tcp_tls_psk_match);
3929 migration_test_add("/migration/precopy/tcp/tls/psk/mismatch",
3930 test_precopy_tcp_tls_psk_mismatch);
3931 #ifdef CONFIG_TASN1
3932 migration_test_add("/migration/precopy/tcp/tls/x509/default-host",
3933 test_precopy_tcp_tls_x509_default_host);
3934 migration_test_add("/migration/precopy/tcp/tls/x509/override-host",
3935 test_precopy_tcp_tls_x509_override_host);
3936 migration_test_add("/migration/precopy/tcp/tls/x509/mismatch-host",
3937 test_precopy_tcp_tls_x509_mismatch_host);
3938 migration_test_add("/migration/precopy/tcp/tls/x509/friendly-client",
3939 test_precopy_tcp_tls_x509_friendly_client);
3940 migration_test_add("/migration/precopy/tcp/tls/x509/hostile-client",
3941 test_precopy_tcp_tls_x509_hostile_client);
3942 migration_test_add("/migration/precopy/tcp/tls/x509/allow-anon-client",
3943 test_precopy_tcp_tls_x509_allow_anon_client);
3944 migration_test_add("/migration/precopy/tcp/tls/x509/reject-anon-client",
3945 test_precopy_tcp_tls_x509_reject_anon_client);
3946 #endif /* CONFIG_TASN1 */
3947 #endif /* CONFIG_GNUTLS */
3949 /* migration_test_add("/migration/ignore_shared", test_ignore_shared); */
3950 #ifndef _WIN32
3951 migration_test_add("/migration/precopy/fd/tcp",
3952 test_migrate_precopy_fd_socket);
3953 migration_test_add("/migration/precopy/fd/file",
3954 test_migrate_precopy_fd_file);
3955 #endif
3956 migration_test_add("/migration/validate_uuid", test_validate_uuid);
3957 migration_test_add("/migration/validate_uuid_error",
3958 test_validate_uuid_error);
3959 migration_test_add("/migration/validate_uuid_src_not_set",
3960 test_validate_uuid_src_not_set);
3961 migration_test_add("/migration/validate_uuid_dst_not_set",
3962 test_validate_uuid_dst_not_set);
3963 migration_test_add("/migration/validate_uri/channels/both_set",
3964 test_validate_uri_channels_both_set);
3965 migration_test_add("/migration/validate_uri/channels/none_set",
3966 test_validate_uri_channels_none_set);
3968 * See explanation why this test is slow on function definition
3970 if (g_test_slow()) {
3971 migration_test_add("/migration/auto_converge",
3972 test_migrate_auto_converge);
3973 if (g_str_equal(arch, "x86_64") &&
3974 has_kvm && kvm_dirty_ring_supported()) {
3975 migration_test_add("/migration/dirty_limit",
3976 test_migrate_dirty_limit);
3979 migration_test_add("/migration/multifd/tcp/uri/plain/none",
3980 test_multifd_tcp_uri_none);
3981 migration_test_add("/migration/multifd/tcp/channels/plain/none",
3982 test_multifd_tcp_channels_none);
3983 migration_test_add("/migration/multifd/tcp/plain/zero-page/legacy",
3984 test_multifd_tcp_zero_page_legacy);
3985 migration_test_add("/migration/multifd/tcp/plain/zero-page/none",
3986 test_multifd_tcp_no_zero_page);
3987 migration_test_add("/migration/multifd/tcp/plain/cancel",
3988 test_multifd_tcp_cancel);
3989 migration_test_add("/migration/multifd/tcp/plain/zlib",
3990 test_multifd_tcp_zlib);
3991 #ifdef CONFIG_ZSTD
3992 migration_test_add("/migration/multifd/tcp/plain/zstd",
3993 test_multifd_tcp_zstd);
3994 #endif
3995 #ifdef CONFIG_QPL
3996 migration_test_add("/migration/multifd/tcp/plain/qpl",
3997 test_multifd_tcp_qpl);
3998 #endif
3999 #ifdef CONFIG_UADK
4000 migration_test_add("/migration/multifd/tcp/plain/uadk",
4001 test_multifd_tcp_uadk);
4002 #endif
4003 #ifdef CONFIG_GNUTLS
4004 migration_test_add("/migration/multifd/tcp/tls/psk/match",
4005 test_multifd_tcp_tls_psk_match);
4006 migration_test_add("/migration/multifd/tcp/tls/psk/mismatch",
4007 test_multifd_tcp_tls_psk_mismatch);
4008 #ifdef CONFIG_TASN1
4009 migration_test_add("/migration/multifd/tcp/tls/x509/default-host",
4010 test_multifd_tcp_tls_x509_default_host);
4011 migration_test_add("/migration/multifd/tcp/tls/x509/override-host",
4012 test_multifd_tcp_tls_x509_override_host);
4013 migration_test_add("/migration/multifd/tcp/tls/x509/mismatch-host",
4014 test_multifd_tcp_tls_x509_mismatch_host);
4015 migration_test_add("/migration/multifd/tcp/tls/x509/allow-anon-client",
4016 test_multifd_tcp_tls_x509_allow_anon_client);
4017 migration_test_add("/migration/multifd/tcp/tls/x509/reject-anon-client",
4018 test_multifd_tcp_tls_x509_reject_anon_client);
4019 #endif /* CONFIG_TASN1 */
4020 #endif /* CONFIG_GNUTLS */
4022 if (g_str_equal(arch, "x86_64") && has_kvm && kvm_dirty_ring_supported()) {
4023 migration_test_add("/migration/dirty_ring",
4024 test_precopy_unix_dirty_ring);
4025 migration_test_add("/migration/vcpu_dirty_limit",
4026 test_vcpu_dirty_limit);
4029 ret = g_test_run();
4031 g_assert_cmpint(ret, ==, 0);
4033 bootfile_delete();
4034 ret = rmdir(tmpfs);
4035 if (ret != 0) {
4036 g_test_message("unable to rmdir: path (%s): %s",
4037 tmpfs, strerror(errno));
4039 g_free(tmpfs);
4041 return ret;