root / hmp.c @ 73f5e313
History | View | Annotate | Download (15.9 kB)
1 |
/*
|
---|---|
2 |
* Human Monitor Interface
|
3 |
*
|
4 |
* Copyright IBM, Corp. 2011
|
5 |
*
|
6 |
* Authors:
|
7 |
* Anthony Liguori <aliguori@us.ibm.com>
|
8 |
*
|
9 |
* This work is licensed under the terms of the GNU GPL, version 2. See
|
10 |
* the COPYING file in the top-level directory.
|
11 |
*
|
12 |
*/
|
13 |
|
14 |
#include "hmp.h" |
15 |
#include "qmp-commands.h" |
16 |
|
17 |
void hmp_info_name(Monitor *mon)
|
18 |
{ |
19 |
NameInfo *info; |
20 |
|
21 |
info = qmp_query_name(NULL);
|
22 |
if (info->has_name) {
|
23 |
monitor_printf(mon, "%s\n", info->name);
|
24 |
} |
25 |
qapi_free_NameInfo(info); |
26 |
} |
27 |
|
28 |
void hmp_info_version(Monitor *mon)
|
29 |
{ |
30 |
VersionInfo *info; |
31 |
|
32 |
info = qmp_query_version(NULL);
|
33 |
|
34 |
monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n", |
35 |
info->qemu.major, info->qemu.minor, info->qemu.micro, |
36 |
info->package); |
37 |
|
38 |
qapi_free_VersionInfo(info); |
39 |
} |
40 |
|
41 |
void hmp_info_kvm(Monitor *mon)
|
42 |
{ |
43 |
KvmInfo *info; |
44 |
|
45 |
info = qmp_query_kvm(NULL);
|
46 |
monitor_printf(mon, "kvm support: ");
|
47 |
if (info->present) {
|
48 |
monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled"); |
49 |
} else {
|
50 |
monitor_printf(mon, "not compiled\n");
|
51 |
} |
52 |
|
53 |
qapi_free_KvmInfo(info); |
54 |
} |
55 |
|
56 |
void hmp_info_status(Monitor *mon)
|
57 |
{ |
58 |
StatusInfo *info; |
59 |
|
60 |
info = qmp_query_status(NULL);
|
61 |
|
62 |
monitor_printf(mon, "VM status: %s%s",
|
63 |
info->running ? "running" : "paused", |
64 |
info->singlestep ? " (single step mode)" : ""); |
65 |
|
66 |
if (!info->running && info->status != RUN_STATE_PAUSED) {
|
67 |
monitor_printf(mon, " (%s)", RunState_lookup[info->status]);
|
68 |
} |
69 |
|
70 |
monitor_printf(mon, "\n");
|
71 |
|
72 |
qapi_free_StatusInfo(info); |
73 |
} |
74 |
|
75 |
void hmp_info_uuid(Monitor *mon)
|
76 |
{ |
77 |
UuidInfo *info; |
78 |
|
79 |
info = qmp_query_uuid(NULL);
|
80 |
monitor_printf(mon, "%s\n", info->UUID);
|
81 |
qapi_free_UuidInfo(info); |
82 |
} |
83 |
|
84 |
void hmp_info_chardev(Monitor *mon)
|
85 |
{ |
86 |
ChardevInfoList *char_info, *info; |
87 |
|
88 |
char_info = qmp_query_chardev(NULL);
|
89 |
for (info = char_info; info; info = info->next) {
|
90 |
monitor_printf(mon, "%s: filename=%s\n", info->value->label,
|
91 |
info->value->filename); |
92 |
} |
93 |
|
94 |
qapi_free_ChardevInfoList(char_info); |
95 |
} |
96 |
|
97 |
void hmp_info_mice(Monitor *mon)
|
98 |
{ |
99 |
MouseInfoList *mice_list, *mouse; |
100 |
|
101 |
mice_list = qmp_query_mice(NULL);
|
102 |
if (!mice_list) {
|
103 |
monitor_printf(mon, "No mouse devices connected\n");
|
104 |
return;
|
105 |
} |
106 |
|
107 |
for (mouse = mice_list; mouse; mouse = mouse->next) {
|
108 |
monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n", |
109 |
mouse->value->current ? '*' : ' ', |
110 |
mouse->value->index, mouse->value->name, |
111 |
mouse->value->absolute ? " (absolute)" : ""); |
112 |
} |
113 |
|
114 |
qapi_free_MouseInfoList(mice_list); |
115 |
} |
116 |
|
117 |
void hmp_info_migrate(Monitor *mon)
|
118 |
{ |
119 |
MigrationInfo *info; |
120 |
|
121 |
info = qmp_query_migrate(NULL);
|
122 |
|
123 |
if (info->has_status) {
|
124 |
monitor_printf(mon, "Migration status: %s\n", info->status);
|
125 |
} |
126 |
|
127 |
if (info->has_ram) {
|
128 |
monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", |
129 |
info->ram->transferred >> 10);
|
130 |
monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", |
131 |
info->ram->remaining >> 10);
|
132 |
monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", |
133 |
info->ram->total >> 10);
|
134 |
} |
135 |
|
136 |
if (info->has_disk) {
|
137 |
monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n", |
138 |
info->disk->transferred >> 10);
|
139 |
monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n", |
140 |
info->disk->remaining >> 10);
|
141 |
monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n", |
142 |
info->disk->total >> 10);
|
143 |
} |
144 |
|
145 |
qapi_free_MigrationInfo(info); |
146 |
} |
147 |
|
148 |
void hmp_info_cpus(Monitor *mon)
|
149 |
{ |
150 |
CpuInfoList *cpu_list, *cpu; |
151 |
|
152 |
cpu_list = qmp_query_cpus(NULL);
|
153 |
|
154 |
for (cpu = cpu_list; cpu; cpu = cpu->next) {
|
155 |
int active = ' '; |
156 |
|
157 |
if (cpu->value->CPU == monitor_get_cpu_index()) {
|
158 |
active = '*';
|
159 |
} |
160 |
|
161 |
monitor_printf(mon, "%c CPU #%" PRId64 ": ", active, cpu->value->CPU); |
162 |
|
163 |
if (cpu->value->has_pc) {
|
164 |
monitor_printf(mon, "pc=0x%016" PRIx64, cpu->value->pc);
|
165 |
} |
166 |
if (cpu->value->has_nip) {
|
167 |
monitor_printf(mon, "nip=0x%016" PRIx64, cpu->value->nip);
|
168 |
} |
169 |
if (cpu->value->has_npc) {
|
170 |
monitor_printf(mon, "pc=0x%016" PRIx64, cpu->value->pc);
|
171 |
monitor_printf(mon, "npc=0x%016" PRIx64, cpu->value->npc);
|
172 |
} |
173 |
if (cpu->value->has_PC) {
|
174 |
monitor_printf(mon, "PC=0x%016" PRIx64, cpu->value->PC);
|
175 |
} |
176 |
|
177 |
if (cpu->value->halted) {
|
178 |
monitor_printf(mon, " (halted)");
|
179 |
} |
180 |
|
181 |
monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id); |
182 |
} |
183 |
|
184 |
qapi_free_CpuInfoList(cpu_list); |
185 |
} |
186 |
|
187 |
void hmp_info_block(Monitor *mon)
|
188 |
{ |
189 |
BlockInfoList *block_list, *info; |
190 |
|
191 |
block_list = qmp_query_block(NULL);
|
192 |
|
193 |
for (info = block_list; info; info = info->next) {
|
194 |
monitor_printf(mon, "%s: removable=%d",
|
195 |
info->value->device, info->value->removable); |
196 |
|
197 |
if (info->value->removable) {
|
198 |
monitor_printf(mon, " locked=%d", info->value->locked);
|
199 |
monitor_printf(mon, " tray-open=%d", info->value->tray_open);
|
200 |
} |
201 |
|
202 |
if (info->value->has_io_status) {
|
203 |
monitor_printf(mon, " io-status=%s",
|
204 |
BlockDeviceIoStatus_lookup[info->value->io_status]); |
205 |
} |
206 |
|
207 |
if (info->value->has_inserted) {
|
208 |
monitor_printf(mon, " file=");
|
209 |
monitor_print_filename(mon, info->value->inserted->file); |
210 |
|
211 |
if (info->value->inserted->has_backing_file) {
|
212 |
monitor_printf(mon, " backing_file=");
|
213 |
monitor_print_filename(mon, info->value->inserted->backing_file); |
214 |
} |
215 |
monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
|
216 |
info->value->inserted->ro, |
217 |
info->value->inserted->drv, |
218 |
info->value->inserted->encrypted); |
219 |
|
220 |
monitor_printf(mon, " bps=%" PRId64 " bps_rd=%" PRId64 |
221 |
" bps_wr=%" PRId64 " iops=%" PRId64 |
222 |
" iops_rd=%" PRId64 " iops_wr=%" PRId64, |
223 |
info->value->inserted->bps, |
224 |
info->value->inserted->bps_rd, |
225 |
info->value->inserted->bps_wr, |
226 |
info->value->inserted->iops, |
227 |
info->value->inserted->iops_rd, |
228 |
info->value->inserted->iops_wr); |
229 |
} else {
|
230 |
monitor_printf(mon, " [not inserted]");
|
231 |
} |
232 |
|
233 |
monitor_printf(mon, "\n");
|
234 |
} |
235 |
|
236 |
qapi_free_BlockInfoList(block_list); |
237 |
} |
238 |
|
239 |
void hmp_info_blockstats(Monitor *mon)
|
240 |
{ |
241 |
BlockStatsList *stats_list, *stats; |
242 |
|
243 |
stats_list = qmp_query_blockstats(NULL);
|
244 |
|
245 |
for (stats = stats_list; stats; stats = stats->next) {
|
246 |
if (!stats->value->has_device) {
|
247 |
continue;
|
248 |
} |
249 |
|
250 |
monitor_printf(mon, "%s:", stats->value->device);
|
251 |
monitor_printf(mon, " rd_bytes=%" PRId64
|
252 |
" wr_bytes=%" PRId64
|
253 |
" rd_operations=%" PRId64
|
254 |
" wr_operations=%" PRId64
|
255 |
" flush_operations=%" PRId64
|
256 |
" wr_total_time_ns=%" PRId64
|
257 |
" rd_total_time_ns=%" PRId64
|
258 |
" flush_total_time_ns=%" PRId64
|
259 |
"\n",
|
260 |
stats->value->stats->rd_bytes, |
261 |
stats->value->stats->wr_bytes, |
262 |
stats->value->stats->rd_operations, |
263 |
stats->value->stats->wr_operations, |
264 |
stats->value->stats->flush_operations, |
265 |
stats->value->stats->wr_total_time_ns, |
266 |
stats->value->stats->rd_total_time_ns, |
267 |
stats->value->stats->flush_total_time_ns); |
268 |
} |
269 |
|
270 |
qapi_free_BlockStatsList(stats_list); |
271 |
} |
272 |
|
273 |
void hmp_info_vnc(Monitor *mon)
|
274 |
{ |
275 |
VncInfo *info; |
276 |
Error *err = NULL;
|
277 |
VncClientInfoList *client; |
278 |
|
279 |
info = qmp_query_vnc(&err); |
280 |
if (err) {
|
281 |
monitor_printf(mon, "%s\n", error_get_pretty(err));
|
282 |
error_free(err); |
283 |
return;
|
284 |
} |
285 |
|
286 |
if (!info->enabled) {
|
287 |
monitor_printf(mon, "Server: disabled\n");
|
288 |
goto out;
|
289 |
} |
290 |
|
291 |
monitor_printf(mon, "Server:\n");
|
292 |
if (info->has_host && info->has_service) {
|
293 |
monitor_printf(mon, " address: %s:%s\n", info->host, info->service);
|
294 |
} |
295 |
if (info->has_auth) {
|
296 |
monitor_printf(mon, " auth: %s\n", info->auth);
|
297 |
} |
298 |
|
299 |
if (!info->has_clients || info->clients == NULL) { |
300 |
monitor_printf(mon, "Client: none\n");
|
301 |
} else {
|
302 |
for (client = info->clients; client; client = client->next) {
|
303 |
monitor_printf(mon, "Client:\n");
|
304 |
monitor_printf(mon, " address: %s:%s\n",
|
305 |
client->value->host, client->value->service); |
306 |
monitor_printf(mon, " x509_dname: %s\n",
|
307 |
client->value->x509_dname ? |
308 |
client->value->x509_dname : "none");
|
309 |
monitor_printf(mon, " username: %s\n",
|
310 |
client->value->has_sasl_username ? |
311 |
client->value->sasl_username : "none");
|
312 |
} |
313 |
} |
314 |
|
315 |
out:
|
316 |
qapi_free_VncInfo(info); |
317 |
} |
318 |
|
319 |
void hmp_info_spice(Monitor *mon)
|
320 |
{ |
321 |
SpiceChannelList *chan; |
322 |
SpiceInfo *info; |
323 |
|
324 |
info = qmp_query_spice(NULL);
|
325 |
|
326 |
if (!info->enabled) {
|
327 |
monitor_printf(mon, "Server: disabled\n");
|
328 |
goto out;
|
329 |
} |
330 |
|
331 |
monitor_printf(mon, "Server:\n");
|
332 |
if (info->has_port) {
|
333 |
monitor_printf(mon, " address: %s:%" PRId64 "\n", |
334 |
info->host, info->port); |
335 |
} |
336 |
if (info->has_tls_port) {
|
337 |
monitor_printf(mon, " address: %s:%" PRId64 " [tls]\n", |
338 |
info->host, info->tls_port); |
339 |
} |
340 |
monitor_printf(mon, " auth: %s\n", info->auth);
|
341 |
monitor_printf(mon, " compiled: %s\n", info->compiled_version);
|
342 |
|
343 |
if (!info->has_channels || info->channels == NULL) { |
344 |
monitor_printf(mon, "Channels: none\n");
|
345 |
} else {
|
346 |
for (chan = info->channels; chan; chan = chan->next) {
|
347 |
monitor_printf(mon, "Channel:\n");
|
348 |
monitor_printf(mon, " address: %s:%s%s\n",
|
349 |
chan->value->host, chan->value->port, |
350 |
chan->value->tls ? " [tls]" : ""); |
351 |
monitor_printf(mon, " session: %" PRId64 "\n", |
352 |
chan->value->connection_id); |
353 |
monitor_printf(mon, " channel: %" PRId64 ":%" PRId64 "\n", |
354 |
chan->value->channel_type, chan->value->channel_id); |
355 |
} |
356 |
} |
357 |
|
358 |
out:
|
359 |
qapi_free_SpiceInfo(info); |
360 |
} |
361 |
|
362 |
void hmp_info_balloon(Monitor *mon)
|
363 |
{ |
364 |
BalloonInfo *info; |
365 |
Error *err = NULL;
|
366 |
|
367 |
info = qmp_query_balloon(&err); |
368 |
if (err) {
|
369 |
monitor_printf(mon, "%s\n", error_get_pretty(err));
|
370 |
error_free(err); |
371 |
return;
|
372 |
} |
373 |
|
374 |
monitor_printf(mon, "balloon: actual=%" PRId64, info->actual >> 20); |
375 |
if (info->has_mem_swapped_in) {
|
376 |
monitor_printf(mon, " mem_swapped_in=%" PRId64, info->mem_swapped_in);
|
377 |
} |
378 |
if (info->has_mem_swapped_out) {
|
379 |
monitor_printf(mon, " mem_swapped_out=%" PRId64, info->mem_swapped_out);
|
380 |
} |
381 |
if (info->has_major_page_faults) {
|
382 |
monitor_printf(mon, " major_page_faults=%" PRId64,
|
383 |
info->major_page_faults); |
384 |
} |
385 |
if (info->has_minor_page_faults) {
|
386 |
monitor_printf(mon, " minor_page_faults=%" PRId64,
|
387 |
info->minor_page_faults); |
388 |
} |
389 |
if (info->has_free_mem) {
|
390 |
monitor_printf(mon, " free_mem=%" PRId64, info->free_mem);
|
391 |
} |
392 |
if (info->has_total_mem) {
|
393 |
monitor_printf(mon, " total_mem=%" PRId64, info->total_mem);
|
394 |
} |
395 |
|
396 |
monitor_printf(mon, "\n");
|
397 |
|
398 |
qapi_free_BalloonInfo(info); |
399 |
} |
400 |
|
401 |
static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev) |
402 |
{ |
403 |
PciMemoryRegionList *region; |
404 |
|
405 |
monitor_printf(mon, " Bus %2" PRId64 ", ", dev->bus); |
406 |
monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n", |
407 |
dev->slot, dev->function); |
408 |
monitor_printf(mon, " ");
|
409 |
|
410 |
if (dev->class_info.has_desc) {
|
411 |
monitor_printf(mon, "%s", dev->class_info.desc);
|
412 |
} else {
|
413 |
monitor_printf(mon, "Class %04" PRId64, dev->class_info.class);
|
414 |
} |
415 |
|
416 |
monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n", |
417 |
dev->id.vendor, dev->id.device); |
418 |
|
419 |
if (dev->has_irq) {
|
420 |
monitor_printf(mon, " IRQ %" PRId64 ".\n", dev->irq); |
421 |
} |
422 |
|
423 |
if (dev->has_pci_bridge) {
|
424 |
monitor_printf(mon, " BUS %" PRId64 ".\n", |
425 |
dev->pci_bridge->bus.number); |
426 |
monitor_printf(mon, " secondary bus %" PRId64 ".\n", |
427 |
dev->pci_bridge->bus.secondary); |
428 |
monitor_printf(mon, " subordinate bus %" PRId64 ".\n", |
429 |
dev->pci_bridge->bus.subordinate); |
430 |
|
431 |
monitor_printf(mon, " IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n", |
432 |
dev->pci_bridge->bus.io_range->base, |
433 |
dev->pci_bridge->bus.io_range->limit); |
434 |
|
435 |
monitor_printf(mon, |
436 |
" memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n", |
437 |
dev->pci_bridge->bus.memory_range->base, |
438 |
dev->pci_bridge->bus.memory_range->limit); |
439 |
|
440 |
monitor_printf(mon, " prefetchable memory range "
|
441 |
"[0x%08"PRIx64", 0x%08"PRIx64"]\n", |
442 |
dev->pci_bridge->bus.prefetchable_range->base, |
443 |
dev->pci_bridge->bus.prefetchable_range->limit); |
444 |
} |
445 |
|
446 |
for (region = dev->regions; region; region = region->next) {
|
447 |
uint64_t addr, size; |
448 |
|
449 |
addr = region->value->address; |
450 |
size = region->value->size; |
451 |
|
452 |
monitor_printf(mon, " BAR%" PRId64 ": ", region->value->bar); |
453 |
|
454 |
if (!strcmp(region->value->type, "io")) { |
455 |
monitor_printf(mon, "I/O at 0x%04" PRIx64
|
456 |
" [0x%04" PRIx64 "].\n", |
457 |
addr, addr + size - 1);
|
458 |
} else {
|
459 |
monitor_printf(mon, "%d bit%s memory at 0x%08" PRIx64
|
460 |
" [0x%08" PRIx64 "].\n", |
461 |
region->value->mem_type_64 ? 64 : 32, |
462 |
region->value->prefetch ? " prefetchable" : "", |
463 |
addr, addr + size - 1);
|
464 |
} |
465 |
} |
466 |
|
467 |
monitor_printf(mon, " id \"%s\"\n", dev->qdev_id);
|
468 |
|
469 |
if (dev->has_pci_bridge) {
|
470 |
if (dev->pci_bridge->has_devices) {
|
471 |
PciDeviceInfoList *cdev; |
472 |
for (cdev = dev->pci_bridge->devices; cdev; cdev = cdev->next) {
|
473 |
hmp_info_pci_device(mon, cdev->value); |
474 |
} |
475 |
} |
476 |
} |
477 |
} |
478 |
|
479 |
void hmp_info_pci(Monitor *mon)
|
480 |
{ |
481 |
PciInfoList *info; |
482 |
Error *err = NULL;
|
483 |
|
484 |
info = qmp_query_pci(&err); |
485 |
if (err) {
|
486 |
monitor_printf(mon, "PCI devices not supported\n");
|
487 |
error_free(err); |
488 |
return;
|
489 |
} |
490 |
|
491 |
for (; info; info = info->next) {
|
492 |
PciDeviceInfoList *dev; |
493 |
|
494 |
for (dev = info->value->devices; dev; dev = dev->next) {
|
495 |
hmp_info_pci_device(mon, dev->value); |
496 |
} |
497 |
} |
498 |
|
499 |
qapi_free_PciInfoList(info); |
500 |
} |
501 |
|
502 |
void hmp_quit(Monitor *mon, const QDict *qdict) |
503 |
{ |
504 |
monitor_suspend(mon); |
505 |
qmp_quit(NULL);
|
506 |
} |
507 |
|
508 |
void hmp_stop(Monitor *mon, const QDict *qdict) |
509 |
{ |
510 |
qmp_stop(NULL);
|
511 |
} |
512 |
|
513 |
void hmp_system_reset(Monitor *mon, const QDict *qdict) |
514 |
{ |
515 |
qmp_system_reset(NULL);
|
516 |
} |
517 |
|
518 |
void hmp_system_powerdown(Monitor *mon, const QDict *qdict) |
519 |
{ |
520 |
qmp_system_powerdown(NULL);
|
521 |
} |
522 |
|
523 |
void hmp_cpu(Monitor *mon, const QDict *qdict) |
524 |
{ |
525 |
int64_t cpu_index; |
526 |
|
527 |
/* XXX: drop the monitor_set_cpu() usage when all HMP commands that
|
528 |
use it are converted to the QAPI */
|
529 |
cpu_index = qdict_get_int(qdict, "index");
|
530 |
if (monitor_set_cpu(cpu_index) < 0) { |
531 |
monitor_printf(mon, "invalid CPU index\n");
|
532 |
} |
533 |
} |