qemu/qom/qom-hmp-cmds.c
<<
>>
Prefs
   1/*
   2 * HMP commands related to QOM
   3 *
   4 * This work is licensed under the terms of the GNU GPL, version 2 or
   5 * later.  See the COPYING file in the top-level directory.
   6 */
   7
   8#include "qemu/osdep.h"
   9#include "hw/qdev-core.h"
  10#include "monitor/hmp.h"
  11#include "monitor/monitor.h"
  12#include "qapi/error.h"
  13#include "qapi/qapi-commands-qom.h"
  14#include "qapi/qmp/qdict.h"
  15#include "qapi/qmp/qjson.h"
  16#include "qom/object.h"
  17
  18void hmp_qom_list(Monitor *mon, const QDict *qdict)
  19{
  20    const char *path = qdict_get_try_str(qdict, "path");
  21    ObjectPropertyInfoList *list;
  22    Error *err = NULL;
  23
  24    if (path == NULL) {
  25        monitor_printf(mon, "/\n");
  26        return;
  27    }
  28
  29    list = qmp_qom_list(path, &err);
  30    if (err == NULL) {
  31        ObjectPropertyInfoList *start = list;
  32        while (list != NULL) {
  33            ObjectPropertyInfo *value = list->value;
  34
  35            monitor_printf(mon, "%s (%s)\n",
  36                           value->name, value->type);
  37            list = list->next;
  38        }
  39        qapi_free_ObjectPropertyInfoList(start);
  40    }
  41    hmp_handle_error(mon, err);
  42}
  43
  44void hmp_qom_set(Monitor *mon, const QDict *qdict)
  45{
  46    const bool json = qdict_get_try_bool(qdict, "json", false);
  47    const char *path = qdict_get_str(qdict, "path");
  48    const char *property = qdict_get_str(qdict, "property");
  49    const char *value = qdict_get_str(qdict, "value");
  50    Error *err = NULL;
  51
  52    if (!json) {
  53        Object *obj = object_resolve_path(path, NULL);
  54
  55        if (!obj) {
  56            error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
  57                      "Device '%s' not found", path);
  58        } else {
  59            object_property_parse(obj, property, value, &err);
  60        }
  61    } else {
  62        QObject *obj = qobject_from_json(value, &err);
  63
  64        if (!err) {
  65            qmp_qom_set(path, property, obj, &err);
  66        }
  67    }
  68
  69    hmp_handle_error(mon, err);
  70}
  71
  72void hmp_qom_get(Monitor *mon, const QDict *qdict)
  73{
  74    const char *path = qdict_get_str(qdict, "path");
  75    const char *property = qdict_get_str(qdict, "property");
  76    Error *err = NULL;
  77    QObject *obj = qmp_qom_get(path, property, &err);
  78
  79    if (err == NULL) {
  80        GString *str = qobject_to_json_pretty(obj, true);
  81        monitor_printf(mon, "%s\n", str->str);
  82        g_string_free(str, true);
  83    }
  84
  85    qobject_unref(obj);
  86    hmp_handle_error(mon, err);
  87}
  88
  89typedef struct QOMCompositionState {
  90    Monitor *mon;
  91    int indent;
  92} QOMCompositionState;
  93
  94static void print_qom_composition(Monitor *mon, Object *obj, int indent);
  95
  96static int qom_composition_compare(const void *a, const void *b)
  97{
  98    return g_strcmp0(object_get_canonical_path_component(*(Object **)a),
  99                     object_get_canonical_path_component(*(Object **)b));
 100}
 101
 102static int insert_qom_composition_child(Object *obj, void *opaque)
 103{
 104    g_array_append_val(opaque, obj);
 105    return 0;
 106}
 107
 108static void print_qom_composition(Monitor *mon, Object *obj, int indent)
 109{
 110    GArray *children = g_array_new(false, false, sizeof(Object *));
 111    const char *name;
 112    int i;
 113
 114    if (obj == object_get_root()) {
 115        name = "";
 116    } else {
 117        name = object_get_canonical_path_component(obj);
 118    }
 119    monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name,
 120                   object_get_typename(obj));
 121
 122    object_child_foreach(obj, insert_qom_composition_child, children);
 123    g_array_sort(children, qom_composition_compare);
 124
 125    for (i = 0; i < children->len; i++) {
 126        print_qom_composition(mon, g_array_index(children, Object *, i),
 127                              indent + 2);
 128    }
 129    g_array_free(children, TRUE);
 130}
 131
 132void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
 133{
 134    const char *path = qdict_get_try_str(dict, "path");
 135    Object *obj;
 136    bool ambiguous = false;
 137
 138    if (path) {
 139        obj = object_resolve_path(path, &ambiguous);
 140        if (!obj) {
 141            monitor_printf(mon, "Path '%s' could not be resolved.\n", path);
 142            return;
 143        }
 144        if (ambiguous) {
 145            monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path);
 146            return;
 147        }
 148    } else {
 149        obj = qdev_get_machine();
 150    }
 151    print_qom_composition(mon, obj, 0);
 152}
 153