[libvirt] [PATCH v2 0/3] Implement mockup capabilities cache in QEMU tests

Since commit e8d55172544c1fafe31a9e09346bdebca4f0d6f9 qemu driver checks emulator capabilities during domain XML post-parse. However, test suite does not initialize it, therefore a condition to skip all checks if there is no cache supplied was added. This is actually a hack, whose sole purpose is to make existing test suite working. Additionally, it prevents from writing new tests for this particular functionality. This series solves this problem by implementing proper cache mockup in test suite. The main idea is to create a cache in standard way and put there pre-defined capabilities sets (which tests already have). In this implementation we introduce "test capability sets", which are named entities. virQEMUCapsCacheLookup() now has a test mode, which is enabled by setting qemuTestCapsName variable to the name of capability set which we want to use in current test. This is based on Martin Kletzander's idea to implement test mode with assertions. Currently, since name of capability set is different from /usr/bin/something, we will get errors if we try to do something with the host filesystem. This is achieved by setting cacheDir and libDir of our mockup cache to "/dev/null". The concept of using named capability sets allows us to further improve the test suite. Now it is possibe to get rid of hardcoded capability sets and replace them with XML files, readable by virQEMUCapsInitCached(). This will allow us to better exercise our capabilities parser. Taking this into account, qemuTestCapsCacheInsert() is actually temporary. It will not be needed any more when capabilities are moved to XML files. Additionally, some small refactoring is done, and common driver initialization and cleanup sequence is put into two functions: qemuTestDriverInit() and qemuTestDriverFree(). V1 => V2 - Fix also domainsnapshotxml2xmltest RFC => v1 - Major rework, almost everything changed. Pavel Fedin (3): Implement infrastracture for mocking up QEMU capabilities cache Use mockup cache Removed unneeded check src/qemu/qemu_capabilities.c | 16 +++++----- src/qemu/qemu_capspriv.h | 36 +++++++++++++++++++++++ src/qemu/qemu_domain.c | 5 +--- tests/domainsnapshotxml2xmltest.c | 15 +++++----- tests/qemuagenttest.c | 18 ++++++++---- tests/qemuargv2xmltest.c | 19 ++++++------ tests/qemuhotplugtest.c | 32 ++++++++++---------- tests/qemuxml2argvtest.c | 17 +++++------ tests/qemuxml2xmltest.c | 16 ++++++---- tests/qemuxmlnstest.c | 17 ++++++----- tests/testutilsqemu.c | 62 +++++++++++++++++++++++++++++++++++++++ tests/testutilsqemu.h | 9 ++++++ 12 files changed, 190 insertions(+), 72 deletions(-) mode change 100644 => 100755 src/qemu/qemu_capabilities.c create mode 100644 src/qemu/qemu_capspriv.h mode change 100644 => 100755 tests/qemuagenttest.c mode change 100644 => 100755 tests/qemuargv2xmltest.c mode change 100644 => 100755 tests/qemuhotplugtest.c mode change 100644 => 100755 tests/qemuxml2argvtest.c mode change 100644 => 100755 tests/qemuxml2xmltest.c mode change 100644 => 100755 tests/qemuxmlnstest.c mode change 100644 => 100755 tests/testutilsqemu.c mode change 100644 => 100755 tests/testutilsqemu.h -- 2.1.4

