The qemu32 CPU model is chosen based on the <os arch=...> name when
creating the QEMU command line. Reflect the kvm32/kvm64/qemu32/qemu64
CPU models in the <os> element when doing the opposite transformation.
To do this, we need to not look at def->os.arch until after the
command-line has been parsed.
At the same time, avoid creating an empty <cpu> element when the QEMU
command-line specifies the default CPU model for the guest arch.
Signed-off-by: Paolo Bonzini <pbonzini(a)redhat.com>
---
src/qemu/qemu_command.c | 70 +++++++++++++++++++++++++++++++----------------
1 files changed, 46 insertions(+), 24 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index aaccf62..7c4460e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6779,12 +6779,10 @@ static int
qemuParseCommandLineCPU(virDomainDefPtr dom,
const char *val)
{
- virCPUDefPtr cpu;
+ virCPUDefPtr cpu = NULL;
const char *p = val;
const char *next;
-
- if (!(cpu = qemuInitGuestCPU(dom)))
- goto error;
+ char *model = NULL;
do {
if (*p == '\0' || *p == ',')
@@ -6793,13 +6791,13 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
if ((next = strchr(p, ',')))
next++;
- if (!cpu->model) {
+ if (!model) {
if (next)
- cpu->model = strndup(p, next - p - 1);
+ model = strndup(p, next - p - 1);
else
- cpu->model = strdup(p);
+ model = strdup(p);
- if (!cpu->model)
+ if (!model)
goto no_memory;
}
else if (*p == '+' || *p == '-') {
@@ -6824,6 +6822,9 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
if (!feature)
goto no_memory;
+ if (!cpu && !(cpu = qemuInitGuestCPU(dom)))
+ goto error;
+
ret = virCPUDefAddFeature(cpu, feature, policy);
VIR_FREE(feature);
if (ret < 0)
@@ -6831,6 +6832,21 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
}
} while ((p = next));
+ if (model) {
+ if (STREQ(model, "qemu32") || STREQ(model, "kvm32")) {
+ dom->os.arch = strdup("i686");
+ VIR_FREE(model);
+ } else if (STREQ(model, "qemu64") || STREQ(model, "kvm64"))
{
+ dom->os.arch = strdup("x86_64");
+ VIR_FREE(model);
+ } else {
+ if (!cpu && !(cpu = qemuInitGuestCPU(dom)))
+ goto error;
+
+ cpu->model = model;
+ }
+ }
+
return 0;
syntax:
@@ -6942,6 +6958,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
const char **nics = NULL;
int video = VIR_DOMAIN_VIDEO_TYPE_CIRRUS;
int nvirtiodisk = 0;
+ int disabled_features = 0;
qemuDomainCmdlineDefPtr cmd = NULL;
virDomainDiskDefPtr disk = NULL;
const char *ceph_args = qemuFindEnv(progenv, "CEPH_ARGS");
@@ -7000,21 +7017,6 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
if (!def->os.type)
goto no_memory;
- if (STRPREFIX(def->emulator, "qemu"))
- path = def->emulator;
- else
- path = strstr(def->emulator, "qemu");
- if (path &&
- STRPREFIX(path, "qemu-system-"))
- def->os.arch = strdup(path + strlen("qemu-system-"));
- else
- def->os.arch = strdup("i686");
- if (!def->os.arch)
- goto no_memory;
-
- if (STREQ(def->os.arch, "i686")||STREQ(def->os.arch,
"x86_64"))
- def->features = (1 << VIR_DOMAIN_FEATURE_ACPI)
- /*| (1 << VIR_DOMAIN_FEATURE_APIC)*/;
#define WANT_VALUE() \
const char *val = progargv[++i]; \
if (!val) { \
@@ -7246,7 +7248,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
def->disks[def->ndisks++] = disk;
disk = NULL;
} else if (STREQ(arg, "-no-acpi")) {
- def->features &= ~(1 << VIR_DOMAIN_FEATURE_ACPI);
+ disabled_features |= (1 << VIR_DOMAIN_FEATURE_ACPI);
} else if (STREQ(arg, "-no-reboot")) {
def->onReboot = VIR_DOMAIN_LIFECYCLE_DESTROY;
} else if (STREQ(arg, "-no-kvm")) {
@@ -7542,6 +7544,26 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
}
}
+ if (!def->os.arch) {
+ if (STRPREFIX(def->emulator, "qemu"))
+ path = def->emulator;
+ else
+ path = strstr(def->emulator, "qemu");
+ if (path &&
+ STRPREFIX(path, "qemu-system-"))
+ def->os.arch = strdup(path + strlen("qemu-system-"));
+ else
+ def->os.arch = strdup("i686");
+ if (!def->os.arch)
+ goto no_memory;
+ }
+
+ if (STREQ(def->os.arch, "i686")||STREQ(def->os.arch,
"x86_64"))
+ def->features = (1 << VIR_DOMAIN_FEATURE_ACPI)
+ /*| (1 << VIR_DOMAIN_FEATURE_APIC)*/;
+
+ def->features &= ~disabled_features;
+
#undef WANT_VALUE
if (def->ndisks > 0 && ceph_args) {
char *hosts, *port, *saveptr = NULL, *token;
--
1.7.7.1