summaryrefslogtreecommitdiffstats
path: root/hmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'hmp.c')
-rw-r--r--hmp.c124
1 files changed, 101 insertions, 23 deletions
diff --git a/hmp.c b/hmp.c
index cc2056e9e2..42bef84ed5 100644
--- a/hmp.c
+++ b/hmp.c
@@ -36,6 +36,7 @@
#include "qemu-io.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
+#include "hw/intc/intc.h"
#ifdef CONFIG_SPICE
#include <spice/enums.h>
@@ -787,6 +788,70 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
}
}
+static int hmp_info_irq_foreach(Object *obj, void *opaque)
+{
+ InterruptStatsProvider *intc;
+ InterruptStatsProviderClass *k;
+ Monitor *mon = opaque;
+
+ if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
+ intc = INTERRUPT_STATS_PROVIDER(obj);
+ k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
+ uint64_t *irq_counts;
+ unsigned int nb_irqs, i;
+ if (k->get_statistics &&
+ k->get_statistics(intc, &irq_counts, &nb_irqs)) {
+ if (nb_irqs > 0) {
+ monitor_printf(mon, "IRQ statistics for %s:\n",
+ object_get_typename(obj));
+ for (i = 0; i < nb_irqs; i++) {
+ if (irq_counts[i] > 0) {
+ monitor_printf(mon, "%2d: %" PRId64 "\n", i,
+ irq_counts[i]);
+ }
+ }
+ }
+ } else {
+ monitor_printf(mon, "IRQ statistics not available for %s.\n",
+ object_get_typename(obj));
+ }
+ }
+
+ return 0;
+}
+
+void hmp_info_irq(Monitor *mon, const QDict *qdict)
+{
+ object_child_foreach_recursive(object_get_root(),
+ hmp_info_irq_foreach, mon);
+}
+
+static int hmp_info_pic_foreach(Object *obj, void *opaque)
+{
+ InterruptStatsProvider *intc;
+ InterruptStatsProviderClass *k;
+ Monitor *mon = opaque;
+
+ if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
+ intc = INTERRUPT_STATS_PROVIDER(obj);
+ k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
+ if (k->print_info) {
+ k->print_info(intc, mon);
+ } else {
+ monitor_printf(mon, "Interrupt controller information not available for %s.\n",
+ object_get_typename(obj));
+ }
+ }
+
+ return 0;
+}
+
+void hmp_info_pic(Monitor *mon, const QDict *qdict)
+{
+ object_child_foreach_recursive(object_get_root(),
+ hmp_info_pic_foreach, mon);
+}
+
void hmp_info_pci(Monitor *mon, const QDict *qdict)
{
PciInfoList *info_list, *info;
@@ -1109,8 +1174,19 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
const char *format = qdict_get_try_str(qdict, "format");
bool reuse = qdict_get_try_bool(qdict, "reuse", false);
bool full = qdict_get_try_bool(qdict, "full", false);
- enum NewImageMode mode;
+ bool compress = qdict_get_try_bool(qdict, "compress", false);
Error *err = NULL;
+ DriveBackup backup = {
+ .device = (char *)device,
+ .target = (char *)filename,
+ .has_format = !!format,
+ .format = (char *)format,
+ .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
+ .has_mode = true,
+ .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
+ .has_compress = !!compress,
+ .compress = compress,
+ };
if (!filename) {
error_setg(&err, QERR_MISSING_PARAMETER, "target");
@@ -1118,16 +1194,7 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
return;
}
- if (reuse) {
- mode = NEW_IMAGE_MODE_EXISTING;
- } else {
- mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
- }
-
- qmp_drive_backup(false, NULL, device, filename, !!format, format,
- full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
- true, mode, false, 0, false, NULL,
- false, 0, false, 0, &err);
+ qmp_drive_backup(&backup, &err);
hmp_handle_error(mon, &err);
}
@@ -1374,7 +1441,7 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
const char *device = qdict_get_str(qdict, "device");
Error *err = NULL;
- qmp_eject(device, true, force, &err);
+ qmp_eject(true, device, false, NULL, true, force, &err);
hmp_handle_error(mon, &err);
}
@@ -1420,8 +1487,9 @@ void hmp_change(Monitor *mon, const QDict *qdict)
}
}
- qmp_blockdev_change_medium(device, target, !!arg, arg,
- !!read_only, read_only_mode, &err);
+ qmp_blockdev_change_medium(true, device, false, NULL, target,
+ !!arg, arg, !!read_only, read_only_mode,
+ &err);
if (err &&
error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
error_free(err);
@@ -1906,6 +1974,7 @@ void hmp_chardev_add(Monitor *mon, const QDict *qdict)
error_setg(&err, "Parsing chardev args failed");
} else {
qemu_chr_new_from_opts(opts, NULL, &err);
+ qemu_opts_del(opts);
}
hmp_handle_error(mon, &err);
}
@@ -1921,23 +1990,32 @@ void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
void hmp_qemu_io(Monitor *mon, const QDict *qdict)
{
BlockBackend *blk;
+ BlockBackend *local_blk = NULL;
+ AioContext *aio_context;
const char* device = qdict_get_str(qdict, "device");
const char* command = qdict_get_str(qdict, "command");
Error *err = NULL;
blk = blk_by_name(device);
- if (blk) {
- AioContext *aio_context = blk_get_aio_context(blk);
- aio_context_acquire(aio_context);
+ if (!blk) {
+ BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
+ if (bs) {
+ blk = local_blk = blk_new();
+ blk_insert_bs(blk, bs);
+ } else {
+ goto fail;
+ }
+ }
- qemuio_command(blk, command);
+ aio_context = blk_get_aio_context(blk);
+ aio_context_acquire(aio_context);
- aio_context_release(aio_context);
- } else {
- error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Device '%s' not found", device);
- }
+ qemuio_command(blk, command);
+
+ aio_context_release(aio_context);
+fail:
+ blk_unref(local_blk);
hmp_handle_error(mon, &err);
}