[libvirt][qemu] unable to start guest under kvm

Hi, all. I have the following problem: when I creating a guest, libvirt resolves <type ... machine="pc" ...> to <type ... machine="pc-0.11" ...> as provided by http://www.mail-archive.com/libvir-list@redhat.com/msg15014.html When <type ... machine="pc-0.11" ...> or <type ... machine="pc-0.10" ...> is set, I get two following errors (which would happend is unpredictable) # virsh -c qemu:///system start $d error: Failed to start domain Desktop error: internal error unable to start guest: Supported machines are: pc Standard PC (default) isapc ISA-only PC and # virsh -c qemu:///system start $d error: Failed to start domain Desktop error: monitor socket did not show up.: Connection refused When <type ... machine="pc" ...> is set, this guest starts successfully. The domain type of this machine is "kvm". But I have # qemu --version && kvm --help | head -1 QEMU PC emulator version 0.11.50, Copyright (c) 2003-2008 Fabrice Bellard QEMU PC emulator version 0.10.0 (kvm-devel), Copyright (c) 2003-2008 Fabrice Bellard on that HN. - why does libvirt sets machine to "pc-0.11" even if kvm qemu version is 0.10? - why does an error occure if I set <type ... machine="pc-0.10 ... ">

On Mon, 2009-09-07 at 14:07 +0400, Anton Protopopov wrote:
Hi, all.
I have the following problem: when I creating a guest, libvirt resolves <type ... machine="pc" ...> to <type ... machine="pc-0.11" ...> as provided by http://www.mail-archive.com/libvir-list@redhat.com/msg15014.html
When <type ... machine="pc-0.11" ...> or <type ... machine="pc-0.10" ...> is set, I get two following errors (which would happend is unpredictable) # virsh -c qemu:///system start $d error: Failed to start domain Desktop error: internal error unable to start guest: Supported machines are: pc Standard PC (default) isapc ISA-only PC and # virsh -c qemu:///system start $d error: Failed to start domain Desktop error: monitor socket did not show up.: Connection refused When <type ... machine="pc" ...> is set, this guest starts successfully.
What does 'virsh dumpxml $d | grep emulator' give? Also, what is the output of 'virsh capabilities' ?
The domain type of this machine is "kvm". But I have # qemu --version && kvm --help | head -1 QEMU PC emulator version 0.11.50, Copyright (c) 2003-2008 Fabrice Bellard QEMU PC emulator version 0.10.0 (kvm-devel), Copyright (c) 2003-2008 Fabrice Bellard on that HN.
What does 'qemu -M ?' and 'kvm -M ?' give?
- why does libvirt sets machine to "pc-0.11" even if kvm qemu version is 0.10? - why does an error occure if I set <type ... machine="pc-0.10 ... ">
I suspect the capabilities output is saying that /usr/bin/kvm supports the pc-0.11 machine type, when in fact only /usr/bin/qemu supports it Cheers, Mark.

What does 'virsh dumpxml $d | grep emulator' give?
<emulator>/usr/bin/kvm</emulator> Also, what is the output of 'virsh capabilities' ?
<guest> <os_type>hvm</os_type> <arch name='x86_64'> <wordsize>64</wordsize> <emulator>/usr/bin/qemu-system-x86_64</emulator> <machine>pc-0.11</machine> <machine canonical='pc-0.11'>pc</machine> <machine>pc-0.10</machine> <machine>isapc</machine> <domain type='qemu'> </domain> <domain type='kvm'> <emulator>/usr/bin/kvm</emulator> </domain> </arch> <features> <acpi default='on' toggle='yes'/> <apic default='on' toggle='no'/> </features> </guest> What does 'qemu -M ?' and 'kvm -M ?' give?
# qemu -M ? Supported machines are: pc Standard PC (alias of pc-0.11) pc-0.11 Standard PC (default) pc-0.10 Standard PC, qemu 0.10 isapc ISA-only PC # kvm -M ? Supported machines are: pc Standard PC (default) isapc ISA-only PC
I suspect the capabilities output is saying that /usr/bin/kvm supports the pc-0.11 machine type, when in fact only /usr/bin/qemu supports it
Yes

On Mon, 2009-09-07 at 14:40 +0400, Anton Protopopov wrote:
Also, what is the output of 'virsh capabilities' ? <guest> <os_type>hvm</os_type> <arch name='x86_64'> <wordsize>64</wordsize> <emulator>/usr/bin/qemu-system-x86_64</emulator> <machine>pc-0.11</machine> <machine canonical='pc-0.11'>pc</machine> <machine>pc-0.10</machine> <machine>isapc</machine> <domain type='qemu'> </domain> <domain type='kvm'> <emulator>/usr/bin/kvm</emulator> </domain>
...
What does 'qemu -M ?' and 'kvm -M ?' give? # qemu -M ? Supported machines are: pc Standard PC (alias of pc-0.11) pc-0.11 Standard PC (default) pc-0.10 Standard PC, qemu 0.10 isapc ISA-only PC # kvm -M ? Supported machines are: pc Standard PC (default) isapc ISA-only PC
Thanks, that shows the problem clearly. We need to probe the kvm binary for the machine types it supports and include it in its domain info. Please try out the four patches following Cheers, Mark.

