xref: /qemu/tests/qtest/migration/framework.h (revision b6f568262b48ca0cb3dc018909908017551b5679)
1 /*
2  * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
3  *   based on the vhost-user-test.c that is:
4  *      Copyright (c) 2014 Virtual Open Systems Sarl.
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7  * See the COPYING file in the top-level directory.
8  *
9  */
10 
11 #ifndef TEST_FRAMEWORK_H
12 #define TEST_FRAMEWORK_H
13 
14 #include "libqtest.h"
15 #include <qapi/qapi-types-migration.h>
16 
17 #define FILE_TEST_FILENAME "migfile"
18 #define FILE_TEST_OFFSET 0x1000
19 #define FILE_TEST_MARKER 'X'
20 
21 typedef struct MigrationTestEnv {
22     bool has_kvm;
23     bool has_tcg;
24     bool has_uffd;
25     bool uffd_feature_thread_id;
26     bool has_dirty_ring;
27     bool is_x86;
28     bool full_set;
29     const char *arch;
30     const char *qemu_src;
31     const char *qemu_dst;
32     char *tmpfs;
33 } MigrationTestEnv;
34 
35 MigrationTestEnv *migration_get_env(void);
36 int migration_env_clean(MigrationTestEnv *env);
37 
38 /*
39  * A hook that runs after the src and dst QEMUs have been
40  * created, but before the migration is started. This can
41  * be used to set migration parameters and capabilities.
42  *
43  * Returns: NULL, or a pointer to opaque state to be
44  *          later passed to the TestMigrateEndHook
45  */
46 typedef void * (*TestMigrateStartHook)(QTestState *from,
47                                        QTestState *to);
48 
49 /*
50  * A hook that runs after the migration has finished,
51  * regardless of whether it succeeded or failed, but
52  * before QEMU has terminated (unless it self-terminated
53  * due to migration error)
54  *
55  * @opaque is a pointer to state previously returned
56  * by the TestMigrateStartHook if any, or NULL.
57  */
58 typedef void (*TestMigrateEndHook)(QTestState *from,
59                                    QTestState *to,
60                                    void *opaque);
61 
62 /*
63  * Our goal is to ensure that we run a single full migration
64  * iteration, and also dirty memory, ensuring that at least
65  * one further iteration is required.
66  *
67  * We can't directly synchronize with the start of a migration
68  * so we have to apply some tricks monitoring memory that is
69  * transferred.
70  *
71  * Initially we set the migration bandwidth to an insanely
72  * low value, with tiny max downtime too. This basically
73  * guarantees migration will never complete.
74  *
75  * This will result in a test that is unacceptably slow though,
76  * so we can't let the entire migration pass run at this speed.
77  * Our intent is to let it run just long enough that we can
78  * prove data prior to the marker has been transferred *AND*
79  * also prove this transferred data is dirty again.
80  *
81  * Before migration starts, we write a 64-bit magic marker
82  * into a fixed location in the src VM RAM.
83  *
84  * Then watch dst memory until the marker appears. This is
85  * proof that start_address -> MAGIC_OFFSET_BASE has been
86  * transferred.
87  *
88  * Finally we go back to the source and read a byte just
89  * before the marker until we see it flip in value. This
90  * is proof that start_address -> MAGIC_OFFSET_BASE
91  * is now dirty again.
92  *
93  * IOW, we're guaranteed at least a 2nd migration pass
94  * at this point.
95  *
96  * We can now let migration run at full speed to finish
97  * the test
98  */
99 typedef struct {
100     /*
101      * QTEST_LOG=1 may override this.  When QTEST_LOG=1, we always dump errors
102      * unconditionally, because it means the user would like to be verbose.
103      */
104     bool hide_stderr;
105     bool use_shmem;
106     /* only launch the target process */
107     bool only_target;
108     /* Use dirty ring if true; dirty logging otherwise */
109     bool use_dirty_ring;
110     const char *opts_source;
111     const char *opts_target;
112     /* suspend the src before migrating to dest. */
113     bool suspend_me;
114     /* enable OOB QMP capability */
115     bool oob;
116     /*
117      * Format string for the main memory backend, containing one %s where the
118      * size is plugged in.  If omitted, "-m %s" is used.
119      */
120     const char *memory_backend;
121 
122     /* Do not connect to target monitor and qtest sockets in qtest_init */
123     bool defer_target_connect;
124 
125     /*
126      * Migration capabilities to be set in both source and
127      * destination. For unilateral capabilities, use
128      * migration_set_capabilities().
129      */
130     bool caps[MIGRATION_CAPABILITY__MAX];
131 } MigrateStart;
132 
133 typedef enum PostcopyRecoveryFailStage {
134     /*
135      * "no failure" must be 0 as it's the default.  OTOH, real failure
136      * cases must be >0 to make sure they trigger by a "if" test.
137      */
138     POSTCOPY_FAIL_NONE = 0,
139     POSTCOPY_FAIL_CHANNEL_ESTABLISH,
140     POSTCOPY_FAIL_RECOVERY,
141     POSTCOPY_FAIL_MAX
142 } PostcopyRecoveryFailStage;
143 
144 typedef struct {
145     /* Optional: fine tune start parameters */
146     MigrateStart start;
147 
148     /* Required: the URI for the dst QEMU to listen on */
149     const char *listen_uri;
150 
151     /*
152      * Optional: the URI for the src QEMU to connect to
153      * If NULL, then it will query the dst QEMU for its actual
154      * listening address and use that as the connect address.
155      * This allows for dynamically picking a free TCP port.
156      */
157     const char *connect_uri;
158 
159     /*
160      * Optional: JSON-formatted list of src QEMU URIs. If a port is
161      * defined as '0' in any QDict key a value of '0' will be
162      * automatically converted to the correct destination port.
163      */
164     const char *connect_channels;
165 
166     /* Optional: the cpr migration channel, in JSON or dotted keys format */
167     const char *cpr_channel;
168 
169     /* Optional: callback to run at start to set migration parameters */
170     TestMigrateStartHook start_hook;
171     /* Optional: callback to run at finish to cleanup */
172     TestMigrateEndHook end_hook;
173 
174     /*
175      * Optional: normally we expect the migration process to complete.
176      *
177      * There can be a variety of reasons and stages in which failure
178      * can happen during tests.
179      *
180      * If a failure is expected to happen at time of establishing
181      * the connection, then MIG_TEST_FAIL will indicate that the dst
182      * QEMU is expected to stay running and accept future migration
183      * connections.
184      *
185      * If a failure is expected to happen while processing the
186      * migration stream, then MIG_TEST_FAIL_DEST_QUIT_ERR will indicate
187      * that the dst QEMU is expected to quit with non-zero exit status
188      */
189     enum {
190         /* This test should succeed, the default */
191         MIG_TEST_SUCCEED = 0,
192         /* This test should fail, dest qemu should keep alive */
193         MIG_TEST_FAIL,
194         /* This test should fail, dest qemu should fail with abnormal status */
195         MIG_TEST_FAIL_DEST_QUIT_ERR,
196         /* The QMP command for this migration should fail with an error */
197         MIG_TEST_QMP_ERROR,
198     } result;
199 
200     /*
201      * Optional: set number of migration passes to wait for, if live==true.
202      * If zero, then merely wait for a few MB of dirty data
203      */
204     unsigned int iterations;
205 
206     /*
207      * Optional: whether the guest CPUs should be running during a precopy
208      * migration test.  We used to always run with live but it took much
209      * longer so we reduced live tests to only the ones that have solid
210      * reason to be tested live-only.  For each of the new test cases for
211      * precopy please provide justifications to use live explicitly (please
212      * refer to existing ones with live=true), or use live=off by default.
213      */
214     bool live;
215 
216     /* Postcopy specific fields */
217     void *postcopy_data;
218     PostcopyRecoveryFailStage postcopy_recovery_fail_stage;
219 } MigrateCommon;
220 
221 void wait_for_serial(const char *side);
222 void migrate_prepare_for_dirty_mem(QTestState *from);
223 void migrate_wait_for_dirty_mem(QTestState *from, QTestState *to);
224 int migrate_start(QTestState **from, QTestState **to, const char *uri,
225                   MigrateStart *args);
226 void migrate_end(QTestState *from, QTestState *to, bool test_dest);
227 
228 void test_postcopy_common(MigrateCommon *args);
229 void test_postcopy_recovery_common(MigrateCommon *args);
230 void test_precopy_common(MigrateCommon *args);
231 void test_file_common(MigrateCommon *args, bool stop_src);
232 void *migrate_hook_start_precopy_tcp_multifd_common(QTestState *from,
233                                                     QTestState *to,
234                                                     const char *method);
235 
236 typedef struct QTestMigrationState QTestMigrationState;
237 QTestMigrationState *get_src(void);
238 
239 #ifdef CONFIG_GNUTLS
240 void migration_test_add_tls(MigrationTestEnv *env);
241 #else
migration_test_add_tls(MigrationTestEnv * env)242 static inline void migration_test_add_tls(MigrationTestEnv *env) {};
243 #endif
244 void migration_test_add_compression(MigrationTestEnv *env);
245 void migration_test_add_postcopy(MigrationTestEnv *env);
246 void migration_test_add_file(MigrationTestEnv *env);
247 void migration_test_add_precopy(MigrationTestEnv *env);
248 void migration_test_add_cpr(MigrationTestEnv *env);
249 void migration_test_add_misc(MigrationTestEnv *env);
250 
251 #endif /* TEST_FRAMEWORK_H */
252