mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Functions for computing baseline CPU from a set of host CPUs
Baseline CPU is the best CPU which can be used for a guest on any of the hosts.
This commit is contained in:
parent
af7c18f7a2
commit
388f3cb565
123
src/cpu/cpu.c
123
src/cpu/cpu.c
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* cpu.c: internal functions for CPU manipulation
|
* cpu.c: internal functions for CPU manipulation
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 Red Hat, Inc.
|
* Copyright (C) 2009--2010 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "memory.h"
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "cpu_x86.h"
|
#include "cpu_x86.h"
|
||||||
@ -237,3 +238,123 @@ cpuGuestData(virCPUDefPtr host,
|
|||||||
|
|
||||||
return driver->guestData(host, guest, data);
|
return driver->guestData(host, guest, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
cpuBaselineXML(const char **xmlCPUs,
|
||||||
|
unsigned int ncpus,
|
||||||
|
const char **models,
|
||||||
|
unsigned int nmodels)
|
||||||
|
{
|
||||||
|
xmlDocPtr doc = NULL;
|
||||||
|
xmlXPathContextPtr ctxt = NULL;
|
||||||
|
virCPUDefPtr *cpus = NULL;
|
||||||
|
virCPUDefPtr cpu = NULL;
|
||||||
|
char *cpustr;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (xmlCPUs == NULL && ncpus != 0) {
|
||||||
|
virCPUReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("nonzero ncpus doesn't match with NULL xmlCPUs"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ncpus < 1) {
|
||||||
|
virCPUReportError(VIR_ERR_INVALID_ARG, "%s", _("No CPUs given"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(cpus, ncpus))
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
for (i = 0; i < ncpus; i++) {
|
||||||
|
doc = xmlParseMemory(xmlCPUs[i], strlen(xmlCPUs[i]));
|
||||||
|
if (doc == NULL || (ctxt = xmlXPathNewContext(doc)) == NULL)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
ctxt->node = xmlDocGetRootElement(doc);
|
||||||
|
|
||||||
|
cpus[i] = virCPUDefParseXML(ctxt->node, ctxt, VIR_CPU_TYPE_HOST);
|
||||||
|
if (cpus[i] == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
xmlXPathFreeContext(ctxt);
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
ctxt = NULL;
|
||||||
|
doc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cpu = cpuBaseline(cpus, ncpus, models, nmodels)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
cpustr = virCPUDefFormat(cpu, "", 0);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (cpus) {
|
||||||
|
for (i = 0; i < ncpus; i++)
|
||||||
|
virCPUDefFree(cpus[i]);
|
||||||
|
VIR_FREE(cpus);
|
||||||
|
}
|
||||||
|
virCPUDefFree(cpu);
|
||||||
|
xmlXPathFreeContext(ctxt);
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
|
||||||
|
return cpustr;
|
||||||
|
|
||||||
|
no_memory:
|
||||||
|
virReportOOMError();
|
||||||
|
error:
|
||||||
|
cpustr = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virCPUDefPtr
|
||||||
|
cpuBaseline(virCPUDefPtr *cpus,
|
||||||
|
unsigned int ncpus,
|
||||||
|
const char **models,
|
||||||
|
unsigned int nmodels)
|
||||||
|
{
|
||||||
|
struct cpuArchDriver *driver;
|
||||||
|
virCPUDefPtr cpu;
|
||||||
|
|
||||||
|
if (cpus == NULL && ncpus != 0) {
|
||||||
|
virCPUReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("nonzero ncpus doesn't match with NULL cpus"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ncpus < 1) {
|
||||||
|
virCPUReportError(VIR_ERR_INVALID_ARG, "%s", _("No CPUs given"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (models == NULL && nmodels != 0) {
|
||||||
|
virCPUReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("nonzero nmodels doesn't match with NULL models"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((driver = cpuGetSubDriver(cpus[0]->arch)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (driver->baseline == NULL) {
|
||||||
|
virCPUReportError(VIR_ERR_NO_SUPPORT,
|
||||||
|
_("cannot compute baseline CPU of %s architecture"),
|
||||||
|
cpus[0]->arch);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cpu = driver->baseline(cpus, ncpus, models, nmodels))) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cpu->type = VIR_CPU_TYPE_GUEST;
|
||||||
|
cpu->match = VIR_CPU_MATCH_EXACT;
|
||||||
|
VIR_FREE(cpu->arch);
|
||||||
|
|
||||||
|
for (i = 0; i < cpu->nfeatures; i++)
|
||||||
|
cpu->features[i].policy = VIR_CPU_FEATURE_REQUIRE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cpu;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* cpu.h: internal functions for CPU manipulation
|
* cpu.h: internal functions for CPU manipulation
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 Red Hat, Inc.
|
* Copyright (C) 2009--2010 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -70,6 +70,12 @@ typedef virCPUCompareResult
|
|||||||
virCPUDefPtr guest,
|
virCPUDefPtr guest,
|
||||||
union cpuData **data);
|
union cpuData **data);
|
||||||
|
|
||||||
|
typedef virCPUDefPtr
|
||||||
|
(*cpuArchBaseline) (virCPUDefPtr *cpus,
|
||||||
|
unsigned int ncpus,
|
||||||
|
const char **models,
|
||||||
|
unsigned int nmodels);
|
||||||
|
|
||||||
|
|
||||||
struct cpuArchDriver {
|
struct cpuArchDriver {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -81,6 +87,7 @@ struct cpuArchDriver {
|
|||||||
cpuArchDataFree free;
|
cpuArchDataFree free;
|
||||||
cpuArchNodeData nodeData;
|
cpuArchNodeData nodeData;
|
||||||
cpuArchGuestData guestData;
|
cpuArchGuestData guestData;
|
||||||
|
cpuArchBaseline baseline;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -119,4 +126,16 @@ cpuGuestData(virCPUDefPtr host,
|
|||||||
virCPUDefPtr guest,
|
virCPUDefPtr guest,
|
||||||
union cpuData **data);
|
union cpuData **data);
|
||||||
|
|
||||||
|
extern char *
|
||||||
|
cpuBaselineXML(const char **xmlCPUs,
|
||||||
|
unsigned int ncpus,
|
||||||
|
const char **models,
|
||||||
|
unsigned int nmodels);
|
||||||
|
|
||||||
|
extern virCPUDefPtr
|
||||||
|
cpuBaseline (virCPUDefPtr *cpus,
|
||||||
|
unsigned int ncpus,
|
||||||
|
const char **models,
|
||||||
|
unsigned int nmodels);
|
||||||
|
|
||||||
#endif /* __VIR_CPU_H__ */
|
#endif /* __VIR_CPU_H__ */
|
||||||
|
@ -118,5 +118,6 @@ struct cpuArchDriver cpuDriverGeneric = {
|
|||||||
.encode = NULL,
|
.encode = NULL,
|
||||||
.free = NULL,
|
.free = NULL,
|
||||||
.nodeData = NULL,
|
.nodeData = NULL,
|
||||||
.guestData = NULL
|
.guestData = NULL,
|
||||||
|
.baseline = NULL,
|
||||||
};
|
};
|
||||||
|
@ -1205,5 +1205,6 @@ struct cpuArchDriver cpuDriverX86 = {
|
|||||||
#else
|
#else
|
||||||
.nodeData = NULL,
|
.nodeData = NULL,
|
||||||
#endif
|
#endif
|
||||||
.guestData = x86GuestData
|
.guestData = x86GuestData,
|
||||||
|
.baseline = NULL,
|
||||||
};
|
};
|
||||||
|
@ -72,6 +72,8 @@ virCgroupSetFreezerState;
|
|||||||
|
|
||||||
|
|
||||||
# cpu.h
|
# cpu.h
|
||||||
|
cpuBaseline;
|
||||||
|
cpuBaselineXML;
|
||||||
cpuCompare;
|
cpuCompare;
|
||||||
cpuCompareXML;
|
cpuCompareXML;
|
||||||
cpuDataFree;
|
cpuDataFree;
|
||||||
|
Loading…
Reference in New Issue
Block a user