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