1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include "hmp.h"
17#include "net/net.h"
18#include "net/eth.h"
19#include "sysemu/char.h"
20#include "sysemu/block-backend.h"
21#include "qemu/option.h"
22#include "qemu/timer.h"
23#include "qmp-commands.h"
24#include "qemu/sockets.h"
25#include "monitor/monitor.h"
26#include "monitor/qdev.h"
27#include "qapi/opts-visitor.h"
28#include "qapi/qmp/qerror.h"
29#include "qapi/string-output-visitor.h"
30#include "qapi-visit.h"
31#include "ui/console.h"
32#include "block/qapi.h"
33#include "qemu-io.h"
34
35#ifdef CONFIG_SPICE
36#include <spice/enums.h>
37#endif
38
39static void hmp_handle_error(Monitor *mon, Error **errp)
40{
41 assert(errp);
42 if (*errp) {
43 monitor_printf(mon, "%s\n", error_get_pretty(*errp));
44 error_free(*errp);
45 }
46}
47
48void hmp_info_name(Monitor *mon, const QDict *qdict)
49{
50 NameInfo *info;
51
52 info = qmp_query_name(NULL);
53 if (info->has_name) {
54 monitor_printf(mon, "%s\n", info->name);
55 }
56 qapi_free_NameInfo(info);
57}
58
59void hmp_info_version(Monitor *mon, const QDict *qdict)
60{
61 VersionInfo *info;
62
63 info = qmp_query_version(NULL);
64
65 monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
66 info->qemu->major, info->qemu->minor, info->qemu->micro,
67 info->package);
68
69 qapi_free_VersionInfo(info);
70}
71
72void hmp_info_kvm(Monitor *mon, const QDict *qdict)
73{
74 KvmInfo *info;
75
76 info = qmp_query_kvm(NULL);
77 monitor_printf(mon, "kvm support: ");
78 if (info->present) {
79 monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled");
80 } else {
81 monitor_printf(mon, "not compiled\n");
82 }
83
84 qapi_free_KvmInfo(info);
85}
86
87void hmp_info_status(Monitor *mon, const QDict *qdict)
88{
89 StatusInfo *info;
90
91 info = qmp_query_status(NULL);
92
93 monitor_printf(mon, "VM status: %s%s",
94 info->running ? "running" : "paused",
95 info->singlestep ? " (single step mode)" : "");
96
97 if (!info->running && info->status != RUN_STATE_PAUSED) {
98 monitor_printf(mon, " (%s)", RunState_lookup[info->status]);
99 }
100
101 monitor_printf(mon, "\n");
102
103 qapi_free_StatusInfo(info);
104}
105
106void hmp_info_uuid(Monitor *mon, const QDict *qdict)
107{
108 UuidInfo *info;
109
110 info = qmp_query_uuid(NULL);
111 monitor_printf(mon, "%s\n", info->UUID);
112 qapi_free_UuidInfo(info);
113}
114
115void hmp_info_chardev(Monitor *mon, const QDict *qdict)
116{
117 ChardevInfoList *char_info, *info;
118
119 char_info = qmp_query_chardev(NULL);
120 for (info = char_info; info; info = info->next) {
121 monitor_printf(mon, "%s: filename=%s\n", info->value->label,
122 info->value->filename);
123 }
124
125 qapi_free_ChardevInfoList(char_info);
126}
127
128void hmp_info_mice(Monitor *mon, const QDict *qdict)
129{
130 MouseInfoList *mice_list, *mouse;
131
132 mice_list = qmp_query_mice(NULL);
133 if (!mice_list) {
134 monitor_printf(mon, "No mouse devices connected\n");
135 return;
136 }
137
138 for (mouse = mice_list; mouse; mouse = mouse->next) {
139 monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
140 mouse->value->current ? '*' : ' ',
141 mouse->value->index, mouse->value->name,
142 mouse->value->absolute ? " (absolute)" : "");
143 }
144
145 qapi_free_MouseInfoList(mice_list);
146}
147
148void hmp_info_migrate(Monitor *mon, const QDict *qdict)
149{
150 MigrationInfo *info;
151 MigrationCapabilityStatusList *caps, *cap;
152
153 info = qmp_query_migrate(NULL);
154 caps = qmp_query_migrate_capabilities(NULL);
155
156
157 if (info->has_status && caps) {
158 monitor_printf(mon, "capabilities: ");
159 for (cap = caps; cap; cap = cap->next) {
160 monitor_printf(mon, "%s: %s ",
161 MigrationCapability_lookup[cap->value->capability],
162 cap->value->state ? "on" : "off");
163 }
164 monitor_printf(mon, "\n");
165 }
166
167 if (info->has_status) {
168 monitor_printf(mon, "Migration status: %s\n",
169 MigrationStatus_lookup[info->status]);
170 monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
171 info->total_time);
172 if (info->has_expected_downtime) {
173 monitor_printf(mon, "expected downtime: %" PRIu64 " milliseconds\n",
174 info->expected_downtime);
175 }
176 if (info->has_downtime) {
177 monitor_printf(mon, "downtime: %" PRIu64 " milliseconds\n",
178 info->downtime);
179 }
180 if (info->has_setup_time) {
181 monitor_printf(mon, "setup: %" PRIu64 " milliseconds\n",
182 info->setup_time);
183 }
184 }
185
186 if (info->has_ram) {
187 monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n",
188 info->ram->transferred >> 10);
189 monitor_printf(mon, "throughput: %0.2f mbps\n",
190 info->ram->mbps);
191 monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n",
192 info->ram->remaining >> 10);
193 monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n",
194 info->ram->total >> 10);
195 monitor_printf(mon, "duplicate: %" PRIu64 " pages\n",
196 info->ram->duplicate);
197 monitor_printf(mon, "skipped: %" PRIu64 " pages\n",
198 info->ram->skipped);
199 monitor_printf(mon, "normal: %" PRIu64 " pages\n",
200 info->ram->normal);
201 monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
202 info->ram->normal_bytes >> 10);
203 monitor_printf(mon, "dirty sync count: %" PRIu64 "\n",
204 info->ram->dirty_sync_count);
205 if (info->ram->dirty_pages_rate) {
206 monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
207 info->ram->dirty_pages_rate);
208 }
209 }
210
211 if (info->has_disk) {
212 monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n",
213 info->disk->transferred >> 10);
214 monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n",
215 info->disk->remaining >> 10);
216 monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n",
217 info->disk->total >> 10);
218 }
219
220 if (info->has_xbzrle_cache) {
221 monitor_printf(mon, "cache size: %" PRIu64 " bytes\n",
222 info->xbzrle_cache->cache_size);
223 monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n",
224 info->xbzrle_cache->bytes >> 10);
225 monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
226 info->xbzrle_cache->pages);
227 monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n",
228 info->xbzrle_cache->cache_miss);
229 monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n",
230 info->xbzrle_cache->cache_miss_rate);
231 monitor_printf(mon, "xbzrle overflow : %" PRIu64 "\n",
232 info->xbzrle_cache->overflow);
233 }
234
235 qapi_free_MigrationInfo(info);
236 qapi_free_MigrationCapabilityStatusList(caps);
237}
238
239void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
240{
241 MigrationCapabilityStatusList *caps, *cap;
242
243 caps = qmp_query_migrate_capabilities(NULL);
244
245 if (caps) {
246 monitor_printf(mon, "capabilities: ");
247 for (cap = caps; cap; cap = cap->next) {
248 monitor_printf(mon, "%s: %s ",
249 MigrationCapability_lookup[cap->value->capability],
250 cap->value->state ? "on" : "off");
251 }
252 monitor_printf(mon, "\n");
253 }
254
255 qapi_free_MigrationCapabilityStatusList(caps);
256}
257
258void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
259{
260 MigrationParameters *params;
261
262 params = qmp_query_migrate_parameters(NULL);
263
264 if (params) {
265 monitor_printf(mon, "parameters:");
266 monitor_printf(mon, " %s: %" PRId64,
267 MigrationParameter_lookup[MIGRATION_PARAMETER_COMPRESS_LEVEL],
268 params->compress_level);
269 monitor_printf(mon, " %s: %" PRId64,
270 MigrationParameter_lookup[MIGRATION_PARAMETER_COMPRESS_THREADS],
271 params->compress_threads);
272 monitor_printf(mon, " %s: %" PRId64,
273 MigrationParameter_lookup[MIGRATION_PARAMETER_DECOMPRESS_THREADS],
274 params->decompress_threads);
275 monitor_printf(mon, "\n");
276 }
277
278 qapi_free_MigrationParameters(params);
279}
280
281void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict)
282{
283 monitor_printf(mon, "xbzrel cache size: %" PRId64 " kbytes\n",
284 qmp_query_migrate_cache_size(NULL) >> 10);
285}
286
287void hmp_info_cpus(Monitor *mon, const QDict *qdict)
288{
289 CpuInfoList *cpu_list, *cpu;
290
291 cpu_list = qmp_query_cpus(NULL);
292
293 for (cpu = cpu_list; cpu; cpu = cpu->next) {
294 int active = ' ';
295
296 if (cpu->value->CPU == monitor_get_cpu_index()) {
297 active = '*';
298 }
299
300 monitor_printf(mon, "%c CPU #%" PRId64 ":", active, cpu->value->CPU);
301
302 if (cpu->value->has_pc) {
303 monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->pc);
304 }
305 if (cpu->value->has_nip) {
306 monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->nip);
307 }
308 if (cpu->value->has_npc) {
309 monitor_printf(mon, " npc=0x%016" PRIx64, cpu->value->npc);
310 }
311 if (cpu->value->has_PC) {
312 monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->PC);
313 }
314
315 if (cpu->value->halted) {
316 monitor_printf(mon, " (halted)");
317 }
318
319 monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id);
320 }
321
322 qapi_free_CpuInfoList(cpu_list);
323}
324
325static void print_block_info(Monitor *mon, BlockInfo *info,
326 BlockDeviceInfo *inserted, bool verbose)
327{
328 ImageInfo *image_info;
329
330 assert(!info || !info->has_inserted || info->inserted == inserted);
331
332 if (info) {
333 monitor_printf(mon, "%s", info->device);
334 if (inserted && inserted->has_node_name) {
335 monitor_printf(mon, " (%s)", inserted->node_name);
336 }
337 } else {
338 assert(inserted);
339 monitor_printf(mon, "%s",
340 inserted->has_node_name
341 ? inserted->node_name
342 : "<anonymous>");
343 }
344
345 if (inserted) {
346 monitor_printf(mon, ": %s (%s%s%s)\n",
347 inserted->file,
348 inserted->drv,
349 inserted->ro ? ", read-only" : "",
350 inserted->encrypted ? ", encrypted" : "");
351 } else {
352 monitor_printf(mon, ": [not inserted]\n");
353 }
354
355 if (info) {
356 if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
357 monitor_printf(mon, " I/O status: %s\n",
358 BlockDeviceIoStatus_lookup[info->io_status]);
359 }
360
361 if (info->removable) {
362 monitor_printf(mon, " Removable device: %slocked, tray %s\n",
363 info->locked ? "" : "not ",
364 info->tray_open ? "open" : "closed");
365 }
366 }
367
368
369 if (!inserted) {
370 return;
371 }
372
373 monitor_printf(mon, " Cache mode: %s%s%s\n",
374 inserted->cache->writeback ? "writeback" : "writethrough",
375 inserted->cache->direct ? ", direct" : "",
376 inserted->cache->no_flush ? ", ignore flushes" : "");
377
378 if (inserted->has_backing_file) {
379 monitor_printf(mon,
380 " Backing file: %s "
381 "(chain depth: %" PRId64 ")\n",
382 inserted->backing_file,
383 inserted->backing_file_depth);
384 }
385
386 if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
387 monitor_printf(mon, " Detect zeroes: %s\n",
388 BlockdevDetectZeroesOptions_lookup[inserted->detect_zeroes]);
389 }
390
391 if (inserted->bps || inserted->bps_rd || inserted->bps_wr ||
392 inserted->iops || inserted->iops_rd || inserted->iops_wr)
393 {
394 monitor_printf(mon, " I/O throttling: bps=%" PRId64
395 " bps_rd=%" PRId64 " bps_wr=%" PRId64
396 " bps_max=%" PRId64
397 " bps_rd_max=%" PRId64
398 " bps_wr_max=%" PRId64
399 " iops=%" PRId64 " iops_rd=%" PRId64
400 " iops_wr=%" PRId64
401 " iops_max=%" PRId64
402 " iops_rd_max=%" PRId64
403 " iops_wr_max=%" PRId64
404 " iops_size=%" PRId64
405 " group=%s\n",
406 inserted->bps,
407 inserted->bps_rd,
408 inserted->bps_wr,
409 inserted->bps_max,
410 inserted->bps_rd_max,
411 inserted->bps_wr_max,
412 inserted->iops,
413 inserted->iops_rd,
414 inserted->iops_wr,
415 inserted->iops_max,
416 inserted->iops_rd_max,
417 inserted->iops_wr_max,
418 inserted->iops_size,
419 inserted->group);
420 }
421
422 if (verbose) {
423 monitor_printf(mon, "\nImages:\n");
424 image_info = inserted->image;
425 while (1) {
426 bdrv_image_info_dump((fprintf_function)monitor_printf,
427 mon, image_info);
428 if (image_info->has_backing_image) {
429 image_info = image_info->backing_image;
430 } else {
431 break;
432 }
433 }
434 }
435}
436
437void hmp_info_block(Monitor *mon, const QDict *qdict)
438{
439 BlockInfoList *block_list, *info;
440 BlockDeviceInfoList *blockdev_list, *blockdev;
441 const char *device = qdict_get_try_str(qdict, "device");
442 bool verbose = qdict_get_try_bool(qdict, "verbose", false);
443 bool nodes = qdict_get_try_bool(qdict, "nodes", false);
444 bool printed = false;
445
446
447 if (!nodes) {
448 block_list = qmp_query_block(NULL);
449 } else {
450 block_list = NULL;
451 }
452
453 for (info = block_list; info; info = info->next) {
454 if (device && strcmp(device, info->value->device)) {
455 continue;
456 }
457
458 if (info != block_list) {
459 monitor_printf(mon, "\n");
460 }
461
462 print_block_info(mon, info->value, info->value->has_inserted
463 ? info->value->inserted : NULL,
464 verbose);
465 printed = true;
466 }
467
468 qapi_free_BlockInfoList(block_list);
469
470 if ((!device && !nodes) || printed) {
471 return;
472 }
473
474
475 blockdev_list = qmp_query_named_block_nodes(NULL);
476 for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
477 assert(blockdev->value->has_node_name);
478 if (device && strcmp(device, blockdev->value->node_name)) {
479 continue;
480 }
481
482 if (blockdev != blockdev_list) {
483 monitor_printf(mon, "\n");
484 }
485
486 print_block_info(mon, NULL, blockdev->value, verbose);
487 }
488 qapi_free_BlockDeviceInfoList(blockdev_list);
489}
490
491void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
492{
493 BlockStatsList *stats_list, *stats;
494
495 stats_list = qmp_query_blockstats(false, false, NULL);
496
497 for (stats = stats_list; stats; stats = stats->next) {
498 if (!stats->value->has_device) {
499 continue;
500 }
501
502 monitor_printf(mon, "%s:", stats->value->device);
503 monitor_printf(mon, " rd_bytes=%" PRId64
504 " wr_bytes=%" PRId64
505 " rd_operations=%" PRId64
506 " wr_operations=%" PRId64
507 " flush_operations=%" PRId64
508 " wr_total_time_ns=%" PRId64
509 " rd_total_time_ns=%" PRId64
510 " flush_total_time_ns=%" PRId64
511 " rd_merged=%" PRId64
512 " wr_merged=%" PRId64
513 "\n",
514 stats->value->stats->rd_bytes,
515 stats->value->stats->wr_bytes,
516 stats->value->stats->rd_operations,
517 stats->value->stats->wr_operations,
518 stats->value->stats->flush_operations,
519 stats->value->stats->wr_total_time_ns,
520 stats->value->stats->rd_total_time_ns,
521 stats->value->stats->flush_total_time_ns,
522 stats->value->stats->rd_merged,
523 stats->value->stats->wr_merged);
524 }
525
526 qapi_free_BlockStatsList(stats_list);
527}
528
529void hmp_info_vnc(Monitor *mon, const QDict *qdict)
530{
531 VncInfo *info;
532 Error *err = NULL;
533 VncClientInfoList *client;
534
535 info = qmp_query_vnc(&err);
536 if (err) {
537 monitor_printf(mon, "%s\n", error_get_pretty(err));
538 error_free(err);
539 return;
540 }
541
542 if (!info->enabled) {
543 monitor_printf(mon, "Server: disabled\n");
544 goto out;
545 }
546
547 monitor_printf(mon, "Server:\n");
548 if (info->has_host && info->has_service) {
549 monitor_printf(mon, " address: %s:%s\n", info->host, info->service);
550 }
551 if (info->has_auth) {
552 monitor_printf(mon, " auth: %s\n", info->auth);
553 }
554
555 if (!info->has_clients || info->clients == NULL) {
556 monitor_printf(mon, "Client: none\n");
557 } else {
558 for (client = info->clients; client; client = client->next) {
559 monitor_printf(mon, "Client:\n");
560 monitor_printf(mon, " address: %s:%s\n",
561 client->value->base->host,
562 client->value->base->service);
563 monitor_printf(mon, " x509_dname: %s\n",
564 client->value->x509_dname ?
565 client->value->x509_dname : "none");
566 monitor_printf(mon, " username: %s\n",
567 client->value->has_sasl_username ?
568 client->value->sasl_username : "none");
569 }
570 }
571
572out:
573 qapi_free_VncInfo(info);
574}
575
576#ifdef CONFIG_SPICE
577void hmp_info_spice(Monitor *mon, const QDict *qdict)
578{
579 SpiceChannelList *chan;
580 SpiceInfo *info;
581 const char *channel_name;
582 const char * const channel_names[] = {
583 [SPICE_CHANNEL_MAIN] = "main",
584 [SPICE_CHANNEL_DISPLAY] = "display",
585 [SPICE_CHANNEL_INPUTS] = "inputs",
586 [SPICE_CHANNEL_CURSOR] = "cursor",
587 [SPICE_CHANNEL_PLAYBACK] = "playback",
588 [SPICE_CHANNEL_RECORD] = "record",
589 [SPICE_CHANNEL_TUNNEL] = "tunnel",
590 [SPICE_CHANNEL_SMARTCARD] = "smartcard",
591 [SPICE_CHANNEL_USBREDIR] = "usbredir",
592 [SPICE_CHANNEL_PORT] = "port",
593#if 0
594
595
596
597 [SPICE_CHANNEL_WEBDAV] = "webdav",
598#endif
599 };
600
601 info = qmp_query_spice(NULL);
602
603 if (!info->enabled) {
604 monitor_printf(mon, "Server: disabled\n");
605 goto out;
606 }
607
608 monitor_printf(mon, "Server:\n");
609 if (info->has_port) {
610 monitor_printf(mon, " address: %s:%" PRId64 "\n",
611 info->host, info->port);
612 }
613 if (info->has_tls_port) {
614 monitor_printf(mon, " address: %s:%" PRId64 " [tls]\n",
615 info->host, info->tls_port);
616 }
617 monitor_printf(mon, " migrated: %s\n",
618 info->migrated ? "true" : "false");
619 monitor_printf(mon, " auth: %s\n", info->auth);
620 monitor_printf(mon, " compiled: %s\n", info->compiled_version);
621 monitor_printf(mon, " mouse-mode: %s\n",
622 SpiceQueryMouseMode_lookup[info->mouse_mode]);
623
624 if (!info->has_channels || info->channels == NULL) {
625 monitor_printf(mon, "Channels: none\n");
626 } else {
627 for (chan = info->channels; chan; chan = chan->next) {
628 monitor_printf(mon, "Channel:\n");
629 monitor_printf(mon, " address: %s:%s%s\n",
630 chan->value->base->host, chan->value->base->port,
631 chan->value->tls ? " [tls]" : "");
632 monitor_printf(mon, " session: %" PRId64 "\n",
633 chan->value->connection_id);
634 monitor_printf(mon, " channel: %" PRId64 ":%" PRId64 "\n",
635 chan->value->channel_type, chan->value->channel_id);
636
637 channel_name = "unknown";
638 if (chan->value->channel_type > 0 &&
639 chan->value->channel_type < ARRAY_SIZE(channel_names) &&
640 channel_names[chan->value->channel_type]) {
641 channel_name = channel_names[chan->value->channel_type];
642 }
643
644 monitor_printf(mon, " channel name: %s\n", channel_name);
645 }
646 }
647
648out:
649 qapi_free_SpiceInfo(info);
650}
651#endif
652
653void hmp_info_balloon(Monitor *mon, const QDict *qdict)
654{
655 BalloonInfo *info;
656 Error *err = NULL;
657
658 info = qmp_query_balloon(&err);
659 if (err) {
660 monitor_printf(mon, "%s\n", error_get_pretty(err));
661 error_free(err);
662 return;
663 }
664
665 monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
666
667 qapi_free_BalloonInfo(info);
668}
669
670static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
671{
672 PciMemoryRegionList *region;
673
674 monitor_printf(mon, " Bus %2" PRId64 ", ", dev->bus);
675 monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n",
676 dev->slot, dev->function);
677 monitor_printf(mon, " ");
678
679 if (dev->class_info->has_desc) {
680 monitor_printf(mon, "%s", dev->class_info->desc);
681 } else {
682 monitor_printf(mon, "Class %04" PRId64, dev->class_info->q_class);
683 }
684
685 monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
686 dev->id->vendor, dev->id->device);
687
688 if (dev->has_irq) {
689 monitor_printf(mon, " IRQ %" PRId64 ".\n", dev->irq);
690 }
691
692 if (dev->has_pci_bridge) {
693 monitor_printf(mon, " BUS %" PRId64 ".\n",
694 dev->pci_bridge->bus->number);
695 monitor_printf(mon, " secondary bus %" PRId64 ".\n",
696 dev->pci_bridge->bus->secondary);
697 monitor_printf(mon, " subordinate bus %" PRId64 ".\n",
698 dev->pci_bridge->bus->subordinate);
699
700 monitor_printf(mon, " IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n",
701 dev->pci_bridge->bus->io_range->base,
702 dev->pci_bridge->bus->io_range->limit);
703
704 monitor_printf(mon,
705 " memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n",
706 dev->pci_bridge->bus->memory_range->base,
707 dev->pci_bridge->bus->memory_range->limit);
708
709 monitor_printf(mon, " prefetchable memory range "
710 "[0x%08"PRIx64", 0x%08"PRIx64"]\n",
711 dev->pci_bridge->bus->prefetchable_range->base,
712 dev->pci_bridge->bus->prefetchable_range->limit);
713 }
714
715 for (region = dev->regions; region; region = region->next) {
716 uint64_t addr, size;
717
718 addr = region->value->address;
719 size = region->value->size;
720
721 monitor_printf(mon, " BAR%" PRId64 ": ", region->value->bar);
722
723 if (!strcmp(region->value->type, "io")) {
724 monitor_printf(mon, "I/O at 0x%04" PRIx64
725 " [0x%04" PRIx64 "].\n",
726 addr, addr + size - 1);
727 } else {
728 monitor_printf(mon, "%d bit%s memory at 0x%08" PRIx64
729 " [0x%08" PRIx64 "].\n",
730 region->value->mem_type_64 ? 64 : 32,
731 region->value->prefetch ? " prefetchable" : "",
732 addr, addr + size - 1);
733 }
734 }
735
736 monitor_printf(mon, " id \"%s\"\n", dev->qdev_id);
737
738 if (dev->has_pci_bridge) {
739 if (dev->pci_bridge->has_devices) {
740 PciDeviceInfoList *cdev;
741 for (cdev = dev->pci_bridge->devices; cdev; cdev = cdev->next) {
742 hmp_info_pci_device(mon, cdev->value);
743 }
744 }
745 }
746}
747
748void hmp_info_pci(Monitor *mon, const QDict *qdict)
749{
750 PciInfoList *info_list, *info;
751 Error *err = NULL;
752
753 info_list = qmp_query_pci(&err);
754 if (err) {
755 monitor_printf(mon, "PCI devices not supported\n");
756 error_free(err);
757 return;
758 }
759
760 for (info = info_list; info; info = info->next) {
761 PciDeviceInfoList *dev;
762
763 for (dev = info->value->devices; dev; dev = dev->next) {
764 hmp_info_pci_device(mon, dev->value);
765 }
766 }
767
768 qapi_free_PciInfoList(info_list);
769}
770
771void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
772{
773 BlockJobInfoList *list;
774 Error *err = NULL;
775
776 list = qmp_query_block_jobs(&err);
777 assert(!err);
778
779 if (!list) {
780 monitor_printf(mon, "No active jobs\n");
781 return;
782 }
783
784 while (list) {
785 if (strcmp(list->value->type, "stream") == 0) {
786 monitor_printf(mon, "Streaming device %s: Completed %" PRId64
787 " of %" PRId64 " bytes, speed limit %" PRId64
788 " bytes/s\n",
789 list->value->device,
790 list->value->offset,
791 list->value->len,
792 list->value->speed);
793 } else {
794 monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
795 " of %" PRId64 " bytes, speed limit %" PRId64
796 " bytes/s\n",
797 list->value->type,
798 list->value->device,
799 list->value->offset,
800 list->value->len,
801 list->value->speed);
802 }
803 list = list->next;
804 }
805
806 qapi_free_BlockJobInfoList(list);
807}
808
809void hmp_info_tpm(Monitor *mon, const QDict *qdict)
810{
811 TPMInfoList *info_list, *info;
812 Error *err = NULL;
813 unsigned int c = 0;
814 TPMPassthroughOptions *tpo;
815
816 info_list = qmp_query_tpm(&err);
817 if (err) {
818 monitor_printf(mon, "TPM device not supported\n");
819 error_free(err);
820 return;
821 }
822
823 if (info_list) {
824 monitor_printf(mon, "TPM device:\n");
825 }
826
827 for (info = info_list; info; info = info->next) {
828 TPMInfo *ti = info->value;
829 monitor_printf(mon, " tpm%d: model=%s\n",
830 c, TpmModel_lookup[ti->model]);
831
832 monitor_printf(mon, " \\ %s: type=%s",
833 ti->id, TpmTypeOptionsKind_lookup[ti->options->kind]);
834
835 switch (ti->options->kind) {
836 case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH:
837 tpo = ti->options->passthrough;
838 monitor_printf(mon, "%s%s%s%s",
839 tpo->has_path ? ",path=" : "",
840 tpo->has_path ? tpo->path : "",
841 tpo->has_cancel_path ? ",cancel-path=" : "",
842 tpo->has_cancel_path ? tpo->cancel_path : "");
843 break;
844 case TPM_TYPE_OPTIONS_KIND_MAX:
845 break;
846 }
847 monitor_printf(mon, "\n");
848 c++;
849 }
850 qapi_free_TPMInfoList(info_list);
851}
852
853void hmp_quit(Monitor *mon, const QDict *qdict)
854{
855 monitor_suspend(mon);
856 qmp_quit(NULL);
857}
858
859void hmp_stop(Monitor *mon, const QDict *qdict)
860{
861 qmp_stop(NULL);
862}
863
864void hmp_system_reset(Monitor *mon, const QDict *qdict)
865{
866 qmp_system_reset(NULL);
867}
868
869void hmp_system_powerdown(Monitor *mon, const QDict *qdict)
870{
871 qmp_system_powerdown(NULL);
872}
873
874void hmp_cpu(Monitor *mon, const QDict *qdict)
875{
876 int64_t cpu_index;
877
878
879
880 cpu_index = qdict_get_int(qdict, "index");
881 if (monitor_set_cpu(cpu_index) < 0) {
882 monitor_printf(mon, "invalid CPU index\n");
883 }
884}
885
886void hmp_memsave(Monitor *mon, const QDict *qdict)
887{
888 uint32_t size = qdict_get_int(qdict, "size");
889 const char *filename = qdict_get_str(qdict, "filename");
890 uint64_t addr = qdict_get_int(qdict, "val");
891 Error *err = NULL;
892
893 qmp_memsave(addr, size, filename, true, monitor_get_cpu_index(), &err);
894 hmp_handle_error(mon, &err);
895}
896
897void hmp_pmemsave(Monitor *mon, const QDict *qdict)
898{
899 uint32_t size = qdict_get_int(qdict, "size");
900 const char *filename = qdict_get_str(qdict, "filename");
901 uint64_t addr = qdict_get_int(qdict, "val");
902 Error *err = NULL;
903
904 qmp_pmemsave(addr, size, filename, &err);
905 hmp_handle_error(mon, &err);
906}
907
908void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
909{
910 const char *chardev = qdict_get_str(qdict, "device");
911 const char *data = qdict_get_str(qdict, "data");
912 Error *err = NULL;
913
914 qmp_ringbuf_write(chardev, data, false, 0, &err);
915
916 hmp_handle_error(mon, &err);
917}
918
919void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
920{
921 uint32_t size = qdict_get_int(qdict, "size");
922 const char *chardev = qdict_get_str(qdict, "device");
923 char *data;
924 Error *err = NULL;
925 int i;
926
927 data = qmp_ringbuf_read(chardev, size, false, 0, &err);
928 if (err) {
929 monitor_printf(mon, "%s\n", error_get_pretty(err));
930 error_free(err);
931 return;
932 }
933
934 for (i = 0; data[i]; i++) {
935 unsigned char ch = data[i];
936
937 if (ch == '\\') {
938 monitor_printf(mon, "\\\\");
939 } else if ((ch < 0x20 && ch != '\n' && ch != '\t') || ch == 0x7F) {
940 monitor_printf(mon, "\\u%04X", ch);
941 } else {
942 monitor_printf(mon, "%c", ch);
943 }
944
945 }
946 monitor_printf(mon, "\n");
947 g_free(data);
948}
949
950static void hmp_cont_cb(void *opaque, int err)
951{
952 if (!err) {
953 qmp_cont(NULL);
954 }
955}
956
957static bool key_is_missing(const BlockInfo *bdev)
958{
959 return (bdev->inserted && bdev->inserted->encryption_key_missing);
960}
961
962void hmp_cont(Monitor *mon, const QDict *qdict)
963{
964 BlockInfoList *bdev_list, *bdev;
965 Error *err = NULL;
966
967 bdev_list = qmp_query_block(NULL);
968 for (bdev = bdev_list; bdev; bdev = bdev->next) {
969 if (key_is_missing(bdev->value)) {
970 monitor_read_block_device_key(mon, bdev->value->device,
971 hmp_cont_cb, NULL);
972 goto out;
973 }
974 }
975
976 qmp_cont(&err);
977 hmp_handle_error(mon, &err);
978
979out:
980 qapi_free_BlockInfoList(bdev_list);
981}
982
983void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
984{
985 qmp_system_wakeup(NULL);
986}
987
988void hmp_nmi(Monitor *mon, const QDict *qdict)
989{
990 Error *err = NULL;
991
992 qmp_inject_nmi(&err);
993 hmp_handle_error(mon, &err);
994}
995
996void hmp_set_link(Monitor *mon, const QDict *qdict)
997{
998 const char *name = qdict_get_str(qdict, "name");
999 bool up = qdict_get_bool(qdict, "up");
1000 Error *err = NULL;
1001
1002 qmp_set_link(name, up, &err);
1003 hmp_handle_error(mon, &err);
1004}
1005
1006void hmp_block_passwd(Monitor *mon, const QDict *qdict)
1007{
1008 const char *device = qdict_get_str(qdict, "device");
1009 const char *password = qdict_get_str(qdict, "password");
1010 Error *err = NULL;
1011
1012 qmp_block_passwd(true, device, false, NULL, password, &err);
1013 hmp_handle_error(mon, &err);
1014}
1015
1016void hmp_balloon(Monitor *mon, const QDict *qdict)
1017{
1018 int64_t value = qdict_get_int(qdict, "value");
1019 Error *err = NULL;
1020
1021 qmp_balloon(value, &err);
1022 if (err) {
1023 monitor_printf(mon, "balloon: %s\n", error_get_pretty(err));
1024 error_free(err);
1025 }
1026}
1027
1028void hmp_block_resize(Monitor *mon, const QDict *qdict)
1029{
1030 const char *device = qdict_get_str(qdict, "device");
1031 int64_t size = qdict_get_int(qdict, "size");
1032 Error *err = NULL;
1033
1034 qmp_block_resize(true, device, false, NULL, size, &err);
1035 hmp_handle_error(mon, &err);
1036}
1037
1038void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
1039{
1040 const char *device = qdict_get_str(qdict, "device");
1041 const char *filename = qdict_get_str(qdict, "target");
1042 const char *format = qdict_get_try_str(qdict, "format");
1043 bool reuse = qdict_get_try_bool(qdict, "reuse", false);
1044 bool full = qdict_get_try_bool(qdict, "full", false);
1045 enum NewImageMode mode;
1046 Error *err = NULL;
1047
1048 if (!filename) {
1049 error_setg(&err, QERR_MISSING_PARAMETER, "target");
1050 hmp_handle_error(mon, &err);
1051 return;
1052 }
1053
1054 if (reuse) {
1055 mode = NEW_IMAGE_MODE_EXISTING;
1056 } else {
1057 mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
1058 }
1059
1060 qmp_drive_mirror(device, filename, !!format, format,
1061 false, NULL, false, NULL,
1062 full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
1063 true, mode, false, 0, false, 0, false, 0,
1064 false, 0, false, 0, false, true, &err);
1065 hmp_handle_error(mon, &err);
1066}
1067
1068void hmp_drive_backup(Monitor *mon, const QDict *qdict)
1069{
1070 const char *device = qdict_get_str(qdict, "device");
1071 const char *filename = qdict_get_str(qdict, "target");
1072 const char *format = qdict_get_try_str(qdict, "format");
1073 bool reuse = qdict_get_try_bool(qdict, "reuse", false);
1074 bool full = qdict_get_try_bool(qdict, "full", false);
1075 enum NewImageMode mode;
1076 Error *err = NULL;
1077
1078 if (!filename) {
1079 error_setg(&err, QERR_MISSING_PARAMETER, "target");
1080 hmp_handle_error(mon, &err);
1081 return;
1082 }
1083
1084 if (reuse) {
1085 mode = NEW_IMAGE_MODE_EXISTING;
1086 } else {
1087 mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
1088 }
1089
1090 qmp_drive_backup(device, filename, !!format, format,
1091 full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
1092 true, mode, false, 0, false, NULL,
1093 false, 0, false, 0, &err);
1094 hmp_handle_error(mon, &err);
1095}
1096
1097void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
1098{
1099 const char *device = qdict_get_str(qdict, "device");
1100 const char *filename = qdict_get_try_str(qdict, "snapshot-file");
1101 const char *format = qdict_get_try_str(qdict, "format");
1102 bool reuse = qdict_get_try_bool(qdict, "reuse", false);
1103 enum NewImageMode mode;
1104 Error *err = NULL;
1105
1106 if (!filename) {
1107
1108
1109 error_setg(&err, QERR_MISSING_PARAMETER, "snapshot-file");
1110 hmp_handle_error(mon, &err);
1111 return;
1112 }
1113
1114 mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
1115 qmp_blockdev_snapshot_sync(true, device, false, NULL,
1116 filename, false, NULL,
1117 !!format, format,
1118 true, mode, &err);
1119 hmp_handle_error(mon, &err);
1120}
1121
1122void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
1123{
1124 const char *device = qdict_get_str(qdict, "device");
1125 const char *name = qdict_get_str(qdict, "name");
1126 Error *err = NULL;
1127
1128 qmp_blockdev_snapshot_internal_sync(device, name, &err);
1129 hmp_handle_error(mon, &err);
1130}
1131
1132void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
1133{
1134 const char *device = qdict_get_str(qdict, "device");
1135 const char *name = qdict_get_str(qdict, "name");
1136 const char *id = qdict_get_try_str(qdict, "id");
1137 Error *err = NULL;
1138
1139 qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id,
1140 true, name, &err);
1141 hmp_handle_error(mon, &err);
1142}
1143
1144void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
1145{
1146 qmp_migrate_cancel(NULL);
1147}
1148
1149void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
1150{
1151 Error *err = NULL;
1152 const char *uri = qdict_get_str(qdict, "uri");
1153
1154 qmp_migrate_incoming(uri, &err);
1155
1156 hmp_handle_error(mon, &err);
1157}
1158
1159void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict)
1160{
1161 double value = qdict_get_double(qdict, "value");
1162 qmp_migrate_set_downtime(value, NULL);
1163}
1164
1165void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict)
1166{
1167 int64_t value = qdict_get_int(qdict, "value");
1168 Error *err = NULL;
1169
1170 qmp_migrate_set_cache_size(value, &err);
1171 if (err) {
1172 monitor_printf(mon, "%s\n", error_get_pretty(err));
1173 error_free(err);
1174 return;
1175 }
1176}
1177
1178void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
1179{
1180 int64_t value = qdict_get_int(qdict, "value");
1181 qmp_migrate_set_speed(value, NULL);
1182}
1183
1184void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
1185{
1186 const char *cap = qdict_get_str(qdict, "capability");
1187 bool state = qdict_get_bool(qdict, "state");
1188 Error *err = NULL;
1189 MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
1190 int i;
1191
1192 for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
1193 if (strcmp(cap, MigrationCapability_lookup[i]) == 0) {
1194 caps->value = g_malloc0(sizeof(*caps->value));
1195 caps->value->capability = i;
1196 caps->value->state = state;
1197 caps->next = NULL;
1198 qmp_migrate_set_capabilities(caps, &err);
1199 break;
1200 }
1201 }
1202
1203 if (i == MIGRATION_CAPABILITY_MAX) {
1204 error_setg(&err, QERR_INVALID_PARAMETER, cap);
1205 }
1206
1207 qapi_free_MigrationCapabilityStatusList(caps);
1208
1209 if (err) {
1210 monitor_printf(mon, "migrate_set_capability: %s\n",
1211 error_get_pretty(err));
1212 error_free(err);
1213 }
1214}
1215
1216void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
1217{
1218 const char *param = qdict_get_str(qdict, "parameter");
1219 int value = qdict_get_int(qdict, "value");
1220 Error *err = NULL;
1221 bool has_compress_level = false;
1222 bool has_compress_threads = false;
1223 bool has_decompress_threads = false;
1224 int i;
1225
1226 for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) {
1227 if (strcmp(param, MigrationParameter_lookup[i]) == 0) {
1228 switch (i) {
1229 case MIGRATION_PARAMETER_COMPRESS_LEVEL:
1230 has_compress_level = true;
1231 break;
1232 case MIGRATION_PARAMETER_COMPRESS_THREADS:
1233 has_compress_threads = true;
1234 break;
1235 case MIGRATION_PARAMETER_DECOMPRESS_THREADS:
1236 has_decompress_threads = true;
1237 break;
1238 }
1239 qmp_migrate_set_parameters(has_compress_level, value,
1240 has_compress_threads, value,
1241 has_decompress_threads, value,
1242 &err);
1243 break;
1244 }
1245 }
1246
1247 if (i == MIGRATION_PARAMETER_MAX) {
1248 error_setg(&err, QERR_INVALID_PARAMETER, param);
1249 }
1250
1251 if (err) {
1252 monitor_printf(mon, "migrate_set_parameter: %s\n",
1253 error_get_pretty(err));
1254 error_free(err);
1255 }
1256}
1257
1258void hmp_client_migrate_info(Monitor *mon, const QDict *qdict)
1259{
1260 Error *err = NULL;
1261 const char *protocol = qdict_get_str(qdict, "protocol");
1262 const char *hostname = qdict_get_str(qdict, "hostname");
1263 bool has_port = qdict_haskey(qdict, "port");
1264 int port = qdict_get_try_int(qdict, "port", -1);
1265 bool has_tls_port = qdict_haskey(qdict, "tls-port");
1266 int tls_port = qdict_get_try_int(qdict, "tls-port", -1);
1267 const char *cert_subject = qdict_get_try_str(qdict, "cert-subject");
1268
1269 qmp_client_migrate_info(protocol, hostname,
1270 has_port, port, has_tls_port, tls_port,
1271 !!cert_subject, cert_subject, &err);
1272 hmp_handle_error(mon, &err);
1273}
1274
1275void hmp_set_password(Monitor *mon, const QDict *qdict)
1276{
1277 const char *protocol = qdict_get_str(qdict, "protocol");
1278 const char *password = qdict_get_str(qdict, "password");
1279 const char *connected = qdict_get_try_str(qdict, "connected");
1280 Error *err = NULL;
1281
1282 qmp_set_password(protocol, password, !!connected, connected, &err);
1283 hmp_handle_error(mon, &err);
1284}
1285
1286void hmp_expire_password(Monitor *mon, const QDict *qdict)
1287{
1288 const char *protocol = qdict_get_str(qdict, "protocol");
1289 const char *whenstr = qdict_get_str(qdict, "time");
1290 Error *err = NULL;
1291
1292 qmp_expire_password(protocol, whenstr, &err);
1293 hmp_handle_error(mon, &err);
1294}
1295
1296void hmp_eject(Monitor *mon, const QDict *qdict)
1297{
1298 bool force = qdict_get_try_bool(qdict, "force", false);
1299 const char *device = qdict_get_str(qdict, "device");
1300 Error *err = NULL;
1301
1302 qmp_eject(device, true, force, &err);
1303 hmp_handle_error(mon, &err);
1304}
1305
1306static void hmp_change_read_arg(void *opaque, const char *password,
1307 void *readline_opaque)
1308{
1309 qmp_change_vnc_password(password, NULL);
1310 monitor_read_command(opaque, 1);
1311}
1312
1313void hmp_change(Monitor *mon, const QDict *qdict)
1314{
1315 const char *device = qdict_get_str(qdict, "device");
1316 const char *target = qdict_get_str(qdict, "target");
1317 const char *arg = qdict_get_try_str(qdict, "arg");
1318 Error *err = NULL;
1319
1320 if (strcmp(device, "vnc") == 0 &&
1321 (strcmp(target, "passwd") == 0 ||
1322 strcmp(target, "password") == 0)) {
1323 if (!arg) {
1324 monitor_read_password(mon, hmp_change_read_arg, NULL);
1325 return;
1326 }
1327 }
1328
1329 qmp_change(device, target, !!arg, arg, &err);
1330 if (err &&
1331 error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
1332 error_free(err);
1333 monitor_read_block_device_key(mon, device, NULL, NULL);
1334 return;
1335 }
1336 hmp_handle_error(mon, &err);
1337}
1338
1339void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
1340{
1341 Error *err = NULL;
1342
1343 qmp_block_set_io_throttle(qdict_get_str(qdict, "device"),
1344 qdict_get_int(qdict, "bps"),
1345 qdict_get_int(qdict, "bps_rd"),
1346 qdict_get_int(qdict, "bps_wr"),
1347 qdict_get_int(qdict, "iops"),
1348 qdict_get_int(qdict, "iops_rd"),
1349 qdict_get_int(qdict, "iops_wr"),
1350 false,
1351 0,
1352 false,
1353 0,
1354 false,
1355 0,
1356 false,
1357 0,
1358 false,
1359 0,
1360 false,
1361 0,
1362 false,
1363 0,
1364 false,
1365 NULL, &err);
1366 hmp_handle_error(mon, &err);
1367}
1368
1369void hmp_block_stream(Monitor *mon, const QDict *qdict)
1370{
1371 Error *error = NULL;
1372 const char *device = qdict_get_str(qdict, "device");
1373 const char *base = qdict_get_try_str(qdict, "base");
1374 int64_t speed = qdict_get_try_int(qdict, "speed", 0);
1375
1376 qmp_block_stream(device, base != NULL, base, false, NULL,
1377 qdict_haskey(qdict, "speed"), speed,
1378 true, BLOCKDEV_ON_ERROR_REPORT, &error);
1379
1380 hmp_handle_error(mon, &error);
1381}
1382
1383void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
1384{
1385 Error *error = NULL;
1386 const char *device = qdict_get_str(qdict, "device");
1387 int64_t value = qdict_get_int(qdict, "speed");
1388
1389 qmp_block_job_set_speed(device, value, &error);
1390
1391 hmp_handle_error(mon, &error);
1392}
1393
1394void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
1395{
1396 Error *error = NULL;
1397 const char *device = qdict_get_str(qdict, "device");
1398 bool force = qdict_get_try_bool(qdict, "force", false);
1399
1400 qmp_block_job_cancel(device, true, force, &error);
1401
1402 hmp_handle_error(mon, &error);
1403}
1404
1405void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
1406{
1407 Error *error = NULL;
1408 const char *device = qdict_get_str(qdict, "device");
1409
1410 qmp_block_job_pause(device, &error);
1411
1412 hmp_handle_error(mon, &error);
1413}
1414
1415void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
1416{
1417 Error *error = NULL;
1418 const char *device = qdict_get_str(qdict, "device");
1419
1420 qmp_block_job_resume(device, &error);
1421
1422 hmp_handle_error(mon, &error);
1423}
1424
1425void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
1426{
1427 Error *error = NULL;
1428 const char *device = qdict_get_str(qdict, "device");
1429
1430 qmp_block_job_complete(device, &error);
1431
1432 hmp_handle_error(mon, &error);
1433}
1434
1435typedef struct HMPMigrationStatus
1436{
1437 QEMUTimer *timer;
1438 Monitor *mon;
1439 bool is_block_migration;
1440} HMPMigrationStatus;
1441
1442static void hmp_migrate_status_cb(void *opaque)
1443{
1444 HMPMigrationStatus *status = opaque;
1445 MigrationInfo *info;
1446
1447 info = qmp_query_migrate(NULL);
1448 if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE ||
1449 info->status == MIGRATION_STATUS_SETUP) {
1450 if (info->has_disk) {
1451 int progress;
1452
1453 if (info->disk->remaining) {
1454 progress = info->disk->transferred * 100 / info->disk->total;
1455 } else {
1456 progress = 100;
1457 }
1458
1459 monitor_printf(status->mon, "Completed %d %%\r", progress);
1460 monitor_flush(status->mon);
1461 }
1462
1463 timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
1464 } else {
1465 if (status->is_block_migration) {
1466 monitor_printf(status->mon, "\n");
1467 }
1468 monitor_resume(status->mon);
1469 timer_del(status->timer);
1470 g_free(status);
1471 }
1472
1473 qapi_free_MigrationInfo(info);
1474}
1475
1476void hmp_migrate(Monitor *mon, const QDict *qdict)
1477{
1478 bool detach = qdict_get_try_bool(qdict, "detach", false);
1479 bool blk = qdict_get_try_bool(qdict, "blk", false);
1480 bool inc = qdict_get_try_bool(qdict, "inc", false);
1481 const char *uri = qdict_get_str(qdict, "uri");
1482 Error *err = NULL;
1483
1484 qmp_migrate(uri, !!blk, blk, !!inc, inc, false, false, &err);
1485 if (err) {
1486 monitor_printf(mon, "migrate: %s\n", error_get_pretty(err));
1487 error_free(err);
1488 return;
1489 }
1490
1491 if (!detach) {
1492 HMPMigrationStatus *status;
1493
1494 if (monitor_suspend(mon) < 0) {
1495 monitor_printf(mon, "terminal does not allow synchronous "
1496 "migration, continuing detached\n");
1497 return;
1498 }
1499
1500 status = g_malloc0(sizeof(*status));
1501 status->mon = mon;
1502 status->is_block_migration = blk || inc;
1503 status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb,
1504 status);
1505 timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
1506 }
1507}
1508
1509void hmp_device_add(Monitor *mon, const QDict *qdict)
1510{
1511 Error *err = NULL;
1512
1513 qmp_device_add((QDict *)qdict, NULL, &err);
1514 hmp_handle_error(mon, &err);
1515}
1516
1517void hmp_device_del(Monitor *mon, const QDict *qdict)
1518{
1519 const char *id = qdict_get_str(qdict, "id");
1520 Error *err = NULL;
1521
1522 qmp_device_del(id, &err);
1523 hmp_handle_error(mon, &err);
1524}
1525
1526void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
1527{
1528 Error *err = NULL;
1529 bool paging = qdict_get_try_bool(qdict, "paging", false);
1530 bool zlib = qdict_get_try_bool(qdict, "zlib", false);
1531 bool lzo = qdict_get_try_bool(qdict, "lzo", false);
1532 bool snappy = qdict_get_try_bool(qdict, "snappy", false);
1533 const char *file = qdict_get_str(qdict, "filename");
1534 bool has_begin = qdict_haskey(qdict, "begin");
1535 bool has_length = qdict_haskey(qdict, "length");
1536 int64_t begin = 0;
1537 int64_t length = 0;
1538 enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
1539 char *prot;
1540
1541 if (zlib + lzo + snappy > 1) {
1542 error_setg(&err, "only one of '-z|-l|-s' can be set");
1543 hmp_handle_error(mon, &err);
1544 return;
1545 }
1546
1547 if (zlib) {
1548 dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
1549 }
1550
1551 if (lzo) {
1552 dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
1553 }
1554
1555 if (snappy) {
1556 dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
1557 }
1558
1559 if (has_begin) {
1560 begin = qdict_get_int(qdict, "begin");
1561 }
1562 if (has_length) {
1563 length = qdict_get_int(qdict, "length");
1564 }
1565
1566 prot = g_strconcat("file:", file, NULL);
1567
1568 qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
1569 true, dump_format, &err);
1570 hmp_handle_error(mon, &err);
1571 g_free(prot);
1572}
1573
1574void hmp_netdev_add(Monitor *mon, const QDict *qdict)
1575{
1576 Error *err = NULL;
1577 QemuOpts *opts;
1578
1579 opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
1580 if (err) {
1581 goto out;
1582 }
1583
1584 netdev_add(opts, &err);
1585 if (err) {
1586 qemu_opts_del(opts);
1587 }
1588
1589out:
1590 hmp_handle_error(mon, &err);
1591}
1592
1593void hmp_netdev_del(Monitor *mon, const QDict *qdict)
1594{
1595 const char *id = qdict_get_str(qdict, "id");
1596 Error *err = NULL;
1597
1598 qmp_netdev_del(id, &err);
1599 hmp_handle_error(mon, &err);
1600}
1601
1602void hmp_object_add(Monitor *mon, const QDict *qdict)
1603{
1604 Error *err = NULL;
1605 Error *err_end = NULL;
1606 QemuOpts *opts;
1607 char *type = NULL;
1608 char *id = NULL;
1609 void *dummy = NULL;
1610 OptsVisitor *ov;
1611 QDict *pdict;
1612
1613 opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err);
1614 if (err) {
1615 goto out;
1616 }
1617
1618 ov = opts_visitor_new(opts);
1619 pdict = qdict_clone_shallow(qdict);
1620
1621 visit_start_struct(opts_get_visitor(ov), &dummy, NULL, NULL, 0, &err);
1622 if (err) {
1623 goto out_clean;
1624 }
1625
1626 qdict_del(pdict, "qom-type");
1627 visit_type_str(opts_get_visitor(ov), &type, "qom-type", &err);
1628 if (err) {
1629 goto out_end;
1630 }
1631
1632 qdict_del(pdict, "id");
1633 visit_type_str(opts_get_visitor(ov), &id, "id", &err);
1634 if (err) {
1635 goto out_end;
1636 }
1637
1638 object_add(type, id, pdict, opts_get_visitor(ov), &err);
1639
1640out_end:
1641 visit_end_struct(opts_get_visitor(ov), &err_end);
1642 if (!err && err_end) {
1643 qmp_object_del(id, NULL);
1644 }
1645 error_propagate(&err, err_end);
1646out_clean:
1647 opts_visitor_cleanup(ov);
1648
1649 QDECREF(pdict);
1650 qemu_opts_del(opts);
1651 g_free(id);
1652 g_free(type);
1653 g_free(dummy);
1654
1655out:
1656 hmp_handle_error(mon, &err);
1657}
1658
1659void hmp_getfd(Monitor *mon, const QDict *qdict)
1660{
1661 const char *fdname = qdict_get_str(qdict, "fdname");
1662 Error *err = NULL;
1663
1664 qmp_getfd(fdname, &err);
1665 hmp_handle_error(mon, &err);
1666}
1667
1668void hmp_closefd(Monitor *mon, const QDict *qdict)
1669{
1670 const char *fdname = qdict_get_str(qdict, "fdname");
1671 Error *err = NULL;
1672
1673 qmp_closefd(fdname, &err);
1674 hmp_handle_error(mon, &err);
1675}
1676
1677void hmp_sendkey(Monitor *mon, const QDict *qdict)
1678{
1679 const char *keys = qdict_get_str(qdict, "keys");
1680 KeyValueList *keylist, *head = NULL, *tmp = NULL;
1681 int has_hold_time = qdict_haskey(qdict, "hold-time");
1682 int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
1683 Error *err = NULL;
1684 char keyname_buf[16];
1685 char *separator;
1686 int keyname_len;
1687
1688 while (1) {
1689 separator = strchr(keys, '-');
1690 keyname_len = separator ? separator - keys : strlen(keys);
1691 pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
1692
1693
1694 if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
1695 pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
1696 keyname_len = 4;
1697 }
1698 keyname_buf[keyname_len] = 0;
1699
1700 keylist = g_malloc0(sizeof(*keylist));
1701 keylist->value = g_malloc0(sizeof(*keylist->value));
1702
1703 if (!head) {
1704 head = keylist;
1705 }
1706 if (tmp) {
1707 tmp->next = keylist;
1708 }
1709 tmp = keylist;
1710
1711 if (strstart(keyname_buf, "0x", NULL)) {
1712 char *endp;
1713 int value = strtoul(keyname_buf, &endp, 0);
1714 if (*endp != '\0') {
1715 goto err_out;
1716 }
1717 keylist->value->kind = KEY_VALUE_KIND_NUMBER;
1718 keylist->value->number = value;
1719 } else {
1720 int idx = index_from_key(keyname_buf);
1721 if (idx == Q_KEY_CODE_MAX) {
1722 goto err_out;
1723 }
1724 keylist->value->kind = KEY_VALUE_KIND_QCODE;
1725 keylist->value->qcode = idx;
1726 }
1727
1728 if (!separator) {
1729 break;
1730 }
1731 keys = separator + 1;
1732 }
1733
1734 qmp_send_key(head, has_hold_time, hold_time, &err);
1735 hmp_handle_error(mon, &err);
1736
1737out:
1738 qapi_free_KeyValueList(head);
1739 return;
1740
1741err_out:
1742 monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
1743 goto out;
1744}
1745
1746void hmp_screendump(Monitor *mon, const QDict *qdict)
1747{
1748 const char *filename = qdict_get_str(qdict, "filename");
1749 Error *err = NULL;
1750
1751 qmp_screendump(filename, &err);
1752 hmp_handle_error(mon, &err);
1753}
1754
1755void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
1756{
1757 const char *uri = qdict_get_str(qdict, "uri");
1758 bool writable = qdict_get_try_bool(qdict, "writable", false);
1759 bool all = qdict_get_try_bool(qdict, "all", false);
1760 Error *local_err = NULL;
1761 BlockInfoList *block_list, *info;
1762 SocketAddress *addr;
1763
1764 if (writable && !all) {
1765 error_setg(&local_err, "-w only valid together with -a");
1766 goto exit;
1767 }
1768
1769
1770 addr = socket_parse(uri, &local_err);
1771 if (local_err != NULL) {
1772 goto exit;
1773 }
1774
1775 qmp_nbd_server_start(addr, &local_err);
1776 qapi_free_SocketAddress(addr);
1777 if (local_err != NULL) {
1778 goto exit;
1779 }
1780
1781 if (!all) {
1782 return;
1783 }
1784
1785
1786
1787
1788 block_list = qmp_query_block(NULL);
1789
1790 for (info = block_list; info; info = info->next) {
1791 if (!info->value->has_inserted) {
1792 continue;
1793 }
1794
1795 qmp_nbd_server_add(info->value->device, true, writable, &local_err);
1796
1797 if (local_err != NULL) {
1798 qmp_nbd_server_stop(NULL);
1799 break;
1800 }
1801 }
1802
1803 qapi_free_BlockInfoList(block_list);
1804
1805exit:
1806 hmp_handle_error(mon, &local_err);
1807}
1808
1809void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
1810{
1811 const char *device = qdict_get_str(qdict, "device");
1812 bool writable = qdict_get_try_bool(qdict, "writable", false);
1813 Error *local_err = NULL;
1814
1815 qmp_nbd_server_add(device, true, writable, &local_err);
1816
1817 if (local_err != NULL) {
1818 hmp_handle_error(mon, &local_err);
1819 }
1820}
1821
1822void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
1823{
1824 Error *err = NULL;
1825
1826 qmp_nbd_server_stop(&err);
1827 hmp_handle_error(mon, &err);
1828}
1829
1830void hmp_cpu_add(Monitor *mon, const QDict *qdict)
1831{
1832 int cpuid;
1833 Error *err = NULL;
1834
1835 cpuid = qdict_get_int(qdict, "id");
1836 qmp_cpu_add(cpuid, &err);
1837 hmp_handle_error(mon, &err);
1838}
1839
1840void hmp_chardev_add(Monitor *mon, const QDict *qdict)
1841{
1842 const char *args = qdict_get_str(qdict, "args");
1843 Error *err = NULL;
1844 QemuOpts *opts;
1845
1846 opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, true);
1847 if (opts == NULL) {
1848 error_setg(&err, "Parsing chardev args failed");
1849 } else {
1850 qemu_chr_new_from_opts(opts, NULL, &err);
1851 }
1852 hmp_handle_error(mon, &err);
1853}
1854
1855void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
1856{
1857 Error *local_err = NULL;
1858
1859 qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
1860 hmp_handle_error(mon, &local_err);
1861}
1862
1863void hmp_qemu_io(Monitor *mon, const QDict *qdict)
1864{
1865 BlockBackend *blk;
1866 const char* device = qdict_get_str(qdict, "device");
1867 const char* command = qdict_get_str(qdict, "command");
1868 Error *err = NULL;
1869
1870 blk = blk_by_name(device);
1871 if (blk) {
1872 qemuio_command(blk, command);
1873 } else {
1874 error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
1875 "Device '%s' not found", device);
1876 }
1877
1878 hmp_handle_error(mon, &err);
1879}
1880
1881void hmp_object_del(Monitor *mon, const QDict *qdict)
1882{
1883 const char *id = qdict_get_str(qdict, "id");
1884 Error *err = NULL;
1885
1886 qmp_object_del(id, &err);
1887 hmp_handle_error(mon, &err);
1888}
1889
1890void hmp_info_memdev(Monitor *mon, const QDict *qdict)
1891{
1892 Error *err = NULL;
1893 MemdevList *memdev_list = qmp_query_memdev(&err);
1894 MemdevList *m = memdev_list;
1895 StringOutputVisitor *ov;
1896 char *str;
1897 int i = 0;
1898
1899
1900 while (m) {
1901 ov = string_output_visitor_new(false);
1902 visit_type_uint16List(string_output_get_visitor(ov),
1903 &m->value->host_nodes, NULL, NULL);
1904 monitor_printf(mon, "memory backend: %d\n", i);
1905 monitor_printf(mon, " size: %" PRId64 "\n", m->value->size);
1906 monitor_printf(mon, " merge: %s\n",
1907 m->value->merge ? "true" : "false");
1908 monitor_printf(mon, " dump: %s\n",
1909 m->value->dump ? "true" : "false");
1910 monitor_printf(mon, " prealloc: %s\n",
1911 m->value->prealloc ? "true" : "false");
1912 monitor_printf(mon, " policy: %s\n",
1913 HostMemPolicy_lookup[m->value->policy]);
1914 str = string_output_get_string(ov);
1915 monitor_printf(mon, " host nodes: %s\n", str);
1916
1917 g_free(str);
1918 string_output_visitor_cleanup(ov);
1919 m = m->next;
1920 i++;
1921 }
1922
1923 monitor_printf(mon, "\n");
1924
1925 qapi_free_MemdevList(memdev_list);
1926}
1927
1928void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
1929{
1930 Error *err = NULL;
1931 MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
1932 MemoryDeviceInfoList *info;
1933 MemoryDeviceInfo *value;
1934 PCDIMMDeviceInfo *di;
1935
1936 for (info = info_list; info; info = info->next) {
1937 value = info->value;
1938
1939 if (value) {
1940 switch (value->kind) {
1941 case MEMORY_DEVICE_INFO_KIND_DIMM:
1942 di = value->dimm;
1943
1944 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
1945 MemoryDeviceInfoKind_lookup[value->kind],
1946 di->id ? di->id : "");
1947 monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr);
1948 monitor_printf(mon, " slot: %" PRId64 "\n", di->slot);
1949 monitor_printf(mon, " node: %" PRId64 "\n", di->node);
1950 monitor_printf(mon, " size: %" PRIu64 "\n", di->size);
1951 monitor_printf(mon, " memdev: %s\n", di->memdev);
1952 monitor_printf(mon, " hotplugged: %s\n",
1953 di->hotplugged ? "true" : "false");
1954 monitor_printf(mon, " hotpluggable: %s\n",
1955 di->hotpluggable ? "true" : "false");
1956 break;
1957 default:
1958 break;
1959 }
1960 }
1961 }
1962
1963 qapi_free_MemoryDeviceInfoList(info_list);
1964}
1965
1966void hmp_qom_list(Monitor *mon, const QDict *qdict)
1967{
1968 const char *path = qdict_get_try_str(qdict, "path");
1969 ObjectPropertyInfoList *list;
1970 Error *err = NULL;
1971
1972 if (path == NULL) {
1973 monitor_printf(mon, "/\n");
1974 return;
1975 }
1976
1977 list = qmp_qom_list(path, &err);
1978 if (err == NULL) {
1979 ObjectPropertyInfoList *start = list;
1980 while (list != NULL) {
1981 ObjectPropertyInfo *value = list->value;
1982
1983 monitor_printf(mon, "%s (%s)\n",
1984 value->name, value->type);
1985 list = list->next;
1986 }
1987 qapi_free_ObjectPropertyInfoList(start);
1988 }
1989 hmp_handle_error(mon, &err);
1990}
1991
1992void hmp_qom_set(Monitor *mon, const QDict *qdict)
1993{
1994 const char *path = qdict_get_str(qdict, "path");
1995 const char *property = qdict_get_str(qdict, "property");
1996 const char *value = qdict_get_str(qdict, "value");
1997 Error *err = NULL;
1998 bool ambiguous = false;
1999 Object *obj;
2000
2001 obj = object_resolve_path(path, &ambiguous);
2002 if (obj == NULL) {
2003 error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
2004 "Device '%s' not found", path);
2005 } else {
2006 if (ambiguous) {
2007 monitor_printf(mon, "Warning: Path '%s' is ambiguous\n", path);
2008 }
2009 object_property_parse(obj, value, property, &err);
2010 }
2011 hmp_handle_error(mon, &err);
2012}
2013
2014void hmp_rocker(Monitor *mon, const QDict *qdict)
2015{
2016 const char *name = qdict_get_str(qdict, "name");
2017 RockerSwitch *rocker;
2018 Error *errp = NULL;
2019
2020 rocker = qmp_query_rocker(name, &errp);
2021 if (errp != NULL) {
2022 hmp_handle_error(mon, &errp);
2023 return;
2024 }
2025
2026 monitor_printf(mon, "name: %s\n", rocker->name);
2027 monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id);
2028 monitor_printf(mon, "ports: %d\n", rocker->ports);
2029
2030 qapi_free_RockerSwitch(rocker);
2031}
2032
2033void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
2034{
2035 RockerPortList *list, *port;
2036 const char *name = qdict_get_str(qdict, "name");
2037 Error *errp = NULL;
2038
2039 list = qmp_query_rocker_ports(name, &errp);
2040 if (errp != NULL) {
2041 hmp_handle_error(mon, &errp);
2042 return;
2043 }
2044
2045 monitor_printf(mon, " ena/ speed/ auto\n");
2046 monitor_printf(mon, " port link duplex neg?\n");
2047
2048 for (port = list; port; port = port->next) {
2049 monitor_printf(mon, "%10s %-4s %-3s %2s %-3s\n",
2050 port->value->name,
2051 port->value->enabled ? port->value->link_up ?
2052 "up" : "down" : "!ena",
2053 port->value->speed == 10000 ? "10G" : "??",
2054 port->value->duplex ? "FD" : "HD",
2055 port->value->autoneg ? "Yes" : "No");
2056 }
2057
2058 qapi_free_RockerPortList(list);
2059}
2060
2061void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
2062{
2063 RockerOfDpaFlowList *list, *info;
2064 const char *name = qdict_get_str(qdict, "name");
2065 uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1);
2066 Error *errp = NULL;
2067
2068 list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &errp);
2069 if (errp != NULL) {
2070 hmp_handle_error(mon, &errp);
2071 return;
2072 }
2073
2074 monitor_printf(mon, "prio tbl hits key(mask) --> actions\n");
2075
2076 for (info = list; info; info = info->next) {
2077 RockerOfDpaFlow *flow = info->value;
2078 RockerOfDpaFlowKey *key = flow->key;
2079 RockerOfDpaFlowMask *mask = flow->mask;
2080 RockerOfDpaFlowAction *action = flow->action;
2081
2082 if (flow->hits) {
2083 monitor_printf(mon, "%-4d %-3d %-4" PRIu64,
2084 key->priority, key->tbl_id, flow->hits);
2085 } else {
2086 monitor_printf(mon, "%-4d %-3d ",
2087 key->priority, key->tbl_id);
2088 }
2089
2090 if (key->has_in_pport) {
2091 monitor_printf(mon, " pport %d", key->in_pport);
2092 if (mask->has_in_pport) {
2093 monitor_printf(mon, "(0x%x)", mask->in_pport);
2094 }
2095 }
2096
2097 if (key->has_vlan_id) {
2098 monitor_printf(mon, " vlan %d",
2099 key->vlan_id & VLAN_VID_MASK);
2100 if (mask->has_vlan_id) {
2101 monitor_printf(mon, "(0x%x)", mask->vlan_id);
2102 }
2103 }
2104
2105 if (key->has_tunnel_id) {
2106 monitor_printf(mon, " tunnel %d", key->tunnel_id);
2107 if (mask->has_tunnel_id) {
2108 monitor_printf(mon, "(0x%x)", mask->tunnel_id);
2109 }
2110 }
2111
2112 if (key->has_eth_type) {
2113 switch (key->eth_type) {
2114 case 0x0806:
2115 monitor_printf(mon, " ARP");
2116 break;
2117 case 0x0800:
2118 monitor_printf(mon, " IP");
2119 break;
2120 case 0x86dd:
2121 monitor_printf(mon, " IPv6");
2122 break;
2123 case 0x8809:
2124 monitor_printf(mon, " LACP");
2125 break;
2126 case 0x88cc:
2127 monitor_printf(mon, " LLDP");
2128 break;
2129 default:
2130 monitor_printf(mon, " eth type 0x%04x", key->eth_type);
2131 break;
2132 }
2133 }
2134
2135 if (key->has_eth_src) {
2136 if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) &&
2137 (mask->has_eth_src) &&
2138 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
2139 monitor_printf(mon, " src <any mcast/bcast>");
2140 } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) &&
2141 (mask->has_eth_src) &&
2142 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
2143 monitor_printf(mon, " src <any ucast>");
2144 } else {
2145 monitor_printf(mon, " src %s", key->eth_src);
2146 if (mask->has_eth_src) {
2147 monitor_printf(mon, "(%s)", mask->eth_src);
2148 }
2149 }
2150 }
2151
2152 if (key->has_eth_dst) {
2153 if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) &&
2154 (mask->has_eth_dst) &&
2155 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
2156 monitor_printf(mon, " dst <any mcast/bcast>");
2157 } else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) &&
2158 (mask->has_eth_dst) &&
2159 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
2160 monitor_printf(mon, " dst <any ucast>");
2161 } else {
2162 monitor_printf(mon, " dst %s", key->eth_dst);
2163 if (mask->has_eth_dst) {
2164 monitor_printf(mon, "(%s)", mask->eth_dst);
2165 }
2166 }
2167 }
2168
2169 if (key->has_ip_proto) {
2170 monitor_printf(mon, " proto %d", key->ip_proto);
2171 if (mask->has_ip_proto) {
2172 monitor_printf(mon, "(0x%x)", mask->ip_proto);
2173 }
2174 }
2175
2176 if (key->has_ip_tos) {
2177 monitor_printf(mon, " TOS %d", key->ip_tos);
2178 if (mask->has_ip_tos) {
2179 monitor_printf(mon, "(0x%x)", mask->ip_tos);
2180 }
2181 }
2182
2183 if (key->has_ip_dst) {
2184 monitor_printf(mon, " dst %s", key->ip_dst);
2185 }
2186
2187 if (action->has_goto_tbl || action->has_group_id ||
2188 action->has_new_vlan_id) {
2189 monitor_printf(mon, " -->");
2190 }
2191
2192 if (action->has_new_vlan_id) {
2193 monitor_printf(mon, " apply new vlan %d",
2194 ntohs(action->new_vlan_id));
2195 }
2196
2197 if (action->has_group_id) {
2198 monitor_printf(mon, " write group 0x%08x", action->group_id);
2199 }
2200
2201 if (action->has_goto_tbl) {
2202 monitor_printf(mon, " goto tbl %d", action->goto_tbl);
2203 }
2204
2205 monitor_printf(mon, "\n");
2206 }
2207
2208 qapi_free_RockerOfDpaFlowList(list);
2209}
2210
2211void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
2212{
2213 RockerOfDpaGroupList *list, *g;
2214 const char *name = qdict_get_str(qdict, "name");
2215 uint8_t type = qdict_get_try_int(qdict, "type", 9);
2216 Error *errp = NULL;
2217 bool set = false;
2218
2219 list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &errp);
2220 if (errp != NULL) {
2221 hmp_handle_error(mon, &errp);
2222 return;
2223 }
2224
2225 monitor_printf(mon, "id (decode) --> buckets\n");
2226
2227 for (g = list; g; g = g->next) {
2228 RockerOfDpaGroup *group = g->value;
2229
2230 monitor_printf(mon, "0x%08x", group->id);
2231
2232 monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" :
2233 group->type == 1 ? "L2 rewrite" :
2234 group->type == 2 ? "L3 unicast" :
2235 group->type == 3 ? "L2 multicast" :
2236 group->type == 4 ? "L2 flood" :
2237 group->type == 5 ? "L3 interface" :
2238 group->type == 6 ? "L3 multicast" :
2239 group->type == 7 ? "L3 ECMP" :
2240 group->type == 8 ? "L2 overlay" :
2241 "unknown");
2242
2243 if (group->has_vlan_id) {
2244 monitor_printf(mon, " vlan %d", group->vlan_id);
2245 }
2246
2247 if (group->has_pport) {
2248 monitor_printf(mon, " pport %d", group->pport);
2249 }
2250
2251 if (group->has_index) {
2252 monitor_printf(mon, " index %d", group->index);
2253 }
2254
2255 monitor_printf(mon, ") -->");
2256
2257 if (group->has_set_vlan_id && group->set_vlan_id) {
2258 set = true;
2259 monitor_printf(mon, " set vlan %d",
2260 group->set_vlan_id & VLAN_VID_MASK);
2261 }
2262
2263 if (group->has_set_eth_src) {
2264 if (!set) {
2265 set = true;
2266 monitor_printf(mon, " set");
2267 }
2268 monitor_printf(mon, " src %s", group->set_eth_src);
2269 }
2270
2271 if (group->has_set_eth_dst) {
2272 if (!set) {
2273 set = true;
2274 monitor_printf(mon, " set");
2275 }
2276 monitor_printf(mon, " dst %s", group->set_eth_dst);
2277 }
2278
2279 set = false;
2280
2281 if (group->has_ttl_check && group->ttl_check) {
2282 monitor_printf(mon, " check TTL");
2283 }
2284
2285 if (group->has_group_id && group->group_id) {
2286 monitor_printf(mon, " group id 0x%08x", group->group_id);
2287 }
2288
2289 if (group->has_pop_vlan && group->pop_vlan) {
2290 monitor_printf(mon, " pop vlan");
2291 }
2292
2293 if (group->has_out_pport) {
2294 monitor_printf(mon, " out pport %d", group->out_pport);
2295 }
2296
2297 if (group->has_group_ids) {
2298 struct uint32List *id;
2299
2300 monitor_printf(mon, " groups [");
2301 for (id = group->group_ids; id; id = id->next) {
2302 monitor_printf(mon, "0x%08x", id->value);
2303 if (id->next) {
2304 monitor_printf(mon, ",");
2305 }
2306 }
2307 monitor_printf(mon, "]");
2308 }
2309
2310 monitor_printf(mon, "\n");
2311 }
2312
2313 qapi_free_RockerOfDpaGroupList(list);
2314}
2315