1 /*
2 * QTest testcase for migration
3 *
4 * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
5 * based on the vhost-user-test.c that is:
6 * Copyright (c) 2014 Virtual Open Systems Sarl.
7 *
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
10 *
11 */
12
13 #include "qemu/osdep.h"
14
15 #include "libqtest.h"
16 #include "qapi/qmp/qdict.h"
17 #include "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"
25
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 */
34
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
39
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;
45
46 /*
47 * An initial 3 MB offset is used as that corresponds
48 * to ~1 sec of data transfer with our bandwidth setting.
49 */
50 #define MAGIC_OFFSET_BASE (3 * 1024 * 1024)
51 /*
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.
55 */
56 #define MAGIC_OFFSET_SHUFFLE 1024
57 #define MAGIC_OFFSET (MAGIC_OFFSET_BASE + MAGIC_OFFSET_SHUFFLE)
58 #define MAGIC_MARKER 0xFEED12345678CAFEULL
59
60 /*
61 * Dirtylimit stop working if dirty page rate error
62 * value less than DIRTYLIMIT_TOLERANCE_RANGE
63 */
64 #define DIRTYLIMIT_TOLERANCE_RANGE 25 /* MB/s */
65
66 #define ANALYZE_SCRIPT "scripts/analyze-migration.py"
67 #define VMSTATE_CHECKER_SCRIPT "scripts/vmstate-static-checker.py"
68
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"
75
76 typedef enum PostcopyRecoveryFailStage {
77 /*
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.
80 */
81 POSTCOPY_FAIL_NONE = 0,
82 POSTCOPY_FAIL_CHANNEL_ESTABLISH,
83 POSTCOPY_FAIL_RECOVERY,
84 POSTCOPY_FAIL_MAX
85 } PostcopyRecoveryFailStage;
86
87 #if defined(__linux__)
88 #include <sys/syscall.h>
89 #include <sys/vfs.h>
90 #endif
91
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"
96
ufd_version_check(void)97 static bool ufd_version_check(void)
98 {
99 struct uffdio_api api_struct;
100 uint64_t ioctl_mask;
101
102 int ufd = uffd_open(O_CLOEXEC);
103
104 if (ufd == -1) {
105 g_test_message("Skipping test: userfaultfd not available");
106 return false;
107 }
108
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;
114 }
115 uffd_feature_thread_id = api_struct.features & UFFD_FEATURE_THREAD_ID;
116
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;
122 }
123
124 return true;
125 }
126
127 #else
ufd_version_check(void)128 static bool ufd_version_check(void)
129 {
130 g_test_message("Skipping test: Userfault not available (builtdtime)");
131 return false;
132 }
133
134 #endif
135
136 static char *tmpfs;
137 static char *bootpath;
138
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.
141 */
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"
146
bootfile_delete(void)147 static void bootfile_delete(void)
148 {
149 unlink(bootpath);
150 g_free(bootpath);
151 bootpath = NULL;
152 }
153
bootfile_create(char * dir,bool suspend_me)154 static void bootfile_create(char *dir, bool suspend_me)
155 {
156 const char *arch = qtest_get_arch();
157 unsigned char *content;
158 size_t len;
159
160 if (bootpath) {
161 bootfile_delete();
162 }
163
164 bootpath = g_strdup_printf("%s/bootsect", dir);
165 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
166 /* the assembled x86 boot sector should be exactly one sector large */
167 g_assert(sizeof(x86_bootsect) == 512);
168 x86_bootsect[SYM_suspend_me - SYM_start] = suspend_me;
169 content = x86_bootsect;
170 len = sizeof(x86_bootsect);
171 } else if (g_str_equal(arch, "s390x")) {
172 content = s390x_elf;
173 len = sizeof(s390x_elf);
174 } else if (strcmp(arch, "ppc64") == 0) {
175 content = ppc64_kernel;
176 len = sizeof(ppc64_kernel);
177 } else if (strcmp(arch, "aarch64") == 0) {
178 content = aarch64_kernel;
179 len = sizeof(aarch64_kernel);
180 g_assert(sizeof(aarch64_kernel) <= ARM_TEST_MAX_KERNEL_SIZE);
181 } else {
182 g_assert_not_reached();
183 }
184
185 FILE *bootfile = fopen(bootpath, "wb");
186
187 g_assert_cmpint(fwrite(content, len, 1, bootfile), ==, 1);
188 fclose(bootfile);
189 }
190
191 /*
192 * Wait for some output in the serial output file,
193 * we get an 'A' followed by an endless string of 'B's
194 * but on the destination we won't have the A (unless we enabled suspend/resume)
195 */
wait_for_serial(const char * side)196 static void wait_for_serial(const char *side)
197 {
198 g_autofree char *serialpath = g_strdup_printf("%s/%s", tmpfs, side);
199 FILE *serialfile = fopen(serialpath, "r");
200
201 do {
202 int readvalue = fgetc(serialfile);
203
204 switch (readvalue) {
205 case 'A':
206 /* Fine */
207 break;
208
209 case 'B':
210 /* It's alive! */
211 fclose(serialfile);
212 return;
213
214 case EOF:
215 fseek(serialfile, 0, SEEK_SET);
216 usleep(1000);
217 break;
218
219 default:
220 fprintf(stderr, "Unexpected %d on %s serial\n", readvalue, side);
221 g_assert_not_reached();
222 }
223 } while (true);
224 }
225
wait_for_stop(QTestState * who,QTestMigrationState * state)226 static void wait_for_stop(QTestState *who, QTestMigrationState *state)
227 {
228 if (!state->stop_seen) {
229 qtest_qmp_eventwait(who, "STOP");
230 }
231 }
232
wait_for_resume(QTestState * who,QTestMigrationState * state)233 static void wait_for_resume(QTestState *who, QTestMigrationState *state)
234 {
235 if (!state->resume_seen) {
236 qtest_qmp_eventwait(who, "RESUME");
237 }
238 }
239
wait_for_suspend(QTestState * who,QTestMigrationState * state)240 static void wait_for_suspend(QTestState *who, QTestMigrationState *state)
241 {
242 if (state->suspend_me && !state->suspend_seen) {
243 qtest_qmp_eventwait(who, "SUSPEND");
244 }
245 }
246
247 /*
248 * It's tricky to use qemu's migration event capability with qtest,
249 * events suddenly appearing confuse the qmp()/hmp() responses.
250 */
251
read_ram_property_int(QTestState * who,const char * property)252 static int64_t read_ram_property_int(QTestState *who, const char *property)
253 {
254 QDict *rsp_return, *rsp_ram;
255 int64_t result;
256
257 rsp_return = migrate_query_not_failed(who);
258 if (!qdict_haskey(rsp_return, "ram")) {
259 /* Still in setup */
260 result = 0;
261 } else {
262 rsp_ram = qdict_get_qdict(rsp_return, "ram");
263 result = qdict_get_try_int(rsp_ram, property, 0);
264 }
265 qobject_unref(rsp_return);
266 return result;
267 }
268
read_migrate_property_int(QTestState * who,const char * property)269 static int64_t read_migrate_property_int(QTestState *who, const char *property)
270 {
271 QDict *rsp_return;
272 int64_t result;
273
274 rsp_return = migrate_query_not_failed(who);
275 result = qdict_get_try_int(rsp_return, property, 0);
276 qobject_unref(rsp_return);
277 return result;
278 }
279
get_migration_pass(QTestState * who)280 static uint64_t get_migration_pass(QTestState *who)
281 {
282 return read_ram_property_int(who, "dirty-sync-count");
283 }
284
read_blocktime(QTestState * who)285 static void read_blocktime(QTestState *who)
286 {
287 QDict *rsp_return;
288
289 rsp_return = migrate_query_not_failed(who);
290 g_assert(qdict_haskey(rsp_return, "postcopy-blocktime"));
291 qobject_unref(rsp_return);
292 }
293
294 /*
295 * Wait for two changes in the migration pass count, but bail if we stop.
296 */
wait_for_migration_pass(QTestState * who)297 static void wait_for_migration_pass(QTestState *who)
298 {
299 uint64_t pass, prev_pass = 0, changes = 0;
300
301 while (changes < 2 && !src_state.stop_seen && !src_state.suspend_seen) {
302 usleep(1000);
303 pass = get_migration_pass(who);
304 changes += (pass != prev_pass);
305 prev_pass = pass;
306 }
307 }
308
check_guests_ram(QTestState * who)309 static void check_guests_ram(QTestState *who)
310 {
311 /* Our ASM test will have been incrementing one byte from each page from
312 * start_address to < end_address in order. This gives us a constraint
313 * that any page's byte should be equal or less than the previous pages
314 * byte (mod 256); and they should all be equal except for one transition
315 * at the point where we meet the incrementer. (We're running this with
316 * the guest stopped).
317 */
318 unsigned address;
319 uint8_t first_byte;
320 uint8_t last_byte;
321 bool hit_edge = false;
322 int bad = 0;
323
324 qtest_memread(who, start_address, &first_byte, 1);
325 last_byte = first_byte;
326
327 for (address = start_address + TEST_MEM_PAGE_SIZE; address < end_address;
328 address += TEST_MEM_PAGE_SIZE)
329 {
330 uint8_t b;
331 qtest_memread(who, address, &b, 1);
332 if (b != last_byte) {
333 if (((b + 1) % 256) == last_byte && !hit_edge) {
334 /* This is OK, the guest stopped at the point of
335 * incrementing the previous page but didn't get
336 * to us yet.
337 */
338 hit_edge = true;
339 last_byte = b;
340 } else {
341 bad++;
342 if (bad <= 10) {
343 fprintf(stderr, "Memory content inconsistency at %x"
344 " first_byte = %x last_byte = %x current = %x"
345 " hit_edge = %x\n",
346 address, first_byte, last_byte, b, hit_edge);
347 }
348 }
349 }
350 }
351 if (bad >= 10) {
352 fprintf(stderr, "and in another %d pages", bad - 10);
353 }
354 g_assert(bad == 0);
355 }
356
cleanup(const char * filename)357 static void cleanup(const char *filename)
358 {
359 g_autofree char *path = g_strdup_printf("%s/%s", tmpfs, filename);
360
361 unlink(path);
362 }
363
migrate_get_parameter_int(QTestState * who,const char * parameter)364 static long long migrate_get_parameter_int(QTestState *who,
365 const char *parameter)
366 {
367 QDict *rsp;
368 long long result;
369
370 rsp = qtest_qmp_assert_success_ref(
371 who, "{ 'execute': 'query-migrate-parameters' }");
372 result = qdict_get_int(rsp, parameter);
373 qobject_unref(rsp);
374 return result;
375 }
376
migrate_check_parameter_int(QTestState * who,const char * parameter,long long value)377 static void migrate_check_parameter_int(QTestState *who, const char *parameter,
378 long long value)
379 {
380 long long result;
381
382 result = migrate_get_parameter_int(who, parameter);
383 g_assert_cmpint(result, ==, value);
384 }
385
migrate_set_parameter_int(QTestState * who,const char * parameter,long long value)386 static void migrate_set_parameter_int(QTestState *who, const char *parameter,
387 long long value)
388 {
389 qtest_qmp_assert_success(who,
390 "{ 'execute': 'migrate-set-parameters',"
391 "'arguments': { %s: %lld } }",
392 parameter, value);
393 migrate_check_parameter_int(who, parameter, value);
394 }
395
migrate_get_parameter_str(QTestState * who,const char * parameter)396 static char *migrate_get_parameter_str(QTestState *who,
397 const char *parameter)
398 {
399 QDict *rsp;
400 char *result;
401
402 rsp = qtest_qmp_assert_success_ref(
403 who, "{ 'execute': 'query-migrate-parameters' }");
404 result = g_strdup(qdict_get_str(rsp, parameter));
405 qobject_unref(rsp);
406 return result;
407 }
408
migrate_check_parameter_str(QTestState * who,const char * parameter,const char * value)409 static void migrate_check_parameter_str(QTestState *who, const char *parameter,
410 const char *value)
411 {
412 g_autofree char *result = migrate_get_parameter_str(who, parameter);
413 g_assert_cmpstr(result, ==, value);
414 }
415
migrate_set_parameter_str(QTestState * who,const char * parameter,const char * value)416 static void migrate_set_parameter_str(QTestState *who, const char *parameter,
417 const char *value)
418 {
419 qtest_qmp_assert_success(who,
420 "{ 'execute': 'migrate-set-parameters',"
421 "'arguments': { %s: %s } }",
422 parameter, value);
423 migrate_check_parameter_str(who, parameter, value);
424 }
425
migrate_get_parameter_bool(QTestState * who,const char * parameter)426 static long long migrate_get_parameter_bool(QTestState *who,
427 const char *parameter)
428 {
429 QDict *rsp;
430 int result;
431
432 rsp = qtest_qmp_assert_success_ref(
433 who, "{ 'execute': 'query-migrate-parameters' }");
434 result = qdict_get_bool(rsp, parameter);
435 qobject_unref(rsp);
436 return !!result;
437 }
438
migrate_check_parameter_bool(QTestState * who,const char * parameter,int value)439 static void migrate_check_parameter_bool(QTestState *who, const char *parameter,
440 int value)
441 {
442 int result;
443
444 result = migrate_get_parameter_bool(who, parameter);
445 g_assert_cmpint(result, ==, value);
446 }
447
migrate_set_parameter_bool(QTestState * who,const char * parameter,int value)448 static void migrate_set_parameter_bool(QTestState *who, const char *parameter,
449 int value)
450 {
451 qtest_qmp_assert_success(who,
452 "{ 'execute': 'migrate-set-parameters',"
453 "'arguments': { %s: %i } }",
454 parameter, value);
455 migrate_check_parameter_bool(who, parameter, value);
456 }
457
migrate_ensure_non_converge(QTestState * who)458 static void migrate_ensure_non_converge(QTestState *who)
459 {
460 /* Can't converge with 1ms downtime + 3 mbs bandwidth limit */
461 migrate_set_parameter_int(who, "max-bandwidth", 3 * 1000 * 1000);
462 migrate_set_parameter_int(who, "downtime-limit", 1);
463 }
464
migrate_ensure_converge(QTestState * who)465 static void migrate_ensure_converge(QTestState *who)
466 {
467 /* Should converge with 30s downtime + 1 gbs bandwidth limit */
468 migrate_set_parameter_int(who, "max-bandwidth", 1 * 1000 * 1000 * 1000);
469 migrate_set_parameter_int(who, "downtime-limit", 30 * 1000);
470 }
471
472 /*
473 * Our goal is to ensure that we run a single full migration
474 * iteration, and also dirty memory, ensuring that at least
475 * one further iteration is required.
476 *
477 * We can't directly synchronize with the start of a migration
478 * so we have to apply some tricks monitoring memory that is
479 * transferred.
480 *
481 * Initially we set the migration bandwidth to an insanely
482 * low value, with tiny max downtime too. This basically
483 * guarantees migration will never complete.
484 *
485 * This will result in a test that is unacceptably slow though,
486 * so we can't let the entire migration pass run at this speed.
487 * Our intent is to let it run just long enough that we can
488 * prove data prior to the marker has been transferred *AND*
489 * also prove this transferred data is dirty again.
490 *
491 * Before migration starts, we write a 64-bit magic marker
492 * into a fixed location in the src VM RAM.
493 *
494 * Then watch dst memory until the marker appears. This is
495 * proof that start_address -> MAGIC_OFFSET_BASE has been
496 * transferred.
497 *
498 * Finally we go back to the source and read a byte just
499 * before the marker until we see it flip in value. This
500 * is proof that start_address -> MAGIC_OFFSET_BASE
501 * is now dirty again.
502 *
503 * IOW, we're guaranteed at least a 2nd migration pass
504 * at this point.
505 *
506 * We can now let migration run at full speed to finish
507 * the test
508 */
migrate_prepare_for_dirty_mem(QTestState * from)509 static void migrate_prepare_for_dirty_mem(QTestState *from)
510 {
511 /*
512 * The guest workflow iterates from start_address to
513 * end_address, writing 1 byte every TEST_MEM_PAGE_SIZE
514 * bytes.
515 *
516 * IOW, if we write to mem at a point which is NOT
517 * a multiple of TEST_MEM_PAGE_SIZE, our write won't
518 * conflict with the migration workflow.
519 *
520 * We put in a marker here, that we'll use to determine
521 * when the data has been transferred to the dst.
522 */
523 qtest_writeq(from, start_address + MAGIC_OFFSET, MAGIC_MARKER);
524 }
525
migrate_wait_for_dirty_mem(QTestState * from,QTestState * to)526 static void migrate_wait_for_dirty_mem(QTestState *from,
527 QTestState *to)
528 {
529 uint64_t watch_address = start_address + MAGIC_OFFSET_BASE;
530 uint64_t marker_address = start_address + MAGIC_OFFSET;
531 uint8_t watch_byte;
532
533 /*
534 * Wait for the MAGIC_MARKER to get transferred, as an
535 * indicator that a migration pass has made some known
536 * amount of progress.
537 */
538 do {
539 usleep(1000 * 10);
540 } while (qtest_readq(to, marker_address) != MAGIC_MARKER);
541
542
543 /* If suspended, src only iterates once, and watch_byte may never change */
544 if (src_state.suspend_me) {
545 return;
546 }
547
548 /*
549 * Now ensure that already transferred bytes are
550 * dirty again from the guest workload. Note the
551 * guest byte value will wrap around and by chance
552 * match the original watch_byte. This is harmless
553 * as we'll eventually see a different value if we
554 * keep watching
555 */
556 watch_byte = qtest_readb(from, watch_address);
557 do {
558 usleep(1000 * 10);
559 } while (qtest_readb(from, watch_address) == watch_byte);
560 }
561
562
migrate_pause(QTestState * who)563 static void migrate_pause(QTestState *who)
564 {
565 qtest_qmp_assert_success(who, "{ 'execute': 'migrate-pause' }");
566 }
567
migrate_continue(QTestState * who,const char * state)568 static void migrate_continue(QTestState *who, const char *state)
569 {
570 qtest_qmp_assert_success(who,
571 "{ 'execute': 'migrate-continue',"
572 " 'arguments': { 'state': %s } }",
573 state);
574 }
575
migrate_recover(QTestState * who,const char * uri)576 static void migrate_recover(QTestState *who, const char *uri)
577 {
578 qtest_qmp_assert_success(who,
579 "{ 'execute': 'migrate-recover', "
580 " 'id': 'recover-cmd', "
581 " 'arguments': { 'uri': %s } }",
582 uri);
583 }
584
migrate_cancel(QTestState * who)585 static void migrate_cancel(QTestState *who)
586 {
587 qtest_qmp_assert_success(who, "{ 'execute': 'migrate_cancel' }");
588 }
589
migrate_postcopy_start(QTestState * from,QTestState * to)590 static void migrate_postcopy_start(QTestState *from, QTestState *to)
591 {
592 qtest_qmp_assert_success(from, "{ 'execute': 'migrate-start-postcopy' }");
593
594 wait_for_stop(from, &src_state);
595 qtest_qmp_eventwait(to, "RESUME");
596 }
597
598 typedef struct {
599 /*
600 * QTEST_LOG=1 may override this. When QTEST_LOG=1, we always dump errors
601 * unconditionally, because it means the user would like to be verbose.
602 */
603 bool hide_stderr;
604 bool use_shmem;
605 /* only launch the target process */
606 bool only_target;
607 /* Use dirty ring if true; dirty logging otherwise */
608 bool use_dirty_ring;
609 const char *opts_source;
610 const char *opts_target;
611 /* suspend the src before migrating to dest. */
612 bool suspend_me;
613 } MigrateStart;
614
615 /*
616 * A hook that runs after the src and dst QEMUs have been
617 * created, but before the migration is started. This can
618 * be used to set migration parameters and capabilities.
619 *
620 * Returns: NULL, or a pointer to opaque state to be
621 * later passed to the TestMigrateFinishHook
622 */
623 typedef void * (*TestMigrateStartHook)(QTestState *from,
624 QTestState *to);
625
626 /*
627 * A hook that runs after the migration has finished,
628 * regardless of whether it succeeded or failed, but
629 * before QEMU has terminated (unless it self-terminated
630 * due to migration error)
631 *
632 * @opaque is a pointer to state previously returned
633 * by the TestMigrateStartHook if any, or NULL.
634 */
635 typedef void (*TestMigrateFinishHook)(QTestState *from,
636 QTestState *to,
637 void *opaque);
638
639 typedef struct {
640 /* Optional: fine tune start parameters */
641 MigrateStart start;
642
643 /* Required: the URI for the dst QEMU to listen on */
644 const char *listen_uri;
645
646 /*
647 * Optional: the URI for the src QEMU to connect to
648 * If NULL, then it will query the dst QEMU for its actual
649 * listening address and use that as the connect address.
650 * This allows for dynamically picking a free TCP port.
651 */
652 const char *connect_uri;
653
654 /*
655 * Optional: JSON-formatted list of src QEMU URIs. If a port is
656 * defined as '0' in any QDict key a value of '0' will be
657 * automatically converted to the correct destination port.
658 */
659 const char *connect_channels;
660
661 /* Optional: callback to run at start to set migration parameters */
662 TestMigrateStartHook start_hook;
663 /* Optional: callback to run at finish to cleanup */
664 TestMigrateFinishHook finish_hook;
665
666 /*
667 * Optional: normally we expect the migration process to complete.
668 *
669 * There can be a variety of reasons and stages in which failure
670 * can happen during tests.
671 *
672 * If a failure is expected to happen at time of establishing
673 * the connection, then MIG_TEST_FAIL will indicate that the dst
674 * QEMU is expected to stay running and accept future migration
675 * connections.
676 *
677 * If a failure is expected to happen while processing the
678 * migration stream, then MIG_TEST_FAIL_DEST_QUIT_ERR will indicate
679 * that the dst QEMU is expected to quit with non-zero exit status
680 */
681 enum {
682 /* This test should succeed, the default */
683 MIG_TEST_SUCCEED = 0,
684 /* This test should fail, dest qemu should keep alive */
685 MIG_TEST_FAIL,
686 /* This test should fail, dest qemu should fail with abnormal status */
687 MIG_TEST_FAIL_DEST_QUIT_ERR,
688 /* The QMP command for this migration should fail with an error */
689 MIG_TEST_QMP_ERROR,
690 } result;
691
692 /*
693 * Optional: set number of migration passes to wait for, if live==true.
694 * If zero, then merely wait for a few MB of dirty data
695 */
696 unsigned int iterations;
697
698 /*
699 * Optional: whether the guest CPUs should be running during a precopy
700 * migration test. We used to always run with live but it took much
701 * longer so we reduced live tests to only the ones that have solid
702 * reason to be tested live-only. For each of the new test cases for
703 * precopy please provide justifications to use live explicitly (please
704 * refer to existing ones with live=true), or use live=off by default.
705 */
706 bool live;
707
708 /* Postcopy specific fields */
709 void *postcopy_data;
710 bool postcopy_preempt;
711 PostcopyRecoveryFailStage postcopy_recovery_fail_stage;
712 } MigrateCommon;
713
test_migrate_start(QTestState ** from,QTestState ** to,const char * uri,MigrateStart * args)714 static int test_migrate_start(QTestState **from, QTestState **to,
715 const char *uri, MigrateStart *args)
716 {
717 g_autofree gchar *arch_source = NULL;
718 g_autofree gchar *arch_target = NULL;
719 /* options for source and target */
720 g_autofree gchar *arch_opts = NULL;
721 g_autofree gchar *cmd_source = NULL;
722 g_autofree gchar *cmd_target = NULL;
723 const gchar *ignore_stderr;
724 g_autofree char *shmem_opts = NULL;
725 g_autofree char *shmem_path = NULL;
726 const char *kvm_opts = NULL;
727 const char *arch = qtest_get_arch();
728 const char *memory_size;
729 const char *machine_alias, *machine_opts = "";
730 g_autofree char *machine = NULL;
731
732 if (args->use_shmem) {
733 if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
734 g_test_skip("/dev/shm is not supported");
735 return -1;
736 }
737 }
738
739 dst_state = (QTestMigrationState) { };
740 src_state = (QTestMigrationState) { };
741 bootfile_create(tmpfs, args->suspend_me);
742 src_state.suspend_me = args->suspend_me;
743
744 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
745 memory_size = "150M";
746
747 if (g_str_equal(arch, "i386")) {
748 machine_alias = "pc";
749 } else {
750 machine_alias = "q35";
751 }
752 arch_opts = g_strdup_printf(
753 "-drive if=none,id=d0,file=%s,format=raw "
754 "-device ide-hd,drive=d0,secs=1,cyls=1,heads=1", bootpath);
755 start_address = X86_TEST_MEM_START;
756 end_address = X86_TEST_MEM_END;
757 } else if (g_str_equal(arch, "s390x")) {
758 memory_size = "128M";
759 machine_alias = "s390-ccw-virtio";
760 arch_opts = g_strdup_printf("-bios %s", bootpath);
761 start_address = S390_TEST_MEM_START;
762 end_address = S390_TEST_MEM_END;
763 } else if (strcmp(arch, "ppc64") == 0) {
764 memory_size = "256M";
765 start_address = PPC_TEST_MEM_START;
766 end_address = PPC_TEST_MEM_END;
767 machine_alias = "pseries";
768 machine_opts = "vsmt=8";
769 arch_opts = g_strdup_printf(
770 "-nodefaults -machine " PSERIES_DEFAULT_CAPABILITIES " "
771 "-bios %s", bootpath);
772 } else if (strcmp(arch, "aarch64") == 0) {
773 memory_size = "150M";
774 machine_alias = "virt";
775 machine_opts = "gic-version=3";
776 arch_opts = g_strdup_printf("-cpu max -kernel %s", bootpath);
777 start_address = ARM_TEST_MEM_START;
778 end_address = ARM_TEST_MEM_END;
779 } else {
780 g_assert_not_reached();
781 }
782
783 if (!getenv("QTEST_LOG") && args->hide_stderr) {
784 #ifndef _WIN32
785 ignore_stderr = "2>/dev/null";
786 #else
787 /*
788 * On Windows the QEMU executable is created via CreateProcess() and
789 * IO redirection does not work, so don't bother adding IO redirection
790 * to the command line.
791 */
792 ignore_stderr = "";
793 #endif
794 } else {
795 ignore_stderr = "";
796 }
797
798 if (args->use_shmem) {
799 shmem_path = g_strdup_printf("/dev/shm/qemu-%d", getpid());
800 shmem_opts = g_strdup_printf(
801 "-object memory-backend-file,id=mem0,size=%s"
802 ",mem-path=%s,share=on -numa node,memdev=mem0",
803 memory_size, shmem_path);
804 }
805
806 if (args->use_dirty_ring) {
807 kvm_opts = ",dirty-ring-size=4096";
808 }
809
810 if (!qtest_has_machine(machine_alias)) {
811 g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
812 g_test_skip(msg);
813 return -1;
814 }
815
816 machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
817 QEMU_ENV_DST);
818
819 g_test_message("Using machine type: %s", machine);
820
821 cmd_source = g_strdup_printf("-accel kvm%s -accel tcg "
822 "-machine %s,%s "
823 "-name source,debug-threads=on "
824 "-m %s "
825 "-serial file:%s/src_serial "
826 "%s %s %s %s %s",
827 kvm_opts ? kvm_opts : "",
828 machine, machine_opts,
829 memory_size, tmpfs,
830 arch_opts ? arch_opts : "",
831 arch_source ? arch_source : "",
832 shmem_opts ? shmem_opts : "",
833 args->opts_source ? args->opts_source : "",
834 ignore_stderr);
835 if (!args->only_target) {
836 *from = qtest_init_with_env(QEMU_ENV_SRC, cmd_source);
837 qtest_qmp_set_event_callback(*from,
838 migrate_watch_for_events,
839 &src_state);
840 }
841
842 cmd_target = g_strdup_printf("-accel kvm%s -accel tcg "
843 "-machine %s,%s "
844 "-name target,debug-threads=on "
845 "-m %s "
846 "-serial file:%s/dest_serial "
847 "-incoming %s "
848 "%s %s %s %s %s",
849 kvm_opts ? kvm_opts : "",
850 machine, machine_opts,
851 memory_size, tmpfs, uri,
852 arch_opts ? arch_opts : "",
853 arch_target ? arch_target : "",
854 shmem_opts ? shmem_opts : "",
855 args->opts_target ? args->opts_target : "",
856 ignore_stderr);
857 *to = qtest_init_with_env(QEMU_ENV_DST, cmd_target);
858 qtest_qmp_set_event_callback(*to,
859 migrate_watch_for_events,
860 &dst_state);
861
862 /*
863 * Remove shmem file immediately to avoid memory leak in test failed case.
864 * It's valid because QEMU has already opened this file
865 */
866 if (args->use_shmem) {
867 unlink(shmem_path);
868 }
869
870 /*
871 * Always enable migration events. Libvirt always uses it, let's try
872 * to mimic as closer as that.
873 */
874 migrate_set_capability(*from, "events", true);
875 migrate_set_capability(*to, "events", true);
876
877 return 0;
878 }
879
test_migrate_end(QTestState * from,QTestState * to,bool test_dest)880 static void test_migrate_end(QTestState *from, QTestState *to, bool test_dest)
881 {
882 unsigned char dest_byte_a, dest_byte_b, dest_byte_c, dest_byte_d;
883
884 qtest_quit(from);
885
886 if (test_dest) {
887 qtest_memread(to, start_address, &dest_byte_a, 1);
888
889 /* Destination still running, wait for a byte to change */
890 do {
891 qtest_memread(to, start_address, &dest_byte_b, 1);
892 usleep(1000 * 10);
893 } while (dest_byte_a == dest_byte_b);
894
895 qtest_qmp_assert_success(to, "{ 'execute' : 'stop'}");
896
897 /* With it stopped, check nothing changes */
898 qtest_memread(to, start_address, &dest_byte_c, 1);
899 usleep(1000 * 200);
900 qtest_memread(to, start_address, &dest_byte_d, 1);
901 g_assert_cmpint(dest_byte_c, ==, dest_byte_d);
902
903 check_guests_ram(to);
904 }
905
906 qtest_quit(to);
907
908 cleanup("migsocket");
909 cleanup("src_serial");
910 cleanup("dest_serial");
911 cleanup(FILE_TEST_FILENAME);
912 }
913
914 #ifdef CONFIG_GNUTLS
915 struct TestMigrateTLSPSKData {
916 char *workdir;
917 char *workdiralt;
918 char *pskfile;
919 char *pskfilealt;
920 };
921
922 static void *
test_migrate_tls_psk_start_common(QTestState * from,QTestState * to,bool mismatch)923 test_migrate_tls_psk_start_common(QTestState *from,
924 QTestState *to,
925 bool mismatch)
926 {
927 struct TestMigrateTLSPSKData *data =
928 g_new0(struct TestMigrateTLSPSKData, 1);
929
930 data->workdir = g_strdup_printf("%s/tlscredspsk0", tmpfs);
931 data->pskfile = g_strdup_printf("%s/%s", data->workdir,
932 QCRYPTO_TLS_CREDS_PSKFILE);
933 g_mkdir_with_parents(data->workdir, 0700);
934 test_tls_psk_init(data->pskfile);
935
936 if (mismatch) {
937 data->workdiralt = g_strdup_printf("%s/tlscredspskalt0", tmpfs);
938 data->pskfilealt = g_strdup_printf("%s/%s", data->workdiralt,
939 QCRYPTO_TLS_CREDS_PSKFILE);
940 g_mkdir_with_parents(data->workdiralt, 0700);
941 test_tls_psk_init_alt(data->pskfilealt);
942 }
943
944 qtest_qmp_assert_success(from,
945 "{ 'execute': 'object-add',"
946 " 'arguments': { 'qom-type': 'tls-creds-psk',"
947 " 'id': 'tlscredspsk0',"
948 " 'endpoint': 'client',"
949 " 'dir': %s,"
950 " 'username': 'qemu'} }",
951 data->workdir);
952
953 qtest_qmp_assert_success(to,
954 "{ 'execute': 'object-add',"
955 " 'arguments': { 'qom-type': 'tls-creds-psk',"
956 " 'id': 'tlscredspsk0',"
957 " 'endpoint': 'server',"
958 " 'dir': %s } }",
959 mismatch ? data->workdiralt : data->workdir);
960
961 migrate_set_parameter_str(from, "tls-creds", "tlscredspsk0");
962 migrate_set_parameter_str(to, "tls-creds", "tlscredspsk0");
963
964 return data;
965 }
966
967 static void *
test_migrate_tls_psk_start_match(QTestState * from,QTestState * to)968 test_migrate_tls_psk_start_match(QTestState *from,
969 QTestState *to)
970 {
971 return test_migrate_tls_psk_start_common(from, to, false);
972 }
973
974 static void *
test_migrate_tls_psk_start_mismatch(QTestState * from,QTestState * to)975 test_migrate_tls_psk_start_mismatch(QTestState *from,
976 QTestState *to)
977 {
978 return test_migrate_tls_psk_start_common(from, to, true);
979 }
980
981 static void
test_migrate_tls_psk_finish(QTestState * from,QTestState * to,void * opaque)982 test_migrate_tls_psk_finish(QTestState *from,
983 QTestState *to,
984 void *opaque)
985 {
986 struct TestMigrateTLSPSKData *data = opaque;
987
988 test_tls_psk_cleanup(data->pskfile);
989 if (data->pskfilealt) {
990 test_tls_psk_cleanup(data->pskfilealt);
991 }
992 rmdir(data->workdir);
993 if (data->workdiralt) {
994 rmdir(data->workdiralt);
995 }
996
997 g_free(data->workdiralt);
998 g_free(data->pskfilealt);
999 g_free(data->workdir);
1000 g_free(data->pskfile);
1001 g_free(data);
1002 }
1003
1004 #ifdef CONFIG_TASN1
1005 typedef struct {
1006 char *workdir;
1007 char *keyfile;
1008 char *cacert;
1009 char *servercert;
1010 char *serverkey;
1011 char *clientcert;
1012 char *clientkey;
1013 } TestMigrateTLSX509Data;
1014
1015 typedef struct {
1016 bool verifyclient;
1017 bool clientcert;
1018 bool hostileclient;
1019 bool authzclient;
1020 const char *certhostname;
1021 const char *certipaddr;
1022 } TestMigrateTLSX509;
1023
1024 static void *
test_migrate_tls_x509_start_common(QTestState * from,QTestState * to,TestMigrateTLSX509 * args)1025 test_migrate_tls_x509_start_common(QTestState *from,
1026 QTestState *to,
1027 TestMigrateTLSX509 *args)
1028 {
1029 TestMigrateTLSX509Data *data = g_new0(TestMigrateTLSX509Data, 1);
1030
1031 data->workdir = g_strdup_printf("%s/tlscredsx5090", tmpfs);
1032 data->keyfile = g_strdup_printf("%s/key.pem", data->workdir);
1033
1034 data->cacert = g_strdup_printf("%s/ca-cert.pem", data->workdir);
1035 data->serverkey = g_strdup_printf("%s/server-key.pem", data->workdir);
1036 data->servercert = g_strdup_printf("%s/server-cert.pem", data->workdir);
1037 if (args->clientcert) {
1038 data->clientkey = g_strdup_printf("%s/client-key.pem", data->workdir);
1039 data->clientcert = g_strdup_printf("%s/client-cert.pem", data->workdir);
1040 }
1041
1042 g_mkdir_with_parents(data->workdir, 0700);
1043
1044 test_tls_init(data->keyfile);
1045 #ifndef _WIN32
1046 g_assert(link(data->keyfile, data->serverkey) == 0);
1047 #else
1048 g_assert(CreateHardLink(data->serverkey, data->keyfile, NULL) != 0);
1049 #endif
1050 if (args->clientcert) {
1051 #ifndef _WIN32
1052 g_assert(link(data->keyfile, data->clientkey) == 0);
1053 #else
1054 g_assert(CreateHardLink(data->clientkey, data->keyfile, NULL) != 0);
1055 #endif
1056 }
1057
1058 TLS_ROOT_REQ_SIMPLE(cacertreq, data->cacert);
1059 if (args->clientcert) {
1060 TLS_CERT_REQ_SIMPLE_CLIENT(servercertreq, cacertreq,
1061 args->hostileclient ?
1062 QCRYPTO_TLS_TEST_CLIENT_HOSTILE_NAME :
1063 QCRYPTO_TLS_TEST_CLIENT_NAME,
1064 data->clientcert);
1065 }
1066
1067 TLS_CERT_REQ_SIMPLE_SERVER(clientcertreq, cacertreq,
1068 data->servercert,
1069 args->certhostname,
1070 args->certipaddr);
1071
1072 qtest_qmp_assert_success(from,
1073 "{ 'execute': 'object-add',"
1074 " 'arguments': { 'qom-type': 'tls-creds-x509',"
1075 " 'id': 'tlscredsx509client0',"
1076 " 'endpoint': 'client',"
1077 " 'dir': %s,"
1078 " 'sanity-check': true,"
1079 " 'verify-peer': true} }",
1080 data->workdir);
1081 migrate_set_parameter_str(from, "tls-creds", "tlscredsx509client0");
1082 if (args->certhostname) {
1083 migrate_set_parameter_str(from, "tls-hostname", args->certhostname);
1084 }
1085
1086 qtest_qmp_assert_success(to,
1087 "{ 'execute': 'object-add',"
1088 " 'arguments': { 'qom-type': 'tls-creds-x509',"
1089 " 'id': 'tlscredsx509server0',"
1090 " 'endpoint': 'server',"
1091 " 'dir': %s,"
1092 " 'sanity-check': true,"
1093 " 'verify-peer': %i} }",
1094 data->workdir, args->verifyclient);
1095 migrate_set_parameter_str(to, "tls-creds", "tlscredsx509server0");
1096
1097 if (args->authzclient) {
1098 qtest_qmp_assert_success(to,
1099 "{ 'execute': 'object-add',"
1100 " 'arguments': { 'qom-type': 'authz-simple',"
1101 " 'id': 'tlsauthz0',"
1102 " 'identity': %s} }",
1103 "CN=" QCRYPTO_TLS_TEST_CLIENT_NAME);
1104 migrate_set_parameter_str(to, "tls-authz", "tlsauthz0");
1105 }
1106
1107 return data;
1108 }
1109
1110 /*
1111 * The normal case: match server's cert hostname against
1112 * whatever host we were telling QEMU to connect to (if any)
1113 */
1114 static void *
test_migrate_tls_x509_start_default_host(QTestState * from,QTestState * to)1115 test_migrate_tls_x509_start_default_host(QTestState *from,
1116 QTestState *to)
1117 {
1118 TestMigrateTLSX509 args = {
1119 .verifyclient = true,
1120 .clientcert = true,
1121 .certipaddr = "127.0.0.1"
1122 };
1123 return test_migrate_tls_x509_start_common(from, to, &args);
1124 }
1125
1126 /*
1127 * The unusual case: the server's cert is different from
1128 * the address we're telling QEMU to connect to (if any),
1129 * so we must give QEMU an explicit hostname to validate
1130 */
1131 static void *
test_migrate_tls_x509_start_override_host(QTestState * from,QTestState * to)1132 test_migrate_tls_x509_start_override_host(QTestState *from,
1133 QTestState *to)
1134 {
1135 TestMigrateTLSX509 args = {
1136 .verifyclient = true,
1137 .clientcert = true,
1138 .certhostname = "qemu.org",
1139 };
1140 return test_migrate_tls_x509_start_common(from, to, &args);
1141 }
1142
1143 /*
1144 * The unusual case: the server's cert is different from
1145 * the address we're telling QEMU to connect to, and so we
1146 * expect the client to reject the server
1147 */
1148 static void *
test_migrate_tls_x509_start_mismatch_host(QTestState * from,QTestState * to)1149 test_migrate_tls_x509_start_mismatch_host(QTestState *from,
1150 QTestState *to)
1151 {
1152 TestMigrateTLSX509 args = {
1153 .verifyclient = true,
1154 .clientcert = true,
1155 .certipaddr = "10.0.0.1",
1156 };
1157 return test_migrate_tls_x509_start_common(from, to, &args);
1158 }
1159
1160 static void *
test_migrate_tls_x509_start_friendly_client(QTestState * from,QTestState * to)1161 test_migrate_tls_x509_start_friendly_client(QTestState *from,
1162 QTestState *to)
1163 {
1164 TestMigrateTLSX509 args = {
1165 .verifyclient = true,
1166 .clientcert = true,
1167 .authzclient = true,
1168 .certipaddr = "127.0.0.1",
1169 };
1170 return test_migrate_tls_x509_start_common(from, to, &args);
1171 }
1172
1173 static void *
test_migrate_tls_x509_start_hostile_client(QTestState * from,QTestState * to)1174 test_migrate_tls_x509_start_hostile_client(QTestState *from,
1175 QTestState *to)
1176 {
1177 TestMigrateTLSX509 args = {
1178 .verifyclient = true,
1179 .clientcert = true,
1180 .hostileclient = true,
1181 .authzclient = true,
1182 .certipaddr = "127.0.0.1",
1183 };
1184 return test_migrate_tls_x509_start_common(from, to, &args);
1185 }
1186
1187 /*
1188 * The case with no client certificate presented,
1189 * and no server verification
1190 */
1191 static void *
test_migrate_tls_x509_start_allow_anon_client(QTestState * from,QTestState * to)1192 test_migrate_tls_x509_start_allow_anon_client(QTestState *from,
1193 QTestState *to)
1194 {
1195 TestMigrateTLSX509 args = {
1196 .certipaddr = "127.0.0.1",
1197 };
1198 return test_migrate_tls_x509_start_common(from, to, &args);
1199 }
1200
1201 /*
1202 * The case with no client certificate presented,
1203 * and server verification rejecting
1204 */
1205 static void *
test_migrate_tls_x509_start_reject_anon_client(QTestState * from,QTestState * to)1206 test_migrate_tls_x509_start_reject_anon_client(QTestState *from,
1207 QTestState *to)
1208 {
1209 TestMigrateTLSX509 args = {
1210 .verifyclient = true,
1211 .certipaddr = "127.0.0.1",
1212 };
1213 return test_migrate_tls_x509_start_common(from, to, &args);
1214 }
1215
1216 static void
test_migrate_tls_x509_finish(QTestState * from,QTestState * to,void * opaque)1217 test_migrate_tls_x509_finish(QTestState *from,
1218 QTestState *to,
1219 void *opaque)
1220 {
1221 TestMigrateTLSX509Data *data = opaque;
1222
1223 test_tls_cleanup(data->keyfile);
1224 g_free(data->keyfile);
1225
1226 unlink(data->cacert);
1227 g_free(data->cacert);
1228 unlink(data->servercert);
1229 g_free(data->servercert);
1230 unlink(data->serverkey);
1231 g_free(data->serverkey);
1232
1233 if (data->clientcert) {
1234 unlink(data->clientcert);
1235 g_free(data->clientcert);
1236 }
1237 if (data->clientkey) {
1238 unlink(data->clientkey);
1239 g_free(data->clientkey);
1240 }
1241
1242 rmdir(data->workdir);
1243 g_free(data->workdir);
1244
1245 g_free(data);
1246 }
1247 #endif /* CONFIG_TASN1 */
1248 #endif /* CONFIG_GNUTLS */
1249
migrate_postcopy_prepare(QTestState ** from_ptr,QTestState ** to_ptr,MigrateCommon * args)1250 static int migrate_postcopy_prepare(QTestState **from_ptr,
1251 QTestState **to_ptr,
1252 MigrateCommon *args)
1253 {
1254 QTestState *from, *to;
1255
1256 if (test_migrate_start(&from, &to, "defer", &args->start)) {
1257 return -1;
1258 }
1259
1260 if (args->start_hook) {
1261 args->postcopy_data = args->start_hook(from, to);
1262 }
1263
1264 migrate_set_capability(from, "postcopy-ram", true);
1265 migrate_set_capability(to, "postcopy-ram", true);
1266 migrate_set_capability(to, "postcopy-blocktime", true);
1267
1268 if (args->postcopy_preempt) {
1269 migrate_set_capability(from, "postcopy-preempt", true);
1270 migrate_set_capability(to, "postcopy-preempt", true);
1271 }
1272
1273 migrate_ensure_non_converge(from);
1274
1275 migrate_prepare_for_dirty_mem(from);
1276 qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming',"
1277 " 'arguments': { "
1278 " 'channels': [ { 'channel-type': 'main',"
1279 " 'addr': { 'transport': 'socket',"
1280 " 'type': 'inet',"
1281 " 'host': '127.0.0.1',"
1282 " 'port': '0' } } ] } }");
1283
1284 /* Wait for the first serial output from the source */
1285 wait_for_serial("src_serial");
1286 wait_for_suspend(from, &src_state);
1287
1288 migrate_qmp(from, to, NULL, NULL, "{}");
1289
1290 migrate_wait_for_dirty_mem(from, to);
1291
1292 *from_ptr = from;
1293 *to_ptr = to;
1294
1295 return 0;
1296 }
1297
migrate_postcopy_complete(QTestState * from,QTestState * to,MigrateCommon * args)1298 static void migrate_postcopy_complete(QTestState *from, QTestState *to,
1299 MigrateCommon *args)
1300 {
1301 wait_for_migration_complete(from);
1302
1303 if (args->start.suspend_me) {
1304 /* wakeup succeeds only if guest is suspended */
1305 qtest_qmp_assert_success(to, "{'execute': 'system_wakeup'}");
1306 }
1307
1308 /* Make sure we get at least one "B" on destination */
1309 wait_for_serial("dest_serial");
1310
1311 if (uffd_feature_thread_id) {
1312 read_blocktime(to);
1313 }
1314
1315 if (args->finish_hook) {
1316 args->finish_hook(from, to, args->postcopy_data);
1317 args->postcopy_data = NULL;
1318 }
1319
1320 test_migrate_end(from, to, true);
1321 }
1322
test_postcopy_common(MigrateCommon * args)1323 static void test_postcopy_common(MigrateCommon *args)
1324 {
1325 QTestState *from, *to;
1326
1327 if (migrate_postcopy_prepare(&from, &to, args)) {
1328 return;
1329 }
1330 migrate_postcopy_start(from, to);
1331 migrate_postcopy_complete(from, to, args);
1332 }
1333
test_postcopy(void)1334 static void test_postcopy(void)
1335 {
1336 MigrateCommon args = { };
1337
1338 test_postcopy_common(&args);
1339 }
1340
test_postcopy_suspend(void)1341 static void test_postcopy_suspend(void)
1342 {
1343 MigrateCommon args = {
1344 .start.suspend_me = true,
1345 };
1346
1347 test_postcopy_common(&args);
1348 }
1349
test_postcopy_preempt(void)1350 static void test_postcopy_preempt(void)
1351 {
1352 MigrateCommon args = {
1353 .postcopy_preempt = true,
1354 };
1355
1356 test_postcopy_common(&args);
1357 }
1358
1359 #ifdef CONFIG_GNUTLS
test_postcopy_tls_psk(void)1360 static void test_postcopy_tls_psk(void)
1361 {
1362 MigrateCommon args = {
1363 .start_hook = test_migrate_tls_psk_start_match,
1364 .finish_hook = test_migrate_tls_psk_finish,
1365 };
1366
1367 test_postcopy_common(&args);
1368 }
1369
test_postcopy_preempt_tls_psk(void)1370 static void test_postcopy_preempt_tls_psk(void)
1371 {
1372 MigrateCommon args = {
1373 .postcopy_preempt = true,
1374 .start_hook = test_migrate_tls_psk_start_match,
1375 .finish_hook = test_migrate_tls_psk_finish,
1376 };
1377
1378 test_postcopy_common(&args);
1379 }
1380 #endif
1381
wait_for_postcopy_status(QTestState * one,const char * status)1382 static void wait_for_postcopy_status(QTestState *one, const char *status)
1383 {
1384 wait_for_migration_status(one, status,
1385 (const char * []) { "failed", "active",
1386 "completed", NULL });
1387 }
1388
postcopy_recover_fail(QTestState * from,QTestState * to,PostcopyRecoveryFailStage stage)1389 static void postcopy_recover_fail(QTestState *from, QTestState *to,
1390 PostcopyRecoveryFailStage stage)
1391 {
1392 #ifndef _WIN32
1393 bool fail_early = (stage == POSTCOPY_FAIL_CHANNEL_ESTABLISH);
1394 int ret, pair1[2], pair2[2];
1395 char c;
1396
1397 g_assert(stage > POSTCOPY_FAIL_NONE && stage < POSTCOPY_FAIL_MAX);
1398
1399 /* Create two unrelated socketpairs */
1400 ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair1);
1401 g_assert_cmpint(ret, ==, 0);
1402
1403 ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair2);
1404 g_assert_cmpint(ret, ==, 0);
1405
1406 /*
1407 * Give the guests unpaired ends of the sockets, so they'll all blocked
1408 * at reading. This mimics a wrong channel established.
1409 */
1410 qtest_qmp_fds_assert_success(from, &pair1[0], 1,
1411 "{ 'execute': 'getfd',"
1412 " 'arguments': { 'fdname': 'fd-mig' }}");
1413 qtest_qmp_fds_assert_success(to, &pair2[0], 1,
1414 "{ 'execute': 'getfd',"
1415 " 'arguments': { 'fdname': 'fd-mig' }}");
1416
1417 /*
1418 * Write the 1st byte as QEMU_VM_COMMAND (0x8) for the dest socket, to
1419 * emulate the 1st byte of a real recovery, but stops from there to
1420 * keep dest QEMU in RECOVER. This is needed so that we can kick off
1421 * the recover process on dest QEMU (by triggering the G_IO_IN event).
1422 *
1423 * NOTE: this trick is not needed on src QEMUs, because src doesn't
1424 * rely on an pre-existing G_IO_IN event, so it will always trigger the
1425 * upcoming recovery anyway even if it can read nothing.
1426 */
1427 #define QEMU_VM_COMMAND 0x08
1428 c = QEMU_VM_COMMAND;
1429 ret = send(pair2[1], &c, 1, 0);
1430 g_assert_cmpint(ret, ==, 1);
1431
1432 if (stage == POSTCOPY_FAIL_CHANNEL_ESTABLISH) {
1433 /*
1434 * This will make src QEMU to fail at an early stage when trying to
1435 * resume later, where it shouldn't reach RECOVER stage at all.
1436 */
1437 close(pair1[1]);
1438 }
1439
1440 migrate_recover(to, "fd:fd-mig");
1441 migrate_qmp(from, to, "fd:fd-mig", NULL, "{'resume': true}");
1442
1443 /*
1444 * Source QEMU has an extra RECOVER_SETUP phase, dest doesn't have it.
1445 * Make sure it appears along the way.
1446 */
1447 migration_event_wait(from, "postcopy-recover-setup");
1448
1449 if (fail_early) {
1450 /*
1451 * When fails at reconnection, src QEMU will automatically goes
1452 * back to PAUSED state. Making sure there is an event in this
1453 * case: Libvirt relies on this to detect early reconnection
1454 * errors.
1455 */
1456 migration_event_wait(from, "postcopy-paused");
1457 } else {
1458 /*
1459 * We want to test "fail later" at RECOVER stage here. Make sure
1460 * both QEMU instances will go into RECOVER stage first, then test
1461 * kicking them out using migrate-pause.
1462 *
1463 * Explicitly check the RECOVER event on src, that's what Libvirt
1464 * relies on, rather than polling.
1465 */
1466 migration_event_wait(from, "postcopy-recover");
1467 wait_for_postcopy_status(from, "postcopy-recover");
1468
1469 /* Need an explicit kick on src QEMU in this case */
1470 migrate_pause(from);
1471 }
1472
1473 /*
1474 * For all failure cases, we'll reach such states on both sides now.
1475 * Check them.
1476 */
1477 wait_for_postcopy_status(from, "postcopy-paused");
1478 wait_for_postcopy_status(to, "postcopy-recover");
1479
1480 /*
1481 * Kick dest QEMU out too. This is normally not needed in reality
1482 * because when the channel is shutdown it should also happen on src.
1483 * However here we used separate socket pairs so we need to do that
1484 * explicitly.
1485 */
1486 migrate_pause(to);
1487 wait_for_postcopy_status(to, "postcopy-paused");
1488
1489 close(pair1[0]);
1490 close(pair2[0]);
1491 close(pair2[1]);
1492
1493 if (stage != POSTCOPY_FAIL_CHANNEL_ESTABLISH) {
1494 close(pair1[1]);
1495 }
1496 #endif
1497 }
1498
test_postcopy_recovery_common(MigrateCommon * args)1499 static void test_postcopy_recovery_common(MigrateCommon *args)
1500 {
1501 QTestState *from, *to;
1502 g_autofree char *uri = NULL;
1503
1504 /* Always hide errors for postcopy recover tests since they're expected */
1505 args->start.hide_stderr = true;
1506
1507 if (migrate_postcopy_prepare(&from, &to, args)) {
1508 return;
1509 }
1510
1511 /* Turn postcopy speed down, 4K/s is slow enough on any machines */
1512 migrate_set_parameter_int(from, "max-postcopy-bandwidth", 4096);
1513
1514 /* Now we start the postcopy */
1515 migrate_postcopy_start(from, to);
1516
1517 /*
1518 * Wait until postcopy is really started; we can only run the
1519 * migrate-pause command during a postcopy
1520 */
1521 wait_for_migration_status(from, "postcopy-active", NULL);
1522
1523 /*
1524 * Manually stop the postcopy migration. This emulates a network
1525 * failure with the migration socket
1526 */
1527 migrate_pause(from);
1528
1529 /*
1530 * Wait for destination side to reach postcopy-paused state. The
1531 * migrate-recover command can only succeed if destination machine
1532 * is in the paused state
1533 */
1534 wait_for_postcopy_status(to, "postcopy-paused");
1535 wait_for_postcopy_status(from, "postcopy-paused");
1536
1537 if (args->postcopy_recovery_fail_stage) {
1538 /*
1539 * Test when a wrong socket specified for recover, and then the
1540 * ability to kick it out, and continue with a correct socket.
1541 */
1542 postcopy_recover_fail(from, to, args->postcopy_recovery_fail_stage);
1543 /* continue with a good recovery */
1544 }
1545
1546 /*
1547 * Create a new socket to emulate a new channel that is different
1548 * from the broken migration channel; tell the destination to
1549 * listen to the new port
1550 */
1551 uri = g_strdup_printf("unix:%s/migsocket-recover", tmpfs);
1552 migrate_recover(to, uri);
1553
1554 /*
1555 * Try to rebuild the migration channel using the resume flag and
1556 * the newly created channel
1557 */
1558 migrate_qmp(from, to, uri, NULL, "{'resume': true}");
1559
1560 /* Restore the postcopy bandwidth to unlimited */
1561 migrate_set_parameter_int(from, "max-postcopy-bandwidth", 0);
1562
1563 migrate_postcopy_complete(from, to, args);
1564 }
1565
test_postcopy_recovery(void)1566 static void test_postcopy_recovery(void)
1567 {
1568 MigrateCommon args = { };
1569
1570 test_postcopy_recovery_common(&args);
1571 }
1572
test_postcopy_recovery_fail_handshake(void)1573 static void test_postcopy_recovery_fail_handshake(void)
1574 {
1575 MigrateCommon args = {
1576 .postcopy_recovery_fail_stage = POSTCOPY_FAIL_RECOVERY,
1577 };
1578
1579 test_postcopy_recovery_common(&args);
1580 }
1581
test_postcopy_recovery_fail_reconnect(void)1582 static void test_postcopy_recovery_fail_reconnect(void)
1583 {
1584 MigrateCommon args = {
1585 .postcopy_recovery_fail_stage = POSTCOPY_FAIL_CHANNEL_ESTABLISH,
1586 };
1587
1588 test_postcopy_recovery_common(&args);
1589 }
1590
1591 #ifdef CONFIG_GNUTLS
test_postcopy_recovery_tls_psk(void)1592 static void test_postcopy_recovery_tls_psk(void)
1593 {
1594 MigrateCommon args = {
1595 .start_hook = test_migrate_tls_psk_start_match,
1596 .finish_hook = test_migrate_tls_psk_finish,
1597 };
1598
1599 test_postcopy_recovery_common(&args);
1600 }
1601 #endif
1602
test_postcopy_preempt_recovery(void)1603 static void test_postcopy_preempt_recovery(void)
1604 {
1605 MigrateCommon args = {
1606 .postcopy_preempt = true,
1607 };
1608
1609 test_postcopy_recovery_common(&args);
1610 }
1611
1612 #ifdef CONFIG_GNUTLS
1613 /* This contains preempt+recovery+tls test altogether */
test_postcopy_preempt_all(void)1614 static void test_postcopy_preempt_all(void)
1615 {
1616 MigrateCommon args = {
1617 .postcopy_preempt = true,
1618 .start_hook = test_migrate_tls_psk_start_match,
1619 .finish_hook = test_migrate_tls_psk_finish,
1620 };
1621
1622 test_postcopy_recovery_common(&args);
1623 }
1624
1625 #endif
1626
test_baddest(void)1627 static void test_baddest(void)
1628 {
1629 MigrateStart args = {
1630 .hide_stderr = true
1631 };
1632 QTestState *from, *to;
1633
1634 if (test_migrate_start(&from, &to, "tcp:127.0.0.1:0", &args)) {
1635 return;
1636 }
1637 migrate_qmp(from, to, "tcp:127.0.0.1:0", NULL, "{}");
1638 wait_for_migration_fail(from, false);
1639 test_migrate_end(from, to, false);
1640 }
1641
1642 #ifndef _WIN32
test_analyze_script(void)1643 static void test_analyze_script(void)
1644 {
1645 MigrateStart args = {
1646 .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
1647 };
1648 QTestState *from, *to;
1649 g_autofree char *uri = NULL;
1650 g_autofree char *file = NULL;
1651 int pid, wstatus;
1652 const char *python = g_getenv("PYTHON");
1653
1654 if (!python) {
1655 g_test_skip("PYTHON variable not set");
1656 return;
1657 }
1658
1659 /* dummy url */
1660 if (test_migrate_start(&from, &to, "tcp:127.0.0.1:0", &args)) {
1661 return;
1662 }
1663
1664 /*
1665 * Setting these two capabilities causes the "configuration"
1666 * vmstate to include subsections for them. The script needs to
1667 * parse those subsections properly.
1668 */
1669 migrate_set_capability(from, "validate-uuid", true);
1670 migrate_set_capability(from, "x-ignore-shared", true);
1671
1672 file = g_strdup_printf("%s/migfile", tmpfs);
1673 uri = g_strdup_printf("exec:cat > %s", file);
1674
1675 migrate_ensure_converge(from);
1676 migrate_qmp(from, to, uri, NULL, "{}");
1677 wait_for_migration_complete(from);
1678
1679 pid = fork();
1680 if (!pid) {
1681 close(1);
1682 open("/dev/null", O_WRONLY);
1683 execl(python, python, ANALYZE_SCRIPT, "-f", file, NULL);
1684 g_assert_not_reached();
1685 }
1686
1687 g_assert(waitpid(pid, &wstatus, 0) == pid);
1688 if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
1689 g_test_message("Failed to analyze the migration stream");
1690 g_test_fail();
1691 }
1692 test_migrate_end(from, to, false);
1693 cleanup("migfile");
1694 }
1695
test_vmstate_checker_script(void)1696 static void test_vmstate_checker_script(void)
1697 {
1698 g_autofree gchar *cmd_src = NULL;
1699 g_autofree gchar *cmd_dst = NULL;
1700 g_autofree gchar *vmstate_src = NULL;
1701 g_autofree gchar *vmstate_dst = NULL;
1702 const char *machine_alias, *machine_opts = "";
1703 g_autofree char *machine = NULL;
1704 const char *arch = qtest_get_arch();
1705 int pid, wstatus;
1706 const char *python = g_getenv("PYTHON");
1707
1708 if (!getenv(QEMU_ENV_SRC) && !getenv(QEMU_ENV_DST)) {
1709 g_test_skip("Test needs two different QEMU versions");
1710 return;
1711 }
1712
1713 if (!python) {
1714 g_test_skip("PYTHON variable not set");
1715 return;
1716 }
1717
1718 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
1719 if (g_str_equal(arch, "i386")) {
1720 machine_alias = "pc";
1721 } else {
1722 machine_alias = "q35";
1723 }
1724 } else if (g_str_equal(arch, "s390x")) {
1725 machine_alias = "s390-ccw-virtio";
1726 } else if (strcmp(arch, "ppc64") == 0) {
1727 machine_alias = "pseries";
1728 } else if (strcmp(arch, "aarch64") == 0) {
1729 machine_alias = "virt";
1730 } else {
1731 g_assert_not_reached();
1732 }
1733
1734 if (!qtest_has_machine(machine_alias)) {
1735 g_autofree char *msg = g_strdup_printf("machine %s not supported", machine_alias);
1736 g_test_skip(msg);
1737 return;
1738 }
1739
1740 machine = resolve_machine_version(machine_alias, QEMU_ENV_SRC,
1741 QEMU_ENV_DST);
1742
1743 vmstate_src = g_strdup_printf("%s/vmstate-src", tmpfs);
1744 vmstate_dst = g_strdup_printf("%s/vmstate-dst", tmpfs);
1745
1746 cmd_dst = g_strdup_printf("-machine %s,%s -dump-vmstate %s",
1747 machine, machine_opts, vmstate_dst);
1748 cmd_src = g_strdup_printf("-machine %s,%s -dump-vmstate %s",
1749 machine, machine_opts, vmstate_src);
1750
1751 qtest_init_with_env_no_handshake(QEMU_ENV_SRC, cmd_src);
1752 qtest_init_with_env_no_handshake(QEMU_ENV_DST, cmd_dst);
1753
1754 pid = fork();
1755 if (!pid) {
1756 close(1);
1757 open("/dev/null", O_WRONLY);
1758 execl(python, python, VMSTATE_CHECKER_SCRIPT,
1759 "-s", vmstate_src,
1760 "-d", vmstate_dst,
1761 NULL);
1762 g_assert_not_reached();
1763 }
1764
1765 g_assert(waitpid(pid, &wstatus, 0) == pid);
1766 if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
1767 g_test_message("Failed to run vmstate-static-checker.py");
1768 g_test_fail();
1769 }
1770
1771 cleanup("vmstate-src");
1772 cleanup("vmstate-dst");
1773 }
1774 #endif
1775
test_precopy_common(MigrateCommon * args)1776 static void test_precopy_common(MigrateCommon *args)
1777 {
1778 QTestState *from, *to;
1779 void *data_hook = NULL;
1780
1781 if (test_migrate_start(&from, &to, args->listen_uri, &args->start)) {
1782 return;
1783 }
1784
1785 if (args->start_hook) {
1786 data_hook = args->start_hook(from, to);
1787 }
1788
1789 /* Wait for the first serial output from the source */
1790 if (args->result == MIG_TEST_SUCCEED) {
1791 wait_for_serial("src_serial");
1792 wait_for_suspend(from, &src_state);
1793 }
1794
1795 if (args->live) {
1796 migrate_ensure_non_converge(from);
1797 migrate_prepare_for_dirty_mem(from);
1798 } else {
1799 /*
1800 * Testing non-live migration, we allow it to run at
1801 * full speed to ensure short test case duration.
1802 * For tests expected to fail, we don't need to
1803 * change anything.
1804 */
1805 if (args->result == MIG_TEST_SUCCEED) {
1806 qtest_qmp_assert_success(from, "{ 'execute' : 'stop'}");
1807 wait_for_stop(from, &src_state);
1808 migrate_ensure_converge(from);
1809 }
1810 }
1811
1812 if (args->result == MIG_TEST_QMP_ERROR) {
1813 migrate_qmp_fail(from, args->connect_uri, args->connect_channels, "{}");
1814 goto finish;
1815 }
1816
1817 migrate_qmp(from, to, args->connect_uri, args->connect_channels, "{}");
1818
1819 if (args->result != MIG_TEST_SUCCEED) {
1820 bool allow_active = args->result == MIG_TEST_FAIL;
1821 wait_for_migration_fail(from, allow_active);
1822
1823 if (args->result == MIG_TEST_FAIL_DEST_QUIT_ERR) {
1824 qtest_set_expected_status(to, EXIT_FAILURE);
1825 }
1826 } else {
1827 if (args->live) {
1828 /*
1829 * For initial iteration(s) we must do a full pass,
1830 * but for the final iteration, we need only wait
1831 * for some dirty mem before switching to converge
1832 */
1833 while (args->iterations > 1) {
1834 wait_for_migration_pass(from);
1835 args->iterations--;
1836 }
1837 migrate_wait_for_dirty_mem(from, to);
1838
1839 migrate_ensure_converge(from);
1840
1841 /*
1842 * We do this first, as it has a timeout to stop us
1843 * hanging forever if migration didn't converge
1844 */
1845 wait_for_migration_complete(from);
1846
1847 wait_for_stop(from, &src_state);
1848
1849 } else {
1850 wait_for_migration_complete(from);
1851 /*
1852 * Must wait for dst to finish reading all incoming
1853 * data on the socket before issuing 'cont' otherwise
1854 * it'll be ignored
1855 */
1856 wait_for_migration_complete(to);
1857
1858 qtest_qmp_assert_success(to, "{ 'execute' : 'cont'}");
1859 }
1860
1861 wait_for_resume(to, &dst_state);
1862
1863 if (args->start.suspend_me) {
1864 /* wakeup succeeds only if guest is suspended */
1865 qtest_qmp_assert_success(to, "{'execute': 'system_wakeup'}");
1866 }
1867
1868 wait_for_serial("dest_serial");
1869 }
1870
1871 finish:
1872 if (args->finish_hook) {
1873 args->finish_hook(from, to, data_hook);
1874 }
1875
1876 test_migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
1877 }
1878
file_dirty_offset_region(void)1879 static void file_dirty_offset_region(void)
1880 {
1881 g_autofree char *path = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
1882 size_t size = FILE_TEST_OFFSET;
1883 g_autofree char *data = g_new0(char, size);
1884
1885 memset(data, FILE_TEST_MARKER, size);
1886 g_assert(g_file_set_contents(path, data, size, NULL));
1887 }
1888
file_check_offset_region(void)1889 static void file_check_offset_region(void)
1890 {
1891 g_autofree char *path = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
1892 size_t size = FILE_TEST_OFFSET;
1893 g_autofree char *expected = g_new0(char, size);
1894 g_autofree char *actual = NULL;
1895 uint64_t *stream_start;
1896
1897 /*
1898 * Ensure the skipped offset region's data has not been touched
1899 * and the migration stream starts at the right place.
1900 */
1901
1902 memset(expected, FILE_TEST_MARKER, size);
1903
1904 g_assert(g_file_get_contents(path, &actual, NULL, NULL));
1905 g_assert(!memcmp(actual, expected, size));
1906
1907 stream_start = (uint64_t *)(actual + size);
1908 g_assert_cmpint(cpu_to_be64(*stream_start) >> 32, ==, QEMU_VM_FILE_MAGIC);
1909 }
1910
test_file_common(MigrateCommon * args,bool stop_src)1911 static void test_file_common(MigrateCommon *args, bool stop_src)
1912 {
1913 QTestState *from, *to;
1914 void *data_hook = NULL;
1915 bool check_offset = false;
1916
1917 if (test_migrate_start(&from, &to, args->listen_uri, &args->start)) {
1918 return;
1919 }
1920
1921 /*
1922 * File migration is never live. We can keep the source VM running
1923 * during migration, but the destination will not be running
1924 * concurrently.
1925 */
1926 g_assert_false(args->live);
1927
1928 if (g_strrstr(args->connect_uri, "offset=")) {
1929 check_offset = true;
1930 /*
1931 * This comes before the start_hook because it's equivalent to
1932 * a management application creating the file and writing to
1933 * it so hooks should expect the file to be already present.
1934 */
1935 file_dirty_offset_region();
1936 }
1937
1938 if (args->start_hook) {
1939 data_hook = args->start_hook(from, to);
1940 }
1941
1942 migrate_ensure_converge(from);
1943 wait_for_serial("src_serial");
1944
1945 if (stop_src) {
1946 qtest_qmp_assert_success(from, "{ 'execute' : 'stop'}");
1947 wait_for_stop(from, &src_state);
1948 }
1949
1950 if (args->result == MIG_TEST_QMP_ERROR) {
1951 migrate_qmp_fail(from, args->connect_uri, NULL, "{}");
1952 goto finish;
1953 }
1954
1955 migrate_qmp(from, to, args->connect_uri, NULL, "{}");
1956 wait_for_migration_complete(from);
1957
1958 /*
1959 * We need to wait for the source to finish before starting the
1960 * destination.
1961 */
1962 migrate_incoming_qmp(to, args->connect_uri, "{}");
1963 wait_for_migration_complete(to);
1964
1965 if (stop_src) {
1966 qtest_qmp_assert_success(to, "{ 'execute' : 'cont'}");
1967 }
1968 wait_for_resume(to, &dst_state);
1969
1970 wait_for_serial("dest_serial");
1971
1972 if (check_offset) {
1973 file_check_offset_region();
1974 }
1975
1976 finish:
1977 if (args->finish_hook) {
1978 args->finish_hook(from, to, data_hook);
1979 }
1980
1981 test_migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
1982 }
1983
test_precopy_unix_plain(void)1984 static void test_precopy_unix_plain(void)
1985 {
1986 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
1987 MigrateCommon args = {
1988 .listen_uri = uri,
1989 .connect_uri = uri,
1990 /*
1991 * The simplest use case of precopy, covering smoke tests of
1992 * get-dirty-log dirty tracking.
1993 */
1994 .live = true,
1995 };
1996
1997 test_precopy_common(&args);
1998 }
1999
test_precopy_unix_suspend_live(void)2000 static void test_precopy_unix_suspend_live(void)
2001 {
2002 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2003 MigrateCommon args = {
2004 .listen_uri = uri,
2005 .connect_uri = uri,
2006 /*
2007 * despite being live, the test is fast because the src
2008 * suspends immediately.
2009 */
2010 .live = true,
2011 .start.suspend_me = true,
2012 };
2013
2014 test_precopy_common(&args);
2015 }
2016
test_precopy_unix_suspend_notlive(void)2017 static void test_precopy_unix_suspend_notlive(void)
2018 {
2019 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2020 MigrateCommon args = {
2021 .listen_uri = uri,
2022 .connect_uri = uri,
2023 .start.suspend_me = true,
2024 };
2025
2026 test_precopy_common(&args);
2027 }
2028
test_precopy_unix_dirty_ring(void)2029 static void test_precopy_unix_dirty_ring(void)
2030 {
2031 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2032 MigrateCommon args = {
2033 .start = {
2034 .use_dirty_ring = true,
2035 },
2036 .listen_uri = uri,
2037 .connect_uri = uri,
2038 /*
2039 * Besides the precopy/unix basic test, cover dirty ring interface
2040 * rather than get-dirty-log.
2041 */
2042 .live = true,
2043 };
2044
2045 test_precopy_common(&args);
2046 }
2047
2048 #ifdef CONFIG_GNUTLS
test_precopy_unix_tls_psk(void)2049 static void test_precopy_unix_tls_psk(void)
2050 {
2051 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2052 MigrateCommon args = {
2053 .connect_uri = uri,
2054 .listen_uri = uri,
2055 .start_hook = test_migrate_tls_psk_start_match,
2056 .finish_hook = test_migrate_tls_psk_finish,
2057 };
2058
2059 test_precopy_common(&args);
2060 }
2061
2062 #ifdef CONFIG_TASN1
test_precopy_unix_tls_x509_default_host(void)2063 static void test_precopy_unix_tls_x509_default_host(void)
2064 {
2065 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2066 MigrateCommon args = {
2067 .start = {
2068 .hide_stderr = true,
2069 },
2070 .connect_uri = uri,
2071 .listen_uri = uri,
2072 .start_hook = test_migrate_tls_x509_start_default_host,
2073 .finish_hook = test_migrate_tls_x509_finish,
2074 .result = MIG_TEST_FAIL_DEST_QUIT_ERR,
2075 };
2076
2077 test_precopy_common(&args);
2078 }
2079
test_precopy_unix_tls_x509_override_host(void)2080 static void test_precopy_unix_tls_x509_override_host(void)
2081 {
2082 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2083 MigrateCommon args = {
2084 .connect_uri = uri,
2085 .listen_uri = uri,
2086 .start_hook = test_migrate_tls_x509_start_override_host,
2087 .finish_hook = test_migrate_tls_x509_finish,
2088 };
2089
2090 test_precopy_common(&args);
2091 }
2092 #endif /* CONFIG_TASN1 */
2093 #endif /* CONFIG_GNUTLS */
2094
2095 #if 0
2096 /* Currently upset on aarch64 TCG */
2097 static void test_ignore_shared(void)
2098 {
2099 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2100 QTestState *from, *to;
2101
2102 if (test_migrate_start(&from, &to, uri, false, true, NULL, NULL)) {
2103 return;
2104 }
2105
2106 migrate_ensure_non_converge(from);
2107 migrate_prepare_for_dirty_mem(from);
2108
2109 migrate_set_capability(from, "x-ignore-shared", true);
2110 migrate_set_capability(to, "x-ignore-shared", true);
2111
2112 /* Wait for the first serial output from the source */
2113 wait_for_serial("src_serial");
2114
2115 migrate_qmp(from, to, uri, NULL, "{}");
2116
2117 migrate_wait_for_dirty_mem(from, to);
2118
2119 wait_for_stop(from, &src_state);
2120
2121 qtest_qmp_eventwait(to, "RESUME");
2122
2123 wait_for_serial("dest_serial");
2124 wait_for_migration_complete(from);
2125
2126 /* Check whether shared RAM has been really skipped */
2127 g_assert_cmpint(read_ram_property_int(from, "transferred"), <, 1024 * 1024);
2128
2129 test_migrate_end(from, to, true);
2130 }
2131 #endif
2132
2133 static void *
test_migrate_xbzrle_start(QTestState * from,QTestState * to)2134 test_migrate_xbzrle_start(QTestState *from,
2135 QTestState *to)
2136 {
2137 migrate_set_parameter_int(from, "xbzrle-cache-size", 33554432);
2138
2139 migrate_set_capability(from, "xbzrle", true);
2140 migrate_set_capability(to, "xbzrle", true);
2141
2142 return NULL;
2143 }
2144
test_precopy_unix_xbzrle(void)2145 static void test_precopy_unix_xbzrle(void)
2146 {
2147 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2148 MigrateCommon args = {
2149 .connect_uri = uri,
2150 .listen_uri = uri,
2151 .start_hook = test_migrate_xbzrle_start,
2152 .iterations = 2,
2153 /*
2154 * XBZRLE needs pages to be modified when doing the 2nd+ round
2155 * iteration to have real data pushed to the stream.
2156 */
2157 .live = true,
2158 };
2159
2160 test_precopy_common(&args);
2161 }
2162
test_precopy_file(void)2163 static void test_precopy_file(void)
2164 {
2165 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2166 FILE_TEST_FILENAME);
2167 MigrateCommon args = {
2168 .connect_uri = uri,
2169 .listen_uri = "defer",
2170 };
2171
2172 test_file_common(&args, true);
2173 }
2174
2175 #ifndef _WIN32
fdset_add_fds(QTestState * qts,const char * file,int flags,int num_fds,bool direct_io)2176 static void fdset_add_fds(QTestState *qts, const char *file, int flags,
2177 int num_fds, bool direct_io)
2178 {
2179 for (int i = 0; i < num_fds; i++) {
2180 int fd;
2181
2182 #ifdef O_DIRECT
2183 /* only secondary channels can use direct-io */
2184 if (direct_io && i != 0) {
2185 flags |= O_DIRECT;
2186 }
2187 #endif
2188
2189 fd = open(file, flags, 0660);
2190 assert(fd != -1);
2191
2192 qtest_qmp_fds_assert_success(qts, &fd, 1, "{'execute': 'add-fd', "
2193 "'arguments': {'fdset-id': 1}}");
2194 close(fd);
2195 }
2196 }
2197
file_offset_fdset_start_hook(QTestState * from,QTestState * to)2198 static void *file_offset_fdset_start_hook(QTestState *from, QTestState *to)
2199 {
2200 g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
2201
2202 fdset_add_fds(from, file, O_WRONLY, 1, false);
2203 fdset_add_fds(to, file, O_RDONLY, 1, false);
2204
2205 return NULL;
2206 }
2207
test_precopy_file_offset_fdset(void)2208 static void test_precopy_file_offset_fdset(void)
2209 {
2210 g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d",
2211 FILE_TEST_OFFSET);
2212 MigrateCommon args = {
2213 .connect_uri = uri,
2214 .listen_uri = "defer",
2215 .start_hook = file_offset_fdset_start_hook,
2216 };
2217
2218 test_file_common(&args, false);
2219 }
2220 #endif
2221
test_precopy_file_offset(void)2222 static void test_precopy_file_offset(void)
2223 {
2224 g_autofree char *uri = g_strdup_printf("file:%s/%s,offset=%d", tmpfs,
2225 FILE_TEST_FILENAME,
2226 FILE_TEST_OFFSET);
2227 MigrateCommon args = {
2228 .connect_uri = uri,
2229 .listen_uri = "defer",
2230 };
2231
2232 test_file_common(&args, false);
2233 }
2234
test_precopy_file_offset_bad(void)2235 static void test_precopy_file_offset_bad(void)
2236 {
2237 /* using a value not supported by qemu_strtosz() */
2238 g_autofree char *uri = g_strdup_printf("file:%s/%s,offset=0x20M",
2239 tmpfs, FILE_TEST_FILENAME);
2240 MigrateCommon args = {
2241 .connect_uri = uri,
2242 .listen_uri = "defer",
2243 .result = MIG_TEST_QMP_ERROR,
2244 };
2245
2246 test_file_common(&args, false);
2247 }
2248
test_mode_reboot_start(QTestState * from,QTestState * to)2249 static void *test_mode_reboot_start(QTestState *from, QTestState *to)
2250 {
2251 migrate_set_parameter_str(from, "mode", "cpr-reboot");
2252 migrate_set_parameter_str(to, "mode", "cpr-reboot");
2253
2254 migrate_set_capability(from, "x-ignore-shared", true);
2255 migrate_set_capability(to, "x-ignore-shared", true);
2256
2257 return NULL;
2258 }
2259
migrate_mapped_ram_start(QTestState * from,QTestState * to)2260 static void *migrate_mapped_ram_start(QTestState *from, QTestState *to)
2261 {
2262 migrate_set_capability(from, "mapped-ram", true);
2263 migrate_set_capability(to, "mapped-ram", true);
2264
2265 return NULL;
2266 }
2267
test_mode_reboot(void)2268 static void test_mode_reboot(void)
2269 {
2270 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2271 FILE_TEST_FILENAME);
2272 MigrateCommon args = {
2273 .start.use_shmem = true,
2274 .connect_uri = uri,
2275 .listen_uri = "defer",
2276 .start_hook = test_mode_reboot_start
2277 };
2278
2279 test_file_common(&args, true);
2280 }
2281
test_precopy_file_mapped_ram_live(void)2282 static void test_precopy_file_mapped_ram_live(void)
2283 {
2284 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2285 FILE_TEST_FILENAME);
2286 MigrateCommon args = {
2287 .connect_uri = uri,
2288 .listen_uri = "defer",
2289 .start_hook = migrate_mapped_ram_start,
2290 };
2291
2292 test_file_common(&args, false);
2293 }
2294
test_precopy_file_mapped_ram(void)2295 static void test_precopy_file_mapped_ram(void)
2296 {
2297 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2298 FILE_TEST_FILENAME);
2299 MigrateCommon args = {
2300 .connect_uri = uri,
2301 .listen_uri = "defer",
2302 .start_hook = migrate_mapped_ram_start,
2303 };
2304
2305 test_file_common(&args, true);
2306 }
2307
migrate_multifd_mapped_ram_start(QTestState * from,QTestState * to)2308 static void *migrate_multifd_mapped_ram_start(QTestState *from, QTestState *to)
2309 {
2310 migrate_mapped_ram_start(from, to);
2311
2312 migrate_set_parameter_int(from, "multifd-channels", 4);
2313 migrate_set_parameter_int(to, "multifd-channels", 4);
2314
2315 migrate_set_capability(from, "multifd", true);
2316 migrate_set_capability(to, "multifd", true);
2317
2318 return NULL;
2319 }
2320
test_multifd_file_mapped_ram_live(void)2321 static void test_multifd_file_mapped_ram_live(void)
2322 {
2323 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2324 FILE_TEST_FILENAME);
2325 MigrateCommon args = {
2326 .connect_uri = uri,
2327 .listen_uri = "defer",
2328 .start_hook = migrate_multifd_mapped_ram_start,
2329 };
2330
2331 test_file_common(&args, false);
2332 }
2333
test_multifd_file_mapped_ram(void)2334 static void test_multifd_file_mapped_ram(void)
2335 {
2336 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2337 FILE_TEST_FILENAME);
2338 MigrateCommon args = {
2339 .connect_uri = uri,
2340 .listen_uri = "defer",
2341 .start_hook = migrate_multifd_mapped_ram_start,
2342 };
2343
2344 test_file_common(&args, true);
2345 }
2346
multifd_mapped_ram_dio_start(QTestState * from,QTestState * to)2347 static void *multifd_mapped_ram_dio_start(QTestState *from, QTestState *to)
2348 {
2349 migrate_multifd_mapped_ram_start(from, to);
2350
2351 migrate_set_parameter_bool(from, "direct-io", true);
2352 migrate_set_parameter_bool(to, "direct-io", true);
2353
2354 return NULL;
2355 }
2356
test_multifd_file_mapped_ram_dio(void)2357 static void test_multifd_file_mapped_ram_dio(void)
2358 {
2359 g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
2360 FILE_TEST_FILENAME);
2361 MigrateCommon args = {
2362 .connect_uri = uri,
2363 .listen_uri = "defer",
2364 .start_hook = multifd_mapped_ram_dio_start,
2365 };
2366
2367 if (!probe_o_direct_support(tmpfs)) {
2368 g_test_skip("Filesystem does not support O_DIRECT");
2369 return;
2370 }
2371
2372 test_file_common(&args, true);
2373 }
2374
2375 #ifndef _WIN32
multifd_mapped_ram_fdset_end(QTestState * from,QTestState * to,void * opaque)2376 static void multifd_mapped_ram_fdset_end(QTestState *from, QTestState *to,
2377 void *opaque)
2378 {
2379 QDict *resp;
2380 QList *fdsets;
2381
2382 /*
2383 * Remove the fdsets after migration, otherwise a second migration
2384 * would fail due fdset reuse.
2385 */
2386 qtest_qmp_assert_success(from, "{'execute': 'remove-fd', "
2387 "'arguments': { 'fdset-id': 1}}");
2388
2389 /*
2390 * Make sure no fdsets are left after migration, otherwise a
2391 * second migration would fail due fdset reuse.
2392 */
2393 resp = qtest_qmp(from, "{'execute': 'query-fdsets', "
2394 "'arguments': {}}");
2395 g_assert(qdict_haskey(resp, "return"));
2396 fdsets = qdict_get_qlist(resp, "return");
2397 g_assert(fdsets && qlist_empty(fdsets));
2398 }
2399
multifd_mapped_ram_fdset_dio(QTestState * from,QTestState * to)2400 static void *multifd_mapped_ram_fdset_dio(QTestState *from, QTestState *to)
2401 {
2402 g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
2403
2404 fdset_add_fds(from, file, O_WRONLY, 2, true);
2405 fdset_add_fds(to, file, O_RDONLY, 2, true);
2406
2407 migrate_multifd_mapped_ram_start(from, to);
2408 migrate_set_parameter_bool(from, "direct-io", true);
2409 migrate_set_parameter_bool(to, "direct-io", true);
2410
2411 return NULL;
2412 }
2413
multifd_mapped_ram_fdset(QTestState * from,QTestState * to)2414 static void *multifd_mapped_ram_fdset(QTestState *from, QTestState *to)
2415 {
2416 g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
2417
2418 fdset_add_fds(from, file, O_WRONLY, 2, false);
2419 fdset_add_fds(to, file, O_RDONLY, 2, false);
2420
2421 migrate_multifd_mapped_ram_start(from, to);
2422
2423 return NULL;
2424 }
2425
test_multifd_file_mapped_ram_fdset(void)2426 static void test_multifd_file_mapped_ram_fdset(void)
2427 {
2428 g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d",
2429 FILE_TEST_OFFSET);
2430 MigrateCommon args = {
2431 .connect_uri = uri,
2432 .listen_uri = "defer",
2433 .start_hook = multifd_mapped_ram_fdset,
2434 .finish_hook = multifd_mapped_ram_fdset_end,
2435 };
2436
2437 test_file_common(&args, true);
2438 }
2439
test_multifd_file_mapped_ram_fdset_dio(void)2440 static void test_multifd_file_mapped_ram_fdset_dio(void)
2441 {
2442 g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d",
2443 FILE_TEST_OFFSET);
2444 MigrateCommon args = {
2445 .connect_uri = uri,
2446 .listen_uri = "defer",
2447 .start_hook = multifd_mapped_ram_fdset_dio,
2448 .finish_hook = multifd_mapped_ram_fdset_end,
2449 };
2450
2451 if (!probe_o_direct_support(tmpfs)) {
2452 g_test_skip("Filesystem does not support O_DIRECT");
2453 return;
2454 }
2455
2456 test_file_common(&args, true);
2457 }
2458 #endif /* !_WIN32 */
2459
test_precopy_tcp_plain(void)2460 static void test_precopy_tcp_plain(void)
2461 {
2462 MigrateCommon args = {
2463 .listen_uri = "tcp:127.0.0.1:0",
2464 };
2465
2466 test_precopy_common(&args);
2467 }
2468
test_migrate_switchover_ack_start(QTestState * from,QTestState * to)2469 static void *test_migrate_switchover_ack_start(QTestState *from, QTestState *to)
2470 {
2471
2472 migrate_set_capability(from, "return-path", true);
2473 migrate_set_capability(to, "return-path", true);
2474
2475 migrate_set_capability(from, "switchover-ack", true);
2476 migrate_set_capability(to, "switchover-ack", true);
2477
2478 return NULL;
2479 }
2480
test_precopy_tcp_switchover_ack(void)2481 static void test_precopy_tcp_switchover_ack(void)
2482 {
2483 MigrateCommon args = {
2484 .listen_uri = "tcp:127.0.0.1:0",
2485 .start_hook = test_migrate_switchover_ack_start,
2486 /*
2487 * Source VM must be running in order to consider the switchover ACK
2488 * when deciding to do switchover or not.
2489 */
2490 .live = true,
2491 };
2492
2493 test_precopy_common(&args);
2494 }
2495
2496 #ifdef CONFIG_GNUTLS
test_precopy_tcp_tls_psk_match(void)2497 static void test_precopy_tcp_tls_psk_match(void)
2498 {
2499 MigrateCommon args = {
2500 .listen_uri = "tcp:127.0.0.1:0",
2501 .start_hook = test_migrate_tls_psk_start_match,
2502 .finish_hook = test_migrate_tls_psk_finish,
2503 };
2504
2505 test_precopy_common(&args);
2506 }
2507
test_precopy_tcp_tls_psk_mismatch(void)2508 static void test_precopy_tcp_tls_psk_mismatch(void)
2509 {
2510 MigrateCommon args = {
2511 .start = {
2512 .hide_stderr = true,
2513 },
2514 .listen_uri = "tcp:127.0.0.1:0",
2515 .start_hook = test_migrate_tls_psk_start_mismatch,
2516 .finish_hook = test_migrate_tls_psk_finish,
2517 .result = MIG_TEST_FAIL,
2518 };
2519
2520 test_precopy_common(&args);
2521 }
2522
2523 #ifdef CONFIG_TASN1
test_precopy_tcp_tls_x509_default_host(void)2524 static void test_precopy_tcp_tls_x509_default_host(void)
2525 {
2526 MigrateCommon args = {
2527 .listen_uri = "tcp:127.0.0.1:0",
2528 .start_hook = test_migrate_tls_x509_start_default_host,
2529 .finish_hook = test_migrate_tls_x509_finish,
2530 };
2531
2532 test_precopy_common(&args);
2533 }
2534
test_precopy_tcp_tls_x509_override_host(void)2535 static void test_precopy_tcp_tls_x509_override_host(void)
2536 {
2537 MigrateCommon args = {
2538 .listen_uri = "tcp:127.0.0.1:0",
2539 .start_hook = test_migrate_tls_x509_start_override_host,
2540 .finish_hook = test_migrate_tls_x509_finish,
2541 };
2542
2543 test_precopy_common(&args);
2544 }
2545
test_precopy_tcp_tls_x509_mismatch_host(void)2546 static void test_precopy_tcp_tls_x509_mismatch_host(void)
2547 {
2548 MigrateCommon args = {
2549 .start = {
2550 .hide_stderr = true,
2551 },
2552 .listen_uri = "tcp:127.0.0.1:0",
2553 .start_hook = test_migrate_tls_x509_start_mismatch_host,
2554 .finish_hook = test_migrate_tls_x509_finish,
2555 .result = MIG_TEST_FAIL_DEST_QUIT_ERR,
2556 };
2557
2558 test_precopy_common(&args);
2559 }
2560
test_precopy_tcp_tls_x509_friendly_client(void)2561 static void test_precopy_tcp_tls_x509_friendly_client(void)
2562 {
2563 MigrateCommon args = {
2564 .listen_uri = "tcp:127.0.0.1:0",
2565 .start_hook = test_migrate_tls_x509_start_friendly_client,
2566 .finish_hook = test_migrate_tls_x509_finish,
2567 };
2568
2569 test_precopy_common(&args);
2570 }
2571
test_precopy_tcp_tls_x509_hostile_client(void)2572 static void test_precopy_tcp_tls_x509_hostile_client(void)
2573 {
2574 MigrateCommon args = {
2575 .start = {
2576 .hide_stderr = true,
2577 },
2578 .listen_uri = "tcp:127.0.0.1:0",
2579 .start_hook = test_migrate_tls_x509_start_hostile_client,
2580 .finish_hook = test_migrate_tls_x509_finish,
2581 .result = MIG_TEST_FAIL,
2582 };
2583
2584 test_precopy_common(&args);
2585 }
2586
test_precopy_tcp_tls_x509_allow_anon_client(void)2587 static void test_precopy_tcp_tls_x509_allow_anon_client(void)
2588 {
2589 MigrateCommon args = {
2590 .listen_uri = "tcp:127.0.0.1:0",
2591 .start_hook = test_migrate_tls_x509_start_allow_anon_client,
2592 .finish_hook = test_migrate_tls_x509_finish,
2593 };
2594
2595 test_precopy_common(&args);
2596 }
2597
test_precopy_tcp_tls_x509_reject_anon_client(void)2598 static void test_precopy_tcp_tls_x509_reject_anon_client(void)
2599 {
2600 MigrateCommon args = {
2601 .start = {
2602 .hide_stderr = true,
2603 },
2604 .listen_uri = "tcp:127.0.0.1:0",
2605 .start_hook = test_migrate_tls_x509_start_reject_anon_client,
2606 .finish_hook = test_migrate_tls_x509_finish,
2607 .result = MIG_TEST_FAIL,
2608 };
2609
2610 test_precopy_common(&args);
2611 }
2612 #endif /* CONFIG_TASN1 */
2613 #endif /* CONFIG_GNUTLS */
2614
2615 #ifndef _WIN32
test_migrate_fd_start_hook(QTestState * from,QTestState * to)2616 static void *test_migrate_fd_start_hook(QTestState *from,
2617 QTestState *to)
2618 {
2619 int ret;
2620 int pair[2];
2621
2622 /* Create two connected sockets for migration */
2623 ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
2624 g_assert_cmpint(ret, ==, 0);
2625
2626 /* Send the 1st socket to the target */
2627 qtest_qmp_fds_assert_success(to, &pair[0], 1,
2628 "{ 'execute': 'getfd',"
2629 " 'arguments': { 'fdname': 'fd-mig' }}");
2630 close(pair[0]);
2631
2632 /* Start incoming migration from the 1st socket */
2633 migrate_incoming_qmp(to, "fd:fd-mig", "{}");
2634
2635 /* Send the 2nd socket to the target */
2636 qtest_qmp_fds_assert_success(from, &pair[1], 1,
2637 "{ 'execute': 'getfd',"
2638 " 'arguments': { 'fdname': 'fd-mig' }}");
2639 close(pair[1]);
2640
2641 return NULL;
2642 }
2643
test_migrate_fd_finish_hook(QTestState * from,QTestState * to,void * opaque)2644 static void test_migrate_fd_finish_hook(QTestState *from,
2645 QTestState *to,
2646 void *opaque)
2647 {
2648 QDict *rsp;
2649 const char *error_desc;
2650
2651 /* Test closing fds */
2652 /* We assume, that QEMU removes named fd from its list,
2653 * so this should fail */
2654 rsp = qtest_qmp(from, "{ 'execute': 'closefd',"
2655 " 'arguments': { 'fdname': 'fd-mig' }}");
2656 g_assert_true(qdict_haskey(rsp, "error"));
2657 error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
2658 g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
2659 qobject_unref(rsp);
2660
2661 rsp = qtest_qmp(to, "{ 'execute': 'closefd',"
2662 " 'arguments': { 'fdname': 'fd-mig' }}");
2663 g_assert_true(qdict_haskey(rsp, "error"));
2664 error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
2665 g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
2666 qobject_unref(rsp);
2667 }
2668
test_migrate_precopy_fd_socket(void)2669 static void test_migrate_precopy_fd_socket(void)
2670 {
2671 MigrateCommon args = {
2672 .listen_uri = "defer",
2673 .connect_uri = "fd:fd-mig",
2674 .start_hook = test_migrate_fd_start_hook,
2675 .finish_hook = test_migrate_fd_finish_hook
2676 };
2677 test_precopy_common(&args);
2678 }
2679
migrate_precopy_fd_file_start(QTestState * from,QTestState * to)2680 static void *migrate_precopy_fd_file_start(QTestState *from, QTestState *to)
2681 {
2682 g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME);
2683 int src_flags = O_CREAT | O_RDWR;
2684 int dst_flags = O_CREAT | O_RDWR;
2685 int fds[2];
2686
2687 fds[0] = open(file, src_flags, 0660);
2688 assert(fds[0] != -1);
2689
2690 fds[1] = open(file, dst_flags, 0660);
2691 assert(fds[1] != -1);
2692
2693
2694 qtest_qmp_fds_assert_success(to, &fds[0], 1,
2695 "{ 'execute': 'getfd',"
2696 " 'arguments': { 'fdname': 'fd-mig' }}");
2697
2698 qtest_qmp_fds_assert_success(from, &fds[1], 1,
2699 "{ 'execute': 'getfd',"
2700 " 'arguments': { 'fdname': 'fd-mig' }}");
2701
2702 close(fds[0]);
2703 close(fds[1]);
2704
2705 return NULL;
2706 }
2707
test_migrate_precopy_fd_file(void)2708 static void test_migrate_precopy_fd_file(void)
2709 {
2710 MigrateCommon args = {
2711 .listen_uri = "defer",
2712 .connect_uri = "fd:fd-mig",
2713 .start_hook = migrate_precopy_fd_file_start,
2714 .finish_hook = test_migrate_fd_finish_hook
2715 };
2716 test_file_common(&args, true);
2717 }
2718 #endif /* _WIN32 */
2719
do_test_validate_uuid(MigrateStart * args,bool should_fail)2720 static void do_test_validate_uuid(MigrateStart *args, bool should_fail)
2721 {
2722 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2723 QTestState *from, *to;
2724
2725 if (test_migrate_start(&from, &to, uri, args)) {
2726 return;
2727 }
2728
2729 /*
2730 * UUID validation is at the begin of migration. So, the main process of
2731 * migration is not interesting for us here. Thus, set huge downtime for
2732 * very fast migration.
2733 */
2734 migrate_set_parameter_int(from, "downtime-limit", 1000000);
2735 migrate_set_capability(from, "validate-uuid", true);
2736
2737 /* Wait for the first serial output from the source */
2738 wait_for_serial("src_serial");
2739
2740 migrate_qmp(from, to, uri, NULL, "{}");
2741
2742 if (should_fail) {
2743 qtest_set_expected_status(to, EXIT_FAILURE);
2744 wait_for_migration_fail(from, true);
2745 } else {
2746 wait_for_migration_complete(from);
2747 }
2748
2749 test_migrate_end(from, to, false);
2750 }
2751
test_validate_uuid(void)2752 static void test_validate_uuid(void)
2753 {
2754 MigrateStart args = {
2755 .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
2756 .opts_target = "-uuid 11111111-1111-1111-1111-111111111111",
2757 };
2758
2759 do_test_validate_uuid(&args, false);
2760 }
2761
test_validate_uuid_error(void)2762 static void test_validate_uuid_error(void)
2763 {
2764 MigrateStart args = {
2765 .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
2766 .opts_target = "-uuid 22222222-2222-2222-2222-222222222222",
2767 .hide_stderr = true,
2768 };
2769
2770 do_test_validate_uuid(&args, true);
2771 }
2772
test_validate_uuid_src_not_set(void)2773 static void test_validate_uuid_src_not_set(void)
2774 {
2775 MigrateStart args = {
2776 .opts_target = "-uuid 22222222-2222-2222-2222-222222222222",
2777 .hide_stderr = true,
2778 };
2779
2780 do_test_validate_uuid(&args, false);
2781 }
2782
test_validate_uuid_dst_not_set(void)2783 static void test_validate_uuid_dst_not_set(void)
2784 {
2785 MigrateStart args = {
2786 .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
2787 .hide_stderr = true,
2788 };
2789
2790 do_test_validate_uuid(&args, false);
2791 }
2792
do_test_validate_uri_channel(MigrateCommon * args)2793 static void do_test_validate_uri_channel(MigrateCommon *args)
2794 {
2795 QTestState *from, *to;
2796
2797 if (test_migrate_start(&from, &to, args->listen_uri, &args->start)) {
2798 return;
2799 }
2800
2801 /* Wait for the first serial output from the source */
2802 wait_for_serial("src_serial");
2803
2804 /*
2805 * 'uri' and 'channels' validation is checked even before the migration
2806 * starts.
2807 */
2808 migrate_qmp_fail(from, args->connect_uri, args->connect_channels, "{}");
2809 test_migrate_end(from, to, false);
2810 }
2811
test_validate_uri_channels_both_set(void)2812 static void test_validate_uri_channels_both_set(void)
2813 {
2814 MigrateCommon args = {
2815 .start = {
2816 .hide_stderr = true,
2817 },
2818 .listen_uri = "defer",
2819 .connect_uri = "tcp:127.0.0.1:0",
2820 .connect_channels = "[ { 'channel-type': 'main',"
2821 " 'addr': { 'transport': 'socket',"
2822 " 'type': 'inet',"
2823 " 'host': '127.0.0.1',"
2824 " 'port': '0' } } ]",
2825 };
2826
2827 do_test_validate_uri_channel(&args);
2828 }
2829
test_validate_uri_channels_none_set(void)2830 static void test_validate_uri_channels_none_set(void)
2831 {
2832 MigrateCommon args = {
2833 .start = {
2834 .hide_stderr = true,
2835 },
2836 .listen_uri = "defer",
2837 };
2838
2839 do_test_validate_uri_channel(&args);
2840 }
2841
2842 /*
2843 * The way auto_converge works, we need to do too many passes to
2844 * run this test. Auto_converge logic is only run once every
2845 * three iterations, so:
2846 *
2847 * - 3 iterations without auto_converge enabled
2848 * - 3 iterations with pct = 5
2849 * - 3 iterations with pct = 30
2850 * - 3 iterations with pct = 55
2851 * - 3 iterations with pct = 80
2852 * - 3 iterations with pct = 95 (max(95, 80 + 25))
2853 *
2854 * To make things even worse, we need to run the initial stage at
2855 * 3MB/s so we enter autoconverge even when host is (over)loaded.
2856 */
test_migrate_auto_converge(void)2857 static void test_migrate_auto_converge(void)
2858 {
2859 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
2860 MigrateStart args = {};
2861 QTestState *from, *to;
2862 int64_t percentage;
2863
2864 /*
2865 * We want the test to be stable and as fast as possible.
2866 * E.g., with 1Gb/s bandwidth migration may pass without throttling,
2867 * so we need to decrease a bandwidth.
2868 */
2869 const int64_t init_pct = 5, inc_pct = 25, max_pct = 95;
2870
2871 if (test_migrate_start(&from, &to, uri, &args)) {
2872 return;
2873 }
2874
2875 migrate_set_capability(from, "auto-converge", true);
2876 migrate_set_parameter_int(from, "cpu-throttle-initial", init_pct);
2877 migrate_set_parameter_int(from, "cpu-throttle-increment", inc_pct);
2878 migrate_set_parameter_int(from, "max-cpu-throttle", max_pct);
2879
2880 /*
2881 * Set the initial parameters so that the migration could not converge
2882 * without throttling.
2883 */
2884 migrate_ensure_non_converge(from);
2885
2886 /* To check remaining size after precopy */
2887 migrate_set_capability(from, "pause-before-switchover", true);
2888
2889 /* Wait for the first serial output from the source */
2890 wait_for_serial("src_serial");
2891
2892 migrate_qmp(from, to, uri, NULL, "{}");
2893
2894 /* Wait for throttling begins */
2895 percentage = 0;
2896 do {
2897 percentage = read_migrate_property_int(from, "cpu-throttle-percentage");
2898 if (percentage != 0) {
2899 break;
2900 }
2901 usleep(20);
2902 g_assert_false(src_state.stop_seen);
2903 } while (true);
2904 /* The first percentage of throttling should be at least init_pct */
2905 g_assert_cmpint(percentage, >=, init_pct);
2906 /* Now, when we tested that throttling works, let it converge */
2907 migrate_ensure_converge(from);
2908
2909 /*
2910 * Wait for pre-switchover status to check last throttle percentage
2911 * and remaining. These values will be zeroed later
2912 */
2913 wait_for_migration_status(from, "pre-switchover", NULL);
2914
2915 /* The final percentage of throttling shouldn't be greater than max_pct */
2916 percentage = read_migrate_property_int(from, "cpu-throttle-percentage");
2917 g_assert_cmpint(percentage, <=, max_pct);
2918 migrate_continue(from, "pre-switchover");
2919
2920 qtest_qmp_eventwait(to, "RESUME");
2921
2922 wait_for_serial("dest_serial");
2923 wait_for_migration_complete(from);
2924
2925 test_migrate_end(from, to, true);
2926 }
2927
2928 static void *
test_migrate_precopy_tcp_multifd_start_common(QTestState * from,QTestState * to,const char * method)2929 test_migrate_precopy_tcp_multifd_start_common(QTestState *from,
2930 QTestState *to,
2931 const char *method)
2932 {
2933 migrate_set_parameter_int(from, "multifd-channels", 16);
2934 migrate_set_parameter_int(to, "multifd-channels", 16);
2935
2936 migrate_set_parameter_str(from, "multifd-compression", method);
2937 migrate_set_parameter_str(to, "multifd-compression", method);
2938
2939 migrate_set_capability(from, "multifd", true);
2940 migrate_set_capability(to, "multifd", true);
2941
2942 /* Start incoming migration from the 1st socket */
2943 migrate_incoming_qmp(to, "tcp:127.0.0.1:0", "{}");
2944
2945 return NULL;
2946 }
2947
2948 static void *
test_migrate_precopy_tcp_multifd_start(QTestState * from,QTestState * to)2949 test_migrate_precopy_tcp_multifd_start(QTestState *from,
2950 QTestState *to)
2951 {
2952 return test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
2953 }
2954
2955 static void *
test_migrate_precopy_tcp_multifd_start_zero_page_legacy(QTestState * from,QTestState * to)2956 test_migrate_precopy_tcp_multifd_start_zero_page_legacy(QTestState *from,
2957 QTestState *to)
2958 {
2959 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
2960 migrate_set_parameter_str(from, "zero-page-detection", "legacy");
2961 return NULL;
2962 }
2963
2964 static void *
test_migration_precopy_tcp_multifd_start_no_zero_page(QTestState * from,QTestState * to)2965 test_migration_precopy_tcp_multifd_start_no_zero_page(QTestState *from,
2966 QTestState *to)
2967 {
2968 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
2969 migrate_set_parameter_str(from, "zero-page-detection", "none");
2970 return NULL;
2971 }
2972
2973 static void *
test_migrate_precopy_tcp_multifd_zlib_start(QTestState * from,QTestState * to)2974 test_migrate_precopy_tcp_multifd_zlib_start(QTestState *from,
2975 QTestState *to)
2976 {
2977 /*
2978 * Overloading this test to also check that set_parameter does not error.
2979 * This is also done in the tests for the other compression methods.
2980 */
2981 migrate_set_parameter_int(from, "multifd-zlib-level", 2);
2982 migrate_set_parameter_int(to, "multifd-zlib-level", 2);
2983
2984 return test_migrate_precopy_tcp_multifd_start_common(from, to, "zlib");
2985 }
2986
2987 #ifdef CONFIG_ZSTD
2988 static void *
test_migrate_precopy_tcp_multifd_zstd_start(QTestState * from,QTestState * to)2989 test_migrate_precopy_tcp_multifd_zstd_start(QTestState *from,
2990 QTestState *to)
2991 {
2992 migrate_set_parameter_int(from, "multifd-zstd-level", 2);
2993 migrate_set_parameter_int(to, "multifd-zstd-level", 2);
2994
2995 return test_migrate_precopy_tcp_multifd_start_common(from, to, "zstd");
2996 }
2997 #endif /* CONFIG_ZSTD */
2998
2999 #ifdef CONFIG_QPL
3000 static void *
test_migrate_precopy_tcp_multifd_qpl_start(QTestState * from,QTestState * to)3001 test_migrate_precopy_tcp_multifd_qpl_start(QTestState *from,
3002 QTestState *to)
3003 {
3004 return test_migrate_precopy_tcp_multifd_start_common(from, to, "qpl");
3005 }
3006 #endif /* CONFIG_QPL */
3007 #ifdef CONFIG_UADK
3008 static void *
test_migrate_precopy_tcp_multifd_uadk_start(QTestState * from,QTestState * to)3009 test_migrate_precopy_tcp_multifd_uadk_start(QTestState *from,
3010 QTestState *to)
3011 {
3012 return test_migrate_precopy_tcp_multifd_start_common(from, to, "uadk");
3013 }
3014 #endif /* CONFIG_UADK */
3015
test_multifd_tcp_uri_none(void)3016 static void test_multifd_tcp_uri_none(void)
3017 {
3018 MigrateCommon args = {
3019 .listen_uri = "defer",
3020 .start_hook = test_migrate_precopy_tcp_multifd_start,
3021 /*
3022 * Multifd is more complicated than most of the features, it
3023 * directly takes guest page buffers when sending, make sure
3024 * everything will work alright even if guest page is changing.
3025 */
3026 .live = true,
3027 };
3028 test_precopy_common(&args);
3029 }
3030
test_multifd_tcp_zero_page_legacy(void)3031 static void test_multifd_tcp_zero_page_legacy(void)
3032 {
3033 MigrateCommon args = {
3034 .listen_uri = "defer",
3035 .start_hook = test_migrate_precopy_tcp_multifd_start_zero_page_legacy,
3036 /*
3037 * Multifd is more complicated than most of the features, it
3038 * directly takes guest page buffers when sending, make sure
3039 * everything will work alright even if guest page is changing.
3040 */
3041 .live = true,
3042 };
3043 test_precopy_common(&args);
3044 }
3045
test_multifd_tcp_no_zero_page(void)3046 static void test_multifd_tcp_no_zero_page(void)
3047 {
3048 MigrateCommon args = {
3049 .listen_uri = "defer",
3050 .start_hook = test_migration_precopy_tcp_multifd_start_no_zero_page,
3051 /*
3052 * Multifd is more complicated than most of the features, it
3053 * directly takes guest page buffers when sending, make sure
3054 * everything will work alright even if guest page is changing.
3055 */
3056 .live = true,
3057 };
3058 test_precopy_common(&args);
3059 }
3060
test_multifd_tcp_channels_none(void)3061 static void test_multifd_tcp_channels_none(void)
3062 {
3063 MigrateCommon args = {
3064 .listen_uri = "defer",
3065 .start_hook = test_migrate_precopy_tcp_multifd_start,
3066 .live = true,
3067 .connect_channels = "[ { 'channel-type': 'main',"
3068 " 'addr': { 'transport': 'socket',"
3069 " 'type': 'inet',"
3070 " 'host': '127.0.0.1',"
3071 " 'port': '0' } } ]",
3072 };
3073 test_precopy_common(&args);
3074 }
3075
test_multifd_tcp_zlib(void)3076 static void test_multifd_tcp_zlib(void)
3077 {
3078 MigrateCommon args = {
3079 .listen_uri = "defer",
3080 .start_hook = test_migrate_precopy_tcp_multifd_zlib_start,
3081 };
3082 test_precopy_common(&args);
3083 }
3084
3085 #ifdef CONFIG_ZSTD
test_multifd_tcp_zstd(void)3086 static void test_multifd_tcp_zstd(void)
3087 {
3088 MigrateCommon args = {
3089 .listen_uri = "defer",
3090 .start_hook = test_migrate_precopy_tcp_multifd_zstd_start,
3091 };
3092 test_precopy_common(&args);
3093 }
3094 #endif
3095
3096 #ifdef CONFIG_QPL
test_multifd_tcp_qpl(void)3097 static void test_multifd_tcp_qpl(void)
3098 {
3099 MigrateCommon args = {
3100 .listen_uri = "defer",
3101 .start_hook = test_migrate_precopy_tcp_multifd_qpl_start,
3102 };
3103 test_precopy_common(&args);
3104 }
3105 #endif
3106
3107 #ifdef CONFIG_UADK
test_multifd_tcp_uadk(void)3108 static void test_multifd_tcp_uadk(void)
3109 {
3110 MigrateCommon args = {
3111 .listen_uri = "defer",
3112 .start_hook = test_migrate_precopy_tcp_multifd_uadk_start,
3113 };
3114 test_precopy_common(&args);
3115 }
3116 #endif
3117
3118 #ifdef CONFIG_GNUTLS
3119 static void *
test_migrate_multifd_tcp_tls_psk_start_match(QTestState * from,QTestState * to)3120 test_migrate_multifd_tcp_tls_psk_start_match(QTestState *from,
3121 QTestState *to)
3122 {
3123 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3124 return test_migrate_tls_psk_start_match(from, to);
3125 }
3126
3127 static void *
test_migrate_multifd_tcp_tls_psk_start_mismatch(QTestState * from,QTestState * to)3128 test_migrate_multifd_tcp_tls_psk_start_mismatch(QTestState *from,
3129 QTestState *to)
3130 {
3131 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3132 return test_migrate_tls_psk_start_mismatch(from, to);
3133 }
3134
3135 #ifdef CONFIG_TASN1
3136 static void *
test_migrate_multifd_tls_x509_start_default_host(QTestState * from,QTestState * to)3137 test_migrate_multifd_tls_x509_start_default_host(QTestState *from,
3138 QTestState *to)
3139 {
3140 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3141 return test_migrate_tls_x509_start_default_host(from, to);
3142 }
3143
3144 static void *
test_migrate_multifd_tls_x509_start_override_host(QTestState * from,QTestState * to)3145 test_migrate_multifd_tls_x509_start_override_host(QTestState *from,
3146 QTestState *to)
3147 {
3148 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3149 return test_migrate_tls_x509_start_override_host(from, to);
3150 }
3151
3152 static void *
test_migrate_multifd_tls_x509_start_mismatch_host(QTestState * from,QTestState * to)3153 test_migrate_multifd_tls_x509_start_mismatch_host(QTestState *from,
3154 QTestState *to)
3155 {
3156 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3157 return test_migrate_tls_x509_start_mismatch_host(from, to);
3158 }
3159
3160 static void *
test_migrate_multifd_tls_x509_start_allow_anon_client(QTestState * from,QTestState * to)3161 test_migrate_multifd_tls_x509_start_allow_anon_client(QTestState *from,
3162 QTestState *to)
3163 {
3164 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3165 return test_migrate_tls_x509_start_allow_anon_client(from, to);
3166 }
3167
3168 static void *
test_migrate_multifd_tls_x509_start_reject_anon_client(QTestState * from,QTestState * to)3169 test_migrate_multifd_tls_x509_start_reject_anon_client(QTestState *from,
3170 QTestState *to)
3171 {
3172 test_migrate_precopy_tcp_multifd_start_common(from, to, "none");
3173 return test_migrate_tls_x509_start_reject_anon_client(from, to);
3174 }
3175 #endif /* CONFIG_TASN1 */
3176
test_multifd_tcp_tls_psk_match(void)3177 static void test_multifd_tcp_tls_psk_match(void)
3178 {
3179 MigrateCommon args = {
3180 .listen_uri = "defer",
3181 .start_hook = test_migrate_multifd_tcp_tls_psk_start_match,
3182 .finish_hook = test_migrate_tls_psk_finish,
3183 };
3184 test_precopy_common(&args);
3185 }
3186
test_multifd_tcp_tls_psk_mismatch(void)3187 static void test_multifd_tcp_tls_psk_mismatch(void)
3188 {
3189 MigrateCommon args = {
3190 .start = {
3191 .hide_stderr = true,
3192 },
3193 .listen_uri = "defer",
3194 .start_hook = test_migrate_multifd_tcp_tls_psk_start_mismatch,
3195 .finish_hook = test_migrate_tls_psk_finish,
3196 .result = MIG_TEST_FAIL,
3197 };
3198 test_precopy_common(&args);
3199 }
3200
3201 #ifdef CONFIG_TASN1
test_multifd_tcp_tls_x509_default_host(void)3202 static void test_multifd_tcp_tls_x509_default_host(void)
3203 {
3204 MigrateCommon args = {
3205 .listen_uri = "defer",
3206 .start_hook = test_migrate_multifd_tls_x509_start_default_host,
3207 .finish_hook = test_migrate_tls_x509_finish,
3208 };
3209 test_precopy_common(&args);
3210 }
3211
test_multifd_tcp_tls_x509_override_host(void)3212 static void test_multifd_tcp_tls_x509_override_host(void)
3213 {
3214 MigrateCommon args = {
3215 .listen_uri = "defer",
3216 .start_hook = test_migrate_multifd_tls_x509_start_override_host,
3217 .finish_hook = test_migrate_tls_x509_finish,
3218 };
3219 test_precopy_common(&args);
3220 }
3221
test_multifd_tcp_tls_x509_mismatch_host(void)3222 static void test_multifd_tcp_tls_x509_mismatch_host(void)
3223 {
3224 /*
3225 * This has different behaviour to the non-multifd case.
3226 *
3227 * In non-multifd case when client aborts due to mismatched
3228 * cert host, the server has already started trying to load
3229 * migration state, and so it exits with I/O failure.
3230 *
3231 * In multifd case when client aborts due to mismatched
3232 * cert host, the server is still waiting for the other
3233 * multifd connections to arrive so hasn't started trying
3234 * to load migration state, and thus just aborts the migration
3235 * without exiting.
3236 */
3237 MigrateCommon args = {
3238 .start = {
3239 .hide_stderr = true,
3240 },
3241 .listen_uri = "defer",
3242 .start_hook = test_migrate_multifd_tls_x509_start_mismatch_host,
3243 .finish_hook = test_migrate_tls_x509_finish,
3244 .result = MIG_TEST_FAIL,
3245 };
3246 test_precopy_common(&args);
3247 }
3248
test_multifd_tcp_tls_x509_allow_anon_client(void)3249 static void test_multifd_tcp_tls_x509_allow_anon_client(void)
3250 {
3251 MigrateCommon args = {
3252 .listen_uri = "defer",
3253 .start_hook = test_migrate_multifd_tls_x509_start_allow_anon_client,
3254 .finish_hook = test_migrate_tls_x509_finish,
3255 };
3256 test_precopy_common(&args);
3257 }
3258
test_multifd_tcp_tls_x509_reject_anon_client(void)3259 static void test_multifd_tcp_tls_x509_reject_anon_client(void)
3260 {
3261 MigrateCommon args = {
3262 .start = {
3263 .hide_stderr = true,
3264 },
3265 .listen_uri = "defer",
3266 .start_hook = test_migrate_multifd_tls_x509_start_reject_anon_client,
3267 .finish_hook = test_migrate_tls_x509_finish,
3268 .result = MIG_TEST_FAIL,
3269 };
3270 test_precopy_common(&args);
3271 }
3272 #endif /* CONFIG_TASN1 */
3273 #endif /* CONFIG_GNUTLS */
3274
3275 /*
3276 * This test does:
3277 * source target
3278 * migrate_incoming
3279 * migrate
3280 * migrate_cancel
3281 * launch another target
3282 * migrate
3283 *
3284 * And see that it works
3285 */
test_multifd_tcp_cancel(void)3286 static void test_multifd_tcp_cancel(void)
3287 {
3288 MigrateStart args = {
3289 .hide_stderr = true,
3290 };
3291 QTestState *from, *to, *to2;
3292
3293 if (test_migrate_start(&from, &to, "defer", &args)) {
3294 return;
3295 }
3296
3297 migrate_ensure_non_converge(from);
3298 migrate_prepare_for_dirty_mem(from);
3299
3300 migrate_set_parameter_int(from, "multifd-channels", 16);
3301 migrate_set_parameter_int(to, "multifd-channels", 16);
3302
3303 migrate_set_capability(from, "multifd", true);
3304 migrate_set_capability(to, "multifd", true);
3305
3306 /* Start incoming migration from the 1st socket */
3307 migrate_incoming_qmp(to, "tcp:127.0.0.1:0", "{}");
3308
3309 /* Wait for the first serial output from the source */
3310 wait_for_serial("src_serial");
3311
3312 migrate_qmp(from, to, NULL, NULL, "{}");
3313
3314 migrate_wait_for_dirty_mem(from, to);
3315
3316 migrate_cancel(from);
3317
3318 /* Make sure QEMU process "to" exited */
3319 qtest_set_expected_status(to, EXIT_FAILURE);
3320 qtest_wait_qemu(to);
3321
3322 args = (MigrateStart){
3323 .only_target = true,
3324 };
3325
3326 if (test_migrate_start(&from, &to2, "defer", &args)) {
3327 return;
3328 }
3329
3330 migrate_set_parameter_int(to2, "multifd-channels", 16);
3331
3332 migrate_set_capability(to2, "multifd", true);
3333
3334 /* Start incoming migration from the 1st socket */
3335 migrate_incoming_qmp(to2, "tcp:127.0.0.1:0", "{}");
3336
3337 wait_for_migration_status(from, "cancelled", NULL);
3338
3339 migrate_ensure_non_converge(from);
3340
3341 migrate_qmp(from, to2, NULL, NULL, "{}");
3342
3343 migrate_wait_for_dirty_mem(from, to2);
3344
3345 migrate_ensure_converge(from);
3346
3347 wait_for_stop(from, &src_state);
3348 qtest_qmp_eventwait(to2, "RESUME");
3349
3350 wait_for_serial("dest_serial");
3351 wait_for_migration_complete(from);
3352 test_migrate_end(from, to2, true);
3353 }
3354
calc_dirty_rate(QTestState * who,uint64_t calc_time)3355 static void calc_dirty_rate(QTestState *who, uint64_t calc_time)
3356 {
3357 qtest_qmp_assert_success(who,
3358 "{ 'execute': 'calc-dirty-rate',"
3359 "'arguments': { "
3360 "'calc-time': %" PRIu64 ","
3361 "'mode': 'dirty-ring' }}",
3362 calc_time);
3363 }
3364
query_dirty_rate(QTestState * who)3365 static QDict *query_dirty_rate(QTestState *who)
3366 {
3367 return qtest_qmp_assert_success_ref(who,
3368 "{ 'execute': 'query-dirty-rate' }");
3369 }
3370
dirtylimit_set_all(QTestState * who,uint64_t dirtyrate)3371 static void dirtylimit_set_all(QTestState *who, uint64_t dirtyrate)
3372 {
3373 qtest_qmp_assert_success(who,
3374 "{ 'execute': 'set-vcpu-dirty-limit',"
3375 "'arguments': { "
3376 "'dirty-rate': %" PRIu64 " } }",
3377 dirtyrate);
3378 }
3379
cancel_vcpu_dirty_limit(QTestState * who)3380 static void cancel_vcpu_dirty_limit(QTestState *who)
3381 {
3382 qtest_qmp_assert_success(who,
3383 "{ 'execute': 'cancel-vcpu-dirty-limit' }");
3384 }
3385
query_vcpu_dirty_limit(QTestState * who)3386 static QDict *query_vcpu_dirty_limit(QTestState *who)
3387 {
3388 QDict *rsp;
3389
3390 rsp = qtest_qmp(who, "{ 'execute': 'query-vcpu-dirty-limit' }");
3391 g_assert(!qdict_haskey(rsp, "error"));
3392 g_assert(qdict_haskey(rsp, "return"));
3393
3394 return rsp;
3395 }
3396
calc_dirtyrate_ready(QTestState * who)3397 static bool calc_dirtyrate_ready(QTestState *who)
3398 {
3399 QDict *rsp_return;
3400 gchar *status;
3401
3402 rsp_return = query_dirty_rate(who);
3403 g_assert(rsp_return);
3404
3405 status = g_strdup(qdict_get_str(rsp_return, "status"));
3406 g_assert(status);
3407
3408 return g_strcmp0(status, "measuring");
3409 }
3410
wait_for_calc_dirtyrate_complete(QTestState * who,int64_t time_s)3411 static void wait_for_calc_dirtyrate_complete(QTestState *who,
3412 int64_t time_s)
3413 {
3414 int max_try_count = 10000;
3415 usleep(time_s * 1000000);
3416
3417 while (!calc_dirtyrate_ready(who) && max_try_count--) {
3418 usleep(1000);
3419 }
3420
3421 /*
3422 * Set the timeout with 10 s(max_try_count * 1000us),
3423 * if dirtyrate measurement not complete, fail test.
3424 */
3425 g_assert_cmpint(max_try_count, !=, 0);
3426 }
3427
get_dirty_rate(QTestState * who)3428 static int64_t get_dirty_rate(QTestState *who)
3429 {
3430 QDict *rsp_return;
3431 gchar *status;
3432 QList *rates;
3433 const QListEntry *entry;
3434 QDict *rate;
3435 int64_t dirtyrate;
3436
3437 rsp_return = query_dirty_rate(who);
3438 g_assert(rsp_return);
3439
3440 status = g_strdup(qdict_get_str(rsp_return, "status"));
3441 g_assert(status);
3442 g_assert_cmpstr(status, ==, "measured");
3443
3444 rates = qdict_get_qlist(rsp_return, "vcpu-dirty-rate");
3445 g_assert(rates && !qlist_empty(rates));
3446
3447 entry = qlist_first(rates);
3448 g_assert(entry);
3449
3450 rate = qobject_to(QDict, qlist_entry_obj(entry));
3451 g_assert(rate);
3452
3453 dirtyrate = qdict_get_try_int(rate, "dirty-rate", -1);
3454
3455 qobject_unref(rsp_return);
3456 return dirtyrate;
3457 }
3458
get_limit_rate(QTestState * who)3459 static int64_t get_limit_rate(QTestState *who)
3460 {
3461 QDict *rsp_return;
3462 QList *rates;
3463 const QListEntry *entry;
3464 QDict *rate;
3465 int64_t dirtyrate;
3466
3467 rsp_return = query_vcpu_dirty_limit(who);
3468 g_assert(rsp_return);
3469
3470 rates = qdict_get_qlist(rsp_return, "return");
3471 g_assert(rates && !qlist_empty(rates));
3472
3473 entry = qlist_first(rates);
3474 g_assert(entry);
3475
3476 rate = qobject_to(QDict, qlist_entry_obj(entry));
3477 g_assert(rate);
3478
3479 dirtyrate = qdict_get_try_int(rate, "limit-rate", -1);
3480
3481 qobject_unref(rsp_return);
3482 return dirtyrate;
3483 }
3484
dirtylimit_start_vm(void)3485 static QTestState *dirtylimit_start_vm(void)
3486 {
3487 QTestState *vm = NULL;
3488 g_autofree gchar *cmd = NULL;
3489
3490 bootfile_create(tmpfs, false);
3491 cmd = g_strdup_printf("-accel kvm,dirty-ring-size=4096 "
3492 "-name dirtylimit-test,debug-threads=on "
3493 "-m 150M -smp 1 "
3494 "-serial file:%s/vm_serial "
3495 "-drive file=%s,format=raw ",
3496 tmpfs, bootpath);
3497
3498 vm = qtest_init(cmd);
3499 return vm;
3500 }
3501
dirtylimit_stop_vm(QTestState * vm)3502 static void dirtylimit_stop_vm(QTestState *vm)
3503 {
3504 qtest_quit(vm);
3505 cleanup("vm_serial");
3506 }
3507
test_vcpu_dirty_limit(void)3508 static void test_vcpu_dirty_limit(void)
3509 {
3510 QTestState *vm;
3511 int64_t origin_rate;
3512 int64_t quota_rate;
3513 int64_t rate ;
3514 int max_try_count = 20;
3515 int hit = 0;
3516
3517 /* Start vm for vcpu dirtylimit test */
3518 vm = dirtylimit_start_vm();
3519
3520 /* Wait for the first serial output from the vm*/
3521 wait_for_serial("vm_serial");
3522
3523 /* Do dirtyrate measurement with calc time equals 1s */
3524 calc_dirty_rate(vm, 1);
3525
3526 /* Sleep calc time and wait for calc dirtyrate complete */
3527 wait_for_calc_dirtyrate_complete(vm, 1);
3528
3529 /* Query original dirty page rate */
3530 origin_rate = get_dirty_rate(vm);
3531
3532 /* VM booted from bootsect should dirty memory steadily */
3533 assert(origin_rate != 0);
3534
3535 /* Setup quota dirty page rate at half of origin */
3536 quota_rate = origin_rate / 2;
3537
3538 /* Set dirtylimit */
3539 dirtylimit_set_all(vm, quota_rate);
3540
3541 /*
3542 * Check if set-vcpu-dirty-limit and query-vcpu-dirty-limit
3543 * works literally
3544 */
3545 g_assert_cmpint(quota_rate, ==, get_limit_rate(vm));
3546
3547 /* Sleep a bit to check if it take effect */
3548 usleep(2000000);
3549
3550 /*
3551 * Check if dirtylimit take effect realistically, set the
3552 * timeout with 20 s(max_try_count * 1s), if dirtylimit
3553 * doesn't take effect, fail test.
3554 */
3555 while (--max_try_count) {
3556 calc_dirty_rate(vm, 1);
3557 wait_for_calc_dirtyrate_complete(vm, 1);
3558 rate = get_dirty_rate(vm);
3559
3560 /*
3561 * Assume hitting if current rate is less
3562 * than quota rate (within accepting error)
3563 */
3564 if (rate < (quota_rate + DIRTYLIMIT_TOLERANCE_RANGE)) {
3565 hit = 1;
3566 break;
3567 }
3568 }
3569
3570 g_assert_cmpint(hit, ==, 1);
3571
3572 hit = 0;
3573 max_try_count = 20;
3574
3575 /* Check if dirtylimit cancellation take effect */
3576 cancel_vcpu_dirty_limit(vm);
3577 while (--max_try_count) {
3578 calc_dirty_rate(vm, 1);
3579 wait_for_calc_dirtyrate_complete(vm, 1);
3580 rate = get_dirty_rate(vm);
3581
3582 /*
3583 * Assume dirtylimit be canceled if current rate is
3584 * greater than quota rate (within accepting error)
3585 */
3586 if (rate > (quota_rate + DIRTYLIMIT_TOLERANCE_RANGE)) {
3587 hit = 1;
3588 break;
3589 }
3590 }
3591
3592 g_assert_cmpint(hit, ==, 1);
3593 dirtylimit_stop_vm(vm);
3594 }
3595
migrate_dirty_limit_wait_showup(QTestState * from,const int64_t period,const int64_t value)3596 static void migrate_dirty_limit_wait_showup(QTestState *from,
3597 const int64_t period,
3598 const int64_t value)
3599 {
3600 /* Enable dirty limit capability */
3601 migrate_set_capability(from, "dirty-limit", true);
3602
3603 /* Set dirty limit parameters */
3604 migrate_set_parameter_int(from, "x-vcpu-dirty-limit-period", period);
3605 migrate_set_parameter_int(from, "vcpu-dirty-limit", value);
3606
3607 /* Make sure migrate can't converge */
3608 migrate_ensure_non_converge(from);
3609
3610 /* To check limit rate after precopy */
3611 migrate_set_capability(from, "pause-before-switchover", true);
3612
3613 /* Wait for the serial output from the source */
3614 wait_for_serial("src_serial");
3615 }
3616
3617 /*
3618 * This test does:
3619 * source destination
3620 * start vm
3621 * start incoming vm
3622 * migrate
3623 * wait dirty limit to begin
3624 * cancel migrate
3625 * cancellation check
3626 * restart incoming vm
3627 * migrate
3628 * wait dirty limit to begin
3629 * wait pre-switchover event
3630 * convergence condition check
3631 *
3632 * And see if dirty limit migration works correctly.
3633 * This test case involves many passes, so it runs in slow mode only.
3634 */
test_migrate_dirty_limit(void)3635 static void test_migrate_dirty_limit(void)
3636 {
3637 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
3638 QTestState *from, *to;
3639 int64_t remaining;
3640 uint64_t throttle_us_per_full;
3641 /*
3642 * We want the test to be stable and as fast as possible.
3643 * E.g., with 1Gb/s bandwidth migration may pass without dirty limit,
3644 * so we need to decrease a bandwidth.
3645 */
3646 const int64_t dirtylimit_period = 1000, dirtylimit_value = 50;
3647 const int64_t max_bandwidth = 400000000; /* ~400Mb/s */
3648 const int64_t downtime_limit = 250; /* 250ms */
3649 /*
3650 * We migrate through unix-socket (> 500Mb/s).
3651 * Thus, expected migration speed ~= bandwidth limit (< 500Mb/s).
3652 * So, we can predict expected_threshold
3653 */
3654 const int64_t expected_threshold = max_bandwidth * downtime_limit / 1000;
3655 int max_try_count = 10;
3656 MigrateCommon args = {
3657 .start = {
3658 .hide_stderr = true,
3659 .use_dirty_ring = true,
3660 },
3661 .listen_uri = uri,
3662 .connect_uri = uri,
3663 };
3664
3665 /* Start src, dst vm */
3666 if (test_migrate_start(&from, &to, args.listen_uri, &args.start)) {
3667 return;
3668 }
3669
3670 /* Prepare for dirty limit migration and wait src vm show up */
3671 migrate_dirty_limit_wait_showup(from, dirtylimit_period, dirtylimit_value);
3672
3673 /* Start migrate */
3674 migrate_qmp(from, to, args.connect_uri, NULL, "{}");
3675
3676 /* Wait for dirty limit throttle begin */
3677 throttle_us_per_full = 0;
3678 while (throttle_us_per_full == 0) {
3679 throttle_us_per_full =
3680 read_migrate_property_int(from, "dirty-limit-throttle-time-per-round");
3681 usleep(100);
3682 g_assert_false(src_state.stop_seen);
3683 }
3684
3685 /* Now cancel migrate and wait for dirty limit throttle switch off */
3686 migrate_cancel(from);
3687 wait_for_migration_status(from, "cancelled", NULL);
3688
3689 /* Check if dirty limit throttle switched off, set timeout 1ms */
3690 do {
3691 throttle_us_per_full =
3692 read_migrate_property_int(from, "dirty-limit-throttle-time-per-round");
3693 usleep(100);
3694 g_assert_false(src_state.stop_seen);
3695 } while (throttle_us_per_full != 0 && --max_try_count);
3696
3697 /* Assert dirty limit is not in service */
3698 g_assert_cmpint(throttle_us_per_full, ==, 0);
3699
3700 args = (MigrateCommon) {
3701 .start = {
3702 .only_target = true,
3703 .use_dirty_ring = true,
3704 },
3705 .listen_uri = uri,
3706 .connect_uri = uri,
3707 };
3708
3709 /* Restart dst vm, src vm already show up so we needn't wait anymore */
3710 if (test_migrate_start(&from, &to, args.listen_uri, &args.start)) {
3711 return;
3712 }
3713
3714 /* Start migrate */
3715 migrate_qmp(from, to, args.connect_uri, NULL, "{}");
3716
3717 /* Wait for dirty limit throttle begin */
3718 throttle_us_per_full = 0;
3719 while (throttle_us_per_full == 0) {
3720 throttle_us_per_full =
3721 read_migrate_property_int(from, "dirty-limit-throttle-time-per-round");
3722 usleep(100);
3723 g_assert_false(src_state.stop_seen);
3724 }
3725
3726 /*
3727 * The dirty limit rate should equals the return value of
3728 * query-vcpu-dirty-limit if dirty limit cap set
3729 */
3730 g_assert_cmpint(dirtylimit_value, ==, get_limit_rate(from));
3731
3732 /* Now, we have tested if dirty limit works, let it converge */
3733 migrate_set_parameter_int(from, "downtime-limit", downtime_limit);
3734 migrate_set_parameter_int(from, "max-bandwidth", max_bandwidth);
3735
3736 /*
3737 * Wait for pre-switchover status to check if migration
3738 * satisfy the convergence condition
3739 */
3740 wait_for_migration_status(from, "pre-switchover", NULL);
3741
3742 remaining = read_ram_property_int(from, "remaining");
3743 g_assert_cmpint(remaining, <,
3744 (expected_threshold + expected_threshold / 100));
3745
3746 migrate_continue(from, "pre-switchover");
3747
3748 qtest_qmp_eventwait(to, "RESUME");
3749
3750 wait_for_serial("dest_serial");
3751 wait_for_migration_complete(from);
3752
3753 test_migrate_end(from, to, true);
3754 }
3755
kvm_dirty_ring_supported(void)3756 static bool kvm_dirty_ring_supported(void)
3757 {
3758 #if defined(__linux__) && defined(HOST_X86_64)
3759 int ret, kvm_fd = open("/dev/kvm", O_RDONLY);
3760
3761 if (kvm_fd < 0) {
3762 return false;
3763 }
3764
3765 ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, KVM_CAP_DIRTY_LOG_RING);
3766 close(kvm_fd);
3767
3768 /* We test with 4096 slots */
3769 if (ret < 4096) {
3770 return false;
3771 }
3772
3773 return true;
3774 #else
3775 return false;
3776 #endif
3777 }
3778
main(int argc,char ** argv)3779 int main(int argc, char **argv)
3780 {
3781 bool has_kvm, has_tcg;
3782 bool has_uffd, is_x86;
3783 const char *arch;
3784 g_autoptr(GError) err = NULL;
3785 const char *qemu_src = getenv(QEMU_ENV_SRC);
3786 const char *qemu_dst = getenv(QEMU_ENV_DST);
3787 int ret;
3788
3789 g_test_init(&argc, &argv, NULL);
3790
3791 /*
3792 * The default QTEST_QEMU_BINARY must always be provided because
3793 * that is what helpers use to query the accel type and
3794 * architecture.
3795 */
3796 if (qemu_src && qemu_dst) {
3797 g_test_message("Only one of %s, %s is allowed",
3798 QEMU_ENV_SRC, QEMU_ENV_DST);
3799 exit(1);
3800 }
3801
3802 has_kvm = qtest_has_accel("kvm");
3803 has_tcg = qtest_has_accel("tcg");
3804
3805 if (!has_tcg && !has_kvm) {
3806 g_test_skip("No KVM or TCG accelerator available");
3807 return 0;
3808 }
3809
3810 has_uffd = ufd_version_check();
3811 arch = qtest_get_arch();
3812 is_x86 = !strcmp(arch, "i386") || !strcmp(arch, "x86_64");
3813
3814 tmpfs = g_dir_make_tmp("migration-test-XXXXXX", &err);
3815 if (!tmpfs) {
3816 g_test_message("Can't create temporary directory in %s: %s",
3817 g_get_tmp_dir(), err->message);
3818 }
3819 g_assert(tmpfs);
3820
3821 module_call_init(MODULE_INIT_QOM);
3822
3823 migration_test_add("/migration/bad_dest", test_baddest);
3824 #ifndef _WIN32
3825 migration_test_add("/migration/analyze-script", test_analyze_script);
3826 migration_test_add("/migration/vmstate-checker-script",
3827 test_vmstate_checker_script);
3828 #endif
3829
3830 if (is_x86) {
3831 migration_test_add("/migration/precopy/unix/suspend/live",
3832 test_precopy_unix_suspend_live);
3833 migration_test_add("/migration/precopy/unix/suspend/notlive",
3834 test_precopy_unix_suspend_notlive);
3835 }
3836
3837 if (has_uffd) {
3838 migration_test_add("/migration/postcopy/plain", test_postcopy);
3839 migration_test_add("/migration/postcopy/recovery/plain",
3840 test_postcopy_recovery);
3841 migration_test_add("/migration/postcopy/preempt/plain",
3842 test_postcopy_preempt);
3843 migration_test_add("/migration/postcopy/preempt/recovery/plain",
3844 test_postcopy_preempt_recovery);
3845 migration_test_add("/migration/postcopy/recovery/double-failures/handshake",
3846 test_postcopy_recovery_fail_handshake);
3847 migration_test_add("/migration/postcopy/recovery/double-failures/reconnect",
3848 test_postcopy_recovery_fail_reconnect);
3849 if (is_x86) {
3850 migration_test_add("/migration/postcopy/suspend",
3851 test_postcopy_suspend);
3852 }
3853 }
3854
3855 migration_test_add("/migration/precopy/unix/plain",
3856 test_precopy_unix_plain);
3857 migration_test_add("/migration/precopy/unix/xbzrle",
3858 test_precopy_unix_xbzrle);
3859 migration_test_add("/migration/precopy/file",
3860 test_precopy_file);
3861 migration_test_add("/migration/precopy/file/offset",
3862 test_precopy_file_offset);
3863 #ifndef _WIN32
3864 migration_test_add("/migration/precopy/file/offset/fdset",
3865 test_precopy_file_offset_fdset);
3866 #endif
3867 migration_test_add("/migration/precopy/file/offset/bad",
3868 test_precopy_file_offset_bad);
3869
3870 /*
3871 * Our CI system has problems with shared memory.
3872 * Don't run this test until we find a workaround.
3873 */
3874 if (getenv("QEMU_TEST_FLAKY_TESTS")) {
3875 migration_test_add("/migration/mode/reboot", test_mode_reboot);
3876 }
3877
3878 migration_test_add("/migration/precopy/file/mapped-ram",
3879 test_precopy_file_mapped_ram);
3880 migration_test_add("/migration/precopy/file/mapped-ram/live",
3881 test_precopy_file_mapped_ram_live);
3882
3883 migration_test_add("/migration/multifd/file/mapped-ram",
3884 test_multifd_file_mapped_ram);
3885 migration_test_add("/migration/multifd/file/mapped-ram/live",
3886 test_multifd_file_mapped_ram_live);
3887
3888 migration_test_add("/migration/multifd/file/mapped-ram/dio",
3889 test_multifd_file_mapped_ram_dio);
3890
3891 #ifndef _WIN32
3892 migration_test_add("/migration/multifd/file/mapped-ram/fdset",
3893 test_multifd_file_mapped_ram_fdset);
3894 migration_test_add("/migration/multifd/file/mapped-ram/fdset/dio",
3895 test_multifd_file_mapped_ram_fdset_dio);
3896 #endif
3897
3898 #ifdef CONFIG_GNUTLS
3899 migration_test_add("/migration/precopy/unix/tls/psk",
3900 test_precopy_unix_tls_psk);
3901
3902 if (has_uffd) {
3903 /*
3904 * NOTE: psk test is enough for postcopy, as other types of TLS
3905 * channels are tested under precopy. Here what we want to test is the
3906 * general postcopy path that has TLS channel enabled.
3907 */
3908 migration_test_add("/migration/postcopy/tls/psk",
3909 test_postcopy_tls_psk);
3910 migration_test_add("/migration/postcopy/recovery/tls/psk",
3911 test_postcopy_recovery_tls_psk);
3912 migration_test_add("/migration/postcopy/preempt/tls/psk",
3913 test_postcopy_preempt_tls_psk);
3914 migration_test_add("/migration/postcopy/preempt/recovery/tls/psk",
3915 test_postcopy_preempt_all);
3916 }
3917 #ifdef CONFIG_TASN1
3918 migration_test_add("/migration/precopy/unix/tls/x509/default-host",
3919 test_precopy_unix_tls_x509_default_host);
3920 migration_test_add("/migration/precopy/unix/tls/x509/override-host",
3921 test_precopy_unix_tls_x509_override_host);
3922 #endif /* CONFIG_TASN1 */
3923 #endif /* CONFIG_GNUTLS */
3924
3925 migration_test_add("/migration/precopy/tcp/plain", test_precopy_tcp_plain);
3926
3927 migration_test_add("/migration/precopy/tcp/plain/switchover-ack",
3928 test_precopy_tcp_switchover_ack);
3929
3930 #ifdef CONFIG_GNUTLS
3931 migration_test_add("/migration/precopy/tcp/tls/psk/match",
3932 test_precopy_tcp_tls_psk_match);
3933 migration_test_add("/migration/precopy/tcp/tls/psk/mismatch",
3934 test_precopy_tcp_tls_psk_mismatch);
3935 #ifdef CONFIG_TASN1
3936 migration_test_add("/migration/precopy/tcp/tls/x509/default-host",
3937 test_precopy_tcp_tls_x509_default_host);
3938 migration_test_add("/migration/precopy/tcp/tls/x509/override-host",
3939 test_precopy_tcp_tls_x509_override_host);
3940 migration_test_add("/migration/precopy/tcp/tls/x509/mismatch-host",
3941 test_precopy_tcp_tls_x509_mismatch_host);
3942 migration_test_add("/migration/precopy/tcp/tls/x509/friendly-client",
3943 test_precopy_tcp_tls_x509_friendly_client);
3944 migration_test_add("/migration/precopy/tcp/tls/x509/hostile-client",
3945 test_precopy_tcp_tls_x509_hostile_client);
3946 migration_test_add("/migration/precopy/tcp/tls/x509/allow-anon-client",
3947 test_precopy_tcp_tls_x509_allow_anon_client);
3948 migration_test_add("/migration/precopy/tcp/tls/x509/reject-anon-client",
3949 test_precopy_tcp_tls_x509_reject_anon_client);
3950 #endif /* CONFIG_TASN1 */
3951 #endif /* CONFIG_GNUTLS */
3952
3953 /* migration_test_add("/migration/ignore_shared", test_ignore_shared); */
3954 #ifndef _WIN32
3955 migration_test_add("/migration/precopy/fd/tcp",
3956 test_migrate_precopy_fd_socket);
3957 migration_test_add("/migration/precopy/fd/file",
3958 test_migrate_precopy_fd_file);
3959 #endif
3960 migration_test_add("/migration/validate_uuid", test_validate_uuid);
3961 migration_test_add("/migration/validate_uuid_error",
3962 test_validate_uuid_error);
3963 migration_test_add("/migration/validate_uuid_src_not_set",
3964 test_validate_uuid_src_not_set);
3965 migration_test_add("/migration/validate_uuid_dst_not_set",
3966 test_validate_uuid_dst_not_set);
3967 migration_test_add("/migration/validate_uri/channels/both_set",
3968 test_validate_uri_channels_both_set);
3969 migration_test_add("/migration/validate_uri/channels/none_set",
3970 test_validate_uri_channels_none_set);
3971 /*
3972 * See explanation why this test is slow on function definition
3973 */
3974 if (g_test_slow()) {
3975 migration_test_add("/migration/auto_converge",
3976 test_migrate_auto_converge);
3977 if (g_str_equal(arch, "x86_64") &&
3978 has_kvm && kvm_dirty_ring_supported()) {
3979 migration_test_add("/migration/dirty_limit",
3980 test_migrate_dirty_limit);
3981 }
3982 }
3983 migration_test_add("/migration/multifd/tcp/uri/plain/none",
3984 test_multifd_tcp_uri_none);
3985 migration_test_add("/migration/multifd/tcp/channels/plain/none",
3986 test_multifd_tcp_channels_none);
3987 migration_test_add("/migration/multifd/tcp/plain/zero-page/legacy",
3988 test_multifd_tcp_zero_page_legacy);
3989 migration_test_add("/migration/multifd/tcp/plain/zero-page/none",
3990 test_multifd_tcp_no_zero_page);
3991 migration_test_add("/migration/multifd/tcp/plain/cancel",
3992 test_multifd_tcp_cancel);
3993 migration_test_add("/migration/multifd/tcp/plain/zlib",
3994 test_multifd_tcp_zlib);
3995 #ifdef CONFIG_ZSTD
3996 migration_test_add("/migration/multifd/tcp/plain/zstd",
3997 test_multifd_tcp_zstd);
3998 #endif
3999 #ifdef CONFIG_QPL
4000 migration_test_add("/migration/multifd/tcp/plain/qpl",
4001 test_multifd_tcp_qpl);
4002 #endif
4003 #ifdef CONFIG_UADK
4004 migration_test_add("/migration/multifd/tcp/plain/uadk",
4005 test_multifd_tcp_uadk);
4006 #endif
4007 #ifdef CONFIG_GNUTLS
4008 migration_test_add("/migration/multifd/tcp/tls/psk/match",
4009 test_multifd_tcp_tls_psk_match);
4010 migration_test_add("/migration/multifd/tcp/tls/psk/mismatch",
4011 test_multifd_tcp_tls_psk_mismatch);
4012 #ifdef CONFIG_TASN1
4013 migration_test_add("/migration/multifd/tcp/tls/x509/default-host",
4014 test_multifd_tcp_tls_x509_default_host);
4015 migration_test_add("/migration/multifd/tcp/tls/x509/override-host",
4016 test_multifd_tcp_tls_x509_override_host);
4017 migration_test_add("/migration/multifd/tcp/tls/x509/mismatch-host",
4018 test_multifd_tcp_tls_x509_mismatch_host);
4019 migration_test_add("/migration/multifd/tcp/tls/x509/allow-anon-client",
4020 test_multifd_tcp_tls_x509_allow_anon_client);
4021 migration_test_add("/migration/multifd/tcp/tls/x509/reject-anon-client",
4022 test_multifd_tcp_tls_x509_reject_anon_client);
4023 #endif /* CONFIG_TASN1 */
4024 #endif /* CONFIG_GNUTLS */
4025
4026 if (g_str_equal(arch, "x86_64") && has_kvm && kvm_dirty_ring_supported()) {
4027 migration_test_add("/migration/dirty_ring",
4028 test_precopy_unix_dirty_ring);
4029 migration_test_add("/migration/vcpu_dirty_limit",
4030 test_vcpu_dirty_limit);
4031 }
4032
4033 ret = g_test_run();
4034
4035 g_assert_cmpint(ret, ==, 0);
4036
4037 bootfile_delete();
4038 ret = rmdir(tmpfs);
4039 if (ret != 0) {
4040 g_test_message("unable to rmdir: path (%s): %s",
4041 tmpfs, strerror(errno));
4042 }
4043 g_free(tmpfs);
4044
4045 return ret;
4046 }
4047