}
+int qemuMonitorJSONGetObjectListPaths(qemuMonitorPtr mon,
+ const char *path,
+ qemuMonitorJSONListPathPtr **paths)
+{
+ int ret;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr data;
+ qemuMonitorJSONListPathPtr *pathlist = NULL;
+ int n = 0;
+ size_t i;
+
+ *paths = NULL;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("qom-list",
+ "s:path", path,
+ 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-list reply was missing return data"));
+ goto cleanup;
+ }
+
+ if ((n = virJSONValueArraySize(data)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qom-list reply data was not an array"));
+ goto cleanup;
+ }
+
+ /* null-terminated list */
+ if (VIR_ALLOC_N(pathlist, n + 1) < 0)
+ goto cleanup;
+
+ for (i = 0; i < n; i++) {
+ virJSONValuePtr child = virJSONValueArrayGet(data, i);
+ const char *tmp;
+ qemuMonitorJSONListPathPtr info;
+
+ if (VIR_ALLOC(info) < 0)
+ goto cleanup;
+
+ pathlist[i] = info;
+
+ if (!(tmp = virJSONValueObjectGetString(child, "name"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qom-list reply data was missing 'name'"));
+ goto cleanup;
+ }
+
+ if (VIR_STRDUP(info->name, tmp) < 0)
+ goto cleanup;
+
+ if (virJSONValueObjectHasKey(child, "type")) {
+ if (!(tmp = virJSONValueObjectGetString(child, "type"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qom-list reply has malformed 'type' data"));
+ goto cleanup;
+ }
+ if (VIR_STRDUP(info->type, tmp) < 0)
+ goto cleanup;
+ }
+ }
+
+ ret = n;
+ *paths = pathlist;
+
+cleanup:
+ if (ret < 0 && pathlist) {
+ for (i = 0; i < n; i++)
+ qemuMonitorJSONListPathFree(pathlist[i]);
+ VIR_FREE(pathlist);
+ }
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
+void qemuMonitorJSONListPathFree(qemuMonitorJSONListPathPtr paths)
+{
+ if (!paths)
+ return;
+ VIR_FREE(paths->name);
+ VIR_FREE(paths->type);
+ VIR_FREE(paths);
+}
+
int qemuMonitorJSONGetObjectProps(qemuMonitorPtr mon,
const char *type,
char ***props)
int qemuMonitorJSONGetObjectTypes(qemuMonitorPtr mon,
char ***types)
ATTRIBUTE_NONNULL(2);
+
+/* ListPath structures and API's are public only for qemumonitorjsontest */
+typedef struct _qemuMonitorJSONListPath qemuMonitorJSONListPath;
+typedef qemuMonitorJSONListPath *qemuMonitorJSONListPathPtr;
+
+struct _qemuMonitorJSONListPath {
+ char *name;
+ char *type;
+};
+
+int qemuMonitorJSONGetObjectListPaths(qemuMonitorPtr mon,
+ const char *path,
+ qemuMonitorJSONListPathPtr **paths)
+ ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
+void qemuMonitorJSONListPathFree(qemuMonitorJSONListPathPtr paths);
+
int qemuMonitorJSONGetObjectProps(qemuMonitorPtr mon,
const char *type,
char ***props)
#include "testutilsqemu.h"
#include "qemumonitortestutils.h"
#include "qemu/qemu_conf.h"
+#include "qemu/qemu_monitor_json.h"
#include "virthread.h"
#include "virerror.h"
#include "virstring.h"
return ret;
}
+/*
+ * This test will request to return a list of paths for "/". It should be
+ * a simple list of 1 real element that being the "machine". The following
+ * is the execution and expected return:
+ *
+ * {"execute":"qom-list", "arguments": { "path": "/"}}"
+ * {"return": [{"name": "machine", "type": "child<container>"}, \
+ * {"name": "type", "type": "string"}]}
+ */
+static int
+testQemuMonitorJSONGetListPaths(const void *data)
+{
+ const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
+ qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt);
+ int ret = -1;
+ qemuMonitorJSONListPathPtr *paths;
+ int npaths = 0;
+ size_t i;
+
+ if (!test)
+ return -1;
+
+ if (qemuMonitorTestAddItem(test, "qom-list",
+ "{ "
+ " \"return\": [ "
+ " {\"name\": \"machine\", "
+ " \"type\": \"child<container>\"}, "
+ " {\"name\": \"type\", "
+ " \"type\": \"string\"} "
+ " ]"
+ "}") < 0)
+ goto cleanup;
+
+ /* present with path */
+ if ((npaths = qemuMonitorJSONGetObjectListPaths(
+ qemuMonitorTestGetMonitor(test),
+ "/",
+ &paths)) < 0)
+ goto cleanup;
+
+ if (npaths != 2) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "npaths was %d, expected 1", npaths);
+ goto cleanup;
+ }
+
+#define CHECK(i, wantname, wanttype) \
+ do { \
+ if (STRNEQ(paths[i]->name, (wantname))) { \
+ virReportError(VIR_ERR_INTERNAL_ERROR, \
+ "name was %s, expected %s", \
+ paths[i]->name, (wantname)); \
+ goto cleanup; \
+ } \
+ if (STRNEQ_NULLABLE(paths[i]->type, (wanttype))) { \
+ virReportError(VIR_ERR_INTERNAL_ERROR, \
+ "type was %s, expected %s", \
+ NULLSTR(paths[i]->type), (wanttype)); \
+ goto cleanup; \
+ } \
+ } while (0)
+
+ CHECK(0, "machine", "child<container>");
+
+#undef CHECK
+
+ ret = 0;
+
+cleanup:
+ qemuMonitorTestFree(test);
+ for (i = 0; i < npaths; i++)
+ qemuMonitorJSONListPathFree(paths[i]);
+ VIR_FREE(paths);
+ return ret;
+}
+
+
static int
mymain(void)
{
DO_TEST(GetCommandLineOptionParameters);
DO_TEST(AttachChardev);
DO_TEST(DetachChardev);
+ DO_TEST(GetListPaths);
virObjectUnref(xmlopt);