The main purpose of this patch is to introduce test mode to virQEMUCapsCacheLookup(). This is done by adding a global variable, which effectively overrides binary name. This variable is supposed to be set by test suite. The second addition is qemuTestCapsCacheInsert() function which allows the test suite to actually populate the cache. Third, two utility functions are introduced for proper initialization and cleanup of the driver. Signed-off-by: Pavel Fedin <p.fedin@samsung.com> --- src/qemu/qemu_capabilities.c | 16 +++++------- src/qemu/qemu_capspriv.h | 36 +++++++++++++++++++++++++ tests/testutilsqemu.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ tests/testutilsqemu.h | 9 +++++++ 4 files changed, 114 insertions(+), 9 deletions(-) mode change 100644 => 100755 src/qemu/qemu_capabilities.c create mode 100644 src/qemu/qemu_capspriv.h mode change 100644 => 100755 tests/testutilsqemu.c mode change 100644 => 100755 tests/testutilsqemu.h diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c old mode 100644 new mode 100755 index 43d11af..fa344b1 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -42,6 +42,7 @@ #include "virstring.h" #include "qemu_hostdev.h" #include "qemu_domain.h" +#include "qemu_capspriv.h" #include <fcntl.h> #include <sys/stat.h> @@ -327,15 +328,6 @@ struct _virQEMUCaps { unsigned int *machineMaxCpus; }; -struct _virQEMUCapsCache { - virMutex lock; - virHashTablePtr binaries; - char *libDir; - char *cacheDir; - uid_t runUid; - gid_t runGid; -}; - struct virQEMUCapsSearchData { virArch arch; }; @@ -3708,11 +3700,17 @@ virQEMUCapsCacheNew(const char *libDir, return NULL; } +const char *qemuTestCapsName; virQEMUCapsPtr virQEMUCapsCacheLookup(virQEMUCapsCachePtr cache, const char *binary) { virQEMUCapsPtr ret = NULL; + + /* This is used only by test suite!!! */ + if (qemuTestCapsName) + binary = qemuTestCapsName; + virMutexLock(&cache->lock); ret = virHashLookup(cache->binaries, binary); if (ret && diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h new file mode 100644 index 0000000..f915ea9 --- /dev/null +++ b/src/qemu/qemu_capspriv.h @@ -0,0 +1,36 @@ +/* + * qemu_capspriv.h: private declarations for QEMU capabilities generation + * + * Copyright (C) 2015 Samsung Electronics Co. Ltd + * Copyright (C) 2015 Pavel Fedin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Pavel Fedin <p.fedin@samsung.com> + */ + +#ifndef __QEMU_CAPSPRIV_H__ +#define __QEMU_CAPSPRIV_H__ + +struct _virQEMUCapsCache { + virMutex lock; + virHashTablePtr binaries; + char *libDir; + char *cacheDir; + uid_t runUid; + gid_t runGid; +}; + +#endif diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c old mode 100644 new mode 100755 index a2f4299..071a694 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -8,6 +8,7 @@ # include "cpu_conf.h" # include "qemu/qemu_driver.h" # include "qemu/qemu_domain.h" +# include "qemu/qemu_capspriv.h" # include "virstring.h" # define VIR_FROM_THIS VIR_FROM_QEMU @@ -526,4 +527,65 @@ qemuTestParseCapabilities(const char *capsFile) xmlXPathFreeContext(ctxt); return NULL; } + +int qemuTestDriverInit(virQEMUDriver *driver) +{ + driver->config = virQEMUDriverConfigNew(false); + if (!driver->config) + return -ENOMEM; + + driver->caps = testQemuCapsInit(); + if (!driver->caps) + goto cleanup; + + /* Using /dev/null for libDir and cacheDir automatically produces errors + * upon attempt to use any of them */ + driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0); + if (!driver->qemuCapsCache) + goto cleanup; + + driver->xmlopt = virQEMUDriverCreateXMLConf(driver); + if (driver->xmlopt) + return 0; + + virQEMUCapsCacheFree(driver->qemuCapsCache); +cleanup: + virObjectUnref(driver->caps); + virObjectUnref(driver->config); + return -ENOMEM; +} + +void qemuTestDriverFree(virQEMUDriver *driver) +{ + virObjectUnref(driver->xmlopt); + virQEMUCapsCacheFree(driver->qemuCapsCache); + virObjectUnref(driver->caps); + virObjectUnref(driver->config); +} + +int qemuTestCapsCacheInsert(virQEMUCapsCachePtr cache, const char *binary, + virQEMUCapsPtr caps) +{ + int ret; + + if (caps) { + /* Our caps were created artificially, so we don't want + * virQEMUCapsCacheFree() to attempt to deallocate them */ + virObjectRef(caps); + } else { + caps = virQEMUCapsNew(); + if (!caps) + return -ENOMEM; + } + + /* We can have repeating names for our test data sets, + * so make sure there's no old copy */ + virHashRemoveEntry(cache->binaries, binary); + + ret = virHashAddEntry(cache->binaries, binary, caps); + if (ret < 0) + virObjectUnref(caps); + + return ret; +} #endif diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h old mode 100644 new mode 100755 index 0ec5dad..53e882d --- a/tests/testutilsqemu.h +++ b/tests/testutilsqemu.h @@ -16,4 +16,13 @@ extern virCPUDefPtr cpuHaswell; void testQemuCapsSetCPU(virCapsPtr caps, virCPUDefPtr hostCPU); +int qemuTestDriverInit(virQEMUDriver *driver); +void qemuTestDriverFree(virQEMUDriver *driver); + +int qemuTestCapsCacheInsert(virQEMUCapsCachePtr cache, const char *binary, + virQEMUCapsPtr caps); + +/* This variable is actually defined in src/qemu/qemu_capabilities.c */ +extern const char *qemuTestCapsName; + #endif -- 2.1.4

