qemu: recognize -machine accel=kvm when parsing native

In Fedora 19, 'qemu-kvm' is a simple wrapper that calls
'qemu-system-x86_64 -machine accel=kvm'.  Attempting
to use 'virsh qemu-attach $pid' to a machine started as:

qemu-kvm -cdrom /var/lib/libvirt/images/foo.img \
 -monitor unix:/tmp/demo,server,nowait -name foo \
 --uuid cece4f9f-dff0-575d-0e8e-01fe380f12ea

was failing with:
error: XML error: No PCI buses available

because we did not see 'kvm' in the executable name read from
/proc/$pid/cmdline, and tried to assign os.machine as
"accel=kvm" instead of "pc"; this in turn led to refusal to
recognize the pci bus.

Noticed while investigating https://bugzilla.redhat.com/995312
although there are still other issues to fix before that bug
will be completely solved.

I've concluded that the existing parser code for native-to-xml
is a horrendous hodge-podge of ad-hoc approaches; I basically
rewrote the -machine section to be a bit saner.

* src/qemu/qemu_command.c (qemuParseCommandLine): Don't assume
-machine argument is always appropriate for os.machine; set
virtType if accel is present.

Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Eric Blake 2013-08-27 21:45:46 -06:00
parent 6a373fb2c9
commit 2b1ef11c6c
1 changed files with 31 additions and 24 deletions

View File

@ -11352,35 +11352,42 @@ qemuParseCommandLine(virCapsPtr qemuCaps,
VIR_FREE(def->name);
} else if (STREQ(arg, "-M") ||
STREQ(arg, "-machine")) {
char *params;
char **list;
char *param;
size_t j = 0;
/* -machine [type=]name[,prop[=value][,...]]
* Set os.machine only if first parameter lacks '=' or
* contains explicit type='...' */
WANT_VALUE();
params = strchr(val, ',');
if (params == NULL) {
if (VIR_STRDUP(def->os.machine, val) < 0)
goto error;
} else {
if (VIR_STRNDUP(def->os.machine, val, params - val) < 0)
goto error;
list = virStringSplit(val, ",", 0);
param = list[0];
while (params++) {
/* prepared for more "-machine" parameters */
char *tmp = params;
params = strchr(params, ',');
if (STRPREFIX(param, "type="))
param += strlen("type=");
if (!strchr(param, '=')) {
if (VIR_STRDUP(def->os.machine, param) < 0) {
virStringFreeList(list);
goto error;
}
j++;
}
if (STRPREFIX(tmp, "dump-guest-core=")) {
tmp += strlen("dump-guest-core=");
if (params && VIR_STRNDUP(tmp, tmp, params - tmp) < 0)
goto error;
def->mem.dump_core = virDomainMemDumpTypeFromString(tmp);
if (def->mem.dump_core <= 0)
def->mem.dump_core = VIR_DOMAIN_MEM_DUMP_DEFAULT;
if (params)
VIR_FREE(tmp);
} else if (STRPREFIX(tmp, "mem-merge=off")) {
def->mem.nosharepages = true;
}
/* handle all remaining "-machine" parameters */
while ((param = list[j++])) {
if (STRPREFIX(param, "dump-guest-core=")) {
param += strlen("dump-guest-core=");
def->mem.dump_core = virDomainMemDumpTypeFromString(param);
if (def->mem.dump_core <= 0)
def->mem.dump_core = VIR_DOMAIN_MEM_DUMP_DEFAULT;
} else if (STRPREFIX(param, "mem-merge=off")) {
def->mem.nosharepages = true;
} else if (STRPREFIX(param, "accel=kvm")) {
def->virtType = VIR_DOMAIN_VIRT_KVM;
def->features |= (1 << VIR_DOMAIN_FEATURE_PAE);
}
}
virStringFreeList(list);
} else if (STREQ(arg, "-serial")) {
WANT_VALUE();
if (STRNEQ(val, "none")) {