]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: don't use passed in caps in post parse method
authorDaniel P. Berrangé <berrange@redhat.com>
Tue, 3 Dec 2019 10:49:49 +0000 (10:49 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Mon, 9 Dec 2019 10:15:16 +0000 (10:15 +0000)
To enable the virCapsPtr parameter to the post parse method to be
eliminated, the drivers must fetch the virCapsPtr from their own
driver via the opaque parameter, or use an alternative approach
to validate the parsed data.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
35 files changed:
src/bhyve/bhyve_domain.c
src/esx/esx_driver.c
src/libxl/libxl_conf.c
src/libxl/libxl_conf.h
src/libxl/libxl_domain.c
src/libxl/libxl_driver.c
src/lxc/lxc_conf.c
src/lxc/lxc_conf.h
src/lxc/lxc_controller.c
src/lxc/lxc_domain.c
src/lxc/lxc_driver.c
src/openvz/openvz_conf.c
src/openvz/openvz_conf.h
src/openvz/openvz_driver.c
src/phyp/phyp_driver.c
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
src/qemu/qemu_domain.c
src/vmware/vmware_driver.c
src/vmx/vmx.c
src/vmx/vmx.h
src/vz/vz_driver.c
tests/Makefile.am
tests/libxlxml2domconfigtest.c
tests/lxcconf2xmltest.c
tests/lxcxml2xmltest.c
tests/openvzutilstest.c
tests/testutilslxc.c
tests/testutilslxc.h
tests/testutilsxen.c
tests/testutilsxen.h
tests/vmx2xmltest.c
tests/xlconfigtest.c
tests/xmconfigtest.c
tests/xml2vmxtest.c

index 575f141b53728b409cb42b4846bece4cb727e09b..eebf5a765032890f7534c1b91071608ac5301c0d 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <config.h>
 
+#include "bhyve_driver.h"
 #include "bhyve_conf.h"
 #include "bhyve_device.h"
 #include "bhyve_domain.h"
@@ -74,11 +75,16 @@ bhyveDomainDefNeedsISAController(virDomainDefPtr def)
 
 static int
 bhyveDomainDefPostParse(virDomainDefPtr def,
-                        virCapsPtr caps,
+                        virCapsPtr _caps G_GNUC_UNUSED,
                         unsigned int parseFlags G_GNUC_UNUSED,
-                        void *opaque G_GNUC_UNUSED,
+                        void *opaque,
                         void *parseOpaque G_GNUC_UNUSED)
 {
+    bhyveConnPtr driver = opaque;
+    g_autoptr(virCaps) caps = bhyveDriverGetCapabilities(driver);
+    if (!caps)
+        return -1;
+
     if (!virCapabilitiesDomainSupported(caps, def->os.type,
                                         def->os.arch,
                                         def->virtType))
index 81ff502769dd32ebee4091aa44f3cfb96a1c02f7..2db89c7986476eac58dd03de68e94e317db2eef6 100644 (file)
@@ -928,7 +928,7 @@ esxConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
     if (!priv->caps)
         goto cleanup;
 
-    if (!(priv->xmlopt = virVMXDomainXMLConfInit()))
+    if (!(priv->xmlopt = virVMXDomainXMLConfInit(priv->caps)))
         goto cleanup;
 
     conn->privateData = priv;
index 37fe3600676984503f731f9551c08d7a3cf1352b..132e04b14783c20c764cf8eaf7a68ff91d377108 100644 (file)
@@ -2470,8 +2470,9 @@ libxlBuildDomainConfig(virPortAllocatorRangePtr graphicsports,
 }
 
 virDomainXMLOptionPtr
-libxlCreateXMLConf(void)
+libxlCreateXMLConf(libxlDriverPrivatePtr driver)
 {
+    libxlDomainDefParserConfig.priv = driver;
     return virDomainXMLOptionNew(&libxlDomainDefParserConfig,
                                  &libxlDomainXMLPrivateDataCallbacks,
                                  NULL, NULL, NULL);
index 305c8c41ef4353abf5c270e0c28633a565542277..4b5d2406843cdc6811be7923b884165490994ec0 100644 (file)
@@ -207,7 +207,7 @@ libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev);
 #endif
 
 virDomainXMLOptionPtr
-libxlCreateXMLConf(void);
+libxlCreateXMLConf(libxlDriverPrivatePtr driver);
 
 #ifdef LIBXL_HAVE_DEVICE_CHANNEL
 # define LIBXL_ATTR_UNUSED
index ad9424155a5f762c577d896ae62f928be7a75036..f202f0fc3e2a27e21fa853e5063ff0249750e09c 100644 (file)
@@ -367,12 +367,15 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
 
 static int
 libxlDomainDefPostParse(virDomainDefPtr def,
-                        virCapsPtr caps,
+                        virCapsPtr caps G_GNUC_UNUSED,
                         unsigned int parseFlags G_GNUC_UNUSED,
-                        void *opaque G_GNUC_UNUSED,
+                        void *opaque,
                         void *parseOpaque G_GNUC_UNUSED)
 {
-    if (!virCapabilitiesDomainSupported(caps, def->os.type,
+    libxlDriverPrivatePtr driver = opaque;
+    g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
+
+    if (!virCapabilitiesDomainSupported(cfg->caps, def->os.type,
                                         def->os.arch,
                                         def->virtType))
         return -1;
index dc0d9b58f32e35d36a5c70293f68b5f521d3243a..fac3c1db49c7fb8d7855362825e204192e3910a2 100644 (file)
@@ -769,7 +769,7 @@ libxlStateInitialize(bool privileged,
         goto error;
     }
 
-    if (!(libxl_driver->xmlopt = libxlCreateXMLConf()))
+    if (!(libxl_driver->xmlopt = libxlCreateXMLConf(libxl_driver)))
         goto error;
 
     /* Add Domain-0 */
index de9793e5236e7b3c78bded9eba0118df9167ea2d..2e866973ce8d409773453346a66e59fbd68a9cbb 100644 (file)
@@ -207,8 +207,9 @@ virCapsPtr virLXCDriverGetCapabilities(virLXCDriverPtr driver,
 
 
 virDomainXMLOptionPtr
-lxcDomainXMLConfInit(void)
+lxcDomainXMLConfInit(virLXCDriverPtr driver)
 {
+    virLXCDriverDomainDefParserConfig.priv = driver;
     return virDomainXMLOptionNew(&virLXCDriverDomainDefParserConfig,
                                  &virLXCDriverPrivateDataCallbacks,
                                  &virLXCDriverDomainXMLNamespace,
index 12a201db381c3752801c32f90d4cf0d8e3e621ba..59782d9cb2d655c107aeab22bb40f84ebc093d2c 100644 (file)
@@ -112,7 +112,7 @@ int virLXCLoadDriverConfig(virLXCDriverConfigPtr cfg,
 virCapsPtr virLXCDriverCapsInit(virLXCDriverPtr driver);
 virCapsPtr virLXCDriverGetCapabilities(virLXCDriverPtr driver,
                                        bool refresh);
-virDomainXMLOptionPtr lxcDomainXMLConfInit(void);
+virDomainXMLOptionPtr lxcDomainXMLConfInit(virLXCDriverPtr driver);
 
 static inline void lxcDriverLock(virLXCDriverPtr driver)
 {
index 2b9d6481df08ec0a675f5696376d5a9caabfb1ca..c869e2e7c4491dd984446d7f7e0f9d04c8fff06d 100644 (file)
@@ -159,11 +159,41 @@ static void virLXCControllerQuitTimer(int timer G_GNUC_UNUSED, void *opaque)
 }
 
 
+static virLXCDriverPtr
+virLXCControllerDriverNew(void)
+{
+    virLXCDriverPtr driver = g_new0(virLXCDriver, 1);
+
+    if (virMutexInit(&driver->lock) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("cannot initialize mutex"));
+        g_free(driver);
+        return NULL;
+    }
+
+    driver->caps = virLXCDriverCapsInit(NULL);
+    driver->xmlopt = lxcDomainXMLConfInit(driver);
+
+    return driver;
+}
+
+
+static void
+virLXCControllerDriverFree(virLXCDriverPtr driver)
+{
+    if (!driver)
+        return;
+    virObjectUnref(driver->xmlopt);
+    virObjectUnref(driver->caps);
+    virMutexDestroy(&driver->lock);
+    g_free(driver);
+}
+
+
 static virLXCControllerPtr virLXCControllerNew(const char *name)
 {
     virLXCControllerPtr ctrl = NULL;
-    virCapsPtr caps = NULL;
-    virDomainXMLOptionPtr xmlopt = NULL;
+    virLXCDriverPtr driver = NULL;
     char *configFile = NULL;
 
     if (VIR_ALLOC(ctrl) < 0)
@@ -174,10 +204,7 @@ static virLXCControllerPtr virLXCControllerNew(const char *name)
 
     ctrl->name = g_strdup(name);
 
-    if (!(caps = virLXCDriverCapsInit(NULL)))
-        goto error;
-
-    if (!(xmlopt = lxcDomainXMLConfInit()))
+    if (!(driver = virLXCControllerDriverNew()))
         goto error;
 
     if ((configFile = virDomainConfigFile(LXC_STATE_DIR,
@@ -185,7 +212,7 @@ static virLXCControllerPtr virLXCControllerNew(const char *name)
         goto error;
 
     if ((ctrl->vm = virDomainObjParseFile(configFile,
-                                          caps, xmlopt,
+                                          driver->caps, driver->xmlopt,
                                           0)) == NULL)
         goto error;
     ctrl->def = ctrl->vm->def;
@@ -197,8 +224,7 @@ static virLXCControllerPtr virLXCControllerNew(const char *name)
 
  cleanup:
     VIR_FREE(configFile);
-    virObjectUnref(caps);
-    virObjectUnref(xmlopt);
+    virLXCControllerDriverFree(driver);
     return ctrl;
 
  error:
index b505a91c1c8b75b260d841043c1fc23d704a3c89..bc54beeadf29dec81b8101571de572d21d3181c8 100644 (file)
@@ -351,11 +351,15 @@ virDomainXMLPrivateDataCallbacks virLXCDriverPrivateDataCallbacks = {
 
 static int
 virLXCDomainDefPostParse(virDomainDefPtr def,
-                         virCapsPtr caps,
+                         virCapsPtr _caps G_GNUC_UNUSED,
                          unsigned int parseFlags G_GNUC_UNUSED,
-                         void *opaque G_GNUC_UNUSED,
+                         void *opaque,
                          void *parseOpaque G_GNUC_UNUSED)
 {
+    virLXCDriverPtr driver = opaque;
+    g_autoptr(virCaps) caps = virLXCDriverGetCapabilities(driver, false);
+    if (!caps)
+        return -1;
     if (!virCapabilitiesDomainSupported(caps, def->os.type,
                                         def->os.arch,
                                         def->virtType))
index 6c125432743bb75af47ffb2a548326b7b081bc7b..f28e20d7563c2fe2ffe383d8f0adaee674d9d9cf 100644 (file)
@@ -1584,7 +1584,7 @@ static int lxcStateInitialize(bool privileged,
     if (!(caps = virLXCDriverGetCapabilities(lxc_driver, true)))
         goto cleanup;
 
-    if (!(lxc_driver->xmlopt = lxcDomainXMLConfInit()))
+    if (!(lxc_driver->xmlopt = lxcDomainXMLConfInit(lxc_driver)))
         goto cleanup;
 
     if (!(lxc_driver->closeCallbacks = virCloseCallbacksNew()))
index de8be1ed7d1765d82715424881cf4be502dacdc3..5060e704a5a6371942ac8c1f776988c65be4fbf7 100644 (file)
@@ -1082,12 +1082,13 @@ int openvzGetVEID(const char *name)
 
 static int
 openvzDomainDefPostParse(virDomainDefPtr def,
-                         virCapsPtr caps,
+                         virCapsPtr caps G_GNUC_UNUSED,
                          unsigned int parseFlags G_GNUC_UNUSED,
-                         void *opaque G_GNUC_UNUSED,
+                         void *opaque,
                          void *parseOpaque G_GNUC_UNUSED)
 {
-    if (!virCapabilitiesDomainSupported(caps, def->os.type,
+    struct openvz_driver *driver = opaque;
+    if (!virCapabilitiesDomainSupported(driver->caps, def->os.type,
                                         def->os.arch,
                                         def->virtType))
         return -1;
@@ -1133,8 +1134,9 @@ virDomainDefParserConfig openvzDomainDefParserConfig = {
     .features = VIR_DOMAIN_DEF_FEATURE_NAME_SLASH,
 };
 
-virDomainXMLOptionPtr openvzXMLOption(void)
+virDomainXMLOptionPtr openvzXMLOption(struct openvz_driver *driver)
 {
+    openvzDomainDefParserConfig.priv = driver;
     return virDomainXMLOptionNew(&openvzDomainDefParserConfig,
                                  NULL, NULL, NULL, NULL);
 }
index 6463c1704a2dd4a9d6e5c3d1ea13991764911ea8..9892f394816433ceebff97c46289d8242c3a40f4 100644 (file)
@@ -63,4 +63,4 @@ int strtoI(const char *str);
 int openvzSetDefinedUUID(int vpsid, unsigned char *uuid);
 int openvzGetVEID(const char *name);
 int openvzReadNetworkConf(virDomainDefPtr def, int veid);
-virDomainXMLOptionPtr openvzXMLOption(void);
+virDomainXMLOptionPtr openvzXMLOption(struct openvz_driver *driver);
index e479ebf58dbbc83720905e1a1746314592f7b253..9b93bc5ca07080ecf374e5e38219381ccd82478f 100644 (file)
@@ -1311,7 +1311,7 @@ static virDrvOpenStatus openvzConnectOpen(virConnectPtr conn,
     if (!(driver->caps = openvzCapsInit()))
         goto cleanup;
 
-    if (!(driver->xmlopt = openvzXMLOption()))
+    if (!(driver->xmlopt = openvzXMLOption(driver)))
         goto cleanup;
 
     if (openvzLoadDomains(driver) < 0)
index 218d6f5b5cdf486e7237da94c0a7c1c608d15c66..05860b7dbe286f340a589ba463faa46830be37b1 100644 (file)
@@ -1062,12 +1062,13 @@ openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
 
 static int
 phypDomainDefPostParse(virDomainDefPtr def,
-                       virCapsPtr caps,
+                       virCapsPtr caps G_GNUC_UNUSED,
                        unsigned int parseFlags G_GNUC_UNUSED,
-                       void *opaque G_GNUC_UNUSED,
+                       void *opaque,
                        void *parseOpaque G_GNUC_UNUSED)
 {
-    if (!virCapabilitiesDomainSupported(caps, def->os.type,
+    phyp_driverPtr driver = opaque;
+    if (!virCapabilitiesDomainSupported(driver->caps, def->os.type,
                                         def->os.arch,
                                         def->virtType))
         return -1;
@@ -1157,6 +1158,7 @@ phypConnectOpen(virConnectPtr conn,
     if ((phyp_driver->caps = phypCapsInit()) == NULL)
         goto failure;
 
+    virPhypDriverDomainDefParserConfig.priv = phyp_driver;
     if (!(phyp_driver->xmlopt = virDomainXMLOptionNew(&virPhypDriverDomainDefParserConfig,
                                                       NULL, NULL, NULL, NULL)))
         goto failure;
index c02ff5b9416647a34163a7f0736290231129a1cc..7a62dfb1a273496c6eb37b8cc03d2475aeea7759 100644 (file)
@@ -2094,6 +2094,44 @@ virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
 }
 
 
+bool
+virQEMUCapsIsArchSupported(virQEMUCapsPtr qemuCaps,
+                           virArch arch)
+{
+    if (arch == qemuCaps->arch)
+        return true;
+
+    if (qemuCaps->arch == VIR_ARCH_X86_64 && arch == VIR_ARCH_I686)
+        return true;
+
+    if (qemuCaps->arch == VIR_ARCH_AARCH64 && arch == VIR_ARCH_ARMV7L)
+        return true;
+
+    if (qemuCaps->arch == VIR_ARCH_ARMV7L && arch == VIR_ARCH_ARMV6L)
+        return true;
+
+    if (qemuCaps->arch == VIR_ARCH_PPC64 && arch == VIR_ARCH_PPC64LE)
+        return true;
+
+    return false;
+}
+
+
+bool
+virQEMUCapsIsVirtTypeSupported(virQEMUCapsPtr qemuCaps,
+                               virDomainVirtType virtType)
+{
+    if (virtType == VIR_DOMAIN_VIRT_QEMU)
+        return true;
+
+    if (virtType == VIR_DOMAIN_VIRT_KVM &&
+        virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
+        return true;
+
+    return false;
+}
+
+
 bool
 virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
                               virArch hostarch,
index 399496796dc22b58d5c5c87e5d7ea42c921a5900..a8a5c38d73cb243e2b5706fc460fc12e652a8abc 100644 (file)
@@ -603,6 +603,10 @@ int virQEMUCapsGetCPUFeatures(virQEMUCapsPtr qemuCaps,
                               bool migratable,
                               char ***features);
 
+bool virQEMUCapsIsArchSupported(virQEMUCapsPtr qemuCaps,
+                                virArch arch);
+bool virQEMUCapsIsVirtTypeSupported(virQEMUCapsPtr qemuCaps,
+                                    virDomainVirtType virtType);
 bool virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
                                    virArch hostarch,
                                    virDomainVirtType type,
index a342af334836c60a3603c1a3023b61059b424222..6159101bcc09cfa078c8523c7cd3c83919e750d0 100644 (file)
@@ -4691,22 +4691,40 @@ qemuDomainDefPostParseBasic(virDomainDefPtr def,
 
 static int
 qemuDomainDefPostParse(virDomainDefPtr def,
-                       virCapsPtr caps,
+                       virCapsPtr caps G_GNUC_UNUSED,
                        unsigned int parseFlags,
                        void *opaque,
-                       void *parseOpaque)
+                       void *parseOpaque G_GNUC_UNUSED)
 {
     virQEMUDriverPtr driver = opaque;
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
-    /* Note that qemuCaps may be NULL when this function is called. This
-     * function shall not fail in that case. It will be re-run on VM startup
-     * with the capabilities populated. */
-    virQEMUCapsPtr qemuCaps = parseOpaque;
+    g_autoptr(virQEMUCaps) qemuCaps = NULL;
+
+    if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
+                                            def->emulator))) {
+        return 1;
+    }
+
+    if (def->os.type != VIR_DOMAIN_OSTYPE_HVM) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Emulator '%s' does not support os type '%s'"),
+                       def->emulator, virDomainOSTypeToString(def->os.type));
+        return -1;
+    }
 
-    if (!virCapabilitiesDomainSupported(caps, def->os.type,
-                                        def->os.arch,
-                                        def->virtType))
+    if (!virQEMUCapsIsArchSupported(qemuCaps, def->os.arch)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Emulator '%s' does not support arch '%s'"),
+                       def->emulator, virArchToString(def->os.arch));
         return -1;
+    }
+
+    if (!virQEMUCapsIsVirtTypeSupported(qemuCaps, def->virtType)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Emulator '%s' does not support virt type '%s'"),
+                       def->emulator, virDomainVirtTypeToString(def->virtType));
+        return -1;
+    }
 
     if (def->os.bootloader || def->os.bootloaderArgs) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -4715,15 +4733,9 @@ qemuDomainDefPostParse(virDomainDefPtr def,
     }
 
     if (!def->os.machine) {
-        g_autofree virCapsDomainDataPtr capsdata = NULL;
-
-        if (!(capsdata = virCapabilitiesDomainDataLookup(caps, def->os.type,
-                                                         def->os.arch,
-                                                         def->virtType,
-                                                         NULL, NULL))) {
-            return -1;
-        }
-        def->os.machine = g_strdup(capsdata->machinetype);
+        const char *machine = virQEMUCapsGetPreferredMachine(qemuCaps,
+                                                             def->virtType);
+        def->os.machine = g_strdup(machine);
     }
 
     qemuDomainNVRAMPathGenerate(cfg, def);
index be0adb1e45bbde3eabaa3598968c82a3a99665b7..308a941f8a5197c9c39fec68be0777bbaf74784d 100644 (file)
@@ -117,12 +117,13 @@ vmwareDataFreeFunc(void *data)
 
 static int
 vmwareDomainDefPostParse(virDomainDefPtr def,
-                         virCapsPtr caps,
+                         virCapsPtr caps G_GNUC_UNUSED,
                          unsigned int parseFlags G_GNUC_UNUSED,
                          void *opaque G_GNUC_UNUSED,
                          void *parseOpaque G_GNUC_UNUSED)
 {
-    if (!virCapabilitiesDomainSupported(caps, def->os.type,
+    struct vmware_driver *driver = opaque;
+    if (!virCapabilitiesDomainSupported(driver->caps, def->os.type,
                                         def->os.arch,
                                         def->virtType))
         return -1;
@@ -148,11 +149,11 @@ virDomainDefParserConfig vmwareDomainDefParserConfig = {
 };
 
 static virDomainXMLOptionPtr
-vmwareDomainXMLConfigInit(void)
+vmwareDomainXMLConfigInit(struct vmware_driver *driver)
 {
     virDomainXMLPrivateDataCallbacks priv = { .alloc = vmwareDataAllocFunc,
                                               .free = vmwareDataFreeFunc };
-
+    vmwareDomainDefParserConfig.priv = driver;
     return virDomainXMLOptionNew(&vmwareDomainDefParserConfig, &priv,
                                  NULL, NULL, NULL);
 }
@@ -235,7 +236,7 @@ vmwareConnectOpen(virConnectPtr conn,
     if (!(driver->caps = vmwareCapsInit()))
         goto cleanup;
 
-    if (!(driver->xmlopt = vmwareDomainXMLConfigInit()))
+    if (!(driver->xmlopt = vmwareDomainXMLConfigInit(driver)))
         goto cleanup;
 
     if (vmwareLoadDomains(driver) < 0)
index c2a06daecb4b9bf81ca90c6b17a53bb56955b072..958b1688915cf833732001d7f9b3e0b237e2a530 100644 (file)
@@ -530,11 +530,12 @@ VIR_ENUM_IMPL(virVMXControllerModelSCSI,
 
 static int
 virVMXDomainDefPostParse(virDomainDefPtr def,
-                         virCapsPtr caps,
+                         virCapsPtr _caps G_GNUC_UNUSED,
                          unsigned int parseFlags G_GNUC_UNUSED,
-                         void *opaque G_GNUC_UNUSED,
+                         void *opaque,
                          void *parseOpaque G_GNUC_UNUSED)
 {
+    virCapsPtr caps = opaque;
     if (!virCapabilitiesDomainSupported(caps, def->os.type,
                                         def->os.arch,
                                         def->virtType))
@@ -612,8 +613,9 @@ static virXMLNamespace virVMXDomainXMLNamespace = {
 };
 
 virDomainXMLOptionPtr
-virVMXDomainXMLConfInit(void)
+virVMXDomainXMLConfInit(virCapsPtr caps)
 {
+    virVMXDomainDefParserConfig.priv = caps;
     return virDomainXMLOptionNew(&virVMXDomainDefParserConfig, NULL,
                                  &virVMXDomainXMLNamespace, NULL, NULL);
 }
index 18478ac0aea0115ca59aedb9307c94c196134b60..63f47822fbf4280741f09a283c2e020276ea6acd 100644 (file)
@@ -29,7 +29,7 @@
 
 typedef struct _virVMXContext virVMXContext;
 
-virDomainXMLOptionPtr virVMXDomainXMLConfInit(void);
+virDomainXMLOptionPtr virVMXDomainXMLConfInit(virCapsPtr caps);
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
index 66b15737a2c78b7f67993c282afc695140d23a50..a0d1efb9dde7fb95d7f3c0f7a96426866095a9e4 100644 (file)
@@ -241,12 +241,13 @@ vzDomainDefAddDefaultInputDevices(virDomainDefPtr def)
 
 static int
 vzDomainDefPostParse(virDomainDefPtr def,
-                     virCapsPtr caps,
+                     virCapsPtr caps G_GNUC_UNUSED,
                      unsigned int parseFlags G_GNUC_UNUSED,
-                     void *opaque G_GNUC_UNUSED,
+                     void *opaque,
                      void *parseOpaque G_GNUC_UNUSED)
 {
-    if (!virCapabilitiesDomainSupported(caps, def->os.type,
+    vzDriverPtr driver = opaque;
+    if (!virCapabilitiesDomainSupported(driver->caps, def->os.type,
                                         def->os.arch,
                                         def->virtType))
         return -1;
@@ -289,10 +290,12 @@ vzDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
 static int
 vzDomainDeviceDefValidate(const virDomainDeviceDef *dev,
                           const virDomainDef *def,
-                          void *opaque G_GNUC_UNUSED)
+                          void *opaque)
 {
+    vzDriverPtr driver = opaque;
+
     if (dev->type == VIR_DOMAIN_DEVICE_DISK)
-        return vzCheckUnsupportedDisk(def, dev->data.disk, opaque);
+        return vzCheckUnsupportedDisk(def, dev->data.disk, driver->vzCaps);
     else if (dev->type == VIR_DOMAIN_DEVICE_GRAPHICS)
         return vzCheckUnsupportedGraphics(dev->data.graphics);
 
@@ -323,7 +326,7 @@ vzDriverObjNew(void)
     if (!(driver = virObjectLockableNew(vzDriverClass)))
         return NULL;
 
-    vzDomainDefParserConfig.priv = &driver->vzCaps;
+    vzDomainDefParserConfig.priv = driver;
 
     if (!(driver->caps = vzBuildCapabilities()) ||
         !(driver->xmlopt = virDomainXMLOptionNew(&vzDomainDefParserConfig,
index 2362b770b5bd6a4a300a6ea739ec614c10cad9c4..9716d9d2befddd656f4cbeddf45ef032f4b26bbd 100644 (file)
@@ -1048,11 +1048,17 @@ endif WITH_LXC
 if WITH_QEMU
 vircapstest_SOURCES += testutilsqemu.c testutilsqemu.h
 endif WITH_QEMU
+vircapstest_LDADD =
 if WITH_QEMU
-vircapstest_LDADD = $(qemu_LDADDS)
-else ! WITH_QEMU
-vircapstest_LDADD = $(LDADDS)
-endif ! WITH_QEMU
+vircapstest_LDADD += ../src/libvirt_driver_qemu_impl.la
+if WITH_DTRACE_PROBES
+vircapstest_LDADD += ../src/libvirt_qemu_probes.lo
+endif WITH_DTRACE_PROBES
+endif WITH_QEMU
+if WITH_LXC
+vircapstest_LDADD += ../src/libvirt_driver_lxc_impl.la
+endif WITH_LXC
+vircapstest_LDADD += $(LDADDS)
 
 libdomaincapsmock_la_SOURCES = domaincapsmock.c
 libdomaincapsmock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
index 5bda6db3600ffd3f14bce1868366d4aa8f77a14e..5c8dcf85031e628578c4569eb38361da6a951d81 100644 (file)
@@ -41,7 +41,7 @@
 
 # define VIR_FROM_THIS VIR_FROM_LIBXL
 
-static virCapsPtr caps;
+static libxlDriverPrivatePtr driver;
 
 static int
 testCompareXMLToDomConfig(const char *xmlfile,
@@ -50,19 +50,13 @@ testCompareXMLToDomConfig(const char *xmlfile,
     int ret = -1;
     libxl_domain_config actualconfig;
     libxl_domain_config expectconfig;
-    libxlDriverConfigPtr cfg;
     xentoollog_logger *log = NULL;
     virPortAllocatorRangePtr gports = NULL;
-    virDomainXMLOptionPtr xmlopt = NULL;
     virDomainDefPtr vmdef = NULL;
     char *actualjson = NULL;
     char *tempjson = NULL;
     char *expectjson = NULL;
-
-    if (!(cfg = libxlDriverConfigNew()))
-        return -1;
-
-    cfg->caps = caps;
+    g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
 
     libxl_domain_config_init(&actualconfig);
     libxl_domain_config_init(&expectconfig);
@@ -82,10 +76,7 @@ testCompareXMLToDomConfig(const char *xmlfile,
     if (!(gports = virPortAllocatorRangeNew("vnc", 5900, 6000)))
         goto cleanup;
 
-    if (!(xmlopt = libxlCreateXMLConf()))
-        goto cleanup;
-
-    if (!(vmdef = virDomainDefParseFile(xmlfile, caps, xmlopt,
+    if (!(vmdef = virDomainDefParseFile(xmlfile, cfg->caps, driver->xmlopt,
                                         NULL, VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
@@ -128,12 +119,9 @@ testCompareXMLToDomConfig(const char *xmlfile,
     VIR_FREE(tempjson);
     virDomainDefFree(vmdef);
     virPortAllocatorRangeFree(gports);
-    virObjectUnref(xmlopt);
     libxl_domain_config_dispose(&actualconfig);
     libxl_domain_config_dispose(&expectconfig);
     xtl_logger_destroy(log);
-    cfg->caps = NULL;
-    virObjectUnref(cfg);
     return ret;
 }
 
@@ -177,7 +165,7 @@ mymain(void)
         return EXIT_FAILURE;
     }
 
-    if ((caps = testXLInitCaps()) == NULL)
+    if ((driver = testXLInitDriver()) == NULL)
         return EXIT_FAILURE;
 
 # define DO_TEST(name) \
@@ -216,6 +204,8 @@ mymain(void)
 
     unlink("libxl-driver.log");
 
+    testXLFreeDriver(driver);
+
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
index 7adc23be9f3b984edc407ad40cab1226b1500fc5..fffe9cbf1adde76fdf5f87d71d24c72e2efeed6f 100644 (file)
@@ -10,8 +10,7 @@
 
 # define VIR_FROM_THIS VIR_FROM_NONE
 
-static virCapsPtr caps;
-static virDomainXMLOptionPtr xmlopt;
+static virLXCDriverPtr driver;
 
 static int testSanitizeDef(virDomainDefPtr vmdef)
 {
@@ -34,7 +33,7 @@ testCompareXMLToConfigFiles(const char *xmlfile,
     if (virTestLoadFile(configfile, &config) < 0)
         goto fail;
 
-    vmdef = lxcParseConfigString(config, caps, xmlopt);
+    vmdef = lxcParseConfigString(config, driver->caps, driver->xmlopt);
     if ((vmdef && expectError) || (!vmdef && !expectError))
         goto fail;
 
@@ -42,7 +41,7 @@ testCompareXMLToConfigFiles(const char *xmlfile,
         if (testSanitizeDef(vmdef) < 0)
             goto fail;
 
-        if (!(actualxml = virDomainDefFormat(vmdef, xmlopt, caps, 0)))
+        if (!(actualxml = virDomainDefFormat(vmdef, driver->xmlopt, driver->caps, 0)))
             goto fail;
 
         if (virTestCompareToFile(actualxml, xmlfile) < 0)
@@ -109,14 +108,9 @@ mymain(void)
 {
     int ret = EXIT_SUCCESS;
 
-    if (!(caps = testLXCCapsInit()))
+    if (!(driver = testLXCDriverInit()))
         return EXIT_FAILURE;
 
-    if (!(xmlopt = lxcDomainXMLConfInit())) {
-        virObjectUnref(caps);
-        return EXIT_FAILURE;
-    }
-
 # define DO_TEST(name, expectError) \
     do { \
         const struct testInfo info = { name, expectError }; \
@@ -166,8 +160,7 @@ mymain(void)
     DO_TEST3("blkiotune", false);
     DO_TEST3("ethernet", false);
 
-    virObjectUnref(xmlopt);
-    virObjectUnref(caps);
+    testLXCDriverFree(driver);
 
     return ret;
 }
index 6a720503a981d0fa66731618224b01c2d40439eb..7b05f7d01641a3ea7f07d81689a8dad27d18943a 100644 (file)
@@ -16,8 +16,7 @@
 
 # define VIR_FROM_THIS VIR_FROM_NONE
 
-static virCapsPtr caps;
-static virDomainXMLOptionPtr xmlopt;
+static virLXCDriverPtr driver;
 
 struct testInfo {
     const char *name;
@@ -39,7 +38,7 @@ testCompareXMLToXMLHelper(const void *data)
     xml_out = g_strdup_printf("%s/lxcxml2xmloutdata/lxc-%s.xml",
                               abs_srcdir, info->name);
 
-    ret = testCompareDomXML2XMLFiles(caps, xmlopt, xml_in,
+    ret = testCompareDomXML2XMLFiles(driver->caps, driver->xmlopt, xml_in,
                                      info->different ? xml_out : xml_in,
                                      !info->inactive_only,
                                      info->parse_flags,
@@ -55,10 +54,7 @@ mymain(void)
 {
     int ret = 0;
 
-    if ((caps = testLXCCapsInit()) == NULL)
-        return EXIT_FAILURE;
-
-    if (!(xmlopt = lxcDomainXMLConfInit()))
+    if (!(driver = testLXCDriverInit()))
         return EXIT_FAILURE;
 
 # define DO_TEST_FULL(name, is_different, inactive, parse_flags) \
@@ -95,8 +91,7 @@ mymain(void)
     DO_TEST("initdir");
     DO_TEST("inituser");
 
-    virObjectUnref(caps);
-    virObjectUnref(xmlopt);
+    testLXCDriverFree(driver);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index f43867ddc9ebfaf91237354bf0b8bfd43ed56b00..681f1a52a0e8983d021cd2f8aa660addaf249c72 100644 (file)
@@ -98,7 +98,10 @@ testReadNetworkConf(const void *data G_GNUC_UNUSED)
         "    </interface>\n"
         "  </devices>\n"
         "</domain>\n";
-    virDomainXMLOptionPtr xmlopt = openvzXMLOption();
+    struct openvz_driver driver = {0};
+
+    driver.xmlopt = openvzXMLOption(&driver);
+    driver.caps = openvzCapsInit();
 
     if (!(def = virDomainDefNew()))
         goto cleanup;
@@ -113,7 +116,7 @@ testReadNetworkConf(const void *data G_GNUC_UNUSED)
         goto cleanup;
     }
 
-    actual = virDomainDefFormat(def, xmlopt, NULL, VIR_DOMAIN_DEF_FORMAT_INACTIVE);
+    actual = virDomainDefFormat(def, driver.xmlopt, driver.caps, VIR_DOMAIN_DEF_FORMAT_INACTIVE);
 
     if (actual == NULL) {
         fprintf(stderr, "ERROR: %s\n", virGetLastErrorMessage());
@@ -128,7 +131,8 @@ testReadNetworkConf(const void *data G_GNUC_UNUSED)
     result = 0;
 
  cleanup:
-    virObjectUnref(xmlopt);
+    virObjectUnref(driver.xmlopt);
+    virObjectUnref(driver.caps);
     VIR_FREE(actual);
     virDomainDefFree(def);
 
index eed18304c4a4b5668902da39801df3753ac4d0ab..b5e2f542e7c1353ef9502cb3ba1415f146d19609 100644 (file)
@@ -6,8 +6,10 @@
 # include "viralloc.h"
 # include "domain_conf.h"
 
+# define VIR_FROM_THIS VIR_FROM_LXC
 
-virCapsPtr testLXCCapsInit(void)
+virCapsPtr
+testLXCCapsInit(void)
 {
     virCapsPtr caps;
     virCapsGuestPtr guest;
@@ -54,4 +56,34 @@ virCapsPtr testLXCCapsInit(void)
     virObjectUnref(caps);
     return NULL;
 }
+
+
+virLXCDriverPtr
+testLXCDriverInit(void)
+{
+    virLXCDriverPtr driver = g_new0(virLXCDriver, 1);
+
+    if (virMutexInit(&driver->lock) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", "cannot initialize mutex");
+        g_free(driver);
+        return NULL;
+    }
+
+    driver->caps = testLXCCapsInit();
+    driver->xmlopt = lxcDomainXMLConfInit(driver);
+
+    return driver;
+}
+
+
+void
+testLXCDriverFree(virLXCDriverPtr driver)
+{
+    virObjectUnref(driver->xmlopt);
+    virObjectUnref(driver->caps);
+    virMutexDestroy(&driver->lock);
+    g_free(driver);
+}
+
 #endif
index 6339f8873400059fda80b2b69ecc23eaa6252efd..fe170540b51f558680e66ae1e97e9afc70ef1283 100644 (file)
 
 #include "capabilities.h"
 
+#include "lxc/lxc_conf.h"
+
 #define FAKEDEVDIR0 "/fakedevdir0/bla/fasl"
 #define FAKEDEVDIR1 "/fakedevdir1/bla/fasl"
 
 virCapsPtr testLXCCapsInit(void);
+virLXCDriverPtr testLXCDriverInit(void);
+void testLXCDriverFree(virLXCDriverPtr driver);
index 314d96abe89a821bb5599f449d68a5ce571e25ed..75cd42ec435f551822c6649a38870946a25ee8b6 100644 (file)
@@ -6,7 +6,9 @@
 #include "testutilshostcpus.h"
 #include "domain_conf.h"
 
-virCapsPtr
+#define VIR_FROM_THIS VIR_FROM_LIBXL
+
+static virCapsPtr
 testXLInitCaps(void)
 {
     virCapsPtr caps;
@@ -79,3 +81,33 @@ testXLInitCaps(void)
     virObjectUnref(caps);
     return NULL;
 }
+
+
+libxlDriverPrivatePtr testXLInitDriver(void)
+{
+    libxlDriverPrivatePtr driver = g_new0(libxlDriverPrivate, 1);
+
+    if (virMutexInit(&driver->lock) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", "cannot initialize mutex");
+        g_free(driver);
+        return NULL;
+    }
+
+    driver->config = libxlDriverConfigNew();
+
+    driver->config->caps = testXLInitCaps();
+
+    driver->xmlopt = libxlCreateXMLConf(driver);
+
+    return driver;
+}
+
+void testXLFreeDriver(libxlDriverPrivatePtr driver)
+{
+    virObjectUnref(driver->config->caps);
+    virObjectUnref(driver->config);
+    virObjectUnref(driver->xmlopt);
+    virMutexDestroy(&driver->lock);
+    g_free(driver);
+}
index 95dadb04c4000816d0ef52ed68b9db66926cef3f..a31d3d90470d5a9d77bb9a7c292379978cf6d663 100644 (file)
 
 #include "capabilities.h"
 #ifdef WITH_LIBXL
-# include "libxl/libxl_capabilities.h"
-#endif
+# include "libxl/libxl_conf.h"
 
-virCapsPtr testXLInitCaps(void);
+libxlDriverPrivatePtr testXLInitDriver(void);
+
+void testXLFreeDriver(libxlDriverPrivatePtr driver);
+
+#endif /* WITH_LIBXL */
index 72ee2a38c8cf6888021e6f98e0115f89d65554dd..beb82cbd7c7b4bd3e60ef33b7118ed723c0d6dc6 100644 (file)
@@ -186,7 +186,7 @@ mymain(void)
     if (caps == NULL)
         return EXIT_FAILURE;
 
-    if (!(xmlopt = virVMXDomainXMLConfInit()))
+    if (!(xmlopt = virVMXDomainXMLConfInit(caps)))
         return EXIT_FAILURE;
 
     ctx.opaque = NULL;
index 890d8bf2b47197b23f8e6fd9eaa142b0e9490f6e..d077933ca952350df601f3dff8b0036fae11a8cc 100644 (file)
@@ -36,9 +36,7 @@
 
 #define VIR_FROM_THIS VIR_FROM_NONE
 
-static virCapsPtr caps;
-static virDomainXMLOptionPtr xmlopt;
-
+static libxlDriverPrivatePtr driver;
 
 /*
  * This function provides a mechanism to replace variables in test
@@ -74,6 +72,7 @@ testCompareParseXML(const char *xlcfg, const char *xml, bool replaceVars)
     int ret = -1;
     virDomainDefPtr def = NULL;
     char *replacedXML = NULL;
+    g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
 
     if (VIR_ALLOC_N(gotxlcfgData, wrote) < 0)
         goto fail;
@@ -84,16 +83,16 @@ testCompareParseXML(const char *xlcfg, const char *xml, bool replaceVars)
     if (replaceVars) {
         if (!(replacedXML = testReplaceVarsXML(xml)))
             goto fail;
-        if (!(def = virDomainDefParseString(replacedXML, caps, xmlopt,
+        if (!(def = virDomainDefParseString(replacedXML, cfg->caps, driver->xmlopt,
                                             NULL, VIR_DOMAIN_XML_INACTIVE)))
             goto fail;
     } else {
-        if (!(def = virDomainDefParseFile(xml, caps, xmlopt,
+        if (!(def = virDomainDefParseFile(xml, cfg->caps, driver->xmlopt,
                                           NULL, VIR_DOMAIN_XML_INACTIVE)))
             goto fail;
     }
 
-    if (!virDomainDefCheckABIStability(def, def, xmlopt)) {
+    if (!virDomainDefCheckABIStability(def, def, driver->xmlopt)) {
         fprintf(stderr, "ABI stability check failed on %s", xml);
         goto fail;
     }
@@ -133,6 +132,7 @@ testCompareFormatXML(const char *xlcfg, const char *xml, bool replaceVars)
     virConnectPtr conn;
     virDomainDefPtr def = NULL;
     char *replacedXML = NULL;
+    g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
 
     conn = virGetConnect();
     if (!conn) goto fail;
@@ -143,10 +143,10 @@ testCompareFormatXML(const char *xlcfg, const char *xml, bool replaceVars)
     if (!(conf = virConfReadString(xlcfgData, 0)))
         goto fail;
 
-    if (!(def = xenParseXL(conf, caps, xmlopt)))
+    if (!(def = xenParseXL(conf, cfg->caps, driver->xmlopt)))
         goto fail;
 
-    if (!(gotxml = virDomainDefFormat(def, xmlopt, caps,
+    if (!(gotxml = virDomainDefFormat(def, driver->xmlopt, cfg->caps,
                                       VIR_DOMAIN_XML_INACTIVE |
                                       VIR_DOMAIN_XML_SECURE)))
         goto fail;
@@ -208,10 +208,7 @@ mymain(void)
 {
     int ret = 0;
 
-    if (!(caps = testXLInitCaps()))
-        return EXIT_FAILURE;
-
-    if (!(xmlopt = libxlCreateXMLConf()))
+    if (!(driver = testXLInitDriver()))
         return EXIT_FAILURE;
 
 #define DO_TEST_PARSE(name, replace) \
@@ -303,10 +300,9 @@ mymain(void)
     DO_TEST("usb");
     DO_TEST("usbctrl");
 
-    virObjectUnref(caps);
-    virObjectUnref(xmlopt);
+    testXLFreeDriver(driver);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
-VIR_TEST_MAIN(mymain)
+VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("xl"))
index 4a4d4192db0e138de7638eecec6a4b638759a1e5..6971ad76e29e81bced340b17d6a19245575895ad 100644 (file)
@@ -34,8 +34,7 @@
 
 #define VIR_FROM_THIS VIR_FROM_NONE
 
-static virCapsPtr caps;
-static virDomainXMLOptionPtr xmlopt;
+static libxlDriverPrivatePtr driver;
 
 static int
 testCompareParseXML(const char *xmcfg, const char *xml)
@@ -46,6 +45,7 @@ testCompareParseXML(const char *xmcfg, const char *xml)
     virConnectPtr conn = NULL;
     int wrote = 4096;
     virDomainDefPtr def = NULL;
+    g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
 
     if (VIR_ALLOC_N(gotxmcfgData, wrote) < 0)
         goto fail;
@@ -53,11 +53,11 @@ testCompareParseXML(const char *xmcfg, const char *xml)
     conn = virGetConnect();
     if (!conn) goto fail;
 
-    if (!(def = virDomainDefParseFile(xml, caps, xmlopt, NULL,
+    if (!(def = virDomainDefParseFile(xml, cfg->caps, driver->xmlopt, NULL,
                                       VIR_DOMAIN_DEF_PARSE_INACTIVE)))
         goto fail;
 
-    if (!virDomainDefCheckABIStability(def, def, xmlopt)) {
+    if (!virDomainDefCheckABIStability(def, def, driver->xmlopt)) {
         fprintf(stderr, "ABI stability check failed on %s", xml);
         goto fail;
     }
@@ -90,6 +90,7 @@ testCompareFormatXML(const char *xmcfg, const char *xml)
     g_autoptr(virConf) conf = NULL;
     int ret = -1;
     virDomainDefPtr def = NULL;
+    g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
 
     if (virTestLoadFile(xmcfg, &xmcfgData) < 0)
         goto fail;
@@ -97,10 +98,10 @@ testCompareFormatXML(const char *xmcfg, const char *xml)
     if (!(conf = virConfReadString(xmcfgData, 0)))
         goto fail;
 
-    if (!(def = xenParseXM(conf, caps, xmlopt)))
+    if (!(def = xenParseXM(conf, cfg->caps, driver->xmlopt)))
         goto fail;
 
-    if (!(gotxml = virDomainDefFormat(def, xmlopt, caps, VIR_DOMAIN_DEF_FORMAT_SECURE)))
+    if (!(gotxml = virDomainDefFormat(def, driver->xmlopt, cfg->caps, VIR_DOMAIN_DEF_FORMAT_SECURE)))
         goto fail;
 
     if (virTestCompareToFile(gotxml, xml) < 0)
@@ -152,10 +153,7 @@ mymain(void)
 {
     int ret = 0;
 
-    if (!(caps = testXLInitCaps()))
-        return EXIT_FAILURE;
-
-    if (!(xmlopt = libxlCreateXMLConf()))
+    if (!(driver = testXLInitDriver()))
         return EXIT_FAILURE;
 
 #define DO_TEST_PARSE(name) \
@@ -225,10 +223,9 @@ mymain(void)
     DO_TEST("disk-drv-blktap-raw");
     DO_TEST("disk-drv-blktap2-raw");
 
-    virObjectUnref(caps);
-    virObjectUnref(xmlopt);
+    testXLFreeDriver(driver);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
-VIR_TEST_MAIN(mymain)
+VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("xl"))
index 8dc37f265aa3e8c4caea97e7623edb362b4c7f73..39781beafde28f500be92ec739f7cf6545656dea 100644 (file)
@@ -207,7 +207,7 @@ mymain(void)
     if (caps == NULL)
         return EXIT_FAILURE;
 
-    if (!(xmlopt = virVMXDomainXMLConfInit()))
+    if (!(xmlopt = virVMXDomainXMLConfInit(caps)))
         return EXIT_FAILURE;
 
     ctx.opaque = NULL;