We need to look at all the domain infos in guest capabilities, not just the defaults. In order to allow that, split out a qemudGetOldMachinesFromInfo() from qemudGetOldMachines(). We'll make more use of it in the next patch. * src/qemu_conf.c: split out qemudGetOldMachinesFromInfo() from qemudGetOldMachines() --- src/qemu_conf.c | 96 ++++++++++++++++++++++++++++++++----------------------- 1 files changed, 56 insertions(+), 40 deletions(-) diff --git a/src/qemu_conf.c b/src/qemu_conf.c index caf518c..50fbb3c 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -496,6 +496,57 @@ rewait: } static int +qemudGetOldMachinesFromInfo(virCapsGuestDomainInfoPtr info, + const char *emulator, + time_t emulator_mtime, + virCapsGuestMachinePtr **machines, + int *nmachines) +{ + virCapsGuestMachinePtr *list; + int i; + + if (!info->emulator || !STREQ(emulator, info->emulator)) + return 0; + + if (emulator_mtime != info->emulator_mtime) { + VIR_DEBUG("mtime on %s has changed, refreshing machine types", + info->emulator); + return 0; + } + + /* It sucks to have to dup these, when we're most likely going + * to free the old caps anyway - except if an error occurs, we'll + * stick with the old caps. + * Also, if we get OOM here, just let the caller try and probe + * the binary directly, which will probably fail too. + */ + if (VIR_ALLOC_N(list, info->nmachines) < 0) + return 0; + + for (i = 0; i < info->nmachines; i++) { + if (VIR_ALLOC(list[i]) < 0) { + virCapabilitiesFreeMachines(list, info->nmachines); + return 0; + } + if (info->machines[i]->name && + !(list[i]->name = strdup(info->machines[i]->name))) { + virCapabilitiesFreeMachines(list, info->nmachines); + return 0; + } + if (info->machines[i]->canonical && + !(list[i]->canonical = strdup(info->machines[i]->canonical))) { + virCapabilitiesFreeMachines(list, info->nmachines); + return 0; + } + } + + *machines = list; + *nmachines = info->nmachines; + + return 1; +} + +static int qemudGetOldMachines(const char *ostype, const char *arch, int wordsize, @@ -509,51 +560,16 @@ qemudGetOldMachines(const char *ostype, for (i = 0; i < old_caps->nguests; i++) { virCapsGuestPtr guest = old_caps->guests[i]; - virCapsGuestDomainInfoPtr info = &guest->arch.defaultInfo; - virCapsGuestMachinePtr *list; if (!STREQ(ostype, guest->ostype) || !STREQ(arch, guest->arch.name) || - wordsize != guest->arch.wordsize || - !STREQ(emulator, info->emulator)) + wordsize != guest->arch.wordsize) continue; - if (emulator_mtime != info->emulator_mtime) { - VIR_DEBUG("mtime on %s has changed, refreshing machine types", - info->emulator); - return 0; - } - - /* It sucks to have to dup these, when we're most likely going - * to free the old caps anyway - except if an error occurs, we'll - * stick with the old caps. - * Also, if we get OOM here, just let the caller try and probe - * the binary directly, which will probably fail too. - */ - if (VIR_ALLOC_N(list, info->nmachines) < 0) - return 0; - - for (i = 0; i < info->nmachines; i++) { - if (VIR_ALLOC(list[i]) < 0) { - virCapabilitiesFreeMachines(list, info->nmachines); - return 0; - } - if (info->machines[i]->name && - !(list[i]->name = strdup(info->machines[i]->name))) { - virCapabilitiesFreeMachines(list, info->nmachines); - return 0; - } - if (info->machines[i]->canonical && - !(list[i]->canonical = strdup(info->machines[i]->canonical))) { - virCapabilitiesFreeMachines(list, info->nmachines); - return 0; - } - } - - *machines = list; - *nmachines = info->nmachines; - - return 1; + if (qemudGetOldMachinesFromInfo(&guest->arch.defaultInfo, + emulator, emulator_mtime, + machines, nmachines)) + return 1; } return 0; -- 1.6.2.5

