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
test_precopy_file(void)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
fdset_add_fds(QTestState * qts,const char * file,int flags,int num_fds,bool direct_io)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
migrate_hook_start_file_offset_fdset(QTestState * from,QTestState * to)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
test_precopy_file_offset_fdset(void)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
test_precopy_file_offset(void)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
test_precopy_file_offset_bad(void)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
test_precopy_file_mapped_ram_live(void)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
test_precopy_file_mapped_ram(void)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
test_multifd_file_mapped_ram_live(void)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
test_multifd_file_mapped_ram(void)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
migrate_hook_start_multifd_mapped_ram_dio(QTestState * from,QTestState * to)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
test_multifd_file_mapped_ram_dio(void)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
migrate_hook_end_multifd_mapped_ram_fdset(QTestState * from,QTestState * to,void * opaque)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
migrate_hook_start_multifd_mapped_ram_fdset_dio(QTestState * from,QTestState * to)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
migrate_hook_start_multifd_mapped_ram_fdset(QTestState * from,QTestState * to)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
test_multifd_file_mapped_ram_fdset(void)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
test_multifd_file_mapped_ram_fdset_dio(void)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
migration_test_add_file_smoke(MigrationTestEnv * env)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
migration_test_add_file(MigrationTestEnv * env)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