[libvirt] [PATCH 21/24] qemu: Introduce generic qemuMonitorGetGuestCPU
Ján Tomko
jtomko at redhat.com
Wed Jun 19 12:32:36 UTC 2019
On Wed, Jun 19, 2019 at 11:38:18AM +0200, Jiri Denemark wrote:
>Unlike the old version (which is now called qemuMonitorGetGuestCPUx86),
>this monitor API checks for individual features by their names rather
>than processing CPUID bits. Thus we can get the list of enabled and
>disabled features for both CPUID and MSR features.
>
>Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
>---
> src/qemu/qemu_monitor.c | 36 ++++++
> src/qemu/qemu_monitor.h | 10 ++
> src/qemu/qemu_monitor_json.c | 211 +++++++++++++++++++++++++++++++++++
> src/qemu/qemu_monitor_json.h | 7 ++
> 4 files changed, 264 insertions(+)
>
>diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
>index 344aac09f0..99aadba2e2 100644
>--- a/src/qemu/qemu_monitor.c
>+++ b/src/qemu/qemu_monitor.c
>@@ -4107,6 +4107,42 @@ qemuMonitorGetGuestCPUx86(qemuMonitorPtr mon,
> }
>
>
>+/**
>+ * qemuMonitorGetGuestCPU:
>+ * @mon: Pointer to the monitor
>+ * @arch: CPU architecture
>+ * @translate: callback for translating CPU feature names from QEMU to libvirt
>+ * @opaque: data for @translate callback
>+ * @enabled: returns the CPU data for all enabled features
>+ * @disabled: returns the CPU data for features which we asked for
>+ * (either explicitly or via a named CPU model) but QEMU disabled them
>+ *
>+ * Retrieve the definition of the guest CPU from a running QEMU instance.
>+ *
>+ * Returns 0 on success, -1 on error.
>+ */
>+int
>+qemuMonitorGetGuestCPU(qemuMonitorPtr mon,
>+ virArch arch,
>+ qemuMonitorCPUFeatureTranslationCallback translate,
>+ void *opaque,
>+ virCPUDataPtr *enabled,
>+ virCPUDataPtr *disabled)
>+{
>+ VIR_DEBUG("arch=%s translate=%p opaque=%p enabled=%p disabled=%p",
>+ virArchToString(arch), translate, opaque, enabled, disabled);
>+
>+ QEMU_CHECK_MONITOR(mon);
>+
>+ *enabled = NULL;
>+ if (disabled)
>+ *disabled = NULL;
>+
>+ return qemuMonitorJSONGetGuestCPU(mon, arch, translate, opaque,
Hehe, "monarch".
>+ enabled, disabled);
>+}
>+
>+
> /**
> * qemuMonitorRTCResetReinjection:
> * @mon: Pointer to the monitor
>diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
>index ac2499c22a..f5be74f461 100644
>--- a/src/qemu/qemu_monitor.h
>+++ b/src/qemu/qemu_monitor.h
>@@ -1154,6 +1154,16 @@ int qemuMonitorGetGuestCPUx86(qemuMonitorPtr mon,
> virCPUDataPtr *data,
> virCPUDataPtr *disabled);
>
>+typedef const char *(*qemuMonitorCPUFeatureTranslationCallback)(const char *name,
>+ void *opaque);
>+
>+int qemuMonitorGetGuestCPU(qemuMonitorPtr mon,
>+ virArch arch,
>+ qemuMonitorCPUFeatureTranslationCallback translate,
>+ void *opaque,
>+ virCPUDataPtr *enabled,
>+ virCPUDataPtr *disabled);
>+
> int qemuMonitorRTCResetReinjection(qemuMonitorPtr mon);
>
> typedef struct _qemuMonitorIOThreadInfo qemuMonitorIOThreadInfo;
>diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
>index efcef211ed..1662e47301 100644
>--- a/src/qemu/qemu_monitor_json.c
>+++ b/src/qemu/qemu_monitor_json.c
>@@ -6137,6 +6137,64 @@ int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon,
> }
>
>
>+static int
>+qemuMonitorJSONGetStringListProperty(qemuMonitorPtr mon,
>+ const char *path,
>+ const char *property,
>+ char ***strList)
>+{
>+ virJSONValuePtr cmd;
>+ virJSONValuePtr reply = NULL;
VIR_AUTOPTR(virJSONValue) cmd = NULL;
VIR_AUTOPTR(virJSONValue) reply = NULL;
>+ virJSONValuePtr data;
>+ char **list = NULL;
VIR_AUTOSTRINGLIST list = NULL;
>+ size_t n;
>+ size_t i;
>+ int ret = -1;
>+
>+ *strList = NULL;
>+
>+ if (!(cmd = qemuMonitorJSONMakeCommand("qom-get",
>+ "s:path", path,
>+ "s:property", property,
>+ NULL)))
>+ return -1;
>+
>+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
>+ goto cleanup;
>+
>+ if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0)
>+ goto cleanup;
>+
>+ data = virJSONValueObjectGetArray(reply, "return");
>+ n = virJSONValueArraySize(data);
>+
>+ if (VIR_ALLOC_N(list, n + 1) < 0)
>+ goto cleanup;
>+
>+ for (i = 0; i < n; i++) {
>+ virJSONValuePtr item = virJSONValueArrayGet(data, i);
>+
>+ if (virJSONValueGetType(item) != VIR_JSON_TYPE_STRING) {
>+ virReportError(VIR_ERR_INTERNAL_ERROR,
>+ _("unexpected value in %s array"), property);
>+ goto cleanup;
>+ }
>+
>+ if (VIR_STRDUP(list[i], virJSONValueGetString(item)) < 0)
>+ goto cleanup;
>+ }
>+
>+ VIR_STEAL_PTR(*strList, list);
>+ ret = n;
>+
>+ cleanup:
>+ virJSONValueFree(cmd);
>+ virJSONValueFree(reply);
>+ virStringListFree(list);
>+ return ret;
>+}
>+
>+
> #define MAKE_SET_CMD(STRING, VALUE) \
> cmd = qemuMonitorJSONMakeCommand("qom-set", \
> "s:path", path, \
>@@ -7369,6 +7427,159 @@ qemuMonitorJSONGetGuestCPUx86(qemuMonitorPtr mon,
> return -1;
> }
>
>+
>+static int
>+qemuMonitorJSONGetCPUProperties(qemuMonitorPtr mon,
>+ char ***props)
>+{
>+ virJSONValuePtr cmd;
>+ virJSONValuePtr reply = NULL;
VIR_AUTOPTR(virJSONValue) cmd = NULL;
VIR_AUTOPTR(virJSONValue) reply = NULL;
>+ int ret = -1;
>+
>+ *props = NULL;
>+
>+ if (!(cmd = qemuMonitorJSONMakeCommand("qom-list",
>+ "s:path", QOM_CPU_PATH,
>+ NULL)))
>+ return -1;
>+
>+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
>+ goto cleanup;
>+
>+ if (qemuMonitorJSONHasError(reply, "DeviceNotFound")) {
Shouldn't this be a hard error? IIUC this will be called only for QEMUs
which do have the capability.
On the other hand, ignoring a missing device is consistent with other
GetProperties helpers.
>+ ret = 0;
>+ goto cleanup;
>+ }
>+
>+ ret = qemuMonitorJSONParsePropsList(cmd, reply, "bool", props);
>+
>+ cleanup:
>+ virJSONValueFree(reply);
>+ virJSONValueFree(cmd);
>+ return ret;
>+}
>+
>+
>+static int
>+qemuMonitorJSONGetCPUData(qemuMonitorPtr mon,
>+ qemuMonitorCPUFeatureTranslationCallback translate,
>+ void *opaque,
>+ virCPUDataPtr data)
>+{
>+ qemuMonitorJSONObjectProperty prop = { .type = QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN };
>+ char **props;
VIR_AUTOSTRINGLIST props = NULL;
>+ char **p;
>+ int ret = -1;
>+
>+ if (qemuMonitorJSONGetCPUProperties(mon, &props) < 0)
>+ goto cleanup;
>+
>+ for (p = props; p && *p; p++) {
>+ const char *name = *p;
>+
>+ if (qemuMonitorJSONGetObjectProperty(mon, QOM_CPU_PATH, name, &prop) < 0)
>+ goto cleanup;
>+
>+ if (!prop.val.b)
>+ continue;
>+
>+ if (translate)
>+ name = translate(name, opaque);
>+
>+ if (virCPUDataAddFeature(data, name) < 0)
>+ goto cleanup;
>+ }
>+
>+ ret = 0;
>+
>+ cleanup:
>+ virStringListFree(props);
>+ return ret;
>+}
>+
>+
>+static int
>+qemuMonitorJSONGetCPUDataDisabled(qemuMonitorPtr mon,
>+ qemuMonitorCPUFeatureTranslationCallback translate,
>+ void *opaque,
>+ virCPUDataPtr data)
>+{
>+ char **props;
VIR_AUTOSTRINGLIST props = NULL;
>+ char **p;
>+ int ret = -1;
>+
>+ if (qemuMonitorJSONGetStringListProperty(mon, QOM_CPU_PATH,
>+ "unavailable-features", &props) < 0)
>+ goto cleanup;
>+
>+ for (p = props; p && *p; p++) {
>+ const char *name = *p;
>+
>+ if (translate)
>+ name = translate(name, opaque);
>+
Reviewed-by: Ján Tomko <jtomko at redhat.com>
Jano
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20190619/245cebcd/attachment-0001.sig>
More information about the libvir-list
mailing list