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_new0(ObjectPropertyInfo, 1);
  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->parent = g_strdup(object_class_get_name(parent));
 103    }
 104
 105    QAPI_LIST_PREPEND(*pret, info);
 106}
 107
 108ObjectTypeInfoList *qmp_qom_list_types(const char *implements,
 109                                       bool has_abstract,
 110                                       bool abstract,
 111                                       Error **errp)
 112{
 113    ObjectTypeInfoList *ret = NULL;
 114
 115    module_load_qom_all();
 116    object_class_foreach(qom_list_types_tramp, implements, abstract, &ret);
 117
 118    return ret;
 119}
 120
 121ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
 122                                                Error **errp)
 123{
 124    ObjectClass *klass;
 125    Object *obj;
 126    ObjectProperty *prop;
 127    ObjectPropertyIterator iter;
 128    ObjectPropertyInfoList *prop_list = NULL;
 129
 130    klass = module_object_class_by_name(typename);
 131    if (klass == NULL) {
 132        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 133                  "Device '%s' not found", typename);
 134        return NULL;
 135    }
 136
 137    if (!object_class_dynamic_cast(klass, TYPE_DEVICE)
 138        || object_class_is_abstract(klass)) {
 139        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
 140                   "a non-abstract device type");
 141        return NULL;
 142    }
 143
 144    obj = object_new(typename);
 145
 146    object_property_iter_init(&iter, obj);
 147    while ((prop = object_property_iter_next(&iter))) {
 148        ObjectPropertyInfo *info;
 149
 150        /* Skip Object and DeviceState properties */
 151        if (strcmp(prop->name, "type") == 0 ||
 152            strcmp(prop->name, "realized") == 0 ||
 153            strcmp(prop->name, "hotpluggable") == 0 ||
 154            strcmp(prop->name, "hotplugged") == 0 ||
 155            strcmp(prop->name, "parent_bus") == 0) {
 156            continue;
 157        }
 158
 159        /* Skip legacy properties since they are just string versions of
 160         * properties that we already list.
 161         */
 162        if (strstart(prop->name, "legacy-", NULL)) {
 163            continue;
 164        }
 165
 166        info = g_new0(ObjectPropertyInfo, 1);
 167        info->name = g_strdup(prop->name);
 168        info->type = g_strdup(prop->type);
 169        info->description = g_strdup(prop->description);
 170        info->default_value = qobject_ref(prop->defval);
 171
 172        QAPI_LIST_PREPEND(prop_list, info);
 173    }
 174
 175    object_unref(obj);
 176
 177    return prop_list;
 178}
 179
 180ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
 181                                             Error **errp)
 182{
 183    ObjectClass *klass;
 184    Object *obj = NULL;
 185    ObjectProperty *prop;
 186    ObjectPropertyIterator iter;
 187    ObjectPropertyInfoList *prop_list = NULL;
 188
 189    klass = object_class_by_name(typename);
 190    if (klass == NULL) {
 191        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 192                  "Class '%s' not found", typename);
 193        return NULL;
 194    }
 195
 196    if (!object_class_dynamic_cast(klass, TYPE_OBJECT)) {
 197        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
 198                   "a QOM type");
 199        return NULL;
 200    }
 201
 202    if (object_class_is_abstract(klass)) {
 203        object_class_property_iter_init(&iter, klass);
 204    } else {
 205        obj = object_new(typename);
 206        object_property_iter_init(&iter, obj);
 207    }
 208    while ((prop = object_property_iter_next(&iter))) {
 209        ObjectPropertyInfo *info;
 210
 211        info = g_malloc0(sizeof(*info));
 212        info->name = g_strdup(prop->name);
 213        info->type = g_strdup(prop->type);
 214        info->description = g_strdup(prop->description);
 215
 216        QAPI_LIST_PREPEND(prop_list, info);
 217    }
 218
 219    object_unref(obj);
 220
 221    return prop_list;
 222}
 223
 224void qmp_object_add(ObjectOptions *options, Error **errp)
 225{
 226    user_creatable_add_qapi(options, errp);
 227}
 228
 229void qmp_object_del(const char *id, Error **errp)
 230{
 231    user_creatable_del(id, errp);
 232}
 233