xref: /openbmc/qemu/monitor/hmp-cmds.c (revision 52cafcea)
1 /*
2  * Human Monitor Interface commands
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 "monitor/hmp.h"
18 #include "net/net.h"
19 #include "sysemu/runstate.h"
20 #include "qemu/sockets.h"
21 #include "qemu/help_option.h"
22 #include "monitor/monitor.h"
23 #include "qapi/error.h"
24 #include "qapi/clone-visitor.h"
25 #include "qapi/qapi-builtin-visit.h"
26 #include "qapi/qapi-commands-control.h"
27 #include "qapi/qapi-commands-migration.h"
28 #include "qapi/qapi-commands-misc.h"
29 #include "qapi/qapi-commands-net.h"
30 #include "qapi/qapi-commands-run-state.h"
31 #include "qapi/qapi-commands-stats.h"
32 #include "qapi/qapi-commands-tpm.h"
33 #include "qapi/qapi-commands-virtio.h"
34 #include "qapi/qapi-visit-net.h"
35 #include "qapi/qapi-visit-migration.h"
36 #include "qapi/qmp/qdict.h"
37 #include "qapi/qmp/qerror.h"
38 #include "qapi/string-input-visitor.h"
39 #include "qapi/string-output-visitor.h"
40 #include "qemu/cutils.h"
41 #include "qemu/error-report.h"
42 #include "hw/core/cpu.h"
43 #include "hw/intc/intc.h"
44 #include "migration/snapshot.h"
45 #include "migration/misc.h"
46 
47 bool hmp_handle_error(Monitor *mon, Error *err)
48 {
49     if (err) {
50         error_reportf_err(err, "Error: ");
51         return true;
52     }
53     return false;
54 }
55 
56 /*
57  * Produce a strList from a comma separated list.
58  * A NULL or empty input string return NULL.
59  */
60 static strList *strList_from_comma_list(const char *in)
61 {
62     strList *res = NULL;
63     strList **tail = &res;
64 
65     while (in && in[0]) {
66         char *comma = strchr(in, ',');
67         char *value;
68 
69         if (comma) {
70             value = g_strndup(in, comma - in);
71             in = comma + 1; /* skip the , */
72         } else {
73             value = g_strdup(in);
74             in = NULL;
75         }
76         QAPI_LIST_APPEND(tail, value);
77     }
78 
79     return res;
80 }
81 
82 void hmp_info_name(Monitor *mon, const QDict *qdict)
83 {
84     NameInfo *info;
85 
86     info = qmp_query_name(NULL);
87     if (info->name) {
88         monitor_printf(mon, "%s\n", info->name);
89     }
90     qapi_free_NameInfo(info);
91 }
92 
93 void hmp_info_version(Monitor *mon, const QDict *qdict)
94 {
95     VersionInfo *info;
96 
97     info = qmp_query_version(NULL);
98 
99     monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
100                    info->qemu->major, info->qemu->minor, info->qemu->micro,
101                    info->package);
102 
103     qapi_free_VersionInfo(info);
104 }
105 
106 void hmp_info_status(Monitor *mon, const QDict *qdict)
107 {
108     StatusInfo *info;
109 
110     info = qmp_query_status(NULL);
111 
112     monitor_printf(mon, "VM status: %s%s",
113                    info->running ? "running" : "paused",
114                    info->singlestep ? " (single step mode)" : "");
115 
116     if (!info->running && info->status != RUN_STATE_PAUSED) {
117         monitor_printf(mon, " (%s)", RunState_str(info->status));
118     }
119 
120     monitor_printf(mon, "\n");
121 
122     qapi_free_StatusInfo(info);
123 }
124 
125 void hmp_info_migrate(Monitor *mon, const QDict *qdict)
126 {
127     MigrationInfo *info;
128 
129     info = qmp_query_migrate(NULL);
130 
131     migration_global_dump(mon);
132 
133     if (info->blocked_reasons) {
134         strList *reasons = info->blocked_reasons;
135         monitor_printf(mon, "Outgoing migration blocked:\n");
136         while (reasons) {
137             monitor_printf(mon, "  %s\n", reasons->value);
138             reasons = reasons->next;
139         }
140     }
141 
142     if (info->has_status) {
143         monitor_printf(mon, "Migration status: %s",
144                        MigrationStatus_str(info->status));
145         if (info->status == MIGRATION_STATUS_FAILED && info->error_desc) {
146             monitor_printf(mon, " (%s)\n", info->error_desc);
147         } else {
148             monitor_printf(mon, "\n");
149         }
150 
151         monitor_printf(mon, "total time: %" PRIu64 " ms\n",
152                        info->total_time);
153         if (info->has_expected_downtime) {
154             monitor_printf(mon, "expected downtime: %" PRIu64 " ms\n",
155                            info->expected_downtime);
156         }
157         if (info->has_downtime) {
158             monitor_printf(mon, "downtime: %" PRIu64 " ms\n",
159                            info->downtime);
160         }
161         if (info->has_setup_time) {
162             monitor_printf(mon, "setup: %" PRIu64 " ms\n",
163                            info->setup_time);
164         }
165     }
166 
167     if (info->ram) {
168         monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n",
169                        info->ram->transferred >> 10);
170         monitor_printf(mon, "throughput: %0.2f mbps\n",
171                        info->ram->mbps);
172         monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n",
173                        info->ram->remaining >> 10);
174         monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n",
175                        info->ram->total >> 10);
176         monitor_printf(mon, "duplicate: %" PRIu64 " pages\n",
177                        info->ram->duplicate);
178         monitor_printf(mon, "skipped: %" PRIu64 " pages\n",
179                        info->ram->skipped);
180         monitor_printf(mon, "normal: %" PRIu64 " pages\n",
181                        info->ram->normal);
182         monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
183                        info->ram->normal_bytes >> 10);
184         monitor_printf(mon, "dirty sync count: %" PRIu64 "\n",
185                        info->ram->dirty_sync_count);
186         monitor_printf(mon, "page size: %" PRIu64 " kbytes\n",
187                        info->ram->page_size >> 10);
188         monitor_printf(mon, "multifd bytes: %" PRIu64 " kbytes\n",
189                        info->ram->multifd_bytes >> 10);
190         monitor_printf(mon, "pages-per-second: %" PRIu64 "\n",
191                        info->ram->pages_per_second);
192 
193         if (info->ram->dirty_pages_rate) {
194             monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
195                            info->ram->dirty_pages_rate);
196         }
197         if (info->ram->postcopy_requests) {
198             monitor_printf(mon, "postcopy request count: %" PRIu64 "\n",
199                            info->ram->postcopy_requests);
200         }
201         if (info->ram->precopy_bytes) {
202             monitor_printf(mon, "precopy ram: %" PRIu64 " kbytes\n",
203                            info->ram->precopy_bytes >> 10);
204         }
205         if (info->ram->downtime_bytes) {
206             monitor_printf(mon, "downtime ram: %" PRIu64 " kbytes\n",
207                            info->ram->downtime_bytes >> 10);
208         }
209         if (info->ram->postcopy_bytes) {
210             monitor_printf(mon, "postcopy ram: %" PRIu64 " kbytes\n",
211                            info->ram->postcopy_bytes >> 10);
212         }
213         if (info->ram->dirty_sync_missed_zero_copy) {
214             monitor_printf(mon,
215                            "Zero-copy-send fallbacks happened: %" PRIu64 " times\n",
216                            info->ram->dirty_sync_missed_zero_copy);
217         }
218     }
219 
220     if (info->disk) {
221         monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n",
222                        info->disk->transferred >> 10);
223         monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n",
224                        info->disk->remaining >> 10);
225         monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n",
226                        info->disk->total >> 10);
227     }
228 
229     if (info->xbzrle_cache) {
230         monitor_printf(mon, "cache size: %" PRIu64 " bytes\n",
231                        info->xbzrle_cache->cache_size);
232         monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n",
233                        info->xbzrle_cache->bytes >> 10);
234         monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
235                        info->xbzrle_cache->pages);
236         monitor_printf(mon, "xbzrle cache miss: %" PRIu64 " pages\n",
237                        info->xbzrle_cache->cache_miss);
238         monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n",
239                        info->xbzrle_cache->cache_miss_rate);
240         monitor_printf(mon, "xbzrle encoding rate: %0.2f\n",
241                        info->xbzrle_cache->encoding_rate);
242         monitor_printf(mon, "xbzrle overflow: %" PRIu64 "\n",
243                        info->xbzrle_cache->overflow);
244     }
245 
246     if (info->compression) {
247         monitor_printf(mon, "compression pages: %" PRIu64 " pages\n",
248                        info->compression->pages);
249         monitor_printf(mon, "compression busy: %" PRIu64 "\n",
250                        info->compression->busy);
251         monitor_printf(mon, "compression busy rate: %0.2f\n",
252                        info->compression->busy_rate);
253         monitor_printf(mon, "compressed size: %" PRIu64 " kbytes\n",
254                        info->compression->compressed_size >> 10);
255         monitor_printf(mon, "compression rate: %0.2f\n",
256                        info->compression->compression_rate);
257     }
258 
259     if (info->has_cpu_throttle_percentage) {
260         monitor_printf(mon, "cpu throttle percentage: %" PRIu64 "\n",
261                        info->cpu_throttle_percentage);
262     }
263 
264     if (info->has_postcopy_blocktime) {
265         monitor_printf(mon, "postcopy blocktime: %u\n",
266                        info->postcopy_blocktime);
267     }
268 
269     if (info->has_postcopy_vcpu_blocktime) {
270         Visitor *v;
271         char *str;
272         v = string_output_visitor_new(false, &str);
273         visit_type_uint32List(v, NULL, &info->postcopy_vcpu_blocktime,
274                               &error_abort);
275         visit_complete(v, &str);
276         monitor_printf(mon, "postcopy vcpu blocktime: %s\n", str);
277         g_free(str);
278         visit_free(v);
279     }
280     if (info->has_socket_address) {
281         SocketAddressList *addr;
282 
283         monitor_printf(mon, "socket address: [\n");
284 
285         for (addr = info->socket_address; addr; addr = addr->next) {
286             char *s = socket_uri(addr->value);
287             monitor_printf(mon, "\t%s\n", s);
288             g_free(s);
289         }
290         monitor_printf(mon, "]\n");
291     }
292 
293     if (info->vfio) {
294         monitor_printf(mon, "vfio device transferred: %" PRIu64 " kbytes\n",
295                        info->vfio->transferred >> 10);
296     }
297 
298     qapi_free_MigrationInfo(info);
299 }
300 
301 void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
302 {
303     MigrationCapabilityStatusList *caps, *cap;
304 
305     caps = qmp_query_migrate_capabilities(NULL);
306 
307     if (caps) {
308         for (cap = caps; cap; cap = cap->next) {
309             monitor_printf(mon, "%s: %s\n",
310                            MigrationCapability_str(cap->value->capability),
311                            cap->value->state ? "on" : "off");
312         }
313     }
314 
315     qapi_free_MigrationCapabilityStatusList(caps);
316 }
317 
318 void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
319 {
320     MigrationParameters *params;
321 
322     params = qmp_query_migrate_parameters(NULL);
323 
324     if (params) {
325         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
326             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_INITIAL),
327             params->announce_initial);
328         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
329             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_MAX),
330             params->announce_max);
331         monitor_printf(mon, "%s: %" PRIu64 "\n",
332             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_ROUNDS),
333             params->announce_rounds);
334         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
335             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_STEP),
336             params->announce_step);
337         assert(params->has_compress_level);
338         monitor_printf(mon, "%s: %u\n",
339             MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_LEVEL),
340             params->compress_level);
341         assert(params->has_compress_threads);
342         monitor_printf(mon, "%s: %u\n",
343             MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_THREADS),
344             params->compress_threads);
345         assert(params->has_compress_wait_thread);
346         monitor_printf(mon, "%s: %s\n",
347             MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_WAIT_THREAD),
348             params->compress_wait_thread ? "on" : "off");
349         assert(params->has_decompress_threads);
350         monitor_printf(mon, "%s: %u\n",
351             MigrationParameter_str(MIGRATION_PARAMETER_DECOMPRESS_THREADS),
352             params->decompress_threads);
353         assert(params->has_throttle_trigger_threshold);
354         monitor_printf(mon, "%s: %u\n",
355             MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD),
356             params->throttle_trigger_threshold);
357         assert(params->has_cpu_throttle_initial);
358         monitor_printf(mon, "%s: %u\n",
359             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL),
360             params->cpu_throttle_initial);
361         assert(params->has_cpu_throttle_increment);
362         monitor_printf(mon, "%s: %u\n",
363             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT),
364             params->cpu_throttle_increment);
365         assert(params->has_cpu_throttle_tailslow);
366         monitor_printf(mon, "%s: %s\n",
367             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW),
368             params->cpu_throttle_tailslow ? "on" : "off");
369         assert(params->has_max_cpu_throttle);
370         monitor_printf(mon, "%s: %u\n",
371             MigrationParameter_str(MIGRATION_PARAMETER_MAX_CPU_THROTTLE),
372             params->max_cpu_throttle);
373         assert(params->tls_creds);
374         monitor_printf(mon, "%s: '%s'\n",
375             MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS),
376             params->tls_creds);
377         assert(params->tls_hostname);
378         monitor_printf(mon, "%s: '%s'\n",
379             MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME),
380             params->tls_hostname);
381         assert(params->has_max_bandwidth);
382         monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
383             MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH),
384             params->max_bandwidth);
385         assert(params->has_downtime_limit);
386         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
387             MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT),
388             params->downtime_limit);
389         assert(params->has_x_checkpoint_delay);
390         monitor_printf(mon, "%s: %u ms\n",
391             MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY),
392             params->x_checkpoint_delay);
393         assert(params->has_block_incremental);
394         monitor_printf(mon, "%s: %s\n",
395             MigrationParameter_str(MIGRATION_PARAMETER_BLOCK_INCREMENTAL),
396             params->block_incremental ? "on" : "off");
397         monitor_printf(mon, "%s: %u\n",
398             MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS),
399             params->multifd_channels);
400         monitor_printf(mon, "%s: %s\n",
401             MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION),
402             MultiFDCompression_str(params->multifd_compression));
403         monitor_printf(mon, "%s: %" PRIu64 " bytes\n",
404             MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
405             params->xbzrle_cache_size);
406         monitor_printf(mon, "%s: %" PRIu64 "\n",
407             MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
408             params->max_postcopy_bandwidth);
409         monitor_printf(mon, "%s: '%s'\n",
410             MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
411             params->tls_authz);
412 
413         if (params->has_block_bitmap_mapping) {
414             const BitmapMigrationNodeAliasList *bmnal;
415 
416             monitor_printf(mon, "%s:\n",
417                            MigrationParameter_str(
418                                MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING));
419 
420             for (bmnal = params->block_bitmap_mapping;
421                  bmnal;
422                  bmnal = bmnal->next)
423             {
424                 const BitmapMigrationNodeAlias *bmna = bmnal->value;
425                 const BitmapMigrationBitmapAliasList *bmbal;
426 
427                 monitor_printf(mon, "  '%s' -> '%s'\n",
428                                bmna->node_name, bmna->alias);
429 
430                 for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) {
431                     const BitmapMigrationBitmapAlias *bmba = bmbal->value;
432 
433                     monitor_printf(mon, "    '%s' -> '%s'\n",
434                                    bmba->name, bmba->alias);
435                 }
436             }
437         }
438     }
439 
440     qapi_free_MigrationParameters(params);
441 }
442 
443 static int hmp_info_pic_foreach(Object *obj, void *opaque)
444 {
445     InterruptStatsProvider *intc;
446     InterruptStatsProviderClass *k;
447     Monitor *mon = opaque;
448 
449     if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
450         intc = INTERRUPT_STATS_PROVIDER(obj);
451         k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
452         if (k->print_info) {
453             k->print_info(intc, mon);
454         } else {
455             monitor_printf(mon, "Interrupt controller information not available for %s.\n",
456                            object_get_typename(obj));
457         }
458     }
459 
460     return 0;
461 }
462 
463 void hmp_info_pic(Monitor *mon, const QDict *qdict)
464 {
465     object_child_foreach_recursive(object_get_root(),
466                                    hmp_info_pic_foreach, mon);
467 }
468 
469 void hmp_info_tpm(Monitor *mon, const QDict *qdict)
470 {
471 #ifdef CONFIG_TPM
472     TPMInfoList *info_list, *info;
473     Error *err = NULL;
474     unsigned int c = 0;
475     TPMPassthroughOptions *tpo;
476     TPMEmulatorOptions *teo;
477 
478     info_list = qmp_query_tpm(&err);
479     if (err) {
480         monitor_printf(mon, "TPM device not supported\n");
481         error_free(err);
482         return;
483     }
484 
485     if (info_list) {
486         monitor_printf(mon, "TPM device:\n");
487     }
488 
489     for (info = info_list; info; info = info->next) {
490         TPMInfo *ti = info->value;
491         monitor_printf(mon, " tpm%d: model=%s\n",
492                        c, TpmModel_str(ti->model));
493 
494         monitor_printf(mon, "  \\ %s: type=%s",
495                        ti->id, TpmType_str(ti->options->type));
496 
497         switch (ti->options->type) {
498         case TPM_TYPE_PASSTHROUGH:
499             tpo = ti->options->u.passthrough.data;
500             monitor_printf(mon, "%s%s%s%s",
501                            tpo->path ? ",path=" : "",
502                            tpo->path ?: "",
503                            tpo->cancel_path ? ",cancel-path=" : "",
504                            tpo->cancel_path ?: "");
505             break;
506         case TPM_TYPE_EMULATOR:
507             teo = ti->options->u.emulator.data;
508             monitor_printf(mon, ",chardev=%s", teo->chardev);
509             break;
510         case TPM_TYPE__MAX:
511             break;
512         }
513         monitor_printf(mon, "\n");
514         c++;
515     }
516     qapi_free_TPMInfoList(info_list);
517 #else
518     monitor_printf(mon, "TPM device not supported\n");
519 #endif /* CONFIG_TPM */
520 }
521 
522 void hmp_quit(Monitor *mon, const QDict *qdict)
523 {
524     monitor_suspend(mon);
525     qmp_quit(NULL);
526 }
527 
528 void hmp_stop(Monitor *mon, const QDict *qdict)
529 {
530     qmp_stop(NULL);
531 }
532 
533 void hmp_sync_profile(Monitor *mon, const QDict *qdict)
534 {
535     const char *op = qdict_get_try_str(qdict, "op");
536 
537     if (op == NULL) {
538         bool on = qsp_is_enabled();
539 
540         monitor_printf(mon, "sync-profile is %s\n", on ? "on" : "off");
541         return;
542     }
543     if (!strcmp(op, "on")) {
544         qsp_enable();
545     } else if (!strcmp(op, "off")) {
546         qsp_disable();
547     } else if (!strcmp(op, "reset")) {
548         qsp_reset();
549     } else {
550         Error *err = NULL;
551 
552         error_setg(&err, QERR_INVALID_PARAMETER, op);
553         hmp_handle_error(mon, err);
554     }
555 }
556 
557 void hmp_exit_preconfig(Monitor *mon, const QDict *qdict)
558 {
559     Error *err = NULL;
560 
561     qmp_x_exit_preconfig(&err);
562     hmp_handle_error(mon, err);
563 }
564 
565 void hmp_cpu(Monitor *mon, const QDict *qdict)
566 {
567     int64_t cpu_index;
568 
569     /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
570             use it are converted to the QAPI */
571     cpu_index = qdict_get_int(qdict, "index");
572     if (monitor_set_cpu(mon, cpu_index) < 0) {
573         monitor_printf(mon, "invalid CPU index\n");
574     }
575 }
576 
577 void hmp_cont(Monitor *mon, const QDict *qdict)
578 {
579     Error *err = NULL;
580 
581     qmp_cont(&err);
582     hmp_handle_error(mon, err);
583 }
584 
585 void hmp_set_link(Monitor *mon, const QDict *qdict)
586 {
587     const char *name = qdict_get_str(qdict, "name");
588     bool up = qdict_get_bool(qdict, "up");
589     Error *err = NULL;
590 
591     qmp_set_link(name, up, &err);
592     hmp_handle_error(mon, err);
593 }
594 
595 void hmp_loadvm(Monitor *mon, const QDict *qdict)
596 {
597     int saved_vm_running  = runstate_is_running();
598     const char *name = qdict_get_str(qdict, "name");
599     Error *err = NULL;
600 
601     vm_stop(RUN_STATE_RESTORE_VM);
602 
603     if (load_snapshot(name, NULL, false, NULL, &err) && saved_vm_running) {
604         vm_start();
605     }
606     hmp_handle_error(mon, err);
607 }
608 
609 void hmp_savevm(Monitor *mon, const QDict *qdict)
610 {
611     Error *err = NULL;
612 
613     save_snapshot(qdict_get_try_str(qdict, "name"),
614                   true, NULL, false, NULL, &err);
615     hmp_handle_error(mon, err);
616 }
617 
618 void hmp_delvm(Monitor *mon, const QDict *qdict)
619 {
620     Error *err = NULL;
621     const char *name = qdict_get_str(qdict, "name");
622 
623     delete_snapshot(name, false, NULL, &err);
624     hmp_handle_error(mon, err);
625 }
626 
627 void hmp_announce_self(Monitor *mon, const QDict *qdict)
628 {
629     const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
630     const char *id = qdict_get_try_str(qdict, "id");
631     AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
632                                             migrate_announce_params());
633 
634     qapi_free_strList(params->interfaces);
635     params->interfaces = strList_from_comma_list(interfaces_str);
636     params->has_interfaces = params->interfaces != NULL;
637     params->id = g_strdup(id);
638     qmp_announce_self(params, NULL);
639     qapi_free_AnnounceParameters(params);
640 }
641 
642 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
643 {
644     qmp_migrate_cancel(NULL);
645 }
646 
647 void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
648 {
649     Error *err = NULL;
650     const char *state = qdict_get_str(qdict, "state");
651     int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
652 
653     if (val >= 0) {
654         qmp_migrate_continue(val, &err);
655     }
656 
657     hmp_handle_error(mon, err);
658 }
659 
660 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
661 {
662     Error *err = NULL;
663     const char *uri = qdict_get_str(qdict, "uri");
664 
665     qmp_migrate_incoming(uri, &err);
666 
667     hmp_handle_error(mon, err);
668 }
669 
670 void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
671 {
672     Error *err = NULL;
673     const char *uri = qdict_get_str(qdict, "uri");
674 
675     qmp_migrate_recover(uri, &err);
676 
677     hmp_handle_error(mon, err);
678 }
679 
680 void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
681 {
682     Error *err = NULL;
683 
684     qmp_migrate_pause(&err);
685 
686     hmp_handle_error(mon, err);
687 }
688 
689 
690 void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
691 {
692     const char *cap = qdict_get_str(qdict, "capability");
693     bool state = qdict_get_bool(qdict, "state");
694     Error *err = NULL;
695     MigrationCapabilityStatusList *caps = NULL;
696     MigrationCapabilityStatus *value;
697     int val;
698 
699     val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err);
700     if (val < 0) {
701         goto end;
702     }
703 
704     value = g_malloc0(sizeof(*value));
705     value->capability = val;
706     value->state = state;
707     QAPI_LIST_PREPEND(caps, value);
708     qmp_migrate_set_capabilities(caps, &err);
709     qapi_free_MigrationCapabilityStatusList(caps);
710 
711 end:
712     hmp_handle_error(mon, err);
713 }
714 
715 void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
716 {
717     const char *param = qdict_get_str(qdict, "parameter");
718     const char *valuestr = qdict_get_str(qdict, "value");
719     Visitor *v = string_input_visitor_new(valuestr);
720     MigrateSetParameters *p = g_new0(MigrateSetParameters, 1);
721     uint64_t valuebw = 0;
722     uint64_t cache_size;
723     Error *err = NULL;
724     int val, ret;
725 
726     val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err);
727     if (val < 0) {
728         goto cleanup;
729     }
730 
731     switch (val) {
732     case MIGRATION_PARAMETER_COMPRESS_LEVEL:
733         p->has_compress_level = true;
734         visit_type_uint8(v, param, &p->compress_level, &err);
735         break;
736     case MIGRATION_PARAMETER_COMPRESS_THREADS:
737         p->has_compress_threads = true;
738         visit_type_uint8(v, param, &p->compress_threads, &err);
739         break;
740     case MIGRATION_PARAMETER_COMPRESS_WAIT_THREAD:
741         p->has_compress_wait_thread = true;
742         visit_type_bool(v, param, &p->compress_wait_thread, &err);
743         break;
744     case MIGRATION_PARAMETER_DECOMPRESS_THREADS:
745         p->has_decompress_threads = true;
746         visit_type_uint8(v, param, &p->decompress_threads, &err);
747         break;
748     case MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD:
749         p->has_throttle_trigger_threshold = true;
750         visit_type_uint8(v, param, &p->throttle_trigger_threshold, &err);
751         break;
752     case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL:
753         p->has_cpu_throttle_initial = true;
754         visit_type_uint8(v, param, &p->cpu_throttle_initial, &err);
755         break;
756     case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT:
757         p->has_cpu_throttle_increment = true;
758         visit_type_uint8(v, param, &p->cpu_throttle_increment, &err);
759         break;
760     case MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW:
761         p->has_cpu_throttle_tailslow = true;
762         visit_type_bool(v, param, &p->cpu_throttle_tailslow, &err);
763         break;
764     case MIGRATION_PARAMETER_MAX_CPU_THROTTLE:
765         p->has_max_cpu_throttle = true;
766         visit_type_uint8(v, param, &p->max_cpu_throttle, &err);
767         break;
768     case MIGRATION_PARAMETER_TLS_CREDS:
769         p->tls_creds = g_new0(StrOrNull, 1);
770         p->tls_creds->type = QTYPE_QSTRING;
771         visit_type_str(v, param, &p->tls_creds->u.s, &err);
772         break;
773     case MIGRATION_PARAMETER_TLS_HOSTNAME:
774         p->tls_hostname = g_new0(StrOrNull, 1);
775         p->tls_hostname->type = QTYPE_QSTRING;
776         visit_type_str(v, param, &p->tls_hostname->u.s, &err);
777         break;
778     case MIGRATION_PARAMETER_TLS_AUTHZ:
779         p->tls_authz = g_new0(StrOrNull, 1);
780         p->tls_authz->type = QTYPE_QSTRING;
781         visit_type_str(v, param, &p->tls_authz->u.s, &err);
782         break;
783     case MIGRATION_PARAMETER_MAX_BANDWIDTH:
784         p->has_max_bandwidth = true;
785         /*
786          * Can't use visit_type_size() here, because it
787          * defaults to Bytes rather than Mebibytes.
788          */
789         ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
790         if (ret < 0 || valuebw > INT64_MAX
791             || (size_t)valuebw != valuebw) {
792             error_setg(&err, "Invalid size %s", valuestr);
793             break;
794         }
795         p->max_bandwidth = valuebw;
796         break;
797     case MIGRATION_PARAMETER_DOWNTIME_LIMIT:
798         p->has_downtime_limit = true;
799         visit_type_size(v, param, &p->downtime_limit, &err);
800         break;
801     case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY:
802         p->has_x_checkpoint_delay = true;
803         visit_type_uint32(v, param, &p->x_checkpoint_delay, &err);
804         break;
805     case MIGRATION_PARAMETER_BLOCK_INCREMENTAL:
806         p->has_block_incremental = true;
807         visit_type_bool(v, param, &p->block_incremental, &err);
808         break;
809     case MIGRATION_PARAMETER_MULTIFD_CHANNELS:
810         p->has_multifd_channels = true;
811         visit_type_uint8(v, param, &p->multifd_channels, &err);
812         break;
813     case MIGRATION_PARAMETER_MULTIFD_COMPRESSION:
814         p->has_multifd_compression = true;
815         visit_type_MultiFDCompression(v, param, &p->multifd_compression,
816                                       &err);
817         break;
818     case MIGRATION_PARAMETER_MULTIFD_ZLIB_LEVEL:
819         p->has_multifd_zlib_level = true;
820         visit_type_uint8(v, param, &p->multifd_zlib_level, &err);
821         break;
822     case MIGRATION_PARAMETER_MULTIFD_ZSTD_LEVEL:
823         p->has_multifd_zstd_level = true;
824         visit_type_uint8(v, param, &p->multifd_zstd_level, &err);
825         break;
826     case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE:
827         p->has_xbzrle_cache_size = true;
828         if (!visit_type_size(v, param, &cache_size, &err)) {
829             break;
830         }
831         if (cache_size > INT64_MAX || (size_t)cache_size != cache_size) {
832             error_setg(&err, "Invalid size %s", valuestr);
833             break;
834         }
835         p->xbzrle_cache_size = cache_size;
836         break;
837     case MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH:
838         p->has_max_postcopy_bandwidth = true;
839         visit_type_size(v, param, &p->max_postcopy_bandwidth, &err);
840         break;
841     case MIGRATION_PARAMETER_ANNOUNCE_INITIAL:
842         p->has_announce_initial = true;
843         visit_type_size(v, param, &p->announce_initial, &err);
844         break;
845     case MIGRATION_PARAMETER_ANNOUNCE_MAX:
846         p->has_announce_max = true;
847         visit_type_size(v, param, &p->announce_max, &err);
848         break;
849     case MIGRATION_PARAMETER_ANNOUNCE_ROUNDS:
850         p->has_announce_rounds = true;
851         visit_type_size(v, param, &p->announce_rounds, &err);
852         break;
853     case MIGRATION_PARAMETER_ANNOUNCE_STEP:
854         p->has_announce_step = true;
855         visit_type_size(v, param, &p->announce_step, &err);
856         break;
857     case MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING:
858         error_setg(&err, "The block-bitmap-mapping parameter can only be set "
859                    "through QMP");
860         break;
861     default:
862         assert(0);
863     }
864 
865     if (err) {
866         goto cleanup;
867     }
868 
869     qmp_migrate_set_parameters(p, &err);
870 
871  cleanup:
872     qapi_free_MigrateSetParameters(p);
873     visit_free(v);
874     hmp_handle_error(mon, err);
875 }
876 
877 void hmp_client_migrate_info(Monitor *mon, const QDict *qdict)
878 {
879     Error *err = NULL;
880     const char *protocol = qdict_get_str(qdict, "protocol");
881     const char *hostname = qdict_get_str(qdict, "hostname");
882     bool has_port        = qdict_haskey(qdict, "port");
883     int port             = qdict_get_try_int(qdict, "port", -1);
884     bool has_tls_port    = qdict_haskey(qdict, "tls-port");
885     int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
886     const char *cert_subject = qdict_get_try_str(qdict, "cert-subject");
887 
888     qmp_client_migrate_info(protocol, hostname,
889                             has_port, port, has_tls_port, tls_port,
890                             cert_subject, &err);
891     hmp_handle_error(mon, err);
892 }
893 
894 void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict)
895 {
896     Error *err = NULL;
897     qmp_migrate_start_postcopy(&err);
898     hmp_handle_error(mon, err);
899 }
900 
901 void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict)
902 {
903     Error *err = NULL;
904 
905     qmp_x_colo_lost_heartbeat(&err);
906     hmp_handle_error(mon, err);
907 }
908 
909 void hmp_change(Monitor *mon, const QDict *qdict)
910 {
911     const char *device = qdict_get_str(qdict, "device");
912     const char *target = qdict_get_str(qdict, "target");
913     const char *arg = qdict_get_try_str(qdict, "arg");
914     const char *read_only = qdict_get_try_str(qdict, "read-only-mode");
915     bool force = qdict_get_try_bool(qdict, "force", false);
916     Error *err = NULL;
917 
918 #ifdef CONFIG_VNC
919     if (strcmp(device, "vnc") == 0) {
920         hmp_change_vnc(mon, device, target, arg, read_only, force, &err);
921     } else
922 #endif
923     {
924         hmp_change_medium(mon, device, target, arg, read_only, force, &err);
925     }
926 
927     hmp_handle_error(mon, err);
928 }
929 
930 typedef struct HMPMigrationStatus {
931     QEMUTimer *timer;
932     Monitor *mon;
933     bool is_block_migration;
934 } HMPMigrationStatus;
935 
936 static void hmp_migrate_status_cb(void *opaque)
937 {
938     HMPMigrationStatus *status = opaque;
939     MigrationInfo *info;
940 
941     info = qmp_query_migrate(NULL);
942     if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE ||
943         info->status == MIGRATION_STATUS_SETUP) {
944         if (info->disk) {
945             int progress;
946 
947             if (info->disk->remaining) {
948                 progress = info->disk->transferred * 100 / info->disk->total;
949             } else {
950                 progress = 100;
951             }
952 
953             monitor_printf(status->mon, "Completed %d %%\r", progress);
954             monitor_flush(status->mon);
955         }
956 
957         timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
958     } else {
959         if (status->is_block_migration) {
960             monitor_printf(status->mon, "\n");
961         }
962         if (info->error_desc) {
963             error_report("%s", info->error_desc);
964         }
965         monitor_resume(status->mon);
966         timer_free(status->timer);
967         g_free(status);
968     }
969 
970     qapi_free_MigrationInfo(info);
971 }
972 
973 void hmp_migrate(Monitor *mon, const QDict *qdict)
974 {
975     bool detach = qdict_get_try_bool(qdict, "detach", false);
976     bool blk = qdict_get_try_bool(qdict, "blk", false);
977     bool inc = qdict_get_try_bool(qdict, "inc", false);
978     bool resume = qdict_get_try_bool(qdict, "resume", false);
979     const char *uri = qdict_get_str(qdict, "uri");
980     Error *err = NULL;
981 
982     qmp_migrate(uri, !!blk, blk, !!inc, inc,
983                 false, false, true, resume, &err);
984     if (hmp_handle_error(mon, err)) {
985         return;
986     }
987 
988     if (!detach) {
989         HMPMigrationStatus *status;
990 
991         if (monitor_suspend(mon) < 0) {
992             monitor_printf(mon, "terminal does not allow synchronous "
993                            "migration, continuing detached\n");
994             return;
995         }
996 
997         status = g_malloc0(sizeof(*status));
998         status->mon = mon;
999         status->is_block_migration = blk || inc;
1000         status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb,
1001                                           status);
1002         timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
1003     }
1004 }
1005 
1006 void hmp_netdev_add(Monitor *mon, const QDict *qdict)
1007 {
1008     Error *err = NULL;
1009     QemuOpts *opts;
1010     const char *type = qdict_get_try_str(qdict, "type");
1011 
1012     if (type && is_help_option(type)) {
1013         show_netdevs();
1014         return;
1015     }
1016     opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
1017     if (err) {
1018         goto out;
1019     }
1020 
1021     netdev_add(opts, &err);
1022     if (err) {
1023         qemu_opts_del(opts);
1024     }
1025 
1026 out:
1027     hmp_handle_error(mon, err);
1028 }
1029 
1030 void hmp_netdev_del(Monitor *mon, const QDict *qdict)
1031 {
1032     const char *id = qdict_get_str(qdict, "id");
1033     Error *err = NULL;
1034 
1035     qmp_netdev_del(id, &err);
1036     hmp_handle_error(mon, err);
1037 }
1038 
1039 void hmp_getfd(Monitor *mon, const QDict *qdict)
1040 {
1041     const char *fdname = qdict_get_str(qdict, "fdname");
1042     Error *err = NULL;
1043 
1044     qmp_getfd(fdname, &err);
1045     hmp_handle_error(mon, err);
1046 }
1047 
1048 void hmp_closefd(Monitor *mon, const QDict *qdict)
1049 {
1050     const char *fdname = qdict_get_str(qdict, "fdname");
1051     Error *err = NULL;
1052 
1053     qmp_closefd(fdname, &err);
1054     hmp_handle_error(mon, err);
1055 }
1056 
1057 void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
1058 {
1059     IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
1060     IOThreadInfoList *info;
1061     IOThreadInfo *value;
1062 
1063     for (info = info_list; info; info = info->next) {
1064         value = info->value;
1065         monitor_printf(mon, "%s:\n", value->id);
1066         monitor_printf(mon, "  thread_id=%" PRId64 "\n", value->thread_id);
1067         monitor_printf(mon, "  poll-max-ns=%" PRId64 "\n", value->poll_max_ns);
1068         monitor_printf(mon, "  poll-grow=%" PRId64 "\n", value->poll_grow);
1069         monitor_printf(mon, "  poll-shrink=%" PRId64 "\n", value->poll_shrink);
1070         monitor_printf(mon, "  aio-max-batch=%" PRId64 "\n",
1071                        value->aio_max_batch);
1072     }
1073 
1074     qapi_free_IOThreadInfoList(info_list);
1075 }
1076 
1077 static void print_stats_schema_value(Monitor *mon, StatsSchemaValue *value)
1078 {
1079     const char *unit = NULL;
1080     monitor_printf(mon, "    %s (%s%s", value->name, StatsType_str(value->type),
1081                    value->has_unit || value->exponent ? ", " : "");
1082 
1083     if (value->has_unit) {
1084         if (value->unit == STATS_UNIT_SECONDS) {
1085             unit = "s";
1086         } else if (value->unit == STATS_UNIT_BYTES) {
1087             unit = "B";
1088         }
1089     }
1090 
1091     if (unit && value->base == 10 &&
1092         value->exponent >= -18 && value->exponent <= 18 &&
1093         value->exponent % 3 == 0) {
1094         monitor_puts(mon, si_prefix(value->exponent));
1095     } else if (unit && value->base == 2 &&
1096                value->exponent >= 0 && value->exponent <= 60 &&
1097                value->exponent % 10 == 0) {
1098 
1099         monitor_puts(mon, iec_binary_prefix(value->exponent));
1100     } else if (value->exponent) {
1101         /* Use exponential notation and write the unit's English name */
1102         monitor_printf(mon, "* %d^%d%s",
1103                        value->base, value->exponent,
1104                        value->has_unit ? " " : "");
1105         unit = NULL;
1106     }
1107 
1108     if (value->has_unit) {
1109         monitor_puts(mon, unit ? unit : StatsUnit_str(value->unit));
1110     }
1111 
1112     /* Print bucket size for linear histograms */
1113     if (value->type == STATS_TYPE_LINEAR_HISTOGRAM && value->has_bucket_size) {
1114         monitor_printf(mon, ", bucket size=%d", value->bucket_size);
1115     }
1116     monitor_printf(mon, ")");
1117 }
1118 
1119 static StatsSchemaValueList *find_schema_value_list(
1120     StatsSchemaList *list, StatsProvider provider,
1121     StatsTarget target)
1122 {
1123     StatsSchemaList *node;
1124 
1125     for (node = list; node; node = node->next) {
1126         if (node->value->provider == provider &&
1127             node->value->target == target) {
1128             return node->value->stats;
1129         }
1130     }
1131     return NULL;
1132 }
1133 
1134 static void print_stats_results(Monitor *mon, StatsTarget target,
1135                                 bool show_provider,
1136                                 StatsResult *result,
1137                                 StatsSchemaList *schema)
1138 {
1139     /* Find provider schema */
1140     StatsSchemaValueList *schema_value_list =
1141         find_schema_value_list(schema, result->provider, target);
1142     StatsList *stats_list;
1143 
1144     if (!schema_value_list) {
1145         monitor_printf(mon, "failed to find schema list for %s\n",
1146                        StatsProvider_str(result->provider));
1147         return;
1148     }
1149 
1150     if (show_provider) {
1151         monitor_printf(mon, "provider: %s\n",
1152                        StatsProvider_str(result->provider));
1153     }
1154 
1155     for (stats_list = result->stats; stats_list;
1156              stats_list = stats_list->next,
1157              schema_value_list = schema_value_list->next) {
1158 
1159         Stats *stats = stats_list->value;
1160         StatsValue *stats_value = stats->value;
1161         StatsSchemaValue *schema_value = schema_value_list->value;
1162 
1163         /* Find schema entry */
1164         while (!g_str_equal(stats->name, schema_value->name)) {
1165             if (!schema_value_list->next) {
1166                 monitor_printf(mon, "failed to find schema entry for %s\n",
1167                                stats->name);
1168                 return;
1169             }
1170             schema_value_list = schema_value_list->next;
1171             schema_value = schema_value_list->value;
1172         }
1173 
1174         print_stats_schema_value(mon, schema_value);
1175 
1176         if (stats_value->type == QTYPE_QNUM) {
1177             monitor_printf(mon, ": %" PRId64 "\n", stats_value->u.scalar);
1178         } else if (stats_value->type == QTYPE_QBOOL) {
1179             monitor_printf(mon, ": %s\n", stats_value->u.boolean ? "yes" : "no");
1180         } else if (stats_value->type == QTYPE_QLIST) {
1181             uint64List *list;
1182             int i;
1183 
1184             monitor_printf(mon, ": ");
1185             for (list = stats_value->u.list, i = 1;
1186                  list;
1187                  list = list->next, i++) {
1188                 monitor_printf(mon, "[%d]=%" PRId64 " ", i, list->value);
1189             }
1190             monitor_printf(mon, "\n");
1191         }
1192     }
1193 }
1194 
1195 /* Create the StatsFilter that is needed for an "info stats" invocation.  */
1196 static StatsFilter *stats_filter(StatsTarget target, const char *names,
1197                                  int cpu_index, StatsProvider provider)
1198 {
1199     StatsFilter *filter = g_malloc0(sizeof(*filter));
1200     StatsProvider provider_idx;
1201     StatsRequestList *request_list = NULL;
1202 
1203     filter->target = target;
1204     switch (target) {
1205     case STATS_TARGET_VM:
1206         break;
1207     case STATS_TARGET_VCPU:
1208     {
1209         strList *vcpu_list = NULL;
1210         CPUState *cpu = qemu_get_cpu(cpu_index);
1211         char *canonical_path = object_get_canonical_path(OBJECT(cpu));
1212 
1213         QAPI_LIST_PREPEND(vcpu_list, canonical_path);
1214         filter->u.vcpu.has_vcpus = true;
1215         filter->u.vcpu.vcpus = vcpu_list;
1216         break;
1217     }
1218     default:
1219         break;
1220     }
1221 
1222     if (!names && provider == STATS_PROVIDER__MAX) {
1223         return filter;
1224     }
1225 
1226     /*
1227      * "info stats" can only query either one or all the providers.  Querying
1228      * by name, but not by provider, requires the creation of one filter per
1229      * provider.
1230      */
1231     for (provider_idx = 0; provider_idx < STATS_PROVIDER__MAX; provider_idx++) {
1232         if (provider == STATS_PROVIDER__MAX || provider == provider_idx) {
1233             StatsRequest *request = g_new0(StatsRequest, 1);
1234             request->provider = provider_idx;
1235             if (names && !g_str_equal(names, "*")) {
1236                 request->has_names = true;
1237                 request->names = strList_from_comma_list(names);
1238             }
1239             QAPI_LIST_PREPEND(request_list, request);
1240         }
1241     }
1242 
1243     filter->has_providers = true;
1244     filter->providers = request_list;
1245     return filter;
1246 }
1247 
1248 void hmp_info_stats(Monitor *mon, const QDict *qdict)
1249 {
1250     const char *target_str = qdict_get_str(qdict, "target");
1251     const char *provider_str = qdict_get_try_str(qdict, "provider");
1252     const char *names = qdict_get_try_str(qdict, "names");
1253 
1254     StatsProvider provider = STATS_PROVIDER__MAX;
1255     StatsTarget target;
1256     Error *err = NULL;
1257     g_autoptr(StatsSchemaList) schema = NULL;
1258     g_autoptr(StatsResultList) stats = NULL;
1259     g_autoptr(StatsFilter) filter = NULL;
1260     StatsResultList *entry;
1261 
1262     target = qapi_enum_parse(&StatsTarget_lookup, target_str, -1, &err);
1263     if (err) {
1264         monitor_printf(mon, "invalid stats target %s\n", target_str);
1265         goto exit_no_print;
1266     }
1267     if (provider_str) {
1268         provider = qapi_enum_parse(&StatsProvider_lookup, provider_str, -1, &err);
1269         if (err) {
1270             monitor_printf(mon, "invalid stats provider %s\n", provider_str);
1271             goto exit_no_print;
1272         }
1273     }
1274 
1275     schema = qmp_query_stats_schemas(provider_str ? true : false,
1276                                      provider, &err);
1277     if (err) {
1278         goto exit;
1279     }
1280 
1281     switch (target) {
1282     case STATS_TARGET_VM:
1283         filter = stats_filter(target, names, -1, provider);
1284         break;
1285     case STATS_TARGET_VCPU: {}
1286         int cpu_index = monitor_get_cpu_index(mon);
1287         filter = stats_filter(target, names, cpu_index, provider);
1288         break;
1289     default:
1290         abort();
1291     }
1292 
1293     stats = qmp_query_stats(filter, &err);
1294     if (err) {
1295         goto exit;
1296     }
1297     for (entry = stats; entry; entry = entry->next) {
1298         print_stats_results(mon, target, provider_str == NULL, entry->value, schema);
1299     }
1300 
1301 exit:
1302     if (err) {
1303         monitor_printf(mon, "%s\n", error_get_pretty(err));
1304     }
1305 exit_no_print:
1306     error_free(err);
1307 }
1308 
1309 static void hmp_virtio_dump_protocols(Monitor *mon,
1310                                       VhostDeviceProtocols *pcol)
1311 {
1312     strList *pcol_list = pcol->protocols;
1313     while (pcol_list) {
1314         monitor_printf(mon, "\t%s", pcol_list->value);
1315         pcol_list = pcol_list->next;
1316         if (pcol_list != NULL) {
1317             monitor_printf(mon, ",\n");
1318         }
1319     }
1320     monitor_printf(mon, "\n");
1321     if (pcol->has_unknown_protocols) {
1322         monitor_printf(mon, "  unknown-protocols(0x%016"PRIx64")\n",
1323                        pcol->unknown_protocols);
1324     }
1325 }
1326 
1327 static void hmp_virtio_dump_status(Monitor *mon,
1328                                    VirtioDeviceStatus *status)
1329 {
1330     strList *status_list = status->statuses;
1331     while (status_list) {
1332         monitor_printf(mon, "\t%s", status_list->value);
1333         status_list = status_list->next;
1334         if (status_list != NULL) {
1335             monitor_printf(mon, ",\n");
1336         }
1337     }
1338     monitor_printf(mon, "\n");
1339     if (status->has_unknown_statuses) {
1340         monitor_printf(mon, "  unknown-statuses(0x%016"PRIx32")\n",
1341                        status->unknown_statuses);
1342     }
1343 }
1344 
1345 static void hmp_virtio_dump_features(Monitor *mon,
1346                                      VirtioDeviceFeatures *features)
1347 {
1348     strList *transport_list = features->transports;
1349     while (transport_list) {
1350         monitor_printf(mon, "\t%s", transport_list->value);
1351         transport_list = transport_list->next;
1352         if (transport_list != NULL) {
1353             monitor_printf(mon, ",\n");
1354         }
1355     }
1356 
1357     monitor_printf(mon, "\n");
1358     strList *list = features->dev_features;
1359     if (list) {
1360         while (list) {
1361             monitor_printf(mon, "\t%s", list->value);
1362             list = list->next;
1363             if (list != NULL) {
1364                 monitor_printf(mon, ",\n");
1365             }
1366         }
1367         monitor_printf(mon, "\n");
1368     }
1369 
1370     if (features->has_unknown_dev_features) {
1371         monitor_printf(mon, "  unknown-features(0x%016"PRIx64")\n",
1372                        features->unknown_dev_features);
1373     }
1374 }
1375 
1376 void hmp_virtio_query(Monitor *mon, const QDict *qdict)
1377 {
1378     Error *err = NULL;
1379     VirtioInfoList *list = qmp_x_query_virtio(&err);
1380     VirtioInfoList *node;
1381 
1382     if (err != NULL) {
1383         hmp_handle_error(mon, err);
1384         return;
1385     }
1386 
1387     if (list == NULL) {
1388         monitor_printf(mon, "No VirtIO devices\n");
1389         return;
1390     }
1391 
1392     node = list;
1393     while (node) {
1394         monitor_printf(mon, "%s [%s]\n", node->value->path,
1395                        node->value->name);
1396         node = node->next;
1397     }
1398     qapi_free_VirtioInfoList(list);
1399 }
1400 
1401 void hmp_virtio_status(Monitor *mon, const QDict *qdict)
1402 {
1403     Error *err = NULL;
1404     const char *path = qdict_get_try_str(qdict, "path");
1405     VirtioStatus *s = qmp_x_query_virtio_status(path, &err);
1406 
1407     if (err != NULL) {
1408         hmp_handle_error(mon, err);
1409         return;
1410     }
1411 
1412     monitor_printf(mon, "%s:\n", path);
1413     monitor_printf(mon, "  device_name:             %s %s\n",
1414                    s->name, s->vhost_dev ? "(vhost)" : "");
1415     monitor_printf(mon, "  device_id:               %d\n", s->device_id);
1416     monitor_printf(mon, "  vhost_started:           %s\n",
1417                    s->vhost_started ? "true" : "false");
1418     monitor_printf(mon, "  bus_name:                %s\n", s->bus_name);
1419     monitor_printf(mon, "  broken:                  %s\n",
1420                    s->broken ? "true" : "false");
1421     monitor_printf(mon, "  disabled:                %s\n",
1422                    s->disabled ? "true" : "false");
1423     monitor_printf(mon, "  disable_legacy_check:    %s\n",
1424                    s->disable_legacy_check ? "true" : "false");
1425     monitor_printf(mon, "  started:                 %s\n",
1426                    s->started ? "true" : "false");
1427     monitor_printf(mon, "  use_started:             %s\n",
1428                    s->use_started ? "true" : "false");
1429     monitor_printf(mon, "  start_on_kick:           %s\n",
1430                    s->start_on_kick ? "true" : "false");
1431     monitor_printf(mon, "  use_guest_notifier_mask: %s\n",
1432                    s->use_guest_notifier_mask ? "true" : "false");
1433     monitor_printf(mon, "  vm_running:              %s\n",
1434                    s->vm_running ? "true" : "false");
1435     monitor_printf(mon, "  num_vqs:                 %"PRId64"\n", s->num_vqs);
1436     monitor_printf(mon, "  queue_sel:               %d\n",
1437                    s->queue_sel);
1438     monitor_printf(mon, "  isr:                     %d\n", s->isr);
1439     monitor_printf(mon, "  endianness:              %s\n",
1440                    s->device_endian);
1441     monitor_printf(mon, "  status:\n");
1442     hmp_virtio_dump_status(mon, s->status);
1443     monitor_printf(mon, "  Guest features:\n");
1444     hmp_virtio_dump_features(mon, s->guest_features);
1445     monitor_printf(mon, "  Host features:\n");
1446     hmp_virtio_dump_features(mon, s->host_features);
1447     monitor_printf(mon, "  Backend features:\n");
1448     hmp_virtio_dump_features(mon, s->backend_features);
1449 
1450     if (s->vhost_dev) {
1451         monitor_printf(mon, "  VHost:\n");
1452         monitor_printf(mon, "    nvqs:           %d\n",
1453                        s->vhost_dev->nvqs);
1454         monitor_printf(mon, "    vq_index:       %"PRId64"\n",
1455                        s->vhost_dev->vq_index);
1456         monitor_printf(mon, "    max_queues:     %"PRId64"\n",
1457                        s->vhost_dev->max_queues);
1458         monitor_printf(mon, "    n_mem_sections: %"PRId64"\n",
1459                        s->vhost_dev->n_mem_sections);
1460         monitor_printf(mon, "    n_tmp_sections: %"PRId64"\n",
1461                        s->vhost_dev->n_tmp_sections);
1462         monitor_printf(mon, "    backend_cap:    %"PRId64"\n",
1463                        s->vhost_dev->backend_cap);
1464         monitor_printf(mon, "    log_enabled:    %s\n",
1465                        s->vhost_dev->log_enabled ? "true" : "false");
1466         monitor_printf(mon, "    log_size:       %"PRId64"\n",
1467                        s->vhost_dev->log_size);
1468         monitor_printf(mon, "    Features:\n");
1469         hmp_virtio_dump_features(mon, s->vhost_dev->features);
1470         monitor_printf(mon, "    Acked features:\n");
1471         hmp_virtio_dump_features(mon, s->vhost_dev->acked_features);
1472         monitor_printf(mon, "    Backend features:\n");
1473         hmp_virtio_dump_features(mon, s->vhost_dev->backend_features);
1474         monitor_printf(mon, "    Protocol features:\n");
1475         hmp_virtio_dump_protocols(mon, s->vhost_dev->protocol_features);
1476     }
1477 
1478     qapi_free_VirtioStatus(s);
1479 }
1480 
1481 void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict)
1482 {
1483     Error *err = NULL;
1484     const char *path = qdict_get_try_str(qdict, "path");
1485     int queue = qdict_get_int(qdict, "queue");
1486     VirtVhostQueueStatus *s =
1487         qmp_x_query_virtio_vhost_queue_status(path, queue, &err);
1488 
1489     if (err != NULL) {
1490         hmp_handle_error(mon, err);
1491         return;
1492     }
1493 
1494     monitor_printf(mon, "%s:\n", path);
1495     monitor_printf(mon, "  device_name:          %s (vhost)\n",
1496                    s->name);
1497     monitor_printf(mon, "  kick:                 %"PRId64"\n", s->kick);
1498     monitor_printf(mon, "  call:                 %"PRId64"\n", s->call);
1499     monitor_printf(mon, "  VRing:\n");
1500     monitor_printf(mon, "    num:         %"PRId64"\n", s->num);
1501     monitor_printf(mon, "    desc:        0x%016"PRIx64"\n", s->desc);
1502     monitor_printf(mon, "    desc_phys:   0x%016"PRIx64"\n",
1503                    s->desc_phys);
1504     monitor_printf(mon, "    desc_size:   %"PRId32"\n", s->desc_size);
1505     monitor_printf(mon, "    avail:       0x%016"PRIx64"\n", s->avail);
1506     monitor_printf(mon, "    avail_phys:  0x%016"PRIx64"\n",
1507                    s->avail_phys);
1508     monitor_printf(mon, "    avail_size:  %"PRId32"\n", s->avail_size);
1509     monitor_printf(mon, "    used:        0x%016"PRIx64"\n", s->used);
1510     monitor_printf(mon, "    used_phys:   0x%016"PRIx64"\n",
1511                    s->used_phys);
1512     monitor_printf(mon, "    used_size:   %"PRId32"\n", s->used_size);
1513 
1514     qapi_free_VirtVhostQueueStatus(s);
1515 }
1516 
1517 void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
1518 {
1519     Error *err = NULL;
1520     const char *path = qdict_get_try_str(qdict, "path");
1521     int queue = qdict_get_int(qdict, "queue");
1522     VirtQueueStatus *s = qmp_x_query_virtio_queue_status(path, queue, &err);
1523 
1524     if (err != NULL) {
1525         hmp_handle_error(mon, err);
1526         return;
1527     }
1528 
1529     monitor_printf(mon, "%s:\n", path);
1530     monitor_printf(mon, "  device_name:          %s\n", s->name);
1531     monitor_printf(mon, "  queue_index:          %d\n", s->queue_index);
1532     monitor_printf(mon, "  inuse:                %d\n", s->inuse);
1533     monitor_printf(mon, "  used_idx:             %d\n", s->used_idx);
1534     monitor_printf(mon, "  signalled_used:       %d\n",
1535                    s->signalled_used);
1536     monitor_printf(mon, "  signalled_used_valid: %s\n",
1537                    s->signalled_used_valid ? "true" : "false");
1538     if (s->has_last_avail_idx) {
1539         monitor_printf(mon, "  last_avail_idx:       %d\n",
1540                        s->last_avail_idx);
1541     }
1542     if (s->has_shadow_avail_idx) {
1543         monitor_printf(mon, "  shadow_avail_idx:     %d\n",
1544                        s->shadow_avail_idx);
1545     }
1546     monitor_printf(mon, "  VRing:\n");
1547     monitor_printf(mon, "    num:          %"PRId32"\n", s->vring_num);
1548     monitor_printf(mon, "    num_default:  %"PRId32"\n",
1549                    s->vring_num_default);
1550     monitor_printf(mon, "    align:        %"PRId32"\n",
1551                    s->vring_align);
1552     monitor_printf(mon, "    desc:         0x%016"PRIx64"\n",
1553                    s->vring_desc);
1554     monitor_printf(mon, "    avail:        0x%016"PRIx64"\n",
1555                    s->vring_avail);
1556     monitor_printf(mon, "    used:         0x%016"PRIx64"\n",
1557                    s->vring_used);
1558 
1559     qapi_free_VirtQueueStatus(s);
1560 }
1561 
1562 void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict)
1563 {
1564     Error *err = NULL;
1565     const char *path = qdict_get_try_str(qdict, "path");
1566     int queue = qdict_get_int(qdict, "queue");
1567     int index = qdict_get_try_int(qdict, "index", -1);
1568     VirtioQueueElement *e;
1569     VirtioRingDescList *list;
1570 
1571     e = qmp_x_query_virtio_queue_element(path, queue, index != -1,
1572                                          index, &err);
1573     if (err != NULL) {
1574         hmp_handle_error(mon, err);
1575         return;
1576     }
1577 
1578     monitor_printf(mon, "%s:\n", path);
1579     monitor_printf(mon, "  device_name: %s\n", e->name);
1580     monitor_printf(mon, "  index:   %d\n", e->index);
1581     monitor_printf(mon, "  desc:\n");
1582     monitor_printf(mon, "    descs:\n");
1583 
1584     list = e->descs;
1585     while (list) {
1586         monitor_printf(mon, "        addr 0x%"PRIx64" len %d",
1587                        list->value->addr, list->value->len);
1588         if (list->value->flags) {
1589             strList *flag = list->value->flags;
1590             monitor_printf(mon, " (");
1591             while (flag) {
1592                 monitor_printf(mon, "%s", flag->value);
1593                 flag = flag->next;
1594                 if (flag) {
1595                     monitor_printf(mon, ", ");
1596                 }
1597             }
1598             monitor_printf(mon, ")");
1599         }
1600         list = list->next;
1601         if (list) {
1602             monitor_printf(mon, ",\n");
1603         }
1604     }
1605     monitor_printf(mon, "\n");
1606     monitor_printf(mon, "  avail:\n");
1607     monitor_printf(mon, "    flags: %d\n", e->avail->flags);
1608     monitor_printf(mon, "    idx:   %d\n", e->avail->idx);
1609     monitor_printf(mon, "    ring:  %d\n", e->avail->ring);
1610     monitor_printf(mon, "  used:\n");
1611     monitor_printf(mon, "    flags: %d\n", e->used->flags);
1612     monitor_printf(mon, "    idx:   %d\n", e->used->idx);
1613 
1614     qapi_free_VirtioQueueElement(e);
1615 }
1616