xref: /openbmc/qemu/monitor/hmp-cmds.c (revision b3eb5b86)
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 "chardev/char.h"
21 #include "sysemu/block-backend.h"
22 #include "sysemu/runstate.h"
23 #include "qemu/config-file.h"
24 #include "qemu/option.h"
25 #include "qemu/timer.h"
26 #include "qemu/sockets.h"
27 #include "qemu/help_option.h"
28 #include "monitor/monitor-internal.h"
29 #include "qapi/error.h"
30 #include "qapi/clone-visitor.h"
31 #include "qapi/opts-visitor.h"
32 #include "qapi/qapi-builtin-visit.h"
33 #include "qapi/qapi-commands-block.h"
34 #include "qapi/qapi-commands-char.h"
35 #include "qapi/qapi-commands-control.h"
36 #include "qapi/qapi-commands-machine.h"
37 #include "qapi/qapi-commands-migration.h"
38 #include "qapi/qapi-commands-misc.h"
39 #include "qapi/qapi-commands-net.h"
40 #include "qapi/qapi-commands-rocker.h"
41 #include "qapi/qapi-commands-run-state.h"
42 #include "qapi/qapi-commands-stats.h"
43 #include "qapi/qapi-commands-tpm.h"
44 #include "qapi/qapi-commands-ui.h"
45 #include "qapi/qapi-commands-virtio.h"
46 #include "qapi/qapi-visit-virtio.h"
47 #include "qapi/qapi-visit-net.h"
48 #include "qapi/qapi-visit-migration.h"
49 #include "qapi/qmp/qdict.h"
50 #include "qapi/qmp/qerror.h"
51 #include "qapi/string-input-visitor.h"
52 #include "qapi/string-output-visitor.h"
53 #include "qom/object_interfaces.h"
54 #include "ui/console.h"
55 #include "qemu/cutils.h"
56 #include "qemu/error-report.h"
57 #include "hw/core/cpu.h"
58 #include "hw/intc/intc.h"
59 #include "migration/snapshot.h"
60 #include "migration/misc.h"
61 
62 #ifdef CONFIG_SPICE
63 #include <spice/enums.h>
64 #endif
65 
66 bool hmp_handle_error(Monitor *mon, Error *err)
67 {
68     if (err) {
69         error_reportf_err(err, "Error: ");
70         return true;
71     }
72     return false;
73 }
74 
75 /*
76  * Produce a strList from a comma separated list.
77  * A NULL or empty input string return NULL.
78  */
79 static strList *strList_from_comma_list(const char *in)
80 {
81     strList *res = NULL;
82     strList **tail = &res;
83 
84     while (in && in[0]) {
85         char *comma = strchr(in, ',');
86         char *value;
87 
88         if (comma) {
89             value = g_strndup(in, comma - in);
90             in = comma + 1; /* skip the , */
91         } else {
92             value = g_strdup(in);
93             in = NULL;
94         }
95         QAPI_LIST_APPEND(tail, value);
96     }
97 
98     return res;
99 }
100 
101 void hmp_info_name(Monitor *mon, const QDict *qdict)
102 {
103     NameInfo *info;
104 
105     info = qmp_query_name(NULL);
106     if (info->name) {
107         monitor_printf(mon, "%s\n", info->name);
108     }
109     qapi_free_NameInfo(info);
110 }
111 
112 void hmp_info_version(Monitor *mon, const QDict *qdict)
113 {
114     VersionInfo *info;
115 
116     info = qmp_query_version(NULL);
117 
118     monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
119                    info->qemu->major, info->qemu->minor, info->qemu->micro,
120                    info->package);
121 
122     qapi_free_VersionInfo(info);
123 }
124 
125 void hmp_info_kvm(Monitor *mon, const QDict *qdict)
126 {
127     KvmInfo *info;
128 
129     info = qmp_query_kvm(NULL);
130     monitor_printf(mon, "kvm support: ");
131     if (info->present) {
132         monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled");
133     } else {
134         monitor_printf(mon, "not compiled\n");
135     }
136 
137     qapi_free_KvmInfo(info);
138 }
139 
140 void hmp_info_status(Monitor *mon, const QDict *qdict)
141 {
142     StatusInfo *info;
143 
144     info = qmp_query_status(NULL);
145 
146     monitor_printf(mon, "VM status: %s%s",
147                    info->running ? "running" : "paused",
148                    info->singlestep ? " (single step mode)" : "");
149 
150     if (!info->running && info->status != RUN_STATE_PAUSED) {
151         monitor_printf(mon, " (%s)", RunState_str(info->status));
152     }
153 
154     monitor_printf(mon, "\n");
155 
156     qapi_free_StatusInfo(info);
157 }
158 
159 void hmp_info_uuid(Monitor *mon, const QDict *qdict)
160 {
161     UuidInfo *info;
162 
163     info = qmp_query_uuid(NULL);
164     monitor_printf(mon, "%s\n", info->UUID);
165     qapi_free_UuidInfo(info);
166 }
167 
168 void hmp_info_chardev(Monitor *mon, const QDict *qdict)
169 {
170     ChardevInfoList *char_info, *info;
171 
172     char_info = qmp_query_chardev(NULL);
173     for (info = char_info; info; info = info->next) {
174         monitor_printf(mon, "%s: filename=%s\n", info->value->label,
175                                                  info->value->filename);
176     }
177 
178     qapi_free_ChardevInfoList(char_info);
179 }
180 
181 void hmp_info_mice(Monitor *mon, const QDict *qdict)
182 {
183     MouseInfoList *mice_list, *mouse;
184 
185     mice_list = qmp_query_mice(NULL);
186     if (!mice_list) {
187         monitor_printf(mon, "No mouse devices connected\n");
188         return;
189     }
190 
191     for (mouse = mice_list; mouse; mouse = mouse->next) {
192         monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
193                        mouse->value->current ? '*' : ' ',
194                        mouse->value->index, mouse->value->name,
195                        mouse->value->absolute ? " (absolute)" : "");
196     }
197 
198     qapi_free_MouseInfoList(mice_list);
199 }
200 
201 void hmp_info_migrate(Monitor *mon, const QDict *qdict)
202 {
203     MigrationInfo *info;
204 
205     info = qmp_query_migrate(NULL);
206 
207     migration_global_dump(mon);
208 
209     if (info->blocked_reasons) {
210         strList *reasons = info->blocked_reasons;
211         monitor_printf(mon, "Outgoing migration blocked:\n");
212         while (reasons) {
213             monitor_printf(mon, "  %s\n", reasons->value);
214             reasons = reasons->next;
215         }
216     }
217 
218     if (info->has_status) {
219         monitor_printf(mon, "Migration status: %s",
220                        MigrationStatus_str(info->status));
221         if (info->status == MIGRATION_STATUS_FAILED && info->error_desc) {
222             monitor_printf(mon, " (%s)\n", info->error_desc);
223         } else {
224             monitor_printf(mon, "\n");
225         }
226 
227         monitor_printf(mon, "total time: %" PRIu64 " ms\n",
228                        info->total_time);
229         if (info->has_expected_downtime) {
230             monitor_printf(mon, "expected downtime: %" PRIu64 " ms\n",
231                            info->expected_downtime);
232         }
233         if (info->has_downtime) {
234             monitor_printf(mon, "downtime: %" PRIu64 " ms\n",
235                            info->downtime);
236         }
237         if (info->has_setup_time) {
238             monitor_printf(mon, "setup: %" PRIu64 " ms\n",
239                            info->setup_time);
240         }
241     }
242 
243     if (info->ram) {
244         monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n",
245                        info->ram->transferred >> 10);
246         monitor_printf(mon, "throughput: %0.2f mbps\n",
247                        info->ram->mbps);
248         monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n",
249                        info->ram->remaining >> 10);
250         monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n",
251                        info->ram->total >> 10);
252         monitor_printf(mon, "duplicate: %" PRIu64 " pages\n",
253                        info->ram->duplicate);
254         monitor_printf(mon, "skipped: %" PRIu64 " pages\n",
255                        info->ram->skipped);
256         monitor_printf(mon, "normal: %" PRIu64 " pages\n",
257                        info->ram->normal);
258         monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
259                        info->ram->normal_bytes >> 10);
260         monitor_printf(mon, "dirty sync count: %" PRIu64 "\n",
261                        info->ram->dirty_sync_count);
262         monitor_printf(mon, "page size: %" PRIu64 " kbytes\n",
263                        info->ram->page_size >> 10);
264         monitor_printf(mon, "multifd bytes: %" PRIu64 " kbytes\n",
265                        info->ram->multifd_bytes >> 10);
266         monitor_printf(mon, "pages-per-second: %" PRIu64 "\n",
267                        info->ram->pages_per_second);
268 
269         if (info->ram->dirty_pages_rate) {
270             monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
271                            info->ram->dirty_pages_rate);
272         }
273         if (info->ram->postcopy_requests) {
274             monitor_printf(mon, "postcopy request count: %" PRIu64 "\n",
275                            info->ram->postcopy_requests);
276         }
277         if (info->ram->precopy_bytes) {
278             monitor_printf(mon, "precopy ram: %" PRIu64 " kbytes\n",
279                            info->ram->precopy_bytes >> 10);
280         }
281         if (info->ram->downtime_bytes) {
282             monitor_printf(mon, "downtime ram: %" PRIu64 " kbytes\n",
283                            info->ram->downtime_bytes >> 10);
284         }
285         if (info->ram->postcopy_bytes) {
286             monitor_printf(mon, "postcopy ram: %" PRIu64 " kbytes\n",
287                            info->ram->postcopy_bytes >> 10);
288         }
289         if (info->ram->dirty_sync_missed_zero_copy) {
290             monitor_printf(mon,
291                            "Zero-copy-send fallbacks happened: %" PRIu64 " times\n",
292                            info->ram->dirty_sync_missed_zero_copy);
293         }
294     }
295 
296     if (info->disk) {
297         monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n",
298                        info->disk->transferred >> 10);
299         monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n",
300                        info->disk->remaining >> 10);
301         monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n",
302                        info->disk->total >> 10);
303     }
304 
305     if (info->xbzrle_cache) {
306         monitor_printf(mon, "cache size: %" PRIu64 " bytes\n",
307                        info->xbzrle_cache->cache_size);
308         monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n",
309                        info->xbzrle_cache->bytes >> 10);
310         monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
311                        info->xbzrle_cache->pages);
312         monitor_printf(mon, "xbzrle cache miss: %" PRIu64 " pages\n",
313                        info->xbzrle_cache->cache_miss);
314         monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n",
315                        info->xbzrle_cache->cache_miss_rate);
316         monitor_printf(mon, "xbzrle encoding rate: %0.2f\n",
317                        info->xbzrle_cache->encoding_rate);
318         monitor_printf(mon, "xbzrle overflow: %" PRIu64 "\n",
319                        info->xbzrle_cache->overflow);
320     }
321 
322     if (info->compression) {
323         monitor_printf(mon, "compression pages: %" PRIu64 " pages\n",
324                        info->compression->pages);
325         monitor_printf(mon, "compression busy: %" PRIu64 "\n",
326                        info->compression->busy);
327         monitor_printf(mon, "compression busy rate: %0.2f\n",
328                        info->compression->busy_rate);
329         monitor_printf(mon, "compressed size: %" PRIu64 " kbytes\n",
330                        info->compression->compressed_size >> 10);
331         monitor_printf(mon, "compression rate: %0.2f\n",
332                        info->compression->compression_rate);
333     }
334 
335     if (info->has_cpu_throttle_percentage) {
336         monitor_printf(mon, "cpu throttle percentage: %" PRIu64 "\n",
337                        info->cpu_throttle_percentage);
338     }
339 
340     if (info->has_postcopy_blocktime) {
341         monitor_printf(mon, "postcopy blocktime: %u\n",
342                        info->postcopy_blocktime);
343     }
344 
345     if (info->has_postcopy_vcpu_blocktime) {
346         Visitor *v;
347         char *str;
348         v = string_output_visitor_new(false, &str);
349         visit_type_uint32List(v, NULL, &info->postcopy_vcpu_blocktime,
350                               &error_abort);
351         visit_complete(v, &str);
352         monitor_printf(mon, "postcopy vcpu blocktime: %s\n", str);
353         g_free(str);
354         visit_free(v);
355     }
356     if (info->has_socket_address) {
357         SocketAddressList *addr;
358 
359         monitor_printf(mon, "socket address: [\n");
360 
361         for (addr = info->socket_address; addr; addr = addr->next) {
362             char *s = socket_uri(addr->value);
363             monitor_printf(mon, "\t%s\n", s);
364             g_free(s);
365         }
366         monitor_printf(mon, "]\n");
367     }
368 
369     if (info->vfio) {
370         monitor_printf(mon, "vfio device transferred: %" PRIu64 " kbytes\n",
371                        info->vfio->transferred >> 10);
372     }
373 
374     qapi_free_MigrationInfo(info);
375 }
376 
377 void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
378 {
379     MigrationCapabilityStatusList *caps, *cap;
380 
381     caps = qmp_query_migrate_capabilities(NULL);
382 
383     if (caps) {
384         for (cap = caps; cap; cap = cap->next) {
385             monitor_printf(mon, "%s: %s\n",
386                            MigrationCapability_str(cap->value->capability),
387                            cap->value->state ? "on" : "off");
388         }
389     }
390 
391     qapi_free_MigrationCapabilityStatusList(caps);
392 }
393 
394 void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
395 {
396     MigrationParameters *params;
397 
398     params = qmp_query_migrate_parameters(NULL);
399 
400     if (params) {
401         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
402             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_INITIAL),
403             params->announce_initial);
404         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
405             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_MAX),
406             params->announce_max);
407         monitor_printf(mon, "%s: %" PRIu64 "\n",
408             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_ROUNDS),
409             params->announce_rounds);
410         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
411             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_STEP),
412             params->announce_step);
413         assert(params->has_compress_level);
414         monitor_printf(mon, "%s: %u\n",
415             MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_LEVEL),
416             params->compress_level);
417         assert(params->has_compress_threads);
418         monitor_printf(mon, "%s: %u\n",
419             MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_THREADS),
420             params->compress_threads);
421         assert(params->has_compress_wait_thread);
422         monitor_printf(mon, "%s: %s\n",
423             MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_WAIT_THREAD),
424             params->compress_wait_thread ? "on" : "off");
425         assert(params->has_decompress_threads);
426         monitor_printf(mon, "%s: %u\n",
427             MigrationParameter_str(MIGRATION_PARAMETER_DECOMPRESS_THREADS),
428             params->decompress_threads);
429         assert(params->has_throttle_trigger_threshold);
430         monitor_printf(mon, "%s: %u\n",
431             MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD),
432             params->throttle_trigger_threshold);
433         assert(params->has_cpu_throttle_initial);
434         monitor_printf(mon, "%s: %u\n",
435             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL),
436             params->cpu_throttle_initial);
437         assert(params->has_cpu_throttle_increment);
438         monitor_printf(mon, "%s: %u\n",
439             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT),
440             params->cpu_throttle_increment);
441         assert(params->has_cpu_throttle_tailslow);
442         monitor_printf(mon, "%s: %s\n",
443             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW),
444             params->cpu_throttle_tailslow ? "on" : "off");
445         assert(params->has_max_cpu_throttle);
446         monitor_printf(mon, "%s: %u\n",
447             MigrationParameter_str(MIGRATION_PARAMETER_MAX_CPU_THROTTLE),
448             params->max_cpu_throttle);
449         assert(params->tls_creds);
450         monitor_printf(mon, "%s: '%s'\n",
451             MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS),
452             params->tls_creds);
453         assert(params->tls_hostname);
454         monitor_printf(mon, "%s: '%s'\n",
455             MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME),
456             params->tls_hostname);
457         assert(params->has_max_bandwidth);
458         monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
459             MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH),
460             params->max_bandwidth);
461         assert(params->has_downtime_limit);
462         monitor_printf(mon, "%s: %" PRIu64 " ms\n",
463             MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT),
464             params->downtime_limit);
465         assert(params->has_x_checkpoint_delay);
466         monitor_printf(mon, "%s: %u ms\n",
467             MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY),
468             params->x_checkpoint_delay);
469         assert(params->has_block_incremental);
470         monitor_printf(mon, "%s: %s\n",
471             MigrationParameter_str(MIGRATION_PARAMETER_BLOCK_INCREMENTAL),
472             params->block_incremental ? "on" : "off");
473         monitor_printf(mon, "%s: %u\n",
474             MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS),
475             params->multifd_channels);
476         monitor_printf(mon, "%s: %s\n",
477             MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION),
478             MultiFDCompression_str(params->multifd_compression));
479         monitor_printf(mon, "%s: %" PRIu64 " bytes\n",
480             MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
481             params->xbzrle_cache_size);
482         monitor_printf(mon, "%s: %" PRIu64 "\n",
483             MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
484             params->max_postcopy_bandwidth);
485         monitor_printf(mon, "%s: '%s'\n",
486             MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
487             params->tls_authz);
488 
489         if (params->has_block_bitmap_mapping) {
490             const BitmapMigrationNodeAliasList *bmnal;
491 
492             monitor_printf(mon, "%s:\n",
493                            MigrationParameter_str(
494                                MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING));
495 
496             for (bmnal = params->block_bitmap_mapping;
497                  bmnal;
498                  bmnal = bmnal->next)
499             {
500                 const BitmapMigrationNodeAlias *bmna = bmnal->value;
501                 const BitmapMigrationBitmapAliasList *bmbal;
502 
503                 monitor_printf(mon, "  '%s' -> '%s'\n",
504                                bmna->node_name, bmna->alias);
505 
506                 for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) {
507                     const BitmapMigrationBitmapAlias *bmba = bmbal->value;
508 
509                     monitor_printf(mon, "    '%s' -> '%s'\n",
510                                    bmba->name, bmba->alias);
511                 }
512             }
513         }
514     }
515 
516     qapi_free_MigrationParameters(params);
517 }
518 
519 
520 #ifdef CONFIG_VNC
521 /* Helper for hmp_info_vnc_clients, _servers */
522 static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info,
523                                   const char *name)
524 {
525     monitor_printf(mon, "  %s: %s:%s (%s%s)\n",
526                    name,
527                    info->host,
528                    info->service,
529                    NetworkAddressFamily_str(info->family),
530                    info->websocket ? " (Websocket)" : "");
531 }
532 
533 /* Helper displaying and auth and crypt info */
534 static void hmp_info_vnc_authcrypt(Monitor *mon, const char *indent,
535                                    VncPrimaryAuth auth,
536                                    VncVencryptSubAuth *vencrypt)
537 {
538     monitor_printf(mon, "%sAuth: %s (Sub: %s)\n", indent,
539                    VncPrimaryAuth_str(auth),
540                    vencrypt ? VncVencryptSubAuth_str(*vencrypt) : "none");
541 }
542 
543 static void hmp_info_vnc_clients(Monitor *mon, VncClientInfoList *client)
544 {
545     while (client) {
546         VncClientInfo *cinfo = client->value;
547 
548         hmp_info_VncBasicInfo(mon, qapi_VncClientInfo_base(cinfo), "Client");
549         monitor_printf(mon, "    x509_dname: %s\n",
550                        cinfo->x509_dname ?: "none");
551         monitor_printf(mon, "    sasl_username: %s\n",
552                        cinfo->sasl_username ?: "none");
553 
554         client = client->next;
555     }
556 }
557 
558 static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server)
559 {
560     while (server) {
561         VncServerInfo2 *sinfo = server->value;
562         hmp_info_VncBasicInfo(mon, qapi_VncServerInfo2_base(sinfo), "Server");
563         hmp_info_vnc_authcrypt(mon, "    ", sinfo->auth,
564                                sinfo->has_vencrypt ? &sinfo->vencrypt : NULL);
565         server = server->next;
566     }
567 }
568 
569 void hmp_info_vnc(Monitor *mon, const QDict *qdict)
570 {
571     VncInfo2List *info2l, *info2l_head;
572     Error *err = NULL;
573 
574     info2l = qmp_query_vnc_servers(&err);
575     info2l_head = info2l;
576     if (hmp_handle_error(mon, err)) {
577         return;
578     }
579     if (!info2l) {
580         monitor_printf(mon, "None\n");
581         return;
582     }
583 
584     while (info2l) {
585         VncInfo2 *info = info2l->value;
586         monitor_printf(mon, "%s:\n", info->id);
587         hmp_info_vnc_servers(mon, info->server);
588         hmp_info_vnc_clients(mon, info->clients);
589         if (!info->server) {
590             /* The server entry displays its auth, we only
591              * need to display in the case of 'reverse' connections
592              * where there's no server.
593              */
594             hmp_info_vnc_authcrypt(mon, "  ", info->auth,
595                                info->has_vencrypt ? &info->vencrypt : NULL);
596         }
597         if (info->display) {
598             monitor_printf(mon, "  Display: %s\n", info->display);
599         }
600         info2l = info2l->next;
601     }
602 
603     qapi_free_VncInfo2List(info2l_head);
604 
605 }
606 #endif
607 
608 #ifdef CONFIG_SPICE
609 void hmp_info_spice(Monitor *mon, const QDict *qdict)
610 {
611     SpiceChannelList *chan;
612     SpiceInfo *info;
613     const char *channel_name;
614     const char * const channel_names[] = {
615         [SPICE_CHANNEL_MAIN] = "main",
616         [SPICE_CHANNEL_DISPLAY] = "display",
617         [SPICE_CHANNEL_INPUTS] = "inputs",
618         [SPICE_CHANNEL_CURSOR] = "cursor",
619         [SPICE_CHANNEL_PLAYBACK] = "playback",
620         [SPICE_CHANNEL_RECORD] = "record",
621         [SPICE_CHANNEL_TUNNEL] = "tunnel",
622         [SPICE_CHANNEL_SMARTCARD] = "smartcard",
623         [SPICE_CHANNEL_USBREDIR] = "usbredir",
624         [SPICE_CHANNEL_PORT] = "port",
625 #if 0
626         /* minimum spice-protocol is 0.12.3, webdav was added in 0.12.7,
627          * no easy way to #ifdef (SPICE_CHANNEL_* is a enum).  Disable
628          * as quick fix for build failures with older versions. */
629         [SPICE_CHANNEL_WEBDAV] = "webdav",
630 #endif
631     };
632 
633     info = qmp_query_spice(NULL);
634 
635     if (!info->enabled) {
636         monitor_printf(mon, "Server: disabled\n");
637         goto out;
638     }
639 
640     monitor_printf(mon, "Server:\n");
641     if (info->has_port) {
642         monitor_printf(mon, "     address: %s:%" PRId64 "\n",
643                        info->host, info->port);
644     }
645     if (info->has_tls_port) {
646         monitor_printf(mon, "     address: %s:%" PRId64 " [tls]\n",
647                        info->host, info->tls_port);
648     }
649     monitor_printf(mon, "    migrated: %s\n",
650                    info->migrated ? "true" : "false");
651     monitor_printf(mon, "        auth: %s\n", info->auth);
652     monitor_printf(mon, "    compiled: %s\n", info->compiled_version);
653     monitor_printf(mon, "  mouse-mode: %s\n",
654                    SpiceQueryMouseMode_str(info->mouse_mode));
655 
656     if (!info->has_channels || info->channels == NULL) {
657         monitor_printf(mon, "Channels: none\n");
658     } else {
659         for (chan = info->channels; chan; chan = chan->next) {
660             monitor_printf(mon, "Channel:\n");
661             monitor_printf(mon, "     address: %s:%s%s\n",
662                            chan->value->host, chan->value->port,
663                            chan->value->tls ? " [tls]" : "");
664             monitor_printf(mon, "     session: %" PRId64 "\n",
665                            chan->value->connection_id);
666             monitor_printf(mon, "     channel: %" PRId64 ":%" PRId64 "\n",
667                            chan->value->channel_type, chan->value->channel_id);
668 
669             channel_name = "unknown";
670             if (chan->value->channel_type > 0 &&
671                 chan->value->channel_type < ARRAY_SIZE(channel_names) &&
672                 channel_names[chan->value->channel_type]) {
673                 channel_name = channel_names[chan->value->channel_type];
674             }
675 
676             monitor_printf(mon, "     channel name: %s\n", channel_name);
677         }
678     }
679 
680 out:
681     qapi_free_SpiceInfo(info);
682 }
683 #endif
684 
685 void hmp_info_balloon(Monitor *mon, const QDict *qdict)
686 {
687     BalloonInfo *info;
688     Error *err = NULL;
689 
690     info = qmp_query_balloon(&err);
691     if (hmp_handle_error(mon, err)) {
692         return;
693     }
694 
695     monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
696 
697     qapi_free_BalloonInfo(info);
698 }
699 
700 static int hmp_info_pic_foreach(Object *obj, void *opaque)
701 {
702     InterruptStatsProvider *intc;
703     InterruptStatsProviderClass *k;
704     Monitor *mon = opaque;
705 
706     if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
707         intc = INTERRUPT_STATS_PROVIDER(obj);
708         k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
709         if (k->print_info) {
710             k->print_info(intc, mon);
711         } else {
712             monitor_printf(mon, "Interrupt controller information not available for %s.\n",
713                            object_get_typename(obj));
714         }
715     }
716 
717     return 0;
718 }
719 
720 void hmp_info_pic(Monitor *mon, const QDict *qdict)
721 {
722     object_child_foreach_recursive(object_get_root(),
723                                    hmp_info_pic_foreach, mon);
724 }
725 
726 void hmp_info_tpm(Monitor *mon, const QDict *qdict)
727 {
728 #ifdef CONFIG_TPM
729     TPMInfoList *info_list, *info;
730     Error *err = NULL;
731     unsigned int c = 0;
732     TPMPassthroughOptions *tpo;
733     TPMEmulatorOptions *teo;
734 
735     info_list = qmp_query_tpm(&err);
736     if (err) {
737         monitor_printf(mon, "TPM device not supported\n");
738         error_free(err);
739         return;
740     }
741 
742     if (info_list) {
743         monitor_printf(mon, "TPM device:\n");
744     }
745 
746     for (info = info_list; info; info = info->next) {
747         TPMInfo *ti = info->value;
748         monitor_printf(mon, " tpm%d: model=%s\n",
749                        c, TpmModel_str(ti->model));
750 
751         monitor_printf(mon, "  \\ %s: type=%s",
752                        ti->id, TpmType_str(ti->options->type));
753 
754         switch (ti->options->type) {
755         case TPM_TYPE_PASSTHROUGH:
756             tpo = ti->options->u.passthrough.data;
757             monitor_printf(mon, "%s%s%s%s",
758                            tpo->path ? ",path=" : "",
759                            tpo->path ?: "",
760                            tpo->cancel_path ? ",cancel-path=" : "",
761                            tpo->cancel_path ?: "");
762             break;
763         case TPM_TYPE_EMULATOR:
764             teo = ti->options->u.emulator.data;
765             monitor_printf(mon, ",chardev=%s", teo->chardev);
766             break;
767         case TPM_TYPE__MAX:
768             break;
769         }
770         monitor_printf(mon, "\n");
771         c++;
772     }
773     qapi_free_TPMInfoList(info_list);
774 #else
775     monitor_printf(mon, "TPM device not supported\n");
776 #endif /* CONFIG_TPM */
777 }
778 
779 void hmp_quit(Monitor *mon, const QDict *qdict)
780 {
781     monitor_suspend(mon);
782     qmp_quit(NULL);
783 }
784 
785 void hmp_stop(Monitor *mon, const QDict *qdict)
786 {
787     qmp_stop(NULL);
788 }
789 
790 void hmp_sync_profile(Monitor *mon, const QDict *qdict)
791 {
792     const char *op = qdict_get_try_str(qdict, "op");
793 
794     if (op == NULL) {
795         bool on = qsp_is_enabled();
796 
797         monitor_printf(mon, "sync-profile is %s\n", on ? "on" : "off");
798         return;
799     }
800     if (!strcmp(op, "on")) {
801         qsp_enable();
802     } else if (!strcmp(op, "off")) {
803         qsp_disable();
804     } else if (!strcmp(op, "reset")) {
805         qsp_reset();
806     } else {
807         Error *err = NULL;
808 
809         error_setg(&err, QERR_INVALID_PARAMETER, op);
810         hmp_handle_error(mon, err);
811     }
812 }
813 
814 void hmp_system_reset(Monitor *mon, const QDict *qdict)
815 {
816     qmp_system_reset(NULL);
817 }
818 
819 void hmp_system_powerdown(Monitor *mon, const QDict *qdict)
820 {
821     qmp_system_powerdown(NULL);
822 }
823 
824 void hmp_exit_preconfig(Monitor *mon, const QDict *qdict)
825 {
826     Error *err = NULL;
827 
828     qmp_x_exit_preconfig(&err);
829     hmp_handle_error(mon, err);
830 }
831 
832 void hmp_cpu(Monitor *mon, const QDict *qdict)
833 {
834     int64_t cpu_index;
835 
836     /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
837             use it are converted to the QAPI */
838     cpu_index = qdict_get_int(qdict, "index");
839     if (monitor_set_cpu(mon, cpu_index) < 0) {
840         monitor_printf(mon, "invalid CPU index\n");
841     }
842 }
843 
844 void hmp_memsave(Monitor *mon, const QDict *qdict)
845 {
846     uint32_t size = qdict_get_int(qdict, "size");
847     const char *filename = qdict_get_str(qdict, "filename");
848     uint64_t addr = qdict_get_int(qdict, "val");
849     Error *err = NULL;
850     int cpu_index = monitor_get_cpu_index(mon);
851 
852     if (cpu_index < 0) {
853         monitor_printf(mon, "No CPU available\n");
854         return;
855     }
856 
857     qmp_memsave(addr, size, filename, true, cpu_index, &err);
858     hmp_handle_error(mon, err);
859 }
860 
861 void hmp_pmemsave(Monitor *mon, const QDict *qdict)
862 {
863     uint32_t size = qdict_get_int(qdict, "size");
864     const char *filename = qdict_get_str(qdict, "filename");
865     uint64_t addr = qdict_get_int(qdict, "val");
866     Error *err = NULL;
867 
868     qmp_pmemsave(addr, size, filename, &err);
869     hmp_handle_error(mon, err);
870 }
871 
872 void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
873 {
874     const char *chardev = qdict_get_str(qdict, "device");
875     const char *data = qdict_get_str(qdict, "data");
876     Error *err = NULL;
877 
878     qmp_ringbuf_write(chardev, data, false, 0, &err);
879 
880     hmp_handle_error(mon, err);
881 }
882 
883 void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
884 {
885     uint32_t size = qdict_get_int(qdict, "size");
886     const char *chardev = qdict_get_str(qdict, "device");
887     char *data;
888     Error *err = NULL;
889     int i;
890 
891     data = qmp_ringbuf_read(chardev, size, false, 0, &err);
892     if (hmp_handle_error(mon, err)) {
893         return;
894     }
895 
896     for (i = 0; data[i]; i++) {
897         unsigned char ch = data[i];
898 
899         if (ch == '\\') {
900             monitor_printf(mon, "\\\\");
901         } else if ((ch < 0x20 && ch != '\n' && ch != '\t') || ch == 0x7F) {
902             monitor_printf(mon, "\\u%04X", ch);
903         } else {
904             monitor_printf(mon, "%c", ch);
905         }
906 
907     }
908     monitor_printf(mon, "\n");
909     g_free(data);
910 }
911 
912 void hmp_cont(Monitor *mon, const QDict *qdict)
913 {
914     Error *err = NULL;
915 
916     qmp_cont(&err);
917     hmp_handle_error(mon, err);
918 }
919 
920 void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
921 {
922     Error *err = NULL;
923 
924     qmp_system_wakeup(&err);
925     hmp_handle_error(mon, err);
926 }
927 
928 void hmp_nmi(Monitor *mon, const QDict *qdict)
929 {
930     Error *err = NULL;
931 
932     qmp_inject_nmi(&err);
933     hmp_handle_error(mon, err);
934 }
935 
936 void hmp_set_link(Monitor *mon, const QDict *qdict)
937 {
938     const char *name = qdict_get_str(qdict, "name");
939     bool up = qdict_get_bool(qdict, "up");
940     Error *err = NULL;
941 
942     qmp_set_link(name, up, &err);
943     hmp_handle_error(mon, err);
944 }
945 
946 void hmp_balloon(Monitor *mon, const QDict *qdict)
947 {
948     int64_t value = qdict_get_int(qdict, "value");
949     Error *err = NULL;
950 
951     qmp_balloon(value, &err);
952     hmp_handle_error(mon, err);
953 }
954 
955 void hmp_loadvm(Monitor *mon, const QDict *qdict)
956 {
957     int saved_vm_running  = runstate_is_running();
958     const char *name = qdict_get_str(qdict, "name");
959     Error *err = NULL;
960 
961     vm_stop(RUN_STATE_RESTORE_VM);
962 
963     if (load_snapshot(name, NULL, false, NULL, &err) && saved_vm_running) {
964         vm_start();
965     }
966     hmp_handle_error(mon, err);
967 }
968 
969 void hmp_savevm(Monitor *mon, const QDict *qdict)
970 {
971     Error *err = NULL;
972 
973     save_snapshot(qdict_get_try_str(qdict, "name"),
974                   true, NULL, false, NULL, &err);
975     hmp_handle_error(mon, err);
976 }
977 
978 void hmp_delvm(Monitor *mon, const QDict *qdict)
979 {
980     Error *err = NULL;
981     const char *name = qdict_get_str(qdict, "name");
982 
983     delete_snapshot(name, false, NULL, &err);
984     hmp_handle_error(mon, err);
985 }
986 
987 void hmp_announce_self(Monitor *mon, const QDict *qdict)
988 {
989     const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
990     const char *id = qdict_get_try_str(qdict, "id");
991     AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
992                                             migrate_announce_params());
993 
994     qapi_free_strList(params->interfaces);
995     params->interfaces = strList_from_comma_list(interfaces_str);
996     params->has_interfaces = params->interfaces != NULL;
997     params->id = g_strdup(id);
998     qmp_announce_self(params, NULL);
999     qapi_free_AnnounceParameters(params);
1000 }
1001 
1002 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
1003 {
1004     qmp_migrate_cancel(NULL);
1005 }
1006 
1007 void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
1008 {
1009     Error *err = NULL;
1010     const char *state = qdict_get_str(qdict, "state");
1011     int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
1012 
1013     if (val >= 0) {
1014         qmp_migrate_continue(val, &err);
1015     }
1016 
1017     hmp_handle_error(mon, err);
1018 }
1019 
1020 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
1021 {
1022     Error *err = NULL;
1023     const char *uri = qdict_get_str(qdict, "uri");
1024 
1025     qmp_migrate_incoming(uri, &err);
1026 
1027     hmp_handle_error(mon, err);
1028 }
1029 
1030 void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
1031 {
1032     Error *err = NULL;
1033     const char *uri = qdict_get_str(qdict, "uri");
1034 
1035     qmp_migrate_recover(uri, &err);
1036 
1037     hmp_handle_error(mon, err);
1038 }
1039 
1040 void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
1041 {
1042     Error *err = NULL;
1043 
1044     qmp_migrate_pause(&err);
1045 
1046     hmp_handle_error(mon, err);
1047 }
1048 
1049 
1050 void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
1051 {
1052     const char *cap = qdict_get_str(qdict, "capability");
1053     bool state = qdict_get_bool(qdict, "state");
1054     Error *err = NULL;
1055     MigrationCapabilityStatusList *caps = NULL;
1056     MigrationCapabilityStatus *value;
1057     int val;
1058 
1059     val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err);
1060     if (val < 0) {
1061         goto end;
1062     }
1063 
1064     value = g_malloc0(sizeof(*value));
1065     value->capability = val;
1066     value->state = state;
1067     QAPI_LIST_PREPEND(caps, value);
1068     qmp_migrate_set_capabilities(caps, &err);
1069     qapi_free_MigrationCapabilityStatusList(caps);
1070 
1071 end:
1072     hmp_handle_error(mon, err);
1073 }
1074 
1075 void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
1076 {
1077     const char *param = qdict_get_str(qdict, "parameter");
1078     const char *valuestr = qdict_get_str(qdict, "value");
1079     Visitor *v = string_input_visitor_new(valuestr);
1080     MigrateSetParameters *p = g_new0(MigrateSetParameters, 1);
1081     uint64_t valuebw = 0;
1082     uint64_t cache_size;
1083     Error *err = NULL;
1084     int val, ret;
1085 
1086     val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err);
1087     if (val < 0) {
1088         goto cleanup;
1089     }
1090 
1091     switch (val) {
1092     case MIGRATION_PARAMETER_COMPRESS_LEVEL:
1093         p->has_compress_level = true;
1094         visit_type_uint8(v, param, &p->compress_level, &err);
1095         break;
1096     case MIGRATION_PARAMETER_COMPRESS_THREADS:
1097         p->has_compress_threads = true;
1098         visit_type_uint8(v, param, &p->compress_threads, &err);
1099         break;
1100     case MIGRATION_PARAMETER_COMPRESS_WAIT_THREAD:
1101         p->has_compress_wait_thread = true;
1102         visit_type_bool(v, param, &p->compress_wait_thread, &err);
1103         break;
1104     case MIGRATION_PARAMETER_DECOMPRESS_THREADS:
1105         p->has_decompress_threads = true;
1106         visit_type_uint8(v, param, &p->decompress_threads, &err);
1107         break;
1108     case MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD:
1109         p->has_throttle_trigger_threshold = true;
1110         visit_type_uint8(v, param, &p->throttle_trigger_threshold, &err);
1111         break;
1112     case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL:
1113         p->has_cpu_throttle_initial = true;
1114         visit_type_uint8(v, param, &p->cpu_throttle_initial, &err);
1115         break;
1116     case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT:
1117         p->has_cpu_throttle_increment = true;
1118         visit_type_uint8(v, param, &p->cpu_throttle_increment, &err);
1119         break;
1120     case MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW:
1121         p->has_cpu_throttle_tailslow = true;
1122         visit_type_bool(v, param, &p->cpu_throttle_tailslow, &err);
1123         break;
1124     case MIGRATION_PARAMETER_MAX_CPU_THROTTLE:
1125         p->has_max_cpu_throttle = true;
1126         visit_type_uint8(v, param, &p->max_cpu_throttle, &err);
1127         break;
1128     case MIGRATION_PARAMETER_TLS_CREDS:
1129         p->tls_creds = g_new0(StrOrNull, 1);
1130         p->tls_creds->type = QTYPE_QSTRING;
1131         visit_type_str(v, param, &p->tls_creds->u.s, &err);
1132         break;
1133     case MIGRATION_PARAMETER_TLS_HOSTNAME:
1134         p->tls_hostname = g_new0(StrOrNull, 1);
1135         p->tls_hostname->type = QTYPE_QSTRING;
1136         visit_type_str(v, param, &p->tls_hostname->u.s, &err);
1137         break;
1138     case MIGRATION_PARAMETER_TLS_AUTHZ:
1139         p->tls_authz = g_new0(StrOrNull, 1);
1140         p->tls_authz->type = QTYPE_QSTRING;
1141         visit_type_str(v, param, &p->tls_authz->u.s, &err);
1142         break;
1143     case MIGRATION_PARAMETER_MAX_BANDWIDTH:
1144         p->has_max_bandwidth = true;
1145         /*
1146          * Can't use visit_type_size() here, because it
1147          * defaults to Bytes rather than Mebibytes.
1148          */
1149         ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
1150         if (ret < 0 || valuebw > INT64_MAX
1151             || (size_t)valuebw != valuebw) {
1152             error_setg(&err, "Invalid size %s", valuestr);
1153             break;
1154         }
1155         p->max_bandwidth = valuebw;
1156         break;
1157     case MIGRATION_PARAMETER_DOWNTIME_LIMIT:
1158         p->has_downtime_limit = true;
1159         visit_type_size(v, param, &p->downtime_limit, &err);
1160         break;
1161     case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY:
1162         p->has_x_checkpoint_delay = true;
1163         visit_type_uint32(v, param, &p->x_checkpoint_delay, &err);
1164         break;
1165     case MIGRATION_PARAMETER_BLOCK_INCREMENTAL:
1166         p->has_block_incremental = true;
1167         visit_type_bool(v, param, &p->block_incremental, &err);
1168         break;
1169     case MIGRATION_PARAMETER_MULTIFD_CHANNELS:
1170         p->has_multifd_channels = true;
1171         visit_type_uint8(v, param, &p->multifd_channels, &err);
1172         break;
1173     case MIGRATION_PARAMETER_MULTIFD_COMPRESSION:
1174         p->has_multifd_compression = true;
1175         visit_type_MultiFDCompression(v, param, &p->multifd_compression,
1176                                       &err);
1177         break;
1178     case MIGRATION_PARAMETER_MULTIFD_ZLIB_LEVEL:
1179         p->has_multifd_zlib_level = true;
1180         visit_type_uint8(v, param, &p->multifd_zlib_level, &err);
1181         break;
1182     case MIGRATION_PARAMETER_MULTIFD_ZSTD_LEVEL:
1183         p->has_multifd_zstd_level = true;
1184         visit_type_uint8(v, param, &p->multifd_zstd_level, &err);
1185         break;
1186     case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE:
1187         p->has_xbzrle_cache_size = true;
1188         if (!visit_type_size(v, param, &cache_size, &err)) {
1189             break;
1190         }
1191         if (cache_size > INT64_MAX || (size_t)cache_size != cache_size) {
1192             error_setg(&err, "Invalid size %s", valuestr);
1193             break;
1194         }
1195         p->xbzrle_cache_size = cache_size;
1196         break;
1197     case MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH:
1198         p->has_max_postcopy_bandwidth = true;
1199         visit_type_size(v, param, &p->max_postcopy_bandwidth, &err);
1200         break;
1201     case MIGRATION_PARAMETER_ANNOUNCE_INITIAL:
1202         p->has_announce_initial = true;
1203         visit_type_size(v, param, &p->announce_initial, &err);
1204         break;
1205     case MIGRATION_PARAMETER_ANNOUNCE_MAX:
1206         p->has_announce_max = true;
1207         visit_type_size(v, param, &p->announce_max, &err);
1208         break;
1209     case MIGRATION_PARAMETER_ANNOUNCE_ROUNDS:
1210         p->has_announce_rounds = true;
1211         visit_type_size(v, param, &p->announce_rounds, &err);
1212         break;
1213     case MIGRATION_PARAMETER_ANNOUNCE_STEP:
1214         p->has_announce_step = true;
1215         visit_type_size(v, param, &p->announce_step, &err);
1216         break;
1217     case MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING:
1218         error_setg(&err, "The block-bitmap-mapping parameter can only be set "
1219                    "through QMP");
1220         break;
1221     default:
1222         assert(0);
1223     }
1224 
1225     if (err) {
1226         goto cleanup;
1227     }
1228 
1229     qmp_migrate_set_parameters(p, &err);
1230 
1231  cleanup:
1232     qapi_free_MigrateSetParameters(p);
1233     visit_free(v);
1234     hmp_handle_error(mon, err);
1235 }
1236 
1237 void hmp_client_migrate_info(Monitor *mon, const QDict *qdict)
1238 {
1239     Error *err = NULL;
1240     const char *protocol = qdict_get_str(qdict, "protocol");
1241     const char *hostname = qdict_get_str(qdict, "hostname");
1242     bool has_port        = qdict_haskey(qdict, "port");
1243     int port             = qdict_get_try_int(qdict, "port", -1);
1244     bool has_tls_port    = qdict_haskey(qdict, "tls-port");
1245     int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
1246     const char *cert_subject = qdict_get_try_str(qdict, "cert-subject");
1247 
1248     qmp_client_migrate_info(protocol, hostname,
1249                             has_port, port, has_tls_port, tls_port,
1250                             cert_subject, &err);
1251     hmp_handle_error(mon, err);
1252 }
1253 
1254 void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict)
1255 {
1256     Error *err = NULL;
1257     qmp_migrate_start_postcopy(&err);
1258     hmp_handle_error(mon, err);
1259 }
1260 
1261 void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict)
1262 {
1263     Error *err = NULL;
1264 
1265     qmp_x_colo_lost_heartbeat(&err);
1266     hmp_handle_error(mon, err);
1267 }
1268 
1269 void hmp_set_password(Monitor *mon, const QDict *qdict)
1270 {
1271     const char *protocol  = qdict_get_str(qdict, "protocol");
1272     const char *password  = qdict_get_str(qdict, "password");
1273     const char *display = qdict_get_try_str(qdict, "display");
1274     const char *connected = qdict_get_try_str(qdict, "connected");
1275     Error *err = NULL;
1276 
1277     SetPasswordOptions opts = {
1278         .password = (char *)password,
1279         .has_connected = !!connected,
1280     };
1281 
1282     opts.connected = qapi_enum_parse(&SetPasswordAction_lookup, connected,
1283                                      SET_PASSWORD_ACTION_KEEP, &err);
1284     if (err) {
1285         goto out;
1286     }
1287 
1288     opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
1289                                     DISPLAY_PROTOCOL_VNC, &err);
1290     if (err) {
1291         goto out;
1292     }
1293 
1294     if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
1295         opts.u.vnc.display = (char *)display;
1296     }
1297 
1298     qmp_set_password(&opts, &err);
1299 
1300 out:
1301     hmp_handle_error(mon, err);
1302 }
1303 
1304 void hmp_expire_password(Monitor *mon, const QDict *qdict)
1305 {
1306     const char *protocol  = qdict_get_str(qdict, "protocol");
1307     const char *whenstr = qdict_get_str(qdict, "time");
1308     const char *display = qdict_get_try_str(qdict, "display");
1309     Error *err = NULL;
1310 
1311     ExpirePasswordOptions opts = {
1312         .time = (char *)whenstr,
1313     };
1314 
1315     opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
1316                                     DISPLAY_PROTOCOL_VNC, &err);
1317     if (err) {
1318         goto out;
1319     }
1320 
1321     if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
1322         opts.u.vnc.display = (char *)display;
1323     }
1324 
1325     qmp_expire_password(&opts, &err);
1326 
1327 out:
1328     hmp_handle_error(mon, err);
1329 }
1330 
1331 
1332 #ifdef CONFIG_VNC
1333 static void hmp_change_read_arg(void *opaque, const char *password,
1334                                 void *readline_opaque)
1335 {
1336     qmp_change_vnc_password(password, NULL);
1337     monitor_read_command(opaque, 1);
1338 }
1339 #endif
1340 
1341 void hmp_change(Monitor *mon, const QDict *qdict)
1342 {
1343     const char *device = qdict_get_str(qdict, "device");
1344     const char *target = qdict_get_str(qdict, "target");
1345     const char *arg = qdict_get_try_str(qdict, "arg");
1346     const char *read_only = qdict_get_try_str(qdict, "read-only-mode");
1347     bool force = qdict_get_try_bool(qdict, "force", false);
1348     BlockdevChangeReadOnlyMode read_only_mode = 0;
1349     Error *err = NULL;
1350 
1351 #ifdef CONFIG_VNC
1352     if (strcmp(device, "vnc") == 0) {
1353         if (read_only) {
1354             monitor_printf(mon,
1355                            "Parameter 'read-only-mode' is invalid for VNC\n");
1356             return;
1357         }
1358         if (strcmp(target, "passwd") == 0 ||
1359             strcmp(target, "password") == 0) {
1360             if (!arg) {
1361                 MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
1362                 monitor_read_password(hmp_mon, hmp_change_read_arg, NULL);
1363                 return;
1364             } else {
1365                 qmp_change_vnc_password(arg, &err);
1366             }
1367         } else {
1368             monitor_printf(mon, "Expected 'password' after 'vnc'\n");
1369         }
1370     } else
1371 #endif
1372     {
1373         if (read_only) {
1374             read_only_mode =
1375                 qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup,
1376                                 read_only,
1377                                 BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err);
1378             if (err) {
1379                 goto end;
1380             }
1381         }
1382 
1383         qmp_blockdev_change_medium(device, NULL, target, arg, true, force,
1384                                    !!read_only, read_only_mode,
1385                                    &err);
1386     }
1387 
1388 end:
1389     hmp_handle_error(mon, err);
1390 }
1391 
1392 typedef struct HMPMigrationStatus {
1393     QEMUTimer *timer;
1394     Monitor *mon;
1395     bool is_block_migration;
1396 } HMPMigrationStatus;
1397 
1398 static void hmp_migrate_status_cb(void *opaque)
1399 {
1400     HMPMigrationStatus *status = opaque;
1401     MigrationInfo *info;
1402 
1403     info = qmp_query_migrate(NULL);
1404     if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE ||
1405         info->status == MIGRATION_STATUS_SETUP) {
1406         if (info->disk) {
1407             int progress;
1408 
1409             if (info->disk->remaining) {
1410                 progress = info->disk->transferred * 100 / info->disk->total;
1411             } else {
1412                 progress = 100;
1413             }
1414 
1415             monitor_printf(status->mon, "Completed %d %%\r", progress);
1416             monitor_flush(status->mon);
1417         }
1418 
1419         timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
1420     } else {
1421         if (status->is_block_migration) {
1422             monitor_printf(status->mon, "\n");
1423         }
1424         if (info->error_desc) {
1425             error_report("%s", info->error_desc);
1426         }
1427         monitor_resume(status->mon);
1428         timer_free(status->timer);
1429         g_free(status);
1430     }
1431 
1432     qapi_free_MigrationInfo(info);
1433 }
1434 
1435 void hmp_migrate(Monitor *mon, const QDict *qdict)
1436 {
1437     bool detach = qdict_get_try_bool(qdict, "detach", false);
1438     bool blk = qdict_get_try_bool(qdict, "blk", false);
1439     bool inc = qdict_get_try_bool(qdict, "inc", false);
1440     bool resume = qdict_get_try_bool(qdict, "resume", false);
1441     const char *uri = qdict_get_str(qdict, "uri");
1442     Error *err = NULL;
1443 
1444     qmp_migrate(uri, !!blk, blk, !!inc, inc,
1445                 false, false, true, resume, &err);
1446     if (hmp_handle_error(mon, err)) {
1447         return;
1448     }
1449 
1450     if (!detach) {
1451         HMPMigrationStatus *status;
1452 
1453         if (monitor_suspend(mon) < 0) {
1454             monitor_printf(mon, "terminal does not allow synchronous "
1455                            "migration, continuing detached\n");
1456             return;
1457         }
1458 
1459         status = g_malloc0(sizeof(*status));
1460         status->mon = mon;
1461         status->is_block_migration = blk || inc;
1462         status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb,
1463                                           status);
1464         timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
1465     }
1466 }
1467 
1468 void hmp_netdev_add(Monitor *mon, const QDict *qdict)
1469 {
1470     Error *err = NULL;
1471     QemuOpts *opts;
1472     const char *type = qdict_get_try_str(qdict, "type");
1473 
1474     if (type && is_help_option(type)) {
1475         show_netdevs();
1476         return;
1477     }
1478     opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
1479     if (err) {
1480         goto out;
1481     }
1482 
1483     netdev_add(opts, &err);
1484     if (err) {
1485         qemu_opts_del(opts);
1486     }
1487 
1488 out:
1489     hmp_handle_error(mon, err);
1490 }
1491 
1492 void hmp_netdev_del(Monitor *mon, const QDict *qdict)
1493 {
1494     const char *id = qdict_get_str(qdict, "id");
1495     Error *err = NULL;
1496 
1497     qmp_netdev_del(id, &err);
1498     hmp_handle_error(mon, err);
1499 }
1500 
1501 void hmp_object_add(Monitor *mon, const QDict *qdict)
1502 {
1503     const char *options = qdict_get_str(qdict, "object");
1504     Error *err = NULL;
1505 
1506     user_creatable_add_from_str(options, &err);
1507     hmp_handle_error(mon, err);
1508 }
1509 
1510 void hmp_getfd(Monitor *mon, const QDict *qdict)
1511 {
1512     const char *fdname = qdict_get_str(qdict, "fdname");
1513     Error *err = NULL;
1514 
1515     qmp_getfd(fdname, &err);
1516     hmp_handle_error(mon, err);
1517 }
1518 
1519 void hmp_closefd(Monitor *mon, const QDict *qdict)
1520 {
1521     const char *fdname = qdict_get_str(qdict, "fdname");
1522     Error *err = NULL;
1523 
1524     qmp_closefd(fdname, &err);
1525     hmp_handle_error(mon, err);
1526 }
1527 
1528 void hmp_sendkey(Monitor *mon, const QDict *qdict)
1529 {
1530     const char *keys = qdict_get_str(qdict, "keys");
1531     KeyValue *v = NULL;
1532     KeyValueList *head = NULL, **tail = &head;
1533     int has_hold_time = qdict_haskey(qdict, "hold-time");
1534     int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
1535     Error *err = NULL;
1536     const char *separator;
1537     int keyname_len;
1538 
1539     while (1) {
1540         separator = qemu_strchrnul(keys, '-');
1541         keyname_len = separator - keys;
1542 
1543         /* Be compatible with old interface, convert user inputted "<" */
1544         if (keys[0] == '<' && keyname_len == 1) {
1545             keys = "less";
1546             keyname_len = 4;
1547         }
1548 
1549         v = g_malloc0(sizeof(*v));
1550 
1551         if (strstart(keys, "0x", NULL)) {
1552             char *endp;
1553             int value = strtoul(keys, &endp, 0);
1554             assert(endp <= keys + keyname_len);
1555             if (endp != keys + keyname_len) {
1556                 goto err_out;
1557             }
1558             v->type = KEY_VALUE_KIND_NUMBER;
1559             v->u.number.data = value;
1560         } else {
1561             int idx = index_from_key(keys, keyname_len);
1562             if (idx == Q_KEY_CODE__MAX) {
1563                 goto err_out;
1564             }
1565             v->type = KEY_VALUE_KIND_QCODE;
1566             v->u.qcode.data = idx;
1567         }
1568         QAPI_LIST_APPEND(tail, v);
1569         v = NULL;
1570 
1571         if (!*separator) {
1572             break;
1573         }
1574         keys = separator + 1;
1575     }
1576 
1577     qmp_send_key(head, has_hold_time, hold_time, &err);
1578     hmp_handle_error(mon, err);
1579 
1580 out:
1581     qapi_free_KeyValue(v);
1582     qapi_free_KeyValueList(head);
1583     return;
1584 
1585 err_out:
1586     monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
1587     goto out;
1588 }
1589 
1590 void coroutine_fn
1591 hmp_screendump(Monitor *mon, const QDict *qdict)
1592 {
1593     const char *filename = qdict_get_str(qdict, "filename");
1594     const char *id = qdict_get_try_str(qdict, "device");
1595     int64_t head = qdict_get_try_int(qdict, "head", 0);
1596     const char *input_format  = qdict_get_try_str(qdict, "format");
1597     Error *err = NULL;
1598     ImageFormat format;
1599 
1600     format = qapi_enum_parse(&ImageFormat_lookup, input_format,
1601                               IMAGE_FORMAT_PPM, &err);
1602     if (err) {
1603         goto end;
1604     }
1605 
1606     qmp_screendump(filename, id, id != NULL, head,
1607                    input_format != NULL, format, &err);
1608 end:
1609     hmp_handle_error(mon, err);
1610 }
1611 
1612 void hmp_chardev_add(Monitor *mon, const QDict *qdict)
1613 {
1614     const char *args = qdict_get_str(qdict, "args");
1615     Error *err = NULL;
1616     QemuOpts *opts;
1617 
1618     opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, true);
1619     if (opts == NULL) {
1620         error_setg(&err, "Parsing chardev args failed");
1621     } else {
1622         qemu_chr_new_from_opts(opts, NULL, &err);
1623         qemu_opts_del(opts);
1624     }
1625     hmp_handle_error(mon, err);
1626 }
1627 
1628 void hmp_chardev_change(Monitor *mon, const QDict *qdict)
1629 {
1630     const char *args = qdict_get_str(qdict, "args");
1631     const char *id;
1632     Error *err = NULL;
1633     ChardevBackend *backend = NULL;
1634     ChardevReturn *ret = NULL;
1635     QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args,
1636                                              true);
1637     if (!opts) {
1638         error_setg(&err, "Parsing chardev args failed");
1639         goto end;
1640     }
1641 
1642     id = qdict_get_str(qdict, "id");
1643     if (qemu_opts_id(opts)) {
1644         error_setg(&err, "Unexpected 'id' parameter");
1645         goto end;
1646     }
1647 
1648     backend = qemu_chr_parse_opts(opts, &err);
1649     if (!backend) {
1650         goto end;
1651     }
1652 
1653     ret = qmp_chardev_change(id, backend, &err);
1654 
1655 end:
1656     qapi_free_ChardevReturn(ret);
1657     qapi_free_ChardevBackend(backend);
1658     qemu_opts_del(opts);
1659     hmp_handle_error(mon, err);
1660 }
1661 
1662 void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
1663 {
1664     Error *local_err = NULL;
1665 
1666     qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
1667     hmp_handle_error(mon, local_err);
1668 }
1669 
1670 void hmp_chardev_send_break(Monitor *mon, const QDict *qdict)
1671 {
1672     Error *local_err = NULL;
1673 
1674     qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err);
1675     hmp_handle_error(mon, local_err);
1676 }
1677 
1678 void hmp_object_del(Monitor *mon, const QDict *qdict)
1679 {
1680     const char *id = qdict_get_str(qdict, "id");
1681     Error *err = NULL;
1682 
1683     user_creatable_del(id, &err);
1684     hmp_handle_error(mon, err);
1685 }
1686 
1687 void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
1688 {
1689     Error *err = NULL;
1690     MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
1691     MemoryDeviceInfoList *info;
1692     VirtioPMEMDeviceInfo *vpi;
1693     VirtioMEMDeviceInfo *vmi;
1694     MemoryDeviceInfo *value;
1695     PCDIMMDeviceInfo *di;
1696     SgxEPCDeviceInfo *se;
1697 
1698     for (info = info_list; info; info = info->next) {
1699         value = info->value;
1700 
1701         if (value) {
1702             switch (value->type) {
1703             case MEMORY_DEVICE_INFO_KIND_DIMM:
1704             case MEMORY_DEVICE_INFO_KIND_NVDIMM:
1705                 di = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ?
1706                      value->u.dimm.data : value->u.nvdimm.data;
1707                 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
1708                                MemoryDeviceInfoKind_str(value->type),
1709                                di->id ? di->id : "");
1710                 monitor_printf(mon, "  addr: 0x%" PRIx64 "\n", di->addr);
1711                 monitor_printf(mon, "  slot: %" PRId64 "\n", di->slot);
1712                 monitor_printf(mon, "  node: %" PRId64 "\n", di->node);
1713                 monitor_printf(mon, "  size: %" PRIu64 "\n", di->size);
1714                 monitor_printf(mon, "  memdev: %s\n", di->memdev);
1715                 monitor_printf(mon, "  hotplugged: %s\n",
1716                                di->hotplugged ? "true" : "false");
1717                 monitor_printf(mon, "  hotpluggable: %s\n",
1718                                di->hotpluggable ? "true" : "false");
1719                 break;
1720             case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM:
1721                 vpi = value->u.virtio_pmem.data;
1722                 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
1723                                MemoryDeviceInfoKind_str(value->type),
1724                                vpi->id ? vpi->id : "");
1725                 monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", vpi->memaddr);
1726                 monitor_printf(mon, "  size: %" PRIu64 "\n", vpi->size);
1727                 monitor_printf(mon, "  memdev: %s\n", vpi->memdev);
1728                 break;
1729             case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM:
1730                 vmi = value->u.virtio_mem.data;
1731                 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
1732                                MemoryDeviceInfoKind_str(value->type),
1733                                vmi->id ? vmi->id : "");
1734                 monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", vmi->memaddr);
1735                 monitor_printf(mon, "  node: %" PRId64 "\n", vmi->node);
1736                 monitor_printf(mon, "  requested-size: %" PRIu64 "\n",
1737                                vmi->requested_size);
1738                 monitor_printf(mon, "  size: %" PRIu64 "\n", vmi->size);
1739                 monitor_printf(mon, "  max-size: %" PRIu64 "\n", vmi->max_size);
1740                 monitor_printf(mon, "  block-size: %" PRIu64 "\n",
1741                                vmi->block_size);
1742                 monitor_printf(mon, "  memdev: %s\n", vmi->memdev);
1743                 break;
1744             case MEMORY_DEVICE_INFO_KIND_SGX_EPC:
1745                 se = value->u.sgx_epc.data;
1746                 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
1747                                MemoryDeviceInfoKind_str(value->type),
1748                                se->id ? se->id : "");
1749                 monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", se->memaddr);
1750                 monitor_printf(mon, "  size: %" PRIu64 "\n", se->size);
1751                 monitor_printf(mon, "  node: %" PRId64 "\n", se->node);
1752                 monitor_printf(mon, "  memdev: %s\n", se->memdev);
1753                 break;
1754             default:
1755                 g_assert_not_reached();
1756             }
1757         }
1758     }
1759 
1760     qapi_free_MemoryDeviceInfoList(info_list);
1761     hmp_handle_error(mon, err);
1762 }
1763 
1764 void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
1765 {
1766     IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
1767     IOThreadInfoList *info;
1768     IOThreadInfo *value;
1769 
1770     for (info = info_list; info; info = info->next) {
1771         value = info->value;
1772         monitor_printf(mon, "%s:\n", value->id);
1773         monitor_printf(mon, "  thread_id=%" PRId64 "\n", value->thread_id);
1774         monitor_printf(mon, "  poll-max-ns=%" PRId64 "\n", value->poll_max_ns);
1775         monitor_printf(mon, "  poll-grow=%" PRId64 "\n", value->poll_grow);
1776         monitor_printf(mon, "  poll-shrink=%" PRId64 "\n", value->poll_shrink);
1777         monitor_printf(mon, "  aio-max-batch=%" PRId64 "\n",
1778                        value->aio_max_batch);
1779     }
1780 
1781     qapi_free_IOThreadInfoList(info_list);
1782 }
1783 
1784 void hmp_rocker(Monitor *mon, const QDict *qdict)
1785 {
1786     const char *name = qdict_get_str(qdict, "name");
1787     RockerSwitch *rocker;
1788     Error *err = NULL;
1789 
1790     rocker = qmp_query_rocker(name, &err);
1791     if (hmp_handle_error(mon, err)) {
1792         return;
1793     }
1794 
1795     monitor_printf(mon, "name: %s\n", rocker->name);
1796     monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id);
1797     monitor_printf(mon, "ports: %d\n", rocker->ports);
1798 
1799     qapi_free_RockerSwitch(rocker);
1800 }
1801 
1802 void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
1803 {
1804     RockerPortList *list, *port;
1805     const char *name = qdict_get_str(qdict, "name");
1806     Error *err = NULL;
1807 
1808     list = qmp_query_rocker_ports(name, &err);
1809     if (hmp_handle_error(mon, err)) {
1810         return;
1811     }
1812 
1813     monitor_printf(mon, "            ena/    speed/ auto\n");
1814     monitor_printf(mon, "      port  link    duplex neg?\n");
1815 
1816     for (port = list; port; port = port->next) {
1817         monitor_printf(mon, "%10s  %-4s   %-3s  %2s  %s\n",
1818                        port->value->name,
1819                        port->value->enabled ? port->value->link_up ?
1820                        "up" : "down" : "!ena",
1821                        port->value->speed == 10000 ? "10G" : "??",
1822                        port->value->duplex ? "FD" : "HD",
1823                        port->value->autoneg ? "Yes" : "No");
1824     }
1825 
1826     qapi_free_RockerPortList(list);
1827 }
1828 
1829 void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
1830 {
1831     RockerOfDpaFlowList *list, *info;
1832     const char *name = qdict_get_str(qdict, "name");
1833     uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1);
1834     Error *err = NULL;
1835 
1836     list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &err);
1837     if (hmp_handle_error(mon, err)) {
1838         return;
1839     }
1840 
1841     monitor_printf(mon, "prio tbl hits key(mask) --> actions\n");
1842 
1843     for (info = list; info; info = info->next) {
1844         RockerOfDpaFlow *flow = info->value;
1845         RockerOfDpaFlowKey *key = flow->key;
1846         RockerOfDpaFlowMask *mask = flow->mask;
1847         RockerOfDpaFlowAction *action = flow->action;
1848 
1849         if (flow->hits) {
1850             monitor_printf(mon, "%-4d %-3d %-4" PRIu64,
1851                            key->priority, key->tbl_id, flow->hits);
1852         } else {
1853             monitor_printf(mon, "%-4d %-3d     ",
1854                            key->priority, key->tbl_id);
1855         }
1856 
1857         if (key->has_in_pport) {
1858             monitor_printf(mon, " pport %d", key->in_pport);
1859             if (mask->has_in_pport) {
1860                 monitor_printf(mon, "(0x%x)", mask->in_pport);
1861             }
1862         }
1863 
1864         if (key->has_vlan_id) {
1865             monitor_printf(mon, " vlan %d",
1866                            key->vlan_id & VLAN_VID_MASK);
1867             if (mask->has_vlan_id) {
1868                 monitor_printf(mon, "(0x%x)", mask->vlan_id);
1869             }
1870         }
1871 
1872         if (key->has_tunnel_id) {
1873             monitor_printf(mon, " tunnel %d", key->tunnel_id);
1874             if (mask->has_tunnel_id) {
1875                 monitor_printf(mon, "(0x%x)", mask->tunnel_id);
1876             }
1877         }
1878 
1879         if (key->has_eth_type) {
1880             switch (key->eth_type) {
1881             case 0x0806:
1882                 monitor_printf(mon, " ARP");
1883                 break;
1884             case 0x0800:
1885                 monitor_printf(mon, " IP");
1886                 break;
1887             case 0x86dd:
1888                 monitor_printf(mon, " IPv6");
1889                 break;
1890             case 0x8809:
1891                 monitor_printf(mon, " LACP");
1892                 break;
1893             case 0x88cc:
1894                 monitor_printf(mon, " LLDP");
1895                 break;
1896             default:
1897                 monitor_printf(mon, " eth type 0x%04x", key->eth_type);
1898                 break;
1899             }
1900         }
1901 
1902         if (key->eth_src) {
1903             if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) &&
1904                 mask->eth_src &&
1905                 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
1906                 monitor_printf(mon, " src <any mcast/bcast>");
1907             } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) &&
1908                 mask->eth_src &&
1909                 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
1910                 monitor_printf(mon, " src <any ucast>");
1911             } else {
1912                 monitor_printf(mon, " src %s", key->eth_src);
1913                 if (mask->eth_src) {
1914                     monitor_printf(mon, "(%s)", mask->eth_src);
1915                 }
1916             }
1917         }
1918 
1919         if (key->eth_dst) {
1920             if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) &&
1921                 mask->eth_dst &&
1922                 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
1923                 monitor_printf(mon, " dst <any mcast/bcast>");
1924             } else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) &&
1925                 mask->eth_dst &&
1926                 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
1927                 monitor_printf(mon, " dst <any ucast>");
1928             } else {
1929                 monitor_printf(mon, " dst %s", key->eth_dst);
1930                 if (mask->eth_dst) {
1931                     monitor_printf(mon, "(%s)", mask->eth_dst);
1932                 }
1933             }
1934         }
1935 
1936         if (key->has_ip_proto) {
1937             monitor_printf(mon, " proto %d", key->ip_proto);
1938             if (mask->has_ip_proto) {
1939                 monitor_printf(mon, "(0x%x)", mask->ip_proto);
1940             }
1941         }
1942 
1943         if (key->has_ip_tos) {
1944             monitor_printf(mon, " TOS %d", key->ip_tos);
1945             if (mask->has_ip_tos) {
1946                 monitor_printf(mon, "(0x%x)", mask->ip_tos);
1947             }
1948         }
1949 
1950         if (key->ip_dst) {
1951             monitor_printf(mon, " dst %s", key->ip_dst);
1952         }
1953 
1954         if (action->has_goto_tbl || action->has_group_id ||
1955             action->has_new_vlan_id) {
1956             monitor_printf(mon, " -->");
1957         }
1958 
1959         if (action->has_new_vlan_id) {
1960             monitor_printf(mon, " apply new vlan %d",
1961                            ntohs(action->new_vlan_id));
1962         }
1963 
1964         if (action->has_group_id) {
1965             monitor_printf(mon, " write group 0x%08x", action->group_id);
1966         }
1967 
1968         if (action->has_goto_tbl) {
1969             monitor_printf(mon, " goto tbl %d", action->goto_tbl);
1970         }
1971 
1972         monitor_printf(mon, "\n");
1973     }
1974 
1975     qapi_free_RockerOfDpaFlowList(list);
1976 }
1977 
1978 void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
1979 {
1980     RockerOfDpaGroupList *list, *g;
1981     const char *name = qdict_get_str(qdict, "name");
1982     uint8_t type = qdict_get_try_int(qdict, "type", 9);
1983     Error *err = NULL;
1984 
1985     list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err);
1986     if (hmp_handle_error(mon, err)) {
1987         return;
1988     }
1989 
1990     monitor_printf(mon, "id (decode) --> buckets\n");
1991 
1992     for (g = list; g; g = g->next) {
1993         RockerOfDpaGroup *group = g->value;
1994         bool set = false;
1995 
1996         monitor_printf(mon, "0x%08x", group->id);
1997 
1998         monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" :
1999                                          group->type == 1 ? "L2 rewrite" :
2000                                          group->type == 2 ? "L3 unicast" :
2001                                          group->type == 3 ? "L2 multicast" :
2002                                          group->type == 4 ? "L2 flood" :
2003                                          group->type == 5 ? "L3 interface" :
2004                                          group->type == 6 ? "L3 multicast" :
2005                                          group->type == 7 ? "L3 ECMP" :
2006                                          group->type == 8 ? "L2 overlay" :
2007                                          "unknown");
2008 
2009         if (group->has_vlan_id) {
2010             monitor_printf(mon, " vlan %d", group->vlan_id);
2011         }
2012 
2013         if (group->has_pport) {
2014             monitor_printf(mon, " pport %d", group->pport);
2015         }
2016 
2017         if (group->has_index) {
2018             monitor_printf(mon, " index %d", group->index);
2019         }
2020 
2021         monitor_printf(mon, ") -->");
2022 
2023         if (group->has_set_vlan_id && group->set_vlan_id) {
2024             set = true;
2025             monitor_printf(mon, " set vlan %d",
2026                            group->set_vlan_id & VLAN_VID_MASK);
2027         }
2028 
2029         if (group->set_eth_src) {
2030             if (!set) {
2031                 set = true;
2032                 monitor_printf(mon, " set");
2033             }
2034             monitor_printf(mon, " src %s", group->set_eth_src);
2035         }
2036 
2037         if (group->set_eth_dst) {
2038             if (!set) {
2039                 monitor_printf(mon, " set");
2040             }
2041             monitor_printf(mon, " dst %s", group->set_eth_dst);
2042         }
2043 
2044         if (group->has_ttl_check && group->ttl_check) {
2045             monitor_printf(mon, " check TTL");
2046         }
2047 
2048         if (group->has_group_id && group->group_id) {
2049             monitor_printf(mon, " group id 0x%08x", group->group_id);
2050         }
2051 
2052         if (group->has_pop_vlan && group->pop_vlan) {
2053             monitor_printf(mon, " pop vlan");
2054         }
2055 
2056         if (group->has_out_pport) {
2057             monitor_printf(mon, " out pport %d", group->out_pport);
2058         }
2059 
2060         if (group->has_group_ids) {
2061             struct uint32List *id;
2062 
2063             monitor_printf(mon, " groups [");
2064             for (id = group->group_ids; id; id = id->next) {
2065                 monitor_printf(mon, "0x%08x", id->value);
2066                 if (id->next) {
2067                     monitor_printf(mon, ",");
2068                 }
2069             }
2070             monitor_printf(mon, "]");
2071         }
2072 
2073         monitor_printf(mon, "\n");
2074     }
2075 
2076     qapi_free_RockerOfDpaGroupList(list);
2077 }
2078 
2079 void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict)
2080 {
2081     Error *err = NULL;
2082     GuidInfo *info = qmp_query_vm_generation_id(&err);
2083     if (info) {
2084         monitor_printf(mon, "%s\n", info->guid);
2085     }
2086     hmp_handle_error(mon, err);
2087     qapi_free_GuidInfo(info);
2088 }
2089 
2090 void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict)
2091 {
2092     Error *err = NULL;
2093     MemoryInfo *info = qmp_query_memory_size_summary(&err);
2094     if (info) {
2095         monitor_printf(mon, "base memory: %" PRIu64 "\n",
2096                        info->base_memory);
2097 
2098         if (info->has_plugged_memory) {
2099             monitor_printf(mon, "plugged memory: %" PRIu64 "\n",
2100                            info->plugged_memory);
2101         }
2102 
2103         qapi_free_MemoryInfo(info);
2104     }
2105     hmp_handle_error(mon, err);
2106 }
2107 
2108 static void print_stats_schema_value(Monitor *mon, StatsSchemaValue *value)
2109 {
2110     const char *unit = NULL;
2111     monitor_printf(mon, "    %s (%s%s", value->name, StatsType_str(value->type),
2112                    value->has_unit || value->exponent ? ", " : "");
2113 
2114     if (value->has_unit) {
2115         if (value->unit == STATS_UNIT_SECONDS) {
2116             unit = "s";
2117         } else if (value->unit == STATS_UNIT_BYTES) {
2118             unit = "B";
2119         }
2120     }
2121 
2122     if (unit && value->base == 10 &&
2123         value->exponent >= -18 && value->exponent <= 18 &&
2124         value->exponent % 3 == 0) {
2125         monitor_puts(mon, si_prefix(value->exponent));
2126     } else if (unit && value->base == 2 &&
2127                value->exponent >= 0 && value->exponent <= 60 &&
2128                value->exponent % 10 == 0) {
2129 
2130         monitor_puts(mon, iec_binary_prefix(value->exponent));
2131     } else if (value->exponent) {
2132         /* Use exponential notation and write the unit's English name */
2133         monitor_printf(mon, "* %d^%d%s",
2134                        value->base, value->exponent,
2135                        value->has_unit ? " " : "");
2136         unit = NULL;
2137     }
2138 
2139     if (value->has_unit) {
2140         monitor_puts(mon, unit ? unit : StatsUnit_str(value->unit));
2141     }
2142 
2143     /* Print bucket size for linear histograms */
2144     if (value->type == STATS_TYPE_LINEAR_HISTOGRAM && value->has_bucket_size) {
2145         monitor_printf(mon, ", bucket size=%d", value->bucket_size);
2146     }
2147     monitor_printf(mon, ")");
2148 }
2149 
2150 static StatsSchemaValueList *find_schema_value_list(
2151     StatsSchemaList *list, StatsProvider provider,
2152     StatsTarget target)
2153 {
2154     StatsSchemaList *node;
2155 
2156     for (node = list; node; node = node->next) {
2157         if (node->value->provider == provider &&
2158             node->value->target == target) {
2159             return node->value->stats;
2160         }
2161     }
2162     return NULL;
2163 }
2164 
2165 static void print_stats_results(Monitor *mon, StatsTarget target,
2166                                 bool show_provider,
2167                                 StatsResult *result,
2168                                 StatsSchemaList *schema)
2169 {
2170     /* Find provider schema */
2171     StatsSchemaValueList *schema_value_list =
2172         find_schema_value_list(schema, result->provider, target);
2173     StatsList *stats_list;
2174 
2175     if (!schema_value_list) {
2176         monitor_printf(mon, "failed to find schema list for %s\n",
2177                        StatsProvider_str(result->provider));
2178         return;
2179     }
2180 
2181     if (show_provider) {
2182         monitor_printf(mon, "provider: %s\n",
2183                        StatsProvider_str(result->provider));
2184     }
2185 
2186     for (stats_list = result->stats; stats_list;
2187              stats_list = stats_list->next,
2188              schema_value_list = schema_value_list->next) {
2189 
2190         Stats *stats = stats_list->value;
2191         StatsValue *stats_value = stats->value;
2192         StatsSchemaValue *schema_value = schema_value_list->value;
2193 
2194         /* Find schema entry */
2195         while (!g_str_equal(stats->name, schema_value->name)) {
2196             if (!schema_value_list->next) {
2197                 monitor_printf(mon, "failed to find schema entry for %s\n",
2198                                stats->name);
2199                 return;
2200             }
2201             schema_value_list = schema_value_list->next;
2202             schema_value = schema_value_list->value;
2203         }
2204 
2205         print_stats_schema_value(mon, schema_value);
2206 
2207         if (stats_value->type == QTYPE_QNUM) {
2208             monitor_printf(mon, ": %" PRId64 "\n", stats_value->u.scalar);
2209         } else if (stats_value->type == QTYPE_QBOOL) {
2210             monitor_printf(mon, ": %s\n", stats_value->u.boolean ? "yes" : "no");
2211         } else if (stats_value->type == QTYPE_QLIST) {
2212             uint64List *list;
2213             int i;
2214 
2215             monitor_printf(mon, ": ");
2216             for (list = stats_value->u.list, i = 1;
2217                  list;
2218                  list = list->next, i++) {
2219                 monitor_printf(mon, "[%d]=%" PRId64 " ", i, list->value);
2220             }
2221             monitor_printf(mon, "\n");
2222         }
2223     }
2224 }
2225 
2226 /* Create the StatsFilter that is needed for an "info stats" invocation.  */
2227 static StatsFilter *stats_filter(StatsTarget target, const char *names,
2228                                  int cpu_index, StatsProvider provider)
2229 {
2230     StatsFilter *filter = g_malloc0(sizeof(*filter));
2231     StatsProvider provider_idx;
2232     StatsRequestList *request_list = NULL;
2233 
2234     filter->target = target;
2235     switch (target) {
2236     case STATS_TARGET_VM:
2237         break;
2238     case STATS_TARGET_VCPU:
2239     {
2240         strList *vcpu_list = NULL;
2241         CPUState *cpu = qemu_get_cpu(cpu_index);
2242         char *canonical_path = object_get_canonical_path(OBJECT(cpu));
2243 
2244         QAPI_LIST_PREPEND(vcpu_list, canonical_path);
2245         filter->u.vcpu.has_vcpus = true;
2246         filter->u.vcpu.vcpus = vcpu_list;
2247         break;
2248     }
2249     default:
2250         break;
2251     }
2252 
2253     if (!names && provider == STATS_PROVIDER__MAX) {
2254         return filter;
2255     }
2256 
2257     /*
2258      * "info stats" can only query either one or all the providers.  Querying
2259      * by name, but not by provider, requires the creation of one filter per
2260      * provider.
2261      */
2262     for (provider_idx = 0; provider_idx < STATS_PROVIDER__MAX; provider_idx++) {
2263         if (provider == STATS_PROVIDER__MAX || provider == provider_idx) {
2264             StatsRequest *request = g_new0(StatsRequest, 1);
2265             request->provider = provider_idx;
2266             if (names && !g_str_equal(names, "*")) {
2267                 request->has_names = true;
2268                 request->names = strList_from_comma_list(names);
2269             }
2270             QAPI_LIST_PREPEND(request_list, request);
2271         }
2272     }
2273 
2274     filter->has_providers = true;
2275     filter->providers = request_list;
2276     return filter;
2277 }
2278 
2279 void hmp_info_stats(Monitor *mon, const QDict *qdict)
2280 {
2281     const char *target_str = qdict_get_str(qdict, "target");
2282     const char *provider_str = qdict_get_try_str(qdict, "provider");
2283     const char *names = qdict_get_try_str(qdict, "names");
2284 
2285     StatsProvider provider = STATS_PROVIDER__MAX;
2286     StatsTarget target;
2287     Error *err = NULL;
2288     g_autoptr(StatsSchemaList) schema = NULL;
2289     g_autoptr(StatsResultList) stats = NULL;
2290     g_autoptr(StatsFilter) filter = NULL;
2291     StatsResultList *entry;
2292 
2293     target = qapi_enum_parse(&StatsTarget_lookup, target_str, -1, &err);
2294     if (err) {
2295         monitor_printf(mon, "invalid stats target %s\n", target_str);
2296         goto exit_no_print;
2297     }
2298     if (provider_str) {
2299         provider = qapi_enum_parse(&StatsProvider_lookup, provider_str, -1, &err);
2300         if (err) {
2301             monitor_printf(mon, "invalid stats provider %s\n", provider_str);
2302             goto exit_no_print;
2303         }
2304     }
2305 
2306     schema = qmp_query_stats_schemas(provider_str ? true : false,
2307                                      provider, &err);
2308     if (err) {
2309         goto exit;
2310     }
2311 
2312     switch (target) {
2313     case STATS_TARGET_VM:
2314         filter = stats_filter(target, names, -1, provider);
2315         break;
2316     case STATS_TARGET_VCPU: {}
2317         int cpu_index = monitor_get_cpu_index(mon);
2318         filter = stats_filter(target, names, cpu_index, provider);
2319         break;
2320     default:
2321         abort();
2322     }
2323 
2324     stats = qmp_query_stats(filter, &err);
2325     if (err) {
2326         goto exit;
2327     }
2328     for (entry = stats; entry; entry = entry->next) {
2329         print_stats_results(mon, target, provider_str == NULL, entry->value, schema);
2330     }
2331 
2332 exit:
2333     if (err) {
2334         monitor_printf(mon, "%s\n", error_get_pretty(err));
2335     }
2336 exit_no_print:
2337     error_free(err);
2338 }
2339 
2340 static void hmp_virtio_dump_protocols(Monitor *mon,
2341                                       VhostDeviceProtocols *pcol)
2342 {
2343     strList *pcol_list = pcol->protocols;
2344     while (pcol_list) {
2345         monitor_printf(mon, "\t%s", pcol_list->value);
2346         pcol_list = pcol_list->next;
2347         if (pcol_list != NULL) {
2348             monitor_printf(mon, ",\n");
2349         }
2350     }
2351     monitor_printf(mon, "\n");
2352     if (pcol->has_unknown_protocols) {
2353         monitor_printf(mon, "  unknown-protocols(0x%016"PRIx64")\n",
2354                        pcol->unknown_protocols);
2355     }
2356 }
2357 
2358 static void hmp_virtio_dump_status(Monitor *mon,
2359                                    VirtioDeviceStatus *status)
2360 {
2361     strList *status_list = status->statuses;
2362     while (status_list) {
2363         monitor_printf(mon, "\t%s", status_list->value);
2364         status_list = status_list->next;
2365         if (status_list != NULL) {
2366             monitor_printf(mon, ",\n");
2367         }
2368     }
2369     monitor_printf(mon, "\n");
2370     if (status->has_unknown_statuses) {
2371         monitor_printf(mon, "  unknown-statuses(0x%016"PRIx32")\n",
2372                        status->unknown_statuses);
2373     }
2374 }
2375 
2376 static void hmp_virtio_dump_features(Monitor *mon,
2377                                      VirtioDeviceFeatures *features)
2378 {
2379     strList *transport_list = features->transports;
2380     while (transport_list) {
2381         monitor_printf(mon, "\t%s", transport_list->value);
2382         transport_list = transport_list->next;
2383         if (transport_list != NULL) {
2384             monitor_printf(mon, ",\n");
2385         }
2386     }
2387 
2388     monitor_printf(mon, "\n");
2389     strList *list = features->dev_features;
2390     if (list) {
2391         while (list) {
2392             monitor_printf(mon, "\t%s", list->value);
2393             list = list->next;
2394             if (list != NULL) {
2395                 monitor_printf(mon, ",\n");
2396             }
2397         }
2398         monitor_printf(mon, "\n");
2399     }
2400 
2401     if (features->has_unknown_dev_features) {
2402         monitor_printf(mon, "  unknown-features(0x%016"PRIx64")\n",
2403                        features->unknown_dev_features);
2404     }
2405 }
2406 
2407 void hmp_virtio_query(Monitor *mon, const QDict *qdict)
2408 {
2409     Error *err = NULL;
2410     VirtioInfoList *list = qmp_x_query_virtio(&err);
2411     VirtioInfoList *node;
2412 
2413     if (err != NULL) {
2414         hmp_handle_error(mon, err);
2415         return;
2416     }
2417 
2418     if (list == NULL) {
2419         monitor_printf(mon, "No VirtIO devices\n");
2420         return;
2421     }
2422 
2423     node = list;
2424     while (node) {
2425         monitor_printf(mon, "%s [%s]\n", node->value->path,
2426                        node->value->name);
2427         node = node->next;
2428     }
2429     qapi_free_VirtioInfoList(list);
2430 }
2431 
2432 void hmp_virtio_status(Monitor *mon, const QDict *qdict)
2433 {
2434     Error *err = NULL;
2435     const char *path = qdict_get_try_str(qdict, "path");
2436     VirtioStatus *s = qmp_x_query_virtio_status(path, &err);
2437 
2438     if (err != NULL) {
2439         hmp_handle_error(mon, err);
2440         return;
2441     }
2442 
2443     monitor_printf(mon, "%s:\n", path);
2444     monitor_printf(mon, "  device_name:             %s %s\n",
2445                    s->name, s->vhost_dev ? "(vhost)" : "");
2446     monitor_printf(mon, "  device_id:               %d\n", s->device_id);
2447     monitor_printf(mon, "  vhost_started:           %s\n",
2448                    s->vhost_started ? "true" : "false");
2449     monitor_printf(mon, "  bus_name:                %s\n", s->bus_name);
2450     monitor_printf(mon, "  broken:                  %s\n",
2451                    s->broken ? "true" : "false");
2452     monitor_printf(mon, "  disabled:                %s\n",
2453                    s->disabled ? "true" : "false");
2454     monitor_printf(mon, "  disable_legacy_check:    %s\n",
2455                    s->disable_legacy_check ? "true" : "false");
2456     monitor_printf(mon, "  started:                 %s\n",
2457                    s->started ? "true" : "false");
2458     monitor_printf(mon, "  use_started:             %s\n",
2459                    s->use_started ? "true" : "false");
2460     monitor_printf(mon, "  start_on_kick:           %s\n",
2461                    s->start_on_kick ? "true" : "false");
2462     monitor_printf(mon, "  use_guest_notifier_mask: %s\n",
2463                    s->use_guest_notifier_mask ? "true" : "false");
2464     monitor_printf(mon, "  vm_running:              %s\n",
2465                    s->vm_running ? "true" : "false");
2466     monitor_printf(mon, "  num_vqs:                 %"PRId64"\n", s->num_vqs);
2467     monitor_printf(mon, "  queue_sel:               %d\n",
2468                    s->queue_sel);
2469     monitor_printf(mon, "  isr:                     %d\n", s->isr);
2470     monitor_printf(mon, "  endianness:              %s\n",
2471                    s->device_endian);
2472     monitor_printf(mon, "  status:\n");
2473     hmp_virtio_dump_status(mon, s->status);
2474     monitor_printf(mon, "  Guest features:\n");
2475     hmp_virtio_dump_features(mon, s->guest_features);
2476     monitor_printf(mon, "  Host features:\n");
2477     hmp_virtio_dump_features(mon, s->host_features);
2478     monitor_printf(mon, "  Backend features:\n");
2479     hmp_virtio_dump_features(mon, s->backend_features);
2480 
2481     if (s->vhost_dev) {
2482         monitor_printf(mon, "  VHost:\n");
2483         monitor_printf(mon, "    nvqs:           %d\n",
2484                        s->vhost_dev->nvqs);
2485         monitor_printf(mon, "    vq_index:       %"PRId64"\n",
2486                        s->vhost_dev->vq_index);
2487         monitor_printf(mon, "    max_queues:     %"PRId64"\n",
2488                        s->vhost_dev->max_queues);
2489         monitor_printf(mon, "    n_mem_sections: %"PRId64"\n",
2490                        s->vhost_dev->n_mem_sections);
2491         monitor_printf(mon, "    n_tmp_sections: %"PRId64"\n",
2492                        s->vhost_dev->n_tmp_sections);
2493         monitor_printf(mon, "    backend_cap:    %"PRId64"\n",
2494                        s->vhost_dev->backend_cap);
2495         monitor_printf(mon, "    log_enabled:    %s\n",
2496                        s->vhost_dev->log_enabled ? "true" : "false");
2497         monitor_printf(mon, "    log_size:       %"PRId64"\n",
2498                        s->vhost_dev->log_size);
2499         monitor_printf(mon, "    Features:\n");
2500         hmp_virtio_dump_features(mon, s->vhost_dev->features);
2501         monitor_printf(mon, "    Acked features:\n");
2502         hmp_virtio_dump_features(mon, s->vhost_dev->acked_features);
2503         monitor_printf(mon, "    Backend features:\n");
2504         hmp_virtio_dump_features(mon, s->vhost_dev->backend_features);
2505         monitor_printf(mon, "    Protocol features:\n");
2506         hmp_virtio_dump_protocols(mon, s->vhost_dev->protocol_features);
2507     }
2508 
2509     qapi_free_VirtioStatus(s);
2510 }
2511 
2512 void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict)
2513 {
2514     Error *err = NULL;
2515     const char *path = qdict_get_try_str(qdict, "path");
2516     int queue = qdict_get_int(qdict, "queue");
2517     VirtVhostQueueStatus *s =
2518         qmp_x_query_virtio_vhost_queue_status(path, queue, &err);
2519 
2520     if (err != NULL) {
2521         hmp_handle_error(mon, err);
2522         return;
2523     }
2524 
2525     monitor_printf(mon, "%s:\n", path);
2526     monitor_printf(mon, "  device_name:          %s (vhost)\n",
2527                    s->name);
2528     monitor_printf(mon, "  kick:                 %"PRId64"\n", s->kick);
2529     monitor_printf(mon, "  call:                 %"PRId64"\n", s->call);
2530     monitor_printf(mon, "  VRing:\n");
2531     monitor_printf(mon, "    num:         %"PRId64"\n", s->num);
2532     monitor_printf(mon, "    desc:        0x%016"PRIx64"\n", s->desc);
2533     monitor_printf(mon, "    desc_phys:   0x%016"PRIx64"\n",
2534                    s->desc_phys);
2535     monitor_printf(mon, "    desc_size:   %"PRId32"\n", s->desc_size);
2536     monitor_printf(mon, "    avail:       0x%016"PRIx64"\n", s->avail);
2537     monitor_printf(mon, "    avail_phys:  0x%016"PRIx64"\n",
2538                    s->avail_phys);
2539     monitor_printf(mon, "    avail_size:  %"PRId32"\n", s->avail_size);
2540     monitor_printf(mon, "    used:        0x%016"PRIx64"\n", s->used);
2541     monitor_printf(mon, "    used_phys:   0x%016"PRIx64"\n",
2542                    s->used_phys);
2543     monitor_printf(mon, "    used_size:   %"PRId32"\n", s->used_size);
2544 
2545     qapi_free_VirtVhostQueueStatus(s);
2546 }
2547 
2548 void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
2549 {
2550     Error *err = NULL;
2551     const char *path = qdict_get_try_str(qdict, "path");
2552     int queue = qdict_get_int(qdict, "queue");
2553     VirtQueueStatus *s = qmp_x_query_virtio_queue_status(path, queue, &err);
2554 
2555     if (err != NULL) {
2556         hmp_handle_error(mon, err);
2557         return;
2558     }
2559 
2560     monitor_printf(mon, "%s:\n", path);
2561     monitor_printf(mon, "  device_name:          %s\n", s->name);
2562     monitor_printf(mon, "  queue_index:          %d\n", s->queue_index);
2563     monitor_printf(mon, "  inuse:                %d\n", s->inuse);
2564     monitor_printf(mon, "  used_idx:             %d\n", s->used_idx);
2565     monitor_printf(mon, "  signalled_used:       %d\n",
2566                    s->signalled_used);
2567     monitor_printf(mon, "  signalled_used_valid: %s\n",
2568                    s->signalled_used_valid ? "true" : "false");
2569     if (s->has_last_avail_idx) {
2570         monitor_printf(mon, "  last_avail_idx:       %d\n",
2571                        s->last_avail_idx);
2572     }
2573     if (s->has_shadow_avail_idx) {
2574         monitor_printf(mon, "  shadow_avail_idx:     %d\n",
2575                        s->shadow_avail_idx);
2576     }
2577     monitor_printf(mon, "  VRing:\n");
2578     monitor_printf(mon, "    num:          %"PRId32"\n", s->vring_num);
2579     monitor_printf(mon, "    num_default:  %"PRId32"\n",
2580                    s->vring_num_default);
2581     monitor_printf(mon, "    align:        %"PRId32"\n",
2582                    s->vring_align);
2583     monitor_printf(mon, "    desc:         0x%016"PRIx64"\n",
2584                    s->vring_desc);
2585     monitor_printf(mon, "    avail:        0x%016"PRIx64"\n",
2586                    s->vring_avail);
2587     monitor_printf(mon, "    used:         0x%016"PRIx64"\n",
2588                    s->vring_used);
2589 
2590     qapi_free_VirtQueueStatus(s);
2591 }
2592 
2593 void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict)
2594 {
2595     Error *err = NULL;
2596     const char *path = qdict_get_try_str(qdict, "path");
2597     int queue = qdict_get_int(qdict, "queue");
2598     int index = qdict_get_try_int(qdict, "index", -1);
2599     VirtioQueueElement *e;
2600     VirtioRingDescList *list;
2601 
2602     e = qmp_x_query_virtio_queue_element(path, queue, index != -1,
2603                                          index, &err);
2604     if (err != NULL) {
2605         hmp_handle_error(mon, err);
2606         return;
2607     }
2608 
2609     monitor_printf(mon, "%s:\n", path);
2610     monitor_printf(mon, "  device_name: %s\n", e->name);
2611     monitor_printf(mon, "  index:   %d\n", e->index);
2612     monitor_printf(mon, "  desc:\n");
2613     monitor_printf(mon, "    descs:\n");
2614 
2615     list = e->descs;
2616     while (list) {
2617         monitor_printf(mon, "        addr 0x%"PRIx64" len %d",
2618                        list->value->addr, list->value->len);
2619         if (list->value->flags) {
2620             strList *flag = list->value->flags;
2621             monitor_printf(mon, " (");
2622             while (flag) {
2623                 monitor_printf(mon, "%s", flag->value);
2624                 flag = flag->next;
2625                 if (flag) {
2626                     monitor_printf(mon, ", ");
2627                 }
2628             }
2629             monitor_printf(mon, ")");
2630         }
2631         list = list->next;
2632         if (list) {
2633             monitor_printf(mon, ",\n");
2634         }
2635     }
2636     monitor_printf(mon, "\n");
2637     monitor_printf(mon, "  avail:\n");
2638     monitor_printf(mon, "    flags: %d\n", e->avail->flags);
2639     monitor_printf(mon, "    idx:   %d\n", e->avail->idx);
2640     monitor_printf(mon, "    ring:  %d\n", e->avail->ring);
2641     monitor_printf(mon, "  used:\n");
2642     monitor_printf(mon, "    flags: %d\n", e->used->flags);
2643     monitor_printf(mon, "    idx:   %d\n", e->used->idx);
2644 
2645     qapi_free_VirtioQueueElement(e);
2646 }
2647