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,
|
||||
virDomainCapsCPUModelsPtr *cpuModels)
|
||||
{
|
||||
g_autoptr(qemuMonitorCPUDefs) defs = NULL;
|
||||
virDomainCapsCPUModelsPtr models = NULL;
|
||||
qemuMonitorCPUDefInfoPtr *cpus = NULL;
|
||||
int ncpus = 0;
|
||||
size_t i;
|
||||
int ret = -1;
|
||||
|
||||
*cpuModels = NULL;
|
||||
|
||||
if ((ncpus = qemuMonitorGetCPUDefinitions(mon, &cpus)) < 0)
|
||||
if (qemuMonitorGetCPUDefinitions(mon, &defs) < 0)
|
||||
return -1;
|
||||
|
||||
if (ncpus == 0) {
|
||||
if (!defs) {
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -2472,29 +2471,29 @@ virQEMUCapsFetchCPUDefinitions(qemuMonitorPtr mon,
|
||||
goto cleanup;
|
||||
|
||||
for (name = libvirtModels; name && *name; name++) {
|
||||
for (i = 0; i < ncpus; i++) {
|
||||
if (STRCASENEQ(cpus[i]->name, *name))
|
||||
for (i = 0; i < defs->ncpus; i++) {
|
||||
if (STRCASENEQ(defs->cpus[i]->name, *name))
|
||||
continue;
|
||||
|
||||
VIR_FREE(cpus[i]->name);
|
||||
cpus[i]->name = g_strdup(*name);
|
||||
VIR_FREE(defs->cpus[i]->name);
|
||||
defs->cpus[i]->name = g_strdup(*name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(models = virDomainCapsCPUModelsNew(ncpus)))
|
||||
if (!(models = virDomainCapsCPUModelsNew(defs->ncpus)))
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < ncpus; i++) {
|
||||
for (i = 0; i < defs->ncpus; i++) {
|
||||
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;
|
||||
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;
|
||||
|
||||
if (virDomainCapsCPUModelsAddSteal(models, &cpus[i]->name, usable,
|
||||
&cpus[i]->blockers) < 0)
|
||||
if (virDomainCapsCPUModelsAddSteal(models, &defs->cpus[i]->name, usable,
|
||||
&defs->cpus[i]->blockers) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -2502,9 +2501,6 @@ virQEMUCapsFetchCPUDefinitions(qemuMonitorPtr mon,
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
for (i = 0; i < ncpus; i++)
|
||||
qemuMonitorCPUDefInfoFree(cpus[i]);
|
||||
VIR_FREE(cpus);
|
||||
virObjectUnref(models);
|
||||
return ret;
|
||||
}
|
||||
|
@ -3550,25 +3550,45 @@ qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine)
|
||||
|
||||
int
|
||||
qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
|
||||
qemuMonitorCPUDefInfoPtr **cpus)
|
||||
qemuMonitorCPUDefsPtr *cpuDefs)
|
||||
{
|
||||
VIR_DEBUG("cpus=%p", cpus);
|
||||
VIR_DEBUG("cpuDefs=%p", cpuDefs);
|
||||
|
||||
QEMU_CHECK_MONITOR(mon);
|
||||
|
||||
return qemuMonitorJSONGetCPUDefinitions(mon, cpus);
|
||||
return qemuMonitorJSONGetCPUDefinitions(mon, cpuDefs);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu)
|
||||
qemuMonitorCPUDefsFree(qemuMonitorCPUDefsPtr defs)
|
||||
{
|
||||
if (!cpu)
|
||||
size_t i;
|
||||
|
||||
if (!defs)
|
||||
return;
|
||||
|
||||
virStringListFree(cpu->blockers);
|
||||
VIR_FREE(cpu->name);
|
||||
VIR_FREE(cpu);
|
||||
for (i = 0; i < defs->ncpus; i++) {
|
||||
g_strfreev(defs->cpus[i]->blockers);
|
||||
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 */
|
||||
};
|
||||
|
||||
typedef struct _qemuMonitorCPUDefs qemuMonitorCPUDefs;
|
||||
typedef qemuMonitorCPUDefs *qemuMonitorCPUDefsPtr;
|
||||
struct _qemuMonitorCPUDefs {
|
||||
size_t ncpus;
|
||||
qemuMonitorCPUDefInfoPtr *cpus;
|
||||
};
|
||||
|
||||
int qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
|
||||
qemuMonitorCPUDefInfoPtr **cpus);
|
||||
void qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu);
|
||||
qemuMonitorCPUDefsPtr *cpuDefs);
|
||||
qemuMonitorCPUDefsPtr qemuMonitorCPUDefsNew(size_t count);
|
||||
void qemuMonitorCPUDefsFree(qemuMonitorCPUDefsPtr defs);
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuMonitorCPUDefs, qemuMonitorCPUDefsFree);
|
||||
|
||||
|
||||
typedef enum {
|
||||
QEMU_MONITOR_CPU_PROPERTY_BOOLEAN,
|
||||
|
@ -5571,56 +5571,53 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
|
||||
|
||||
int
|
||||
qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
||||
qemuMonitorCPUDefInfoPtr **cpus)
|
||||
qemuMonitorCPUDefsPtr *cpuDefs)
|
||||
{
|
||||
int ret = -1;
|
||||
g_autoptr(qemuMonitorCPUDefs) defs = NULL;
|
||||
g_autoptr(virJSONValue) cmd = NULL;
|
||||
g_autoptr(virJSONValue) reply = NULL;
|
||||
virJSONValuePtr data;
|
||||
qemuMonitorCPUDefInfoPtr *cpulist = NULL;
|
||||
size_t n = 0;
|
||||
size_t ncpus;
|
||||
size_t i;
|
||||
|
||||
*cpus = NULL;
|
||||
*cpuDefs = NULL;
|
||||
|
||||
if (!(cmd = qemuMonitorJSONMakeCommand("query-cpu-definitions", NULL)))
|
||||
return -1;
|
||||
|
||||
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
||||
goto cleanup;
|
||||
return -1;
|
||||
|
||||
/* Urgh, some QEMU architectures have the query-cpu-definitions
|
||||
* command, but return 'GenericError' with string "Not supported",
|
||||
* instead of simply omitting the command entirely :-(
|
||||
*/
|
||||
if (qemuMonitorJSONHasError(reply, "GenericError")) {
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
if (qemuMonitorJSONHasError(reply, "GenericError"))
|
||||
return 0;
|
||||
|
||||
if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0)
|
||||
goto cleanup;
|
||||
return -1;
|
||||
|
||||
data = virJSONValueObjectGetArray(reply, "return");
|
||||
n = virJSONValueArraySize(data);
|
||||
ncpus = virJSONValueArraySize(data);
|
||||
|
||||
if (VIR_ALLOC_N(cpulist, n) < 0)
|
||||
goto cleanup;
|
||||
if (!(defs = qemuMonitorCPUDefsNew(ncpus)))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
for (i = 0; i < defs->ncpus; i++) {
|
||||
virJSONValuePtr child = virJSONValueArrayGet(data, i);
|
||||
const char *tmp;
|
||||
qemuMonitorCPUDefInfoPtr cpu;
|
||||
|
||||
if (VIR_ALLOC(cpu) < 0)
|
||||
goto cleanup;
|
||||
return -1;
|
||||
|
||||
cpulist[i] = cpu;
|
||||
defs->cpus[i] = cpu;
|
||||
|
||||
if (!(tmp = virJSONValueObjectGetString(child, "name"))) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("query-cpu-definitions reply data was missing 'name'"));
|
||||
goto cleanup;
|
||||
return -1;
|
||||
}
|
||||
|
||||
cpu->name = g_strdup(tmp);
|
||||
@ -5636,7 +5633,7 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("unavailable-features in query-cpu-definitions "
|
||||
"reply data was not an array"));
|
||||
goto cleanup;
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = virJSONValueArraySize(blockers);
|
||||
@ -5648,7 +5645,7 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
||||
|
||||
cpu->usable = VIR_TRISTATE_BOOL_NO;
|
||||
if (VIR_ALLOC_N(cpu->blockers, len + 1) < 0)
|
||||
goto cleanup;
|
||||
return -1;
|
||||
|
||||
for (j = 0; j < len; j++) {
|
||||
virJSONValuePtr blocker = virJSONValueArrayGet(blockers, j);
|
||||
@ -5657,7 +5654,7 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("unexpected value in unavailable-features "
|
||||
"array"));
|
||||
goto cleanup;
|
||||
return -1;
|
||||
}
|
||||
|
||||
cpu->blockers[j] = g_strdup(virJSONValueGetString(blocker));
|
||||
@ -5665,17 +5662,8 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
||||
}
|
||||
}
|
||||
|
||||
ret = n;
|
||||
*cpus = cpulist;
|
||||
cpulist = NULL;
|
||||
|
||||
cleanup:
|
||||
if (cpulist) {
|
||||
for (i = 0; i < n; i++)
|
||||
qemuMonitorCPUDefInfoFree(cpulist[i]);
|
||||
VIR_FREE(cpulist);
|
||||
}
|
||||
return ret;
|
||||
*cpuDefs = g_steal_pointer(&defs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -379,7 +379,7 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
|
||||
ATTRIBUTE_NONNULL(2);
|
||||
|
||||
int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
|
||||
qemuMonitorCPUDefInfoPtr **cpus)
|
||||
qemuMonitorCPUDefsPtr *cpuDefs)
|
||||
ATTRIBUTE_NONNULL(2);
|
||||
|
||||
int qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
|
||||
|
@ -428,10 +428,7 @@ testQemuMonitorJSONGetCPUDefinitions(const void *opaque)
|
||||
{
|
||||
const testGenericData *data = opaque;
|
||||
virDomainXMLOptionPtr xmlopt = data->xmlopt;
|
||||
int ret = -1;
|
||||
qemuMonitorCPUDefInfoPtr *cpus = NULL;
|
||||
int ncpus = 0;
|
||||
size_t i;
|
||||
g_autoptr(qemuMonitorCPUDefs) defs = NULL;
|
||||
g_autoptr(qemuMonitorTest) test = NULL;
|
||||
|
||||
if (!(test = qemuMonitorTestNewSchema(xmlopt, data->schema)))
|
||||
@ -453,31 +450,30 @@ testQemuMonitorJSONGetCPUDefinitions(const void *opaque)
|
||||
" } "
|
||||
" ]"
|
||||
"}") < 0)
|
||||
goto cleanup;
|
||||
return -1;
|
||||
|
||||
if ((ncpus = qemuMonitorGetCPUDefinitions(qemuMonitorTestGetMonitor(test),
|
||||
&cpus)) < 0)
|
||||
goto cleanup;
|
||||
if (qemuMonitorGetCPUDefinitions(qemuMonitorTestGetMonitor(test), &defs) < 0)
|
||||
return -1;
|
||||
|
||||
if (ncpus != 3) {
|
||||
if (defs->ncpus != 3) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"ncpus %d is not 3", ncpus);
|
||||
goto cleanup;
|
||||
"ncpus %zu is not 3", defs->ncpus);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define CHECK_FULL(i, wantname, Usable) \
|
||||
do { \
|
||||
if (STRNEQ(cpus[i]->name, (wantname))) { \
|
||||
if (STRNEQ(defs->cpus[i]->name, (wantname))) { \
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
||||
"name %s is not %s", \
|
||||
cpus[i]->name, (wantname)); \
|
||||
goto cleanup; \
|
||||
defs->cpus[i]->name, (wantname)); \
|
||||
return -1; \
|
||||
} \
|
||||
if (cpus[i]->usable != (Usable)) { \
|
||||
if (defs->cpus[i]->usable != (Usable)) { \
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
||||
"%s: expecting usable flag %d, got %d", \
|
||||
cpus[i]->name, Usable, cpus[i]->usable); \
|
||||
goto cleanup; \
|
||||
defs->cpus[i]->name, Usable, defs->cpus[i]->usable); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@ -496,13 +492,7 @@ testQemuMonitorJSONGetCPUDefinitions(const void *opaque)
|
||||
#undef CHECK_USABLE
|
||||
#undef CHECK_FULL
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
for (i = 0; i < ncpus; i++)
|
||||
qemuMonitorCPUDefInfoFree(cpus[i]);
|
||||
VIR_FREE(cpus);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user