Conversion functions are used convert CPUModelInfo structs into
QMP JSON and the reverse.
QMP JSON is of form:
{"model": {"name": "IvyBridge", "props": {}}}
qemuMonitorCPUModelInfoBoolPropAdd is used to add boolean properties to
CPUModelInfo struct.
qemuMonitorJSONGetCPUModelExpansion makes full use of conversions and
propAdd in prep to support input of full cpu model in future.
Signed-off-by: Chris Venteicher <cventeic(a)redhat.com>
---
src/qemu/qemu_monitor.c | 24 ++++++
src/qemu/qemu_monitor.h | 5 ++
src/qemu/qemu_monitor_json.c | 154 +++++++++++++++++++++++++----------
3 files changed, 138 insertions(+), 45 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 5effc74736..ddf4d96799 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3764,6 +3764,30 @@ qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig)
}
+int
+qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
+ const char *prop_name,
+ bool prop_value)
+{
+ int ret = -1;
+ qemuMonitorCPUProperty prop;
+ prop.type = QEMU_MONITOR_CPU_PROPERTY_BOOLEAN;
+ prop.value.boolean = prop_value;
+
+ if (VIR_STRDUP(prop.name, prop_name) < 0)
+ goto cleanup;
+
+ if (VIR_APPEND_ELEMENT(model->props, model->nprops, prop) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(prop.name);
+ return ret;
+}
+
+
int
qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d486af201a..d0c54f60a9 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1047,6 +1047,11 @@ qemuMonitorCPUModelInfoPtr qemuMonitorCPUModelInfoNew(const char
*name);
qemuMonitorCPUModelInfoPtr
qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig);
+int qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
+ const char *prop_name,
+ bool prop_value)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
int qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands);
int qemuMonitorGetEvents(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 5a806f6c0e..abfa4155ee 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -5505,6 +5505,101 @@ qemuMonitorJSONParseCPUModelProperty(const char *key,
return 0;
}
+
+/* model_json: {"name": "z13-base", "props": {}}
+ */
+static virJSONValuePtr
+qemuMonitorJSONBuildCPUModelInfoToJSON(qemuMonitorCPUModelInfoPtr model)
+{
+ virJSONValuePtr cpu_props = NULL;
+ virJSONValuePtr model_json = NULL;
+ size_t i;
+
+ if (!model)
+ goto cleanup;
+
+ if (model->nprops > 0 && !(cpu_props = virJSONValueNewObject()))
+ goto cleanup;
+
+ for (i = 0; i < model->nprops; i++) {
+ qemuMonitorCPUPropertyPtr prop = &(model->props[i]);
+
+ switch (prop->type) {
+ case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
+ if (virJSONValueObjectAppendBoolean(cpu_props, prop->name,
+ prop->value.boolean) < 0)
+ goto cleanup;
+ break;
+
+ case QEMU_MONITOR_CPU_PROPERTY_STRING:
+ if (virJSONValueObjectAppendString(cpu_props, prop->name,
+ prop->value.string) < 0)
+ goto cleanup;
+ break;
+
+ case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
+ if (virJSONValueObjectAppendNumberLong(cpu_props, prop->name,
+ prop->value.number) < 0)
+ goto cleanup;
+ break;
+
+ case QEMU_MONITOR_CPU_PROPERTY_LAST:
+ default:
+ virReportEnumRangeError(qemuMonitorCPUPropertyPtr, prop->type);
+ goto cleanup;
+ }
+ }
+
+ ignore_value(virJSONValueObjectCreate(&model_json, "s:name",
model->name,
+ "A:props", &cpu_props, NULL));
+
+ cleanup:
+ virJSONValueFree(cpu_props);
+ return model_json;
+}
+
+
+/* model_json: {"name": "IvyBridge", "props": {}}
+ */
+static qemuMonitorCPUModelInfoPtr
+qemuMonitorJSONBuildCPUModelInfoFromJSON(virJSONValuePtr cpu_model)
+{
+ virJSONValuePtr cpu_props;
+ qemuMonitorCPUModelInfoPtr model = NULL;
+ qemuMonitorCPUModelInfoPtr ret = NULL;
+ char const *cpu_name;
+
+ if (!(cpu_name = virJSONValueObjectGetString(cpu_model, "name"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Parsed JSON reply missing 'name'"));
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC(model) < 0)
+ goto cleanup;
+
+ if (VIR_STRDUP(model->name, cpu_name) < 0)
+ goto cleanup;
+
+ if ((cpu_props = virJSONValueObjectGetObject(cpu_model, "props"))) {
+ if (VIR_ALLOC_N(model->props,
+ virJSONValueObjectKeysNumber(cpu_props)) < 0)
+ goto cleanup;
+
+ if (virJSONValueObjectForeachKeyValue(cpu_props,
+ qemuMonitorJSONParseCPUModelProperty,
+ model) < 0)
+ goto cleanup;
+ }
+
+ VIR_STEAL_PTR(ret, model);
+
+ cleanup:
+ qemuMonitorCPUModelInfoFree(model);
+
+ return ret;
+}
+
int
qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
qemuMonitorCPUModelExpansionType type,
@@ -5513,32 +5608,25 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
qemuMonitorCPUModelInfoPtr *model_info)
{
int ret = -1;
- virJSONValuePtr model = NULL;
- virJSONValuePtr props = NULL;
+ virJSONValuePtr json_model_in = NULL;
virJSONValuePtr cmd = NULL;
virJSONValuePtr reply = NULL;
virJSONValuePtr data;
virJSONValuePtr cpu_model;
- virJSONValuePtr cpu_props;
- qemuMonitorCPUModelInfoPtr machine_model = NULL;
- char const *cpu_name;
+ qemuMonitorCPUModelInfoPtr model_in = NULL;
const char *typeStr = "";
*model_info = NULL;
- if (!(model = virJSONValueNewObject()))
+ if (!(model_in = qemuMonitorCPUModelInfoNew(model_name)))
goto cleanup;
- if (virJSONValueObjectAppendString(model, "name", model_name) < 0)
+ if (!migratable &&
+ qemuMonitorCPUModelInfoBoolPropAdd(model_in, "migratable", false) <
0)
goto cleanup;
- if (!migratable) {
- if (!(props = virJSONValueNewObject()) ||
- virJSONValueObjectAppendBoolean(props, "migratable", false) < 0
||
- virJSONValueObjectAppend(model, "props", props) < 0)
- goto cleanup;
- props = NULL;
- }
+ if (!(json_model_in = qemuMonitorJSONBuildCPUModelInfoToJSON(model_in)))
+ goto cleanup;
retry:
switch (type) {
@@ -5554,7 +5642,7 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
if (!(cmd = qemuMonitorJSONMakeCommand("query-cpu-model-expansion",
"s:type", typeStr,
- "a:model", &model,
+ "a:model", &json_model_in,
NULL)))
goto cleanup;
@@ -5585,7 +5673,9 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
* on the result of the initial "static" expansion.
*/
if (type == QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC_FULL) {
- if (!(model = virJSONValueCopy(cpu_model)))
+ virJSONValueFree(json_model_in);
+
+ if (!(json_model_in = virJSONValueCopy(cpu_model)))
goto cleanup;
virJSONValueFree(cmd);
@@ -5594,42 +5684,16 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
goto retry;
}
- if (!(cpu_name = virJSONValueObjectGetString(cpu_model, "name"))) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("query-cpu-model-expansion reply data was missing
'name'"));
- goto cleanup;
- }
-
- if (!(cpu_props = virJSONValueObjectGetObject(cpu_model, "props"))) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("query-cpu-model-expansion reply data was missing
'props'"));
- goto cleanup;
- }
-
- if (VIR_ALLOC(machine_model) < 0)
- goto cleanup;
-
- if (VIR_STRDUP(machine_model->name, cpu_name) < 0)
- goto cleanup;
-
- if (VIR_ALLOC_N(machine_model->props, virJSONValueObjectKeysNumber(cpu_props))
< 0)
- goto cleanup;
-
- if (virJSONValueObjectForeachKeyValue(cpu_props,
- qemuMonitorJSONParseCPUModelProperty,
- machine_model) < 0)
+ if (!(*model_info = qemuMonitorJSONBuildCPUModelInfoFromJSON(cpu_model)))
goto cleanup;
ret = 0;
- *model_info = machine_model;
- machine_model = NULL;
cleanup:
- qemuMonitorCPUModelInfoFree(machine_model);
+ qemuMonitorCPUModelInfoFree(model_in);
virJSONValueFree(cmd);
virJSONValueFree(reply);
- virJSONValueFree(model);
- virJSONValueFree(props);
+ virJSONValueFree(json_model_in);
return ret;
}
--
2.17.1