qemu/qom/qom-qmp-cmds.c
<<
>>
Prefs
   1/*
   2 * QMP commands related to QOM
   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 "qemu/osdep.h"
  17#include "block/qdict.h"
  18#include "hw/qdev-core.h"
  19#include "qapi/error.h"
  20#include "qapi/qapi-commands-qdev.h"
  21#include "qapi/qapi-commands-qom.h"
  22#include "qapi/qapi-visit-qom.h"
  23#include "qapi/qmp/qdict.h"
  24#include "qapi/qmp/qerror.h"
  25#include "qapi/qobject-input-visitor.h"
  26#include "qapi/qobject-output-visitor.h"
  27#include "qemu/cutils.h"
  28#include "qom/object_interfaces.h"
  29#include "qom/qom-qobject.h"
  30
  31ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
  32{
  33    Object *obj;
  34    bool ambiguous = false;
  35    ObjectPropertyInfoList *props = NULL;
  36    ObjectProperty *prop;
  37    ObjectPropertyIterator iter;
  38
  39    obj = object_resolve_path(path, &ambiguous);
  40    if (obj == NULL) {
  41        if (ambiguous) {
  42            error_setg(errp, "Path '%s' is ambiguous", path);
  43        } else {
  44            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
  45                      "Device '%s' not found", path);
  46        }
  47        return NULL;
  48    }
  49
  50    object_property_iter_init(&iter, obj);
  51    while ((prop = object_property_iter_next(&iter))) {
  52        ObjectPropertyInfo *value = g_malloc0(sizeof(ObjectPropertyInfo));
  53
  54        QAPI_LIST_PREPEND(props, value);
  55
  56        value->name = g_strdup(prop->name);
  57        value->type = g_strdup(prop->type);
  58    }
  59
  60    return props;
  61}
  62
  63void qmp_qom_set(const char *path, const char *property, QObject *value,
  64                 Error **errp)
  65{
  66    Object *obj;
  67
  68    obj = object_resolve_path(path, NULL);
  69    if (!obj) {
  70        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
  71                  "Device '%s' not found", path);
  72        return;
  73    }
  74
  75    object_property_set_qobject(obj, property, value, errp);
  76}
  77
  78QObject *qmp_qom_get(const char *path, const char *property, Error **errp)
  79{
  80    Object *obj;
  81
  82    obj = object_resolve_path(path, NULL);
  83    if (!obj) {
  84        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
  85                  "Device '%s' not found", path);
  86        return NULL;
  87    }
  88
  89    return object_property_get_qobject(obj, property, errp);
  90}
  91
  92static void qom_list_types_tramp(ObjectClass *klass, void *data)
  93{
  94    ObjectTypeInfoList **pret = data;
  95    ObjectTypeInfo *info;
  96    ObjectClass *parent = object_class_get_parent(klass);
  97
  98    info = g_malloc0(sizeof(*info));
  99    info->name = g_strdup(object_class_get_name(klass));
 100    info->has_abstract = info->abstract = object_class_is_abstract(klass);
 101    if (parent) {
 102        info->has_parent = true;
 103        info->parent = g_strdup(object_class_get_name(parent));
 104    }
 105
 106    QAPI_LIST_PREPEND(*pret, info);
 107}
 108
 109ObjectTypeInfoList *qmp_qom_list_types(bool has_implements,
 110                                       const char *implements,
 111                                       bool has_abstract,
 112                                       bool abstract,
 113                                       Error **errp)
 114{
 115    ObjectTypeInfoList *ret = NULL;
 116
 117    module_load_qom_all();
 118    object_class_foreach(qom_list_types_tramp, implements, abstract, &ret);
 119
 120    return ret;
 121}
 122
 123ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
 124                                                Error **errp)
 125{
 126    ObjectClass *klass;
 127    Object *obj;
 128    ObjectProperty *prop;
 129    ObjectPropertyIterator iter;
 130    ObjectPropertyInfoList *prop_list = NULL;
 131
 132    klass = module_object_class_by_name(typename);
 133    if (klass == NULL) {
 134        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 135                  "Device '%s' not found", typename);
 136        return NULL;
 137    }
 138
 139    if (!object_class_dynamic_cast(klass, TYPE_DEVICE)
 140        || object_class_is_abstract(klass)) {
 141        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
 142                   "a non-abstract device type");
 143        return NULL;
 144    }
 145
 146    obj = object_new(typename);
 147
 148    object_property_iter_init(&iter, obj);
 149    while ((prop = object_property_iter_next(&iter))) {
 150        ObjectPropertyInfo *info;
 151
 152        /* Skip Object and DeviceState properties */
 153        if (strcmp(prop->name, "type") == 0 ||
 154            strcmp(prop->name, "realized") == 0 ||
 155            strcmp(prop->name, "hotpluggable") == 0 ||
 156            strcmp(prop->name, "hotplugged") == 0 ||
 157            strcmp(prop->name, "parent_bus") == 0) {
 158            continue;
 159        }
 160
 161        /* Skip legacy properties since they are just string versions of
 162         * properties that we already list.
 163         */
 164        if (strstart(prop->name, "legacy-", NULL)) {
 165            continue;
 166        }
 167
 168        info = g_new0(ObjectPropertyInfo, 1);
 169        info->name = g_strdup(prop->name);
 170        info->type = g_strdup(prop->type);
 171        info->has_description = !!prop->description;
 172        info->description = g_strdup(prop->description);
 173        info->default_value = qobject_ref(prop->defval);
 174        info->has_default_value = !!info->default_value;
 175
 176        QAPI_LIST_PREPEND(prop_list, info);
 177    }
 178
 179    object_unref(obj);
 180
 181    return prop_list;
 182}
 183
 184ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
 185                                             Error **errp)
 186{
 187    ObjectClass *klass;
 188    Object *obj = NULL;
 189    ObjectProperty *prop;
 190    ObjectPropertyIterator iter;
 191    ObjectPropertyInfoList *prop_list = NULL;
 192
 193    klass = object_class_by_name(typename);
 194    if (klass == NULL) {
 195        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 196                  "Class '%s' not found", typename);
 197        return NULL;
 198    }
 199
 200    if (!object_class_dynamic_cast(klass, TYPE_OBJECT)) {
 201        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
 202                   "a QOM type");
 203        return NULL;
 204    }
 205
 206    if (object_class_is_abstract(klass)) {
 207        object_class_property_iter_init(&iter, klass);
 208    } else {
 209        obj = object_new(typename);
 210        object_property_iter_init(&iter, obj);
 211    }
 212    while ((prop = object_property_iter_next(&iter))) {
 213        ObjectPropertyInfo *info;
 214
 215        info = g_malloc0(sizeof(*info));
 216        info->name = g_strdup(prop->name);
 217        info->type = g_strdup(prop->type);
 218        info->has_description = !!prop->description;
 219        info->description = g_strdup(prop->description);
 220
 221        QAPI_LIST_PREPEND(prop_list, info);
 222    }
 223
 224    object_unref(obj);
 225
 226    return prop_list;
 227}
 228
 229void qmp_object_add(ObjectOptions *options, Error **errp)
 230{
 231    user_creatable_add_qapi(options, errp);
 232}
 233
 234void qmp_object_del(const char *id, Error **errp)
 235{
 236    user_creatable_del(id, errp);
 237}
 238