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