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