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" 18d8057eb3SFabiano Rosas #include "qapi/qmp/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 *migrate_hook_start_mapped_ram(QTestState *from, 111d8057eb3SFabiano Rosas QTestState *to) 112d8057eb3SFabiano Rosas { 113d8057eb3SFabiano Rosas migrate_set_capability(from, "mapped-ram", true); 114d8057eb3SFabiano Rosas migrate_set_capability(to, "mapped-ram", true); 115d8057eb3SFabiano Rosas 116d8057eb3SFabiano Rosas return NULL; 117d8057eb3SFabiano Rosas } 118d8057eb3SFabiano Rosas 119d8057eb3SFabiano Rosas static void test_precopy_file_mapped_ram_live(void) 120d8057eb3SFabiano Rosas { 121d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 122d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 123d8057eb3SFabiano Rosas MigrateCommon args = { 124d8057eb3SFabiano Rosas .connect_uri = uri, 125d8057eb3SFabiano Rosas .listen_uri = "defer", 126d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_mapped_ram, 127d8057eb3SFabiano Rosas }; 128d8057eb3SFabiano Rosas 129d8057eb3SFabiano Rosas test_file_common(&args, false); 130d8057eb3SFabiano Rosas } 131d8057eb3SFabiano Rosas 132d8057eb3SFabiano Rosas static void test_precopy_file_mapped_ram(void) 133d8057eb3SFabiano Rosas { 134d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 135d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 136d8057eb3SFabiano Rosas MigrateCommon args = { 137d8057eb3SFabiano Rosas .connect_uri = uri, 138d8057eb3SFabiano Rosas .listen_uri = "defer", 139d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_mapped_ram, 140d8057eb3SFabiano Rosas }; 141d8057eb3SFabiano Rosas 142d8057eb3SFabiano Rosas test_file_common(&args, true); 143d8057eb3SFabiano Rosas } 144d8057eb3SFabiano Rosas 145d8057eb3SFabiano Rosas static void *migrate_hook_start_multifd_mapped_ram(QTestState *from, 146d8057eb3SFabiano Rosas QTestState *to) 147d8057eb3SFabiano Rosas { 148d8057eb3SFabiano Rosas migrate_hook_start_mapped_ram(from, to); 149d8057eb3SFabiano Rosas 150d8057eb3SFabiano Rosas migrate_set_parameter_int(from, "multifd-channels", 4); 151d8057eb3SFabiano Rosas migrate_set_parameter_int(to, "multifd-channels", 4); 152d8057eb3SFabiano Rosas 153d8057eb3SFabiano Rosas migrate_set_capability(from, "multifd", true); 154d8057eb3SFabiano Rosas migrate_set_capability(to, "multifd", true); 155d8057eb3SFabiano Rosas 156d8057eb3SFabiano Rosas return NULL; 157d8057eb3SFabiano Rosas } 158d8057eb3SFabiano Rosas 159d8057eb3SFabiano Rosas static void test_multifd_file_mapped_ram_live(void) 160d8057eb3SFabiano Rosas { 161d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 162d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 163d8057eb3SFabiano Rosas MigrateCommon args = { 164d8057eb3SFabiano Rosas .connect_uri = uri, 165d8057eb3SFabiano Rosas .listen_uri = "defer", 166d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_multifd_mapped_ram, 167d8057eb3SFabiano Rosas }; 168d8057eb3SFabiano Rosas 169d8057eb3SFabiano Rosas test_file_common(&args, false); 170d8057eb3SFabiano Rosas } 171d8057eb3SFabiano Rosas 172d8057eb3SFabiano Rosas static void test_multifd_file_mapped_ram(void) 173d8057eb3SFabiano Rosas { 174d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 175d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 176d8057eb3SFabiano Rosas MigrateCommon args = { 177d8057eb3SFabiano Rosas .connect_uri = uri, 178d8057eb3SFabiano Rosas .listen_uri = "defer", 179d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_multifd_mapped_ram, 180d8057eb3SFabiano Rosas }; 181d8057eb3SFabiano Rosas 182d8057eb3SFabiano Rosas test_file_common(&args, true); 183d8057eb3SFabiano Rosas } 184d8057eb3SFabiano Rosas 185d8057eb3SFabiano Rosas static void *migrate_hook_start_multifd_mapped_ram_dio(QTestState *from, 186d8057eb3SFabiano Rosas QTestState *to) 187d8057eb3SFabiano Rosas { 188d8057eb3SFabiano Rosas migrate_hook_start_multifd_mapped_ram(from, to); 189d8057eb3SFabiano Rosas 190d8057eb3SFabiano Rosas migrate_set_parameter_bool(from, "direct-io", true); 191d8057eb3SFabiano Rosas migrate_set_parameter_bool(to, "direct-io", true); 192d8057eb3SFabiano Rosas 193d8057eb3SFabiano Rosas return NULL; 194d8057eb3SFabiano Rosas } 195d8057eb3SFabiano Rosas 196d8057eb3SFabiano Rosas static void test_multifd_file_mapped_ram_dio(void) 197d8057eb3SFabiano Rosas { 198d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, 199d8057eb3SFabiano Rosas FILE_TEST_FILENAME); 200d8057eb3SFabiano Rosas MigrateCommon args = { 201d8057eb3SFabiano Rosas .connect_uri = uri, 202d8057eb3SFabiano Rosas .listen_uri = "defer", 203d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_multifd_mapped_ram_dio, 204d8057eb3SFabiano Rosas }; 205d8057eb3SFabiano Rosas 206d8057eb3SFabiano Rosas if (!probe_o_direct_support(tmpfs)) { 207d8057eb3SFabiano Rosas g_test_skip("Filesystem does not support O_DIRECT"); 208d8057eb3SFabiano Rosas return; 209d8057eb3SFabiano Rosas } 210d8057eb3SFabiano Rosas 211d8057eb3SFabiano Rosas test_file_common(&args, true); 212d8057eb3SFabiano Rosas } 213d8057eb3SFabiano Rosas 214d8057eb3SFabiano Rosas #ifndef _WIN32 215d8057eb3SFabiano Rosas static void migrate_hook_end_multifd_mapped_ram_fdset(QTestState *from, 216d8057eb3SFabiano Rosas QTestState *to, 217d8057eb3SFabiano Rosas void *opaque) 218d8057eb3SFabiano Rosas { 219d8057eb3SFabiano Rosas QDict *resp; 220d8057eb3SFabiano Rosas QList *fdsets; 221d8057eb3SFabiano Rosas 222d8057eb3SFabiano Rosas /* 223d8057eb3SFabiano Rosas * Remove the fdsets after migration, otherwise a second migration 224d8057eb3SFabiano Rosas * would fail due fdset reuse. 225d8057eb3SFabiano Rosas */ 226d8057eb3SFabiano Rosas qtest_qmp_assert_success(from, "{'execute': 'remove-fd', " 227d8057eb3SFabiano Rosas "'arguments': { 'fdset-id': 1}}"); 228d8057eb3SFabiano Rosas 229d8057eb3SFabiano Rosas /* 230d8057eb3SFabiano Rosas * Make sure no fdsets are left after migration, otherwise a 231d8057eb3SFabiano Rosas * second migration would fail due fdset reuse. 232d8057eb3SFabiano Rosas */ 233d8057eb3SFabiano Rosas resp = qtest_qmp(from, "{'execute': 'query-fdsets', " 234d8057eb3SFabiano Rosas "'arguments': {}}"); 235d8057eb3SFabiano Rosas g_assert(qdict_haskey(resp, "return")); 236d8057eb3SFabiano Rosas fdsets = qdict_get_qlist(resp, "return"); 237d8057eb3SFabiano Rosas g_assert(fdsets && qlist_empty(fdsets)); 238d8057eb3SFabiano Rosas qobject_unref(resp); 239d8057eb3SFabiano Rosas } 240d8057eb3SFabiano Rosas 241d8057eb3SFabiano Rosas static void *migrate_hook_start_multifd_mapped_ram_fdset_dio(QTestState *from, 242d8057eb3SFabiano Rosas QTestState *to) 243d8057eb3SFabiano Rosas { 244d8057eb3SFabiano Rosas g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME); 245d8057eb3SFabiano Rosas 246d8057eb3SFabiano Rosas fdset_add_fds(from, file, O_WRONLY, 2, true); 247d8057eb3SFabiano Rosas fdset_add_fds(to, file, O_RDONLY, 2, true); 248d8057eb3SFabiano Rosas 249d8057eb3SFabiano Rosas migrate_hook_start_multifd_mapped_ram(from, to); 250d8057eb3SFabiano Rosas migrate_set_parameter_bool(from, "direct-io", true); 251d8057eb3SFabiano Rosas migrate_set_parameter_bool(to, "direct-io", true); 252d8057eb3SFabiano Rosas 253d8057eb3SFabiano Rosas return NULL; 254d8057eb3SFabiano Rosas } 255d8057eb3SFabiano Rosas 256d8057eb3SFabiano Rosas static void *migrate_hook_start_multifd_mapped_ram_fdset(QTestState *from, 257d8057eb3SFabiano Rosas QTestState *to) 258d8057eb3SFabiano Rosas { 259d8057eb3SFabiano Rosas g_autofree char *file = g_strdup_printf("%s/%s", tmpfs, FILE_TEST_FILENAME); 260d8057eb3SFabiano Rosas 261d8057eb3SFabiano Rosas fdset_add_fds(from, file, O_WRONLY, 2, false); 262d8057eb3SFabiano Rosas fdset_add_fds(to, file, O_RDONLY, 2, false); 263d8057eb3SFabiano Rosas 264d8057eb3SFabiano Rosas migrate_hook_start_multifd_mapped_ram(from, to); 265d8057eb3SFabiano Rosas 266d8057eb3SFabiano Rosas return NULL; 267d8057eb3SFabiano Rosas } 268d8057eb3SFabiano Rosas 269d8057eb3SFabiano Rosas static void test_multifd_file_mapped_ram_fdset(void) 270d8057eb3SFabiano Rosas { 271d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d", 272d8057eb3SFabiano Rosas FILE_TEST_OFFSET); 273d8057eb3SFabiano Rosas MigrateCommon args = { 274d8057eb3SFabiano Rosas .connect_uri = uri, 275d8057eb3SFabiano Rosas .listen_uri = "defer", 276d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_multifd_mapped_ram_fdset, 277d8057eb3SFabiano Rosas .end_hook = migrate_hook_end_multifd_mapped_ram_fdset, 278d8057eb3SFabiano Rosas }; 279d8057eb3SFabiano Rosas 280d8057eb3SFabiano Rosas test_file_common(&args, true); 281d8057eb3SFabiano Rosas } 282d8057eb3SFabiano Rosas 283d8057eb3SFabiano Rosas static void test_multifd_file_mapped_ram_fdset_dio(void) 284d8057eb3SFabiano Rosas { 285d8057eb3SFabiano Rosas g_autofree char *uri = g_strdup_printf("file:/dev/fdset/1,offset=%d", 286d8057eb3SFabiano Rosas FILE_TEST_OFFSET); 287d8057eb3SFabiano Rosas MigrateCommon args = { 288d8057eb3SFabiano Rosas .connect_uri = uri, 289d8057eb3SFabiano Rosas .listen_uri = "defer", 290d8057eb3SFabiano Rosas .start_hook = migrate_hook_start_multifd_mapped_ram_fdset_dio, 291d8057eb3SFabiano Rosas .end_hook = migrate_hook_end_multifd_mapped_ram_fdset, 292d8057eb3SFabiano Rosas }; 293d8057eb3SFabiano Rosas 294d8057eb3SFabiano Rosas if (!probe_o_direct_support(tmpfs)) { 295d8057eb3SFabiano Rosas g_test_skip("Filesystem does not support O_DIRECT"); 296d8057eb3SFabiano Rosas return; 297d8057eb3SFabiano Rosas } 298d8057eb3SFabiano Rosas 299d8057eb3SFabiano Rosas test_file_common(&args, true); 300d8057eb3SFabiano Rosas } 301d8057eb3SFabiano Rosas #endif /* !_WIN32 */ 302d8057eb3SFabiano Rosas 303*43ab3fb3SFabiano Rosas static void migration_test_add_file_smoke(MigrationTestEnv *env) 304*43ab3fb3SFabiano Rosas { 305*43ab3fb3SFabiano Rosas migration_test_add("/migration/precopy/file", 306*43ab3fb3SFabiano Rosas test_precopy_file); 307*43ab3fb3SFabiano Rosas 308*43ab3fb3SFabiano Rosas migration_test_add("/migration/multifd/file/mapped-ram/dio", 309*43ab3fb3SFabiano Rosas test_multifd_file_mapped_ram_dio); 310*43ab3fb3SFabiano Rosas } 311*43ab3fb3SFabiano Rosas 312d8057eb3SFabiano Rosas void migration_test_add_file(MigrationTestEnv *env) 313d8057eb3SFabiano Rosas { 314d8057eb3SFabiano Rosas tmpfs = env->tmpfs; 315d8057eb3SFabiano Rosas 316*43ab3fb3SFabiano Rosas migration_test_add_file_smoke(env); 317*43ab3fb3SFabiano Rosas 318bc2a1f1aSFabiano Rosas if (!env->full_set) { 319bc2a1f1aSFabiano Rosas return; 320bc2a1f1aSFabiano Rosas } 321bc2a1f1aSFabiano Rosas 322d8057eb3SFabiano Rosas migration_test_add("/migration/precopy/file/offset", 323d8057eb3SFabiano Rosas test_precopy_file_offset); 324d8057eb3SFabiano Rosas #ifndef _WIN32 325d8057eb3SFabiano Rosas migration_test_add("/migration/precopy/file/offset/fdset", 326d8057eb3SFabiano Rosas test_precopy_file_offset_fdset); 327d8057eb3SFabiano Rosas #endif 328d8057eb3SFabiano Rosas migration_test_add("/migration/precopy/file/offset/bad", 329d8057eb3SFabiano Rosas test_precopy_file_offset_bad); 330d8057eb3SFabiano Rosas 331d8057eb3SFabiano Rosas migration_test_add("/migration/precopy/file/mapped-ram", 332d8057eb3SFabiano Rosas test_precopy_file_mapped_ram); 333d8057eb3SFabiano Rosas migration_test_add("/migration/precopy/file/mapped-ram/live", 334d8057eb3SFabiano Rosas test_precopy_file_mapped_ram_live); 335d8057eb3SFabiano Rosas 336d8057eb3SFabiano Rosas migration_test_add("/migration/multifd/file/mapped-ram", 337d8057eb3SFabiano Rosas test_multifd_file_mapped_ram); 338d8057eb3SFabiano Rosas migration_test_add("/migration/multifd/file/mapped-ram/live", 339d8057eb3SFabiano Rosas test_multifd_file_mapped_ram_live); 340d8057eb3SFabiano Rosas 341d8057eb3SFabiano Rosas #ifndef _WIN32 342d8057eb3SFabiano Rosas migration_test_add("/migration/multifd/file/mapped-ram/fdset", 343d8057eb3SFabiano Rosas test_multifd_file_mapped_ram_fdset); 344d8057eb3SFabiano Rosas migration_test_add("/migration/multifd/file/mapped-ram/fdset/dio", 345d8057eb3SFabiano Rosas test_multifd_file_mapped_ram_fdset_dio); 346d8057eb3SFabiano Rosas #endif 347d8057eb3SFabiano Rosas } 348