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