xref: /openbmc/qemu/monitor/hmp-cmds.c (revision f4c1bcb8)
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         [SPICE_CHANNEL_WEBDAV] = "webdav",
626     };
627 
628     info = qmp_query_spice(NULL);
629 
630     if (!info->enabled) {
631         monitor_printf(mon, "Server: disabled\n");
632         goto out;
633     }
634 
635     monitor_printf(mon, "Server:\n");
636     if (info->has_port) {
637         monitor_printf(mon, "     address: %s:%" PRId64 "\n",
638                        info->host, info->port);
639     }
640     if (info->has_tls_port) {
641         monitor_printf(mon, "     address: %s:%" PRId64 " [tls]\n",
642                        info->host, info->tls_port);
643     }
644     monitor_printf(mon, "    migrated: %s\n",
645                    info->migrated ? "true" : "false");
646     monitor_printf(mon, "        auth: %s\n", info->auth);
647     monitor_printf(mon, "    compiled: %s\n", info->compiled_version);
648     monitor_printf(mon, "  mouse-mode: %s\n",
649                    SpiceQueryMouseMode_str(info->mouse_mode));
650 
651     if (!info->has_channels || info->channels == NULL) {
652         monitor_printf(mon, "Channels: none\n");
653     } else {
654         for (chan = info->channels; chan; chan = chan->next) {
655             monitor_printf(mon, "Channel:\n");
656             monitor_printf(mon, "     address: %s:%s%s\n",
657                            chan->value->host, chan->value->port,
658                            chan->value->tls ? " [tls]" : "");
659             monitor_printf(mon, "     session: %" PRId64 "\n",
660                            chan->value->connection_id);
661             monitor_printf(mon, "     channel: %" PRId64 ":%" PRId64 "\n",
662                            chan->value->channel_type, chan->value->channel_id);
663 
664             channel_name = "unknown";
665             if (chan->value->channel_type > 0 &&
666                 chan->value->channel_type < ARRAY_SIZE(channel_names) &&
667                 channel_names[chan->value->channel_type]) {
668                 channel_name = channel_names[chan->value->channel_type];
669             }
670 
671             monitor_printf(mon, "     channel name: %s\n", channel_name);
672         }
673     }
674 
675 out:
676     qapi_free_SpiceInfo(info);
677 }
678 #endif
679 
680 void hmp_info_balloon(Monitor *mon, const QDict *qdict)
681 {
682     BalloonInfo *info;
683     Error *err = NULL;
684 
685     info = qmp_query_balloon(&err);
686     if (hmp_handle_error(mon, err)) {
687         return;
688     }
689 
690     monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
691 
692     qapi_free_BalloonInfo(info);
693 }
694 
695 static int hmp_info_pic_foreach(Object *obj, void *opaque)
696 {
697     InterruptStatsProvider *intc;
698     InterruptStatsProviderClass *k;
699     Monitor *mon = opaque;
700 
701     if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
702         intc = INTERRUPT_STATS_PROVIDER(obj);
703         k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
704         if (k->print_info) {
705             k->print_info(intc, mon);
706         } else {
707             monitor_printf(mon, "Interrupt controller information not available for %s.\n",
708                            object_get_typename(obj));
709         }
710     }
711 
712     return 0;
713 }
714 
715 void hmp_info_pic(Monitor *mon, const QDict *qdict)
716 {
717     object_child_foreach_recursive(object_get_root(),
718                                    hmp_info_pic_foreach, mon);
719 }
720 
721 void hmp_info_tpm(Monitor *mon, const QDict *qdict)
722 {
723 #ifdef CONFIG_TPM
724     TPMInfoList *info_list, *info;
725     Error *err = NULL;
726     unsigned int c = 0;
727     TPMPassthroughOptions *tpo;
728     TPMEmulatorOptions *teo;
729 
730     info_list = qmp_query_tpm(&err);
731     if (err) {
732         monitor_printf(mon, "TPM device not supported\n");
733         error_free(err);
734         return;
735     }
736 
737     if (info_list) {
738         monitor_printf(mon, "TPM device:\n");
739     }
740 
741     for (info = info_list; info; info = info->next) {
742         TPMInfo *ti = info->value;
743         monitor_printf(mon, " tpm%d: model=%s\n",
744                        c, TpmModel_str(ti->model));
745 
746         monitor_printf(mon, "  \\ %s: type=%s",
747                        ti->id, TpmType_str(ti->options->type));
748 
749         switch (ti->options->type) {
750         case TPM_TYPE_PASSTHROUGH:
751             tpo = ti->options->u.passthrough.data;
752             monitor_printf(mon, "%s%s%s%s",
753                            tpo->path ? ",path=" : "",
754                            tpo->path ?: "",
755                            tpo->cancel_path ? ",cancel-path=" : "",
756                            tpo->cancel_path ?: "");
757             break;
758         case TPM_TYPE_EMULATOR:
759             teo = ti->options->u.emulator.data;
760             monitor_printf(mon, ",chardev=%s", teo->chardev);
761             break;
762         case TPM_TYPE__MAX:
763             break;
764         }
765         monitor_printf(mon, "\n");
766         c++;
767     }
768     qapi_free_TPMInfoList(info_list);
769 #else
770     monitor_printf(mon, "TPM device not supported\n");
771 #endif /* CONFIG_TPM */
772 }
773 
774 void hmp_quit(Monitor *mon, const QDict *qdict)
775 {
776     monitor_suspend(mon);
777     qmp_quit(NULL);
778 }
779 
780 void hmp_stop(Monitor *mon, const QDict *qdict)
781 {
782     qmp_stop(NULL);
783 }
784 
785 void hmp_sync_profile(Monitor *mon, const QDict *qdict)
786 {
787     const char *op = qdict_get_try_str(qdict, "op");
788 
789     if (op == NULL) {
790         bool on = qsp_is_enabled();
791 
792         monitor_printf(mon, "sync-profile is %s\n", on ? "on" : "off");
793         return;
794     }
795     if (!strcmp(op, "on")) {
796         qsp_enable();
797     } else if (!strcmp(op, "off")) {
798         qsp_disable();
799     } else if (!strcmp(op, "reset")) {
800         qsp_reset();
801     } else {
802         Error *err = NULL;
803 
804         error_setg(&err, QERR_INVALID_PARAMETER, op);
805         hmp_handle_error(mon, err);
806     }
807 }
808 
809 void hmp_system_reset(Monitor *mon, const QDict *qdict)
810 {
811     qmp_system_reset(NULL);
812 }
813 
814 void hmp_system_powerdown(Monitor *mon, const QDict *qdict)
815 {
816     qmp_system_powerdown(NULL);
817 }
818 
819 void hmp_exit_preconfig(Monitor *mon, const QDict *qdict)
820 {
821     Error *err = NULL;
822 
823     qmp_x_exit_preconfig(&err);
824     hmp_handle_error(mon, err);
825 }
826 
827 void hmp_cpu(Monitor *mon, const QDict *qdict)
828 {
829     int64_t cpu_index;
830 
831     /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
832             use it are converted to the QAPI */
833     cpu_index = qdict_get_int(qdict, "index");
834     if (monitor_set_cpu(mon, cpu_index) < 0) {
835         monitor_printf(mon, "invalid CPU index\n");
836     }
837 }
838 
839 void hmp_memsave(Monitor *mon, const QDict *qdict)
840 {
841     uint32_t size = qdict_get_int(qdict, "size");
842     const char *filename = qdict_get_str(qdict, "filename");
843     uint64_t addr = qdict_get_int(qdict, "val");
844     Error *err = NULL;
845     int cpu_index = monitor_get_cpu_index(mon);
846 
847     if (cpu_index < 0) {
848         monitor_printf(mon, "No CPU available\n");
849         return;
850     }
851 
852     qmp_memsave(addr, size, filename, true, cpu_index, &err);
853     hmp_handle_error(mon, err);
854 }
855 
856 void hmp_pmemsave(Monitor *mon, const QDict *qdict)
857 {
858     uint32_t size = qdict_get_int(qdict, "size");
859     const char *filename = qdict_get_str(qdict, "filename");
860     uint64_t addr = qdict_get_int(qdict, "val");
861     Error *err = NULL;
862 
863     qmp_pmemsave(addr, size, filename, &err);
864     hmp_handle_error(mon, err);
865 }
866 
867 void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
868 {
869     const char *chardev = qdict_get_str(qdict, "device");
870     const char *data = qdict_get_str(qdict, "data");
871     Error *err = NULL;
872 
873     qmp_ringbuf_write(chardev, data, false, 0, &err);
874 
875     hmp_handle_error(mon, err);
876 }
877 
878 void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
879 {
880     uint32_t size = qdict_get_int(qdict, "size");
881     const char *chardev = qdict_get_str(qdict, "device");
882     char *data;
883     Error *err = NULL;
884     int i;
885 
886     data = qmp_ringbuf_read(chardev, size, false, 0, &err);
887     if (hmp_handle_error(mon, err)) {
888         return;
889     }
890 
891     for (i = 0; data[i]; i++) {
892         unsigned char ch = data[i];
893 
894         if (ch == '\\') {
895             monitor_printf(mon, "\\\\");
896         } else if ((ch < 0x20 && ch != '\n' && ch != '\t') || ch == 0x7F) {
897             monitor_printf(mon, "\\u%04X", ch);
898         } else {
899             monitor_printf(mon, "%c", ch);
900         }
901 
902     }
903     monitor_printf(mon, "\n");
904     g_free(data);
905 }
906 
907 void hmp_cont(Monitor *mon, const QDict *qdict)
908 {
909     Error *err = NULL;
910 
911     qmp_cont(&err);
912     hmp_handle_error(mon, err);
913 }
914 
915 void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
916 {
917     Error *err = NULL;
918 
919     qmp_system_wakeup(&err);
920     hmp_handle_error(mon, err);
921 }
922 
923 void hmp_nmi(Monitor *mon, const QDict *qdict)
924 {
925     Error *err = NULL;
926 
927     qmp_inject_nmi(&err);
928     hmp_handle_error(mon, err);
929 }
930 
931 void hmp_set_link(Monitor *mon, const QDict *qdict)
932 {
933     const char *name = qdict_get_str(qdict, "name");
934     bool up = qdict_get_bool(qdict, "up");
935     Error *err = NULL;
936 
937     qmp_set_link(name, up, &err);
938     hmp_handle_error(mon, err);
939 }
940 
941 void hmp_balloon(Monitor *mon, const QDict *qdict)
942 {
943     int64_t value = qdict_get_int(qdict, "value");
944     Error *err = NULL;
945 
946     qmp_balloon(value, &err);
947     hmp_handle_error(mon, err);
948 }
949 
950 void hmp_loadvm(Monitor *mon, const QDict *qdict)
951 {
952     int saved_vm_running  = runstate_is_running();
953     const char *name = qdict_get_str(qdict, "name");
954     Error *err = NULL;
955 
956     vm_stop(RUN_STATE_RESTORE_VM);
957 
958     if (load_snapshot(name, NULL, false, NULL, &err) && saved_vm_running) {
959         vm_start();
960     }
961     hmp_handle_error(mon, err);
962 }
963 
964 void hmp_savevm(Monitor *mon, const QDict *qdict)
965 {
966     Error *err = NULL;
967 
968     save_snapshot(qdict_get_try_str(qdict, "name"),
969                   true, NULL, false, NULL, &err);
970     hmp_handle_error(mon, err);
971 }
972 
973 void hmp_delvm(Monitor *mon, const QDict *qdict)
974 {
975     Error *err = NULL;
976     const char *name = qdict_get_str(qdict, "name");
977 
978     delete_snapshot(name, false, NULL, &err);
979     hmp_handle_error(mon, err);
980 }
981 
982 void hmp_announce_self(Monitor *mon, const QDict *qdict)
983 {
984     const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
985     const char *id = qdict_get_try_str(qdict, "id");
986     AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
987                                             migrate_announce_params());
988 
989     qapi_free_strList(params->interfaces);
990     params->interfaces = strList_from_comma_list(interfaces_str);
991     params->has_interfaces = params->interfaces != NULL;
992     params->id = g_strdup(id);
993     qmp_announce_self(params, NULL);
994     qapi_free_AnnounceParameters(params);
995 }
996 
997 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
998 {
999     qmp_migrate_cancel(NULL);
1000 }
1001 
1002 void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
1003 {
1004     Error *err = NULL;
1005     const char *state = qdict_get_str(qdict, "state");
1006     int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
1007 
1008     if (val >= 0) {
1009         qmp_migrate_continue(val, &err);
1010     }
1011 
1012     hmp_handle_error(mon, err);
1013 }
1014 
1015 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
1016 {
1017     Error *err = NULL;
1018     const char *uri = qdict_get_str(qdict, "uri");
1019 
1020     qmp_migrate_incoming(uri, &err);
1021 
1022     hmp_handle_error(mon, err);
1023 }
1024 
1025 void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
1026 {
1027     Error *err = NULL;
1028     const char *uri = qdict_get_str(qdict, "uri");
1029 
1030     qmp_migrate_recover(uri, &err);
1031 
1032     hmp_handle_error(mon, err);
1033 }
1034 
1035 void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
1036 {
1037     Error *err = NULL;
1038 
1039     qmp_migrate_pause(&err);
1040 
1041     hmp_handle_error(mon, err);
1042 }
1043 
1044 
1045 void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
1046 {
1047     const char *cap = qdict_get_str(qdict, "capability");
1048     bool state = qdict_get_bool(qdict, "state");
1049     Error *err = NULL;
1050     MigrationCapabilityStatusList *caps = NULL;
1051     MigrationCapabilityStatus *value;
1052     int val;
1053 
1054     val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err);
1055     if (val < 0) {
1056         goto end;
1057     }
1058 
1059     value = g_malloc0(sizeof(*value));
1060     value->capability = val;
1061     value->state = state;
1062     QAPI_LIST_PREPEND(caps, value);
1063     qmp_migrate_set_capabilities(caps, &err);
1064     qapi_free_MigrationCapabilityStatusList(caps);
1065 
1066 end:
1067     hmp_handle_error(mon, err);
1068 }
1069 
1070 void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
1071 {
1072     const char *param = qdict_get_str(qdict, "parameter");
1073     const char *valuestr = qdict_get_str(qdict, "value");
1074     Visitor *v = string_input_visitor_new(valuestr);
1075     MigrateSetParameters *p = g_new0(MigrateSetParameters, 1);
1076     uint64_t valuebw = 0;
1077     uint64_t cache_size;
1078     Error *err = NULL;
1079     int val, ret;
1080 
1081     val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err);
1082     if (val < 0) {
1083         goto cleanup;
1084     }
1085 
1086     switch (val) {
1087     case MIGRATION_PARAMETER_COMPRESS_LEVEL:
1088         p->has_compress_level = true;
1089         visit_type_uint8(v, param, &p->compress_level, &err);
1090         break;
1091     case MIGRATION_PARAMETER_COMPRESS_THREADS:
1092         p->has_compress_threads = true;
1093         visit_type_uint8(v, param, &p->compress_threads, &err);
1094         break;
1095     case MIGRATION_PARAMETER_COMPRESS_WAIT_THREAD:
1096         p->has_compress_wait_thread = true;
1097         visit_type_bool(v, param, &p->compress_wait_thread, &err);
1098         break;
1099     case MIGRATION_PARAMETER_DECOMPRESS_THREADS:
1100         p->has_decompress_threads = true;
1101         visit_type_uint8(v, param, &p->decompress_threads, &err);
1102         break;
1103     case MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD:
1104         p->has_throttle_trigger_threshold = true;
1105         visit_type_uint8(v, param, &p->throttle_trigger_threshold, &err);
1106         break;
1107     case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL:
1108         p->has_cpu_throttle_initial = true;
1109         visit_type_uint8(v, param, &p->cpu_throttle_initial, &err);
1110         break;
1111     case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT:
1112         p->has_cpu_throttle_increment = true;
1113         visit_type_uint8(v, param, &p->cpu_throttle_increment, &err);
1114         break;
1115     case MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW:
1116         p->has_cpu_throttle_tailslow = true;
1117         visit_type_bool(v, param, &p->cpu_throttle_tailslow, &err);
1118         break;
1119     case MIGRATION_PARAMETER_MAX_CPU_THROTTLE:
1120         p->has_max_cpu_throttle = true;
1121         visit_type_uint8(v, param, &p->max_cpu_throttle, &err);
1122         break;
1123     case MIGRATION_PARAMETER_TLS_CREDS:
1124         p->tls_creds = g_new0(StrOrNull, 1);
1125         p->tls_creds->type = QTYPE_QSTRING;
1126         visit_type_str(v, param, &p->tls_creds->u.s, &err);
1127         break;
1128     case MIGRATION_PARAMETER_TLS_HOSTNAME:
1129         p->tls_hostname = g_new0(StrOrNull, 1);
1130         p->tls_hostname->type = QTYPE_QSTRING;
1131         visit_type_str(v, param, &p->tls_hostname->u.s, &err);
1132         break;
1133     case MIGRATION_PARAMETER_TLS_AUTHZ:
1134         p->tls_authz = g_new0(StrOrNull, 1);
1135         p->tls_authz->type = QTYPE_QSTRING;
1136         visit_type_str(v, param, &p->tls_authz->u.s, &err);
1137         break;
1138     case MIGRATION_PARAMETER_MAX_BANDWIDTH:
1139         p->has_max_bandwidth = true;
1140         /*
1141          * Can't use visit_type_size() here, because it
1142          * defaults to Bytes rather than Mebibytes.
1143          */
1144         ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
1145         if (ret < 0 || valuebw > INT64_MAX
1146             || (size_t)valuebw != valuebw) {
1147             error_setg(&err, "Invalid size %s", valuestr);
1148             break;
1149         }
1150         p->max_bandwidth = valuebw;
1151         break;
1152     case MIGRATION_PARAMETER_DOWNTIME_LIMIT:
1153         p->has_downtime_limit = true;
1154         visit_type_size(v, param, &p->downtime_limit, &err);
1155         break;
1156     case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY:
1157         p->has_x_checkpoint_delay = true;
1158         visit_type_uint32(v, param, &p->x_checkpoint_delay, &err);
1159         break;
1160     case MIGRATION_PARAMETER_BLOCK_INCREMENTAL:
1161         p->has_block_incremental = true;
1162         visit_type_bool(v, param, &p->block_incremental, &err);
1163         break;
1164     case MIGRATION_PARAMETER_MULTIFD_CHANNELS:
1165         p->has_multifd_channels = true;
1166         visit_type_uint8(v, param, &p->multifd_channels, &err);
1167         break;
1168     case MIGRATION_PARAMETER_MULTIFD_COMPRESSION:
1169         p->has_multifd_compression = true;
1170         visit_type_MultiFDCompression(v, param, &p->multifd_compression,
1171                                       &err);
1172         break;
1173     case MIGRATION_PARAMETER_MULTIFD_ZLIB_LEVEL:
1174         p->has_multifd_zlib_level = true;
1175         visit_type_uint8(v, param, &p->multifd_zlib_level, &err);
1176         break;
1177     case MIGRATION_PARAMETER_MULTIFD_ZSTD_LEVEL:
1178         p->has_multifd_zstd_level = true;
1179         visit_type_uint8(v, param, &p->multifd_zstd_level, &err);
1180         break;
1181     case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE:
1182         p->has_xbzrle_cache_size = true;
1183         if (!visit_type_size(v, param, &cache_size, &err)) {
1184             break;
1185         }
1186         if (cache_size > INT64_MAX || (size_t)cache_size != cache_size) {
1187             error_setg(&err, "Invalid size %s", valuestr);
1188             break;
1189         }
1190         p->xbzrle_cache_size = cache_size;
1191         break;
1192     case MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH:
1193         p->has_max_postcopy_bandwidth = true;
1194         visit_type_size(v, param, &p->max_postcopy_bandwidth, &err);
1195         break;
1196     case MIGRATION_PARAMETER_ANNOUNCE_INITIAL:
1197         p->has_announce_initial = true;
1198         visit_type_size(v, param, &p->announce_initial, &err);
1199         break;
1200     case MIGRATION_PARAMETER_ANNOUNCE_MAX:
1201         p->has_announce_max = true;
1202         visit_type_size(v, param, &p->announce_max, &err);
1203         break;
1204     case MIGRATION_PARAMETER_ANNOUNCE_ROUNDS:
1205         p->has_announce_rounds = true;
1206         visit_type_size(v, param, &p->announce_rounds, &err);
1207         break;
1208     case MIGRATION_PARAMETER_ANNOUNCE_STEP:
1209         p->has_announce_step = true;
1210         visit_type_size(v, param, &p->announce_step, &err);
1211         break;
1212     case MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING:
1213         error_setg(&err, "The block-bitmap-mapping parameter can only be set "
1214                    "through QMP");
1215         break;
1216     default:
1217         assert(0);
1218     }
1219 
1220     if (err) {
1221         goto cleanup;
1222     }
1223 
1224     qmp_migrate_set_parameters(p, &err);
1225 
1226  cleanup:
1227     qapi_free_MigrateSetParameters(p);
1228     visit_free(v);
1229     hmp_handle_error(mon, err);
1230 }
1231 
1232 void hmp_client_migrate_info(Monitor *mon, const QDict *qdict)
1233 {
1234     Error *err = NULL;
1235     const char *protocol = qdict_get_str(qdict, "protocol");
1236     const char *hostname = qdict_get_str(qdict, "hostname");
1237     bool has_port        = qdict_haskey(qdict, "port");
1238     int port             = qdict_get_try_int(qdict, "port", -1);
1239     bool has_tls_port    = qdict_haskey(qdict, "tls-port");
1240     int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
1241     const char *cert_subject = qdict_get_try_str(qdict, "cert-subject");
1242 
1243     qmp_client_migrate_info(protocol, hostname,
1244                             has_port, port, has_tls_port, tls_port,
1245                             cert_subject, &err);
1246     hmp_handle_error(mon, err);
1247 }
1248 
1249 void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict)
1250 {
1251     Error *err = NULL;
1252     qmp_migrate_start_postcopy(&err);
1253     hmp_handle_error(mon, err);
1254 }
1255 
1256 void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict)
1257 {
1258     Error *err = NULL;
1259 
1260     qmp_x_colo_lost_heartbeat(&err);
1261     hmp_handle_error(mon, err);
1262 }
1263 
1264 void hmp_set_password(Monitor *mon, const QDict *qdict)
1265 {
1266     const char *protocol  = qdict_get_str(qdict, "protocol");
1267     const char *password  = qdict_get_str(qdict, "password");
1268     const char *display = qdict_get_try_str(qdict, "display");
1269     const char *connected = qdict_get_try_str(qdict, "connected");
1270     Error *err = NULL;
1271 
1272     SetPasswordOptions opts = {
1273         .password = (char *)password,
1274         .has_connected = !!connected,
1275     };
1276 
1277     opts.connected = qapi_enum_parse(&SetPasswordAction_lookup, connected,
1278                                      SET_PASSWORD_ACTION_KEEP, &err);
1279     if (err) {
1280         goto out;
1281     }
1282 
1283     opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
1284                                     DISPLAY_PROTOCOL_VNC, &err);
1285     if (err) {
1286         goto out;
1287     }
1288 
1289     if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
1290         opts.u.vnc.display = (char *)display;
1291     }
1292 
1293     qmp_set_password(&opts, &err);
1294 
1295 out:
1296     hmp_handle_error(mon, err);
1297 }
1298 
1299 void hmp_expire_password(Monitor *mon, const QDict *qdict)
1300 {
1301     const char *protocol  = qdict_get_str(qdict, "protocol");
1302     const char *whenstr = qdict_get_str(qdict, "time");
1303     const char *display = qdict_get_try_str(qdict, "display");
1304     Error *err = NULL;
1305 
1306     ExpirePasswordOptions opts = {
1307         .time = (char *)whenstr,
1308     };
1309 
1310     opts.protocol = qapi_enum_parse(&DisplayProtocol_lookup, protocol,
1311                                     DISPLAY_PROTOCOL_VNC, &err);
1312     if (err) {
1313         goto out;
1314     }
1315 
1316     if (opts.protocol == DISPLAY_PROTOCOL_VNC) {
1317         opts.u.vnc.display = (char *)display;
1318     }
1319 
1320     qmp_expire_password(&opts, &err);
1321 
1322 out:
1323     hmp_handle_error(mon, err);
1324 }
1325 
1326 
1327 #ifdef CONFIG_VNC
1328 static void hmp_change_read_arg(void *opaque, const char *password,
1329                                 void *readline_opaque)
1330 {
1331     qmp_change_vnc_password(password, NULL);
1332     monitor_read_command(opaque, 1);
1333 }
1334 #endif
1335 
1336 void hmp_change(Monitor *mon, const QDict *qdict)
1337 {
1338     const char *device = qdict_get_str(qdict, "device");
1339     const char *target = qdict_get_str(qdict, "target");
1340     const char *arg = qdict_get_try_str(qdict, "arg");
1341     const char *read_only = qdict_get_try_str(qdict, "read-only-mode");
1342     bool force = qdict_get_try_bool(qdict, "force", false);
1343     BlockdevChangeReadOnlyMode read_only_mode = 0;
1344     Error *err = NULL;
1345 
1346 #ifdef CONFIG_VNC
1347     if (strcmp(device, "vnc") == 0) {
1348         if (read_only) {
1349             monitor_printf(mon,
1350                            "Parameter 'read-only-mode' is invalid for VNC\n");
1351             return;
1352         }
1353         if (strcmp(target, "passwd") == 0 ||
1354             strcmp(target, "password") == 0) {
1355             if (!arg) {
1356                 MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
1357                 monitor_read_password(hmp_mon, hmp_change_read_arg, NULL);
1358                 return;
1359             } else {
1360                 qmp_change_vnc_password(arg, &err);
1361             }
1362         } else {
1363             monitor_printf(mon, "Expected 'password' after 'vnc'\n");
1364         }
1365     } else
1366 #endif
1367     {
1368         if (read_only) {
1369             read_only_mode =
1370                 qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup,
1371                                 read_only,
1372                                 BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err);
1373             if (err) {
1374                 goto end;
1375             }
1376         }
1377 
1378         qmp_blockdev_change_medium(device, NULL, target, arg, true, force,
1379                                    !!read_only, read_only_mode,
1380                                    &err);
1381     }
1382 
1383 end:
1384     hmp_handle_error(mon, err);
1385 }
1386 
1387 typedef struct HMPMigrationStatus {
1388     QEMUTimer *timer;
1389     Monitor *mon;
1390     bool is_block_migration;
1391 } HMPMigrationStatus;
1392 
1393 static void hmp_migrate_status_cb(void *opaque)
1394 {
1395     HMPMigrationStatus *status = opaque;
1396     MigrationInfo *info;
1397 
1398     info = qmp_query_migrate(NULL);
1399     if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE ||
1400         info->status == MIGRATION_STATUS_SETUP) {
1401         if (info->disk) {
1402             int progress;
1403 
1404             if (info->disk->remaining) {
1405                 progress = info->disk->transferred * 100 / info->disk->total;
1406             } else {
1407                 progress = 100;
1408             }
1409 
1410             monitor_printf(status->mon, "Completed %d %%\r", progress);
1411             monitor_flush(status->mon);
1412         }
1413 
1414         timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
1415     } else {
1416         if (status->is_block_migration) {
1417             monitor_printf(status->mon, "\n");
1418         }
1419         if (info->error_desc) {
1420             error_report("%s", info->error_desc);
1421         }
1422         monitor_resume(status->mon);
1423         timer_free(status->timer);
1424         g_free(status);
1425     }
1426 
1427     qapi_free_MigrationInfo(info);
1428 }
1429 
1430 void hmp_migrate(Monitor *mon, const QDict *qdict)
1431 {
1432     bool detach = qdict_get_try_bool(qdict, "detach", false);
1433     bool blk = qdict_get_try_bool(qdict, "blk", false);
1434     bool inc = qdict_get_try_bool(qdict, "inc", false);
1435     bool resume = qdict_get_try_bool(qdict, "resume", false);
1436     const char *uri = qdict_get_str(qdict, "uri");
1437     Error *err = NULL;
1438 
1439     qmp_migrate(uri, !!blk, blk, !!inc, inc,
1440                 false, false, true, resume, &err);
1441     if (hmp_handle_error(mon, err)) {
1442         return;
1443     }
1444 
1445     if (!detach) {
1446         HMPMigrationStatus *status;
1447 
1448         if (monitor_suspend(mon) < 0) {
1449             monitor_printf(mon, "terminal does not allow synchronous "
1450                            "migration, continuing detached\n");
1451             return;
1452         }
1453 
1454         status = g_malloc0(sizeof(*status));
1455         status->mon = mon;
1456         status->is_block_migration = blk || inc;
1457         status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb,
1458                                           status);
1459         timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
1460     }
1461 }
1462 
1463 void hmp_netdev_add(Monitor *mon, const QDict *qdict)
1464 {
1465     Error *err = NULL;
1466     QemuOpts *opts;
1467     const char *type = qdict_get_try_str(qdict, "type");
1468 
1469     if (type && is_help_option(type)) {
1470         show_netdevs();
1471         return;
1472     }
1473     opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
1474     if (err) {
1475         goto out;
1476     }
1477 
1478     netdev_add(opts, &err);
1479     if (err) {
1480         qemu_opts_del(opts);
1481     }
1482 
1483 out:
1484     hmp_handle_error(mon, err);
1485 }
1486 
1487 void hmp_netdev_del(Monitor *mon, const QDict *qdict)
1488 {
1489     const char *id = qdict_get_str(qdict, "id");
1490     Error *err = NULL;
1491 
1492     qmp_netdev_del(id, &err);
1493     hmp_handle_error(mon, err);
1494 }
1495 
1496 void hmp_object_add(Monitor *mon, const QDict *qdict)
1497 {
1498     const char *options = qdict_get_str(qdict, "object");
1499     Error *err = NULL;
1500 
1501     user_creatable_add_from_str(options, &err);
1502     hmp_handle_error(mon, err);
1503 }
1504 
1505 void hmp_getfd(Monitor *mon, const QDict *qdict)
1506 {
1507     const char *fdname = qdict_get_str(qdict, "fdname");
1508     Error *err = NULL;
1509 
1510     qmp_getfd(fdname, &err);
1511     hmp_handle_error(mon, err);
1512 }
1513 
1514 void hmp_closefd(Monitor *mon, const QDict *qdict)
1515 {
1516     const char *fdname = qdict_get_str(qdict, "fdname");
1517     Error *err = NULL;
1518 
1519     qmp_closefd(fdname, &err);
1520     hmp_handle_error(mon, err);
1521 }
1522 
1523 void hmp_sendkey(Monitor *mon, const QDict *qdict)
1524 {
1525     const char *keys = qdict_get_str(qdict, "keys");
1526     KeyValue *v = NULL;
1527     KeyValueList *head = NULL, **tail = &head;
1528     int has_hold_time = qdict_haskey(qdict, "hold-time");
1529     int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
1530     Error *err = NULL;
1531     const char *separator;
1532     int keyname_len;
1533 
1534     while (1) {
1535         separator = qemu_strchrnul(keys, '-');
1536         keyname_len = separator - keys;
1537 
1538         /* Be compatible with old interface, convert user inputted "<" */
1539         if (keys[0] == '<' && keyname_len == 1) {
1540             keys = "less";
1541             keyname_len = 4;
1542         }
1543 
1544         v = g_malloc0(sizeof(*v));
1545 
1546         if (strstart(keys, "0x", NULL)) {
1547             const char *endp;
1548             int value;
1549 
1550             if (qemu_strtoi(keys, &endp, 0, &value) < 0) {
1551                 goto err_out;
1552             }
1553             assert(endp <= keys + keyname_len);
1554             if (endp != keys + keyname_len) {
1555                 goto err_out;
1556             }
1557             v->type = KEY_VALUE_KIND_NUMBER;
1558             v->u.number.data = value;
1559         } else {
1560             int idx = index_from_key(keys, keyname_len);
1561             if (idx == Q_KEY_CODE__MAX) {
1562                 goto err_out;
1563             }
1564             v->type = KEY_VALUE_KIND_QCODE;
1565             v->u.qcode.data = idx;
1566         }
1567         QAPI_LIST_APPEND(tail, v);
1568         v = NULL;
1569 
1570         if (!*separator) {
1571             break;
1572         }
1573         keys = separator + 1;
1574     }
1575 
1576     qmp_send_key(head, has_hold_time, hold_time, &err);
1577     hmp_handle_error(mon, err);
1578 
1579 out:
1580     qapi_free_KeyValue(v);
1581     qapi_free_KeyValueList(head);
1582     return;
1583 
1584 err_out:
1585     monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
1586     goto out;
1587 }
1588 
1589 void coroutine_fn
1590 hmp_screendump(Monitor *mon, const QDict *qdict)
1591 {
1592     const char *filename = qdict_get_str(qdict, "filename");
1593     const char *id = qdict_get_try_str(qdict, "device");
1594     int64_t head = qdict_get_try_int(qdict, "head", 0);
1595     const char *input_format  = qdict_get_try_str(qdict, "format");
1596     Error *err = NULL;
1597     ImageFormat format;
1598 
1599     format = qapi_enum_parse(&ImageFormat_lookup, input_format,
1600                               IMAGE_FORMAT_PPM, &err);
1601     if (err) {
1602         goto end;
1603     }
1604 
1605     qmp_screendump(filename, id, id != NULL, head,
1606                    input_format != NULL, format, &err);
1607 end:
1608     hmp_handle_error(mon, err);
1609 }
1610 
1611 void hmp_chardev_add(Monitor *mon, const QDict *qdict)
1612 {
1613     const char *args = qdict_get_str(qdict, "args");
1614     Error *err = NULL;
1615     QemuOpts *opts;
1616 
1617     opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, true);
1618     if (opts == NULL) {
1619         error_setg(&err, "Parsing chardev args failed");
1620     } else {
1621         qemu_chr_new_from_opts(opts, NULL, &err);
1622         qemu_opts_del(opts);
1623     }
1624     hmp_handle_error(mon, err);
1625 }
1626 
1627 void hmp_chardev_change(Monitor *mon, const QDict *qdict)
1628 {
1629     const char *args = qdict_get_str(qdict, "args");
1630     const char *id;
1631     Error *err = NULL;
1632     ChardevBackend *backend = NULL;
1633     ChardevReturn *ret = NULL;
1634     QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args,
1635                                              true);
1636     if (!opts) {
1637         error_setg(&err, "Parsing chardev args failed");
1638         goto end;
1639     }
1640 
1641     id = qdict_get_str(qdict, "id");
1642     if (qemu_opts_id(opts)) {
1643         error_setg(&err, "Unexpected 'id' parameter");
1644         goto end;
1645     }
1646 
1647     backend = qemu_chr_parse_opts(opts, &err);
1648     if (!backend) {
1649         goto end;
1650     }
1651 
1652     ret = qmp_chardev_change(id, backend, &err);
1653 
1654 end:
1655     qapi_free_ChardevReturn(ret);
1656     qapi_free_ChardevBackend(backend);
1657     qemu_opts_del(opts);
1658     hmp_handle_error(mon, err);
1659 }
1660 
1661 void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
1662 {
1663     Error *local_err = NULL;
1664 
1665     qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
1666     hmp_handle_error(mon, local_err);
1667 }
1668 
1669 void hmp_chardev_send_break(Monitor *mon, const QDict *qdict)
1670 {
1671     Error *local_err = NULL;
1672 
1673     qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err);
1674     hmp_handle_error(mon, local_err);
1675 }
1676 
1677 void hmp_object_del(Monitor *mon, const QDict *qdict)
1678 {
1679     const char *id = qdict_get_str(qdict, "id");
1680     Error *err = NULL;
1681 
1682     user_creatable_del(id, &err);
1683     hmp_handle_error(mon, err);
1684 }
1685 
1686 void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
1687 {
1688     Error *err = NULL;
1689     MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
1690     MemoryDeviceInfoList *info;
1691     VirtioPMEMDeviceInfo *vpi;
1692     VirtioMEMDeviceInfo *vmi;
1693     MemoryDeviceInfo *value;
1694     PCDIMMDeviceInfo *di;
1695     SgxEPCDeviceInfo *se;
1696 
1697     for (info = info_list; info; info = info->next) {
1698         value = info->value;
1699 
1700         if (value) {
1701             switch (value->type) {
1702             case MEMORY_DEVICE_INFO_KIND_DIMM:
1703             case MEMORY_DEVICE_INFO_KIND_NVDIMM:
1704                 di = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ?
1705                      value->u.dimm.data : value->u.nvdimm.data;
1706                 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
1707                                MemoryDeviceInfoKind_str(value->type),
1708                                di->id ? di->id : "");
1709                 monitor_printf(mon, "  addr: 0x%" PRIx64 "\n", di->addr);
1710                 monitor_printf(mon, "  slot: %" PRId64 "\n", di->slot);
1711                 monitor_printf(mon, "  node: %" PRId64 "\n", di->node);
1712                 monitor_printf(mon, "  size: %" PRIu64 "\n", di->size);
1713                 monitor_printf(mon, "  memdev: %s\n", di->memdev);
1714                 monitor_printf(mon, "  hotplugged: %s\n",
1715                                di->hotplugged ? "true" : "false");
1716                 monitor_printf(mon, "  hotpluggable: %s\n",
1717                                di->hotpluggable ? "true" : "false");
1718                 break;
1719             case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM:
1720                 vpi = value->u.virtio_pmem.data;
1721                 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
1722                                MemoryDeviceInfoKind_str(value->type),
1723                                vpi->id ? vpi->id : "");
1724                 monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", vpi->memaddr);
1725                 monitor_printf(mon, "  size: %" PRIu64 "\n", vpi->size);
1726                 monitor_printf(mon, "  memdev: %s\n", vpi->memdev);
1727                 break;
1728             case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM:
1729                 vmi = value->u.virtio_mem.data;
1730                 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
1731                                MemoryDeviceInfoKind_str(value->type),
1732                                vmi->id ? vmi->id : "");
1733                 monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", vmi->memaddr);
1734                 monitor_printf(mon, "  node: %" PRId64 "\n", vmi->node);
1735                 monitor_printf(mon, "  requested-size: %" PRIu64 "\n",
1736                                vmi->requested_size);
1737                 monitor_printf(mon, "  size: %" PRIu64 "\n", vmi->size);
1738                 monitor_printf(mon, "  max-size: %" PRIu64 "\n", vmi->max_size);
1739                 monitor_printf(mon, "  block-size: %" PRIu64 "\n",
1740                                vmi->block_size);
1741                 monitor_printf(mon, "  memdev: %s\n", vmi->memdev);
1742                 break;
1743             case MEMORY_DEVICE_INFO_KIND_SGX_EPC:
1744                 se = value->u.sgx_epc.data;
1745                 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
1746                                MemoryDeviceInfoKind_str(value->type),
1747                                se->id ? se->id : "");
1748                 monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", se->memaddr);
1749                 monitor_printf(mon, "  size: %" PRIu64 "\n", se->size);
1750                 monitor_printf(mon, "  node: %" PRId64 "\n", se->node);
1751                 monitor_printf(mon, "  memdev: %s\n", se->memdev);
1752                 break;
1753             default:
1754                 g_assert_not_reached();
1755             }
1756         }
1757     }
1758 
1759     qapi_free_MemoryDeviceInfoList(info_list);
1760     hmp_handle_error(mon, err);
1761 }
1762 
1763 void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
1764 {
1765     IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
1766     IOThreadInfoList *info;
1767     IOThreadInfo *value;
1768 
1769     for (info = info_list; info; info = info->next) {
1770         value = info->value;
1771         monitor_printf(mon, "%s:\n", value->id);
1772         monitor_printf(mon, "  thread_id=%" PRId64 "\n", value->thread_id);
1773         monitor_printf(mon, "  poll-max-ns=%" PRId64 "\n", value->poll_max_ns);
1774         monitor_printf(mon, "  poll-grow=%" PRId64 "\n", value->poll_grow);
1775         monitor_printf(mon, "  poll-shrink=%" PRId64 "\n", value->poll_shrink);
1776         monitor_printf(mon, "  aio-max-batch=%" PRId64 "\n",
1777                        value->aio_max_batch);
1778     }
1779 
1780     qapi_free_IOThreadInfoList(info_list);
1781 }
1782 
1783 void hmp_rocker(Monitor *mon, const QDict *qdict)
1784 {
1785     const char *name = qdict_get_str(qdict, "name");
1786     RockerSwitch *rocker;
1787     Error *err = NULL;
1788 
1789     rocker = qmp_query_rocker(name, &err);
1790     if (hmp_handle_error(mon, err)) {
1791         return;
1792     }
1793 
1794     monitor_printf(mon, "name: %s\n", rocker->name);
1795     monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id);
1796     monitor_printf(mon, "ports: %d\n", rocker->ports);
1797 
1798     qapi_free_RockerSwitch(rocker);
1799 }
1800 
1801 void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
1802 {
1803     RockerPortList *list, *port;
1804     const char *name = qdict_get_str(qdict, "name");
1805     Error *err = NULL;
1806 
1807     list = qmp_query_rocker_ports(name, &err);
1808     if (hmp_handle_error(mon, err)) {
1809         return;
1810     }
1811 
1812     monitor_printf(mon, "            ena/    speed/ auto\n");
1813     monitor_printf(mon, "      port  link    duplex neg?\n");
1814 
1815     for (port = list; port; port = port->next) {
1816         monitor_printf(mon, "%10s  %-4s   %-3s  %2s  %s\n",
1817                        port->value->name,
1818                        port->value->enabled ? port->value->link_up ?
1819                        "up" : "down" : "!ena",
1820                        port->value->speed == 10000 ? "10G" : "??",
1821                        port->value->duplex ? "FD" : "HD",
1822                        port->value->autoneg ? "Yes" : "No");
1823     }
1824 
1825     qapi_free_RockerPortList(list);
1826 }
1827 
1828 void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
1829 {
1830     RockerOfDpaFlowList *list, *info;
1831     const char *name = qdict_get_str(qdict, "name");
1832     uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1);
1833     Error *err = NULL;
1834 
1835     list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &err);
1836     if (hmp_handle_error(mon, err)) {
1837         return;
1838     }
1839 
1840     monitor_printf(mon, "prio tbl hits key(mask) --> actions\n");
1841 
1842     for (info = list; info; info = info->next) {
1843         RockerOfDpaFlow *flow = info->value;
1844         RockerOfDpaFlowKey *key = flow->key;
1845         RockerOfDpaFlowMask *mask = flow->mask;
1846         RockerOfDpaFlowAction *action = flow->action;
1847 
1848         if (flow->hits) {
1849             monitor_printf(mon, "%-4d %-3d %-4" PRIu64,
1850                            key->priority, key->tbl_id, flow->hits);
1851         } else {
1852             monitor_printf(mon, "%-4d %-3d     ",
1853                            key->priority, key->tbl_id);
1854         }
1855 
1856         if (key->has_in_pport) {
1857             monitor_printf(mon, " pport %d", key->in_pport);
1858             if (mask->has_in_pport) {
1859                 monitor_printf(mon, "(0x%x)", mask->in_pport);
1860             }
1861         }
1862 
1863         if (key->has_vlan_id) {
1864             monitor_printf(mon, " vlan %d",
1865                            key->vlan_id & VLAN_VID_MASK);
1866             if (mask->has_vlan_id) {
1867                 monitor_printf(mon, "(0x%x)", mask->vlan_id);
1868             }
1869         }
1870 
1871         if (key->has_tunnel_id) {
1872             monitor_printf(mon, " tunnel %d", key->tunnel_id);
1873             if (mask->has_tunnel_id) {
1874                 monitor_printf(mon, "(0x%x)", mask->tunnel_id);
1875             }
1876         }
1877 
1878         if (key->has_eth_type) {
1879             switch (key->eth_type) {
1880             case 0x0806:
1881                 monitor_printf(mon, " ARP");
1882                 break;
1883             case 0x0800:
1884                 monitor_printf(mon, " IP");
1885                 break;
1886             case 0x86dd:
1887                 monitor_printf(mon, " IPv6");
1888                 break;
1889             case 0x8809:
1890                 monitor_printf(mon, " LACP");
1891                 break;
1892             case 0x88cc:
1893                 monitor_printf(mon, " LLDP");
1894                 break;
1895             default:
1896                 monitor_printf(mon, " eth type 0x%04x", key->eth_type);
1897                 break;
1898             }
1899         }
1900 
1901         if (key->eth_src) {
1902             if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) &&
1903                 mask->eth_src &&
1904                 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
1905                 monitor_printf(mon, " src <any mcast/bcast>");
1906             } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) &&
1907                 mask->eth_src &&
1908                 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
1909                 monitor_printf(mon, " src <any ucast>");
1910             } else {
1911                 monitor_printf(mon, " src %s", key->eth_src);
1912                 if (mask->eth_src) {
1913                     monitor_printf(mon, "(%s)", mask->eth_src);
1914                 }
1915             }
1916         }
1917 
1918         if (key->eth_dst) {
1919             if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) &&
1920                 mask->eth_dst &&
1921                 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
1922                 monitor_printf(mon, " dst <any mcast/bcast>");
1923             } else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) &&
1924                 mask->eth_dst &&
1925                 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
1926                 monitor_printf(mon, " dst <any ucast>");
1927             } else {
1928                 monitor_printf(mon, " dst %s", key->eth_dst);
1929                 if (mask->eth_dst) {
1930                     monitor_printf(mon, "(%s)", mask->eth_dst);
1931                 }
1932             }
1933         }
1934 
1935         if (key->has_ip_proto) {
1936             monitor_printf(mon, " proto %d", key->ip_proto);
1937             if (mask->has_ip_proto) {
1938                 monitor_printf(mon, "(0x%x)", mask->ip_proto);
1939             }
1940         }
1941 
1942         if (key->has_ip_tos) {
1943             monitor_printf(mon, " TOS %d", key->ip_tos);
1944             if (mask->has_ip_tos) {
1945                 monitor_printf(mon, "(0x%x)", mask->ip_tos);
1946             }
1947         }
1948 
1949         if (key->ip_dst) {
1950             monitor_printf(mon, " dst %s", key->ip_dst);
1951         }
1952 
1953         if (action->has_goto_tbl || action->has_group_id ||
1954             action->has_new_vlan_id) {
1955             monitor_printf(mon, " -->");
1956         }
1957 
1958         if (action->has_new_vlan_id) {
1959             monitor_printf(mon, " apply new vlan %d",
1960                            ntohs(action->new_vlan_id));
1961         }
1962 
1963         if (action->has_group_id) {
1964             monitor_printf(mon, " write group 0x%08x", action->group_id);
1965         }
1966 
1967         if (action->has_goto_tbl) {
1968             monitor_printf(mon, " goto tbl %d", action->goto_tbl);
1969         }
1970 
1971         monitor_printf(mon, "\n");
1972     }
1973 
1974     qapi_free_RockerOfDpaFlowList(list);
1975 }
1976 
1977 void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
1978 {
1979     RockerOfDpaGroupList *list, *g;
1980     const char *name = qdict_get_str(qdict, "name");
1981     uint8_t type = qdict_get_try_int(qdict, "type", 9);
1982     Error *err = NULL;
1983 
1984     list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err);
1985     if (hmp_handle_error(mon, err)) {
1986         return;
1987     }
1988 
1989     monitor_printf(mon, "id (decode) --> buckets\n");
1990 
1991     for (g = list; g; g = g->next) {
1992         RockerOfDpaGroup *group = g->value;
1993         bool set = false;
1994 
1995         monitor_printf(mon, "0x%08x", group->id);
1996 
1997         monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" :
1998                                          group->type == 1 ? "L2 rewrite" :
1999                                          group->type == 2 ? "L3 unicast" :
2000                                          group->type == 3 ? "L2 multicast" :
2001                                          group->type == 4 ? "L2 flood" :
2002                                          group->type == 5 ? "L3 interface" :
2003                                          group->type == 6 ? "L3 multicast" :
2004                                          group->type == 7 ? "L3 ECMP" :
2005                                          group->type == 8 ? "L2 overlay" :
2006                                          "unknown");
2007 
2008         if (group->has_vlan_id) {
2009             monitor_printf(mon, " vlan %d", group->vlan_id);
2010         }
2011 
2012         if (group->has_pport) {
2013             monitor_printf(mon, " pport %d", group->pport);
2014         }
2015 
2016         if (group->has_index) {
2017             monitor_printf(mon, " index %d", group->index);
2018         }
2019 
2020         monitor_printf(mon, ") -->");
2021 
2022         if (group->has_set_vlan_id && group->set_vlan_id) {
2023             set = true;
2024             monitor_printf(mon, " set vlan %d",
2025                            group->set_vlan_id & VLAN_VID_MASK);
2026         }
2027 
2028         if (group->set_eth_src) {
2029             if (!set) {
2030                 set = true;
2031                 monitor_printf(mon, " set");
2032             }
2033             monitor_printf(mon, " src %s", group->set_eth_src);
2034         }
2035 
2036         if (group->set_eth_dst) {
2037             if (!set) {
2038                 monitor_printf(mon, " set");
2039             }
2040             monitor_printf(mon, " dst %s", group->set_eth_dst);
2041         }
2042 
2043         if (group->has_ttl_check && group->ttl_check) {
2044             monitor_printf(mon, " check TTL");
2045         }
2046 
2047         if (group->has_group_id && group->group_id) {
2048             monitor_printf(mon, " group id 0x%08x", group->group_id);
2049         }
2050 
2051         if (group->has_pop_vlan && group->pop_vlan) {
2052             monitor_printf(mon, " pop vlan");
2053         }
2054 
2055         if (group->has_out_pport) {
2056             monitor_printf(mon, " out pport %d", group->out_pport);
2057         }
2058 
2059         if (group->has_group_ids) {
2060             struct uint32List *id;
2061 
2062             monitor_printf(mon, " groups [");
2063             for (id = group->group_ids; id; id = id->next) {
2064                 monitor_printf(mon, "0x%08x", id->value);
2065                 if (id->next) {
2066                     monitor_printf(mon, ",");
2067                 }
2068             }
2069             monitor_printf(mon, "]");
2070         }
2071 
2072         monitor_printf(mon, "\n");
2073     }
2074 
2075     qapi_free_RockerOfDpaGroupList(list);
2076 }
2077 
2078 void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict)
2079 {
2080     Error *err = NULL;
2081     GuidInfo *info = qmp_query_vm_generation_id(&err);
2082     if (info) {
2083         monitor_printf(mon, "%s\n", info->guid);
2084     }
2085     hmp_handle_error(mon, err);
2086     qapi_free_GuidInfo(info);
2087 }
2088 
2089 void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict)
2090 {
2091     Error *err = NULL;
2092     MemoryInfo *info = qmp_query_memory_size_summary(&err);
2093     if (info) {
2094         monitor_printf(mon, "base memory: %" PRIu64 "\n",
2095                        info->base_memory);
2096 
2097         if (info->has_plugged_memory) {
2098             monitor_printf(mon, "plugged memory: %" PRIu64 "\n",
2099                            info->plugged_memory);
2100         }
2101 
2102         qapi_free_MemoryInfo(info);
2103     }
2104     hmp_handle_error(mon, err);
2105 }
2106 
2107 static void print_stats_schema_value(Monitor *mon, StatsSchemaValue *value)
2108 {
2109     const char *unit = NULL;
2110     monitor_printf(mon, "    %s (%s%s", value->name, StatsType_str(value->type),
2111                    value->has_unit || value->exponent ? ", " : "");
2112 
2113     if (value->has_unit) {
2114         if (value->unit == STATS_UNIT_SECONDS) {
2115             unit = "s";
2116         } else if (value->unit == STATS_UNIT_BYTES) {
2117             unit = "B";
2118         }
2119     }
2120 
2121     if (unit && value->base == 10 &&
2122         value->exponent >= -18 && value->exponent <= 18 &&
2123         value->exponent % 3 == 0) {
2124         monitor_puts(mon, si_prefix(value->exponent));
2125     } else if (unit && value->base == 2 &&
2126                value->exponent >= 0 && value->exponent <= 60 &&
2127                value->exponent % 10 == 0) {
2128 
2129         monitor_puts(mon, iec_binary_prefix(value->exponent));
2130     } else if (value->exponent) {
2131         /* Use exponential notation and write the unit's English name */
2132         monitor_printf(mon, "* %d^%d%s",
2133                        value->base, value->exponent,
2134                        value->has_unit ? " " : "");
2135         unit = NULL;
2136     }
2137 
2138     if (value->has_unit) {
2139         monitor_puts(mon, unit ? unit : StatsUnit_str(value->unit));
2140     }
2141 
2142     /* Print bucket size for linear histograms */
2143     if (value->type == STATS_TYPE_LINEAR_HISTOGRAM && value->has_bucket_size) {
2144         monitor_printf(mon, ", bucket size=%d", value->bucket_size);
2145     }
2146     monitor_printf(mon, ")");
2147 }
2148 
2149 static StatsSchemaValueList *find_schema_value_list(
2150     StatsSchemaList *list, StatsProvider provider,
2151     StatsTarget target)
2152 {
2153     StatsSchemaList *node;
2154 
2155     for (node = list; node; node = node->next) {
2156         if (node->value->provider == provider &&
2157             node->value->target == target) {
2158             return node->value->stats;
2159         }
2160     }
2161     return NULL;
2162 }
2163 
2164 static void print_stats_results(Monitor *mon, StatsTarget target,
2165                                 bool show_provider,
2166                                 StatsResult *result,
2167                                 StatsSchemaList *schema)
2168 {
2169     /* Find provider schema */
2170     StatsSchemaValueList *schema_value_list =
2171         find_schema_value_list(schema, result->provider, target);
2172     StatsList *stats_list;
2173 
2174     if (!schema_value_list) {
2175         monitor_printf(mon, "failed to find schema list for %s\n",
2176                        StatsProvider_str(result->provider));
2177         return;
2178     }
2179 
2180     if (show_provider) {
2181         monitor_printf(mon, "provider: %s\n",
2182                        StatsProvider_str(result->provider));
2183     }
2184 
2185     for (stats_list = result->stats; stats_list;
2186              stats_list = stats_list->next,
2187              schema_value_list = schema_value_list->next) {
2188 
2189         Stats *stats = stats_list->value;
2190         StatsValue *stats_value = stats->value;
2191         StatsSchemaValue *schema_value = schema_value_list->value;
2192 
2193         /* Find schema entry */
2194         while (!g_str_equal(stats->name, schema_value->name)) {
2195             if (!schema_value_list->next) {
2196                 monitor_printf(mon, "failed to find schema entry for %s\n",
2197                                stats->name);
2198                 return;
2199             }
2200             schema_value_list = schema_value_list->next;
2201             schema_value = schema_value_list->value;
2202         }
2203 
2204         print_stats_schema_value(mon, schema_value);
2205 
2206         if (stats_value->type == QTYPE_QNUM) {
2207             monitor_printf(mon, ": %" PRId64 "\n", stats_value->u.scalar);
2208         } else if (stats_value->type == QTYPE_QBOOL) {
2209             monitor_printf(mon, ": %s\n", stats_value->u.boolean ? "yes" : "no");
2210         } else if (stats_value->type == QTYPE_QLIST) {
2211             uint64List *list;
2212             int i;
2213 
2214             monitor_printf(mon, ": ");
2215             for (list = stats_value->u.list, i = 1;
2216                  list;
2217                  list = list->next, i++) {
2218                 monitor_printf(mon, "[%d]=%" PRId64 " ", i, list->value);
2219             }
2220             monitor_printf(mon, "\n");
2221         }
2222     }
2223 }
2224 
2225 /* Create the StatsFilter that is needed for an "info stats" invocation.  */
2226 static StatsFilter *stats_filter(StatsTarget target, const char *names,
2227                                  int cpu_index, StatsProvider provider)
2228 {
2229     StatsFilter *filter = g_malloc0(sizeof(*filter));
2230     StatsProvider provider_idx;
2231     StatsRequestList *request_list = NULL;
2232 
2233     filter->target = target;
2234     switch (target) {
2235     case STATS_TARGET_VM:
2236         break;
2237     case STATS_TARGET_VCPU:
2238     {
2239         strList *vcpu_list = NULL;
2240         CPUState *cpu = qemu_get_cpu(cpu_index);
2241         char *canonical_path = object_get_canonical_path(OBJECT(cpu));
2242 
2243         QAPI_LIST_PREPEND(vcpu_list, canonical_path);
2244         filter->u.vcpu.has_vcpus = true;
2245         filter->u.vcpu.vcpus = vcpu_list;
2246         break;
2247     }
2248     default:
2249         break;
2250     }
2251 
2252     if (!names && provider == STATS_PROVIDER__MAX) {
2253         return filter;
2254     }
2255 
2256     /*
2257      * "info stats" can only query either one or all the providers.  Querying
2258      * by name, but not by provider, requires the creation of one filter per
2259      * provider.
2260      */
2261     for (provider_idx = 0; provider_idx < STATS_PROVIDER__MAX; provider_idx++) {
2262         if (provider == STATS_PROVIDER__MAX || provider == provider_idx) {
2263             StatsRequest *request = g_new0(StatsRequest, 1);
2264             request->provider = provider_idx;
2265             if (names && !g_str_equal(names, "*")) {
2266                 request->has_names = true;
2267                 request->names = strList_from_comma_list(names);
2268             }
2269             QAPI_LIST_PREPEND(request_list, request);
2270         }
2271     }
2272 
2273     filter->has_providers = true;
2274     filter->providers = request_list;
2275     return filter;
2276 }
2277 
2278 void hmp_info_stats(Monitor *mon, const QDict *qdict)
2279 {
2280     const char *target_str = qdict_get_str(qdict, "target");
2281     const char *provider_str = qdict_get_try_str(qdict, "provider");
2282     const char *names = qdict_get_try_str(qdict, "names");
2283 
2284     StatsProvider provider = STATS_PROVIDER__MAX;
2285     StatsTarget target;
2286     Error *err = NULL;
2287     g_autoptr(StatsSchemaList) schema = NULL;
2288     g_autoptr(StatsResultList) stats = NULL;
2289     g_autoptr(StatsFilter) filter = NULL;
2290     StatsResultList *entry;
2291 
2292     target = qapi_enum_parse(&StatsTarget_lookup, target_str, -1, &err);
2293     if (err) {
2294         monitor_printf(mon, "invalid stats target %s\n", target_str);
2295         goto exit_no_print;
2296     }
2297     if (provider_str) {
2298         provider = qapi_enum_parse(&StatsProvider_lookup, provider_str, -1, &err);
2299         if (err) {
2300             monitor_printf(mon, "invalid stats provider %s\n", provider_str);
2301             goto exit_no_print;
2302         }
2303     }
2304 
2305     schema = qmp_query_stats_schemas(provider_str ? true : false,
2306                                      provider, &err);
2307     if (err) {
2308         goto exit;
2309     }
2310 
2311     switch (target) {
2312     case STATS_TARGET_VM:
2313         filter = stats_filter(target, names, -1, provider);
2314         break;
2315     case STATS_TARGET_VCPU: {}
2316         int cpu_index = monitor_get_cpu_index(mon);
2317         filter = stats_filter(target, names, cpu_index, provider);
2318         break;
2319     default:
2320         abort();
2321     }
2322 
2323     stats = qmp_query_stats(filter, &err);
2324     if (err) {
2325         goto exit;
2326     }
2327     for (entry = stats; entry; entry = entry->next) {
2328         print_stats_results(mon, target, provider_str == NULL, entry->value, schema);
2329     }
2330 
2331 exit:
2332     if (err) {
2333         monitor_printf(mon, "%s\n", error_get_pretty(err));
2334     }
2335 exit_no_print:
2336     error_free(err);
2337 }
2338 
2339 static void hmp_virtio_dump_protocols(Monitor *mon,
2340                                       VhostDeviceProtocols *pcol)
2341 {
2342     strList *pcol_list = pcol->protocols;
2343     while (pcol_list) {
2344         monitor_printf(mon, "\t%s", pcol_list->value);
2345         pcol_list = pcol_list->next;
2346         if (pcol_list != NULL) {
2347             monitor_printf(mon, ",\n");
2348         }
2349     }
2350     monitor_printf(mon, "\n");
2351     if (pcol->has_unknown_protocols) {
2352         monitor_printf(mon, "  unknown-protocols(0x%016"PRIx64")\n",
2353                        pcol->unknown_protocols);
2354     }
2355 }
2356 
2357 static void hmp_virtio_dump_status(Monitor *mon,
2358                                    VirtioDeviceStatus *status)
2359 {
2360     strList *status_list = status->statuses;
2361     while (status_list) {
2362         monitor_printf(mon, "\t%s", status_list->value);
2363         status_list = status_list->next;
2364         if (status_list != NULL) {
2365             monitor_printf(mon, ",\n");
2366         }
2367     }
2368     monitor_printf(mon, "\n");
2369     if (status->has_unknown_statuses) {
2370         monitor_printf(mon, "  unknown-statuses(0x%016"PRIx32")\n",
2371                        status->unknown_statuses);
2372     }
2373 }
2374 
2375 static void hmp_virtio_dump_features(Monitor *mon,
2376                                      VirtioDeviceFeatures *features)
2377 {
2378     strList *transport_list = features->transports;
2379     while (transport_list) {
2380         monitor_printf(mon, "\t%s", transport_list->value);
2381         transport_list = transport_list->next;
2382         if (transport_list != NULL) {
2383             monitor_printf(mon, ",\n");
2384         }
2385     }
2386 
2387     monitor_printf(mon, "\n");
2388     strList *list = features->dev_features;
2389     if (list) {
2390         while (list) {
2391             monitor_printf(mon, "\t%s", list->value);
2392             list = list->next;
2393             if (list != NULL) {
2394                 monitor_printf(mon, ",\n");
2395             }
2396         }
2397         monitor_printf(mon, "\n");
2398     }
2399 
2400     if (features->has_unknown_dev_features) {
2401         monitor_printf(mon, "  unknown-features(0x%016"PRIx64")\n",
2402                        features->unknown_dev_features);
2403     }
2404 }
2405 
2406 void hmp_virtio_query(Monitor *mon, const QDict *qdict)
2407 {
2408     Error *err = NULL;
2409     VirtioInfoList *list = qmp_x_query_virtio(&err);
2410     VirtioInfoList *node;
2411 
2412     if (err != NULL) {
2413         hmp_handle_error(mon, err);
2414         return;
2415     }
2416 
2417     if (list == NULL) {
2418         monitor_printf(mon, "No VirtIO devices\n");
2419         return;
2420     }
2421 
2422     node = list;
2423     while (node) {
2424         monitor_printf(mon, "%s [%s]\n", node->value->path,
2425                        node->value->name);
2426         node = node->next;
2427     }
2428     qapi_free_VirtioInfoList(list);
2429 }
2430 
2431 void hmp_virtio_status(Monitor *mon, const QDict *qdict)
2432 {
2433     Error *err = NULL;
2434     const char *path = qdict_get_try_str(qdict, "path");
2435     VirtioStatus *s = qmp_x_query_virtio_status(path, &err);
2436 
2437     if (err != NULL) {
2438         hmp_handle_error(mon, err);
2439         return;
2440     }
2441 
2442     monitor_printf(mon, "%s:\n", path);
2443     monitor_printf(mon, "  device_name:             %s %s\n",
2444                    s->name, s->vhost_dev ? "(vhost)" : "");
2445     monitor_printf(mon, "  device_id:               %d\n", s->device_id);
2446     monitor_printf(mon, "  vhost_started:           %s\n",
2447                    s->vhost_started ? "true" : "false");
2448     monitor_printf(mon, "  bus_name:                %s\n", s->bus_name);
2449     monitor_printf(mon, "  broken:                  %s\n",
2450                    s->broken ? "true" : "false");
2451     monitor_printf(mon, "  disabled:                %s\n",
2452                    s->disabled ? "true" : "false");
2453     monitor_printf(mon, "  disable_legacy_check:    %s\n",
2454                    s->disable_legacy_check ? "true" : "false");
2455     monitor_printf(mon, "  started:                 %s\n",
2456                    s->started ? "true" : "false");
2457     monitor_printf(mon, "  use_started:             %s\n",
2458                    s->use_started ? "true" : "false");
2459     monitor_printf(mon, "  start_on_kick:           %s\n",
2460                    s->start_on_kick ? "true" : "false");
2461     monitor_printf(mon, "  use_guest_notifier_mask: %s\n",
2462                    s->use_guest_notifier_mask ? "true" : "false");
2463     monitor_printf(mon, "  vm_running:              %s\n",
2464                    s->vm_running ? "true" : "false");
2465     monitor_printf(mon, "  num_vqs:                 %"PRId64"\n", s->num_vqs);
2466     monitor_printf(mon, "  queue_sel:               %d\n",
2467                    s->queue_sel);
2468     monitor_printf(mon, "  isr:                     %d\n", s->isr);
2469     monitor_printf(mon, "  endianness:              %s\n",
2470                    s->device_endian);
2471     monitor_printf(mon, "  status:\n");
2472     hmp_virtio_dump_status(mon, s->status);
2473     monitor_printf(mon, "  Guest features:\n");
2474     hmp_virtio_dump_features(mon, s->guest_features);
2475     monitor_printf(mon, "  Host features:\n");
2476     hmp_virtio_dump_features(mon, s->host_features);
2477     monitor_printf(mon, "  Backend features:\n");
2478     hmp_virtio_dump_features(mon, s->backend_features);
2479 
2480     if (s->vhost_dev) {
2481         monitor_printf(mon, "  VHost:\n");
2482         monitor_printf(mon, "    nvqs:           %d\n",
2483                        s->vhost_dev->nvqs);
2484         monitor_printf(mon, "    vq_index:       %"PRId64"\n",
2485                        s->vhost_dev->vq_index);
2486         monitor_printf(mon, "    max_queues:     %"PRId64"\n",
2487                        s->vhost_dev->max_queues);
2488         monitor_printf(mon, "    n_mem_sections: %"PRId64"\n",
2489                        s->vhost_dev->n_mem_sections);
2490         monitor_printf(mon, "    n_tmp_sections: %"PRId64"\n",
2491                        s->vhost_dev->n_tmp_sections);
2492         monitor_printf(mon, "    backend_cap:    %"PRId64"\n",
2493                        s->vhost_dev->backend_cap);
2494         monitor_printf(mon, "    log_enabled:    %s\n",
2495                        s->vhost_dev->log_enabled ? "true" : "false");
2496         monitor_printf(mon, "    log_size:       %"PRId64"\n",
2497                        s->vhost_dev->log_size);
2498         monitor_printf(mon, "    Features:\n");
2499         hmp_virtio_dump_features(mon, s->vhost_dev->features);
2500         monitor_printf(mon, "    Acked features:\n");
2501         hmp_virtio_dump_features(mon, s->vhost_dev->acked_features);
2502         monitor_printf(mon, "    Backend features:\n");
2503         hmp_virtio_dump_features(mon, s->vhost_dev->backend_features);
2504         monitor_printf(mon, "    Protocol features:\n");
2505         hmp_virtio_dump_protocols(mon, s->vhost_dev->protocol_features);
2506     }
2507 
2508     qapi_free_VirtioStatus(s);
2509 }
2510 
2511 void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict)
2512 {
2513     Error *err = NULL;
2514     const char *path = qdict_get_try_str(qdict, "path");
2515     int queue = qdict_get_int(qdict, "queue");
2516     VirtVhostQueueStatus *s =
2517         qmp_x_query_virtio_vhost_queue_status(path, queue, &err);
2518 
2519     if (err != NULL) {
2520         hmp_handle_error(mon, err);
2521         return;
2522     }
2523 
2524     monitor_printf(mon, "%s:\n", path);
2525     monitor_printf(mon, "  device_name:          %s (vhost)\n",
2526                    s->name);
2527     monitor_printf(mon, "  kick:                 %"PRId64"\n", s->kick);
2528     monitor_printf(mon, "  call:                 %"PRId64"\n", s->call);
2529     monitor_printf(mon, "  VRing:\n");
2530     monitor_printf(mon, "    num:         %"PRId64"\n", s->num);
2531     monitor_printf(mon, "    desc:        0x%016"PRIx64"\n", s->desc);
2532     monitor_printf(mon, "    desc_phys:   0x%016"PRIx64"\n",
2533                    s->desc_phys);
2534     monitor_printf(mon, "    desc_size:   %"PRId32"\n", s->desc_size);
2535     monitor_printf(mon, "    avail:       0x%016"PRIx64"\n", s->avail);
2536     monitor_printf(mon, "    avail_phys:  0x%016"PRIx64"\n",
2537                    s->avail_phys);
2538     monitor_printf(mon, "    avail_size:  %"PRId32"\n", s->avail_size);
2539     monitor_printf(mon, "    used:        0x%016"PRIx64"\n", s->used);
2540     monitor_printf(mon, "    used_phys:   0x%016"PRIx64"\n",
2541                    s->used_phys);
2542     monitor_printf(mon, "    used_size:   %"PRId32"\n", s->used_size);
2543 
2544     qapi_free_VirtVhostQueueStatus(s);
2545 }
2546 
2547 void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
2548 {
2549     Error *err = NULL;
2550     const char *path = qdict_get_try_str(qdict, "path");
2551     int queue = qdict_get_int(qdict, "queue");
2552     VirtQueueStatus *s = qmp_x_query_virtio_queue_status(path, queue, &err);
2553 
2554     if (err != NULL) {
2555         hmp_handle_error(mon, err);
2556         return;
2557     }
2558 
2559     monitor_printf(mon, "%s:\n", path);
2560     monitor_printf(mon, "  device_name:          %s\n", s->name);
2561     monitor_printf(mon, "  queue_index:          %d\n", s->queue_index);
2562     monitor_printf(mon, "  inuse:                %d\n", s->inuse);
2563     monitor_printf(mon, "  used_idx:             %d\n", s->used_idx);
2564     monitor_printf(mon, "  signalled_used:       %d\n",
2565                    s->signalled_used);
2566     monitor_printf(mon, "  signalled_used_valid: %s\n",
2567                    s->signalled_used_valid ? "true" : "false");
2568     if (s->has_last_avail_idx) {
2569         monitor_printf(mon, "  last_avail_idx:       %d\n",
2570                        s->last_avail_idx);
2571     }
2572     if (s->has_shadow_avail_idx) {
2573         monitor_printf(mon, "  shadow_avail_idx:     %d\n",
2574                        s->shadow_avail_idx);
2575     }
2576     monitor_printf(mon, "  VRing:\n");
2577     monitor_printf(mon, "    num:          %"PRId32"\n", s->vring_num);
2578     monitor_printf(mon, "    num_default:  %"PRId32"\n",
2579                    s->vring_num_default);
2580     monitor_printf(mon, "    align:        %"PRId32"\n",
2581                    s->vring_align);
2582     monitor_printf(mon, "    desc:         0x%016"PRIx64"\n",
2583                    s->vring_desc);
2584     monitor_printf(mon, "    avail:        0x%016"PRIx64"\n",
2585                    s->vring_avail);
2586     monitor_printf(mon, "    used:         0x%016"PRIx64"\n",
2587                    s->vring_used);
2588 
2589     qapi_free_VirtQueueStatus(s);
2590 }
2591 
2592 void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict)
2593 {
2594     Error *err = NULL;
2595     const char *path = qdict_get_try_str(qdict, "path");
2596     int queue = qdict_get_int(qdict, "queue");
2597     int index = qdict_get_try_int(qdict, "index", -1);
2598     VirtioQueueElement *e;
2599     VirtioRingDescList *list;
2600 
2601     e = qmp_x_query_virtio_queue_element(path, queue, index != -1,
2602                                          index, &err);
2603     if (err != NULL) {
2604         hmp_handle_error(mon, err);
2605         return;
2606     }
2607 
2608     monitor_printf(mon, "%s:\n", path);
2609     monitor_printf(mon, "  device_name: %s\n", e->name);
2610     monitor_printf(mon, "  index:   %d\n", e->index);
2611     monitor_printf(mon, "  desc:\n");
2612     monitor_printf(mon, "    descs:\n");
2613 
2614     list = e->descs;
2615     while (list) {
2616         monitor_printf(mon, "        addr 0x%"PRIx64" len %d",
2617                        list->value->addr, list->value->len);
2618         if (list->value->flags) {
2619             strList *flag = list->value->flags;
2620             monitor_printf(mon, " (");
2621             while (flag) {
2622                 monitor_printf(mon, "%s", flag->value);
2623                 flag = flag->next;
2624                 if (flag) {
2625                     monitor_printf(mon, ", ");
2626                 }
2627             }
2628             monitor_printf(mon, ")");
2629         }
2630         list = list->next;
2631         if (list) {
2632             monitor_printf(mon, ",\n");
2633         }
2634     }
2635     monitor_printf(mon, "\n");
2636     monitor_printf(mon, "  avail:\n");
2637     monitor_printf(mon, "    flags: %d\n", e->avail->flags);
2638     monitor_printf(mon, "    idx:   %d\n", e->avail->idx);
2639     monitor_printf(mon, "    ring:  %d\n", e->avail->ring);
2640     monitor_printf(mon, "  used:\n");
2641     monitor_printf(mon, "    flags: %d\n", e->used->flags);
2642     monitor_printf(mon, "    idx:   %d\n", e->used->idx);
2643 
2644     qapi_free_VirtioQueueElement(e);
2645 }
2646