Use the new API in order to correctly add capability sets to the cache before parsing XML files Signed-off-by: Pavel Fedin <p.fedin@samsung.com> --- tests/domainsnapshotxml2xmltest.c | 15 ++++++++------- tests/qemuagenttest.c | 18 +++++++++++++----- tests/qemuargv2xmltest.c | 19 +++++++++---------- tests/qemuhotplugtest.c | 32 +++++++++++++++++--------------- tests/qemuxml2argvtest.c | 17 ++++++++--------- tests/qemuxml2xmltest.c | 16 +++++++++++----- tests/qemuxmlnstest.c | 17 +++++++++-------- 7 files changed, 75 insertions(+), 59 deletions(-) mode change 100644 => 100755 tests/qemuagenttest.c mode change 100644 => 100755 tests/qemuargv2xmltest.c mode change 100644 => 100755 tests/qemuhotplugtest.c mode change 100644 => 100755 tests/qemuxml2argvtest.c mode change 100644 => 100755 tests/qemuxml2xmltest.c mode change 100644 => 100755 tests/qemuxmlnstest.c diff --git a/tests/domainsnapshotxml2xmltest.c b/tests/domainsnapshotxml2xmltest.c index 3955a19..9f4486d 100644 --- a/tests/domainsnapshotxml2xmltest.c +++ b/tests/domainsnapshotxml2xmltest.c @@ -152,13 +152,15 @@ mymain(void) { int ret = 0; - if ((driver.caps = testQemuCapsInit()) == NULL) + if (qemuTestDriverInit(&driver) < 0) return EXIT_FAILURE; - if (!(driver.xmlopt = virQEMUDriverCreateXMLConf(&driver))) { - virObjectUnref(driver.caps); - return EXIT_FAILURE; - } + driver.config->allowDiskFormatProbing = true; + + qemuTestCapsName = "empty"; + ret = qemuTestCapsCacheInsert(driver.qemuCapsCache, "empty", NULL); + if (ret < 0) + goto cleanup; if (VIR_ALLOC(testSnapshotXMLVariableLineRegex) < 0) goto cleanup; @@ -227,8 +229,7 @@ mymain(void) if (testSnapshotXMLVariableLineRegex) regfree(testSnapshotXMLVariableLineRegex); VIR_FREE(testSnapshotXMLVariableLineRegex); - virObjectUnref(driver.caps); - virObjectUnref(driver.xmlopt); + qemuTestDriverFree(&driver); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c old mode 100644 new mode 100755 index 52cc834..bc2fabc --- a/tests/qemuagenttest.c +++ b/tests/qemuagenttest.c @@ -31,6 +31,8 @@ #define VIR_FROM_THIS VIR_FROM_NONE +static virQEMUDriver driver; + static int testQemuAgentFSFreeze(const void *data) { @@ -909,7 +911,6 @@ static int mymain(void) { int ret = 0; - virDomainXMLOptionPtr xmlopt; #if !WITH_YAJL fputs("libvirt not compiled with yajl, skipping this test\n", stderr); @@ -917,13 +918,19 @@ mymain(void) #endif if (virThreadInitialize() < 0 || - !(xmlopt = virQEMUDriverCreateXMLConf(NULL))) + qemuTestDriverInit(&driver) < 0) return EXIT_FAILURE; + /* We use a single empty capability set for all tests here */ + qemuTestCapsName = "empty"; + ret = qemuTestCapsCacheInsert(driver.qemuCapsCache, "empty", NULL); + if (ret < 0) + goto cleanup; + virEventRegisterDefaultImpl(); -#define DO_TEST(name) \ - if (virtTestRun(# name, testQemuAgent ## name, xmlopt) < 0) \ +#define DO_TEST(name) \ + if (virtTestRun(# name, testQemuAgent ## name, driver.xmlopt) < 0) \ ret = -1 DO_TEST(FSFreeze); @@ -938,7 +945,8 @@ mymain(void) DO_TEST(Timeout); /* Timeout should always be called last */ - virObjectUnref(xmlopt); +cleanup: + qemuTestDriverFree(&driver); return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c old mode 100644 new mode 100755 index ea85913..bc20431 --- a/tests/qemuargv2xmltest.c +++ b/tests/qemuargv2xmltest.c @@ -145,15 +145,15 @@ mymain(void) { int ret = 0; - driver.config = virQEMUDriverConfigNew(false); - if (driver.config == NULL) + if (qemuTestDriverInit(&driver) < 0) return EXIT_FAILURE; - if ((driver.caps = testQemuCapsInit()) == NULL) - return EXIT_FAILURE; - - if (!(driver.xmlopt = virQEMUDriverCreateXMLConf(&driver))) - return EXIT_FAILURE; + /* We use a single empty capability set for all tests here */ + qemuTestCapsName = "empty"; + ret = qemuTestCapsCacheInsert(driver.qemuCapsCache, "empty", + NULL); + if (ret < 0) + goto cleanup; # define DO_TEST_FULL(name, flags) \ do { \ @@ -298,9 +298,8 @@ mymain(void) DO_TEST("machine-deakeywrap-off-argv"); DO_TEST("machine-keywrap-none-argv"); - virObjectUnref(driver.config); - virObjectUnref(driver.caps); - virObjectUnref(driver.xmlopt); +cleanup: + qemuTestDriverFree(&driver); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c old mode 100644 new mode 100755 index 368a5e7..109d820 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -57,7 +57,7 @@ static int qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, virDomainObjPtr *vm, const char *domxml, - bool event) + bool event, const char *testname) { int ret = -1; qemuDomainObjPrivatePtr priv = NULL; @@ -65,12 +65,6 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, if (!(*vm = virDomainObjNew(xmlopt))) goto cleanup; - if (!((*vm)->def = virDomainDefParseString(domxml, - driver.caps, - driver.xmlopt, - VIR_DOMAIN_DEF_PARSE_INACTIVE))) - goto cleanup; - priv = (*vm)->privateData; if (!(priv->qemuCaps = virQEMUCapsNew())) @@ -85,6 +79,18 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, if (event) virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT); + qemuTestCapsName = testname; + ret = qemuTestCapsCacheInsert(driver.qemuCapsCache, testname, + priv->qemuCaps); + if (ret < 0) + goto cleanup; + + if (!((*vm)->def = virDomainDefParseString(domxml, + driver.caps, + driver.xmlopt, + VIR_DOMAIN_DEF_PARSE_INACTIVE))) + goto cleanup; + if (qemuDomainAssignAddresses((*vm)->def, priv->qemuCaps, *vm) < 0) goto cleanup; @@ -243,7 +249,8 @@ testQemuHotplug(const void *data) vm = test->vm; } else { if (qemuHotplugCreateObjects(driver.xmlopt, &vm, domain_xml, - test->deviceDeletedEvent) < 0) + test->deviceDeletedEvent, + test->domain_filename) < 0) goto cleanup; } @@ -338,14 +345,11 @@ mymain(void) #endif if (virThreadInitialize() < 0 || - !(driver.caps = testQemuCapsInit()) || - !(driver.xmlopt = virQEMUDriverCreateXMLConf(&driver))) + qemuTestDriverInit(&driver) < 0) return EXIT_FAILURE; virEventRegisterDefaultImpl(); - if (!(driver.config = virQEMUDriverConfigNew(false))) - return EXIT_FAILURE; VIR_FREE(driver.config->spiceListen); VIR_FREE(driver.config->vncListen); /* some dummy values from 'config file' */ @@ -486,9 +490,7 @@ mymain(void) "device_del", QMP_DEVICE_DELETED("scsi0-0-0-5") QMP_OK, "human-monitor-command", HMP("")); - virObjectUnref(driver.caps); - virObjectUnref(driver.xmlopt); - virObjectUnref(driver.config); + qemuTestDriverFree(&driver); return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c old mode 100644 new mode 100755 index d4432df..1fc767e --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -423,6 +423,12 @@ testCompareXMLToArgvHelper(const void *data) if (virQEMUCapsGet(info->extraFlags, QEMU_CAPS_ENABLE_FIPS)) flags |= FLAG_FIPS; + qemuTestCapsName = info->name; + result = qemuTestCapsCacheInsert(driver.qemuCapsCache, info->name, + info->extraFlags); + if (result < 0) + goto cleanup; + result = testCompareXMLToArgvFiles(xml, args, info->extraFlags, info->migrateFrom, info->migrateFd, flags); @@ -483,8 +489,7 @@ mymain(void) return EXIT_FAILURE; } - driver.config = virQEMUDriverConfigNew(false); - if (driver.config == NULL) + if (qemuTestDriverInit(&driver) < 0) return EXIT_FAILURE; driver.privileged = true; @@ -499,10 +504,6 @@ mymain(void) if (VIR_STRDUP_QUIET(driver.config->spiceTLSx509certdir, "/etc/pki/libvirt-spice") < 0) return EXIT_FAILURE; - if ((driver.caps = testQemuCapsInit()) == NULL) - return EXIT_FAILURE; - if (!(driver.xmlopt = virQEMUDriverCreateXMLConf(&driver))) - return EXIT_FAILURE; VIR_FREE(driver.config->stateDir); if (VIR_STRDUP_QUIET(driver.config->stateDir, "/nowhere") < 0) return EXIT_FAILURE; @@ -1761,9 +1762,7 @@ mymain(void) QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_DRIVE, QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_CCW, QEMU_CAPS_VIRTIO_S390); - virObjectUnref(driver.config); - virObjectUnref(driver.caps); - virObjectUnref(driver.xmlopt); + qemuTestDriverFree(&driver); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c old mode 100644 new mode 100755 index 5a20ebc..176e97a --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -302,11 +302,17 @@ mymain(void) int ret = 0; struct testInfo info; - if ((driver.caps = testQemuCapsInit()) == NULL) + if (qemuTestDriverInit(&driver) < 0) return EXIT_FAILURE; - if (!(driver.xmlopt = virQEMUDriverCreateXMLConf(&driver))) - return EXIT_FAILURE; + driver.config->allowDiskFormatProbing = true; + + /* We use a single empty capability set for all tests here */ + qemuTestCapsName = "empty"; + ret = qemuTestCapsCacheInsert(driver.qemuCapsCache, "empty", + NULL); + if (ret < 0) + goto cleanup; # define DO_TEST_FULL(name, is_different, when) \ do { \ @@ -631,8 +637,8 @@ mymain(void) DO_TEST("memory-hotplug-dimm"); DO_TEST("net-udp"); - virObjectUnref(driver.caps); - virObjectUnref(driver.xmlopt); +cleanup: + qemuTestDriverFree(&driver); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/qemuxmlnstest.c b/tests/qemuxmlnstest.c old mode 100644 new mode 100755 index a68e762..65bf1d3 --- a/tests/qemuxmlnstest.c +++ b/tests/qemuxmlnstest.c @@ -179,6 +179,12 @@ testCompareXMLToArgvHelper(const void *data) abs_srcdir, info->name) < 0) goto cleanup; + qemuTestCapsName = info->name; + result = qemuTestCapsCacheInsert(driver.qemuCapsCache, info->name, + info->extraFlags); + if (result < 0) + goto cleanup; + result = testCompareXMLToArgvFiles(xml, args, info->extraFlags, info->migrateFrom, info->migrateFd, info->json, info->expectError); @@ -201,15 +207,12 @@ mymain(void) if (!abs_top_srcdir) abs_top_srcdir = abs_srcdir "/.."; - if (!(driver.config = virQEMUDriverConfigNew(false))) + if (qemuTestDriverInit(&driver) < 0) return EXIT_FAILURE; + VIR_FREE(driver.config->libDir); if (VIR_STRDUP_QUIET(driver.config->libDir, "/tmp") < 0) return EXIT_FAILURE; - if ((driver.caps = testQemuCapsInit()) == NULL) - return EXIT_FAILURE; - if (!(driver.xmlopt = virQEMUDriverCreateXMLConf(&driver))) - return EXIT_FAILURE; # define DO_TEST_FULL(name, migrateFrom, migrateFd, expectError, ...) \ do { \ @@ -251,9 +254,7 @@ mymain(void) DO_TEST("qemu-ns-commandline-ns0", false, NONE); DO_TEST("qemu-ns-commandline-ns1", false, NONE); - virObjectUnref(driver.config); - virObjectUnref(driver.caps); - virObjectUnref(driver.xmlopt); + qemuTestDriverFree(&driver); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } -- 2.1.4

Since test suite now correctly creates capabilities cache, the hack is not needed any more. Signed-off-by: Pavel Fedin <p.fedin@samsung.com> --- src/qemu/qemu_domain.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 91c632c..3de755c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1039,10 +1039,7 @@ qemuDomainDefPostParse(virDomainDefPtr def, return ret; - /* This condition is actually a (temporary) hack for test suite which - * does not create capabilities cache */ - if (driver && driver->qemuCapsCache) - qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, def->emulator); + qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, def->emulator); /* Add implicit PCI root controller if the machine has one */ switch (def->os.arch) { -- 2.1.4
participants (1)
-
Pavel Fedin