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