root / hmp.c @ 60e1b2a6
History | View | Annotate | Download (25.2 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 |
* Contributions after 2012-01-13 are licensed under the terms of the
|
13 |
* GNU GPL, version 2 or (at your option) any later version.
|
14 |
*/
|
15 |
|
16 |
#include "hmp.h" |
17 |
#include "qmp-commands.h" |
18 |
|
19 |
static void hmp_handle_error(Monitor *mon, Error **errp) |
20 |
{ |
21 |
if (error_is_set(errp)) {
|
22 |
monitor_printf(mon, "%s\n", error_get_pretty(*errp));
|
23 |
error_free(*errp); |
24 |
} |
25 |
} |
26 |
|
27 |
void hmp_info_name(Monitor *mon)
|
28 |
{ |
29 |
NameInfo *info; |
30 |
|
31 |
info = qmp_query_name(NULL);
|
32 |
if (info->has_name) {
|
33 |
monitor_printf(mon, "%s\n", info->name);
|
34 |
} |
35 |
qapi_free_NameInfo(info); |
36 |
} |
37 |
|
38 |
void hmp_info_version(Monitor *mon)
|
39 |
{ |
40 |
VersionInfo *info; |
41 |
|
42 |
info = qmp_query_version(NULL);
|
43 |
|
44 |
monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n", |
45 |
info->qemu.major, info->qemu.minor, info->qemu.micro, |
46 |
info->package); |
47 |
|
48 |
qapi_free_VersionInfo(info); |
49 |
} |
50 |
|
51 |
void hmp_info_kvm(Monitor *mon)
|
52 |
{ |
53 |
KvmInfo *info; |
54 |
|
55 |
info = qmp_query_kvm(NULL);
|
56 |
monitor_printf(mon, "kvm support: ");
|
57 |
if (info->present) {
|
58 |
monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled"); |
59 |
} else {
|
60 |
monitor_printf(mon, "not compiled\n");
|
61 |
} |
62 |
|
63 |
qapi_free_KvmInfo(info); |
64 |
} |
65 |
|
66 |
void hmp_info_status(Monitor *mon)
|
67 |
{ |
68 |
StatusInfo *info; |
69 |
|
70 |
info = qmp_query_status(NULL);
|
71 |
|
72 |
monitor_printf(mon, "VM status: %s%s",
|
73 |
info->running ? "running" : "paused", |
74 |
info->singlestep ? " (single step mode)" : ""); |
75 |
|
76 |
if (!info->running && info->status != RUN_STATE_PAUSED) {
|
77 |
monitor_printf(mon, " (%s)", RunState_lookup[info->status]);
|
78 |
} |
79 |
|
80 |
monitor_printf(mon, "\n");
|
81 |
|
82 |
qapi_free_StatusInfo(info); |
83 |
} |
84 |
|
85 |
void hmp_info_uuid(Monitor *mon)
|
86 |
{ |
87 |
UuidInfo *info; |
88 |
|
89 |
info = qmp_query_uuid(NULL);
|
90 |
monitor_printf(mon, "%s\n", info->UUID);
|
91 |
qapi_free_UuidInfo(info); |
92 |
} |
93 |
|
94 |
void hmp_info_chardev(Monitor *mon)
|
95 |
{ |
96 |
ChardevInfoList *char_info, *info; |
97 |
|
98 |
char_info = qmp_query_chardev(NULL);
|
99 |
for (info = char_info; info; info = info->next) {
|
100 |
monitor_printf(mon, "%s: filename=%s\n", info->value->label,
|
101 |
info->value->filename); |
102 |
} |
103 |
|
104 |
qapi_free_ChardevInfoList(char_info); |
105 |
} |
106 |
|
107 |
void hmp_info_mice(Monitor *mon)
|
108 |
{ |
109 |
MouseInfoList *mice_list, *mouse; |
110 |
|
111 |
mice_list = qmp_query_mice(NULL);
|
112 |
if (!mice_list) {
|
113 |
monitor_printf(mon, "No mouse devices connected\n");
|
114 |
return;
|
115 |
} |
116 |
|
117 |
for (mouse = mice_list; mouse; mouse = mouse->next) {
|
118 |
monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n", |
119 |
mouse->value->current ? '*' : ' ', |
120 |
mouse->value->index, mouse->value->name, |
121 |
mouse->value->absolute ? " (absolute)" : ""); |
122 |
} |
123 |
|
124 |
qapi_free_MouseInfoList(mice_list); |
125 |
} |
126 |
|
127 |
void hmp_info_migrate(Monitor *mon)
|
128 |
{ |
129 |
MigrationInfo *info; |
130 |
|
131 |
info = qmp_query_migrate(NULL);
|
132 |
|
133 |
if (info->has_status) {
|
134 |
monitor_printf(mon, "Migration status: %s\n", info->status);
|
135 |
} |
136 |
|
137 |
if (info->has_ram) {
|
138 |
monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", |
139 |
info->ram->transferred >> 10);
|
140 |
monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", |
141 |
info->ram->remaining >> 10);
|
142 |
monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", |
143 |
info->ram->total >> 10);
|
144 |
} |
145 |
|
146 |
if (info->has_disk) {
|
147 |
monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n", |
148 |
info->disk->transferred >> 10);
|
149 |
monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n", |
150 |
info->disk->remaining >> 10);
|
151 |
monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n", |
152 |
info->disk->total >> 10);
|
153 |
} |
154 |
|
155 |
qapi_free_MigrationInfo(info); |
156 |
} |
157 |
|
158 |
void hmp_info_cpus(Monitor *mon)
|
159 |
{ |
160 |
CpuInfoList *cpu_list, *cpu; |
161 |
|
162 |
cpu_list = qmp_query_cpus(NULL);
|
163 |
|
164 |
for (cpu = cpu_list; cpu; cpu = cpu->next) {
|
165 |
int active = ' '; |
166 |
|
167 |
if (cpu->value->CPU == monitor_get_cpu_index()) {
|
168 |
active = '*';
|
169 |
} |
170 |
|
171 |
monitor_printf(mon, "%c CPU #%" PRId64 ": ", active, cpu->value->CPU); |
172 |
|
173 |
if (cpu->value->has_pc) {
|
174 |
monitor_printf(mon, "pc=0x%016" PRIx64, cpu->value->pc);
|
175 |
} |
176 |
if (cpu->value->has_nip) {
|
177 |
monitor_printf(mon, "nip=0x%016" PRIx64, cpu->value->nip);
|
178 |
} |
179 |
if (cpu->value->has_npc) {
|
180 |
monitor_printf(mon, "pc=0x%016" PRIx64, cpu->value->pc);
|
181 |
monitor_printf(mon, "npc=0x%016" PRIx64, cpu->value->npc);
|
182 |
} |
183 |
if (cpu->value->has_PC) {
|
184 |
monitor_printf(mon, "PC=0x%016" PRIx64, cpu->value->PC);
|
185 |
} |
186 |
|
187 |
if (cpu->value->halted) {
|
188 |
monitor_printf(mon, " (halted)");
|
189 |
} |
190 |
|
191 |
monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id); |
192 |
} |
193 |
|
194 |
qapi_free_CpuInfoList(cpu_list); |
195 |
} |
196 |
|
197 |
void hmp_info_block(Monitor *mon)
|
198 |
{ |
199 |
BlockInfoList *block_list, *info; |
200 |
|
201 |
block_list = qmp_query_block(NULL);
|
202 |
|
203 |
for (info = block_list; info; info = info->next) {
|
204 |
monitor_printf(mon, "%s: removable=%d",
|
205 |
info->value->device, info->value->removable); |
206 |
|
207 |
if (info->value->removable) {
|
208 |
monitor_printf(mon, " locked=%d", info->value->locked);
|
209 |
monitor_printf(mon, " tray-open=%d", info->value->tray_open);
|
210 |
} |
211 |
|
212 |
if (info->value->has_io_status) {
|
213 |
monitor_printf(mon, " io-status=%s",
|
214 |
BlockDeviceIoStatus_lookup[info->value->io_status]); |
215 |
} |
216 |
|
217 |
if (info->value->has_inserted) {
|
218 |
monitor_printf(mon, " file=");
|
219 |
monitor_print_filename(mon, info->value->inserted->file); |
220 |
|
221 |
if (info->value->inserted->has_backing_file) {
|
222 |
monitor_printf(mon, " backing_file=");
|
223 |
monitor_print_filename(mon, info->value->inserted->backing_file); |
224 |
} |
225 |
monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
|
226 |
info->value->inserted->ro, |
227 |
info->value->inserted->drv, |
228 |
info->value->inserted->encrypted); |
229 |
|
230 |
monitor_printf(mon, " bps=%" PRId64 " bps_rd=%" PRId64 |
231 |
" bps_wr=%" PRId64 " iops=%" PRId64 |
232 |
" iops_rd=%" PRId64 " iops_wr=%" PRId64, |
233 |
info->value->inserted->bps, |
234 |
info->value->inserted->bps_rd, |
235 |
info->value->inserted->bps_wr, |
236 |
info->value->inserted->iops, |
237 |
info->value->inserted->iops_rd, |
238 |
info->value->inserted->iops_wr); |
239 |
} else {
|
240 |
monitor_printf(mon, " [not inserted]");
|
241 |
} |
242 |
|
243 |
monitor_printf(mon, "\n");
|
244 |
} |
245 |
|
246 |
qapi_free_BlockInfoList(block_list); |
247 |
} |
248 |
|
249 |
void hmp_info_blockstats(Monitor *mon)
|
250 |
{ |
251 |
BlockStatsList *stats_list, *stats; |
252 |
|
253 |
stats_list = qmp_query_blockstats(NULL);
|
254 |
|
255 |
for (stats = stats_list; stats; stats = stats->next) {
|
256 |
if (!stats->value->has_device) {
|
257 |
continue;
|
258 |
} |
259 |
|
260 |
monitor_printf(mon, "%s:", stats->value->device);
|
261 |
monitor_printf(mon, " rd_bytes=%" PRId64
|
262 |
" wr_bytes=%" PRId64
|
263 |
" rd_operations=%" PRId64
|
264 |
" wr_operations=%" PRId64
|
265 |
" flush_operations=%" PRId64
|
266 |
" wr_total_time_ns=%" PRId64
|
267 |
" rd_total_time_ns=%" PRId64
|
268 |
" flush_total_time_ns=%" PRId64
|
269 |
"\n",
|
270 |
stats->value->stats->rd_bytes, |
271 |
stats->value->stats->wr_bytes, |
272 |
stats->value->stats->rd_operations, |
273 |
stats->value->stats->wr_operations, |
274 |
stats->value->stats->flush_operations, |
275 |
stats->value->stats->wr_total_time_ns, |
276 |
stats->value->stats->rd_total_time_ns, |
277 |
stats->value->stats->flush_total_time_ns); |
278 |
} |
279 |
|
280 |
qapi_free_BlockStatsList(stats_list); |
281 |
} |
282 |
|
283 |
void hmp_info_vnc(Monitor *mon)
|
284 |
{ |
285 |
VncInfo *info; |
286 |
Error *err = NULL;
|
287 |
VncClientInfoList *client; |
288 |
|
289 |
info = qmp_query_vnc(&err); |
290 |
if (err) {
|
291 |
monitor_printf(mon, "%s\n", error_get_pretty(err));
|
292 |
error_free(err); |
293 |
return;
|
294 |
} |
295 |
|
296 |
if (!info->enabled) {
|
297 |
monitor_printf(mon, "Server: disabled\n");
|
298 |
goto out;
|
299 |
} |
300 |
|
301 |
monitor_printf(mon, "Server:\n");
|
302 |
if (info->has_host && info->has_service) {
|
303 |
monitor_printf(mon, " address: %s:%s\n", info->host, info->service);
|
304 |
} |
305 |
if (info->has_auth) {
|
306 |
monitor_printf(mon, " auth: %s\n", info->auth);
|
307 |
} |
308 |
|
309 |
if (!info->has_clients || info->clients == NULL) { |
310 |
monitor_printf(mon, "Client: none\n");
|
311 |
} else {
|
312 |
for (client = info->clients; client; client = client->next) {
|
313 |
monitor_printf(mon, "Client:\n");
|
314 |
monitor_printf(mon, " address: %s:%s\n",
|
315 |
client->value->host, client->value->service); |
316 |
monitor_printf(mon, " x509_dname: %s\n",
|
317 |
client->value->x509_dname ? |
318 |
client->value->x509_dname : "none");
|
319 |
monitor_printf(mon, " username: %s\n",
|
320 |
client->value->has_sasl_username ? |
321 |
client->value->sasl_username : "none");
|
322 |
} |
323 |
} |
324 |
|
325 |
out:
|
326 |
qapi_free_VncInfo(info); |
327 |
} |
328 |
|
329 |
void hmp_info_spice(Monitor *mon)
|
330 |
{ |
331 |
SpiceChannelList *chan; |
332 |
SpiceInfo *info; |
333 |
|
334 |
info = qmp_query_spice(NULL);
|
335 |
|
336 |
if (!info->enabled) {
|
337 |
monitor_printf(mon, "Server: disabled\n");
|
338 |
goto out;
|
339 |
} |
340 |
|
341 |
monitor_printf(mon, "Server:\n");
|
342 |
if (info->has_port) {
|
343 |
monitor_printf(mon, " address: %s:%" PRId64 "\n", |
344 |
info->host, info->port); |
345 |
} |
346 |
if (info->has_tls_port) {
|
347 |
monitor_printf(mon, " address: %s:%" PRId64 " [tls]\n", |
348 |
info->host, info->tls_port); |
349 |
} |
350 |
monitor_printf(mon, " auth: %s\n", info->auth);
|
351 |
monitor_printf(mon, " compiled: %s\n", info->compiled_version);
|
352 |
|
353 |
if (!info->has_channels || info->channels == NULL) { |
354 |
monitor_printf(mon, "Channels: none\n");
|
355 |
} else {
|
356 |
for (chan = info->channels; chan; chan = chan->next) {
|
357 |
monitor_printf(mon, "Channel:\n");
|
358 |
monitor_printf(mon, " address: %s:%s%s\n",
|
359 |
chan->value->host, chan->value->port, |
360 |
chan->value->tls ? " [tls]" : ""); |
361 |
monitor_printf(mon, " session: %" PRId64 "\n", |
362 |
chan->value->connection_id); |
363 |
monitor_printf(mon, " channel: %" PRId64 ":%" PRId64 "\n", |
364 |
chan->value->channel_type, chan->value->channel_id); |
365 |
} |
366 |
} |
367 |
|
368 |
out:
|
369 |
qapi_free_SpiceInfo(info); |
370 |
} |
371 |
|
372 |
void hmp_info_balloon(Monitor *mon)
|
373 |
{ |
374 |
BalloonInfo *info; |
375 |
Error *err = NULL;
|
376 |
|
377 |
info = qmp_query_balloon(&err); |
378 |
if (err) {
|
379 |
monitor_printf(mon, "%s\n", error_get_pretty(err));
|
380 |
error_free(err); |
381 |
return;
|
382 |
} |
383 |
|
384 |
monitor_printf(mon, "balloon: actual=%" PRId64, info->actual >> 20); |
385 |
if (info->has_mem_swapped_in) {
|
386 |
monitor_printf(mon, " mem_swapped_in=%" PRId64, info->mem_swapped_in);
|
387 |
} |
388 |
if (info->has_mem_swapped_out) {
|
389 |
monitor_printf(mon, " mem_swapped_out=%" PRId64, info->mem_swapped_out);
|
390 |
} |
391 |
if (info->has_major_page_faults) {
|
392 |
monitor_printf(mon, " major_page_faults=%" PRId64,
|
393 |
info->major_page_faults); |
394 |
} |
395 |
if (info->has_minor_page_faults) {
|
396 |
monitor_printf(mon, " minor_page_faults=%" PRId64,
|
397 |
info->minor_page_faults); |
398 |
} |
399 |
if (info->has_free_mem) {
|
400 |
monitor_printf(mon, " free_mem=%" PRId64, info->free_mem);
|
401 |
} |
402 |
if (info->has_total_mem) {
|
403 |
monitor_printf(mon, " total_mem=%" PRId64, info->total_mem);
|
404 |
} |
405 |
|
406 |
monitor_printf(mon, "\n");
|
407 |
|
408 |
qapi_free_BalloonInfo(info); |
409 |
} |
410 |
|
411 |
static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev) |
412 |
{ |
413 |
PciMemoryRegionList *region; |
414 |
|
415 |
monitor_printf(mon, " Bus %2" PRId64 ", ", dev->bus); |
416 |
monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n", |
417 |
dev->slot, dev->function); |
418 |
monitor_printf(mon, " ");
|
419 |
|
420 |
if (dev->class_info.has_desc) {
|
421 |
monitor_printf(mon, "%s", dev->class_info.desc);
|
422 |
} else {
|
423 |
monitor_printf(mon, "Class %04" PRId64, dev->class_info.class);
|
424 |
} |
425 |
|
426 |
monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n", |
427 |
dev->id.vendor, dev->id.device); |
428 |
|
429 |
if (dev->has_irq) {
|
430 |
monitor_printf(mon, " IRQ %" PRId64 ".\n", dev->irq); |
431 |
} |
432 |
|
433 |
if (dev->has_pci_bridge) {
|
434 |
monitor_printf(mon, " BUS %" PRId64 ".\n", |
435 |
dev->pci_bridge->bus.number); |
436 |
monitor_printf(mon, " secondary bus %" PRId64 ".\n", |
437 |
dev->pci_bridge->bus.secondary); |
438 |
monitor_printf(mon, " subordinate bus %" PRId64 ".\n", |
439 |
dev->pci_bridge->bus.subordinate); |
440 |
|
441 |
monitor_printf(mon, " IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n", |
442 |
dev->pci_bridge->bus.io_range->base, |
443 |
dev->pci_bridge->bus.io_range->limit); |
444 |
|
445 |
monitor_printf(mon, |
446 |
" memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n", |
447 |
dev->pci_bridge->bus.memory_range->base, |
448 |
dev->pci_bridge->bus.memory_range->limit); |
449 |
|
450 |
monitor_printf(mon, " prefetchable memory range "
|
451 |
"[0x%08"PRIx64", 0x%08"PRIx64"]\n", |
452 |
dev->pci_bridge->bus.prefetchable_range->base, |
453 |
dev->pci_bridge->bus.prefetchable_range->limit); |
454 |
} |
455 |
|
456 |
for (region = dev->regions; region; region = region->next) {
|
457 |
uint64_t addr, size; |
458 |
|
459 |
addr = region->value->address; |
460 |
size = region->value->size; |
461 |
|
462 |
monitor_printf(mon, " BAR%" PRId64 ": ", region->value->bar); |
463 |
|
464 |
if (!strcmp(region->value->type, "io")) { |
465 |
monitor_printf(mon, "I/O at 0x%04" PRIx64
|
466 |
" [0x%04" PRIx64 "].\n", |
467 |
addr, addr + size - 1);
|
468 |
} else {
|
469 |
monitor_printf(mon, "%d bit%s memory at 0x%08" PRIx64
|
470 |
" [0x%08" PRIx64 "].\n", |
471 |
region->value->mem_type_64 ? 64 : 32, |
472 |
region->value->prefetch ? " prefetchable" : "", |
473 |
addr, addr + size - 1);
|
474 |
} |
475 |
} |
476 |
|
477 |
monitor_printf(mon, " id \"%s\"\n", dev->qdev_id);
|
478 |
|
479 |
if (dev->has_pci_bridge) {
|
480 |
if (dev->pci_bridge->has_devices) {
|
481 |
PciDeviceInfoList *cdev; |
482 |
for (cdev = dev->pci_bridge->devices; cdev; cdev = cdev->next) {
|
483 |
hmp_info_pci_device(mon, cdev->value); |
484 |
} |
485 |
} |
486 |
} |
487 |
} |
488 |
|
489 |
void hmp_info_pci(Monitor *mon)
|
490 |
{ |
491 |
PciInfoList *info_list, *info; |
492 |
Error *err = NULL;
|
493 |
|
494 |
info_list = qmp_query_pci(&err); |
495 |
if (err) {
|
496 |
monitor_printf(mon, "PCI devices not supported\n");
|
497 |
error_free(err); |
498 |
return;
|
499 |
} |
500 |
|
501 |
for (info = info_list; info; info = info->next) {
|
502 |
PciDeviceInfoList *dev; |
503 |
|
504 |
for (dev = info->value->devices; dev; dev = dev->next) {
|
505 |
hmp_info_pci_device(mon, dev->value); |
506 |
} |
507 |
} |
508 |
|
509 |
qapi_free_PciInfoList(info_list); |
510 |
} |
511 |
|
512 |
void hmp_info_block_jobs(Monitor *mon)
|
513 |
{ |
514 |
BlockJobInfoList *list; |
515 |
Error *err = NULL;
|
516 |
|
517 |
list = qmp_query_block_jobs(&err); |
518 |
assert(!err); |
519 |
|
520 |
if (!list) {
|
521 |
monitor_printf(mon, "No active jobs\n");
|
522 |
return;
|
523 |
} |
524 |
|
525 |
while (list) {
|
526 |
if (strcmp(list->value->type, "stream") == 0) { |
527 |
monitor_printf(mon, "Streaming device %s: Completed %" PRId64
|
528 |
" of %" PRId64 " bytes, speed limit %" PRId64 |
529 |
" bytes/s\n",
|
530 |
list->value->device, |
531 |
list->value->offset, |
532 |
list->value->len, |
533 |
list->value->speed); |
534 |
} else {
|
535 |
monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
|
536 |
" of %" PRId64 " bytes, speed limit %" PRId64 |
537 |
" bytes/s\n",
|
538 |
list->value->type, |
539 |
list->value->device, |
540 |
list->value->offset, |
541 |
list->value->len, |
542 |
list->value->speed); |
543 |
} |
544 |
list = list->next; |
545 |
} |
546 |
} |
547 |
|
548 |
void hmp_quit(Monitor *mon, const QDict *qdict) |
549 |
{ |
550 |
monitor_suspend(mon); |
551 |
qmp_quit(NULL);
|
552 |
} |
553 |
|
554 |
void hmp_stop(Monitor *mon, const QDict *qdict) |
555 |
{ |
556 |
qmp_stop(NULL);
|
557 |
} |
558 |
|
559 |
void hmp_system_reset(Monitor *mon, const QDict *qdict) |
560 |
{ |
561 |
qmp_system_reset(NULL);
|
562 |
} |
563 |
|
564 |
void hmp_system_powerdown(Monitor *mon, const QDict *qdict) |
565 |
{ |
566 |
qmp_system_powerdown(NULL);
|
567 |
} |
568 |
|
569 |
void hmp_cpu(Monitor *mon, const QDict *qdict) |
570 |
{ |
571 |
int64_t cpu_index; |
572 |
|
573 |
/* XXX: drop the monitor_set_cpu() usage when all HMP commands that
|
574 |
use it are converted to the QAPI */
|
575 |
cpu_index = qdict_get_int(qdict, "index");
|
576 |
if (monitor_set_cpu(cpu_index) < 0) { |
577 |
monitor_printf(mon, "invalid CPU index\n");
|
578 |
} |
579 |
} |
580 |
|
581 |
void hmp_memsave(Monitor *mon, const QDict *qdict) |
582 |
{ |
583 |
uint32_t size = qdict_get_int(qdict, "size");
|
584 |
const char *filename = qdict_get_str(qdict, "filename"); |
585 |
uint64_t addr = qdict_get_int(qdict, "val");
|
586 |
Error *errp = NULL;
|
587 |
|
588 |
qmp_memsave(addr, size, filename, true, monitor_get_cpu_index(), &errp);
|
589 |
hmp_handle_error(mon, &errp); |
590 |
} |
591 |
|
592 |
void hmp_pmemsave(Monitor *mon, const QDict *qdict) |
593 |
{ |
594 |
uint32_t size = qdict_get_int(qdict, "size");
|
595 |
const char *filename = qdict_get_str(qdict, "filename"); |
596 |
uint64_t addr = qdict_get_int(qdict, "val");
|
597 |
Error *errp = NULL;
|
598 |
|
599 |
qmp_pmemsave(addr, size, filename, &errp); |
600 |
hmp_handle_error(mon, &errp); |
601 |
} |
602 |
|
603 |
static void hmp_cont_cb(void *opaque, int err) |
604 |
{ |
605 |
Monitor *mon = opaque; |
606 |
|
607 |
if (!err) {
|
608 |
hmp_cont(mon, NULL);
|
609 |
} |
610 |
} |
611 |
|
612 |
void hmp_cont(Monitor *mon, const QDict *qdict) |
613 |
{ |
614 |
Error *errp = NULL;
|
615 |
|
616 |
qmp_cont(&errp); |
617 |
if (error_is_set(&errp)) {
|
618 |
if (error_is_type(errp, QERR_DEVICE_ENCRYPTED)) {
|
619 |
const char *device; |
620 |
|
621 |
/* The device is encrypted. Ask the user for the password
|
622 |
and retry */
|
623 |
|
624 |
device = error_get_field(errp, "device");
|
625 |
assert(device != NULL);
|
626 |
|
627 |
monitor_read_block_device_key(mon, device, hmp_cont_cb, mon); |
628 |
error_free(errp); |
629 |
return;
|
630 |
} |
631 |
hmp_handle_error(mon, &errp); |
632 |
} |
633 |
} |
634 |
|
635 |
void hmp_system_wakeup(Monitor *mon, const QDict *qdict) |
636 |
{ |
637 |
qmp_system_wakeup(NULL);
|
638 |
} |
639 |
|
640 |
void hmp_inject_nmi(Monitor *mon, const QDict *qdict) |
641 |
{ |
642 |
Error *errp = NULL;
|
643 |
|
644 |
qmp_inject_nmi(&errp); |
645 |
hmp_handle_error(mon, &errp); |
646 |
} |
647 |
|
648 |
void hmp_set_link(Monitor *mon, const QDict *qdict) |
649 |
{ |
650 |
const char *name = qdict_get_str(qdict, "name"); |
651 |
int up = qdict_get_bool(qdict, "up"); |
652 |
Error *errp = NULL;
|
653 |
|
654 |
qmp_set_link(name, up, &errp); |
655 |
hmp_handle_error(mon, &errp); |
656 |
} |
657 |
|
658 |
void hmp_block_passwd(Monitor *mon, const QDict *qdict) |
659 |
{ |
660 |
const char *device = qdict_get_str(qdict, "device"); |
661 |
const char *password = qdict_get_str(qdict, "password"); |
662 |
Error *errp = NULL;
|
663 |
|
664 |
qmp_block_passwd(device, password, &errp); |
665 |
hmp_handle_error(mon, &errp); |
666 |
} |
667 |
|
668 |
void hmp_balloon(Monitor *mon, const QDict *qdict) |
669 |
{ |
670 |
int64_t value = qdict_get_int(qdict, "value");
|
671 |
Error *errp = NULL;
|
672 |
|
673 |
qmp_balloon(value, &errp); |
674 |
if (error_is_set(&errp)) {
|
675 |
monitor_printf(mon, "balloon: %s\n", error_get_pretty(errp));
|
676 |
error_free(errp); |
677 |
} |
678 |
} |
679 |
|
680 |
void hmp_block_resize(Monitor *mon, const QDict *qdict) |
681 |
{ |
682 |
const char *device = qdict_get_str(qdict, "device"); |
683 |
int64_t size = qdict_get_int(qdict, "size");
|
684 |
Error *errp = NULL;
|
685 |
|
686 |
qmp_block_resize(device, size, &errp); |
687 |
hmp_handle_error(mon, &errp); |
688 |
} |
689 |
|
690 |
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict) |
691 |
{ |
692 |
const char *device = qdict_get_str(qdict, "device"); |
693 |
const char *filename = qdict_get_try_str(qdict, "snapshot-file"); |
694 |
const char *format = qdict_get_try_str(qdict, "format"); |
695 |
int reuse = qdict_get_try_bool(qdict, "reuse", 0); |
696 |
enum NewImageMode mode;
|
697 |
Error *errp = NULL;
|
698 |
|
699 |
if (!filename) {
|
700 |
/* In the future, if 'snapshot-file' is not specified, the snapshot
|
701 |
will be taken internally. Today it's actually required. */
|
702 |
error_set(&errp, QERR_MISSING_PARAMETER, "snapshot-file");
|
703 |
hmp_handle_error(mon, &errp); |
704 |
return;
|
705 |
} |
706 |
|
707 |
mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS; |
708 |
qmp_blockdev_snapshot_sync(device, filename, !!format, format, |
709 |
true, mode, &errp);
|
710 |
hmp_handle_error(mon, &errp); |
711 |
} |
712 |
|
713 |
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict) |
714 |
{ |
715 |
qmp_migrate_cancel(NULL);
|
716 |
} |
717 |
|
718 |
void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict) |
719 |
{ |
720 |
double value = qdict_get_double(qdict, "value"); |
721 |
qmp_migrate_set_downtime(value, NULL);
|
722 |
} |
723 |
|
724 |
void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict) |
725 |
{ |
726 |
int64_t value = qdict_get_int(qdict, "value");
|
727 |
qmp_migrate_set_speed(value, NULL);
|
728 |
} |
729 |
|
730 |
void hmp_set_password(Monitor *mon, const QDict *qdict) |
731 |
{ |
732 |
const char *protocol = qdict_get_str(qdict, "protocol"); |
733 |
const char *password = qdict_get_str(qdict, "password"); |
734 |
const char *connected = qdict_get_try_str(qdict, "connected"); |
735 |
Error *err = NULL;
|
736 |
|
737 |
qmp_set_password(protocol, password, !!connected, connected, &err); |
738 |
hmp_handle_error(mon, &err); |
739 |
} |
740 |
|
741 |
void hmp_expire_password(Monitor *mon, const QDict *qdict) |
742 |
{ |
743 |
const char *protocol = qdict_get_str(qdict, "protocol"); |
744 |
const char *whenstr = qdict_get_str(qdict, "time"); |
745 |
Error *err = NULL;
|
746 |
|
747 |
qmp_expire_password(protocol, whenstr, &err); |
748 |
hmp_handle_error(mon, &err); |
749 |
} |
750 |
|
751 |
void hmp_eject(Monitor *mon, const QDict *qdict) |
752 |
{ |
753 |
int force = qdict_get_try_bool(qdict, "force", 0); |
754 |
const char *device = qdict_get_str(qdict, "device"); |
755 |
Error *err = NULL;
|
756 |
|
757 |
qmp_eject(device, true, force, &err);
|
758 |
hmp_handle_error(mon, &err); |
759 |
} |
760 |
|
761 |
static void hmp_change_read_arg(Monitor *mon, const char *password, |
762 |
void *opaque)
|
763 |
{ |
764 |
qmp_change_vnc_password(password, NULL);
|
765 |
monitor_read_command(mon, 1);
|
766 |
} |
767 |
|
768 |
static void cb_hmp_change_bdrv_pwd(Monitor *mon, const char *password, |
769 |
void *opaque)
|
770 |
{ |
771 |
Error *encryption_err = opaque; |
772 |
Error *err = NULL;
|
773 |
const char *device; |
774 |
|
775 |
device = error_get_field(encryption_err, "device");
|
776 |
|
777 |
qmp_block_passwd(device, password, &err); |
778 |
hmp_handle_error(mon, &err); |
779 |
error_free(encryption_err); |
780 |
|
781 |
monitor_read_command(mon, 1);
|
782 |
} |
783 |
|
784 |
void hmp_change(Monitor *mon, const QDict *qdict) |
785 |
{ |
786 |
const char *device = qdict_get_str(qdict, "device"); |
787 |
const char *target = qdict_get_str(qdict, "target"); |
788 |
const char *arg = qdict_get_try_str(qdict, "arg"); |
789 |
Error *err = NULL;
|
790 |
|
791 |
if (strcmp(device, "vnc") == 0 && |
792 |
(strcmp(target, "passwd") == 0 || |
793 |
strcmp(target, "password") == 0)) { |
794 |
if (!arg) {
|
795 |
monitor_read_password(mon, hmp_change_read_arg, NULL);
|
796 |
return;
|
797 |
} |
798 |
} |
799 |
|
800 |
qmp_change(device, target, !!arg, arg, &err); |
801 |
if (error_is_type(err, QERR_DEVICE_ENCRYPTED)) {
|
802 |
monitor_printf(mon, "%s (%s) is encrypted.\n",
|
803 |
error_get_field(err, "device"),
|
804 |
error_get_field(err, "filename"));
|
805 |
if (!monitor_get_rs(mon)) {
|
806 |
monitor_printf(mon, |
807 |
"terminal does not support password prompting\n");
|
808 |
error_free(err); |
809 |
return;
|
810 |
} |
811 |
readline_start(monitor_get_rs(mon), "Password: ", 1, |
812 |
cb_hmp_change_bdrv_pwd, err); |
813 |
return;
|
814 |
} |
815 |
hmp_handle_error(mon, &err); |
816 |
} |
817 |
|
818 |
void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict) |
819 |
{ |
820 |
Error *err = NULL;
|
821 |
|
822 |
qmp_block_set_io_throttle(qdict_get_str(qdict, "device"),
|
823 |
qdict_get_int(qdict, "bps"),
|
824 |
qdict_get_int(qdict, "bps_rd"),
|
825 |
qdict_get_int(qdict, "bps_wr"),
|
826 |
qdict_get_int(qdict, "iops"),
|
827 |
qdict_get_int(qdict, "iops_rd"),
|
828 |
qdict_get_int(qdict, "iops_wr"), &err);
|
829 |
hmp_handle_error(mon, &err); |
830 |
} |
831 |
|
832 |
void hmp_block_stream(Monitor *mon, const QDict *qdict) |
833 |
{ |
834 |
Error *error = NULL;
|
835 |
const char *device = qdict_get_str(qdict, "device"); |
836 |
const char *base = qdict_get_try_str(qdict, "base"); |
837 |
|
838 |
qmp_block_stream(device, base != NULL, base, &error);
|
839 |
|
840 |
hmp_handle_error(mon, &error); |
841 |
} |
842 |
|
843 |
void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict) |
844 |
{ |
845 |
Error *error = NULL;
|
846 |
const char *device = qdict_get_str(qdict, "device"); |
847 |
int64_t value = qdict_get_int(qdict, "value");
|
848 |
|
849 |
qmp_block_job_set_speed(device, value, &error); |
850 |
|
851 |
hmp_handle_error(mon, &error); |
852 |
} |
853 |
|
854 |
void hmp_block_job_cancel(Monitor *mon, const QDict *qdict) |
855 |
{ |
856 |
Error *error = NULL;
|
857 |
const char *device = qdict_get_str(qdict, "device"); |
858 |
|
859 |
qmp_block_job_cancel(device, &error); |
860 |
|
861 |
hmp_handle_error(mon, &error); |
862 |
} |