Merge tag 'qemu-macppc-20230206' of https://github.com/mcayland/qemu into staging
[qemu.git] / migration / migration-hmp-cmds.c
blobef25bc89290e66cd5c1d3b42ee5eef80f28eca18
1 /*
2 * HMP commands related to migration
4 * Copyright IBM, Corp. 2011
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
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.
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"
35 void hmp_info_migrate(Monitor *mon, const QDict *qdict)
37 MigrationInfo *info;
39 info = qmp_query_migrate(NULL);
41 migration_global_dump(mon);
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;
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");
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);
67 if (info->has_downtime) {
68 monitor_printf(mon, "downtime: %" PRIu64 " ms\n",
69 info->downtime);
71 if (info->has_setup_time) {
72 monitor_printf(mon, "setup: %" PRIu64 " ms\n",
73 info->setup_time);
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);
103 if (info->ram->dirty_pages_rate) {
104 monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
105 info->ram->dirty_pages_rate);
107 if (info->ram->postcopy_requests) {
108 monitor_printf(mon, "postcopy request count: %" PRIu64 "\n",
109 info->ram->postcopy_requests);
111 if (info->ram->precopy_bytes) {
112 monitor_printf(mon, "precopy ram: %" PRIu64 " kbytes\n",
113 info->ram->precopy_bytes >> 10);
115 if (info->ram->downtime_bytes) {
116 monitor_printf(mon, "downtime ram: %" PRIu64 " kbytes\n",
117 info->ram->downtime_bytes >> 10);
119 if (info->ram->postcopy_bytes) {
120 monitor_printf(mon, "postcopy ram: %" PRIu64 " kbytes\n",
121 info->ram->postcopy_bytes >> 10);
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);
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);
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);
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);
169 if (info->has_cpu_throttle_percentage) {
170 monitor_printf(mon, "cpu throttle percentage: %" PRIu64 "\n",
171 info->cpu_throttle_percentage);
174 if (info->has_postcopy_blocktime) {
175 monitor_printf(mon, "postcopy blocktime: %u\n",
176 info->postcopy_blocktime);
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);
190 if (info->has_socket_address) {
191 SocketAddressList *addr;
193 monitor_printf(mon, "socket address: [\n");
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);
200 monitor_printf(mon, "]\n");
203 if (info->vfio) {
204 monitor_printf(mon, "vfio device transferred: %" PRIu64 " kbytes\n",
205 info->vfio->transferred >> 10);
208 qapi_free_MigrationInfo(info);
211 void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
213 MigrationCapabilityStatusList *caps, *cap;
215 caps = qmp_query_migrate_capabilities(NULL);
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");
225 qapi_free_MigrationCapabilityStatusList(caps);
228 void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
230 MigrationParameters *params;
232 params = qmp_query_migrate_parameters(NULL);
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);
323 if (params->has_block_bitmap_mapping) {
324 const BitmapMigrationNodeAliasList *bmnal;
326 monitor_printf(mon, "%s:\n",
327 MigrationParameter_str(
328 MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING));
330 for (bmnal = params->block_bitmap_mapping;
331 bmnal;
332 bmnal = bmnal->next)
334 const BitmapMigrationNodeAlias *bmna = bmnal->value;
335 const BitmapMigrationBitmapAliasList *bmbal;
337 monitor_printf(mon, " '%s' -> '%s'\n",
338 bmna->node_name, bmna->alias);
340 for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) {
341 const BitmapMigrationBitmapAlias *bmba = bmbal->value;
343 monitor_printf(mon, " '%s' -> '%s'\n",
344 bmba->name, bmba->alias);
350 qapi_free_MigrationParameters(params);
353 void hmp_loadvm(Monitor *mon, const QDict *qdict)
355 int saved_vm_running = runstate_is_running();
356 const char *name = qdict_get_str(qdict, "name");
357 Error *err = NULL;
359 vm_stop(RUN_STATE_RESTORE_VM);
361 if (load_snapshot(name, NULL, false, NULL, &err) && saved_vm_running) {
362 vm_start();
364 hmp_handle_error(mon, err);
367 void hmp_savevm(Monitor *mon, const QDict *qdict)
369 Error *err = NULL;
371 save_snapshot(qdict_get_try_str(qdict, "name"),
372 true, NULL, false, NULL, &err);
373 hmp_handle_error(mon, err);
376 void hmp_delvm(Monitor *mon, const QDict *qdict)
378 Error *err = NULL;
379 const char *name = qdict_get_str(qdict, "name");
381 delete_snapshot(name, false, NULL, &err);
382 hmp_handle_error(mon, err);
385 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
387 qmp_migrate_cancel(NULL);
390 void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
392 Error *err = NULL;
393 const char *state = qdict_get_str(qdict, "state");
394 int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
396 if (val >= 0) {
397 qmp_migrate_continue(val, &err);
400 hmp_handle_error(mon, err);
403 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
405 Error *err = NULL;
406 const char *uri = qdict_get_str(qdict, "uri");
408 qmp_migrate_incoming(uri, &err);
410 hmp_handle_error(mon, err);
413 void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
415 Error *err = NULL;
416 const char *uri = qdict_get_str(qdict, "uri");
418 qmp_migrate_recover(uri, &err);
420 hmp_handle_error(mon, err);
423 void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
425 Error *err = NULL;
427 qmp_migrate_pause(&err);
429 hmp_handle_error(mon, err);
433 void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
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;
442 val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err);
443 if (val < 0) {
444 goto end;
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);
454 end:
455 hmp_handle_error(mon, err);
458 void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
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;
469 val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err);
470 if (val < 0) {
471 goto cleanup;
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;
529 * Can't use visit_type_size() here, because it
530 * defaults to Bytes rather than Mebibytes.
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;
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;
574 if (cache_size > INT64_MAX || (size_t)cache_size != cache_size) {
575 error_setg(&err, "Invalid size %s", valuestr);
576 break;
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);
608 if (err) {
609 goto cleanup;
612 qmp_migrate_set_parameters(p, &err);
614 cleanup:
615 qapi_free_MigrateSetParameters(p);
616 visit_free(v);
617 hmp_handle_error(mon, err);
620 void hmp_client_migrate_info(Monitor *mon, const QDict *qdict)
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");
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);
637 void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict)
639 Error *err = NULL;
640 qmp_migrate_start_postcopy(&err);
641 hmp_handle_error(mon, err);
644 void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict)
646 Error *err = NULL;
648 qmp_x_colo_lost_heartbeat(&err);
649 hmp_handle_error(mon, err);
652 typedef struct HMPMigrationStatus {
653 QEMUTimer *timer;
654 Monitor *mon;
655 bool is_block_migration;
656 } HMPMigrationStatus;
658 static void hmp_migrate_status_cb(void *opaque)
660 HMPMigrationStatus *status = opaque;
661 MigrationInfo *info;
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;
669 if (info->disk->remaining) {
670 progress = info->disk->transferred * 100 / info->disk->total;
671 } else {
672 progress = 100;
675 monitor_printf(status->mon, "Completed %d %%\r", progress);
676 monitor_flush(status->mon);
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");
684 if (info->error_desc) {
685 error_report("%s", info->error_desc);
687 monitor_resume(status->mon);
688 timer_free(status->timer);
689 g_free(status);
692 qapi_free_MigrationInfo(info);
695 void hmp_migrate(Monitor *mon, const QDict *qdict)
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;
704 qmp_migrate(uri, !!blk, blk, !!inc, inc,
705 false, false, true, resume, &err);
706 if (hmp_handle_error(mon, err)) {
707 return;
710 if (!detach) {
711 HMPMigrationStatus *status;
713 if (monitor_suspend(mon) < 0) {
714 monitor_printf(mon, "terminal does not allow synchronous "
715 "migration, continuing detached\n");
716 return;
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));
728 void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
729 const char *str)
731 size_t len;
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));
740 } else if (nb_args == 3) {
741 readline_add_completion_of(rs, str, "on");
742 readline_add_completion_of(rs, str, "off");
746 void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
747 const char *str)
749 size_t len;
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));
761 static void vm_completion(ReadLineState *rs, const char *str)
763 size_t len;
764 BlockDriverState *bs;
765 BdrvNextIterator it;
767 len = strlen(str);
768 readline_set_completion_index(rs, len);
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;
775 aio_context_acquire(ctx);
776 if (bdrv_can_snapshot(bs)) {
777 ok = bdrv_query_snapshot_info_list(bs, &snapshots, NULL) == 0;
779 aio_context_release(ctx);
780 if (!ok) {
781 continue;
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;
790 qapi_free_SnapshotInfoList(snapshots);
795 void delvm_completion(ReadLineState *rs, int nb_args, const char *str)
797 if (nb_args == 2) {
798 vm_completion(rs, str);
802 void loadvm_completion(ReadLineState *rs, int nb_args, const char *str)
804 if (nb_args == 2) {
805 vm_completion(rs, str);