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 "qobject/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 "system/runstate.h"
31 #include "ui/qemu-spice.h"
32 #include "system/system.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, " send-switchover-start: %s\n",
50 ms->send_switchover_start ? "on" : "off");
51 monitor_printf(mon, " clear-bitmap-shift: %u\n",
52 ms->clear_bitmap_shift);
53 }
54
format_time_str(uint64_t us)55 static const gchar *format_time_str(uint64_t us)
56 {
57 const char *units[] = {"us", "ms", "sec"};
58 int index = 0;
59
60 while (us >= 1000 && index + 1 < ARRAY_SIZE(units)) {
61 us /= 1000;
62 index++;
63 }
64
65 return g_strdup_printf("%"PRIu64" %s", us, units[index]);
66 }
67
migration_dump_blocktime(Monitor * mon,MigrationInfo * info)68 static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info)
69 {
70 if (info->has_postcopy_blocktime) {
71 monitor_printf(mon, "Postcopy Blocktime (ms): %" PRIu32 "\n",
72 info->postcopy_blocktime);
73 }
74
75 if (info->has_postcopy_vcpu_blocktime) {
76 uint32List *item = info->postcopy_vcpu_blocktime;
77 const char *sep = "";
78 int count = 0;
79
80 monitor_printf(mon, "Postcopy vCPU Blocktime (ms):\n [");
81
82 while (item) {
83 monitor_printf(mon, "%s%"PRIu32, sep, item->value);
84 item = item->next;
85 /* Each line 10 vcpu results, newline if there's more */
86 sep = ((++count % 10 == 0) && item) ? ",\n " : ", ";
87 }
88 monitor_printf(mon, "]\n");
89 }
90
91 if (info->has_postcopy_latency) {
92 monitor_printf(mon, "Postcopy Latency (ns): %" PRIu64 "\n",
93 info->postcopy_latency);
94 }
95
96 if (info->has_postcopy_non_vcpu_latency) {
97 monitor_printf(mon, "Postcopy non-vCPU Latencies (ns): %" PRIu64 "\n",
98 info->postcopy_non_vcpu_latency);
99 }
100
101 if (info->has_postcopy_vcpu_latency) {
102 uint64List *item = info->postcopy_vcpu_latency;
103 const char *sep = "";
104 int count = 0;
105
106 monitor_printf(mon, "Postcopy vCPU Latencies (ns):\n [");
107
108 while (item) {
109 monitor_printf(mon, "%s%"PRIu64, sep, item->value);
110 item = item->next;
111 /* Each line 10 vcpu results, newline if there's more */
112 sep = ((++count % 10 == 0) && item) ? ",\n " : ", ";
113 }
114 monitor_printf(mon, "]\n");
115 }
116
117 if (info->has_postcopy_latency_dist) {
118 uint64List *item = info->postcopy_latency_dist;
119 int count = 0;
120
121 monitor_printf(mon, "Postcopy Latency Distribution:\n");
122
123 while (item) {
124 g_autofree const gchar *from = format_time_str(1UL << count);
125 g_autofree const gchar *to = format_time_str(1UL << (count + 1));
126
127 monitor_printf(mon, " [ %8s - %8s ]: %10"PRIu64"\n",
128 from, to, item->value);
129 item = item->next;
130 count++;
131 }
132 }
133 }
134
hmp_info_migrate(Monitor * mon,const QDict * qdict)135 void hmp_info_migrate(Monitor *mon, const QDict *qdict)
136 {
137 bool show_all = qdict_get_try_bool(qdict, "all", false);
138 MigrationInfo *info;
139
140 info = qmp_query_migrate(NULL);
141
142 if (info->blocked_reasons) {
143 strList *reasons = info->blocked_reasons;
144 monitor_printf(mon, "Outgoing migration blocked:\n");
145 while (reasons) {
146 monitor_printf(mon, " %s\n", reasons->value);
147 reasons = reasons->next;
148 }
149 }
150
151 if (info->has_status) {
152 monitor_printf(mon, "Status: \t\t%s",
153 MigrationStatus_str(info->status));
154 if ((info->status == MIGRATION_STATUS_FAILED ||
155 info->status == MIGRATION_STATUS_POSTCOPY_PAUSED) &&
156 info->error_desc) {
157 monitor_printf(mon, " (%s)\n", info->error_desc);
158 } else {
159 monitor_printf(mon, "\n");
160 }
161
162 if (info->total_time) {
163 monitor_printf(mon, "Time (ms): \t\ttotal=%" PRIu64,
164 info->total_time);
165 if (info->has_setup_time) {
166 monitor_printf(mon, ", setup=%" PRIu64,
167 info->setup_time);
168 }
169 if (info->has_expected_downtime) {
170 monitor_printf(mon, ", exp_down=%" PRIu64,
171 info->expected_downtime);
172 }
173 if (info->has_downtime) {
174 monitor_printf(mon, ", down=%" PRIu64,
175 info->downtime);
176 }
177 monitor_printf(mon, "\n");
178 }
179 }
180
181 if (info->has_socket_address) {
182 SocketAddressList *addr;
183
184 monitor_printf(mon, "Sockets: [\n");
185
186 for (addr = info->socket_address; addr; addr = addr->next) {
187 char *s = socket_uri(addr->value);
188 monitor_printf(mon, "\t%s\n", s);
189 g_free(s);
190 }
191 monitor_printf(mon, "]\n");
192 }
193
194 if (info->ram) {
195 g_autofree char *str_psize = size_to_str(info->ram->page_size);
196 g_autofree char *str_total = size_to_str(info->ram->total);
197 g_autofree char *str_transferred = size_to_str(info->ram->transferred);
198 g_autofree char *str_remaining = size_to_str(info->ram->remaining);
199 g_autofree char *str_precopy = size_to_str(info->ram->precopy_bytes);
200 g_autofree char *str_multifd = size_to_str(info->ram->multifd_bytes);
201 g_autofree char *str_postcopy = size_to_str(info->ram->postcopy_bytes);
202
203 monitor_printf(mon, "RAM info:\n");
204 monitor_printf(mon, " Throughput (Mbps): \t%0.2f\n",
205 info->ram->mbps);
206 monitor_printf(mon, " Sizes: \t\tpagesize=%s, total=%s\n",
207 str_psize, str_total);
208 monitor_printf(mon, " Transfers: \t\ttransferred=%s, remain=%s\n",
209 str_transferred, str_remaining);
210 monitor_printf(mon, " Channels: \t\tprecopy=%s, "
211 "multifd=%s, postcopy=%s",
212 str_precopy, str_multifd, str_postcopy);
213
214 if (info->vfio) {
215 g_autofree char *str_vfio = size_to_str(info->vfio->transferred);
216
217 monitor_printf(mon, ", vfio=%s", str_vfio);
218 }
219 monitor_printf(mon, "\n");
220
221 monitor_printf(mon, " Page Types: \tnormal=%" PRIu64
222 ", zero=%" PRIu64 "\n",
223 info->ram->normal, info->ram->duplicate);
224 monitor_printf(mon, " Page Rates (pps): \ttransfer=%" PRIu64,
225 info->ram->pages_per_second);
226 if (info->ram->dirty_pages_rate) {
227 monitor_printf(mon, ", dirty=%" PRIu64,
228 info->ram->dirty_pages_rate);
229 }
230 monitor_printf(mon, "\n");
231
232 monitor_printf(mon, " Others: \t\tdirty_syncs=%" PRIu64,
233 info->ram->dirty_sync_count);
234 if (info->ram->postcopy_requests) {
235 monitor_printf(mon, ", postcopy_req=%" PRIu64,
236 info->ram->postcopy_requests);
237 }
238 if (info->ram->downtime_bytes) {
239 monitor_printf(mon, ", downtime_bytes=%" PRIu64,
240 info->ram->downtime_bytes);
241 }
242 if (info->ram->dirty_sync_missed_zero_copy) {
243 monitor_printf(mon, ", zerocopy_fallbacks=%" PRIu64,
244 info->ram->dirty_sync_missed_zero_copy);
245 }
246 monitor_printf(mon, "\n");
247 }
248
249 if (!show_all) {
250 goto out;
251 }
252
253 migration_global_dump(mon);
254
255 if (info->xbzrle_cache) {
256 monitor_printf(mon, "XBZRLE: size=%" PRIu64
257 ", transferred=%" PRIu64
258 ", pages=%" PRIu64
259 ", miss=%" PRIu64 "\n"
260 " miss_rate=%0.2f"
261 ", encode_rate=%0.2f"
262 ", overflow=%" PRIu64 "\n",
263 info->xbzrle_cache->cache_size,
264 info->xbzrle_cache->bytes,
265 info->xbzrle_cache->pages,
266 info->xbzrle_cache->cache_miss,
267 info->xbzrle_cache->cache_miss_rate,
268 info->xbzrle_cache->encoding_rate,
269 info->xbzrle_cache->overflow);
270 }
271
272 if (info->has_cpu_throttle_percentage) {
273 monitor_printf(mon, "CPU Throttle (%%): %" PRIu64 "\n",
274 info->cpu_throttle_percentage);
275 }
276
277 if (info->has_dirty_limit_throttle_time_per_round) {
278 monitor_printf(mon, "Dirty-limit Throttle (us): %" PRIu64 "\n",
279 info->dirty_limit_throttle_time_per_round);
280 }
281
282 if (info->has_dirty_limit_ring_full_time) {
283 monitor_printf(mon, "Dirty-limit Ring Full (us): %" PRIu64 "\n",
284 info->dirty_limit_ring_full_time);
285 }
286
287 migration_dump_blocktime(mon, info);
288 out:
289 qapi_free_MigrationInfo(info);
290 }
291
hmp_info_migrate_capabilities(Monitor * mon,const QDict * qdict)292 void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
293 {
294 MigrationCapabilityStatusList *caps, *cap;
295
296 caps = qmp_query_migrate_capabilities(NULL);
297
298 if (caps) {
299 for (cap = caps; cap; cap = cap->next) {
300 monitor_printf(mon, "%s: %s\n",
301 MigrationCapability_str(cap->value->capability),
302 cap->value->state ? "on" : "off");
303 }
304 }
305
306 qapi_free_MigrationCapabilityStatusList(caps);
307 }
308
hmp_info_migrate_parameters(Monitor * mon,const QDict * qdict)309 void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
310 {
311 MigrationParameters *params;
312
313 params = qmp_query_migrate_parameters(NULL);
314
315 if (params) {
316 monitor_printf(mon, "%s: %" PRIu64 " ms\n",
317 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_INITIAL),
318 params->announce_initial);
319 monitor_printf(mon, "%s: %" PRIu64 " ms\n",
320 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_MAX),
321 params->announce_max);
322 monitor_printf(mon, "%s: %" PRIu64 "\n",
323 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_ROUNDS),
324 params->announce_rounds);
325 monitor_printf(mon, "%s: %" PRIu64 " ms\n",
326 MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_STEP),
327 params->announce_step);
328 assert(params->has_throttle_trigger_threshold);
329 monitor_printf(mon, "%s: %u\n",
330 MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD),
331 params->throttle_trigger_threshold);
332 assert(params->has_cpu_throttle_initial);
333 monitor_printf(mon, "%s: %u\n",
334 MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL),
335 params->cpu_throttle_initial);
336 assert(params->has_cpu_throttle_increment);
337 monitor_printf(mon, "%s: %u\n",
338 MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT),
339 params->cpu_throttle_increment);
340 assert(params->has_cpu_throttle_tailslow);
341 monitor_printf(mon, "%s: %s\n",
342 MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW),
343 params->cpu_throttle_tailslow ? "on" : "off");
344 assert(params->has_max_cpu_throttle);
345 monitor_printf(mon, "%s: %u\n",
346 MigrationParameter_str(MIGRATION_PARAMETER_MAX_CPU_THROTTLE),
347 params->max_cpu_throttle);
348 assert(params->tls_creds);
349 monitor_printf(mon, "%s: '%s'\n",
350 MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS),
351 params->tls_creds);
352 assert(params->tls_hostname);
353 monitor_printf(mon, "%s: '%s'\n",
354 MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME),
355 params->tls_hostname);
356 assert(params->has_max_bandwidth);
357 monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
358 MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH),
359 params->max_bandwidth);
360 assert(params->has_avail_switchover_bandwidth);
361 monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
362 MigrationParameter_str(MIGRATION_PARAMETER_AVAIL_SWITCHOVER_BANDWIDTH),
363 params->avail_switchover_bandwidth);
364 assert(params->has_downtime_limit);
365 monitor_printf(mon, "%s: %" PRIu64 " ms\n",
366 MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT),
367 params->downtime_limit);
368 assert(params->has_x_checkpoint_delay);
369 monitor_printf(mon, "%s: %u ms\n",
370 MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY),
371 params->x_checkpoint_delay);
372 monitor_printf(mon, "%s: %u\n",
373 MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS),
374 params->multifd_channels);
375 monitor_printf(mon, "%s: %s\n",
376 MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION),
377 MultiFDCompression_str(params->multifd_compression));
378 assert(params->has_zero_page_detection);
379 monitor_printf(mon, "%s: %s\n",
380 MigrationParameter_str(MIGRATION_PARAMETER_ZERO_PAGE_DETECTION),
381 qapi_enum_lookup(&ZeroPageDetection_lookup,
382 params->zero_page_detection));
383 monitor_printf(mon, "%s: %" PRIu64 " bytes\n",
384 MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
385 params->xbzrle_cache_size);
386 monitor_printf(mon, "%s: %" PRIu64 "\n",
387 MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
388 params->max_postcopy_bandwidth);
389 monitor_printf(mon, "%s: '%s'\n",
390 MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
391 params->tls_authz);
392
393 if (params->has_block_bitmap_mapping) {
394 const BitmapMigrationNodeAliasList *bmnal;
395
396 monitor_printf(mon, "%s:\n",
397 MigrationParameter_str(
398 MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING));
399
400 for (bmnal = params->block_bitmap_mapping;
401 bmnal;
402 bmnal = bmnal->next)
403 {
404 const BitmapMigrationNodeAlias *bmna = bmnal->value;
405 const BitmapMigrationBitmapAliasList *bmbal;
406
407 monitor_printf(mon, " '%s' -> '%s'\n",
408 bmna->node_name, bmna->alias);
409
410 for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) {
411 const BitmapMigrationBitmapAlias *bmba = bmbal->value;
412
413 monitor_printf(mon, " '%s' -> '%s'\n",
414 bmba->name, bmba->alias);
415 }
416 }
417 }
418
419 monitor_printf(mon, "%s: %" PRIu64 " ms\n",
420 MigrationParameter_str(MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD),
421 params->x_vcpu_dirty_limit_period);
422
423 monitor_printf(mon, "%s: %" PRIu64 " MB/s\n",
424 MigrationParameter_str(MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT),
425 params->vcpu_dirty_limit);
426
427 assert(params->has_mode);
428 monitor_printf(mon, "%s: %s\n",
429 MigrationParameter_str(MIGRATION_PARAMETER_MODE),
430 qapi_enum_lookup(&MigMode_lookup, params->mode));
431
432 if (params->has_direct_io) {
433 monitor_printf(mon, "%s: %s\n",
434 MigrationParameter_str(
435 MIGRATION_PARAMETER_DIRECT_IO),
436 params->direct_io ? "on" : "off");
437 }
438 }
439
440 qapi_free_MigrationParameters(params);
441 }
442
hmp_loadvm(Monitor * mon,const QDict * qdict)443 void hmp_loadvm(Monitor *mon, const QDict *qdict)
444 {
445 RunState saved_state = runstate_get();
446
447 const char *name = qdict_get_str(qdict, "name");
448 Error *err = NULL;
449
450 vm_stop(RUN_STATE_RESTORE_VM);
451
452 if (load_snapshot(name, NULL, false, NULL, &err)) {
453 load_snapshot_resume(saved_state);
454 }
455
456 hmp_handle_error(mon, err);
457 }
458
hmp_savevm(Monitor * mon,const QDict * qdict)459 void hmp_savevm(Monitor *mon, const QDict *qdict)
460 {
461 Error *err = NULL;
462
463 save_snapshot(qdict_get_try_str(qdict, "name"),
464 true, NULL, false, NULL, &err);
465 hmp_handle_error(mon, err);
466 }
467
hmp_delvm(Monitor * mon,const QDict * qdict)468 void hmp_delvm(Monitor *mon, const QDict *qdict)
469 {
470 Error *err = NULL;
471 const char *name = qdict_get_str(qdict, "name");
472
473 delete_snapshot(name, false, NULL, &err);
474 hmp_handle_error(mon, err);
475 }
476
hmp_migrate_cancel(Monitor * mon,const QDict * qdict)477 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
478 {
479 qmp_migrate_cancel(NULL);
480 }
481
hmp_migrate_continue(Monitor * mon,const QDict * qdict)482 void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
483 {
484 Error *err = NULL;
485 const char *state = qdict_get_str(qdict, "state");
486 int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
487
488 if (val >= 0) {
489 qmp_migrate_continue(val, &err);
490 }
491
492 hmp_handle_error(mon, err);
493 }
494
hmp_migrate_incoming(Monitor * mon,const QDict * qdict)495 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
496 {
497 Error *err = NULL;
498 const char *uri = qdict_get_str(qdict, "uri");
499 MigrationChannelList *caps = NULL;
500 g_autoptr(MigrationChannel) channel = NULL;
501
502 if (!migrate_uri_parse(uri, &channel, &err)) {
503 goto end;
504 }
505 QAPI_LIST_PREPEND(caps, g_steal_pointer(&channel));
506
507 qmp_migrate_incoming(NULL, true, caps, true, false, &err);
508 qapi_free_MigrationChannelList(caps);
509
510 end:
511 hmp_handle_error(mon, err);
512 }
513
hmp_migrate_recover(Monitor * mon,const QDict * qdict)514 void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
515 {
516 Error *err = NULL;
517 const char *uri = qdict_get_str(qdict, "uri");
518
519 qmp_migrate_recover(uri, &err);
520
521 hmp_handle_error(mon, err);
522 }
523
hmp_migrate_pause(Monitor * mon,const QDict * qdict)524 void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
525 {
526 Error *err = NULL;
527
528 qmp_migrate_pause(&err);
529
530 hmp_handle_error(mon, err);
531 }
532
533
hmp_migrate_set_capability(Monitor * mon,const QDict * qdict)534 void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
535 {
536 const char *cap = qdict_get_str(qdict, "capability");
537 bool state = qdict_get_bool(qdict, "state");
538 Error *err = NULL;
539 MigrationCapabilityStatusList *caps = NULL;
540 MigrationCapabilityStatus *value;
541 int val;
542
543 val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err);
544 if (val < 0) {
545 goto end;
546 }
547
548 value = g_malloc0(sizeof(*value));
549 value->capability = val;
550 value->state = state;
551 QAPI_LIST_PREPEND(caps, value);
552 qmp_migrate_set_capabilities(caps, &err);
553 qapi_free_MigrationCapabilityStatusList(caps);
554
555 end:
556 hmp_handle_error(mon, err);
557 }
558
hmp_migrate_set_parameter(Monitor * mon,const QDict * qdict)559 void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
560 {
561 const char *param = qdict_get_str(qdict, "parameter");
562 const char *valuestr = qdict_get_str(qdict, "value");
563 Visitor *v = string_input_visitor_new(valuestr);
564 MigrateSetParameters *p = g_new0(MigrateSetParameters, 1);
565 uint64_t valuebw = 0;
566 uint64_t cache_size;
567 Error *err = NULL;
568 int val, ret;
569
570 val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err);
571 if (val < 0) {
572 goto cleanup;
573 }
574
575 switch (val) {
576 case MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD:
577 p->has_throttle_trigger_threshold = true;
578 visit_type_uint8(v, param, &p->throttle_trigger_threshold, &err);
579 break;
580 case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL:
581 p->has_cpu_throttle_initial = true;
582 visit_type_uint8(v, param, &p->cpu_throttle_initial, &err);
583 break;
584 case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT:
585 p->has_cpu_throttle_increment = true;
586 visit_type_uint8(v, param, &p->cpu_throttle_increment, &err);
587 break;
588 case MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW:
589 p->has_cpu_throttle_tailslow = true;
590 visit_type_bool(v, param, &p->cpu_throttle_tailslow, &err);
591 break;
592 case MIGRATION_PARAMETER_MAX_CPU_THROTTLE:
593 p->has_max_cpu_throttle = true;
594 visit_type_uint8(v, param, &p->max_cpu_throttle, &err);
595 break;
596 case MIGRATION_PARAMETER_TLS_CREDS:
597 p->tls_creds = g_new0(StrOrNull, 1);
598 p->tls_creds->type = QTYPE_QSTRING;
599 visit_type_str(v, param, &p->tls_creds->u.s, &err);
600 break;
601 case MIGRATION_PARAMETER_TLS_HOSTNAME:
602 p->tls_hostname = g_new0(StrOrNull, 1);
603 p->tls_hostname->type = QTYPE_QSTRING;
604 visit_type_str(v, param, &p->tls_hostname->u.s, &err);
605 break;
606 case MIGRATION_PARAMETER_TLS_AUTHZ:
607 p->tls_authz = g_new0(StrOrNull, 1);
608 p->tls_authz->type = QTYPE_QSTRING;
609 visit_type_str(v, param, &p->tls_authz->u.s, &err);
610 break;
611 case MIGRATION_PARAMETER_MAX_BANDWIDTH:
612 p->has_max_bandwidth = true;
613 /*
614 * Can't use visit_type_size() here, because it
615 * defaults to Bytes rather than Mebibytes.
616 */
617 ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
618 if (ret < 0 || valuebw > INT64_MAX
619 || (size_t)valuebw != valuebw) {
620 error_setg(&err, "Invalid size %s", valuestr);
621 break;
622 }
623 p->max_bandwidth = valuebw;
624 break;
625 case MIGRATION_PARAMETER_AVAIL_SWITCHOVER_BANDWIDTH:
626 p->has_avail_switchover_bandwidth = true;
627 ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
628 if (ret < 0 || valuebw > INT64_MAX
629 || (size_t)valuebw != valuebw) {
630 error_setg(&err, "Invalid size %s", valuestr);
631 break;
632 }
633 p->avail_switchover_bandwidth = valuebw;
634 break;
635 case MIGRATION_PARAMETER_DOWNTIME_LIMIT:
636 p->has_downtime_limit = true;
637 visit_type_size(v, param, &p->downtime_limit, &err);
638 break;
639 case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY:
640 p->has_x_checkpoint_delay = true;
641 visit_type_uint32(v, param, &p->x_checkpoint_delay, &err);
642 break;
643 case MIGRATION_PARAMETER_MULTIFD_CHANNELS:
644 p->has_multifd_channels = true;
645 visit_type_uint8(v, param, &p->multifd_channels, &err);
646 break;
647 case MIGRATION_PARAMETER_MULTIFD_COMPRESSION:
648 p->has_multifd_compression = true;
649 visit_type_MultiFDCompression(v, param, &p->multifd_compression,
650 &err);
651 break;
652 case MIGRATION_PARAMETER_MULTIFD_ZLIB_LEVEL:
653 p->has_multifd_zlib_level = true;
654 visit_type_uint8(v, param, &p->multifd_zlib_level, &err);
655 break;
656 case MIGRATION_PARAMETER_MULTIFD_QATZIP_LEVEL:
657 p->has_multifd_qatzip_level = true;
658 visit_type_uint8(v, param, &p->multifd_qatzip_level, &err);
659 break;
660 case MIGRATION_PARAMETER_MULTIFD_ZSTD_LEVEL:
661 p->has_multifd_zstd_level = true;
662 visit_type_uint8(v, param, &p->multifd_zstd_level, &err);
663 break;
664 case MIGRATION_PARAMETER_ZERO_PAGE_DETECTION:
665 p->has_zero_page_detection = true;
666 visit_type_ZeroPageDetection(v, param, &p->zero_page_detection, &err);
667 break;
668 case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE:
669 p->has_xbzrle_cache_size = true;
670 if (!visit_type_size(v, param, &cache_size, &err)) {
671 break;
672 }
673 if (cache_size > INT64_MAX || (size_t)cache_size != cache_size) {
674 error_setg(&err, "Invalid size %s", valuestr);
675 break;
676 }
677 p->xbzrle_cache_size = cache_size;
678 break;
679 case MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH:
680 p->has_max_postcopy_bandwidth = true;
681 visit_type_size(v, param, &p->max_postcopy_bandwidth, &err);
682 break;
683 case MIGRATION_PARAMETER_ANNOUNCE_INITIAL:
684 p->has_announce_initial = true;
685 visit_type_size(v, param, &p->announce_initial, &err);
686 break;
687 case MIGRATION_PARAMETER_ANNOUNCE_MAX:
688 p->has_announce_max = true;
689 visit_type_size(v, param, &p->announce_max, &err);
690 break;
691 case MIGRATION_PARAMETER_ANNOUNCE_ROUNDS:
692 p->has_announce_rounds = true;
693 visit_type_size(v, param, &p->announce_rounds, &err);
694 break;
695 case MIGRATION_PARAMETER_ANNOUNCE_STEP:
696 p->has_announce_step = true;
697 visit_type_size(v, param, &p->announce_step, &err);
698 break;
699 case MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING:
700 error_setg(&err, "The block-bitmap-mapping parameter can only be set "
701 "through QMP");
702 break;
703 case MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD:
704 p->has_x_vcpu_dirty_limit_period = true;
705 visit_type_size(v, param, &p->x_vcpu_dirty_limit_period, &err);
706 break;
707 case MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT:
708 p->has_vcpu_dirty_limit = true;
709 visit_type_size(v, param, &p->vcpu_dirty_limit, &err);
710 break;
711 case MIGRATION_PARAMETER_MODE:
712 p->has_mode = true;
713 visit_type_MigMode(v, param, &p->mode, &err);
714 break;
715 case MIGRATION_PARAMETER_DIRECT_IO:
716 p->has_direct_io = true;
717 visit_type_bool(v, param, &p->direct_io, &err);
718 break;
719 default:
720 g_assert_not_reached();
721 }
722
723 if (err) {
724 goto cleanup;
725 }
726
727 qmp_migrate_set_parameters(p, &err);
728
729 cleanup:
730 qapi_free_MigrateSetParameters(p);
731 visit_free(v);
732 hmp_handle_error(mon, err);
733 }
734
hmp_migrate_start_postcopy(Monitor * mon,const QDict * qdict)735 void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict)
736 {
737 Error *err = NULL;
738 qmp_migrate_start_postcopy(&err);
739 hmp_handle_error(mon, err);
740 }
741
742 #ifdef CONFIG_REPLICATION
hmp_x_colo_lost_heartbeat(Monitor * mon,const QDict * qdict)743 void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict)
744 {
745 Error *err = NULL;
746
747 qmp_x_colo_lost_heartbeat(&err);
748 hmp_handle_error(mon, err);
749 }
750 #endif
751
752 typedef struct HMPMigrationStatus {
753 QEMUTimer *timer;
754 Monitor *mon;
755 } HMPMigrationStatus;
756
hmp_migrate_status_cb(void * opaque)757 static void hmp_migrate_status_cb(void *opaque)
758 {
759 HMPMigrationStatus *status = opaque;
760 MigrationInfo *info;
761
762 info = qmp_query_migrate(NULL);
763 if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE ||
764 info->status == MIGRATION_STATUS_SETUP) {
765 timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
766 } else {
767 if (info->error_desc) {
768 error_report("%s", info->error_desc);
769 }
770 monitor_resume(status->mon);
771 timer_free(status->timer);
772 g_free(status);
773 }
774
775 qapi_free_MigrationInfo(info);
776 }
777
hmp_migrate(Monitor * mon,const QDict * qdict)778 void hmp_migrate(Monitor *mon, const QDict *qdict)
779 {
780 bool detach = qdict_get_try_bool(qdict, "detach", false);
781 bool resume = qdict_get_try_bool(qdict, "resume", false);
782 const char *uri = qdict_get_str(qdict, "uri");
783 Error *err = NULL;
784 g_autoptr(MigrationChannelList) caps = NULL;
785 g_autoptr(MigrationChannel) channel = NULL;
786
787 if (!migrate_uri_parse(uri, &channel, &err)) {
788 hmp_handle_error(mon, err);
789 return;
790 }
791 QAPI_LIST_PREPEND(caps, g_steal_pointer(&channel));
792
793 qmp_migrate(NULL, true, caps, false, false, true, resume, &err);
794 if (hmp_handle_error(mon, err)) {
795 return;
796 }
797
798 if (!detach) {
799 HMPMigrationStatus *status;
800
801 if (monitor_suspend(mon) < 0) {
802 monitor_printf(mon, "terminal does not allow synchronous "
803 "migration, continuing detached\n");
804 return;
805 }
806
807 status = g_malloc0(sizeof(*status));
808 status->mon = mon;
809 status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb,
810 status);
811 timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
812 }
813 }
814
migrate_set_capability_completion(ReadLineState * rs,int nb_args,const char * str)815 void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
816 const char *str)
817 {
818 size_t len;
819
820 len = strlen(str);
821 readline_set_completion_index(rs, len);
822 if (nb_args == 2) {
823 int i;
824 for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
825 readline_add_completion_of(rs, str, MigrationCapability_str(i));
826 }
827 } else if (nb_args == 3) {
828 readline_add_completion_of(rs, str, "on");
829 readline_add_completion_of(rs, str, "off");
830 }
831 }
832
migrate_set_parameter_completion(ReadLineState * rs,int nb_args,const char * str)833 void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
834 const char *str)
835 {
836 size_t len;
837
838 len = strlen(str);
839 readline_set_completion_index(rs, len);
840 if (nb_args == 2) {
841 int i;
842 for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) {
843 readline_add_completion_of(rs, str, MigrationParameter_str(i));
844 }
845 }
846 }
847
vm_completion(ReadLineState * rs,const char * str)848 static void vm_completion(ReadLineState *rs, const char *str)
849 {
850 size_t len;
851 BlockDriverState *bs;
852 BdrvNextIterator it;
853
854 GRAPH_RDLOCK_GUARD_MAINLOOP();
855
856 len = strlen(str);
857 readline_set_completion_index(rs, len);
858
859 for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
860 SnapshotInfoList *snapshots, *snapshot;
861 bool ok = false;
862
863 if (bdrv_can_snapshot(bs)) {
864 ok = bdrv_query_snapshot_info_list(bs, &snapshots, NULL) == 0;
865 }
866 if (!ok) {
867 continue;
868 }
869
870 snapshot = snapshots;
871 while (snapshot) {
872 readline_add_completion_of(rs, str, snapshot->value->name);
873 readline_add_completion_of(rs, str, snapshot->value->id);
874 snapshot = snapshot->next;
875 }
876 qapi_free_SnapshotInfoList(snapshots);
877 }
878
879 }
880
delvm_completion(ReadLineState * rs,int nb_args,const char * str)881 void delvm_completion(ReadLineState *rs, int nb_args, const char *str)
882 {
883 if (nb_args == 2) {
884 vm_completion(rs, str);
885 }
886 }
887
loadvm_completion(ReadLineState * rs,int nb_args,const char * str)888 void loadvm_completion(ReadLineState *rs, int nb_args, const char *str)
889 {
890 if (nb_args == 2) {
891 vm_completion(rs, str);
892 }
893 }
894