iotests: check: multiprocessing support
[qemu/rayw.git] / tests / qtest / virtio-net-failover.c
blob4b2ba8a106b12bc432fb66780b5351e128292d20
1 /*
2 * QTest testcase for virtio-net failover
4 * See docs/system/virtio-net-failover.rst
6 * Copyright (c) 2021 Red Hat, Inc.
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10 #include "qemu/osdep.h"
11 #include "libqos/libqtest.h"
12 #include "libqos/pci.h"
13 #include "libqos/pci-pc.h"
14 #include "qapi/qmp/qdict.h"
15 #include "qapi/qmp/qlist.h"
16 #include "qapi/qmp/qjson.h"
17 #include "libqos/malloc-pc.h"
18 #include "libqos/virtio-pci.h"
19 #include "hw/pci/pci.h"
21 #define ACPI_PCIHP_ADDR_ICH9 0x0cc0
22 #define PCI_EJ_BASE 0x0008
23 #define PCI_SEL_BASE 0x0010
25 #define BASE_MACHINE "-M q35 -nodefaults " \
26 "-device pcie-root-port,id=root0,addr=0x1,bus=pcie.0,chassis=1 " \
27 "-device pcie-root-port,id=root1,addr=0x2,bus=pcie.0,chassis=2 "
29 #define MAC_PRIMARY0 "52:54:00:11:11:11"
30 #define MAC_STANDBY0 "52:54:00:22:22:22"
31 #define MAC_PRIMARY1 "52:54:00:33:33:33"
32 #define MAC_STANDBY1 "52:54:00:44:44:44"
34 static QGuestAllocator guest_malloc;
35 static QPCIBus *pcibus;
37 static QTestState *machine_start(const char *args, int numbus)
39 QTestState *qts;
40 QPCIDevice *dev;
41 int bus;
43 qts = qtest_init(args);
45 pc_alloc_init(&guest_malloc, qts, 0);
46 pcibus = qpci_new_pc(qts, &guest_malloc);
47 g_assert(qpci_secondary_buses_init(pcibus) == numbus);
49 for (bus = 1; bus <= numbus; bus++) {
50 dev = qpci_device_find(pcibus, QPCI_DEVFN(bus, 0));
51 g_assert_nonnull(dev);
53 qpci_device_enable(dev);
54 qpci_iomap(dev, 4, NULL);
56 g_free(dev);
59 return qts;
62 static void machine_stop(QTestState *qts)
64 qpci_free_pc(pcibus);
65 alloc_destroy(&guest_malloc);
66 qtest_quit(qts);
69 static void test_error_id(void)
71 QTestState *qts;
72 QDict *resp;
73 QDict *err;
75 qts = machine_start(BASE_MACHINE
76 "-device virtio-net,bus=root0,id=standby0,failover=on",
77 2);
79 resp = qtest_qmp(qts, "{'execute': 'device_add',"
80 "'arguments': {"
81 "'driver': 'virtio-net',"
82 "'bus': 'root1',"
83 "'failover_pair_id': 'standby0'"
84 "} }");
85 g_assert(qdict_haskey(resp, "error"));
87 err = qdict_get_qdict(resp, "error");
88 g_assert(qdict_haskey(err, "desc"));
90 g_assert_cmpstr(qdict_get_str(err, "desc"), ==,
91 "Device with failover_pair_id needs to have id");
93 qobject_unref(resp);
95 machine_stop(qts);
98 static void test_error_pcie(void)
100 QTestState *qts;
101 QDict *resp;
102 QDict *err;
104 qts = machine_start(BASE_MACHINE
105 "-device virtio-net,bus=root0,id=standby0,failover=on",
108 resp = qtest_qmp(qts, "{'execute': 'device_add',"
109 "'arguments': {"
110 "'driver': 'virtio-net',"
111 "'id': 'primary0',"
112 "'bus': 'pcie.0',"
113 "'failover_pair_id': 'standby0'"
114 "} }");
115 g_assert(qdict_haskey(resp, "error"));
117 err = qdict_get_qdict(resp, "error");
118 g_assert(qdict_haskey(err, "desc"));
120 g_assert_cmpstr(qdict_get_str(err, "desc"), ==,
121 "Bus 'pcie.0' does not support hotplugging");
123 qobject_unref(resp);
125 machine_stop(qts);
128 static QDict *find_device(QDict *bus, const char *name)
130 const QObject *obj;
131 QList *devices;
132 QList *list;
134 devices = qdict_get_qlist(bus, "devices");
135 if (devices == NULL) {
136 return NULL;
139 list = qlist_copy(devices);
140 while ((obj = qlist_pop(list))) {
141 QDict *device;
143 device = qobject_to(QDict, obj);
145 if (qdict_haskey(device, "pci_bridge")) {
146 QDict *bridge;
147 QDict *bridge_device;
149 bridge = qdict_get_qdict(device, "pci_bridge");
151 if (qdict_haskey(bridge, "devices")) {
152 bridge_device = find_device(bridge, name);
153 if (bridge_device) {
154 qobject_unref(device);
155 qobject_unref(list);
156 return bridge_device;
161 if (!qdict_haskey(device, "qdev_id")) {
162 qobject_unref(device);
163 continue;
166 if (strcmp(qdict_get_str(device, "qdev_id"), name) == 0) {
167 qobject_unref(list);
168 return device;
170 qobject_unref(device);
172 qobject_unref(list);
174 return NULL;
177 static QDict *get_bus(QTestState *qts, int num)
179 QObject *obj;
180 QDict *resp;
181 QList *ret;
183 resp = qtest_qmp(qts, "{ 'execute': 'query-pci' }");
184 g_assert(qdict_haskey(resp, "return"));
186 ret = qdict_get_qlist(resp, "return");
187 g_assert_nonnull(ret);
189 while ((obj = qlist_pop(ret))) {
190 QDict *bus;
192 bus = qobject_to(QDict, obj);
193 if (!qdict_haskey(bus, "bus")) {
194 qobject_unref(bus);
195 continue;
197 if (qdict_get_int(bus, "bus") == num) {
198 qobject_unref(resp);
199 return bus;
201 qobject_ref(bus);
203 qobject_unref(resp);
205 return NULL;
208 static char *get_mac(QTestState *qts, const char *name)
210 QDict *resp;
211 char *mac;
213 resp = qtest_qmp(qts, "{ 'execute': 'qom-get', "
214 "'arguments': { "
215 "'path': %s, "
216 "'property': 'mac' } }", name);
218 g_assert(qdict_haskey(resp, "return"));
220 mac = g_strdup(qdict_get_str(resp, "return"));
222 qobject_unref(resp);
224 return mac;
227 static void check_one_card(QTestState *qts, bool present,
228 const char *id, const char *mac)
230 QDict *device;
231 QDict *bus;
232 char *addr;
234 bus = get_bus(qts, 0);
235 device = find_device(bus, id);
236 if (present) {
237 char *path;
239 g_assert_nonnull(device);
240 qobject_unref(device);
242 path = g_strdup_printf("/machine/peripheral/%s", id);
243 addr = get_mac(qts, path);
244 g_free(path);
245 g_assert_cmpstr(mac, ==, addr);
246 g_free(addr);
247 } else {
248 g_assert_null(device);
251 qobject_unref(bus);
254 static void test_on(void)
256 QTestState *qts;
258 qts = machine_start(BASE_MACHINE
259 "-netdev user,id=hs0 "
260 "-device virtio-net,bus=root0,id=standby0,"
261 "failover=on,netdev=hs0,mac="MAC_STANDBY0" "
262 "-device virtio-net,bus=root1,id=primary0,"
263 "failover_pair_id=standby0,netdev=hs1,mac="MAC_PRIMARY0,
266 check_one_card(qts, true, "standby0", MAC_STANDBY0);
267 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
269 machine_stop(qts);
272 static void test_on_mismatch(void)
274 QTestState *qts;
276 qts = machine_start(BASE_MACHINE
277 "-netdev user,id=hs0 "
278 "-device virtio-net,bus=root0,id=standby0,"
279 "failover=on,netdev=hs0,mac="MAC_STANDBY0" "
280 "-netdev user,id=hs1 "
281 "-device virtio-net,bus=root1,id=primary0,"
282 "failover_pair_id=standby1,netdev=hs1,mac="MAC_PRIMARY0,
285 check_one_card(qts, true, "standby0", MAC_STANDBY0);
286 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
288 machine_stop(qts);
291 static void test_off(void)
293 QTestState *qts;
295 qts = machine_start(BASE_MACHINE
296 "-netdev user,id=hs0 "
297 "-device virtio-net,bus=root0,id=standby0,"
298 "failover=off,netdev=hs0,mac="MAC_STANDBY0" "
299 "-netdev user,id=hs1 "
300 "-device virtio-net,bus=root1,id=primary0,"
301 "failover_pair_id=standby0,netdev=hs1,mac="MAC_PRIMARY0,
304 check_one_card(qts, true, "standby0", MAC_STANDBY0);
305 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
307 machine_stop(qts);
310 static QDict *get_failover_negociated_event(QTestState *qts)
312 QDict *resp;
313 QDict *data;
315 resp = qtest_qmp_eventwait_ref(qts, "FAILOVER_NEGOTIATED");
316 g_assert(qdict_haskey(resp, "data"));
318 data = qdict_get_qdict(resp, "data");
319 g_assert(qdict_haskey(data, "device-id"));
320 qobject_ref(data);
321 qobject_unref(resp);
323 return data;
326 static QVirtioPCIDevice *start_virtio_net(QTestState *qts, int bus, int slot,
327 const char *id)
329 QVirtioPCIDevice *dev;
330 uint64_t features;
331 QPCIAddress addr;
332 QDict *resp;
334 addr.devfn = QPCI_DEVFN((bus << 5) + slot, 0);
335 dev = virtio_pci_new(pcibus, &addr);
336 g_assert_nonnull(dev);
337 qvirtio_pci_device_enable(dev);
338 qvirtio_start_device(&dev->vdev);
339 features = qvirtio_get_features(&dev->vdev);
340 features = features & ~(QVIRTIO_F_BAD_FEATURE |
341 (1ull << VIRTIO_RING_F_INDIRECT_DESC) |
342 (1ull << VIRTIO_RING_F_EVENT_IDX));
343 qvirtio_set_features(&dev->vdev, features);
344 qvirtio_set_driver_ok(&dev->vdev);
346 resp = get_failover_negociated_event(qts);
347 g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, id);
348 qobject_unref(resp);
350 return dev;
353 static void test_enabled(void)
355 QTestState *qts;
356 QVirtioPCIDevice *vdev;
358 qts = machine_start(BASE_MACHINE
359 "-netdev user,id=hs0 "
360 "-device virtio-net,bus=root0,id=standby0,"
361 "failover=on,netdev=hs0,mac="MAC_STANDBY0" "
362 "-netdev user,id=hs1 "
363 "-device virtio-net,bus=root1,id=primary0,"
364 "failover_pair_id=standby0,netdev=hs1,mac="MAC_PRIMARY0" ",
367 check_one_card(qts, true, "standby0", MAC_STANDBY0);
368 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
370 vdev = start_virtio_net(qts, 1, 0, "standby0");
372 check_one_card(qts, true, "standby0", MAC_STANDBY0);
373 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
375 qos_object_destroy((QOSGraphObject *)vdev);
376 machine_stop(qts);
379 static void test_hotplug_1(void)
381 QTestState *qts;
382 QVirtioPCIDevice *vdev;
384 qts = machine_start(BASE_MACHINE
385 "-netdev user,id=hs0 "
386 "-device virtio-net,bus=root0,id=standby0,"
387 "failover=on,netdev=hs0,mac="MAC_STANDBY0" "
388 "-netdev user,id=hs1 ", 2);
390 check_one_card(qts, true, "standby0", MAC_STANDBY0);
391 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
393 vdev = start_virtio_net(qts, 1, 0, "standby0");
395 check_one_card(qts, true, "standby0", MAC_STANDBY0);
396 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
398 qtest_qmp_device_add(qts, "virtio-net", "primary0",
399 "{'bus': 'root1',"
400 "'failover_pair_id': 'standby0',"
401 "'netdev': 'hs1',"
402 "'mac': '"MAC_PRIMARY0"'}");
404 check_one_card(qts, true, "standby0", MAC_STANDBY0);
405 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
407 qos_object_destroy((QOSGraphObject *)vdev);
408 machine_stop(qts);
411 static void test_hotplug_1_reverse(void)
413 QTestState *qts;
414 QVirtioPCIDevice *vdev;
416 qts = machine_start(BASE_MACHINE
417 "-netdev user,id=hs0 "
418 "-netdev user,id=hs1 "
419 "-device virtio-net,bus=root1,id=primary0,"
420 "failover_pair_id=standby0,netdev=hs1,mac="MAC_PRIMARY0" ",
423 check_one_card(qts, false, "standby0", MAC_STANDBY0);
424 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
426 qtest_qmp_device_add(qts, "virtio-net", "standby0",
427 "{'bus': 'root0',"
428 "'failover': 'on',"
429 "'netdev': 'hs0',"
430 "'mac': '"MAC_STANDBY0"'}");
432 check_one_card(qts, true, "standby0", MAC_STANDBY0);
433 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
435 vdev = start_virtio_net(qts, 1, 0, "standby0");
437 check_one_card(qts, true, "standby0", MAC_STANDBY0);
438 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
440 qos_object_destroy((QOSGraphObject *)vdev);
441 machine_stop(qts);
444 static void test_hotplug_2(void)
446 QTestState *qts;
447 QVirtioPCIDevice *vdev;
449 qts = machine_start(BASE_MACHINE
450 "-netdev user,id=hs0 "
451 "-netdev user,id=hs1 ",
454 check_one_card(qts, false, "standby0", MAC_STANDBY0);
455 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
457 qtest_qmp_device_add(qts, "virtio-net", "standby0",
458 "{'bus': 'root0',"
459 "'failover': 'on',"
460 "'netdev': 'hs0',"
461 "'mac': '"MAC_STANDBY0"'}");
463 check_one_card(qts, true, "standby0", MAC_STANDBY0);
464 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
466 vdev = start_virtio_net(qts, 1, 0, "standby0");
468 check_one_card(qts, true, "standby0", MAC_STANDBY0);
469 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
471 qtest_qmp_device_add(qts, "virtio-net", "primary0",
472 "{'bus': 'root1',"
473 "'failover_pair_id': 'standby0',"
474 "'netdev': 'hs1',"
475 "'mac': '"MAC_PRIMARY0"'}");
477 check_one_card(qts, true, "standby0", MAC_STANDBY0);
478 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
480 qos_object_destroy((QOSGraphObject *)vdev);
481 machine_stop(qts);
484 static void test_hotplug_2_reverse(void)
486 QTestState *qts;
487 QVirtioPCIDevice *vdev;
489 qts = machine_start(BASE_MACHINE
490 "-netdev user,id=hs0 "
491 "-netdev user,id=hs1 ",
494 check_one_card(qts, false, "standby0", MAC_STANDBY0);
495 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
497 qtest_qmp_device_add(qts, "virtio-net", "primary0",
498 "{'bus': 'root1',"
499 "'failover_pair_id': 'standby0',"
500 "'netdev': 'hs1',"
501 "'mac': '"MAC_PRIMARY0"'}");
503 check_one_card(qts, false, "standby0", MAC_STANDBY0);
504 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
506 qtest_qmp_device_add(qts, "virtio-net", "standby0",
507 "{'bus': 'root0',"
508 "'failover': 'on',"
509 "'netdev': 'hs0',"
510 "'rombar': 0,"
511 "'romfile': '',"
512 "'mac': '"MAC_STANDBY0"'}");
515 * XXX: sounds like a bug:
516 * The primary should be hidden until the virtio-net driver
517 * negotiates the VIRTIO_NET_F_STANDBY feature by start_virtio_net()
519 check_one_card(qts, true, "standby0", MAC_STANDBY0);
520 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
522 vdev = start_virtio_net(qts, 1, 0, "standby0");
524 check_one_card(qts, true, "standby0", MAC_STANDBY0);
525 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
527 qos_object_destroy((QOSGraphObject *)vdev);
528 machine_stop(qts);
531 static QDict *migrate_status(QTestState *qts)
533 QDict *resp, *ret;
535 resp = qtest_qmp(qts, "{ 'execute': 'query-migrate' }");
536 g_assert(qdict_haskey(resp, "return"));
538 ret = qdict_get_qdict(resp, "return");
539 g_assert(qdict_haskey(ret, "status"));
540 qobject_ref(ret);
541 qobject_unref(resp);
543 return ret;
546 static QDict *get_unplug_primary_event(QTestState *qts)
548 QDict *resp;
549 QDict *data;
551 resp = qtest_qmp_eventwait_ref(qts, "UNPLUG_PRIMARY");
552 g_assert(qdict_haskey(resp, "data"));
554 data = qdict_get_qdict(resp, "data");
555 g_assert(qdict_haskey(data, "device-id"));
556 qobject_ref(data);
557 qobject_unref(resp);
559 return data;
562 static void test_migrate_out(gconstpointer opaque)
564 QTestState *qts;
565 QDict *resp, *args, *ret;
566 g_autofree gchar *uri = g_strdup_printf("exec: cat > %s", (gchar *)opaque);
567 const gchar *status;
568 QVirtioPCIDevice *vdev;
570 qts = machine_start(BASE_MACHINE
571 "-netdev user,id=hs0 "
572 "-netdev user,id=hs1 ",
575 check_one_card(qts, false, "standby0", MAC_STANDBY0);
576 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
578 qtest_qmp_device_add(qts, "virtio-net", "standby0",
579 "{'bus': 'root0',"
580 "'failover': 'on',"
581 "'netdev': 'hs0',"
582 "'mac': '"MAC_STANDBY0"'}");
584 check_one_card(qts, true, "standby0", MAC_STANDBY0);
585 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
587 vdev = start_virtio_net(qts, 1, 0, "standby0");
589 check_one_card(qts, true, "standby0", MAC_STANDBY0);
590 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
592 qtest_qmp_device_add(qts, "virtio-net", "primary0",
593 "{'bus': 'root1',"
594 "'failover_pair_id': 'standby0',"
595 "'netdev': 'hs1',"
596 "'rombar': 0,"
597 "'romfile': '',"
598 "'mac': '"MAC_PRIMARY0"'}");
600 check_one_card(qts, true, "standby0", MAC_STANDBY0);
601 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
603 args = qdict_from_jsonf_nofail("{}");
604 g_assert_nonnull(args);
605 qdict_put_str(args, "uri", uri);
607 resp = qtest_qmp(qts, "{ 'execute': 'migrate', 'arguments': %p}", args);
608 g_assert(qdict_haskey(resp, "return"));
609 qobject_unref(resp);
611 /* the event is sent when QEMU asks the OS to unplug the card */
612 resp = get_unplug_primary_event(qts);
613 g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, "primary0");
614 qobject_unref(resp);
616 /* wait the end of the migration setup phase */
617 while (true) {
618 ret = migrate_status(qts);
620 status = qdict_get_str(ret, "status");
621 if (strcmp(status, "wait-unplug") == 0) {
622 qobject_unref(ret);
623 break;
626 /* The migration must not start if the card is not ejected */
627 g_assert_cmpstr(status, !=, "active");
628 g_assert_cmpstr(status, !=, "completed");
629 g_assert_cmpstr(status, !=, "failed");
630 g_assert_cmpstr(status, !=, "cancelling");
631 g_assert_cmpstr(status, !=, "cancelled");
633 qobject_unref(ret);
636 if (g_test_slow()) {
637 /* check we stay in wait-unplug while the card is not ejected */
638 for (int i = 0; i < 5; i++) {
639 sleep(1);
640 ret = migrate_status(qts);
641 status = qdict_get_str(ret, "status");
642 g_assert_cmpstr(status, ==, "wait-unplug");
643 qobject_unref(ret);
647 /* OS unplugs the cards, QEMU can move from wait-unplug state */
648 qtest_outl(qts, ACPI_PCIHP_ADDR_ICH9 + PCI_EJ_BASE, 1);
650 while (true) {
651 ret = migrate_status(qts);
653 status = qdict_get_str(ret, "status");
654 if (strcmp(status, "completed") == 0) {
655 qobject_unref(ret);
656 break;
658 g_assert_cmpstr(status, !=, "failed");
659 g_assert_cmpstr(status, !=, "cancelling");
660 g_assert_cmpstr(status, !=, "cancelled");
661 qobject_unref(ret);
664 qtest_qmp_eventwait(qts, "STOP");
667 * in fact, the card is ejected from the point of view of kernel
668 * but not really from QEMU to be able to hotplug it back if
669 * migration fails. So we can't check that:
670 * check_one_card(qts, true, "standby0", MAC_STANDBY0);
671 * check_one_card(qts, false, "primary0", MAC_PRIMARY0);
674 qos_object_destroy((QOSGraphObject *)vdev);
675 machine_stop(qts);
678 static QDict *get_migration_event(QTestState *qts)
680 QDict *resp;
681 QDict *data;
683 resp = qtest_qmp_eventwait_ref(qts, "MIGRATION");
684 g_assert(qdict_haskey(resp, "data"));
686 data = qdict_get_qdict(resp, "data");
687 g_assert(qdict_haskey(data, "status"));
688 qobject_ref(data);
689 qobject_unref(resp);
691 return data;
694 static void test_migrate_in(gconstpointer opaque)
696 QTestState *qts;
697 QDict *resp, *args, *ret;
698 g_autofree gchar *uri = g_strdup_printf("exec: cat %s", (gchar *)opaque);
700 qts = machine_start(BASE_MACHINE
701 "-netdev user,id=hs0 "
702 "-netdev user,id=hs1 "
703 "-incoming defer ",
706 check_one_card(qts, false, "standby0", MAC_STANDBY0);
707 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
709 qtest_qmp_device_add(qts, "virtio-net", "standby0",
710 "{'bus': 'root0',"
711 "'failover': 'on',"
712 "'netdev': 'hs0',"
713 "'mac': '"MAC_STANDBY0"'}");
715 check_one_card(qts, true, "standby0", MAC_STANDBY0);
716 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
718 qtest_qmp_device_add(qts, "virtio-net", "primary0",
719 "{'bus': 'root1',"
720 "'failover_pair_id': 'standby0',"
721 "'netdev': 'hs1',"
722 "'rombar': 0,"
723 "'romfile': '',"
724 "'mac': '"MAC_PRIMARY0"'}");
726 check_one_card(qts, true, "standby0", MAC_STANDBY0);
727 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
729 args = qdict_from_jsonf_nofail("{}");
730 g_assert_nonnull(args);
731 qdict_put_str(args, "uri", uri);
733 resp = qtest_qmp(qts, "{ 'execute': 'migrate-incoming', 'arguments': %p}",
734 args);
735 g_assert(qdict_haskey(resp, "return"));
736 qobject_unref(resp);
738 resp = get_migration_event(qts);
739 g_assert_cmpstr(qdict_get_str(resp, "status"), ==, "setup");
740 qobject_unref(resp);
742 resp = get_failover_negociated_event(qts);
743 g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, "standby0");
744 qobject_unref(resp);
746 check_one_card(qts, true, "standby0", MAC_STANDBY0);
747 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
749 qtest_qmp_eventwait(qts, "RESUME");
751 ret = migrate_status(qts);
752 g_assert_cmpstr(qdict_get_str(ret, "status"), ==, "completed");
753 qobject_unref(ret);
755 machine_stop(qts);
758 static void test_migrate_abort_wait_unplug(gconstpointer opaque)
760 QTestState *qts;
761 QDict *resp, *args, *ret;
762 g_autofree gchar *uri = g_strdup_printf("exec: cat > %s", (gchar *)opaque);
763 const gchar *status;
764 QVirtioPCIDevice *vdev;
766 qts = machine_start(BASE_MACHINE
767 "-netdev user,id=hs0 "
768 "-netdev user,id=hs1 ",
771 check_one_card(qts, false, "standby0", MAC_STANDBY0);
772 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
774 qtest_qmp_device_add(qts, "virtio-net", "standby0",
775 "{'bus': 'root0',"
776 "'failover': 'on',"
777 "'netdev': 'hs0',"
778 "'mac': '"MAC_STANDBY0"'}");
780 check_one_card(qts, true, "standby0", MAC_STANDBY0);
781 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
783 vdev = start_virtio_net(qts, 1, 0, "standby0");
785 check_one_card(qts, true, "standby0", MAC_STANDBY0);
786 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
788 qtest_qmp_device_add(qts, "virtio-net", "primary0",
789 "{'bus': 'root1',"
790 "'failover_pair_id': 'standby0',"
791 "'netdev': 'hs1',"
792 "'rombar': 0,"
793 "'romfile': '',"
794 "'mac': '"MAC_PRIMARY0"'}");
796 check_one_card(qts, true, "standby0", MAC_STANDBY0);
797 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
799 args = qdict_from_jsonf_nofail("{}");
800 g_assert_nonnull(args);
801 qdict_put_str(args, "uri", uri);
803 resp = qtest_qmp(qts, "{ 'execute': 'migrate', 'arguments': %p}", args);
804 g_assert(qdict_haskey(resp, "return"));
805 qobject_unref(resp);
807 /* the event is sent when QEMU asks the OS to unplug the card */
808 resp = get_unplug_primary_event(qts);
809 g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, "primary0");
810 qobject_unref(resp);
812 resp = qtest_qmp(qts, "{ 'execute': 'migrate_cancel' }");
813 g_assert(qdict_haskey(resp, "return"));
814 qobject_unref(resp);
816 /* migration has been cancelled while the unplug was in progress */
818 /* while the card is not ejected, we must be in "cancelling" state */
819 ret = migrate_status(qts);
821 status = qdict_get_str(ret, "status");
822 g_assert_cmpstr(status, ==, "cancelling");
823 qobject_unref(ret);
825 /* OS unplugs the cards, QEMU can move from wait-unplug state */
826 qtest_outl(qts, ACPI_PCIHP_ADDR_ICH9 + PCI_EJ_BASE, 1);
828 while (true) {
829 ret = migrate_status(qts);
831 status = qdict_get_str(ret, "status");
832 if (strcmp(status, "cancelled") == 0) {
833 qobject_unref(ret);
834 break;
836 g_assert_cmpstr(status, !=, "failed");
837 g_assert_cmpstr(status, !=, "active");
838 qobject_unref(ret);
841 check_one_card(qts, true, "standby0", MAC_STANDBY0);
842 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
844 qos_object_destroy((QOSGraphObject *)vdev);
845 machine_stop(qts);
848 static void test_migrate_abort_active(gconstpointer opaque)
850 QTestState *qts;
851 QDict *resp, *args, *ret;
852 g_autofree gchar *uri = g_strdup_printf("exec: cat > %s", (gchar *)opaque);
853 const gchar *status;
854 QVirtioPCIDevice *vdev;
856 qts = machine_start(BASE_MACHINE
857 "-netdev user,id=hs0 "
858 "-netdev user,id=hs1 ",
861 check_one_card(qts, false, "standby0", MAC_STANDBY0);
862 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
864 qtest_qmp_device_add(qts, "virtio-net", "standby0",
865 "{'bus': 'root0',"
866 "'failover': 'on',"
867 "'netdev': 'hs0',"
868 "'mac': '"MAC_STANDBY0"'}");
870 check_one_card(qts, true, "standby0", MAC_STANDBY0);
871 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
873 vdev = start_virtio_net(qts, 1, 0, "standby0");
875 check_one_card(qts, true, "standby0", MAC_STANDBY0);
876 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
878 qtest_qmp_device_add(qts, "virtio-net", "primary0",
879 "{'bus': 'root1',"
880 "'failover_pair_id': 'standby0',"
881 "'netdev': 'hs1',"
882 "'rombar': 0,"
883 "'romfile': '',"
884 "'mac': '"MAC_PRIMARY0"'}");
886 check_one_card(qts, true, "standby0", MAC_STANDBY0);
887 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
889 args = qdict_from_jsonf_nofail("{}");
890 g_assert_nonnull(args);
891 qdict_put_str(args, "uri", uri);
893 resp = qtest_qmp(qts, "{ 'execute': 'migrate', 'arguments': %p}", args);
894 g_assert(qdict_haskey(resp, "return"));
895 qobject_unref(resp);
897 /* the event is sent when QEMU asks the OS to unplug the card */
898 resp = get_unplug_primary_event(qts);
899 g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, "primary0");
900 qobject_unref(resp);
902 /* OS unplugs the cards, QEMU can move from wait-unplug state */
903 qtest_outl(qts, ACPI_PCIHP_ADDR_ICH9 + PCI_EJ_BASE, 1);
905 while (true) {
906 ret = migrate_status(qts);
908 status = qdict_get_str(ret, "status");
909 if (strcmp(status, "wait-unplug") != 0) {
910 qobject_unref(ret);
911 break;
913 g_assert_cmpstr(status, !=, "failed");
914 qobject_unref(ret);
917 resp = qtest_qmp(qts, "{ 'execute': 'migrate_cancel' }");
918 g_assert(qdict_haskey(resp, "return"));
919 qobject_unref(resp);
921 while (true) {
922 ret = migrate_status(qts);
924 status = qdict_get_str(ret, "status");
925 if (strcmp(status, "cancelled") == 0) {
926 qobject_unref(ret);
927 break;
929 g_assert_cmpstr(status, !=, "failed");
930 g_assert_cmpstr(status, !=, "active");
931 qobject_unref(ret);
934 check_one_card(qts, true, "standby0", MAC_STANDBY0);
935 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
937 qos_object_destroy((QOSGraphObject *)vdev);
938 machine_stop(qts);
941 static void test_migrate_abort_timeout(gconstpointer opaque)
943 QTestState *qts;
944 QDict *resp, *args, *ret;
945 g_autofree gchar *uri = g_strdup_printf("exec: cat > %s", (gchar *)opaque);
946 const gchar *status;
947 int total;
948 QVirtioPCIDevice *vdev;
950 qts = machine_start(BASE_MACHINE
951 "-netdev user,id=hs0 "
952 "-netdev user,id=hs1 ",
955 check_one_card(qts, false, "standby0", MAC_STANDBY0);
956 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
958 qtest_qmp_device_add(qts, "virtio-net", "standby0",
959 "{'bus': 'root0',"
960 "'failover': 'on',"
961 "'netdev': 'hs0',"
962 "'mac': '"MAC_STANDBY0"'}");
964 check_one_card(qts, true, "standby0", MAC_STANDBY0);
965 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
967 vdev = start_virtio_net(qts, 1, 0, "standby0");
969 check_one_card(qts, true, "standby0", MAC_STANDBY0);
970 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
972 qtest_qmp_device_add(qts, "virtio-net", "primary0",
973 "{'bus': 'root1',"
974 "'failover_pair_id': 'standby0',"
975 "'netdev': 'hs1',"
976 "'rombar': 0,"
977 "'romfile': '',"
978 "'mac': '"MAC_PRIMARY0"'}");
980 check_one_card(qts, true, "standby0", MAC_STANDBY0);
981 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
983 args = qdict_from_jsonf_nofail("{}");
984 g_assert_nonnull(args);
985 qdict_put_str(args, "uri", uri);
987 resp = qtest_qmp(qts, "{ 'execute': 'migrate', 'arguments': %p}", args);
988 g_assert(qdict_haskey(resp, "return"));
989 qobject_unref(resp);
991 /* the event is sent when QEMU asks the OS to unplug the card */
992 resp = get_unplug_primary_event(qts);
993 g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, "primary0");
994 qobject_unref(resp);
996 resp = qtest_qmp(qts, "{ 'execute': 'migrate_cancel' }");
997 g_assert(qdict_haskey(resp, "return"));
998 qobject_unref(resp);
1000 /* migration has been cancelled while the unplug was in progress */
1002 /* while the card is not ejected, we must be in "cancelling" state */
1004 total = 0;
1005 while (true) {
1006 ret = migrate_status(qts);
1008 status = qdict_get_str(ret, "status");
1009 if (strcmp(status, "cancelled") == 0) {
1010 qobject_unref(ret);
1011 break;
1013 g_assert_cmpstr(status, ==, "cancelling");
1014 g_assert(qdict_haskey(ret, "total-time"));
1015 total = qdict_get_int(ret, "total-time");
1016 qobject_unref(ret);
1020 * migration timeout in this case is 30 seconds
1021 * check we exit on the timeout (ms)
1023 g_assert_cmpint(total, >, 30000);
1025 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1026 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
1028 qos_object_destroy((QOSGraphObject *)vdev);
1029 machine_stop(qts);
1032 static void test_multi_out(gconstpointer opaque)
1034 QTestState *qts;
1035 QDict *resp, *args, *ret;
1036 g_autofree gchar *uri = g_strdup_printf("exec: cat > %s", (gchar *)opaque);
1037 const gchar *status, *expected;
1038 QVirtioPCIDevice *vdev0, *vdev1;
1040 qts = machine_start(BASE_MACHINE
1041 "-device pcie-root-port,id=root2,addr=0x3,bus=pcie.0,chassis=3 "
1042 "-device pcie-root-port,id=root3,addr=0x4,bus=pcie.0,chassis=4 "
1043 "-netdev user,id=hs0 "
1044 "-netdev user,id=hs1 "
1045 "-netdev user,id=hs2 "
1046 "-netdev user,id=hs3 ",
1049 check_one_card(qts, false, "standby0", MAC_STANDBY0);
1050 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
1051 check_one_card(qts, false, "standby1", MAC_STANDBY1);
1052 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1054 qtest_qmp_device_add(qts, "virtio-net", "standby0",
1055 "{'bus': 'root0',"
1056 "'failover': 'on',"
1057 "'netdev': 'hs0',"
1058 "'mac': '"MAC_STANDBY0"'}");
1060 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1061 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
1062 check_one_card(qts, false, "standby1", MAC_STANDBY1);
1063 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1065 qtest_qmp_device_add(qts, "virtio-net", "primary0",
1066 "{'bus': 'root1',"
1067 "'failover_pair_id': 'standby0',"
1068 "'netdev': 'hs1',"
1069 "'rombar': 0,"
1070 "'romfile': '',"
1071 "'mac': '"MAC_PRIMARY0"'}");
1073 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1074 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
1075 check_one_card(qts, false, "standby1", MAC_STANDBY1);
1076 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1078 vdev0 = start_virtio_net(qts, 1, 0, "standby0");
1080 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1081 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
1082 check_one_card(qts, false, "standby1", MAC_STANDBY1);
1083 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1085 qtest_qmp_device_add(qts, "virtio-net", "standby1",
1086 "{'bus': 'root2',"
1087 "'failover': 'on',"
1088 "'netdev': 'hs2',"
1089 "'mac': '"MAC_STANDBY1"'}");
1091 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1092 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
1093 check_one_card(qts, true, "standby1", MAC_STANDBY1);
1094 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1096 qtest_qmp_device_add(qts, "virtio-net", "primary1",
1097 "{'bus': 'root3',"
1098 "'failover_pair_id': 'standby1',"
1099 "'netdev': 'hs3',"
1100 "'rombar': 0,"
1101 "'romfile': '',"
1102 "'mac': '"MAC_PRIMARY1"'}");
1104 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1105 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
1106 check_one_card(qts, true, "standby1", MAC_STANDBY1);
1107 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1109 vdev1 = start_virtio_net(qts, 3, 0, "standby1");
1111 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1112 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
1113 check_one_card(qts, true, "standby1", MAC_STANDBY1);
1114 check_one_card(qts, true, "primary1", MAC_PRIMARY1);
1116 args = qdict_from_jsonf_nofail("{}");
1117 g_assert_nonnull(args);
1118 qdict_put_str(args, "uri", uri);
1120 resp = qtest_qmp(qts, "{ 'execute': 'migrate', 'arguments': %p}", args);
1121 g_assert(qdict_haskey(resp, "return"));
1122 qobject_unref(resp);
1124 /* the event is sent when QEMU asks the OS to unplug the card */
1125 resp = get_unplug_primary_event(qts);
1126 if (strcmp(qdict_get_str(resp, "device-id"), "primary0") == 0) {
1127 expected = "primary1";
1128 } else if (strcmp(qdict_get_str(resp, "device-id"), "primary1") == 0) {
1129 expected = "primary0";
1130 } else {
1131 g_assert_not_reached();
1133 qobject_unref(resp);
1135 resp = get_unplug_primary_event(qts);
1136 g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, expected);
1137 qobject_unref(resp);
1139 /* wait the end of the migration setup phase */
1140 while (true) {
1141 ret = migrate_status(qts);
1143 status = qdict_get_str(ret, "status");
1144 if (strcmp(status, "wait-unplug") == 0) {
1145 qobject_unref(ret);
1146 break;
1149 /* The migration must not start if the card is not ejected */
1150 g_assert_cmpstr(status, !=, "active");
1151 g_assert_cmpstr(status, !=, "completed");
1152 g_assert_cmpstr(status, !=, "failed");
1153 g_assert_cmpstr(status, !=, "cancelling");
1154 g_assert_cmpstr(status, !=, "cancelled");
1156 qobject_unref(ret);
1159 /* OS unplugs primary1, but we must wait the second */
1160 qtest_outl(qts, ACPI_PCIHP_ADDR_ICH9 + PCI_EJ_BASE, 1);
1162 ret = migrate_status(qts);
1163 status = qdict_get_str(ret, "status");
1164 g_assert_cmpstr(status, ==, "wait-unplug");
1165 qobject_unref(ret);
1167 if (g_test_slow()) {
1168 /* check we stay in wait-unplug while the card is not ejected */
1169 for (int i = 0; i < 5; i++) {
1170 sleep(1);
1171 ret = migrate_status(qts);
1172 status = qdict_get_str(ret, "status");
1173 g_assert_cmpstr(status, ==, "wait-unplug");
1174 qobject_unref(ret);
1178 /* OS unplugs primary0, QEMU can move from wait-unplug state */
1179 qtest_outl(qts, ACPI_PCIHP_ADDR_ICH9 + PCI_SEL_BASE, 2);
1180 qtest_outl(qts, ACPI_PCIHP_ADDR_ICH9 + PCI_EJ_BASE, 1);
1182 while (true) {
1183 ret = migrate_status(qts);
1185 status = qdict_get_str(ret, "status");
1186 if (strcmp(status, "completed") == 0) {
1187 qobject_unref(ret);
1188 break;
1190 g_assert_cmpstr(status, !=, "failed");
1191 g_assert_cmpstr(status, !=, "cancelling");
1192 g_assert_cmpstr(status, !=, "cancelled");
1193 qobject_unref(ret);
1196 qtest_qmp_eventwait(qts, "STOP");
1198 qos_object_destroy((QOSGraphObject *)vdev0);
1199 qos_object_destroy((QOSGraphObject *)vdev1);
1200 machine_stop(qts);
1203 static void test_multi_in(gconstpointer opaque)
1205 QTestState *qts;
1206 QDict *resp, *args, *ret;
1207 g_autofree gchar *uri = g_strdup_printf("exec: cat %s", (gchar *)opaque);
1209 qts = machine_start(BASE_MACHINE
1210 "-device pcie-root-port,id=root2,addr=0x3,bus=pcie.0,chassis=3 "
1211 "-device pcie-root-port,id=root3,addr=0x4,bus=pcie.0,chassis=4 "
1212 "-netdev user,id=hs0 "
1213 "-netdev user,id=hs1 "
1214 "-netdev user,id=hs2 "
1215 "-netdev user,id=hs3 "
1216 "-incoming defer ",
1219 check_one_card(qts, false, "standby0", MAC_STANDBY0);
1220 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
1221 check_one_card(qts, false, "standby1", MAC_STANDBY1);
1222 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1224 qtest_qmp_device_add(qts, "virtio-net", "standby0",
1225 "{'bus': 'root0',"
1226 "'failover': 'on',"
1227 "'netdev': 'hs0',"
1228 "'mac': '"MAC_STANDBY0"'}");
1230 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1231 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
1232 check_one_card(qts, false, "standby1", MAC_STANDBY1);
1233 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1235 qtest_qmp_device_add(qts, "virtio-net", "primary0",
1236 "{'bus': 'root1',"
1237 "'failover_pair_id': 'standby0',"
1238 "'netdev': 'hs1',"
1239 "'rombar': 0,"
1240 "'romfile': '',"
1241 "'mac': '"MAC_PRIMARY0"'}");
1243 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1244 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
1245 check_one_card(qts, false, "standby1", MAC_STANDBY1);
1246 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1248 qtest_qmp_device_add(qts, "virtio-net", "standby1",
1249 "{'bus': 'root2',"
1250 "'failover': 'on',"
1251 "'netdev': 'hs2',"
1252 "'mac': '"MAC_STANDBY1"'}");
1254 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1255 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
1256 check_one_card(qts, true, "standby1", MAC_STANDBY1);
1257 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1259 qtest_qmp_device_add(qts, "virtio-net", "primary1",
1260 "{'bus': 'root3',"
1261 "'failover_pair_id': 'standby1',"
1262 "'netdev': 'hs3',"
1263 "'rombar': 0,"
1264 "'romfile': '',"
1265 "'mac': '"MAC_PRIMARY1"'}");
1267 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1268 check_one_card(qts, false, "primary0", MAC_PRIMARY0);
1269 check_one_card(qts, true, "standby1", MAC_STANDBY1);
1270 check_one_card(qts, false, "primary1", MAC_PRIMARY1);
1272 args = qdict_from_jsonf_nofail("{}");
1273 g_assert_nonnull(args);
1274 qdict_put_str(args, "uri", uri);
1276 resp = qtest_qmp(qts, "{ 'execute': 'migrate-incoming', 'arguments': %p}",
1277 args);
1278 g_assert(qdict_haskey(resp, "return"));
1279 qobject_unref(resp);
1281 resp = get_migration_event(qts);
1282 g_assert_cmpstr(qdict_get_str(resp, "status"), ==, "setup");
1283 qobject_unref(resp);
1285 resp = get_failover_negociated_event(qts);
1286 g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, "standby0");
1287 qobject_unref(resp);
1289 resp = get_failover_negociated_event(qts);
1290 g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, "standby1");
1291 qobject_unref(resp);
1293 check_one_card(qts, true, "standby0", MAC_STANDBY0);
1294 check_one_card(qts, true, "primary0", MAC_PRIMARY0);
1295 check_one_card(qts, true, "standby1", MAC_STANDBY1);
1296 check_one_card(qts, true, "primary1", MAC_PRIMARY1);
1298 qtest_qmp_eventwait(qts, "RESUME");
1300 ret = migrate_status(qts);
1301 g_assert_cmpstr(qdict_get_str(ret, "status"), ==, "completed");
1302 qobject_unref(ret);
1304 machine_stop(qts);
1307 int main(int argc, char **argv)
1309 const gchar *tmpdir = g_get_tmp_dir();
1310 gchar *tmpfile = g_strdup_printf("%s/failover_test_migrate-%u-%u",
1311 tmpdir, getpid(), g_test_rand_int());
1312 int ret;
1314 g_test_init(&argc, &argv, NULL);
1316 qtest_add_func("failover-virtio-net/params/error/id", test_error_id);
1317 qtest_add_func("failover-virtio-net/params/error/pcie", test_error_pcie);
1318 qtest_add_func("failover-virtio-net/params/on", test_on);
1319 qtest_add_func("failover-virtio-net/params/on_mismatch",
1320 test_on_mismatch);
1321 qtest_add_func("failover-virtio-net/params/off", test_off);
1322 qtest_add_func("failover-virtio-net/params/enabled", test_enabled);
1323 qtest_add_func("failover-virtio-net/hotplug_1", test_hotplug_1);
1324 qtest_add_func("failover-virtio-net/hotplug_1_reverse",
1325 test_hotplug_1_reverse);
1326 qtest_add_func("failover-virtio-net/hotplug_2", test_hotplug_2);
1327 qtest_add_func("failover-virtio-net/hotplug_2_reverse",
1328 test_hotplug_2_reverse);
1329 qtest_add_data_func("failover-virtio-net/migrate/out", tmpfile,
1330 test_migrate_out);
1331 qtest_add_data_func("failover-virtio-net/migrate/in", tmpfile,
1332 test_migrate_in);
1333 qtest_add_data_func("failover-virtio-net/migrate/abort/wait-unplug",
1334 tmpfile, test_migrate_abort_wait_unplug);
1335 qtest_add_data_func("failover-virtio-net/migrate/abort/active", tmpfile,
1336 test_migrate_abort_active);
1337 if (g_test_slow()) {
1338 qtest_add_data_func("failover-virtio-net/migrate/abort/timeout",
1339 tmpfile, test_migrate_abort_timeout);
1341 qtest_add_data_func("failover-virtio-net/multi/out",
1342 tmpfile, test_multi_out);
1343 qtest_add_data_func("failover-virtio-net/multi/in",
1344 tmpfile, test_multi_in);
1346 ret = g_test_run();
1348 unlink(tmpfile);
1349 g_free(tmpfile);
1351 return ret;