diff options
Diffstat (limited to 'tests/qtest/virtio-net-failover.c')
| -rw-r--r-- | tests/qtest/virtio-net-failover.c | 671 |
1 files changed, 596 insertions, 75 deletions
diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c index 22ad54bb95..80292eecf6 100644 --- a/tests/qtest/virtio-net-failover.c +++ b/tests/qtest/virtio-net-failover.c @@ -18,6 +18,8 @@ #include "libqos/virtio-pci.h" #include "hw/pci/pci.h" +#define VIRTIO_NET_F_STANDBY 62 + #define ACPI_PCIHP_ADDR_ICH9 0x0cc0 #define PCI_EJ_BASE 0x0008 #define PCI_SEL_BASE 0x0010 @@ -224,31 +226,85 @@ static char *get_mac(QTestState *qts, const char *name) return mac; } -static void check_one_card(QTestState *qts, bool present, - const char *id, const char *mac) +#define check_one_card(qts, present, id, mac) \ +do { \ + QDict *device; \ + QDict *bus; \ + char *addr; \ + bus = get_bus(qts, 0); \ + device = find_device(bus, id); \ + if (present) { \ + char *path; \ + g_assert_nonnull(device); \ + qobject_unref(device); \ + path = g_strdup_printf("/machine/peripheral/%s", id); \ + addr = get_mac(qts, path); \ + g_free(path); \ + g_assert_cmpstr(mac, ==, addr); \ + g_free(addr); \ + } else { \ + g_assert_null(device); \ + } \ + qobject_unref(bus); \ +} while (0) + +static QDict *get_failover_negociated_event(QTestState *qts) { - QDict *device; - QDict *bus; - char *addr; + QDict *resp; + QDict *data; - bus = get_bus(qts, 0); - device = find_device(bus, id); - if (present) { - char *path; + resp = qtest_qmp_eventwait_ref(qts, "FAILOVER_NEGOTIATED"); + g_assert(qdict_haskey(resp, "data")); - g_assert_nonnull(device); - qobject_unref(device); + data = qdict_get_qdict(resp, "data"); + g_assert(qdict_haskey(data, "device-id")); + qobject_ref(data); + qobject_unref(resp); - path = g_strdup_printf("/machine/peripheral/%s", id); - addr = get_mac(qts, path); - g_free(path); - g_assert_cmpstr(mac, ==, addr); - g_free(addr); - } else { - g_assert_null(device); + return data; +} + +static QVirtioPCIDevice *start_virtio_net_internal(QTestState *qts, + int bus, int slot, + uint64_t *features) +{ + QVirtioPCIDevice *dev; + QPCIAddress addr; + + addr.devfn = QPCI_DEVFN((bus << 5) + slot, 0); + dev = virtio_pci_new(pcibus, &addr); + g_assert_nonnull(dev); + qvirtio_pci_device_enable(dev); + qvirtio_start_device(&dev->vdev); + *features &= qvirtio_get_features(&dev->vdev); + qvirtio_set_features(&dev->vdev, *features); + qvirtio_set_driver_ok(&dev->vdev); + return dev; +} + +static QVirtioPCIDevice *start_virtio_net(QTestState *qts, int bus, int slot, + const char *id, bool failover) +{ + QVirtioPCIDevice *dev; + uint64_t features; + + features = ~(QVIRTIO_F_BAD_FEATURE | + (1ull << VIRTIO_RING_F_INDIRECT_DESC) | + (1ull << VIRTIO_RING_F_EVENT_IDX)); + + dev = start_virtio_net_internal(qts, bus, slot, &features); + + g_assert(!!(features & (1ull << VIRTIO_NET_F_STANDBY)) == failover); + + if (failover) { + QDict *resp; + + resp = get_failover_negociated_event(qts); + g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, id); + qobject_unref(resp); } - qobject_unref(bus); + return dev; } static void test_on(void) @@ -259,6 +315,7 @@ static void test_on(void) "-netdev user,id=hs0 " "-device virtio-net,bus=root0,id=standby0," "failover=on,netdev=hs0,mac="MAC_STANDBY0" " + "-netdev user,id=hs1 " "-device virtio-net,bus=root1,id=primary0," "failover_pair_id=standby0,netdev=hs1,mac="MAC_PRIMARY0, 2); @@ -272,6 +329,7 @@ static void test_on(void) static void test_on_mismatch(void) { QTestState *qts; + QVirtioPCIDevice *vdev; qts = machine_start(BASE_MACHINE "-netdev user,id=hs0 " @@ -285,12 +343,19 @@ static void test_on_mismatch(void) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, true, "primary0", MAC_PRIMARY0); + vdev = start_virtio_net(qts, 1, 0, "standby0", true); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, true, "primary0", MAC_PRIMARY0); + + qos_object_destroy((QOSGraphObject *)vdev); machine_stop(qts); } static void test_off(void) { QTestState *qts; + QVirtioPCIDevice *vdev; qts = machine_start(BASE_MACHINE "-netdev user,id=hs0 " @@ -304,56 +369,46 @@ static void test_off(void) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, true, "primary0", MAC_PRIMARY0); + vdev = start_virtio_net(qts, 1, 0, "standby0", false); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, true, "primary0", MAC_PRIMARY0); + + qos_object_destroy((QOSGraphObject *)vdev); machine_stop(qts); } -static QDict *get_failover_negociated_event(QTestState *qts) +static void test_enabled(void) { - QDict *resp; - QDict *data; - - resp = qtest_qmp_eventwait_ref(qts, "FAILOVER_NEGOTIATED"); - g_assert(qdict_haskey(resp, "data")); - - data = qdict_get_qdict(resp, "data"); - g_assert(qdict_haskey(data, "device-id")); - qobject_ref(data); - qobject_unref(resp); + QTestState *qts; + QVirtioPCIDevice *vdev; - return data; -} + qts = machine_start(BASE_MACHINE + "-netdev user,id=hs0 " + "-device virtio-net,bus=root0,id=standby0," + "failover=on,netdev=hs0,mac="MAC_STANDBY0" " + "-netdev user,id=hs1 " + "-device virtio-net,bus=root1,id=primary0," + "failover_pair_id=standby0,netdev=hs1,mac="MAC_PRIMARY0" ", + 2); -static QVirtioPCIDevice *start_virtio_net(QTestState *qts, int bus, int slot, - const char *id) -{ - QVirtioPCIDevice *dev; - uint64_t features; - QPCIAddress addr; - QDict *resp; + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); - addr.devfn = QPCI_DEVFN((bus << 5) + slot, 0); - dev = virtio_pci_new(pcibus, &addr); - g_assert_nonnull(dev); - qvirtio_pci_device_enable(dev); - qvirtio_start_device(&dev->vdev); - features = qvirtio_get_features(&dev->vdev); - features = features & ~(QVIRTIO_F_BAD_FEATURE | - (1ull << VIRTIO_RING_F_INDIRECT_DESC) | - (1ull << VIRTIO_RING_F_EVENT_IDX)); - qvirtio_set_features(&dev->vdev, features); - qvirtio_set_driver_ok(&dev->vdev); + vdev = start_virtio_net(qts, 1, 0, "standby0", true); - resp = get_failover_negociated_event(qts); - g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, id); - qobject_unref(resp); + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, true, "primary0", MAC_PRIMARY0); - return dev; + qos_object_destroy((QOSGraphObject *)vdev); + machine_stop(qts); } -static void test_enabled(void) +static void test_guest_off(void) { QTestState *qts; QVirtioPCIDevice *vdev; + uint64_t features; qts = machine_start(BASE_MACHINE "-netdev user,id=hs0 " @@ -367,10 +422,15 @@ static void test_enabled(void) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); - vdev = start_virtio_net(qts, 1, 0, "standby0"); + features = ~(QVIRTIO_F_BAD_FEATURE | + (1ull << VIRTIO_RING_F_INDIRECT_DESC) | + (1ull << VIRTIO_RING_F_EVENT_IDX) | + (1ull << VIRTIO_NET_F_STANDBY)); + + vdev = start_virtio_net_internal(qts, 1, 0, &features); check_one_card(qts, true, "standby0", MAC_STANDBY0); - check_one_card(qts, true, "primary0", MAC_PRIMARY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); qos_object_destroy((QOSGraphObject *)vdev); machine_stop(qts); @@ -390,7 +450,7 @@ static void test_hotplug_1(void) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); - vdev = start_virtio_net(qts, 1, 0, "standby0"); + vdev = start_virtio_net(qts, 1, 0, "standby0", true); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); @@ -432,7 +492,7 @@ static void test_hotplug_1_reverse(void) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, true, "primary0", MAC_PRIMARY0); - vdev = start_virtio_net(qts, 1, 0, "standby0"); + vdev = start_virtio_net(qts, 1, 0, "standby0", true); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, true, "primary0", MAC_PRIMARY0); @@ -463,7 +523,7 @@ static void test_hotplug_2(void) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); - vdev = start_virtio_net(qts, 1, 0, "standby0"); + vdev = start_virtio_net(qts, 1, 0, "standby0", true); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); @@ -519,7 +579,7 @@ static void test_hotplug_2_reverse(void) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, true, "primary0", MAC_PRIMARY0); - vdev = start_virtio_net(qts, 1, 0, "standby0"); + vdev = start_virtio_net(qts, 1, 0, "standby0", true); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, true, "primary0", MAC_PRIMARY0); @@ -584,7 +644,7 @@ static void test_migrate_out(gconstpointer opaque) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); - vdev = start_virtio_net(qts, 1, 0, "standby0"); + vdev = start_virtio_net(qts, 1, 0, "standby0", true); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); @@ -755,6 +815,364 @@ static void test_migrate_in(gconstpointer opaque) machine_stop(qts); } +static void test_off_migrate_out(gconstpointer opaque) +{ + QTestState *qts; + QDict *resp, *args, *ret; + g_autofree gchar *uri = g_strdup_printf("exec: cat > %s", (gchar *)opaque); + const gchar *status; + QVirtioPCIDevice *vdev; + + qts = machine_start(BASE_MACHINE + "-netdev user,id=hs0 " + "-netdev user,id=hs1 ", + 2); + + check_one_card(qts, false, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "standby0", + "{'bus': 'root0'," + "'failover': 'off'," + "'netdev': 'hs0'," + "'mac': '"MAC_STANDBY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "primary0", + "{'bus': 'root1'," + "'failover_pair_id': 'standby0'," + "'netdev': 'hs1'," + "'rombar': 0," + "'romfile': ''," + "'mac': '"MAC_PRIMARY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, true, "primary0", MAC_PRIMARY0); + + vdev = start_virtio_net(qts, 1, 0, "standby0", false); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, true, "primary0", MAC_PRIMARY0); + + args = qdict_from_jsonf_nofail("{}"); + g_assert_nonnull(args); + qdict_put_str(args, "uri", uri); + + resp = qtest_qmp(qts, "{ 'execute': 'migrate', 'arguments': %p}", args); + g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); + + while (true) { + ret = migrate_status(qts); + + status = qdict_get_str(ret, "status"); + if (strcmp(status, "completed") == 0) { + qobject_unref(ret); + break; + } + g_assert_cmpstr(status, !=, "failed"); + g_assert_cmpstr(status, !=, "cancelling"); + g_assert_cmpstr(status, !=, "cancelled"); + qobject_unref(ret); + } + + qtest_qmp_eventwait(qts, "STOP"); + + qos_object_destroy((QOSGraphObject *)vdev); + machine_stop(qts); +} + +static void test_off_migrate_in(gconstpointer opaque) +{ + QTestState *qts; + QDict *resp, *args, *ret; + g_autofree gchar *uri = g_strdup_printf("exec: cat %s", (gchar *)opaque); + + qts = machine_start(BASE_MACHINE + "-netdev user,id=hs0 " + "-netdev user,id=hs1 " + "-incoming defer ", + 2); + + check_one_card(qts, false, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "standby0", + "{'bus': 'root0'," + "'failover': 'off'," + "'netdev': 'hs0'," + "'mac': '"MAC_STANDBY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "primary0", + "{'bus': 'root1'," + "'failover_pair_id': 'standby0'," + "'netdev': 'hs1'," + "'rombar': 0," + "'romfile': ''," + "'mac': '"MAC_PRIMARY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, true, "primary0", MAC_PRIMARY0); + + args = qdict_from_jsonf_nofail("{}"); + g_assert_nonnull(args); + qdict_put_str(args, "uri", uri); + + resp = qtest_qmp(qts, "{ 'execute': 'migrate-incoming', 'arguments': %p}", + args); + g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); + + resp = get_migration_event(qts); + g_assert_cmpstr(qdict_get_str(resp, "status"), ==, "setup"); + qobject_unref(resp); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, true, "primary0", MAC_PRIMARY0); + + qtest_qmp_eventwait(qts, "RESUME"); + + ret = migrate_status(qts); + g_assert_cmpstr(qdict_get_str(ret, "status"), ==, "completed"); + qobject_unref(ret); + + machine_stop(qts); +} + +static void test_guest_off_migrate_out(gconstpointer opaque) +{ + QTestState *qts; + QDict *resp, *args, *ret; + g_autofree gchar *uri = g_strdup_printf("exec: cat > %s", (gchar *)opaque); + const gchar *status; + QVirtioPCIDevice *vdev; + uint64_t features; + + qts = machine_start(BASE_MACHINE + "-netdev user,id=hs0 " + "-netdev user,id=hs1 ", + 2); + + check_one_card(qts, false, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "standby0", + "{'bus': 'root0'," + "'failover': 'on'," + "'netdev': 'hs0'," + "'mac': '"MAC_STANDBY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "primary0", + "{'bus': 'root1'," + "'failover_pair_id': 'standby0'," + "'netdev': 'hs1'," + "'rombar': 0," + "'romfile': ''," + "'mac': '"MAC_PRIMARY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + features = ~(QVIRTIO_F_BAD_FEATURE | + (1ull << VIRTIO_RING_F_INDIRECT_DESC) | + (1ull << VIRTIO_RING_F_EVENT_IDX) | + (1ull << VIRTIO_NET_F_STANDBY)); + + vdev = start_virtio_net_internal(qts, 1, 0, &features); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + args = qdict_from_jsonf_nofail("{}"); + g_assert_nonnull(args); + qdict_put_str(args, "uri", uri); + + resp = qtest_qmp(qts, "{ 'execute': 'migrate', 'arguments': %p}", args); + g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); + + while (true) { + ret = migrate_status(qts); + + status = qdict_get_str(ret, "status"); + if (strcmp(status, "completed") == 0) { + qobject_unref(ret); + break; + } + g_assert_cmpstr(status, !=, "failed"); + g_assert_cmpstr(status, !=, "cancelling"); + g_assert_cmpstr(status, !=, "cancelled"); + qobject_unref(ret); + } + + qtest_qmp_eventwait(qts, "STOP"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qos_object_destroy((QOSGraphObject *)vdev); + machine_stop(qts); +} + +static void test_guest_off_migrate_in(gconstpointer opaque) +{ + QTestState *qts; + QDict *resp, *args, *ret; + g_autofree gchar *uri = g_strdup_printf("exec: cat %s", (gchar *)opaque); + + qts = machine_start(BASE_MACHINE + "-netdev user,id=hs0 " + "-netdev user,id=hs1 " + "-incoming defer ", + 2); + + check_one_card(qts, false, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "standby0", + "{'bus': 'root0'," + "'failover': 'on'," + "'netdev': 'hs0'," + "'mac': '"MAC_STANDBY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "primary0", + "{'bus': 'root1'," + "'failover_pair_id': 'standby0'," + "'netdev': 'hs1'," + "'rombar': 0," + "'romfile': ''," + "'mac': '"MAC_PRIMARY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + args = qdict_from_jsonf_nofail("{}"); + g_assert_nonnull(args); + qdict_put_str(args, "uri", uri); + + resp = qtest_qmp(qts, "{ 'execute': 'migrate-incoming', 'arguments': %p}", + args); + g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); + + resp = get_migration_event(qts); + g_assert_cmpstr(qdict_get_str(resp, "status"), ==, "setup"); + qobject_unref(resp); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_eventwait(qts, "RESUME"); + + ret = migrate_status(qts); + g_assert_cmpstr(qdict_get_str(ret, "status"), ==, "completed"); + qobject_unref(ret); + + machine_stop(qts); +} + +static void test_migrate_guest_off_abort(gconstpointer opaque) +{ + QTestState *qts; + QDict *resp, *args, *ret; + g_autofree gchar *uri = g_strdup_printf("exec: cat > %s", (gchar *)opaque); + const gchar *status; + QVirtioPCIDevice *vdev; + uint64_t features; + + qts = machine_start(BASE_MACHINE + "-netdev user,id=hs0 " + "-netdev user,id=hs1 ", + 2); + + check_one_card(qts, false, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "standby0", + "{'bus': 'root0'," + "'failover': 'on'," + "'netdev': 'hs0'," + "'mac': '"MAC_STANDBY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "primary0", + "{'bus': 'root1'," + "'failover_pair_id': 'standby0'," + "'netdev': 'hs1'," + "'rombar': 0," + "'romfile': ''," + "'mac': '"MAC_PRIMARY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + features = ~(QVIRTIO_F_BAD_FEATURE | + (1ull << VIRTIO_RING_F_INDIRECT_DESC) | + (1ull << VIRTIO_RING_F_EVENT_IDX) | + (1ull << VIRTIO_NET_F_STANDBY)); + + vdev = start_virtio_net_internal(qts, 1, 0, &features); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + args = qdict_from_jsonf_nofail("{}"); + g_assert_nonnull(args); + qdict_put_str(args, "uri", uri); + + resp = qtest_qmp(qts, "{ 'execute': 'migrate', 'arguments': %p}", args); + g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); + + while (true) { + ret = migrate_status(qts); + + status = qdict_get_str(ret, "status"); + if (strcmp(status, "active") == 0) { + qobject_unref(ret); + break; + } + g_assert_cmpstr(status, !=, "failed"); + qobject_unref(ret); + } + + resp = qtest_qmp(qts, "{ 'execute': 'migrate_cancel' }"); + g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); + + while (true) { + ret = migrate_status(qts); + + status = qdict_get_str(ret, "status"); + if (strcmp(status, "cancelled") == 0) { + qobject_unref(ret); + break; + } + g_assert_cmpstr(status, !=, "failed"); + g_assert_cmpstr(status, !=, "active"); + qobject_unref(ret); + } + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qos_object_destroy((QOSGraphObject *)vdev); + machine_stop(qts); +} + static void test_migrate_abort_wait_unplug(gconstpointer opaque) { QTestState *qts; @@ -780,7 +1198,7 @@ static void test_migrate_abort_wait_unplug(gconstpointer opaque) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); - vdev = start_virtio_net(qts, 1, 0, "standby0"); + vdev = start_virtio_net(qts, 1, 0, "standby0", true); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); @@ -870,7 +1288,7 @@ static void test_migrate_abort_active(gconstpointer opaque) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); - vdev = start_virtio_net(qts, 1, 0, "standby0"); + vdev = start_virtio_net(qts, 1, 0, "standby0", true); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); @@ -938,6 +1356,91 @@ static void test_migrate_abort_active(gconstpointer opaque) machine_stop(qts); } +static void test_migrate_off_abort(gconstpointer opaque) +{ + QTestState *qts; + QDict *resp, *args, *ret; + g_autofree gchar *uri = g_strdup_printf("exec: cat > %s", (gchar *)opaque); + const gchar *status; + QVirtioPCIDevice *vdev; + + qts = machine_start(BASE_MACHINE + "-netdev user,id=hs0 " + "-netdev user,id=hs1 ", + 2); + + check_one_card(qts, false, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "standby0", + "{'bus': 'root0'," + "'failover': 'off'," + "'netdev': 'hs0'," + "'mac': '"MAC_STANDBY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + vdev = start_virtio_net(qts, 1, 0, "standby0", false); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, false, "primary0", MAC_PRIMARY0); + + qtest_qmp_device_add(qts, "virtio-net", "primary0", + "{'bus': 'root1'," + "'failover_pair_id': 'standby0'," + "'netdev': 'hs1'," + "'rombar': 0," + "'romfile': ''," + "'mac': '"MAC_PRIMARY0"'}"); + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, true, "primary0", MAC_PRIMARY0); + + args = qdict_from_jsonf_nofail("{}"); + g_assert_nonnull(args); + qdict_put_str(args, "uri", uri); + + resp = qtest_qmp(qts, "{ 'execute': 'migrate', 'arguments': %p}", args); + g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); + + while (true) { + ret = migrate_status(qts); + + status = qdict_get_str(ret, "status"); + if (strcmp(status, "active") == 0) { + qobject_unref(ret); + break; + } + g_assert_cmpstr(status, !=, "failed"); + qobject_unref(ret); + } + + resp = qtest_qmp(qts, "{ 'execute': 'migrate_cancel' }"); + g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); + + while (true) { + ret = migrate_status(qts); + + status = qdict_get_str(ret, "status"); + if (strcmp(status, "cancelled") == 0) { + qobject_unref(ret); + break; + } + g_assert_cmpstr(status, !=, "failed"); + g_assert_cmpstr(status, !=, "active"); + qobject_unref(ret); + } + + check_one_card(qts, true, "standby0", MAC_STANDBY0); + check_one_card(qts, true, "primary0", MAC_PRIMARY0); + + qos_object_destroy((QOSGraphObject *)vdev); + machine_stop(qts); +} + static void test_migrate_abort_timeout(gconstpointer opaque) { QTestState *qts; @@ -964,7 +1467,7 @@ static void test_migrate_abort_timeout(gconstpointer opaque) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); - vdev = start_virtio_net(qts, 1, 0, "standby0"); + vdev = start_virtio_net(qts, 1, 0, "standby0", true); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); @@ -1075,7 +1578,7 @@ static void test_multi_out(gconstpointer opaque) check_one_card(qts, false, "standby1", MAC_STANDBY1); check_one_card(qts, false, "primary1", MAC_PRIMARY1); - vdev0 = start_virtio_net(qts, 1, 0, "standby0"); + vdev0 = start_virtio_net(qts, 1, 0, "standby0", true); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, true, "primary0", MAC_PRIMARY0); @@ -1106,7 +1609,7 @@ static void test_multi_out(gconstpointer opaque) check_one_card(qts, true, "standby1", MAC_STANDBY1); check_one_card(qts, false, "primary1", MAC_PRIMARY1); - vdev1 = start_virtio_net(qts, 3, 0, "standby1"); + vdev1 = start_virtio_net(qts, 3, 0, "standby1", true); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, true, "primary0", MAC_PRIMARY0); @@ -1315,6 +1818,7 @@ int main(int argc, char **argv) g_assert_true(ret >= 0); close(ret); + /* parameters tests */ qtest_add_func("failover-virtio-net/params/error/id", test_error_id); qtest_add_func("failover-virtio-net/params/error/pcie", test_error_pcie); qtest_add_func("failover-virtio-net/params/on", test_on); @@ -1322,16 +1826,33 @@ int main(int argc, char **argv) test_on_mismatch); qtest_add_func("failover-virtio-net/params/off", test_off); qtest_add_func("failover-virtio-net/params/enabled", test_enabled); - qtest_add_func("failover-virtio-net/hotplug_1", test_hotplug_1); - qtest_add_func("failover-virtio-net/hotplug_1_reverse", + qtest_add_func("failover-virtio-net/params/guest_off", test_guest_off); + + /* hotplug tests */ + qtest_add_func("failover-virtio-net/hotplug/1", test_hotplug_1); + qtest_add_func("failover-virtio-net/hotplug/1_reverse", test_hotplug_1_reverse); - qtest_add_func("failover-virtio-net/hotplug_2", test_hotplug_2); - qtest_add_func("failover-virtio-net/hotplug_2_reverse", + qtest_add_func("failover-virtio-net/hotplug/2", test_hotplug_2); + qtest_add_func("failover-virtio-net/hotplug/2_reverse", test_hotplug_2_reverse); - qtest_add_data_func("failover-virtio-net/migrate/out", tmpfile, + + /* migration tests */ + qtest_add_data_func("failover-virtio-net/migrate/on/out", tmpfile, test_migrate_out); - qtest_add_data_func("failover-virtio-net/migrate/in", tmpfile, + qtest_add_data_func("failover-virtio-net/migrate/on/in", tmpfile, test_migrate_in); + qtest_add_data_func("failover-virtio-net/migrate/off/out", tmpfile, + test_off_migrate_out); + qtest_add_data_func("failover-virtio-net/migrate/off/in", tmpfile, + test_off_migrate_in); + qtest_add_data_func("failover-virtio-net/migrate/off/abort", tmpfile, + test_migrate_off_abort); + qtest_add_data_func("failover-virtio-net/migrate/guest_off/out", tmpfile, + test_guest_off_migrate_out); + qtest_add_data_func("failover-virtio-net/migrate/guest_off/in", tmpfile, + test_guest_off_migrate_in); + qtest_add_data_func("failover-virtio-net/migrate/guest_off/abort", tmpfile, + test_migrate_guest_off_abort); qtest_add_data_func("failover-virtio-net/migrate/abort/wait-unplug", tmpfile, test_migrate_abort_wait_unplug); qtest_add_data_func("failover-virtio-net/migrate/abort/active", tmpfile, @@ -1340,9 +1861,9 @@ int main(int argc, char **argv) qtest_add_data_func("failover-virtio-net/migrate/abort/timeout", tmpfile, test_migrate_abort_timeout); } - qtest_add_data_func("failover-virtio-net/multi/out", + qtest_add_data_func("failover-virtio-net/migrate/multi/out", tmpfile, test_multi_out); - qtest_add_data_func("failover-virtio-net/multi/in", + qtest_add_data_func("failover-virtio-net/migrate/multi/in", tmpfile, test_multi_in); ret = g_test_run(); |