X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=qmp.c;h=f556a04d1981f7424d01c48c39168c5f9573a11e;hb=3d1140bf3e73e4fd244914bdf2867fe634759c71;hp=be63fe10296b31e25064882bb1c896d1e7b9f8b8;hpb=9c17d615a66ebd655871bf891ec0fe901ad8b332;p=mirror_qemu.git diff --git a/qmp.c b/qmp.c index be63fe1029..f556a04d19 100644 --- a/qmp.c +++ b/qmp.c @@ -16,7 +16,7 @@ #include "qemu-common.h" #include "sysemu/sysemu.h" #include "qmp-commands.h" -#include "qemu-char.h" +#include "sysemu/char.h" #include "ui/qemu-spice.h" #include "ui/vnc.h" #include "sysemu/kvm.h" @@ -24,6 +24,10 @@ #include "hw/qdev.h" #include "sysemu/blockdev.h" #include "qom/qom-qobject.h" +#include "qapi/qmp/qobject.h" +#include "qapi/qmp-input-visitor.h" +#include "hw/boards.h" +#include "qom/object_interfaces.h" NameInfo *qmp_query_name(Error **errp) { @@ -108,6 +112,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 */ @@ -149,8 +162,7 @@ void qmp_cont(Error **errp) { Error *local_err = NULL; - 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)) { @@ -391,7 +403,7 @@ void qmp_change(const char *device, const char *target, if (strcmp(device, "vnc") == 0) { qmp_change_vnc(target, has_arg, arg, err); } else { - qmp_change_blockdev(device, target, has_arg, arg, err); + qmp_change_blockdev(device, target, arg, err); } } @@ -520,3 +532,90 @@ void qmp_add_client(const char *protocol, const char *fdname, error_setg(errp, "protocol '%s' is invalid", protocol); close(fd); } + +void object_add(const char *type, const char *id, const QDict *qdict, + Visitor *v, Error **errp) +{ + Object *obj; + const QDictEntry *e; + Error *local_err = NULL; + + if (!object_class_by_name(type)) { + error_setg(errp, "invalid class name"); + return; + } + + obj = object_new(type); + if (qdict) { + for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) { + object_property_set(obj, v, e->key, &local_err); + if (local_err) { + goto out; + } + } + } + + if (!object_dynamic_cast(obj, TYPE_USER_CREATABLE)) { + error_setg(&local_err, "object type '%s' isn't supported by object-add", + type); + goto out; + } + + user_creatable_complete(obj, &local_err); + if (local_err) { + goto out; + } + + object_property_add_child(container_get(object_get_root(), "/objects"), + id, obj, &local_err); +out: + if (local_err) { + error_propagate(errp, local_err); + } + object_unref(obj); +} + +int qmp_object_add(Monitor *mon, const QDict *qdict, QObject **ret) +{ + const char *type = qdict_get_str(qdict, "qom-type"); + const char *id = qdict_get_str(qdict, "id"); + QObject *props = qdict_get(qdict, "props"); + const QDict *pdict = NULL; + Error *local_err = NULL; + QmpInputVisitor *qiv; + + if (props) { + pdict = qobject_to_qdict(props); + if (!pdict) { + error_set(&local_err, QERR_INVALID_PARAMETER_TYPE, "props", "dict"); + goto out; + } + } + + qiv = qmp_input_visitor_new(props); + object_add(type, id, pdict, qmp_input_get_visitor(qiv), &local_err); + qmp_input_visitor_cleanup(qiv); + +out: + if (local_err) { + qerror_report_err(local_err); + error_free(local_err); + return -1; + } + + return 0; +} + +void qmp_object_del(const char *id, Error **errp) +{ + Object *container; + Object *obj; + + container = container_get(object_get_root(), "/objects"); + obj = object_resolve_path_component(container, id); + if (!obj) { + error_setg(errp, "object id not found"); + return; + } + object_unparent(obj); +}