On Mon, Sep 07, 2009 at 02:44:11PM +0100, Mark McLoughlin wrote:
We need to look at all the domain infos in guest capabilities, not just the defaults.
In order to allow that, split out a qemudGetOldMachinesFromInfo() from qemudGetOldMachines(). We'll make more use of it in the next patch.
* src/qemu_conf.c: split out qemudGetOldMachinesFromInfo() from qemudGetOldMachines() [...] + /* It sucks to have to dup these, when we're most likely going
Hum, maybe we could clean this comment a bit while we refactor it, I'm french but still :-) ACK to splitting out that chunk as a separated function, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Rather than just looking at the default domain info, look at all domains * src/qemu_conf.c: look at all domains in qemudGetOldMachines() --- src/qemu_conf.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 50fbb3c..9993065 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -560,12 +560,22 @@ qemudGetOldMachines(const char *ostype, for (i = 0; i < old_caps->nguests; i++) { virCapsGuestPtr guest = old_caps->guests[i]; + int j; if (!STREQ(ostype, guest->ostype) || !STREQ(arch, guest->arch.name) || wordsize != guest->arch.wordsize) continue; + for (j = 0; j < guest->arch.ndomains; j++) { + virCapsGuestDomainPtr dom = guest->arch.domains[j]; + + if (qemudGetOldMachinesFromInfo(&dom->info, + emulator, emulator_mtime, + machines, nmachines)) + return 1; + } + if (qemudGetOldMachinesFromInfo(&guest->arch.defaultInfo, emulator, emulator_mtime, machines, nmachines)) -- 1.6.2.5

Currently we only probe the main qemu binary for machine types, but we should also probe the kvm binary. * src/qemu_conf.c: probe kvm binary machines in qemudCapsInitGuest() --- src/qemu_conf.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 9993065..1e579a6 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -716,14 +716,44 @@ qemudCapsInitGuest(virCapsPtr caps, NULL) == NULL) return -1; - if (haskvm && - virCapabilitiesAddGuestDomain(guest, - "kvm", - kvmbin, - NULL, - 0, - NULL) == NULL) - return -1; + if (haskvm) { + machines = NULL; + nmachines = 0; + + if (stat(kvmbin, &st) == 0) { + binary_mtime = st.st_mtime; + } else { + char ebuf[1024]; + VIR_WARN(_("Failed to stat %s, most peculiar : %s"), + binary, virStrerror(errno, ebuf, sizeof(ebuf))); + binary_mtime = 0; + } + + if (!STREQ(binary, kvmbin)) { + int probe = 1; + if (old_caps && binary_mtime) + probe = !qemudGetOldMachines("hvm", info->arch, info->wordsize, + kvmbin, binary_mtime, + old_caps, &machines, &nmachines); + if (probe && + qemudProbeMachineTypes(kvmbin, &machines, &nmachines) < 0) + return -1; + } + + if (virCapabilitiesAddGuestDomain(guest, + "kvm", + kvmbin, + NULL, + nmachines, + machines) == NULL) { + for (i = 0; i < nmachines; i++) { + VIR_FREE(machines[i]->name); + VIR_FREE(machines[i]); + } + VIR_FREE(machines); + return -1; + } + } } else { if (virCapabilitiesAddGuestDomain(guest, "kvm", -- 1.6.2.5

* src/capabilities.c: fix machine type formatting in virCapabilitiesFormatXML() --- src/capabilities.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/capabilities.c b/src/capabilities.c index 289180d..38fe7fc 100644 --- a/src/capabilities.c +++ b/src/capabilities.c @@ -713,7 +713,7 @@ virCapabilitiesFormatXML(virCapsPtr caps) for (k = 0 ; k < caps->guests[i]->arch.domains[j]->info.nmachines ; k++) { virCapsGuestMachinePtr machine = caps->guests[i]->arch.domains[j]->info.machines[k]; - virBufferAddLit(&xml, " <machine"); + virBufferAddLit(&xml, " <machine"); if (machine->canonical) virBufferVSprintf(&xml, " canonical='%s'", machine->canonical); virBufferVSprintf(&xml, ">%s</machine>\n", machine->name); -- 1.6.2.5

On Mon, Sep 07, 2009 at 02:44:14PM +0100, Mark McLoughlin wrote:
* src/capabilities.c: fix machine type formatting in virCapabilitiesFormatXML() --- src/capabilities.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/capabilities.c b/src/capabilities.c index 289180d..38fe7fc 100644 --- a/src/capabilities.c +++ b/src/capabilities.c @@ -713,7 +713,7 @@ virCapabilitiesFormatXML(virCapsPtr caps)
for (k = 0 ; k < caps->guests[i]->arch.domains[j]->info.nmachines ; k++) { virCapsGuestMachinePtr machine = caps->guests[i]->arch.domains[j]->info.machines[k]; - virBufferAddLit(&xml, " <machine"); + virBufferAddLit(&xml, " <machine"); if (machine->canonical) virBufferVSprintf(&xml, " canonical='%s'", machine->canonical); virBufferVSprintf(&xml, ">%s</machine>\n", machine->name);
Ah, yes, theorically equivalent but nicer :-) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

2009/9/7 Mark McLoughlin <markmc@redhat.com>
On Mon, 2009-09-07 at 14:40 +0400, Anton Protopopov wrote:
Also, what is the output of 'virsh capabilities' ? <guest> <os_type>hvm</os_type> <arch name='x86_64'> <wordsize>64</wordsize> <emulator>/usr/bin/qemu-system-x86_64</emulator> <machine>pc-0.11</machine> <machine canonical='pc-0.11'>pc</machine> <machine>pc-0.10</machine> <machine>isapc</machine> <domain type='qemu'> </domain> <domain type='kvm'> <emulator>/usr/bin/kvm</emulator> </domain>
...
What does 'qemu -M ?' and 'kvm -M ?' give? # qemu -M ? Supported machines are: pc Standard PC (alias of pc-0.11) pc-0.11 Standard PC (default) pc-0.10 Standard PC, qemu 0.10 isapc ISA-only PC # kvm -M ? Supported machines are: pc Standard PC (default) isapc ISA-only PC
Thanks, that shows the problem clearly. We need to probe the kvm binary for the machine types it supports and include it in its domain info.
Please try out the four patches following
Thanks, I will try them tomorrow.
Cheers, Mark.

2009/9/7 Anton Protopopov <aspsk2@gmail.com>
2009/9/7 Mark McLoughlin <markmc@redhat.com>
On Mon, 2009-09-07 at 14:40 +0400, Anton Protopopov wrote:
Also, what is the output of 'virsh capabilities' ? <guest> <os_type>hvm</os_type> <arch name='x86_64'> <wordsize>64</wordsize> <emulator>/usr/bin/qemu-system-x86_64</emulator> <machine>pc-0.11</machine> <machine canonical='pc-0.11'>pc</machine> <machine>pc-0.10</machine> <machine>isapc</machine> <domain type='qemu'> </domain> <domain type='kvm'> <emulator>/usr/bin/kvm</emulator> </domain>
...
What does 'qemu -M ?' and 'kvm -M ?' give? # qemu -M ? Supported machines are: pc Standard PC (alias of pc-0.11) pc-0.11 Standard PC (default) pc-0.10 Standard PC, qemu 0.10 isapc ISA-only PC # kvm -M ? Supported machines are: pc Standard PC (default) isapc ISA-only PC
Thanks, that shows the problem clearly. We need to probe the kvm binary for the machine types it supports and include it in its domain info.
Please try out the four patches following
Thanks, I will try them tomorrow.
It didn't help. The capabilities changed to <guest> <os_type>hvm</os_type> <arch name='x86_64'> <wordsize>64</wordsize> <emulator>/usr/bin/qemu-system-x86_64</emulator> <machine>pc-0.11</machine> <machine canonical='pc-0.11'>pc</machine> <machine>pc-0.10</machine> <machine>isapc</machine> <domain type='qemu'> </domain> <domain type='kvm'> <emulator>/usr/bin/kvm</emulator> <machine>pc</machine> <machine>isapc</machine> </domain> </arch> <features> <acpi default='on' toggle='yes'/> <apic default='on' toggle='no'/> </features> </guest> But after defining a domain, I get # grep machine= $xml <type arch='x86_64' machine='pc-0.11'>hvm</type> again.

Hi, Okay, I've got this fixed for certain now. Definitely. I think. The problem turned out to be that qemudCanonicalizeMachine() was using the alias in the default machine types if the domain's machine types didn't have an alias that matched. We even have a test for this now, so hopefully it'll stay fixed too :-) If you want to test this, try the machine-types-fixes branch on: git://gitorious.org/~markmc/libvirt/markmc-staging.git Thanks, Mark.

2009/9/10 Mark McLoughlin <markmc@redhat.com>
Hi, Okay, I've got this fixed for certain now. Definitely. I think.
The problem turned out to be that qemudCanonicalizeMachine() was using the alias in the default machine types if the domain's machine types didn't have an alias that matched.
We even have a test for this now, so hopefully it'll stay fixed too :-)
If you want to test this, try the machine-types-fixes branch on:
git://gitorious.org/~markmc/libvirt/markmc-staging.git<http://gitorious.org/%7Emarkmc/libvirt/markmc-staging.git>
Though I didn't find branch machine-types-fixes in that repo, I checked your changes and they works fine for me :) Thanks
Thanks, Mark.

* src/capabilities.c: fix machine type formatting in virCapabilitiesFormatXML() --- src/capabilities.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/capabilities.c b/src/capabilities.c index 289180d..38fe7fc 100644 --- a/src/capabilities.c +++ b/src/capabilities.c @@ -713,7 +713,7 @@ virCapabilitiesFormatXML(virCapsPtr caps) for (k = 0 ; k < caps->guests[i]->arch.domains[j]->info.nmachines ; k++) { virCapsGuestMachinePtr machine = caps->guests[i]->arch.domains[j]->info.machines[k]; - virBufferAddLit(&xml, " <machine"); + virBufferAddLit(&xml, " <machine"); if (machine->canonical) virBufferVSprintf(&xml, " canonical='%s'", machine->canonical); virBufferVSprintf(&xml, ">%s</machine>\n", machine->name); -- 1.6.2.5

On Thu, Sep 10, 2009 at 12:35:09PM +0100, Mark McLoughlin wrote:
* src/capabilities.c: fix machine type formatting in virCapabilitiesFormatXML() --- src/capabilities.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/capabilities.c b/src/capabilities.c index 289180d..38fe7fc 100644 --- a/src/capabilities.c +++ b/src/capabilities.c @@ -713,7 +713,7 @@ virCapabilitiesFormatXML(virCapsPtr caps)
for (k = 0 ; k < caps->guests[i]->arch.domains[j]->info.nmachines ; k++) { virCapsGuestMachinePtr machine = caps->guests[i]->arch.domains[j]->info.machines[k]; - virBufferAddLit(&xml, " <machine"); + virBufferAddLit(&xml, " <machine"); if (machine->canonical) virBufferVSprintf(&xml, " canonical='%s'", machine->canonical); virBufferVSprintf(&xml, ">%s</machine>\n", machine->name);
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

* src/testutils.[ch]: make testDebug externally available * src/testutilsqemu.c: if VIR_TEST_DEBUG is set, dump the qemu driver capabilities to stderr --- tests/testutils.c | 3 ++- tests/testutils.h | 2 ++ tests/testutilsqemu.c | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 1 deletions(-) diff --git a/tests/testutils.c b/tests/testutils.c index 5072fec..536441a 100644 --- a/tests/testutils.c +++ b/tests/testutils.c @@ -45,8 +45,9 @@ ((((int) ((T)->tv_sec - (U)->tv_sec)) * 1000000.0 + \ ((int) ((T)->tv_usec - (U)->tv_usec))) / 1000.0) +unsigned int testDebug = 0; + static unsigned int testOOM = 0; -static unsigned int testDebug = 0; static unsigned int testCounter = 0; double diff --git a/tests/testutils.h b/tests/testutils.h index 96b246f..f036e0f 100644 --- a/tests/testutils.h +++ b/tests/testutils.h @@ -43,4 +43,6 @@ int virtTestMain(int argc, return virtTestMain(argc,argv, func); \ } +extern unsigned int testDebug; + #endif /* __VIT_TEST_UTILS_H__ */ diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index 58707e1..d8854be 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -4,6 +4,8 @@ #include <stdlib.h> #include "testutilsqemu.h" +#include "testutils.h" +#include "memory.h" virCapsPtr testQemuCapsInit(void) { struct utsname utsname; @@ -84,6 +86,18 @@ virCapsPtr testQemuCapsInit(void) { NULL) == NULL) goto cleanup; + if (testDebug) { + char *caps_str; + + caps_str = virCapabilitiesFormatXML(caps); + if (!caps_str) + goto cleanup; + + fprintf(stderr, "QEMU driver capabilities:\n%s", caps_str); + + VIR_FREE(caps_str); + } + return caps; cleanup: -- 1.6.2.5

