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