1d8057eb3SFabiano Rosas /* 2d8057eb3SFabiano Rosas * QTest testcases for migration to file 3d8057eb3SFabiano Rosas * 4d8057eb3SFabiano Rosas * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates 5d8057eb3SFabiano Rosas * based on the vhost-user-test.c that is: 6d8057eb3SFabiano Rosas * Copyright (c) 2014 Virtual Open Systems Sarl. 7d8057eb3SFabiano Rosas * 8d8057eb3SFabiano Rosas * This work is licensed under the terms of the GNU GPL, version 2 or later. 9d8057eb3SFabiano Rosas * See the COPYING file in the top-level directory. 10d8057eb3SFabiano Rosas * 11d8057eb3SFabiano Rosas */ 12d8057eb3SFabiano Rosas 13d8057eb3SFabiano Rosas #include "qemu/osdep.h" 14d8057eb3SFabiano Rosas #include "libqtest.h" 15d8057eb3SFabiano Rosas #include "migration/framework.h" 16d8057eb3SFabiano Rosas #include "migration/migration-qmp.h" 17d8057eb3SFabiano Rosas #include "migration/migration-util.h" 18407bc4bfSDaniel P. Berrangé #include "qobject/qlist.h" 19d8057eb3SFabiano Rosas 20d8057eb3SFabiano Rosas 21d8057eb3SFabiano Rosas static char *tmpfs; 22d8057eb3SFabiano Rosas 23d8057eb3SFabiano Rosas static void test_precopy_file(void) 24d8057eb3SFabiano Rosas { 25d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 26d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 27d8057eb3SFabiano Rosas MigrateCommon args = { 28d8057eb3SFabiano Rosas .connect_uri = uri, 29d8057eb3SFabiano Rosas .listen_uri = "defer", 30d8057eb3SFabiano Rosas }; 31d8057eb3SFabiano Rosas 32d8057eb3SFabiano Rosas test_file_common(&args, true); 33d8057eb3SFabiano Rosas } 34d8057eb3SFabiano Rosas 35d8057eb3SFabiano Rosas #ifndef _WIN32 36d8057eb3SFabiano Rosas static void fdset_add_fds(QTestState *qts, const char *file, int flags, 37d8057eb3SFabiano Rosas int num_fds, bool direct_io) 38d8057eb3SFabiano Rosas { 39d8057eb3SFabiano Rosas for (int i = 0; i < num_fds; i++) { 40d8057eb3SFabiano Rosas int fd; 41d8057eb3SFabiano Rosas 42d8057eb3SFabiano Rosas #ifdef O_DIRECT 43d8057eb3SFabiano Rosas /* only secondary channels can use direct-io */ 44d8057eb3SFabiano Rosas if (direct_io && i != 0) { 45d8057eb3SFabiano Rosas flags |= O_DIRECT; 46d8057eb3SFabiano Rosas } 47d8057eb3SFabiano Rosas #endif 48d8057eb3SFabiano Rosas 49d8057eb3SFabiano Rosas fd = open(file, flags, 0660); 50d8057eb3SFabiano Rosas assert(fd != -1); 51d8057eb3SFabiano Rosas 52d8057eb3SFabiano Rosas qtest_qmp_fds_assert_success(qts, &fd, 1, "{'execute': 'add-fd', " 53d8057eb3SFabiano Rosas "'arguments': {'fdset-id': 1}}"); 54d8057eb3SFabiano Rosas close(fd); 55d8057eb3SFabiano Rosas } 56d8057eb3SFabiano Rosas } 57d8057eb3SFabiano Rosas 58d8057eb3SFabiano Rosas static void *migrate_hook_start_file_offset_fdset(QTestState *from, 59d8057eb3SFabiano Rosas QTestState *to) 60d8057eb3SFabiano Rosas { 61d8057eb3SFabiano Rosas g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME); 62d8057eb3SFabiano Rosas 63d8057eb3SFabiano Rosas fdset_add_fds(from, file, O_WRONLY, 1, false); 64d8057eb3SFabiano Rosas fdset_add_fds(to, file, O_RDONLY, 1, false); 65d8057eb3SFabiano Rosas 66d8057eb3SFabiano Rosas return NULL; 67d8057eb3SFabiano Rosas } 68d8057eb3SFabiano Rosas 69d8057eb3SFabiano Rosas static void test_precopy_file_offset_fdset(void) 70d8057eb3SFabiano Rosas { 71d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d", 72d8057eb3SFabiano Rosas FILE_TEST_OFFSET); 73d8057eb3SFabiano Rosas MigrateCommon args = { 74d8057eb3SFabiano Rosas .connect_uri = uri, 75d8057eb3SFabiano Rosas .listen_uri = "defer", 76d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_file_offset_fdset, 77d8057eb3SFabiano Rosas }; 78d8057eb3SFabiano Rosas 79d8057eb3SFabiano Rosas test_file_common(&args, false); 80d8057eb3SFabiano Rosas } 81d8057eb3SFabiano Rosas #endif 82d8057eb3SFabiano Rosas 83d8057eb3SFabiano Rosas static void test_precopy_file_offset(void) 84d8057eb3SFabiano Rosas { 85d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s,offset=%d", tmpfs, 86d8057eb3SFabiano Rosas FILE_TEST_FILENAME, 87d8057eb3SFabiano Rosas FILE_TEST_OFFSET); 88d8057eb3SFabiano Rosas MigrateCommon args = { 89d8057eb3SFabiano Rosas .connect_uri = uri, 90d8057eb3SFabiano Rosas .listen_uri = "defer", 91d8057eb3SFabiano Rosas }; 92d8057eb3SFabiano Rosas 93d8057eb3SFabiano Rosas test_file_common(&args, false); 94d8057eb3SFabiano Rosas } 95d8057eb3SFabiano Rosas 96d8057eb3SFabiano Rosas static void test_precopy_file_offset_bad(void) 97d8057eb3SFabiano Rosas { 98d8057eb3SFabiano Rosas /* using a value not supported by qemu_strtosz() */ 99d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s,offset=0x20M", 100d8057eb3SFabiano Rosas tmpfs, FILE_TEST_FILENAME); 101d8057eb3SFabiano Rosas MigrateCommon args = { 102d8057eb3SFabiano Rosas .connect_uri = uri, 103d8057eb3SFabiano Rosas .listen_uri = "defer", 104d8057eb3SFabiano Rosas .result = MIG_TEST_QMP_ERROR, 105d8057eb3SFabiano Rosas }; 106d8057eb3SFabiano Rosas 107d8057eb3SFabiano Rosas test_file_common(&args, false); 108d8057eb3SFabiano Rosas } 109d8057eb3SFabiano Rosas 110d8057eb3SFabiano Rosas static void test_precopy_file_mapped_ram_live(void) 111d8057eb3SFabiano Rosas { 112d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 113d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 114d8057eb3SFabiano Rosas MigrateCommon args = { 115d8057eb3SFabiano Rosas .connect_uri = uri, 116d8057eb3SFabiano Rosas .listen_uri = "defer", 117*115cec9dSPrasad Pandit .start = { 118*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, 119*115cec9dSPrasad Pandit }, 120d8057eb3SFabiano Rosas }; 121d8057eb3SFabiano Rosas 122d8057eb3SFabiano Rosas test_file_common(&args, false); 123d8057eb3SFabiano Rosas } 124d8057eb3SFabiano Rosas 125d8057eb3SFabiano Rosas static void test_precopy_file_mapped_ram(void) 126d8057eb3SFabiano Rosas { 127d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 128d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 129d8057eb3SFabiano Rosas MigrateCommon args = { 130d8057eb3SFabiano Rosas .connect_uri = uri, 131d8057eb3SFabiano Rosas .listen_uri = "defer", 132*115cec9dSPrasad Pandit .start = { 133*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, 134*115cec9dSPrasad Pandit }, 135d8057eb3SFabiano Rosas }; 136d8057eb3SFabiano Rosas 137d8057eb3SFabiano Rosas test_file_common(&args, true); 138d8057eb3SFabiano Rosas } 139d8057eb3SFabiano Rosas 140d8057eb3SFabiano Rosas static void test_multifd_file_mapped_ram_live(void) 141d8057eb3SFabiano Rosas { 142d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 143d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 144d8057eb3SFabiano Rosas MigrateCommon args = { 145d8057eb3SFabiano Rosas .connect_uri = uri, 146d8057eb3SFabiano Rosas .listen_uri = "defer", 147*115cec9dSPrasad Pandit .start = { 148*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MULTIFD] = true, 149*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, 150*115cec9dSPrasad Pandit }, 151d8057eb3SFabiano Rosas }; 152d8057eb3SFabiano Rosas 153d8057eb3SFabiano Rosas test_file_common(&args, false); 154d8057eb3SFabiano Rosas } 155d8057eb3SFabiano Rosas 156d8057eb3SFabiano Rosas static void test_multifd_file_mapped_ram(void) 157d8057eb3SFabiano Rosas { 158d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 159d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 160d8057eb3SFabiano Rosas MigrateCommon args = { 161d8057eb3SFabiano Rosas .connect_uri = uri, 162d8057eb3SFabiano Rosas .listen_uri = "defer", 163*115cec9dSPrasad Pandit .start = { 164*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MULTIFD] = true, 165*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, 166*115cec9dSPrasad Pandit }, 167d8057eb3SFabiano Rosas }; 168d8057eb3SFabiano Rosas 169d8057eb3SFabiano Rosas test_file_common(&args, true); 170d8057eb3SFabiano Rosas } 171d8057eb3SFabiano Rosas 172d8057eb3SFabiano Rosas static void *migrate_hook_start_multifd_mapped_ram_dio(QTestState *from, 173d8057eb3SFabiano Rosas QTestState *to) 174d8057eb3SFabiano Rosas { 175d8057eb3SFabiano Rosas migrate_set_parameter_bool(from, "direct-io", true); 176d8057eb3SFabiano Rosas migrate_set_parameter_bool(to, "direct-io", true); 177d8057eb3SFabiano Rosas 178d8057eb3SFabiano Rosas return NULL; 179d8057eb3SFabiano Rosas } 180d8057eb3SFabiano Rosas 181d8057eb3SFabiano Rosas static void test_multifd_file_mapped_ram_dio(void) 182d8057eb3SFabiano Rosas { 183d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 184d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 185d8057eb3SFabiano Rosas MigrateCommon args = { 186d8057eb3SFabiano Rosas .connect_uri = uri, 187d8057eb3SFabiano Rosas .listen_uri = "defer", 188d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_multifd_mapped_ram_dio, 189*115cec9dSPrasad Pandit .start = { 190*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, 191*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MULTIFD] = true, 192*115cec9dSPrasad Pandit }, 193d8057eb3SFabiano Rosas }; 194d8057eb3SFabiano Rosas 195d8057eb3SFabiano Rosas if (!probe_o_direct_support(tmpfs)) { 196d8057eb3SFabiano Rosas g_test_skip("Filesystem does not support O_DIRECT"); 197d8057eb3SFabiano Rosas return; 198d8057eb3SFabiano Rosas } 199d8057eb3SFabiano Rosas 200d8057eb3SFabiano Rosas test_file_common(&args, true); 201d8057eb3SFabiano Rosas } 202d8057eb3SFabiano Rosas 203d8057eb3SFabiano Rosas #ifndef _WIN32 204d8057eb3SFabiano Rosas static void migrate_hook_end_multifd_mapped_ram_fdset(QTestState *from, 205d8057eb3SFabiano Rosas QTestState *to, 206d8057eb3SFabiano Rosas void *opaque) 207d8057eb3SFabiano Rosas { 208d8057eb3SFabiano Rosas QDict *resp; 209d8057eb3SFabiano Rosas QList *fdsets; 210d8057eb3SFabiano Rosas 211d8057eb3SFabiano Rosas /* 212d8057eb3SFabiano Rosas * Remove the fdsets after migration, otherwise a second migration 213d8057eb3SFabiano Rosas * would fail due fdset reuse. 214d8057eb3SFabiano Rosas */ 215d8057eb3SFabiano Rosas qtest_qmp_assert_success(from, "{'execute': 'remove-fd', " 216d8057eb3SFabiano Rosas "'arguments': { 'fdset-id': 1}}"); 217d8057eb3SFabiano Rosas 218d8057eb3SFabiano Rosas /* 219d8057eb3SFabiano Rosas * Make sure no fdsets are left after migration, otherwise a 220d8057eb3SFabiano Rosas * second migration would fail due fdset reuse. 221d8057eb3SFabiano Rosas */ 222d8057eb3SFabiano Rosas resp = qtest_qmp(from, "{'execute': 'query-fdsets', " 223d8057eb3SFabiano Rosas "'arguments': {}}"); 224d8057eb3SFabiano Rosas g_assert(qdict_haskey(resp, "return")); 225d8057eb3SFabiano Rosas fdsets = qdict_get_qlist(resp, "return"); 226d8057eb3SFabiano Rosas g_assert(fdsets && qlist_empty(fdsets)); 227d8057eb3SFabiano Rosas qobject_unref(resp); 228d8057eb3SFabiano Rosas } 229d8057eb3SFabiano Rosas 230d8057eb3SFabiano Rosas static void *migrate_hook_start_multifd_mapped_ram_fdset_dio(QTestState *from, 231d8057eb3SFabiano Rosas QTestState *to) 232d8057eb3SFabiano Rosas { 233d8057eb3SFabiano Rosas g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME); 234d8057eb3SFabiano Rosas 235d8057eb3SFabiano Rosas fdset_add_fds(from, file, O_WRONLY, 2, true); 236d8057eb3SFabiano Rosas fdset_add_fds(to, file, O_RDONLY, 2, true); 237d8057eb3SFabiano Rosas 238d8057eb3SFabiano Rosas migrate_set_parameter_bool(from, "direct-io", true); 239d8057eb3SFabiano Rosas migrate_set_parameter_bool(to, "direct-io", true); 240d8057eb3SFabiano Rosas 241d8057eb3SFabiano Rosas return NULL; 242d8057eb3SFabiano Rosas } 243d8057eb3SFabiano Rosas 244d8057eb3SFabiano Rosas static void *migrate_hook_start_multifd_mapped_ram_fdset(QTestState *from, 245d8057eb3SFabiano Rosas QTestState *to) 246d8057eb3SFabiano Rosas { 247d8057eb3SFabiano Rosas g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME); 248d8057eb3SFabiano Rosas 249d8057eb3SFabiano Rosas fdset_add_fds(from, file, O_WRONLY, 2, false); 250d8057eb3SFabiano Rosas fdset_add_fds(to, file, O_RDONLY, 2, false); 251d8057eb3SFabiano Rosas 252d8057eb3SFabiano Rosas return NULL; 253d8057eb3SFabiano Rosas } 254d8057eb3SFabiano Rosas 255d8057eb3SFabiano Rosas static void test_multifd_file_mapped_ram_fdset(void) 256d8057eb3SFabiano Rosas { 257d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d", 258d8057eb3SFabiano Rosas FILE_TEST_OFFSET); 259d8057eb3SFabiano Rosas MigrateCommon args = { 260d8057eb3SFabiano Rosas .connect_uri = uri, 261d8057eb3SFabiano Rosas .listen_uri = "defer", 262d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_multifd_mapped_ram_fdset, 263d8057eb3SFabiano Rosas .end_hook = migrate_hook_end_multifd_mapped_ram_fdset, 264*115cec9dSPrasad Pandit .start = { 265*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, 266*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MULTIFD] = true, 267*115cec9dSPrasad Pandit }, 268d8057eb3SFabiano Rosas }; 269d8057eb3SFabiano Rosas 270d8057eb3SFabiano Rosas test_file_common(&args, true); 271d8057eb3SFabiano Rosas } 272d8057eb3SFabiano Rosas 273d8057eb3SFabiano Rosas static void test_multifd_file_mapped_ram_fdset_dio(void) 274d8057eb3SFabiano Rosas { 275d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d", 276d8057eb3SFabiano Rosas FILE_TEST_OFFSET); 277d8057eb3SFabiano Rosas MigrateCommon args = { 278d8057eb3SFabiano Rosas .connect_uri = uri, 279d8057eb3SFabiano Rosas .listen_uri = "defer", 280d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_multifd_mapped_ram_fdset_dio, 281d8057eb3SFabiano Rosas .end_hook = migrate_hook_end_multifd_mapped_ram_fdset, 282*115cec9dSPrasad Pandit .start = { 283*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, 284*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_MULTIFD] = true, 285*115cec9dSPrasad Pandit }, 286d8057eb3SFabiano Rosas }; 287d8057eb3SFabiano Rosas 288d8057eb3SFabiano Rosas if (!probe_o_direct_support(tmpfs)) { 289d8057eb3SFabiano Rosas g_test_skip("Filesystem does not support O_DIRECT"); 290d8057eb3SFabiano Rosas return; 291d8057eb3SFabiano Rosas } 292d8057eb3SFabiano Rosas 293d8057eb3SFabiano Rosas test_file_common(&args, true); 294d8057eb3SFabiano Rosas } 295d8057eb3SFabiano Rosas #endif /* !_WIN32 */ 296d8057eb3SFabiano Rosas 29743ab3fb3SFabiano Rosas static void migration_test_add_file_smoke(MigrationTestEnv *env) 29843ab3fb3SFabiano Rosas { 29943ab3fb3SFabiano Rosas migration_test_add("/migration/precopy/file", 30043ab3fb3SFabiano Rosas test_precopy_file); 30143ab3fb3SFabiano Rosas 30243ab3fb3SFabiano Rosas migration_test_add("/migration/multifd/file/mapped-ram/dio", 30343ab3fb3SFabiano Rosas test_multifd_file_mapped_ram_dio); 30443ab3fb3SFabiano Rosas } 30543ab3fb3SFabiano Rosas 306d8057eb3SFabiano Rosas void migration_test_add_file(MigrationTestEnv *env) 307d8057eb3SFabiano Rosas { 308d8057eb3SFabiano Rosas tmpfs = env->tmpfs; 309d8057eb3SFabiano Rosas 31043ab3fb3SFabiano Rosas migration_test_add_file_smoke(env); 31143ab3fb3SFabiano Rosas 312bc2a1f1aSFabiano Rosas if (!env->full_set) { 313bc2a1f1aSFabiano Rosas return; 314bc2a1f1aSFabiano Rosas } 315d8057eb3SFabiano Rosas 316d8057eb3SFabiano Rosas migration_test_add("/migration/precopy/file/offset", 317d8057eb3SFabiano Rosas test_precopy_file_offset); 318d8057eb3SFabiano Rosas #ifndef _WIN32 319d8057eb3SFabiano Rosas migration_test_add("/migration/precopy/file/offset/fdset", 320d8057eb3SFabiano Rosas test_precopy_file_offset_fdset); 321d8057eb3SFabiano Rosas #endif 322d8057eb3SFabiano Rosas migration_test_add("/migration/precopy/file/offset/bad", 323d8057eb3SFabiano Rosas test_precopy_file_offset_bad); 324d8057eb3SFabiano Rosas 325d8057eb3SFabiano Rosas migration_test_add("/migration/precopy/file/mapped-ram", 326d8057eb3SFabiano Rosas test_precopy_file_mapped_ram); 327d8057eb3SFabiano Rosas migration_test_add("/migration/precopy/file/mapped-ram/live", 328d8057eb3SFabiano Rosas test_precopy_file_mapped_ram_live); 329d8057eb3SFabiano Rosas 330d8057eb3SFabiano Rosas migration_test_add("/migration/multifd/file/mapped-ram", 331d8057eb3SFabiano Rosas test_multifd_file_mapped_ram); 332d8057eb3SFabiano Rosas migration_test_add("/migration/multifd/file/mapped-ram/live", 333d8057eb3SFabiano Rosas test_multifd_file_mapped_ram_live); 334d8057eb3SFabiano Rosas 335d8057eb3SFabiano Rosas #ifndef _WIN32 336d8057eb3SFabiano Rosas migration_test_add("/migration/multifd/file/mapped-ram/fdset", 337d8057eb3SFabiano Rosas test_multifd_file_mapped_ram_fdset); 338d8057eb3SFabiano Rosas migration_test_add("/migration/multifd/file/mapped-ram/fdset/dio", 339d8057eb3SFabiano Rosas test_multifd_file_mapped_ram_fdset_dio); 340d8057eb3SFabiano Rosas #endif 341d8057eb3SFabiano Rosas } 342