On Thu, Sep 10, 2009 at 12:35:10PM +0100, Mark McLoughlin wrote:
* src/testutils.[ch]: make testDebug externally available
* src/testutilsqemu.c: if VIR_TEST_DEBUG is set, dump the qemu driver capabilities to stderr
ACK, useful ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

This doesn't have any affect on the current tests because we don't have any machine aliases in the current test data. * src/qemu_conf.h, src/qemu_driver.c: expose qemudCanonicalizeMachine() for the tests * tests/qemuxml2argvtest.c: canonicalize the machine type --- src/qemu_conf.h | 3 +++ src/qemu_driver.c | 7 +++---- tests/qemuxml2argvtest.c | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/qemu_conf.h b/src/qemu_conf.h index 9fa4559..ed91d2c 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -194,6 +194,9 @@ int qemudProbeMachineTypes (const char *binary, virCapsGuestMachinePtr **machines, int *nmachines); +int qemudCanonicalizeMachine (struct qemud_driver *driver, + virDomainDefPtr def); + virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, virCapsPtr caps, const char **progenv, diff --git a/src/qemu_driver.c b/src/qemu_driver.c index ae112d8..f2b0bec 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -4781,10 +4781,9 @@ qemudCanonicalizeMachineDirect(virDomainDefPtr def, char **canonical) return 0; } -static int -qemudCanonicalizeMachine(virConnectPtr conn, virDomainDefPtr def) +int +qemudCanonicalizeMachine(struct qemud_driver *driver, virDomainDefPtr def) { - struct qemud_driver *driver = conn->privateData; char *canonical = NULL; int i; @@ -4875,7 +4874,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { } } - if (qemudCanonicalizeMachine(conn, def) < 0) + if (qemudCanonicalizeMachine(driver, def) < 0) goto cleanup; if (!(vm = virDomainAssignDef(conn, diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d1cef0e..edd3744 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -56,6 +56,9 @@ static int testCompareXMLToArgvFiles(const char *xml, QEMUD_CMD_FLAG_NO_REBOOT | extraFlags; + if (qemudCanonicalizeMachine(&driver, vmdef) < 0) + goto fail; + if (qemudBuildCommandLine(NULL, &driver, vmdef, &monitor_chr, flags, &argv, &qenv, -- 1.6.2.5

On Thu, Sep 10, 2009 at 12:35:11PM +0100, Mark McLoughlin wrote:
This doesn't have any affect on the current tests because we don't have any machine aliases in the current test data.
* src/qemu_conf.h, src/qemu_driver.c: expose qemudCanonicalizeMachine() for the tests
* tests/qemuxml2argvtest.c: canonicalize the machine type --- src/qemu_conf.h | 3 +++ src/qemu_driver.c | 7 +++---- tests/qemuxml2argvtest.c | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/qemu_conf.h b/src/qemu_conf.h index 9fa4559..ed91d2c 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -194,6 +194,9 @@ int qemudProbeMachineTypes (const char *binary, virCapsGuestMachinePtr **machines, int *nmachines);
+int qemudCanonicalizeMachine (struct qemud_driver *driver, + virDomainDefPtr def); + virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, virCapsPtr caps, const char **progenv, diff --git a/src/qemu_driver.c b/src/qemu_driver.c index ae112d8..f2b0bec 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -4781,10 +4781,9 @@ qemudCanonicalizeMachineDirect(virDomainDefPtr def, char **canonical) return 0; }
-static int -qemudCanonicalizeMachine(virConnectPtr conn, virDomainDefPtr def) +int +qemudCanonicalizeMachine(struct qemud_driver *driver, virDomainDefPtr def) { - struct qemud_driver *driver = conn->privateData; char *canonical = NULL; int i;
@@ -4875,7 +4874,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { } }
- if (qemudCanonicalizeMachine(conn, def) < 0) + if (qemudCanonicalizeMachine(driver, def) < 0) goto cleanup;
if (!(vm = virDomainAssignDef(conn, diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d1cef0e..edd3744 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -56,6 +56,9 @@ static int testCompareXMLToArgvFiles(const char *xml, QEMUD_CMD_FLAG_NO_REBOOT | extraFlags;
+ if (qemudCanonicalizeMachine(&driver, vmdef) < 0) + goto fail; + if (qemudBuildCommandLine(NULL, &driver, vmdef, &monitor_chr, flags, &argv, &qenv,
Okay, the patch to source is minor, and this will help later on testing, ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

* test/testutilsqemu.c: split out code to testQemuAllocMachines() and make use of the ARRAY_CARDINALITY macro --- tests/testutilsqemu.c | 30 +++++++++++++++++++++--------- 1 files changed, 21 insertions(+), 9 deletions(-) diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index d8854be..d85e4c7 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -7,15 +7,29 @@ #include "testutils.h" #include "memory.h" +static virCapsGuestMachinePtr *testQemuAllocMachines(int *nmachines) +{ + virCapsGuestMachinePtr *machines; + static const char *const x86_machines[] = { + "pc", "isapc" + }; + + machines = virCapabilitiesAllocMachines(x86_machines, + ARRAY_CARDINALITY(x86_machines)); + if (machines == NULL) + return NULL; + + *nmachines = ARRAY_CARDINALITY(x86_machines); + + return machines; +} + virCapsPtr testQemuCapsInit(void) { struct utsname utsname; virCapsPtr caps; virCapsGuestPtr guest; virCapsGuestMachinePtr *machines; int nmachines; - static const char *const x86_machines[] = { - "pc", "isapc" - }; static const char *const xen_machines[] = { "xenner" }; @@ -25,8 +39,7 @@ virCapsPtr testQemuCapsInit(void) { 0, 0)) == NULL) return NULL; - nmachines = 2; - if ((machines = virCapabilitiesAllocMachines(x86_machines, nmachines)) == NULL) + if ((machines = testQemuAllocMachines(&nmachines)) == NULL) goto cleanup; if ((guest = virCapabilitiesAddGuest(caps, "hvm", "i686", 32, @@ -43,8 +56,7 @@ virCapsPtr testQemuCapsInit(void) { NULL) == NULL) goto cleanup; - nmachines = 2; - if ((machines = virCapabilitiesAllocMachines(x86_machines, nmachines)) == NULL) + if ((machines = testQemuAllocMachines(&nmachines)) == NULL) goto cleanup; if ((guest = virCapabilitiesAddGuest(caps, "hvm", "x86_64", 64, @@ -68,13 +80,13 @@ virCapsPtr testQemuCapsInit(void) { NULL) == NULL) goto cleanup; - nmachines = 1; + nmachines = ARRAY_CARDINALITY(xen_machines); if ((machines = virCapabilitiesAllocMachines(xen_machines, nmachines)) == NULL) goto cleanup; if ((guest = virCapabilitiesAddGuest(caps, "xen", "x86_64", 64, "/usr/bin/xenner", NULL, - 1, machines)) == NULL) + nmachines, machines)) == NULL) goto cleanup; machines = NULL; -- 1.6.2.5

On Thu, Sep 10, 2009 at 12:35:12PM +0100, Mark McLoughlin wrote:
* test/testutilsqemu.c: split out code to testQemuAllocMachines() and make use of the ARRAY_CARDINALITY macro --- tests/testutilsqemu.c | 30 +++++++++++++++++++++--------- 1 files changed, 21 insertions(+), 9 deletions(-)
cleanup, ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

* tests/testutilsqemu.c: make 'pc' an alias for qemu-system-x86_64 * tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.*, tests/qemuxml2argvtest.c: add a test which uses qemu-system-x86_64 and make sure the machine type is canonicalized. --- .../qemuxml2argv-machine-aliases1.args | 1 + .../qemuxml2argv-machine-aliases1.xml | 22 ++++++++++++++ tests/qemuxml2argvtest.c | 1 + tests/testutilsqemu.c | 31 +++++++++++++++++++- 4 files changed, 54 insertions(+), 1 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.args b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.args new file mode 100644 index 0000000..4f62cb1 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-system-x86_64 -S -M pc-0.11 -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml new file mode 100644 index 0000000..039abfd --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml @@ -0,0 +1,22 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index edd3744..afaf392 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -190,6 +190,7 @@ mymain(int argc, char **argv) unsetenv("LD_LIBRARY_PATH"); DO_TEST("minimal", QEMUD_CMD_FLAG_NAME); + DO_TEST("machine-aliases1", 0); DO_TEST("boot-cdrom", 0); DO_TEST("boot-network", 0); DO_TEST("boot-floppy", 0); diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index d85e4c7..ad58010 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -24,6 +24,35 @@ static virCapsGuestMachinePtr *testQemuAllocMachines(int *nmachines) return machines; } +/* Newer versions of qemu have versioned machine types to allow + * compatibility with older releases. + * The 'pc' machine type is an alias of the newest machine type. + */ +static virCapsGuestMachinePtr *testQemuAllocNewerMachines(int *nmachines) +{ + virCapsGuestMachinePtr *machines; + char *canonical; + static const char *const x86_machines[] = { + "pc-0.11", "pc", "pc-0.10", "isapc" + }; + + if ((canonical = strdup(x86_machines[0])) == NULL) + return NULL; + + machines = virCapabilitiesAllocMachines(x86_machines, + ARRAY_CARDINALITY(x86_machines)); + if (machines == NULL) { + VIR_FREE(canonical); + return NULL; + } + + machines[1]->canonical = canonical; + + *nmachines = ARRAY_CARDINALITY(x86_machines); + + return machines; +} + virCapsPtr testQemuCapsInit(void) { struct utsname utsname; virCapsPtr caps; @@ -56,7 +85,7 @@ virCapsPtr testQemuCapsInit(void) { NULL) == NULL) goto cleanup; - if ((machines = testQemuAllocMachines(&nmachines)) == NULL) + if ((machines = testQemuAllocNewerMachines(&nmachines)) == NULL) goto cleanup; if ((guest = virCapabilitiesAddGuest(caps, "hvm", "x86_64", 64, -- 1.6.2.5

On Thu, Sep 10, 2009 at 12:35:13PM +0100, Mark McLoughlin wrote:
* tests/testutilsqemu.c: make 'pc' an alias for qemu-system-x86_64
* tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.*, tests/qemuxml2argvtest.c: add a test which uses qemu-system-x86_64 and make sure the machine type is canonicalized. --- .../qemuxml2argv-machine-aliases1.args | 1 + .../qemuxml2argv-machine-aliases1.xml | 22 ++++++++++++++ tests/qemuxml2argvtest.c | 1 + tests/testutilsqemu.c | 31 +++++++++++++++++++- 4 files changed, 54 insertions(+), 1 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.args b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.args new file mode 100644 index 0000000..4f62cb1 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-system-x86_64 -S -M pc-0.11 -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml new file mode 100644 index 0000000..039abfd --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml @@ -0,0 +1,22 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index edd3744..afaf392 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -190,6 +190,7 @@ mymain(int argc, char **argv) unsetenv("LD_LIBRARY_PATH");
DO_TEST("minimal", QEMUD_CMD_FLAG_NAME); + DO_TEST("machine-aliases1", 0); DO_TEST("boot-cdrom", 0); DO_TEST("boot-network", 0); DO_TEST("boot-floppy", 0); diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index d85e4c7..ad58010 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -24,6 +24,35 @@ static virCapsGuestMachinePtr *testQemuAllocMachines(int *nmachines) return machines; }
+/* Newer versions of qemu have versioned machine types to allow + * compatibility with older releases. + * The 'pc' machine type is an alias of the newest machine type. + */ +static virCapsGuestMachinePtr *testQemuAllocNewerMachines(int *nmachines) +{ + virCapsGuestMachinePtr *machines; + char *canonical; + static const char *const x86_machines[] = { + "pc-0.11", "pc", "pc-0.10", "isapc" + }; + + if ((canonical = strdup(x86_machines[0])) == NULL) + return NULL; + + machines = virCapabilitiesAllocMachines(x86_machines, + ARRAY_CARDINALITY(x86_machines)); + if (machines == NULL) { + VIR_FREE(canonical); + return NULL; + } + + machines[1]->canonical = canonical; + + *nmachines = ARRAY_CARDINALITY(x86_machines); + + return machines; +} + virCapsPtr testQemuCapsInit(void) { struct utsname utsname; virCapsPtr caps; @@ -56,7 +85,7 @@ virCapsPtr testQemuCapsInit(void) { NULL) == NULL) goto cleanup;
- if ((machines = testQemuAllocMachines(&nmachines)) == NULL) + if ((machines = testQemuAllocNewerMachines(&nmachines)) == NULL) goto cleanup;
if ((guest = virCapabilitiesAddGuest(caps, "hvm", "x86_64", 64,
ACK, more tests is good, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

We need to look at all the domain infos in guest capabilities, not just the defaults. In order to allow that, split out a qemudGetOldMachinesFromInfo() from qemudGetOldMachines(). We'll make more use of it in the next patch. * src/qemu_conf.c: split out qemudGetOldMachinesFromInfo() from qemudGetOldMachines() --- src/qemu_conf.c | 90 ++++++++++++++++++++++++++++++------------------------ 1 files changed, 50 insertions(+), 40 deletions(-) diff --git a/src/qemu_conf.c b/src/qemu_conf.c index caf518c..882f9f9 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -496,6 +496,51 @@ rewait: } static int +qemudGetOldMachinesFromInfo(virCapsGuestDomainInfoPtr info, + const char *emulator, + time_t emulator_mtime, + virCapsGuestMachinePtr **machines, + int *nmachines) +{ + virCapsGuestMachinePtr *list; + int i; + + if (!info->emulator || !STREQ(emulator, info->emulator)) + return 0; + + if (emulator_mtime != info->emulator_mtime) { + VIR_DEBUG("mtime on %s has changed, refreshing machine types", + info->emulator); + return 0; + } + + if (VIR_ALLOC_N(list, info->nmachines) < 0) + return 0; + + for (i = 0; i < info->nmachines; i++) { + if (VIR_ALLOC(list[i]) < 0) { + virCapabilitiesFreeMachines(list, info->nmachines); + return 0; + } + if (info->machines[i]->name && + !(list[i]->name = strdup(info->machines[i]->name))) { + virCapabilitiesFreeMachines(list, info->nmachines); + return 0; + } + if (info->machines[i]->canonical && + !(list[i]->canonical = strdup(info->machines[i]->canonical))) { + virCapabilitiesFreeMachines(list, info->nmachines); + return 0; + } + } + + *machines = list; + *nmachines = info->nmachines; + + return 1; +} + +static int qemudGetOldMachines(const char *ostype, const char *arch, int wordsize, @@ -509,51 +554,16 @@ qemudGetOldMachines(const char *ostype, for (i = 0; i < old_caps->nguests; i++) { virCapsGuestPtr guest = old_caps->guests[i]; - virCapsGuestDomainInfoPtr info = &guest->arch.defaultInfo; - virCapsGuestMachinePtr *list; if (!STREQ(ostype, guest->ostype) || !STREQ(arch, guest->arch.name) || - wordsize != guest->arch.wordsize || - !STREQ(emulator, info->emulator)) + wordsize != guest->arch.wordsize) continue; - if (emulator_mtime != info->emulator_mtime) { - VIR_DEBUG("mtime on %s has changed, refreshing machine types", - info->emulator); - return 0; - } - - /* It sucks to have to dup these, when we're most likely going - * to free the old caps anyway - except if an error occurs, we'll - * stick with the old caps. - * Also, if we get OOM here, just let the caller try and probe - * the binary directly, which will probably fail too. - */ - if (VIR_ALLOC_N(list, info->nmachines) < 0) - return 0; - - for (i = 0; i < info->nmachines; i++) { - if (VIR_ALLOC(list[i]) < 0) { - virCapabilitiesFreeMachines(list, info->nmachines); - return 0; - } - if (info->machines[i]->name && - !(list[i]->name = strdup(info->machines[i]->name))) { - virCapabilitiesFreeMachines(list, info->nmachines); - return 0; - } - if (info->machines[i]->canonical && - !(list[i]->canonical = strdup(info->machines[i]->canonical))) { - virCapabilitiesFreeMachines(list, info->nmachines); - return 0; - } - } - - *machines = list; - *nmachines = info->nmachines; - - return 1; + if (qemudGetOldMachinesFromInfo(&guest->arch.defaultInfo, + emulator, emulator_mtime, + machines, nmachines)) + return 1; } return 0; -- 1.6.2.5

On Thu, Sep 10, 2009 at 12:35:14PM +0100, Mark McLoughlin wrote:
We need to look at all the domain infos in guest capabilities, not just the defaults.
In order to allow that, split out a qemudGetOldMachinesFromInfo() from qemudGetOldMachines(). We'll make more use of it in the next patch.
* src/qemu_conf.c: split out qemudGetOldMachinesFromInfo() from qemudGetOldMachines() --- src/qemu_conf.c | 90 ++++++++++++++++++++++++++++++------------------------ 1 files changed, 50 insertions(+), 40 deletions(-)
Hum, I really had to convince myself this was really functionally equivalent, but yes, ACK Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Rather than just looking at the default domain info, look at all domains * src/qemu_conf.c: look at all domains in qemudGetOldMachines() --- src/qemu_conf.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 882f9f9..0d498c2 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -554,12 +554,22 @@ qemudGetOldMachines(const char *ostype, for (i = 0; i < old_caps->nguests; i++) { virCapsGuestPtr guest = old_caps->guests[i]; + int j; if (!STREQ(ostype, guest->ostype) || !STREQ(arch, guest->arch.name) || wordsize != guest->arch.wordsize) continue; + for (j = 0; j < guest->arch.ndomains; j++) { + virCapsGuestDomainPtr dom = guest->arch.domains[j]; + + if (qemudGetOldMachinesFromInfo(&dom->info, + emulator, emulator_mtime, + machines, nmachines)) + return 1; + } + if (qemudGetOldMachinesFromInfo(&guest->arch.defaultInfo, emulator, emulator_mtime, machines, nmachines)) -- 1.6.2.5

On Thu, Sep 10, 2009 at 12:35:15PM +0100, Mark McLoughlin wrote:
Rather than just looking at the default domain info, look at all domains
* src/qemu_conf.c: look at all domains in qemudGetOldMachines() ---
I'm not entierely clear of what this actually does, but it sounds fine. Not 100% sure though, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Currently we only probe the main qemu binary for machine types, but we should also probe the kvm binary. * src/qemu_conf.c: probe kvm binary machines in qemudCapsInitGuest() --- src/qemu_conf.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 0d498c2..ddf7348 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -710,14 +710,48 @@ qemudCapsInitGuest(virCapsPtr caps, NULL) == NULL) return -1; - if (haskvm && - virCapabilitiesAddGuestDomain(guest, - "kvm", - kvmbin, - NULL, - 0, - NULL) == NULL) - return -1; + if (haskvm) { + virCapsGuestDomainPtr dom; + + if (stat(kvmbin, &st) == 0) { + binary_mtime = st.st_mtime; + } else { + char ebuf[1024]; + VIR_WARN(_("Failed to stat %s, most peculiar : %s"), + binary, virStrerror(errno, ebuf, sizeof(ebuf))); + binary_mtime = 0; + } + + machines = NULL; + nmachines = 0; + + if (!STREQ(binary, kvmbin)) { + int probe = 1; + if (old_caps && binary_mtime) + probe = !qemudGetOldMachines("hvm", info->arch, info->wordsize, + kvmbin, binary_mtime, + old_caps, &machines, &nmachines); + if (probe && + qemudProbeMachineTypes(kvmbin, &machines, &nmachines) < 0) + return -1; + } + + if ((dom = virCapabilitiesAddGuestDomain(guest, + "kvm", + kvmbin, + NULL, + nmachines, + machines)) == NULL) { + for (i = 0; i < nmachines; i++) { + VIR_FREE(machines[i]->name); + VIR_FREE(machines[i]); + } + VIR_FREE(machines); + return -1; + } + + dom->info.emulator_mtime = binary_mtime; + } } else { if (virCapabilitiesAddGuestDomain(guest, "kvm", -- 1.6.2.5

On Thu, Sep 10, 2009 at 12:35:16PM +0100, Mark McLoughlin wrote:
Currently we only probe the main qemu binary for machine types, but we should also probe the kvm binary.
* src/qemu_conf.c: probe kvm binary machines in qemudCapsInitGuest() --- src/qemu_conf.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 42 insertions(+), 8 deletions(-)
ACK, IIRC we have a bug about this, right ? Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The algorithm is quite simple: If the emulator matches a guest's domain: if domain has machine type info: check the domain's machine type info else check the guest's default machine type info else if the emulator matches the guest's default emulator: check the guest's default machine type info The previous implementation was incorrectly falling back to the default machine type info if the domain's machine type info didn't have an alias. * src/qemu_driver.c: simplify and fix qemudCanonicalizeMachine() --- src/qemu_driver.c | 33 +++++++++++++++------------------ 1 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/qemu_driver.c b/src/qemu_driver.c index f2b0bec..fad3939 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -4789,30 +4789,27 @@ qemudCanonicalizeMachine(struct qemud_driver *driver, virDomainDefPtr def) for (i = 0; i < driver->caps->nguests; i++) { virCapsGuestPtr guest = driver->caps->guests[i]; + virCapsGuestDomainInfoPtr info; int j; for (j = 0; j < guest->arch.ndomains; j++) { - virCapsGuestDomainPtr dom = guest->arch.domains[j]; + info = &guest->arch.domains[j]->info; - if (dom->info.emulator && - STREQ(dom->info.emulator, def->emulator)) { - if (qemudCanonicalizeMachineFromInfo(def, &dom->info, - &canonical) < 0) - return -1; - if (canonical) - goto out; - break; - } + if (!info->emulator || !STREQ(info->emulator, def->emulator)) + continue; + + if (!info->nmachines) + info = &guest->arch.defaultInfo; + + if (qemudCanonicalizeMachineFromInfo(def, info, &canonical) < 0) + return -1; + goto out; } - /* if we matched one of the domain's emulators, or if - * we match the default emulator - */ - if (j < guest->arch.ndomains || - (guest->arch.defaultInfo.emulator && - STREQ(guest->arch.defaultInfo.emulator, def->emulator))) { - if (qemudCanonicalizeMachineFromInfo(def, &guest->arch.defaultInfo, - &canonical) < 0) + info = &guest->arch.defaultInfo; + + if (info->emulator && STREQ(info->emulator, def->emulator)) { + if (qemudCanonicalizeMachineFromInfo(def, info, &canonical) < 0) return -1; goto out; } -- 1.6.2.5

On Thu, Sep 10, 2009 at 12:35:17PM +0100, Mark McLoughlin wrote:
The algorithm is quite simple:
If the emulator matches a guest's domain: if domain has machine type info: check the domain's machine type info else check the guest's default machine type info else if the emulator matches the guest's default emulator: check the guest's default machine type info
The previous implementation was incorrectly falling back to the default machine type info if the domain's machine type info didn't have an alias.
* src/qemu_driver.c: simplify and fix qemudCanonicalizeMachine() --- src/qemu_driver.c | 33 +++++++++++++++------------------ 1 files changed, 15 insertions(+), 18 deletions(-)
That looks simpler, I'm a bit worried about landing this so close to 0.7.1 release though, but I guess we have good reasons, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Thu, 2009-09-10 at 14:13 +0200, Daniel Veillard wrote:
On Thu, Sep 10, 2009 at 12:35:17PM +0100, Mark McLoughlin wrote:
The algorithm is quite simple:
If the emulator matches a guest's domain: if domain has machine type info: check the domain's machine type info else check the guest's default machine type info else if the emulator matches the guest's default emulator: check the guest's default machine type info
The previous implementation was incorrectly falling back to the default machine type info if the domain's machine type info didn't have an alias.
* src/qemu_driver.c: simplify and fix qemudCanonicalizeMachine() --- src/qemu_driver.c | 33 +++++++++++++++------------------ 1 files changed, 15 insertions(+), 18 deletions(-)
That looks simpler, I'm a bit worried about landing this so close to 0.7.1 release though, but I guess we have good reasons,
Yeah - it's basically a blocker for people like Anton who's installed kvm is newer than the installed qemu. Pushing now Cheers, Mark.

* tests/testutilsqemu.c: add a machine types list for /usr/bin/kvm which doesn't have any aliases, while the guest has aliases * tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.*, tests/qemuxml2argvtest.c: add a test using /usr/bin/kvm and make sure that 'pc' machine type doesn't get canonicalized using the aliases in the guest machine type list --- .../qemuxml2argv-machine-aliases2.args | 1 + .../qemuxml2argv-machine-aliases2.xml | 22 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + tests/testutilsqemu.c | 9 ++++++- 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.args b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.args new file mode 100644 index 0000000..1a7650d --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/kvm -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml new file mode 100644 index 0000000..6f62243 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml @@ -0,0 +1,22 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/kvm</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index afaf392..d0cf712 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -191,6 +191,7 @@ mymain(int argc, char **argv) DO_TEST("minimal", QEMUD_CMD_FLAG_NAME); DO_TEST("machine-aliases1", 0); + DO_TEST("machine-aliases2", 0); DO_TEST("boot-cdrom", 0); DO_TEST("boot-network", 0); DO_TEST("boot-floppy", 0); diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index ad58010..9269f5c 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -101,13 +101,18 @@ virCapsPtr testQemuCapsInit(void) { 0, NULL) == NULL) goto cleanup; + + if ((machines = testQemuAllocMachines(&nmachines)) == NULL) + goto cleanup; + if (virCapabilitiesAddGuestDomain(guest, "kvm", "/usr/bin/kvm", NULL, - 0, - NULL) == NULL) + nmachines, + machines) == NULL) goto cleanup; + machines = NULL; nmachines = ARRAY_CARDINALITY(xen_machines); if ((machines = virCapabilitiesAllocMachines(xen_machines, nmachines)) == NULL) -- 1.6.2.5

On Thu, Sep 10, 2009 at 12:35:18PM +0100, Mark McLoughlin wrote:
* tests/testutilsqemu.c: add a machine types list for /usr/bin/kvm which doesn't have any aliases, while the guest has aliases
* tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.*, tests/qemuxml2argvtest.c: add a test using /usr/bin/kvm and make sure that 'pc' machine type doesn't get canonicalized using the aliases in the guest machine type list --- .../qemuxml2argv-machine-aliases2.args | 1 + .../qemuxml2argv-machine-aliases2.xml | 22 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + tests/testutilsqemu.c | 9 ++++++- 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/
participants (3)
-
Anton Protopopov
-
Daniel Veillard
-
Mark McLoughlin