X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=qmp.c;h=4c149b33a459af7d3cb8da25c057298d9fd6fdcf;hb=60aad298cb6de52f2716b2e82e1353ea9de95fd6;hp=45052cc9781f5d852e8ac78261d31518bd4ea5e2;hpb=cb437e48ab7ddd9b85843beb524904ee4b565721;p=qemu.git diff --git a/qmp.c b/qmp.c index 45052cc97..4c149b33a 100644 --- a/qmp.c +++ b/qmp.c @@ -14,16 +14,17 @@ */ #include "qemu-common.h" -#include "sysemu.h" +#include "sysemu/sysemu.h" #include "qmp-commands.h" +#include "sysemu/char.h" #include "ui/qemu-spice.h" #include "ui/vnc.h" -#include "kvm.h" -#include "arch_init.h" +#include "sysemu/kvm.h" +#include "sysemu/arch_init.h" #include "hw/qdev.h" -#include "qapi/qmp-input-visitor.h" -#include "qapi/qmp-output-visitor.h" -#include "blockdev.h" +#include "sysemu/blockdev.h" +#include "qom/qom-qobject.h" +#include "hw/boards.h" NameInfo *qmp_query_name(Error **errp) { @@ -86,7 +87,11 @@ void qmp_quit(Error **err) void qmp_stop(Error **errp) { - vm_stop(RUN_STATE_PAUSED); + if (runstate_check(RUN_STATE_INMIGRATE)) { + autostart = 0; + } else { + vm_stop(RUN_STATE_PAUSED); + } } void qmp_system_reset(Error **errp) @@ -104,6 +109,15 @@ void qmp_cpu(int64_t index, Error **errp) /* Just do nothing */ } +void qmp_cpu_add(int64_t id, Error **errp) +{ + if (current_machine->hot_add_cpu) { + current_machine->hot_add_cpu(id, errp); + } else { + error_setg(errp, "Not supported"); + } +} + #ifndef CONFIG_VNC /* If VNC support is enabled, the "true" query-vnc command is defined in the VNC subsystem */ @@ -145,13 +159,11 @@ void qmp_cont(Error **errp) { Error *local_err = NULL; - if (runstate_check(RUN_STATE_INMIGRATE)) { - error_set(errp, QERR_MIGRATION_EXPECTED); - return; - } else if (runstate_check(RUN_STATE_INTERNAL_ERROR) || - runstate_check(RUN_STATE_SHUTDOWN)) { + if (runstate_needs_reset()) { error_set(errp, QERR_RESET_REQUIRED); return; + } else if (runstate_check(RUN_STATE_SUSPENDED)) { + return; } bdrv_iterate(iostatus_bdrv_it, NULL); @@ -161,7 +173,16 @@ void qmp_cont(Error **errp) return; } - vm_start(); + if (runstate_check(RUN_STATE_INMIGRATE)) { + autostart = 1; + } else { + vm_start(); + } +} + +void qmp_system_wakeup(Error **errp) +{ + qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); } ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp) @@ -198,7 +219,6 @@ int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret) const char *property = qdict_get_str(qdict, "property"); QObject *value = qdict_get(qdict, "value"); Error *local_err = NULL; - QmpInputVisitor *mi; Object *obj; obj = object_resolve_path(path, NULL); @@ -207,10 +227,7 @@ int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret) goto out; } - mi = qmp_input_visitor_new(value); - object_property_set(obj, qmp_input_get_visitor(mi), property, &local_err); - - qmp_input_visitor_cleanup(mi); + object_property_set_qobject(obj, value, property, &local_err); out: if (local_err) { @@ -227,7 +244,6 @@ int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret) const char *path = qdict_get_str(qdict, "path"); const char *property = qdict_get_str(qdict, "property"); Error *local_err = NULL; - QmpOutputVisitor *mo; Object *obj; obj = object_resolve_path(path, NULL); @@ -236,13 +252,7 @@ int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret) goto out; } - mo = qmp_output_visitor_new(); - object_property_get(obj, qmp_output_get_visitor(mo), property, &local_err); - if (!local_err) { - *ret = qmp_output_get_qobject(mo); - } - - qmp_output_visitor_cleanup(mo); + *ret = object_property_get_qobject(obj, property, &local_err); out: if (local_err) { @@ -354,11 +364,9 @@ void qmp_change_vnc_password(const char *password, Error **errp) } } -static void qmp_change_vnc_listen(const char *target, Error **err) +static void qmp_change_vnc_listen(const char *target, Error **errp) { - if (vnc_display_open(NULL, target) < 0) { - error_set(err, QERR_VNC_SERVER_FAILED, target); - } + vnc_display_open(NULL, target, errp); } static void qmp_change_vnc(const char *target, bool has_arg, const char *arg, @@ -422,3 +430,102 @@ ObjectTypeInfoList *qmp_qom_list_types(bool has_implements, return ret; } + +DevicePropertyInfoList *qmp_device_list_properties(const char *typename, + Error **errp) +{ + ObjectClass *klass; + Property *prop; + DevicePropertyInfoList *prop_list = NULL; + + klass = object_class_by_name(typename); + if (klass == NULL) { + error_set(errp, QERR_DEVICE_NOT_FOUND, typename); + return NULL; + } + + klass = object_class_dynamic_cast(klass, TYPE_DEVICE); + if (klass == NULL) { + error_set(errp, QERR_INVALID_PARAMETER_VALUE, + "name", TYPE_DEVICE); + return NULL; + } + + do { + for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) { + DevicePropertyInfoList *entry; + DevicePropertyInfo *info; + + /* + * TODO Properties without a parser are just for dirty hacks. + * qdev_prop_ptr is the only such PropertyInfo. It's marked + * for removal. This conditional should be removed along with + * it. + */ + if (!prop->info->set) { + continue; /* no way to set it, don't show */ + } + + info = g_malloc0(sizeof(*info)); + info->name = g_strdup(prop->name); + info->type = g_strdup(prop->info->legacy_name ?: prop->info->name); + + entry = g_malloc0(sizeof(*entry)); + entry->value = info; + entry->next = prop_list; + prop_list = entry; + } + klass = object_class_get_parent(klass); + } while (klass != object_class_by_name(TYPE_DEVICE)); + + return prop_list; +} + +CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +{ + return arch_query_cpu_definitions(errp); +} + +void qmp_add_client(const char *protocol, const char *fdname, + bool has_skipauth, bool skipauth, bool has_tls, bool tls, + Error **errp) +{ + CharDriverState *s; + int fd; + + fd = monitor_get_fd(cur_mon, fdname, errp); + if (fd < 0) { + return; + } + + if (strcmp(protocol, "spice") == 0) { + if (!using_spice) { + error_set(errp, QERR_DEVICE_NOT_ACTIVE, "spice"); + close(fd); + return; + } + skipauth = has_skipauth ? skipauth : false; + tls = has_tls ? tls : false; + if (qemu_spice_display_add_client(fd, skipauth, tls) < 0) { + error_setg(errp, "spice failed to add client"); + close(fd); + } + return; +#ifdef CONFIG_VNC + } else if (strcmp(protocol, "vnc") == 0) { + skipauth = has_skipauth ? skipauth : false; + vnc_display_add_client(NULL, fd, skipauth); + return; +#endif + } else if ((s = qemu_chr_find(protocol)) != NULL) { + if (qemu_chr_add_client(s, fd) < 0) { + error_setg(errp, "failed to add client"); + close(fd); + return; + } + return; + } + + error_setg(errp, "protocol '%s' is invalid", protocol); + close(fd); +}