xref: /qemu/migration/migration-hmp-cmds.c (revision 0c79effd)
1 /*
2  * HMP commands related to migration
3  *
4  * Copyright IBM, Corp. 2011
5  *
6  * Authors:
7  *  Anthony Liguori   <aliguori@us.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  *
12  * Contributions after 2012-01-13 are licensed under the terms of the
13  * GNU GPL, version 2 or (at your option) any later version.
14  */
15 
16 #include "qemu/osdep.h"
17 #include "block/qapi.h"
18 #include "migration/snapshot.h"
19 #include "monitor/hmp.h"
20 #include "monitor/monitor.h"
21 #include "qapi/error.h"
22 #include "qapi/qapi-commands-migration.h"
23 #include "qapi/qapi-visit-migration.h"
24 #include "qapi/qmp/qdict.h"
25 #include "qapi/string-input-visitor.h"
26 #include "qapi/string-output-visitor.h"
27 #include "qemu/cutils.h"
28 #include "qemu/error-report.h"
29 #include "qemu/sockets.h"
30 #include "sysemu/runstate.h"
31 #include "ui/qemu-spice.h"
32 #include "sysemu/sysemu.h"
33 #include "options.h"
34 #include "migration.h"
35 
migration_global_dump(Monitor * mon)36 static void migration_global_dump(Monitor *mon)
37 {
38     MigrationState *ms = migrate_get_current();
39 
40     monitor_printf(mon, "globals:\n");
41     monitor_printf(mon, "store-global-state: %s\n",
42                    ms->store_global_state ? "on" : "off");
43     monitor_printf(mon, "only-migratable: %s\n",
44                    only_migratable ? "on" : "off");
45     monitor_printf(mon, "send-configuration: %s\n",
46                    ms->send_configuration ? "on" : "off");
47     monitor_printf(mon, "send-section-footer: %s\n",
48                    ms->send_section_footer ? "on" : "off");
49     monitor_printf(mon, "clear-bitmap-shift: %u\n",
50                    ms->clear_bitmap_shift);
51 }
52 
hmp_info_migrate(Monitor * mon,const QDict * qdict)53 void hmp_info_migrate(Monitor *mon, const QDict *qdict)
54 {
55     MigrationInfo *info;
56 
57     info = qmp_query_migrate(NULL);
58 
59     migration_global_dump(mon);
60 
61     if (info->blocked_reasons) {
62         strList *reasons = info->blocked_reasons;
63         monitor_printf(mon, "Outgoing migration blocked:\n");
64         while (reasons) {
65             monitor_printf(mon, "  %s\n", reasons->value);
66             reasons = reasons->next;
67         }
68     }
69 
70     if (info->has_status) {
71         monitor_printf(mon, "Migration status: %s",
72                        MigrationStatus_str(info->status));
73         if (info->status == MIGRATION_STATUS_FAILED && info->error_desc) {
74             monitor_printf(mon, " (%s)\n", info->error_desc);
75         } else {
76             monitor_printf(mon, "\n");
77         }
78 
79         monitor_printf(mon, "total time: %" PRIu64 " ms\n",
80                        info->total_time);
81         if (info->has_expected_downtime) {
82             monitor_printf(mon, "expected downtime: %" PRIu64 " ms\n",
83                            info->expected_downtime);
84         }
85         if (info->has_downtime) {
86             monitor_printf(mon, "downtime: %" PRIu64 " ms\n",
87                            info->downtime);
88         }
89         if (info->has_setup_time) {
90             monitor_printf(mon, "setup: %" PRIu64 " ms\n",
91                            info->setup_time);
92         }
93     }
94 
95     if (info->ram) {
96         monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n",
97                        info->ram->transferred >> 10);
98         monitor_printf(mon, "throughput: %0.2f mbps\n",
99                        info->ram->mbps);
100         monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n",
101                        info->ram->remaining >> 10);
102         monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n",
103                        info->ram->total >> 10);
104         monitor_printf(mon, "duplicate: %" PRIu64 " pages\n",
105                        info->ram->duplicate);
106         monitor_printf(mon, "normal: %" PRIu64 " pages\n",
107                        info->ram->normal);
108         monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
109                        info->ram->normal_bytes >> 10);
110         monitor_printf(mon, "dirty sync count: %" PRIu64 "\n",
111                        info->ram->dirty_sync_count);
112         monitor_printf(mon, "page size: %" PRIu64 " kbytes\n",
113                        info->ram->page_size >> 10);
114         monitor_printf(mon, "multifd bytes: %" PRIu64 " kbytes\n",
115                        info->ram->multifd_bytes >> 10);
116         monitor_printf(mon, "pages-per-second: %" PRIu64 "\n",
117                        info->ram->pages_per_second);
118 
119         if (info->ram->dirty_pages_rate) {
120             monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
121                            info->ram->dirty_pages_rate);
122         }
123         if (info->ram->postcopy_requests) {
124             monitor_printf(mon, "postcopy request count: %" PRIu64 "\n",
125                            info->ram->postcopy_requests);
126         }
127         if (info->ram->precopy_bytes) {
128             monitor_printf(mon, "precopy ram: %" PRIu64 " kbytes\n",
129                            info->ram->precopy_bytes >> 10);
130         }
131         if (info->ram->downtime_bytes) {
132             monitor_printf(mon, "downtime ram: %" PRIu64 " kbytes\n",
133                            info->ram->downtime_bytes >> 10);
134         }
135         if (info->ram->postcopy_bytes) {
136             monitor_printf(mon, "postcopy ram: %" PRIu64 " kbytes\n",
137                            info->ram->postcopy_bytes >> 10);
138         }
139         if (info->ram->dirty_sync_missed_zero_copy) {
140             monitor_printf(mon,
141                            "Zero-copy-send fallbacks happened: %" PRIu64 " times\n",
142                            info->ram->dirty_sync_missed_zero_copy);
143         }
144     }
145 
146     if (info->xbzrle_cache) {
147         monitor_printf(mon, "cache size: %" PRIu64 " bytes\n",
148                        info->xbzrle_cache->cache_size);
149         monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n",
150                        info->xbzrle_cache->bytes >> 10);
151         monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
152                        info->xbzrle_cache->pages);
153         monitor_printf(mon, "xbzrle cache miss: %" PRIu64 " pages\n",
154                        info->xbzrle_cache->cache_miss);
155         monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n",
156                        info->xbzrle_cache->cache_miss_rate);
157         monitor_printf(mon, "xbzrle encoding rate: %0.2f\n",
158                        info->xbzrle_cache->encoding_rate);
159         monitor_printf(mon, "xbzrle overflow: %" PRIu64 "\n",
160                        info->xbzrle_cache->overflow);
161     }
162 
163     if (info->has_cpu_throttle_percentage) {
164         monitor_printf(mon, "cpu throttle percentage: %" PRIu64 "\n",
165                        info->cpu_throttle_percentage);
166     }
167 
168     if (info->has_dirty_limit_throttle_time_per_round) {
169         monitor_printf(mon, "dirty-limit throttle time: %" PRIu64 " us\n",
170                        info->dirty_limit_throttle_time_per_round);
171     }
172 
173     if (info->has_dirty_limit_ring_full_time) {
174         monitor_printf(mon, "dirty-limit ring full time: %" PRIu64 " us\n",
175                        info->dirty_limit_ring_full_time);
176     }
177 
178     if (info->has_postcopy_blocktime) {
179         monitor_printf(mon, "postcopy blocktime: %u\n",
180                        info->postcopy_blocktime);
181     }
182 
183     if (info->has_postcopy_vcpu_blocktime) {
184         Visitor *v;
185         char *str;
186         v = string_output_visitor_new(false, &str);
187         visit_type_uint32List(v, NULL, &info->postcopy_vcpu_blocktime,
188                               &error_abort);
189         visit_complete(v, &str);
190         monitor_printf(mon, "postcopy vcpu blocktime: %s\n", str);
191         g_free(str);
192         visit_free(v);
193     }
194     if (info->has_socket_address) {
195         SocketAddressList *addr;
196 
197         monitor_printf(mon, "socket address: [\n");
198 
199         for (addr = info->socket_address; addr; addr = addr->next) {
200             char *s = socket_uri(addr->value);
201             monitor_printf(mon, "\t%s\n", s);
202             g_free(s);
203         }
204         monitor_printf(mon, "]\n");
205     }
206 
207     if (info->vfio) {
208         monitor_printf(mon, "vfio device transferred: %" PRIu64 " kbytes\n",
209                        info->vfio->transferred >> 10);
210     }
211 
212     qapi_free_MigrationInfo(info);
213 }
214 
hmp_info_migrate_capabilities(Monitor * mon,const QDict * qdict)215 void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
216 {
217     MigrationCapabilityStatusList *caps, *cap;
218 
219     caps = qmp_query_migrate_capabilities(NULL);
220 
221     if (caps) {
222         for (cap = caps; cap; cap = cap->next) {
223             monitor_printf(mon, "%s: %s\n",
224                            MigrationCapability_str(cap->value->capability),
225                            cap->value->state ? "on" : "off");
226         }
227     }
228 
229     qapi_free_MigrationCapabilityStatusList(caps);
230 }
231 
hmp_info_migrate_parameters(Monitor * mon,const QDict * qdict)232 void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
233 {
234     MigrationParameters *params;
235 
236     params = qmp_query_migrate_parameters(NULL);
237 
238     if (params) {
239         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
240             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_INITIAL),
241             params->announce_initial);
242         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
243             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_MAX),
244             params->announce_max);
245         monitor_printf(mon, "%s: %" PRIu64 "\n",
246             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_ROUNDS),
247             params->announce_rounds);
248         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
249             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_STEP),
250             params->announce_step);
251         assert(params->has_throttle_trigger_threshold);
252         monitor_printf(mon, "%s: %u\n",
253             MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD),
254             params->throttle_trigger_threshold);
255         assert(params->has_cpu_throttle_initial);
256         monitor_printf(mon, "%s: %u\n",
257             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL),
258             params->cpu_throttle_initial);
259         assert(params->has_cpu_throttle_increment);
260         monitor_printf(mon, "%s: %u\n",
261             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT),
262             params->cpu_throttle_increment);
263         assert(params->has_cpu_throttle_tailslow);
264         monitor_printf(mon, "%s: %s\n",
265             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW),
266             params->cpu_throttle_tailslow ? "on" : "off");
267         assert(params->has_max_cpu_throttle);
268         monitor_printf(mon, "%s: %u\n",
269             MigrationParameter_str(MIGRATION_PARAMETER_MAX_CPU_THROTTLE),
270             params->max_cpu_throttle);
271         assert(params->tls_creds);
272         monitor_printf(mon, "%s: '%s'\n",
273             MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS),
274             params->tls_creds);
275         assert(params->tls_hostname);
276         monitor_printf(mon, "%s: '%s'\n",
277             MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME),
278             params->tls_hostname);
279         assert(params->has_max_bandwidth);
280         monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
281             MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH),
282             params->max_bandwidth);
283         assert(params->has_avail_switchover_bandwidth);
284         monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
285             MigrationParameter_str(MIGRATION_PARAMETER_AVAIL_SWITCHOVER_BANDWIDTH),
286             params->avail_switchover_bandwidth);
287         assert(params->has_downtime_limit);
288         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
289             MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT),
290             params->downtime_limit);
291         assert(params->has_x_checkpoint_delay);
292         monitor_printf(mon, "%s: %u ms\n",
293             MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY),
294             params->x_checkpoint_delay);
295         monitor_printf(mon, "%s: %u\n",
296             MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS),
297             params->multifd_channels);
298         monitor_printf(mon, "%s: %s\n",
299             MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION),
300             MultiFDCompression_str(params->multifd_compression));
301         assert(params->has_zero_page_detection);
302         monitor_printf(mon, "%s: %s\n",
303             MigrationParameter_str(MIGRATION_PARAMETER_ZERO_PAGE_DETECTION),
304             qapi_enum_lookup(&ZeroPageDetection_lookup,
305                 params->zero_page_detection));
306         monitor_printf(mon, "%s: %" PRIu64 " bytes\n",
307             MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
308             params->xbzrle_cache_size);
309         monitor_printf(mon, "%s: %" PRIu64 "\n",
310             MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
311             params->max_postcopy_bandwidth);
312         monitor_printf(mon, "%s: '%s'\n",
313             MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
314             params->tls_authz);
315 
316         if (params->has_block_bitmap_mapping) {
317             const BitmapMigrationNodeAliasList *bmnal;
318 
319             monitor_printf(mon, "%s:\n",
320                            MigrationParameter_str(
321                                MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING));
322 
323             for (bmnal = params->block_bitmap_mapping;
324                  bmnal;
325                  bmnal = bmnal->next)
326             {
327                 const BitmapMigrationNodeAlias *bmna = bmnal->value;
328                 const BitmapMigrationBitmapAliasList *bmbal;
329 
330                 monitor_printf(mon, "  '%s' -> '%s'\n",
331                                bmna->node_name, bmna->alias);
332 
333                 for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) {
334                     const BitmapMigrationBitmapAlias *bmba = bmbal->value;
335 
336                     monitor_printf(mon, "    '%s' -> '%s'\n",
337                                    bmba->name, bmba->alias);
338                 }
339             }
340         }
341 
342         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
343         MigrationParameter_str(MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD),
344         params->x_vcpu_dirty_limit_period);
345 
346         monitor_printf(mon, "%s: %" PRIu64 " MB/s\n",
347             MigrationParameter_str(MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT),
348             params->vcpu_dirty_limit);
349 
350         assert(params->has_mode);
351         monitor_printf(mon, "%s: %s\n",
352             MigrationParameter_str(MIGRATION_PARAMETER_MODE),
353             qapi_enum_lookup(&MigMode_lookup, params->mode));
354 
355         if (params->has_direct_io) {
356             monitor_printf(mon, "%s: %s\n",
357                            MigrationParameter_str(
358                                MIGRATION_PARAMETER_DIRECT_IO),
359                            params->direct_io ? "on" : "off");
360         }
361     }
362 
363     qapi_free_MigrationParameters(params);
364 }
365 
hmp_loadvm(Monitor * mon,const QDict * qdict)366 void hmp_loadvm(Monitor *mon, const QDict *qdict)
367 {
368     RunState saved_state = runstate_get();
369 
370     const char *name = qdict_get_str(qdict, "name");
371     Error *err = NULL;
372 
373     vm_stop(RUN_STATE_RESTORE_VM);
374 
375     if (load_snapshot(name, NULL, false, NULL, &err)) {
376         load_snapshot_resume(saved_state);
377     }
378 
379     hmp_handle_error(mon, err);
380 }
381 
hmp_savevm(Monitor * mon,const QDict * qdict)382 void hmp_savevm(Monitor *mon, const QDict *qdict)
383 {
384     Error *err = NULL;
385 
386     save_snapshot(qdict_get_try_str(qdict, "name"),
387                   true, NULL, false, NULL, &err);
388     hmp_handle_error(mon, err);
389 }
390 
hmp_delvm(Monitor * mon,const QDict * qdict)391 void hmp_delvm(Monitor *mon, const QDict *qdict)
392 {
393     Error *err = NULL;
394     const char *name = qdict_get_str(qdict, "name");
395 
396     delete_snapshot(name, false, NULL, &err);
397     hmp_handle_error(mon, err);
398 }
399 
hmp_migrate_cancel(Monitor * mon,const QDict * qdict)400 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
401 {
402     qmp_migrate_cancel(NULL);
403 }
404 
hmp_migrate_continue(Monitor * mon,const QDict * qdict)405 void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
406 {
407     Error *err = NULL;
408     const char *state = qdict_get_str(qdict, "state");
409     int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
410 
411     if (val >= 0) {
412         qmp_migrate_continue(val, &err);
413     }
414 
415     hmp_handle_error(mon, err);
416 }
417 
hmp_migrate_incoming(Monitor * mon,const QDict * qdict)418 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
419 {
420     Error *err = NULL;
421     const char *uri = qdict_get_str(qdict, "uri");
422     MigrationChannelList *caps = NULL;
423     g_autoptr(MigrationChannel) channel = NULL;
424 
425     if (!migrate_uri_parse(uri, &channel, &err)) {
426         goto end;
427     }
428     QAPI_LIST_PREPEND(caps, g_steal_pointer(&channel));
429 
430     qmp_migrate_incoming(NULL, true, caps, true, false, &err);
431     qapi_free_MigrationChannelList(caps);
432 
433 end:
434     hmp_handle_error(mon, err);
435 }
436 
hmp_migrate_recover(Monitor * mon,const QDict * qdict)437 void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
438 {
439     Error *err = NULL;
440     const char *uri = qdict_get_str(qdict, "uri");
441 
442     qmp_migrate_recover(uri, &err);
443 
444     hmp_handle_error(mon, err);
445 }
446 
hmp_migrate_pause(Monitor * mon,const QDict * qdict)447 void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
448 {
449     Error *err = NULL;
450 
451     qmp_migrate_pause(&err);
452 
453     hmp_handle_error(mon, err);
454 }
455 
456 
hmp_migrate_set_capability(Monitor * mon,const QDict * qdict)457 void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
458 {
459     const char *cap = qdict_get_str(qdict, "capability");
460     bool state = qdict_get_bool(qdict, "state");
461     Error *err = NULL;
462     MigrationCapabilityStatusList *caps = NULL;
463     MigrationCapabilityStatus *value;
464     int val;
465 
466     val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err);
467     if (val < 0) {
468         goto end;
469     }
470 
471     value = g_malloc0(sizeof(*value));
472     value->capability = val;
473     value->state = state;
474     QAPI_LIST_PREPEND(caps, value);
475     qmp_migrate_set_capabilities(caps, &err);
476     qapi_free_MigrationCapabilityStatusList(caps);
477 
478 end:
479     hmp_handle_error(mon, err);
480 }
481 
hmp_migrate_set_parameter(Monitor * mon,const QDict * qdict)482 void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
483 {
484     const char *param = qdict_get_str(qdict, "parameter");
485     const char *valuestr = qdict_get_str(qdict, "value");
486     Visitor *v = string_input_visitor_new(valuestr);
487     MigrateSetParameters *p = g_new0(MigrateSetParameters, 1);
488     uint64_t valuebw = 0;
489     uint64_t cache_size;
490     Error *err = NULL;
491     int val, ret;
492 
493     val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err);
494     if (val < 0) {
495         goto cleanup;
496     }
497 
498     switch (val) {
499     case MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD:
500         p->has_throttle_trigger_threshold = true;
501         visit_type_uint8(v, param, &p->throttle_trigger_threshold, &err);
502         break;
503     case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL:
504         p->has_cpu_throttle_initial = true;
505         visit_type_uint8(v, param, &p->cpu_throttle_initial, &err);
506         break;
507     case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT:
508         p->has_cpu_throttle_increment = true;
509         visit_type_uint8(v, param, &p->cpu_throttle_increment, &err);
510         break;
511     case MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW:
512         p->has_cpu_throttle_tailslow = true;
513         visit_type_bool(v, param, &p->cpu_throttle_tailslow, &err);
514         break;
515     case MIGRATION_PARAMETER_MAX_CPU_THROTTLE:
516         p->has_max_cpu_throttle = true;
517         visit_type_uint8(v, param, &p->max_cpu_throttle, &err);
518         break;
519     case MIGRATION_PARAMETER_TLS_CREDS:
520         p->tls_creds = g_new0(StrOrNull, 1);
521         p->tls_creds->type = QTYPE_QSTRING;
522         visit_type_str(v, param, &p->tls_creds->u.s, &err);
523         break;
524     case MIGRATION_PARAMETER_TLS_HOSTNAME:
525         p->tls_hostname = g_new0(StrOrNull, 1);
526         p->tls_hostname->type = QTYPE_QSTRING;
527         visit_type_str(v, param, &p->tls_hostname->u.s, &err);
528         break;
529     case MIGRATION_PARAMETER_TLS_AUTHZ:
530         p->tls_authz = g_new0(StrOrNull, 1);
531         p->tls_authz->type = QTYPE_QSTRING;
532         visit_type_str(v, param, &p->tls_authz->u.s, &err);
533         break;
534     case MIGRATION_PARAMETER_MAX_BANDWIDTH:
535         p->has_max_bandwidth = true;
536         /*
537          * Can't use visit_type_size() here, because it
538          * defaults to Bytes rather than Mebibytes.
539          */
540         ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
541         if (ret < 0 || valuebw > INT64_MAX
542             || (size_t)valuebw != valuebw) {
543             error_setg(&err, "Invalid size %s", valuestr);
544             break;
545         }
546         p->max_bandwidth = valuebw;
547         break;
548     case MIGRATION_PARAMETER_AVAIL_SWITCHOVER_BANDWIDTH:
549         p->has_avail_switchover_bandwidth = true;
550         ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
551         if (ret < 0 || valuebw > INT64_MAX
552             || (size_t)valuebw != valuebw) {
553             error_setg(&err, "Invalid size %s", valuestr);
554             break;
555         }
556         p->avail_switchover_bandwidth = valuebw;
557         break;
558     case MIGRATION_PARAMETER_DOWNTIME_LIMIT:
559         p->has_downtime_limit = true;
560         visit_type_size(v, param, &p->downtime_limit, &err);
561         break;
562     case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY:
563         p->has_x_checkpoint_delay = true;
564         visit_type_uint32(v, param, &p->x_checkpoint_delay, &err);
565         break;
566     case MIGRATION_PARAMETER_MULTIFD_CHANNELS:
567         p->has_multifd_channels = true;
568         visit_type_uint8(v, param, &p->multifd_channels, &err);
569         break;
570     case MIGRATION_PARAMETER_MULTIFD_COMPRESSION:
571         p->has_multifd_compression = true;
572         visit_type_MultiFDCompression(v, param, &p->multifd_compression,
573                                       &err);
574         break;
575     case MIGRATION_PARAMETER_MULTIFD_ZLIB_LEVEL:
576         p->has_multifd_zlib_level = true;
577         visit_type_uint8(v, param, &p->multifd_zlib_level, &err);
578         break;
579     case MIGRATION_PARAMETER_MULTIFD_QATZIP_LEVEL:
580         p->has_multifd_qatzip_level = true;
581         visit_type_uint8(v, param, &p->multifd_qatzip_level, &err);
582         break;
583     case MIGRATION_PARAMETER_MULTIFD_ZSTD_LEVEL:
584         p->has_multifd_zstd_level = true;
585         visit_type_uint8(v, param, &p->multifd_zstd_level, &err);
586         break;
587     case MIGRATION_PARAMETER_ZERO_PAGE_DETECTION:
588         p->has_zero_page_detection = true;
589         visit_type_ZeroPageDetection(v, param, &p->zero_page_detection, &err);
590         break;
591     case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE:
592         p->has_xbzrle_cache_size = true;
593         if (!visit_type_size(v, param, &cache_size, &err)) {
594             break;
595         }
596         if (cache_size > INT64_MAX || (size_t)cache_size != cache_size) {
597             error_setg(&err, "Invalid size %s", valuestr);
598             break;
599         }
600         p->xbzrle_cache_size = cache_size;
601         break;
602     case MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH:
603         p->has_max_postcopy_bandwidth = true;
604         visit_type_size(v, param, &p->max_postcopy_bandwidth, &err);
605         break;
606     case MIGRATION_PARAMETER_ANNOUNCE_INITIAL:
607         p->has_announce_initial = true;
608         visit_type_size(v, param, &p->announce_initial, &err);
609         break;
610     case MIGRATION_PARAMETER_ANNOUNCE_MAX:
611         p->has_announce_max = true;
612         visit_type_size(v, param, &p->announce_max, &err);
613         break;
614     case MIGRATION_PARAMETER_ANNOUNCE_ROUNDS:
615         p->has_announce_rounds = true;
616         visit_type_size(v, param, &p->announce_rounds, &err);
617         break;
618     case MIGRATION_PARAMETER_ANNOUNCE_STEP:
619         p->has_announce_step = true;
620         visit_type_size(v, param, &p->announce_step, &err);
621         break;
622     case MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING:
623         error_setg(&err, "The block-bitmap-mapping parameter can only be set "
624                    "through QMP");
625         break;
626     case MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD:
627         p->has_x_vcpu_dirty_limit_period = true;
628         visit_type_size(v, param, &p->x_vcpu_dirty_limit_period, &err);
629         break;
630     case MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT:
631         p->has_vcpu_dirty_limit = true;
632         visit_type_size(v, param, &p->vcpu_dirty_limit, &err);
633         break;
634     case MIGRATION_PARAMETER_MODE:
635         p->has_mode = true;
636         visit_type_MigMode(v, param, &p->mode, &err);
637         break;
638     case MIGRATION_PARAMETER_DIRECT_IO:
639         p->has_direct_io = true;
640         visit_type_bool(v, param, &p->direct_io, &err);
641         break;
642     default:
643         g_assert_not_reached();
644     }
645 
646     if (err) {
647         goto cleanup;
648     }
649 
650     qmp_migrate_set_parameters(p, &err);
651 
652  cleanup:
653     qapi_free_MigrateSetParameters(p);
654     visit_free(v);
655     hmp_handle_error(mon, err);
656 }
657 
hmp_migrate_start_postcopy(Monitor * mon,const QDict * qdict)658 void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict)
659 {
660     Error *err = NULL;
661     qmp_migrate_start_postcopy(&err);
662     hmp_handle_error(mon, err);
663 }
664 
665 #ifdef CONFIG_REPLICATION
hmp_x_colo_lost_heartbeat(Monitor * mon,const QDict * qdict)666 void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict)
667 {
668     Error *err = NULL;
669 
670     qmp_x_colo_lost_heartbeat(&err);
671     hmp_handle_error(mon, err);
672 }
673 #endif
674 
675 typedef struct HMPMigrationStatus {
676     QEMUTimer *timer;
677     Monitor *mon;
678 } HMPMigrationStatus;
679 
hmp_migrate_status_cb(void * opaque)680 static void hmp_migrate_status_cb(void *opaque)
681 {
682     HMPMigrationStatus *status = opaque;
683     MigrationInfo *info;
684 
685     info = qmp_query_migrate(NULL);
686     if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE ||
687         info->status == MIGRATION_STATUS_SETUP) {
688         timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
689     } else {
690         if (info->error_desc) {
691             error_report("%s", info->error_desc);
692         }
693         monitor_resume(status->mon);
694         timer_free(status->timer);
695         g_free(status);
696     }
697 
698     qapi_free_MigrationInfo(info);
699 }
700 
hmp_migrate(Monitor * mon,const QDict * qdict)701 void hmp_migrate(Monitor *mon, const QDict *qdict)
702 {
703     bool detach = qdict_get_try_bool(qdict, "detach", false);
704     bool resume = qdict_get_try_bool(qdict, "resume", false);
705     const char *uri = qdict_get_str(qdict, "uri");
706     Error *err = NULL;
707     g_autoptr(MigrationChannelList) caps = NULL;
708     g_autoptr(MigrationChannel) channel = NULL;
709 
710     if (!migrate_uri_parse(uri, &channel, &err)) {
711         hmp_handle_error(mon, err);
712         return;
713     }
714     QAPI_LIST_PREPEND(caps, g_steal_pointer(&channel));
715 
716     qmp_migrate(NULL, true, caps, false, false, true, resume, &err);
717     if (hmp_handle_error(mon, err)) {
718         return;
719     }
720 
721     if (!detach) {
722         HMPMigrationStatus *status;
723 
724         if (monitor_suspend(mon) < 0) {
725             monitor_printf(mon, "terminal does not allow synchronous "
726                            "migration, continuing detached\n");
727             return;
728         }
729 
730         status = g_malloc0(sizeof(*status));
731         status->mon = mon;
732         status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb,
733                                           status);
734         timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
735     }
736 }
737 
migrate_set_capability_completion(ReadLineState * rs,int nb_args,const char * str)738 void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
739                                        const char *str)
740 {
741     size_t len;
742 
743     len = strlen(str);
744     readline_set_completion_index(rs, len);
745     if (nb_args == 2) {
746         int i;
747         for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
748             readline_add_completion_of(rs, str, MigrationCapability_str(i));
749         }
750     } else if (nb_args == 3) {
751         readline_add_completion_of(rs, str, "on");
752         readline_add_completion_of(rs, str, "off");
753     }
754 }
755 
migrate_set_parameter_completion(ReadLineState * rs,int nb_args,const char * str)756 void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
757                                       const char *str)
758 {
759     size_t len;
760 
761     len = strlen(str);
762     readline_set_completion_index(rs, len);
763     if (nb_args == 2) {
764         int i;
765         for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) {
766             readline_add_completion_of(rs, str, MigrationParameter_str(i));
767         }
768     }
769 }
770 
vm_completion(ReadLineState * rs,const char * str)771 static void vm_completion(ReadLineState *rs, const char *str)
772 {
773     size_t len;
774     BlockDriverState *bs;
775     BdrvNextIterator it;
776 
777     GRAPH_RDLOCK_GUARD_MAINLOOP();
778 
779     len = strlen(str);
780     readline_set_completion_index(rs, len);
781 
782     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
783         SnapshotInfoList *snapshots, *snapshot;
784         bool ok = false;
785 
786         if (bdrv_can_snapshot(bs)) {
787             ok = bdrv_query_snapshot_info_list(bs, &snapshots, NULL) == 0;
788         }
789         if (!ok) {
790             continue;
791         }
792 
793         snapshot = snapshots;
794         while (snapshot) {
795             readline_add_completion_of(rs, str, snapshot->value->name);
796             readline_add_completion_of(rs, str, snapshot->value->id);
797             snapshot = snapshot->next;
798         }
799         qapi_free_SnapshotInfoList(snapshots);
800     }
801 
802 }
803 
delvm_completion(ReadLineState * rs,int nb_args,const char * str)804 void delvm_completion(ReadLineState *rs, int nb_args, const char *str)
805 {
806     if (nb_args == 2) {
807         vm_completion(rs, str);
808     }
809 }
810 
loadvm_completion(ReadLineState * rs,int nb_args,const char * str)811 void loadvm_completion(ReadLineState *rs, int nb_args, const char *str)
812 {
813     if (nb_args == 2) {
814         vm_completion(rs, str);
815     }
816 }
817