mirror of https://gitee.com/openkylin/libvirt.git
cpu: Introduce virCPUConvertLegacy API
PPC driver needs to convert POWERx_v* legacy CPU model names into POWERx to maintain backward compatibility with existing domains. This patch adds a new step into the guest CPU configuration work flow which CPU drivers can use to convert legacy CPU definitions. Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
509a4a40f9
commit
d73422c186
|
@ -934,3 +934,38 @@ virCPUTranslate(virArch arch,
|
||||||
VIR_DEBUG("model=%s", NULLSTR(cpu->model));
|
VIR_DEBUG("model=%s", NULLSTR(cpu->model));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virCPUConvertLegacy:
|
||||||
|
*
|
||||||
|
* @arch: CPU architecture
|
||||||
|
* @cpu: CPU definition to be converted
|
||||||
|
*
|
||||||
|
* Convert legacy CPU definition into one that the corresponding cpu driver
|
||||||
|
* will be able to work with. Currently this is only implemented by the PPC
|
||||||
|
* driver, which needs to convert legacy POWERx_v* names into POWERx.
|
||||||
|
*
|
||||||
|
* Returns -1 on error, 0 on success.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virCPUConvertLegacy(virArch arch,
|
||||||
|
virCPUDefPtr cpu)
|
||||||
|
{
|
||||||
|
struct cpuArchDriver *driver;
|
||||||
|
|
||||||
|
VIR_DEBUG("arch=%s, cpu=%p, model=%s",
|
||||||
|
virArchToString(arch), cpu, NULLSTR(cpu->model));
|
||||||
|
|
||||||
|
if (!(driver = cpuGetSubDriver(arch)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!driver->convertLegacy)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (driver->convertLegacy(cpu) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
VIR_DEBUG("model=%s", NULLSTR(cpu->model));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -112,6 +112,9 @@ typedef int
|
||||||
const char **models,
|
const char **models,
|
||||||
unsigned int nmodels);
|
unsigned int nmodels);
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(*virCPUArchConvertLegacy)(virCPUDefPtr cpu);
|
||||||
|
|
||||||
struct cpuArchDriver {
|
struct cpuArchDriver {
|
||||||
const char *name;
|
const char *name;
|
||||||
const virArch *arch;
|
const virArch *arch;
|
||||||
|
@ -130,6 +133,7 @@ struct cpuArchDriver {
|
||||||
virCPUArchDataParse dataParse;
|
virCPUArchDataParse dataParse;
|
||||||
virCPUArchGetModels getModels;
|
virCPUArchGetModels getModels;
|
||||||
virCPUArchTranslate translate;
|
virCPUArchTranslate translate;
|
||||||
|
virCPUArchConvertLegacy convertLegacy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,6 +233,10 @@ virCPUTranslate(virArch arch,
|
||||||
unsigned int nmodels)
|
unsigned int nmodels)
|
||||||
ATTRIBUTE_NONNULL(2);
|
ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
|
int
|
||||||
|
virCPUConvertLegacy(virArch arch,
|
||||||
|
virCPUDefPtr cpu)
|
||||||
|
ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
/* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and
|
/* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and
|
||||||
* have no real-life usage
|
* have no real-life usage
|
||||||
|
|
|
@ -63,26 +63,18 @@ struct ppc64_map {
|
||||||
* POWER7_v2.3 => POWER7
|
* POWER7_v2.3 => POWER7
|
||||||
* POWER7+_v2.1 => POWER7
|
* POWER7+_v2.1 => POWER7
|
||||||
* POWER8_v1.0 => POWER8 */
|
* POWER8_v1.0 => POWER8 */
|
||||||
static virCPUDefPtr
|
static int
|
||||||
ppc64ConvertLegacyCPUDef(const virCPUDef *legacy)
|
virCPUppc64ConvertLegacy(virCPUDefPtr cpu)
|
||||||
{
|
{
|
||||||
virCPUDefPtr cpu;
|
if (cpu->model &&
|
||||||
|
(STREQ(cpu->model, "POWER7_v2.1") ||
|
||||||
if (!(cpu = virCPUDefCopy(legacy)))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!cpu->model ||
|
|
||||||
!(STREQ(cpu->model, "POWER7_v2.1") ||
|
|
||||||
STREQ(cpu->model, "POWER7_v2.3") ||
|
STREQ(cpu->model, "POWER7_v2.3") ||
|
||||||
STREQ(cpu->model, "POWER7+_v2.1") ||
|
STREQ(cpu->model, "POWER7+_v2.1") ||
|
||||||
STREQ(cpu->model, "POWER8_v1.0"))) {
|
STREQ(cpu->model, "POWER8_v1.0"))) {
|
||||||
goto out;
|
cpu->model[strlen("POWERx")] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->model[strlen("POWERx")] = 0;
|
return 0;
|
||||||
|
|
||||||
out:
|
|
||||||
return cpu;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some hosts can run guests in compatibility mode, but not all
|
/* Some hosts can run guests in compatibility mode, but not all
|
||||||
|
@ -519,7 +511,8 @@ ppc64Compute(virCPUDefPtr host,
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* Ensure existing configurations are handled correctly */
|
/* Ensure existing configurations are handled correctly */
|
||||||
if (!(cpu = ppc64ConvertLegacyCPUDef(other)))
|
if (!(cpu = virCPUDefCopy(other)) ||
|
||||||
|
virCPUppc64ConvertLegacy(cpu) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (cpu->arch != VIR_ARCH_NONE) {
|
if (cpu->arch != VIR_ARCH_NONE) {
|
||||||
|
@ -922,4 +915,5 @@ struct cpuArchDriver cpuDriverPPC64 = {
|
||||||
.baseline = ppc64DriverBaseline,
|
.baseline = ppc64DriverBaseline,
|
||||||
.update = virCPUppc64Update,
|
.update = virCPUppc64Update,
|
||||||
.getModels = virCPUppc64DriverGetModels,
|
.getModels = virCPUppc64DriverGetModels,
|
||||||
|
.convertLegacy = virCPUppc64ConvertLegacy,
|
||||||
};
|
};
|
||||||
|
|
|
@ -983,6 +983,7 @@ cpuNodeData;
|
||||||
virCPUCheckFeature;
|
virCPUCheckFeature;
|
||||||
virCPUCompare;
|
virCPUCompare;
|
||||||
virCPUCompareXML;
|
virCPUCompareXML;
|
||||||
|
virCPUConvertLegacy;
|
||||||
virCPUDataCheckFeature;
|
virCPUDataCheckFeature;
|
||||||
virCPUDataFormat;
|
virCPUDataFormat;
|
||||||
virCPUDataParse;
|
virCPUDataParse;
|
||||||
|
|
|
@ -5066,6 +5066,9 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virCPUConvertLegacy(caps->host.arch, def->cpu) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* nothing to update for host-passthrough */
|
/* nothing to update for host-passthrough */
|
||||||
if (def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
|
if (def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -251,6 +251,9 @@ cpuTestGuestCPU(const void *arg)
|
||||||
!(cpu = cpuTestLoadXML(data->arch, data->name)))
|
!(cpu = cpuTestLoadXML(data->arch, data->name)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virCPUConvertLegacy(host->arch, cpu) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
cmpResult = virCPUCompare(host->arch, host, cpu, false);
|
cmpResult = virCPUCompare(host->arch, host, cpu, false);
|
||||||
if (cmpResult == VIR_CPU_COMPARE_ERROR ||
|
if (cmpResult == VIR_CPU_COMPARE_ERROR ||
|
||||||
cmpResult == VIR_CPU_COMPARE_INCOMPATIBLE) {
|
cmpResult == VIR_CPU_COMPARE_INCOMPATIBLE) {
|
||||||
|
@ -794,7 +797,7 @@ mymain(void)
|
||||||
|
|
||||||
DO_TEST_GUESTCPU("ppc64", "host", "guest", ppc_models, 0);
|
DO_TEST_GUESTCPU("ppc64", "host", "guest", ppc_models, 0);
|
||||||
DO_TEST_GUESTCPU("ppc64", "host", "guest-nofallback", ppc_models, -1);
|
DO_TEST_GUESTCPU("ppc64", "host", "guest-nofallback", ppc_models, -1);
|
||||||
DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy", ppc_models, /*0*/ -1);
|
DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy", ppc_models, 0);
|
||||||
DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy-incompatible", ppc_models, -1);
|
DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy-incompatible", ppc_models, -1);
|
||||||
DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy-invalid", ppc_models, -1);
|
DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy-invalid", ppc_models, -1);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue