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