提交 cc6d6b3c 编写于 作者: J Jiri Denemark

qemu: Introduce generic qemuMonitorGetGuestCPU

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: NJiri Denemark <jdenemar@redhat.com>
Reviewed-by: NJán Tomko <jtomko@redhat.com>
上级 430023e5
...@@ -4107,6 +4107,42 @@ qemuMonitorGetGuestCPUx86(qemuMonitorPtr mon, ...@@ -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,
enabled, disabled);
}
/** /**
* qemuMonitorRTCResetReinjection: * qemuMonitorRTCResetReinjection:
* @mon: Pointer to the monitor * @mon: Pointer to the monitor
......
...@@ -1153,6 +1153,16 @@ int qemuMonitorGetGuestCPUx86(qemuMonitorPtr mon, ...@@ -1153,6 +1153,16 @@ int qemuMonitorGetGuestCPUx86(qemuMonitorPtr mon,
virCPUDataPtr *data, virCPUDataPtr *data,
virCPUDataPtr *disabled); 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); int qemuMonitorRTCResetReinjection(qemuMonitorPtr mon);
typedef struct _qemuMonitorIOThreadInfo qemuMonitorIOThreadInfo; typedef struct _qemuMonitorIOThreadInfo qemuMonitorIOThreadInfo;
......
...@@ -6137,6 +6137,57 @@ int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon, ...@@ -6137,6 +6137,57 @@ int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon,
} }
static int
qemuMonitorJSONGetStringListProperty(qemuMonitorPtr mon,
const char *path,
const char *property,
char ***strList)
{
VIR_AUTOPTR(virJSONValue) cmd = NULL;
VIR_AUTOPTR(virJSONValue) reply = NULL;
VIR_AUTOSTRINGLIST list = NULL;
virJSONValuePtr data;
size_t n;
size_t i;
*strList = NULL;
if (!(cmd = qemuMonitorJSONMakeCommand("qom-get",
"s:path", path,
"s:property", property,
NULL)))
return -1;
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
return -1;
if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0)
return -1;
data = virJSONValueObjectGetArray(reply, "return");
n = virJSONValueArraySize(data);
if (VIR_ALLOC_N(list, n + 1) < 0)
return -1;
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);
return -1;
}
if (VIR_STRDUP(list[i], virJSONValueGetString(item)) < 0)
return -1;
}
VIR_STEAL_PTR(*strList, list);
return n;
}
#define MAKE_SET_CMD(STRING, VALUE) \ #define MAKE_SET_CMD(STRING, VALUE) \
cmd = qemuMonitorJSONMakeCommand("qom-set", \ cmd = qemuMonitorJSONMakeCommand("qom-set", \
"s:path", path, \ "s:path", path, \
...@@ -7369,6 +7420,141 @@ qemuMonitorJSONGetGuestCPUx86(qemuMonitorPtr mon, ...@@ -7369,6 +7420,141 @@ qemuMonitorJSONGetGuestCPUx86(qemuMonitorPtr mon,
return -1; return -1;
} }
static int
qemuMonitorJSONGetCPUProperties(qemuMonitorPtr mon,
char ***props)
{
VIR_AUTOPTR(virJSONValue) cmd = NULL;
VIR_AUTOPTR(virJSONValue) reply = NULL;
*props = NULL;
if (!(cmd = qemuMonitorJSONMakeCommand("qom-list",
"s:path", QOM_CPU_PATH,
NULL)))
return -1;
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
return -1;
if (qemuMonitorJSONHasError(reply, "DeviceNotFound"))
return 0;
return qemuMonitorJSONParsePropsList(cmd, reply, "bool", props);
}
static int
qemuMonitorJSONGetCPUData(qemuMonitorPtr mon,
qemuMonitorCPUFeatureTranslationCallback translate,
void *opaque,
virCPUDataPtr data)
{
qemuMonitorJSONObjectProperty prop = { .type = QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN };
VIR_AUTOSTRINGLIST props = NULL;
char **p;
if (qemuMonitorJSONGetCPUProperties(mon, &props) < 0)
return -1;
for (p = props; p && *p; p++) {
const char *name = *p;
if (qemuMonitorJSONGetObjectProperty(mon, QOM_CPU_PATH, name, &prop) < 0)
return -1;
if (!prop.val.b)
continue;
if (translate)
name = translate(name, opaque);
if (virCPUDataAddFeature(data, name) < 0)
return -1;
}
return 0;
}
static int
qemuMonitorJSONGetCPUDataDisabled(qemuMonitorPtr mon,
qemuMonitorCPUFeatureTranslationCallback translate,
void *opaque,
virCPUDataPtr data)
{
VIR_AUTOSTRINGLIST props = NULL;
char **p;
if (qemuMonitorJSONGetStringListProperty(mon, QOM_CPU_PATH,
"unavailable-features", &props) < 0)
return -1;
for (p = props; p && *p; p++) {
const char *name = *p;
if (translate)
name = translate(name, opaque);
if (virCPUDataAddFeature(data, name) < 0)
return -1;
}
return 0;
}
/**
* qemuMonitorJSONGetGuestCPU:
* @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
qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon,
virArch arch,
qemuMonitorCPUFeatureTranslationCallback translate,
void *opaque,
virCPUDataPtr *enabled,
virCPUDataPtr *disabled)
{
virCPUDataPtr cpuEnabled = NULL;
virCPUDataPtr cpuDisabled = NULL;
int ret = -1;
if (!(cpuEnabled = virCPUDataNew(arch)) ||
!(cpuDisabled = virCPUDataNew(arch)))
goto cleanup;
if (qemuMonitorJSONGetCPUData(mon, translate, opaque, cpuEnabled) < 0)
goto cleanup;
if (disabled &&
qemuMonitorJSONGetCPUDataDisabled(mon, translate, opaque, cpuDisabled) < 0)
goto cleanup;
VIR_STEAL_PTR(*enabled, cpuEnabled);
if (disabled)
VIR_STEAL_PTR(*disabled, cpuDisabled);
ret = 0;
cleanup:
virCPUDataFree(cpuEnabled);
virCPUDataFree(cpuDisabled);
return ret;
}
int int
qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon) qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon)
{ {
......
...@@ -492,6 +492,13 @@ int qemuMonitorJSONGetGuestCPUx86(qemuMonitorPtr mon, ...@@ -492,6 +492,13 @@ int qemuMonitorJSONGetGuestCPUx86(qemuMonitorPtr mon,
virCPUDataPtr *data, virCPUDataPtr *data,
virCPUDataPtr *disabled); virCPUDataPtr *disabled);
int qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon,
virArch arch,
qemuMonitorCPUFeatureTranslationCallback translate,
void *opaque,
virCPUDataPtr *enabled,
virCPUDataPtr *disabled);
int qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon); int qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon);
int qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon, int qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册