Add qemuMonitorJSONGetObjectProperty() method for QMP qom-get command

Add a new qemuMonitorJSONGetObjectProperty() method to support invocation
of the 'qom-get' JSON monitor command with a provided path, property, and
expected data type return. The qemuMonitorJSONObjectProperty is similar to
virTypedParameter; however, a future patch will extend it a bit to include
a void pointer to balloon driver statistic data.

NOTE: The ObjectProperty structures and API are added only for the
      purpose of the qemumonitorjsontest

The provided test will execute a qom-get on "/machine/i440fx" which will
return a property "realized".
This commit is contained in:
John Ferlan 2013-07-03 14:15:07 -04:00
parent d76a89780b
commit bdce278984
3 changed files with 169 additions and 0 deletions

View File

@ -4605,6 +4605,92 @@ void qemuMonitorJSONListPathFree(qemuMonitorJSONListPathPtr paths)
VIR_FREE(paths);
}
int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon,
const char *path,
const char *property,
qemuMonitorJSONObjectPropertyPtr prop)
{
int ret;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
virJSONValuePtr data;
const char *tmp;
if (!(cmd = qemuMonitorJSONMakeCommand("qom-get",
"s:path", path,
"s:property", property,
NULL)))
return -1;
ret = qemuMonitorJSONCommand(mon, cmd, &reply);
if (ret == 0)
ret = qemuMonitorJSONCheckError(cmd, reply);
if (ret < 0)
goto cleanup;
ret = -1;
if (!(data = virJSONValueObjectGet(reply, "return"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("qom-get reply was missing return data"));
goto cleanup;
}
switch ((qemuMonitorJSONObjectPropertyType) prop->type) {
/* Simple cases of boolean, int, long, uint, ulong, double, and string
* will receive return value as part of {"return": xxx} statement
*/
case QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN:
ret = virJSONValueGetBoolean(data, &prop->val.b);
break;
case QEMU_MONITOR_OBJECT_PROPERTY_INT:
ret = virJSONValueGetNumberInt(data, &prop->val.iv);
break;
case QEMU_MONITOR_OBJECT_PROPERTY_LONG:
ret = virJSONValueGetNumberLong(data, &prop->val.l);
break;
case QEMU_MONITOR_OBJECT_PROPERTY_UINT:
ret = virJSONValueGetNumberUint(data, &prop->val.ui);
break;
case QEMU_MONITOR_OBJECT_PROPERTY_ULONG:
ret = virJSONValueGetNumberUlong(data, &prop->val.ul);
break;
case QEMU_MONITOR_OBJECT_PROPERTY_DOUBLE:
ret = virJSONValueGetNumberDouble(data, &prop->val.d);
break;
case QEMU_MONITOR_OBJECT_PROPERTY_STRING:
tmp = virJSONValueGetString(data);
if (tmp && VIR_STRDUP(prop->val.str, tmp) < 0)
goto cleanup;
if (tmp)
ret = 0;
break;
case QEMU_MONITOR_OBJECT_PROPERTY_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("qom-get invalid object property type %d"),
prop->type);
goto cleanup;
break;
}
if (ret == -1) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("qom-get reply was missing return data"));
goto cleanup;
}
ret = 0;
cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
}
int qemuMonitorJSONGetObjectProps(qemuMonitorPtr mon,
const char *type,
char ***props)

View File

@ -349,6 +349,41 @@ int qemuMonitorJSONGetObjectListPaths(qemuMonitorPtr mon,
void qemuMonitorJSONListPathFree(qemuMonitorJSONListPathPtr paths);
/* ObjectProperty structures and API are public only for qemumonitorjsontest */
/* Flags for the 'type' field in _qemuMonitorJSONObjectProperty */
typedef enum {
QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN=1,
QEMU_MONITOR_OBJECT_PROPERTY_INT,
QEMU_MONITOR_OBJECT_PROPERTY_LONG,
QEMU_MONITOR_OBJECT_PROPERTY_UINT,
QEMU_MONITOR_OBJECT_PROPERTY_ULONG,
QEMU_MONITOR_OBJECT_PROPERTY_DOUBLE,
QEMU_MONITOR_OBJECT_PROPERTY_STRING,
QEMU_MONITOR_OBJECT_PROPERTY_LAST
} qemuMonitorJSONObjectPropertyType;
typedef struct _qemuMonitorJSONObjectProperty qemuMonitorJSONObjectProperty;
typedef qemuMonitorJSONObjectProperty *qemuMonitorJSONObjectPropertyPtr;
struct _qemuMonitorJSONObjectProperty {
int type; /* qemuMonitorJSONObjectPropertyType */
union {
bool b;
int iv;
long long l;
unsigned int ui;
unsigned long long ul;
double d;
char *str;
} val;
};
int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon,
const char *path,
const char *property,
qemuMonitorJSONObjectPropertyPtr prop)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
int qemuMonitorJSONGetObjectProps(qemuMonitorPtr mon,
const char *type,
char ***props)

View File

@ -777,6 +777,53 @@ cleanup:
}
/*
* This test will use a path to /machine/i440fx which should exist in order
* to ensure that the qom-get property fetch works properly. The following
* is the execution and expected return:
*
*
* { "execute": "qom-get","arguments": \
* { "path": "/machine/i440fx","property": "realized"}}
* {"return": true}
*/
static int
testQemuMonitorJSONGetObjectProperty(const void *data)
{
const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt);
int ret = -1;
qemuMonitorJSONObjectProperty prop;
if (!test)
return -1;
if (qemuMonitorTestAddItem(test, "qom-get",
"{ \"return\": true }") < 0)
goto cleanup;
/* Present with path and property */
memset(&prop, 0, sizeof(qemuMonitorJSONObjectProperty));
prop.type = QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN;
if (qemuMonitorJSONGetObjectProperty(qemuMonitorTestGetMonitor(test),
"/machine/i440fx",
"realized",
&prop) < 0)
goto cleanup;
if (!prop.val.b) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
"expected true, but false returned");
goto cleanup;
}
ret = 0;
cleanup:
qemuMonitorTestFree(test);
return ret;
}
static int
mymain(void)
{
@ -808,6 +855,7 @@ mymain(void)
DO_TEST(AttachChardev);
DO_TEST(DetachChardev);
DO_TEST(GetListPaths);
DO_TEST(GetObjectProperty);
virObjectUnref(xmlopt);