mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
qemu: Introduce qemuMonitorCPUDefs struct
It is a container for a CPU models list (qemuMonitorCPUDefInfo) and a number of elements in this list. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
a94f67ee69
commit
3aa53dcf01
@ -2446,18 +2446,17 @@ virQEMUCapsFetchCPUDefinitions(qemuMonitorPtr mon,
|
|||||||
virArch arch,
|
virArch arch,
|
||||||
virDomainCapsCPUModelsPtr *cpuModels)
|
virDomainCapsCPUModelsPtr *cpuModels)
|
||||||
{
|
{
|
||||||
|
g_autoptr(qemuMonitorCPUDefs) defs = NULL;
|
||||||
virDomainCapsCPUModelsPtr models = NULL;
|
virDomainCapsCPUModelsPtr models = NULL;
|
||||||
qemuMonitorCPUDefInfoPtr *cpus = NULL;
|
|
||||||
int ncpus = 0;
|
|
||||||
size_t i;
|
size_t i;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
*cpuModels = NULL;
|
*cpuModels = NULL;
|
||||||
|
|
||||||
if ((ncpus = qemuMonitorGetCPUDefinitions(mon, &cpus)) < 0)
|
if (qemuMonitorGetCPUDefinitions(mon, &defs) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ncpus == 0) {
|
if (!defs) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -2472,29 +2471,29 @@ virQEMUCapsFetchCPUDefinitions(qemuMonitorPtr mon,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
for (name = libvirtModels; name && *name; name++) {
|
for (name = libvirtModels; name && *name; name++) {
|
||||||
for (i = 0; i < ncpus; i++) {
|
for (i = 0; i < defs->ncpus; i++) {
|
||||||
if (STRCASENEQ(cpus[i]->name, *name))
|
if (STRCASENEQ(defs->cpus[i]->name, *name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
VIR_FREE(cpus[i]->name);
|
VIR_FREE(defs->cpus[i]->name);
|
||||||
cpus[i]->name = g_strdup(*name);
|
defs->cpus[i]->name = g_strdup(*name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(models = virDomainCapsCPUModelsNew(ncpus)))
|
if (!(models = virDomainCapsCPUModelsNew(defs->ncpus)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
for (i = 0; i < ncpus; i++) {
|
for (i = 0; i < defs->ncpus; i++) {
|
||||||
virDomainCapsCPUUsable usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN;
|
virDomainCapsCPUUsable usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN;
|
||||||
|
|
||||||
if (cpus[i]->usable == VIR_TRISTATE_BOOL_YES)
|
if (defs->cpus[i]->usable == VIR_TRISTATE_BOOL_YES)
|
||||||
usable = VIR_DOMCAPS_CPU_USABLE_YES;
|
usable = VIR_DOMCAPS_CPU_USABLE_YES;
|
||||||
else if (cpus[i]->usable == VIR_TRISTATE_BOOL_NO)
|
else if (defs->cpus[i]->usable == VIR_TRISTATE_BOOL_NO)
|
||||||
usable = VIR_DOMCAPS_CPU_USABLE_NO;
|
usable = VIR_DOMCAPS_CPU_USABLE_NO;
|
||||||
|
|
||||||
if (virDomainCapsCPUModelsAddSteal(models, &cpus[i]->name, usable,
|
if (virDomainCapsCPUModelsAddSteal(models, &defs->cpus[i]->name, usable,
|
||||||
&cpus[i]->blockers) < 0)
|
&defs->cpus[i]->blockers) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2502,9 +2501,6 @@ virQEMUCapsFetchCPUDefinitions(qemuMonitorPtr mon,
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
for (i = 0; i < ncpus; i++)
|
|
||||||
qemuMonitorCPUDefInfoFree(cpus[i]);
|
|
||||||
VIR_FREE(cpus);
|
|
||||||
virObjectUnref(models);
|
virObjectUnref(models);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -3550,25 +3550,45 @@ qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine)
|
|||||||
|
|
||||||
int
|
int
|
||||||
qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
|
qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
|
||||||
qemuMonitorCPUDefInfoPtr **cpus)
|
qemuMonitorCPUDefsPtr *cpuDefs)
|
||||||
{
|
{
|
||||||
VIR_DEBUG("cpus=%p", cpus);
|
VIR_DEBUG("cpuDefs=%p", cpuDefs);
|
||||||
|
|
||||||
QEMU_CHECK_MONITOR(mon);
|
QEMU_CHECK_MONITOR(mon);
|
||||||
|
|
||||||
return qemuMonitorJSONGetCPUDefinitions(mon, cpus);
|
return qemuMonitorJSONGetCPUDefinitions(mon, cpuDefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu)
|
qemuMonitorCPUDefsFree(qemuMonitorCPUDefsPtr defs)
|
||||||
{
|
{
|
||||||
if (!cpu)
|
size_t i;
|
||||||
|
|
||||||
|
if (!defs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
virStringListFree(cpu->blockers);
|
for (i = 0; i < defs->ncpus; i++) {
|
||||||
VIR_FREE(cpu->name);
|
g_strfreev(defs->cpus[i]->blockers);
|
||||||
VIR_FREE(cpu);
|
g_free(defs->cpus[i]->name);
|
||||||
|
g_free(defs->cpus[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(defs->cpus);
|
||||||
|
g_free(defs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qemuMonitorCPUDefsPtr
|
||||||
|
qemuMonitorCPUDefsNew(size_t count)
|
||||||
|
{
|
||||||
|
g_autoptr(qemuMonitorCPUDefs) defs = NULL;
|
||||||
|
|
||||||
|
defs = g_new0(qemuMonitorCPUDefs, 1);
|
||||||
|
defs->cpus = g_new0(qemuMonitorCPUDefInfoPtr, count);
|
||||||
|
defs->ncpus = count;
|
||||||
|
|
||||||
|
return g_steal_pointer(&defs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1093,9 +1093,19 @@ struct _qemuMonitorCPUDefInfo {
|
|||||||
char **blockers; /* NULL-terminated string list */
|
char **blockers; /* NULL-terminated string list */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _qemuMonitorCPUDefs qemuMonitorCPUDefs;
|
||||||
|
typedef qemuMonitorCPUDefs *qemuMonitorCPUDefsPtr;
|
||||||
|
struct _qemuMonitorCPUDefs {
|
||||||
|
size_t ncpus;
|
||||||
|
qemuMonitorCPUDefInfoPtr *cpus;
|
||||||
|
};
|
||||||
|
|
||||||
int qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
|
int qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
|
||||||
qemuMonitorCPUDefInfoPtr **cpus);
|
qemuMonitorCPUDefsPtr *cpuDefs);
|
||||||
void qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu);
|
qemuMonitorCPUDefsPtr qemuMonitorCPUDefsNew(size_t count);
|
||||||
|
void qemuMonitorCPUDefsFree(qemuMonitorCPUDefsPtr defs);
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuMonitorCPUDefs, qemuMonitorCPUDefsFree);
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
QEMU_MONITOR_CPU_PROPERTY_BOOLEAN,
|
QEMU_MONITOR_CPU_PROPERTY_BOOLEAN,
|
||||||
|
@ -5571,56 +5571,53 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
|
|||||||
|
|
||||||
int
|
int
|
||||||
qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
||||||
qemuMonitorCPUDefInfoPtr **cpus)
|
qemuMonitorCPUDefsPtr *cpuDefs)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
g_autoptr(qemuMonitorCPUDefs) defs = NULL;
|
||||||
g_autoptr(virJSONValue) cmd = NULL;
|
g_autoptr(virJSONValue) cmd = NULL;
|
||||||
g_autoptr(virJSONValue) reply = NULL;
|
g_autoptr(virJSONValue) reply = NULL;
|
||||||
virJSONValuePtr data;
|
virJSONValuePtr data;
|
||||||
qemuMonitorCPUDefInfoPtr *cpulist = NULL;
|
size_t ncpus;
|
||||||
size_t n = 0;
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
*cpus = NULL;
|
*cpuDefs = NULL;
|
||||||
|
|
||||||
if (!(cmd = qemuMonitorJSONMakeCommand("query-cpu-definitions", NULL)))
|
if (!(cmd = qemuMonitorJSONMakeCommand("query-cpu-definitions", NULL)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
||||||
goto cleanup;
|
return -1;
|
||||||
|
|
||||||
/* Urgh, some QEMU architectures have the query-cpu-definitions
|
/* Urgh, some QEMU architectures have the query-cpu-definitions
|
||||||
* command, but return 'GenericError' with string "Not supported",
|
* command, but return 'GenericError' with string "Not supported",
|
||||||
* instead of simply omitting the command entirely :-(
|
* instead of simply omitting the command entirely :-(
|
||||||
*/
|
*/
|
||||||
if (qemuMonitorJSONHasError(reply, "GenericError")) {
|
if (qemuMonitorJSONHasError(reply, "GenericError"))
|
||||||
ret = 0;
|
return 0;
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0)
|
if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0)
|
||||||
goto cleanup;
|
return -1;
|
||||||
|
|
||||||
data = virJSONValueObjectGetArray(reply, "return");
|
data = virJSONValueObjectGetArray(reply, "return");
|
||||||
n = virJSONValueArraySize(data);
|
ncpus = virJSONValueArraySize(data);
|
||||||
|
|
||||||
if (VIR_ALLOC_N(cpulist, n) < 0)
|
if (!(defs = qemuMonitorCPUDefsNew(ncpus)))
|
||||||
goto cleanup;
|
return -1;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < defs->ncpus; i++) {
|
||||||
virJSONValuePtr child = virJSONValueArrayGet(data, i);
|
virJSONValuePtr child = virJSONValueArrayGet(data, i);
|
||||||
const char *tmp;
|
const char *tmp;
|
||||||
qemuMonitorCPUDefInfoPtr cpu;
|
qemuMonitorCPUDefInfoPtr cpu;
|
||||||
|
|
||||||
if (VIR_ALLOC(cpu) < 0)
|
if (VIR_ALLOC(cpu) < 0)
|
||||||
goto cleanup;
|
return -1;
|
||||||
|
|
||||||
cpulist[i] = cpu;
|
defs->cpus[i] = cpu;
|
||||||
|
|
||||||
if (!(tmp = virJSONValueObjectGetString(child, "name"))) {
|
if (!(tmp = virJSONValueObjectGetString(child, "name"))) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("query-cpu-definitions reply data was missing 'name'"));
|
_("query-cpu-definitions reply data was missing 'name'"));
|
||||||
goto cleanup;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->name = g_strdup(tmp);
|
cpu->name = g_strdup(tmp);
|
||||||
@ -5636,7 +5633,7 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
|||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("unavailable-features in query-cpu-definitions "
|
_("unavailable-features in query-cpu-definitions "
|
||||||
"reply data was not an array"));
|
"reply data was not an array"));
|
||||||
goto cleanup;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = virJSONValueArraySize(blockers);
|
len = virJSONValueArraySize(blockers);
|
||||||
@ -5648,7 +5645,7 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
|||||||
|
|
||||||
cpu->usable = VIR_TRISTATE_BOOL_NO;
|
cpu->usable = VIR_TRISTATE_BOOL_NO;
|
||||||
if (VIR_ALLOC_N(cpu->blockers, len + 1) < 0)
|
if (VIR_ALLOC_N(cpu->blockers, len + 1) < 0)
|
||||||
goto cleanup;
|
return -1;
|
||||||
|
|
||||||
for (j = 0; j < len; j++) {
|
for (j = 0; j < len; j++) {
|
||||||
virJSONValuePtr blocker = virJSONValueArrayGet(blockers, j);
|
virJSONValuePtr blocker = virJSONValueArrayGet(blockers, j);
|
||||||
@ -5657,7 +5654,7 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
|||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("unexpected value in unavailable-features "
|
_("unexpected value in unavailable-features "
|
||||||
"array"));
|
"array"));
|
||||||
goto cleanup;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->blockers[j] = g_strdup(virJSONValueGetString(blocker));
|
cpu->blockers[j] = g_strdup(virJSONValueGetString(blocker));
|
||||||
@ -5665,17 +5662,8 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = n;
|
*cpuDefs = g_steal_pointer(&defs);
|
||||||
*cpus = cpulist;
|
return 0;
|
||||||
cpulist = NULL;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (cpulist) {
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
qemuMonitorCPUDefInfoFree(cpulist[i]);
|
|
||||||
VIR_FREE(cpulist);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
|
|||||||
ATTRIBUTE_NONNULL(2);
|
ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
||||||
qemuMonitorCPUDefInfoPtr **cpus)
|
qemuMonitorCPUDefsPtr *cpuDefs)
|
||||||
ATTRIBUTE_NONNULL(2);
|
ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
int qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
|
int qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
|
||||||
|
@ -428,10 +428,7 @@ testQemuMonitorJSONGetCPUDefinitions(const void *opaque)
|
|||||||
{
|
{
|
||||||
const testGenericData *data = opaque;
|
const testGenericData *data = opaque;
|
||||||
virDomainXMLOptionPtr xmlopt = data->xmlopt;
|
virDomainXMLOptionPtr xmlopt = data->xmlopt;
|
||||||
int ret = -1;
|
g_autoptr(qemuMonitorCPUDefs) defs = NULL;
|
||||||
qemuMonitorCPUDefInfoPtr *cpus = NULL;
|
|
||||||
int ncpus = 0;
|
|
||||||
size_t i;
|
|
||||||
g_autoptr(qemuMonitorTest) test = NULL;
|
g_autoptr(qemuMonitorTest) test = NULL;
|
||||||
|
|
||||||
if (!(test = qemuMonitorTestNewSchema(xmlopt, data->schema)))
|
if (!(test = qemuMonitorTestNewSchema(xmlopt, data->schema)))
|
||||||
@ -453,31 +450,30 @@ testQemuMonitorJSONGetCPUDefinitions(const void *opaque)
|
|||||||
" } "
|
" } "
|
||||||
" ]"
|
" ]"
|
||||||
"}") < 0)
|
"}") < 0)
|
||||||
goto cleanup;
|
return -1;
|
||||||
|
|
||||||
if ((ncpus = qemuMonitorGetCPUDefinitions(qemuMonitorTestGetMonitor(test),
|
if (qemuMonitorGetCPUDefinitions(qemuMonitorTestGetMonitor(test), &defs) < 0)
|
||||||
&cpus)) < 0)
|
return -1;
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (ncpus != 3) {
|
if (defs->ncpus != 3) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"ncpus %d is not 3", ncpus);
|
"ncpus %zu is not 3", defs->ncpus);
|
||||||
goto cleanup;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_FULL(i, wantname, Usable) \
|
#define CHECK_FULL(i, wantname, Usable) \
|
||||||
do { \
|
do { \
|
||||||
if (STRNEQ(cpus[i]->name, (wantname))) { \
|
if (STRNEQ(defs->cpus[i]->name, (wantname))) { \
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
||||||
"name %s is not %s", \
|
"name %s is not %s", \
|
||||||
cpus[i]->name, (wantname)); \
|
defs->cpus[i]->name, (wantname)); \
|
||||||
goto cleanup; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
if (cpus[i]->usable != (Usable)) { \
|
if (defs->cpus[i]->usable != (Usable)) { \
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
||||||
"%s: expecting usable flag %d, got %d", \
|
"%s: expecting usable flag %d, got %d", \
|
||||||
cpus[i]->name, Usable, cpus[i]->usable); \
|
defs->cpus[i]->name, Usable, defs->cpus[i]->usable); \
|
||||||
goto cleanup; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@ -496,13 +492,7 @@ testQemuMonitorJSONGetCPUDefinitions(const void *opaque)
|
|||||||
#undef CHECK_USABLE
|
#undef CHECK_USABLE
|
||||||
#undef CHECK_FULL
|
#undef CHECK_FULL
|
||||||
|
|
||||||
ret = 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
|
||||||
for (i = 0; i < ncpus; i++)
|
|
||||||
qemuMonitorCPUDefInfoFree(cpus[i]);
|
|
||||||
VIR_FREE(cpus);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user