root / migration.c @ cb9c377f
History | View | Annotate | Download (15.4 kB)
1 | 5bb7910a | aliguori | /*
|
---|---|---|---|
2 | 5bb7910a | aliguori | * QEMU live migration
|
3 | 5bb7910a | aliguori | *
|
4 | 5bb7910a | aliguori | * Copyright IBM, Corp. 2008
|
5 | 5bb7910a | aliguori | *
|
6 | 5bb7910a | aliguori | * Authors:
|
7 | 5bb7910a | aliguori | * Anthony Liguori <aliguori@us.ibm.com>
|
8 | 5bb7910a | aliguori | *
|
9 | 5bb7910a | aliguori | * This work is licensed under the terms of the GNU GPL, version 2. See
|
10 | 5bb7910a | aliguori | * the COPYING file in the top-level directory.
|
11 | 5bb7910a | aliguori | *
|
12 | 6b620ca3 | Paolo Bonzini | * Contributions after 2012-01-13 are licensed under the terms of the
|
13 | 6b620ca3 | Paolo Bonzini | * GNU GPL, version 2 or (at your option) any later version.
|
14 | 5bb7910a | aliguori | */
|
15 | 5bb7910a | aliguori | |
16 | 5bb7910a | aliguori | #include "qemu-common.h" |
17 | 5bb7910a | aliguori | #include "migration.h" |
18 | 376253ec | aliguori | #include "monitor.h" |
19 | 065e2813 | aliguori | #include "buffered_file.h" |
20 | 065e2813 | aliguori | #include "sysemu.h" |
21 | 065e2813 | aliguori | #include "block.h" |
22 | 065e2813 | aliguori | #include "qemu_socket.h" |
23 | 25f23643 | Jan Kiszka | #include "block-migration.h" |
24 | 791e7c82 | Luiz Capitulino | #include "qmp-commands.h" |
25 | 065e2813 | aliguori | |
26 | 065e2813 | aliguori | //#define DEBUG_MIGRATION
|
27 | 065e2813 | aliguori | |
28 | 065e2813 | aliguori | #ifdef DEBUG_MIGRATION
|
29 | d0f2c4c6 | malc | #define DPRINTF(fmt, ...) \
|
30 | 065e2813 | aliguori | do { printf("migration: " fmt, ## __VA_ARGS__); } while (0) |
31 | 065e2813 | aliguori | #else
|
32 | d0f2c4c6 | malc | #define DPRINTF(fmt, ...) \
|
33 | 065e2813 | aliguori | do { } while (0) |
34 | 065e2813 | aliguori | #endif
|
35 | 5bb7910a | aliguori | |
36 | 7dc688ed | Juan Quintela | enum {
|
37 | 7dc688ed | Juan Quintela | MIG_STATE_ERROR, |
38 | 7dc688ed | Juan Quintela | MIG_STATE_SETUP, |
39 | 7dc688ed | Juan Quintela | MIG_STATE_CANCELLED, |
40 | 7dc688ed | Juan Quintela | MIG_STATE_ACTIVE, |
41 | 7dc688ed | Juan Quintela | MIG_STATE_COMPLETED, |
42 | 7dc688ed | Juan Quintela | }; |
43 | 5bb7910a | aliguori | |
44 | d0ae46c1 | Juan Quintela | #define MAX_THROTTLE (32 << 20) /* Migration speed throttling */ |
45 | 5bb7910a | aliguori | |
46 | 17ad9b35 | Orit Wasserman | /* Migration XBZRLE default cache size */
|
47 | 17ad9b35 | Orit Wasserman | #define DEFAULT_MIGRATE_CACHE_SIZE (64 * 1024 * 1024) |
48 | 17ad9b35 | Orit Wasserman | |
49 | 99a0db9b | Gerd Hoffmann | static NotifierList migration_state_notifiers =
|
50 | 99a0db9b | Gerd Hoffmann | NOTIFIER_LIST_INITIALIZER(migration_state_notifiers); |
51 | 99a0db9b | Gerd Hoffmann | |
52 | 17549e84 | Juan Quintela | /* When we add fault tolerance, we could have several
|
53 | 17549e84 | Juan Quintela | migrations at once. For now we don't need to add
|
54 | 17549e84 | Juan Quintela | dynamic creation of migration */
|
55 | 17549e84 | Juan Quintela | |
56 | 859bc756 | Juan Quintela | MigrationState *migrate_get_current(void)
|
57 | 17549e84 | Juan Quintela | { |
58 | 17549e84 | Juan Quintela | static MigrationState current_migration = {
|
59 | 17549e84 | Juan Quintela | .state = MIG_STATE_SETUP, |
60 | d0ae46c1 | Juan Quintela | .bandwidth_limit = MAX_THROTTLE, |
61 | 17ad9b35 | Orit Wasserman | .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE, |
62 | 17549e84 | Juan Quintela | }; |
63 | 17549e84 | Juan Quintela | |
64 | 17549e84 | Juan Quintela | return ¤t_migration;
|
65 | 17549e84 | Juan Quintela | } |
66 | 17549e84 | Juan Quintela | |
67 | 43eaae28 | Paolo Bonzini | void qemu_start_incoming_migration(const char *uri, Error **errp) |
68 | 5bb7910a | aliguori | { |
69 | 34c9dd8e | aliguori | const char *p; |
70 | 34c9dd8e | aliguori | |
71 | 34c9dd8e | aliguori | if (strstart(uri, "tcp:", &p)) |
72 | 43eaae28 | Paolo Bonzini | tcp_start_incoming_migration(p, errp); |
73 | 065e2813 | aliguori | #if !defined(WIN32)
|
74 | 065e2813 | aliguori | else if (strstart(uri, "exec:", &p)) |
75 | 43eaae28 | Paolo Bonzini | exec_start_incoming_migration(p, errp); |
76 | 4951f65b | Chris Lalancette | else if (strstart(uri, "unix:", &p)) |
77 | 43eaae28 | Paolo Bonzini | unix_start_incoming_migration(p, errp); |
78 | 5ac1fad3 | Paolo Bonzini | else if (strstart(uri, "fd:", &p)) |
79 | 43eaae28 | Paolo Bonzini | fd_start_incoming_migration(p, errp); |
80 | 065e2813 | aliguori | #endif
|
81 | 8ca5e801 | Juan Quintela | else {
|
82 | 43eaae28 | Paolo Bonzini | error_setg(errp, "unknown migration protocol: %s\n", uri);
|
83 | 8ca5e801 | Juan Quintela | } |
84 | 5bb7910a | aliguori | } |
85 | 5bb7910a | aliguori | |
86 | 82a4da79 | Paolo Bonzini | static void process_incoming_migration_co(void *opaque) |
87 | 511c0231 | Juan Quintela | { |
88 | 82a4da79 | Paolo Bonzini | QEMUFile *f = opaque; |
89 | 1c12e1f5 | Paolo Bonzini | int ret;
|
90 | 1c12e1f5 | Paolo Bonzini | |
91 | 1c12e1f5 | Paolo Bonzini | ret = qemu_loadvm_state(f); |
92 | 82a4da79 | Paolo Bonzini | qemu_set_fd_handler(qemu_get_fd(f), NULL, NULL, NULL); |
93 | 1c12e1f5 | Paolo Bonzini | qemu_fclose(f); |
94 | 1c12e1f5 | Paolo Bonzini | if (ret < 0) { |
95 | 511c0231 | Juan Quintela | fprintf(stderr, "load of migration failed\n");
|
96 | 511c0231 | Juan Quintela | exit(0);
|
97 | 511c0231 | Juan Quintela | } |
98 | 511c0231 | Juan Quintela | qemu_announce_self(); |
99 | 511c0231 | Juan Quintela | DPRINTF("successfully loaded vm state\n");
|
100 | 511c0231 | Juan Quintela | |
101 | 901862cb | Benoît Canet | bdrv_clear_incoming_migration_all(); |
102 | 0f15423c | Anthony Liguori | /* Make sure all file formats flush their mutable metadata */
|
103 | 0f15423c | Anthony Liguori | bdrv_invalidate_cache_all(); |
104 | 0f15423c | Anthony Liguori | |
105 | f5bbfba1 | Luiz Capitulino | if (autostart) {
|
106 | 511c0231 | Juan Quintela | vm_start(); |
107 | f5bbfba1 | Luiz Capitulino | } else {
|
108 | 29ed72f1 | Paolo Bonzini | runstate_set(RUN_STATE_PAUSED); |
109 | f5bbfba1 | Luiz Capitulino | } |
110 | 511c0231 | Juan Quintela | } |
111 | 511c0231 | Juan Quintela | |
112 | 82a4da79 | Paolo Bonzini | static void enter_migration_coroutine(void *opaque) |
113 | 82a4da79 | Paolo Bonzini | { |
114 | 82a4da79 | Paolo Bonzini | Coroutine *co = opaque; |
115 | 82a4da79 | Paolo Bonzini | qemu_coroutine_enter(co, NULL);
|
116 | 82a4da79 | Paolo Bonzini | } |
117 | 82a4da79 | Paolo Bonzini | |
118 | 82a4da79 | Paolo Bonzini | void process_incoming_migration(QEMUFile *f)
|
119 | 82a4da79 | Paolo Bonzini | { |
120 | 82a4da79 | Paolo Bonzini | Coroutine *co = qemu_coroutine_create(process_incoming_migration_co); |
121 | 82a4da79 | Paolo Bonzini | int fd = qemu_get_fd(f);
|
122 | 82a4da79 | Paolo Bonzini | |
123 | 82a4da79 | Paolo Bonzini | assert(fd != -1);
|
124 | 82a4da79 | Paolo Bonzini | socket_set_nonblock(fd); |
125 | 82a4da79 | Paolo Bonzini | qemu_set_fd_handler(fd, enter_migration_coroutine, NULL, co);
|
126 | 82a4da79 | Paolo Bonzini | qemu_coroutine_enter(co, f); |
127 | 82a4da79 | Paolo Bonzini | } |
128 | 82a4da79 | Paolo Bonzini | |
129 | a0a3fd60 | Glauber Costa | /* amount of nanoseconds we are willing to wait for migration to be down.
|
130 | a0a3fd60 | Glauber Costa | * the choice of nanoseconds is because it is the maximum resolution that
|
131 | a0a3fd60 | Glauber Costa | * get_clock() can achieve. It is an internal measure. All user-visible
|
132 | a0a3fd60 | Glauber Costa | * units must be in seconds */
|
133 | a0a3fd60 | Glauber Costa | static uint64_t max_downtime = 30000000; |
134 | a0a3fd60 | Glauber Costa | |
135 | a0a3fd60 | Glauber Costa | uint64_t migrate_max_downtime(void)
|
136 | a0a3fd60 | Glauber Costa | { |
137 | a0a3fd60 | Glauber Costa | return max_downtime;
|
138 | a0a3fd60 | Glauber Costa | } |
139 | a0a3fd60 | Glauber Costa | |
140 | bbf6da32 | Orit Wasserman | MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) |
141 | bbf6da32 | Orit Wasserman | { |
142 | bbf6da32 | Orit Wasserman | MigrationCapabilityStatusList *head = NULL;
|
143 | bbf6da32 | Orit Wasserman | MigrationCapabilityStatusList *caps; |
144 | bbf6da32 | Orit Wasserman | MigrationState *s = migrate_get_current(); |
145 | bbf6da32 | Orit Wasserman | int i;
|
146 | bbf6da32 | Orit Wasserman | |
147 | bbf6da32 | Orit Wasserman | for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { |
148 | bbf6da32 | Orit Wasserman | if (head == NULL) { |
149 | bbf6da32 | Orit Wasserman | head = g_malloc0(sizeof(*caps));
|
150 | bbf6da32 | Orit Wasserman | caps = head; |
151 | bbf6da32 | Orit Wasserman | } else {
|
152 | bbf6da32 | Orit Wasserman | caps->next = g_malloc0(sizeof(*caps));
|
153 | bbf6da32 | Orit Wasserman | caps = caps->next; |
154 | bbf6da32 | Orit Wasserman | } |
155 | bbf6da32 | Orit Wasserman | caps->value = |
156 | bbf6da32 | Orit Wasserman | g_malloc(sizeof(*caps->value));
|
157 | bbf6da32 | Orit Wasserman | caps->value->capability = i; |
158 | bbf6da32 | Orit Wasserman | caps->value->state = s->enabled_capabilities[i]; |
159 | bbf6da32 | Orit Wasserman | } |
160 | bbf6da32 | Orit Wasserman | |
161 | bbf6da32 | Orit Wasserman | return head;
|
162 | bbf6da32 | Orit Wasserman | } |
163 | bbf6da32 | Orit Wasserman | |
164 | f36d55af | Orit Wasserman | static void get_xbzrle_cache_stats(MigrationInfo *info) |
165 | f36d55af | Orit Wasserman | { |
166 | f36d55af | Orit Wasserman | if (migrate_use_xbzrle()) {
|
167 | f36d55af | Orit Wasserman | info->has_xbzrle_cache = true;
|
168 | f36d55af | Orit Wasserman | info->xbzrle_cache = g_malloc0(sizeof(*info->xbzrle_cache));
|
169 | f36d55af | Orit Wasserman | info->xbzrle_cache->cache_size = migrate_xbzrle_cache_size(); |
170 | f36d55af | Orit Wasserman | info->xbzrle_cache->bytes = xbzrle_mig_bytes_transferred(); |
171 | f36d55af | Orit Wasserman | info->xbzrle_cache->pages = xbzrle_mig_pages_transferred(); |
172 | f36d55af | Orit Wasserman | info->xbzrle_cache->cache_miss = xbzrle_mig_pages_cache_miss(); |
173 | f36d55af | Orit Wasserman | info->xbzrle_cache->overflow = xbzrle_mig_pages_overflow(); |
174 | f36d55af | Orit Wasserman | } |
175 | f36d55af | Orit Wasserman | } |
176 | f36d55af | Orit Wasserman | |
177 | 791e7c82 | Luiz Capitulino | MigrationInfo *qmp_query_migrate(Error **errp) |
178 | 5bb7910a | aliguori | { |
179 | 791e7c82 | Luiz Capitulino | MigrationInfo *info = g_malloc0(sizeof(*info));
|
180 | 17549e84 | Juan Quintela | MigrationState *s = migrate_get_current(); |
181 | 17549e84 | Juan Quintela | |
182 | 17549e84 | Juan Quintela | switch (s->state) {
|
183 | 17549e84 | Juan Quintela | case MIG_STATE_SETUP:
|
184 | 17549e84 | Juan Quintela | /* no migration has happened ever */
|
185 | 17549e84 | Juan Quintela | break;
|
186 | 17549e84 | Juan Quintela | case MIG_STATE_ACTIVE:
|
187 | 791e7c82 | Luiz Capitulino | info->has_status = true;
|
188 | 791e7c82 | Luiz Capitulino | info->status = g_strdup("active");
|
189 | 7aa939af | Juan Quintela | info->has_total_time = true;
|
190 | 7aa939af | Juan Quintela | info->total_time = qemu_get_clock_ms(rt_clock) |
191 | 7aa939af | Juan Quintela | - s->total_time; |
192 | 2c52ddf1 | Juan Quintela | info->has_expected_downtime = true;
|
193 | 2c52ddf1 | Juan Quintela | info->expected_downtime = s->expected_downtime; |
194 | 17549e84 | Juan Quintela | |
195 | 791e7c82 | Luiz Capitulino | info->has_ram = true;
|
196 | 791e7c82 | Luiz Capitulino | info->ram = g_malloc0(sizeof(*info->ram));
|
197 | 791e7c82 | Luiz Capitulino | info->ram->transferred = ram_bytes_transferred(); |
198 | 791e7c82 | Luiz Capitulino | info->ram->remaining = ram_bytes_remaining(); |
199 | 791e7c82 | Luiz Capitulino | info->ram->total = ram_bytes_total(); |
200 | 004d4c10 | Orit Wasserman | info->ram->duplicate = dup_mig_pages_transferred(); |
201 | 004d4c10 | Orit Wasserman | info->ram->normal = norm_mig_pages_transferred(); |
202 | 004d4c10 | Orit Wasserman | info->ram->normal_bytes = norm_mig_bytes_transferred(); |
203 | 8d017193 | Juan Quintela | info->ram->dirty_pages_rate = s->dirty_pages_rate; |
204 | 8d017193 | Juan Quintela | |
205 | 17549e84 | Juan Quintela | |
206 | 17549e84 | Juan Quintela | if (blk_mig_active()) {
|
207 | 791e7c82 | Luiz Capitulino | info->has_disk = true;
|
208 | 791e7c82 | Luiz Capitulino | info->disk = g_malloc0(sizeof(*info->disk));
|
209 | 791e7c82 | Luiz Capitulino | info->disk->transferred = blk_mig_bytes_transferred(); |
210 | 791e7c82 | Luiz Capitulino | info->disk->remaining = blk_mig_bytes_remaining(); |
211 | 791e7c82 | Luiz Capitulino | info->disk->total = blk_mig_bytes_total(); |
212 | ff8d81d8 | aliguori | } |
213 | f36d55af | Orit Wasserman | |
214 | f36d55af | Orit Wasserman | get_xbzrle_cache_stats(info); |
215 | 17549e84 | Juan Quintela | break;
|
216 | 17549e84 | Juan Quintela | case MIG_STATE_COMPLETED:
|
217 | f36d55af | Orit Wasserman | get_xbzrle_cache_stats(info); |
218 | f36d55af | Orit Wasserman | |
219 | 791e7c82 | Luiz Capitulino | info->has_status = true;
|
220 | 791e7c82 | Luiz Capitulino | info->status = g_strdup("completed");
|
221 | 7aa939af | Juan Quintela | info->total_time = s->total_time; |
222 | 9c5a9fcf | Juan Quintela | info->has_downtime = true;
|
223 | 9c5a9fcf | Juan Quintela | info->downtime = s->downtime; |
224 | d5f8a570 | Juan Quintela | |
225 | d5f8a570 | Juan Quintela | info->has_ram = true;
|
226 | d5f8a570 | Juan Quintela | info->ram = g_malloc0(sizeof(*info->ram));
|
227 | d5f8a570 | Juan Quintela | info->ram->transferred = ram_bytes_transferred(); |
228 | d5f8a570 | Juan Quintela | info->ram->remaining = 0;
|
229 | d5f8a570 | Juan Quintela | info->ram->total = ram_bytes_total(); |
230 | 004d4c10 | Orit Wasserman | info->ram->duplicate = dup_mig_pages_transferred(); |
231 | 004d4c10 | Orit Wasserman | info->ram->normal = norm_mig_pages_transferred(); |
232 | 004d4c10 | Orit Wasserman | info->ram->normal_bytes = norm_mig_bytes_transferred(); |
233 | 17549e84 | Juan Quintela | break;
|
234 | 17549e84 | Juan Quintela | case MIG_STATE_ERROR:
|
235 | 791e7c82 | Luiz Capitulino | info->has_status = true;
|
236 | 791e7c82 | Luiz Capitulino | info->status = g_strdup("failed");
|
237 | 17549e84 | Juan Quintela | break;
|
238 | 17549e84 | Juan Quintela | case MIG_STATE_CANCELLED:
|
239 | 791e7c82 | Luiz Capitulino | info->has_status = true;
|
240 | 791e7c82 | Luiz Capitulino | info->status = g_strdup("cancelled");
|
241 | 17549e84 | Juan Quintela | break;
|
242 | 5bb7910a | aliguori | } |
243 | 791e7c82 | Luiz Capitulino | |
244 | 791e7c82 | Luiz Capitulino | return info;
|
245 | 5bb7910a | aliguori | } |
246 | 5bb7910a | aliguori | |
247 | 00458433 | Orit Wasserman | void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
|
248 | 00458433 | Orit Wasserman | Error **errp) |
249 | 00458433 | Orit Wasserman | { |
250 | 00458433 | Orit Wasserman | MigrationState *s = migrate_get_current(); |
251 | 00458433 | Orit Wasserman | MigrationCapabilityStatusList *cap; |
252 | 00458433 | Orit Wasserman | |
253 | 00458433 | Orit Wasserman | if (s->state == MIG_STATE_ACTIVE) {
|
254 | 00458433 | Orit Wasserman | error_set(errp, QERR_MIGRATION_ACTIVE); |
255 | 00458433 | Orit Wasserman | return;
|
256 | 00458433 | Orit Wasserman | } |
257 | 00458433 | Orit Wasserman | |
258 | 00458433 | Orit Wasserman | for (cap = params; cap; cap = cap->next) {
|
259 | 00458433 | Orit Wasserman | s->enabled_capabilities[cap->value->capability] = cap->value->state; |
260 | 00458433 | Orit Wasserman | } |
261 | 00458433 | Orit Wasserman | } |
262 | 00458433 | Orit Wasserman | |
263 | 065e2813 | aliguori | /* shared migration helpers */
|
264 | 065e2813 | aliguori | |
265 | 8b6b99b3 | Juan Quintela | static int migrate_fd_cleanup(MigrationState *s) |
266 | 065e2813 | aliguori | { |
267 | 41ef56e6 | Anthony Liguori | int ret = 0; |
268 | 41ef56e6 | Anthony Liguori | |
269 | 065e2813 | aliguori | if (s->file) {
|
270 | d0f2c4c6 | malc | DPRINTF("closing file\n");
|
271 | a6d34a94 | Eduardo Habkost | ret = qemu_fclose(s->file); |
272 | 5d39c799 | Jan Kiszka | s->file = NULL;
|
273 | 065e2813 | aliguori | } |
274 | 065e2813 | aliguori | |
275 | 8dc592e6 | Paolo Bonzini | migrate_fd_close(s); |
276 | 41ef56e6 | Anthony Liguori | return ret;
|
277 | 065e2813 | aliguori | } |
278 | 065e2813 | aliguori | |
279 | 8b6b99b3 | Juan Quintela | void migrate_fd_error(MigrationState *s)
|
280 | 065e2813 | aliguori | { |
281 | 8b6b99b3 | Juan Quintela | DPRINTF("setting error state\n");
|
282 | 8b6b99b3 | Juan Quintela | s->state = MIG_STATE_ERROR; |
283 | e0eb7390 | Juan Quintela | notifier_list_notify(&migration_state_notifiers, s); |
284 | 8b6b99b3 | Juan Quintela | migrate_fd_cleanup(s); |
285 | 8b6b99b3 | Juan Quintela | } |
286 | 8b6b99b3 | Juan Quintela | |
287 | 458cf28e | Juan Quintela | static void migrate_fd_completed(MigrationState *s) |
288 | 458cf28e | Juan Quintela | { |
289 | 458cf28e | Juan Quintela | DPRINTF("setting completed state\n");
|
290 | 458cf28e | Juan Quintela | if (migrate_fd_cleanup(s) < 0) { |
291 | 458cf28e | Juan Quintela | s->state = MIG_STATE_ERROR; |
292 | 458cf28e | Juan Quintela | } else {
|
293 | 458cf28e | Juan Quintela | s->state = MIG_STATE_COMPLETED; |
294 | 458cf28e | Juan Quintela | runstate_set(RUN_STATE_POSTMIGRATE); |
295 | 458cf28e | Juan Quintela | } |
296 | e0eb7390 | Juan Quintela | notifier_list_notify(&migration_state_notifiers, s); |
297 | 458cf28e | Juan Quintela | } |
298 | 458cf28e | Juan Quintela | |
299 | 8b6b99b3 | Juan Quintela | static void migrate_fd_put_notify(void *opaque) |
300 | 065e2813 | aliguori | { |
301 | 22f00a44 | Juan Quintela | MigrationState *s = opaque; |
302 | a2b41351 | Juan Quintela | int ret;
|
303 | 065e2813 | aliguori | |
304 | 065e2813 | aliguori | qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); |
305 | a2b41351 | Juan Quintela | ret = qemu_file_put_notify(s->file); |
306 | a2b41351 | Juan Quintela | if (ret) {
|
307 | 2350e13c | Yoshiaki Tamura | migrate_fd_error(s); |
308 | 2350e13c | Yoshiaki Tamura | } |
309 | 065e2813 | aliguori | } |
310 | 065e2813 | aliguori | |
311 | c87b015b | Juan Quintela | ssize_t migrate_fd_put_buffer(MigrationState *s, const void *data, |
312 | c87b015b | Juan Quintela | size_t size) |
313 | 065e2813 | aliguori | { |
314 | 065e2813 | aliguori | ssize_t ret; |
315 | 065e2813 | aliguori | |
316 | fdbecb5d | Juan Quintela | if (s->state != MIG_STATE_ACTIVE) {
|
317 | fdbecb5d | Juan Quintela | return -EIO;
|
318 | fdbecb5d | Juan Quintela | } |
319 | fdbecb5d | Juan Quintela | |
320 | 065e2813 | aliguori | do {
|
321 | 065e2813 | aliguori | ret = s->write(s, data, size); |
322 | 95b134ea | Uri Lublin | } while (ret == -1 && ((s->get_error(s)) == EINTR)); |
323 | 065e2813 | aliguori | |
324 | 065e2813 | aliguori | if (ret == -1) |
325 | 065e2813 | aliguori | ret = -(s->get_error(s)); |
326 | 065e2813 | aliguori | |
327 | e447b1a6 | Marcelo Tosatti | if (ret == -EAGAIN) {
|
328 | 065e2813 | aliguori | qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s); |
329 | e447b1a6 | Marcelo Tosatti | } |
330 | 065e2813 | aliguori | |
331 | 065e2813 | aliguori | return ret;
|
332 | 065e2813 | aliguori | } |
333 | 065e2813 | aliguori | |
334 | 2c9adcb8 | Juan Quintela | void migrate_fd_put_ready(MigrationState *s)
|
335 | 065e2813 | aliguori | { |
336 | 065e2813 | aliguori | int ret;
|
337 | 065e2813 | aliguori | |
338 | 065e2813 | aliguori | if (s->state != MIG_STATE_ACTIVE) {
|
339 | d0f2c4c6 | malc | DPRINTF("put_ready returning because of non-active state\n");
|
340 | 065e2813 | aliguori | return;
|
341 | 065e2813 | aliguori | } |
342 | 065e2813 | aliguori | |
343 | d0f2c4c6 | malc | DPRINTF("iterate\n");
|
344 | 539de124 | Luiz Capitulino | ret = qemu_savevm_state_iterate(s->file); |
345 | 39346385 | Juan Quintela | if (ret < 0) { |
346 | 39346385 | Juan Quintela | migrate_fd_error(s); |
347 | 39346385 | Juan Quintela | } else if (ret == 1) { |
348 | 1354869c | Luiz Capitulino | int old_vm_running = runstate_is_running();
|
349 | 9c5a9fcf | Juan Quintela | int64_t start_time, end_time; |
350 | eeb34af9 | Anthony Liguori | |
351 | d0f2c4c6 | malc | DPRINTF("done iterating\n");
|
352 | 9c5a9fcf | Juan Quintela | start_time = qemu_get_clock_ms(rt_clock); |
353 | 7b5d3aa2 | Gerd Hoffmann | qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); |
354 | 8a9236f1 | Luiz Capitulino | vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); |
355 | 065e2813 | aliguori | |
356 | 539de124 | Luiz Capitulino | if (qemu_savevm_state_complete(s->file) < 0) { |
357 | 67afff79 | Juan Quintela | migrate_fd_error(s); |
358 | b161d123 | aliguori | } else {
|
359 | 458cf28e | Juan Quintela | migrate_fd_completed(s); |
360 | b161d123 | aliguori | } |
361 | 97d4d961 | Juan Quintela | end_time = qemu_get_clock_ms(rt_clock); |
362 | 97d4d961 | Juan Quintela | s->total_time = end_time - s->total_time; |
363 | 9c5a9fcf | Juan Quintela | s->downtime = end_time - start_time; |
364 | 48a2f4d6 | Juan Quintela | if (s->state != MIG_STATE_COMPLETED) {
|
365 | 41ef56e6 | Anthony Liguori | if (old_vm_running) {
|
366 | 41ef56e6 | Anthony Liguori | vm_start(); |
367 | 41ef56e6 | Anthony Liguori | } |
368 | f5bbfba1 | Luiz Capitulino | } |
369 | 065e2813 | aliguori | } |
370 | 065e2813 | aliguori | } |
371 | 065e2813 | aliguori | |
372 | 0edda1c4 | Juan Quintela | static void migrate_fd_cancel(MigrationState *s) |
373 | 065e2813 | aliguori | { |
374 | 065e2813 | aliguori | if (s->state != MIG_STATE_ACTIVE)
|
375 | 065e2813 | aliguori | return;
|
376 | 065e2813 | aliguori | |
377 | d0f2c4c6 | malc | DPRINTF("cancelling migration\n");
|
378 | 065e2813 | aliguori | |
379 | 065e2813 | aliguori | s->state = MIG_STATE_CANCELLED; |
380 | e0eb7390 | Juan Quintela | notifier_list_notify(&migration_state_notifiers, s); |
381 | 539de124 | Luiz Capitulino | qemu_savevm_state_cancel(s->file); |
382 | 065e2813 | aliguori | |
383 | 065e2813 | aliguori | migrate_fd_cleanup(s); |
384 | 065e2813 | aliguori | } |
385 | 065e2813 | aliguori | |
386 | 9499743f | Juan Quintela | int migrate_fd_wait_for_unfreeze(MigrationState *s)
|
387 | 065e2813 | aliguori | { |
388 | 065e2813 | aliguori | int ret;
|
389 | 065e2813 | aliguori | |
390 | d0f2c4c6 | malc | DPRINTF("wait for unfreeze\n");
|
391 | 065e2813 | aliguori | if (s->state != MIG_STATE_ACTIVE)
|
392 | 9499743f | Juan Quintela | return -EINVAL;
|
393 | 065e2813 | aliguori | |
394 | 065e2813 | aliguori | do {
|
395 | 065e2813 | aliguori | fd_set wfds; |
396 | 065e2813 | aliguori | |
397 | 065e2813 | aliguori | FD_ZERO(&wfds); |
398 | 065e2813 | aliguori | FD_SET(s->fd, &wfds); |
399 | 065e2813 | aliguori | |
400 | 065e2813 | aliguori | ret = select(s->fd + 1, NULL, &wfds, NULL, NULL); |
401 | 065e2813 | aliguori | } while (ret == -1 && (s->get_error(s)) == EINTR); |
402 | af509450 | Juan Quintela | |
403 | af509450 | Juan Quintela | if (ret == -1) { |
404 | 9499743f | Juan Quintela | return -s->get_error(s);
|
405 | af509450 | Juan Quintela | } |
406 | 9499743f | Juan Quintela | return 0; |
407 | 065e2813 | aliguori | } |
408 | 065e2813 | aliguori | |
409 | 11c76741 | Juan Quintela | int migrate_fd_close(MigrationState *s)
|
410 | 065e2813 | aliguori | { |
411 | 8dc592e6 | Paolo Bonzini | int rc = 0; |
412 | 8dc592e6 | Paolo Bonzini | if (s->fd != -1) { |
413 | 8dc592e6 | Paolo Bonzini | qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); |
414 | 8dc592e6 | Paolo Bonzini | rc = s->close(s); |
415 | 8dc592e6 | Paolo Bonzini | s->fd = -1;
|
416 | 8dc592e6 | Paolo Bonzini | } |
417 | 8dc592e6 | Paolo Bonzini | return rc;
|
418 | 065e2813 | aliguori | } |
419 | 99a0db9b | Gerd Hoffmann | |
420 | 99a0db9b | Gerd Hoffmann | void add_migration_state_change_notifier(Notifier *notify)
|
421 | 99a0db9b | Gerd Hoffmann | { |
422 | 99a0db9b | Gerd Hoffmann | notifier_list_add(&migration_state_notifiers, notify); |
423 | 99a0db9b | Gerd Hoffmann | } |
424 | 99a0db9b | Gerd Hoffmann | |
425 | 99a0db9b | Gerd Hoffmann | void remove_migration_state_change_notifier(Notifier *notify)
|
426 | 99a0db9b | Gerd Hoffmann | { |
427 | 31552529 | Paolo Bonzini | notifier_remove(notify); |
428 | 99a0db9b | Gerd Hoffmann | } |
429 | 99a0db9b | Gerd Hoffmann | |
430 | afe2df69 | Gerd Hoffmann | bool migration_is_active(MigrationState *s)
|
431 | afe2df69 | Gerd Hoffmann | { |
432 | afe2df69 | Gerd Hoffmann | return s->state == MIG_STATE_ACTIVE;
|
433 | afe2df69 | Gerd Hoffmann | } |
434 | afe2df69 | Gerd Hoffmann | |
435 | 7073693b | Juan Quintela | bool migration_has_finished(MigrationState *s)
|
436 | 99a0db9b | Gerd Hoffmann | { |
437 | 7073693b | Juan Quintela | return s->state == MIG_STATE_COMPLETED;
|
438 | 99a0db9b | Gerd Hoffmann | } |
439 | 0edda1c4 | Juan Quintela | |
440 | afe2df69 | Gerd Hoffmann | bool migration_has_failed(MigrationState *s)
|
441 | afe2df69 | Gerd Hoffmann | { |
442 | afe2df69 | Gerd Hoffmann | return (s->state == MIG_STATE_CANCELLED ||
|
443 | afe2df69 | Gerd Hoffmann | s->state == MIG_STATE_ERROR); |
444 | afe2df69 | Gerd Hoffmann | } |
445 | afe2df69 | Gerd Hoffmann | |
446 | 8b6b99b3 | Juan Quintela | void migrate_fd_connect(MigrationState *s)
|
447 | 99a0db9b | Gerd Hoffmann | { |
448 | 8b6b99b3 | Juan Quintela | int ret;
|
449 | 8b6b99b3 | Juan Quintela | |
450 | d5934dde | Juan Quintela | s->state = MIG_STATE_ACTIVE; |
451 | 796b4b0f | Juan Quintela | s->file = qemu_fopen_ops_buffered(s); |
452 | 8b6b99b3 | Juan Quintela | |
453 | 8b6b99b3 | Juan Quintela | DPRINTF("beginning savevm\n");
|
454 | 6607ae23 | Isaku Yamahata | ret = qemu_savevm_state_begin(s->file, &s->params); |
455 | 8b6b99b3 | Juan Quintela | if (ret < 0) { |
456 | 8b6b99b3 | Juan Quintela | DPRINTF("failed, %d\n", ret);
|
457 | 8b6b99b3 | Juan Quintela | migrate_fd_error(s); |
458 | 8b6b99b3 | Juan Quintela | return;
|
459 | 8b6b99b3 | Juan Quintela | } |
460 | 8b6b99b3 | Juan Quintela | migrate_fd_put_ready(s); |
461 | 8b6b99b3 | Juan Quintela | } |
462 | 8b6b99b3 | Juan Quintela | |
463 | 6607ae23 | Isaku Yamahata | static MigrationState *migrate_init(const MigrationParams *params) |
464 | 0edda1c4 | Juan Quintela | { |
465 | 17549e84 | Juan Quintela | MigrationState *s = migrate_get_current(); |
466 | d0ae46c1 | Juan Quintela | int64_t bandwidth_limit = s->bandwidth_limit; |
467 | bbf6da32 | Orit Wasserman | bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
|
468 | 17ad9b35 | Orit Wasserman | int64_t xbzrle_cache_size = s->xbzrle_cache_size; |
469 | bbf6da32 | Orit Wasserman | |
470 | bbf6da32 | Orit Wasserman | memcpy(enabled_capabilities, s->enabled_capabilities, |
471 | bbf6da32 | Orit Wasserman | sizeof(enabled_capabilities));
|
472 | 0edda1c4 | Juan Quintela | |
473 | 17549e84 | Juan Quintela | memset(s, 0, sizeof(*s)); |
474 | d0ae46c1 | Juan Quintela | s->bandwidth_limit = bandwidth_limit; |
475 | 6607ae23 | Isaku Yamahata | s->params = *params; |
476 | bbf6da32 | Orit Wasserman | memcpy(s->enabled_capabilities, enabled_capabilities, |
477 | bbf6da32 | Orit Wasserman | sizeof(enabled_capabilities));
|
478 | 17ad9b35 | Orit Wasserman | s->xbzrle_cache_size = xbzrle_cache_size; |
479 | 1299c631 | Juan Quintela | |
480 | 0edda1c4 | Juan Quintela | s->bandwidth_limit = bandwidth_limit; |
481 | d5934dde | Juan Quintela | s->state = MIG_STATE_SETUP; |
482 | d5f8a570 | Juan Quintela | s->total_time = qemu_get_clock_ms(rt_clock); |
483 | 0edda1c4 | Juan Quintela | |
484 | 0edda1c4 | Juan Quintela | return s;
|
485 | 0edda1c4 | Juan Quintela | } |
486 | cab30143 | Juan Quintela | |
487 | fa2756b7 | Anthony Liguori | static GSList *migration_blockers;
|
488 | fa2756b7 | Anthony Liguori | |
489 | fa2756b7 | Anthony Liguori | void migrate_add_blocker(Error *reason)
|
490 | fa2756b7 | Anthony Liguori | { |
491 | fa2756b7 | Anthony Liguori | migration_blockers = g_slist_prepend(migration_blockers, reason); |
492 | fa2756b7 | Anthony Liguori | } |
493 | fa2756b7 | Anthony Liguori | |
494 | fa2756b7 | Anthony Liguori | void migrate_del_blocker(Error *reason)
|
495 | fa2756b7 | Anthony Liguori | { |
496 | fa2756b7 | Anthony Liguori | migration_blockers = g_slist_remove(migration_blockers, reason); |
497 | fa2756b7 | Anthony Liguori | } |
498 | fa2756b7 | Anthony Liguori | |
499 | e1c37d0e | Luiz Capitulino | void qmp_migrate(const char *uri, bool has_blk, bool blk, |
500 | e1c37d0e | Luiz Capitulino | bool has_inc, bool inc, bool has_detach, bool detach, |
501 | e1c37d0e | Luiz Capitulino | Error **errp) |
502 | cab30143 | Juan Quintela | { |
503 | be7059cd | Paolo Bonzini | Error *local_err = NULL;
|
504 | 17549e84 | Juan Quintela | MigrationState *s = migrate_get_current(); |
505 | 6607ae23 | Isaku Yamahata | MigrationParams params; |
506 | cab30143 | Juan Quintela | const char *p; |
507 | cab30143 | Juan Quintela | |
508 | 6607ae23 | Isaku Yamahata | params.blk = blk; |
509 | 6607ae23 | Isaku Yamahata | params.shared = inc; |
510 | 6607ae23 | Isaku Yamahata | |
511 | 17549e84 | Juan Quintela | if (s->state == MIG_STATE_ACTIVE) {
|
512 | e1c37d0e | Luiz Capitulino | error_set(errp, QERR_MIGRATION_ACTIVE); |
513 | e1c37d0e | Luiz Capitulino | return;
|
514 | cab30143 | Juan Quintela | } |
515 | cab30143 | Juan Quintela | |
516 | e1c37d0e | Luiz Capitulino | if (qemu_savevm_state_blocked(errp)) {
|
517 | e1c37d0e | Luiz Capitulino | return;
|
518 | cab30143 | Juan Quintela | } |
519 | cab30143 | Juan Quintela | |
520 | fa2756b7 | Anthony Liguori | if (migration_blockers) {
|
521 | e1c37d0e | Luiz Capitulino | *errp = error_copy(migration_blockers->data); |
522 | e1c37d0e | Luiz Capitulino | return;
|
523 | fa2756b7 | Anthony Liguori | } |
524 | fa2756b7 | Anthony Liguori | |
525 | 6607ae23 | Isaku Yamahata | s = migrate_init(¶ms); |
526 | cab30143 | Juan Quintela | |
527 | cab30143 | Juan Quintela | if (strstart(uri, "tcp:", &p)) { |
528 | f37afb5a | Paolo Bonzini | tcp_start_outgoing_migration(s, p, &local_err); |
529 | cab30143 | Juan Quintela | #if !defined(WIN32)
|
530 | cab30143 | Juan Quintela | } else if (strstart(uri, "exec:", &p)) { |
531 | f37afb5a | Paolo Bonzini | exec_start_outgoing_migration(s, p, &local_err); |
532 | cab30143 | Juan Quintela | } else if (strstart(uri, "unix:", &p)) { |
533 | f37afb5a | Paolo Bonzini | unix_start_outgoing_migration(s, p, &local_err); |
534 | cab30143 | Juan Quintela | } else if (strstart(uri, "fd:", &p)) { |
535 | f37afb5a | Paolo Bonzini | fd_start_outgoing_migration(s, p, &local_err); |
536 | cab30143 | Juan Quintela | #endif
|
537 | 99a0db9b | Gerd Hoffmann | } else {
|
538 | e1c37d0e | Luiz Capitulino | error_set(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol"); |
539 | e1c37d0e | Luiz Capitulino | return;
|
540 | cab30143 | Juan Quintela | } |
541 | cab30143 | Juan Quintela | |
542 | f37afb5a | Paolo Bonzini | if (local_err) {
|
543 | 342ab8d1 | Paolo Bonzini | migrate_fd_error(s); |
544 | f37afb5a | Paolo Bonzini | error_propagate(errp, local_err); |
545 | e1c37d0e | Luiz Capitulino | return;
|
546 | 1299c631 | Juan Quintela | } |
547 | 1299c631 | Juan Quintela | |
548 | e0eb7390 | Juan Quintela | notifier_list_notify(&migration_state_notifiers, s); |
549 | cab30143 | Juan Quintela | } |
550 | cab30143 | Juan Quintela | |
551 | 6cdedb07 | Luiz Capitulino | void qmp_migrate_cancel(Error **errp)
|
552 | cab30143 | Juan Quintela | { |
553 | 17549e84 | Juan Quintela | migrate_fd_cancel(migrate_get_current()); |
554 | cab30143 | Juan Quintela | } |
555 | cab30143 | Juan Quintela | |
556 | 9e1ba4cc | Orit Wasserman | void qmp_migrate_set_cache_size(int64_t value, Error **errp)
|
557 | 9e1ba4cc | Orit Wasserman | { |
558 | 9e1ba4cc | Orit Wasserman | MigrationState *s = migrate_get_current(); |
559 | 9e1ba4cc | Orit Wasserman | |
560 | 9e1ba4cc | Orit Wasserman | /* Check for truncation */
|
561 | 9e1ba4cc | Orit Wasserman | if (value != (size_t)value) {
|
562 | 9e1ba4cc | Orit Wasserman | error_set(errp, QERR_INVALID_PARAMETER_VALUE, "cache size",
|
563 | 9e1ba4cc | Orit Wasserman | "exceeding address space");
|
564 | 9e1ba4cc | Orit Wasserman | return;
|
565 | 9e1ba4cc | Orit Wasserman | } |
566 | 9e1ba4cc | Orit Wasserman | |
567 | 9e1ba4cc | Orit Wasserman | s->xbzrle_cache_size = xbzrle_cache_resize(value); |
568 | 9e1ba4cc | Orit Wasserman | } |
569 | 9e1ba4cc | Orit Wasserman | |
570 | 9e1ba4cc | Orit Wasserman | int64_t qmp_query_migrate_cache_size(Error **errp) |
571 | 9e1ba4cc | Orit Wasserman | { |
572 | 9e1ba4cc | Orit Wasserman | return migrate_xbzrle_cache_size();
|
573 | 9e1ba4cc | Orit Wasserman | } |
574 | 9e1ba4cc | Orit Wasserman | |
575 | 3dc85383 | Luiz Capitulino | void qmp_migrate_set_speed(int64_t value, Error **errp)
|
576 | cab30143 | Juan Quintela | { |
577 | cab30143 | Juan Quintela | MigrationState *s; |
578 | cab30143 | Juan Quintela | |
579 | 3dc85383 | Luiz Capitulino | if (value < 0) { |
580 | 3dc85383 | Luiz Capitulino | value = 0;
|
581 | 99a0db9b | Gerd Hoffmann | } |
582 | cab30143 | Juan Quintela | |
583 | 17549e84 | Juan Quintela | s = migrate_get_current(); |
584 | 3dc85383 | Luiz Capitulino | s->bandwidth_limit = value; |
585 | d0ae46c1 | Juan Quintela | qemu_file_set_rate_limit(s->file, s->bandwidth_limit); |
586 | cab30143 | Juan Quintela | } |
587 | cab30143 | Juan Quintela | |
588 | 4f0a993b | Luiz Capitulino | void qmp_migrate_set_downtime(double value, Error **errp) |
589 | cab30143 | Juan Quintela | { |
590 | 4f0a993b | Luiz Capitulino | value *= 1e9;
|
591 | 4f0a993b | Luiz Capitulino | value = MAX(0, MIN(UINT64_MAX, value));
|
592 | 4f0a993b | Luiz Capitulino | max_downtime = (uint64_t)value; |
593 | 99a0db9b | Gerd Hoffmann | } |
594 | 17ad9b35 | Orit Wasserman | |
595 | 17ad9b35 | Orit Wasserman | int migrate_use_xbzrle(void) |
596 | 17ad9b35 | Orit Wasserman | { |
597 | 17ad9b35 | Orit Wasserman | MigrationState *s; |
598 | 17ad9b35 | Orit Wasserman | |
599 | 17ad9b35 | Orit Wasserman | s = migrate_get_current(); |
600 | 17ad9b35 | Orit Wasserman | |
601 | 17ad9b35 | Orit Wasserman | return s->enabled_capabilities[MIGRATION_CAPABILITY_XBZRLE];
|
602 | 17ad9b35 | Orit Wasserman | } |
603 | 17ad9b35 | Orit Wasserman | |
604 | 17ad9b35 | Orit Wasserman | int64_t migrate_xbzrle_cache_size(void)
|
605 | 17ad9b35 | Orit Wasserman | { |
606 | 17ad9b35 | Orit Wasserman | MigrationState *s; |
607 | 17ad9b35 | Orit Wasserman | |
608 | 17ad9b35 | Orit Wasserman | s = migrate_get_current(); |
609 | 17ad9b35 | Orit Wasserman | |
610 | 17ad9b35 | Orit Wasserman | return s->xbzrle_cache_size;
|
611 | 17ad9b35 | Orit Wasserman | } |