The 'driver->caps' pointer can be changed on the fly. Accessing
it currently requires the global driver lock. Isolate this
access in a single helper, so a future patch can relax the
locking constraints.
---
src/lxc/lxc_conf.c | 29 +++++++++++-
src/lxc/lxc_conf.h | 7 ++-
src/lxc/lxc_controller.c | 2 +-
src/lxc/lxc_driver.c | 121 +++++++++++++++++++++++++++++++++++++----------
src/lxc/lxc_process.c | 9 +++-
5 files changed, 136 insertions(+), 32 deletions(-)
diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c
index 4e97f10..6739df9 100644
--- a/src/lxc/lxc_conf.c
+++ b/src/lxc/lxc_conf.c
@@ -59,7 +59,7 @@ VIR_ONCE_GLOBAL_INIT(virLXCConfig)
/* Functions */
-virCapsPtr lxcCapsInit(virLXCDriverPtr driver)
+virCapsPtr virLXCDriverCapsInit(virLXCDriverPtr driver)
{
virCapsPtr caps;
virCapsGuestPtr guest;
@@ -153,6 +153,33 @@ error:
}
+/**
+ * virLXCDriverGetCapabilities:
+ *
+ * Get a reference to the virCapsPtr instance for the
+ * driver. If @refresh is true, the capabilities will be
+ * rebuilt first
+ *
+ * The caller must release the reference with virObjetUnref
+ *
+ * Returns: a reference to a virCapsPtr instance or NULL
+ */
+virCapsPtr virLXCDriverGetCapabilities(virLXCDriverPtr driver,
+ bool refresh)
+{
+ if (refresh) {
+ virCapsPtr caps = NULL;
+ if ((caps = virLXCDriverCapsInit(driver)) == NULL)
+ return NULL;
+
+ virObjectUnref(driver->caps);
+ driver->caps = caps;
+ }
+
+ return virObjectRef(driver->caps);
+}
+
+
virDomainXMLOptionPtr
lxcDomainXMLConfInit(void)
{
diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h
index 6c81368..f8caebe 100644
--- a/src/lxc/lxc_conf.h
+++ b/src/lxc/lxc_conf.h
@@ -72,7 +72,8 @@ struct _virLXCDriver {
* then lockless thereafter */
virLXCDriverConfigPtr config;
- /* Require lock while using. Unsafe. XXX */
+ /* Require lock to get a reference on the object,
+ * lockless access thereafter */
virCapsPtr caps;
/* Immutable pointer. Unsafe APIs XXX */
@@ -112,7 +113,9 @@ virLXCDriverConfigPtr virLXCDriverConfigNew(void);
virLXCDriverConfigPtr virLXCDriverGetConfig(virLXCDriverPtr driver);
int virLXCLoadDriverConfig(virLXCDriverConfigPtr cfg,
const char *filename);
-virCapsPtr lxcCapsInit(virLXCDriverPtr driver);
+virCapsPtr virLXCDriverCapsInit(virLXCDriverPtr driver);
+virCapsPtr virLXCDriverGetCapabilities(virLXCDriverPtr driver,
+ bool refresh);
virDomainXMLOptionPtr lxcDomainXMLConfInit(void);
static inline void lxcDriverLock(virLXCDriverPtr driver)
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index ce1f941..f86b0b2 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -159,7 +159,7 @@ static virLXCControllerPtr virLXCControllerNew(const char *name)
if (VIR_STRDUP(ctrl->name, name) < 0)
goto error;
- if ((caps = lxcCapsInit(NULL)) == NULL)
+ if (!(caps = virLXCDriverCapsInit(NULL)))
goto error;
if (!(xmlopt = lxcDomainXMLConfInit()))
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 60d21e3..df9fb92 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -193,16 +193,23 @@ static int lxcConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
static char *lxcConnectGetCapabilities(virConnectPtr conn) {
virLXCDriverPtr driver = conn->privateData;
+ virCapsPtr caps;
char *xml;
if (virConnectGetCapabilitiesEnsureACL(conn) < 0)
return NULL;
lxcDriverLock(driver);
- if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
+ if (!(caps = virLXCDriverGetCapabilities(driver, false))) {
+ lxcDriverUnlock(driver);
+ return NULL;
+ }
+
+ if ((xml = virCapabilitiesFormatXML(caps)) == NULL)
virReportOOMError();
lxcDriverUnlock(driver);
+ virObjectUnref(caps);
return xml;
}
@@ -457,11 +464,15 @@ static virDomainPtr lxcDomainDefineXML(virConnectPtr conn, const
char *xml)
virDomainEventPtr event = NULL;
virDomainDefPtr oldDef = NULL;
virLXCDriverConfigPtr cfg = NULL;
+ virCapsPtr caps = NULL;
lxcDriverLock(driver);
cfg = virLXCDriverGetConfig(driver);
- if (!(def = virDomainDefParseString(xml, driver->caps, driver->xmlopt,
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
+ if (!(def = virDomainDefParseString(xml, caps, driver->xmlopt,
1 << VIR_DOMAIN_VIRT_LXC,
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
@@ -509,6 +520,7 @@ cleanup:
virObjectUnlock(vm);
if (event)
virDomainEventStateQueue(driver->domainEventState, event);
+ virObjectUnref(caps);
lxcDriverUnlock(driver);
virObjectUnref(cfg);
return dom;
@@ -1119,17 +1131,21 @@ lxcDomainCreateXML(virConnectPtr conn,
{
virLXCDriverPtr driver = conn->privateData;
virDomainObjPtr vm = NULL;
- virDomainDefPtr def;
+ virDomainDefPtr def = NULL;
virDomainPtr dom = NULL;
virDomainEventPtr event = NULL;
virLXCDriverConfigPtr cfg = NULL;
+ virCapsPtr caps = NULL;
virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, NULL);
lxcDriverLock(driver);
cfg = virLXCDriverGetConfig(driver);
- if (!(def = virDomainDefParseString(xml, driver->caps, driver->xmlopt,
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
+ if (!(def = virDomainDefParseString(xml, caps, driver->xmlopt,
1 << VIR_DOMAIN_VIRT_LXC,
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
@@ -1178,6 +1194,7 @@ cleanup:
virObjectUnlock(vm);
if (event)
virDomainEventStateQueue(driver->domainEventState, event);
+ virObjectUnref(caps);
lxcDriverUnlock(driver);
virObjectUnref(cfg);
return dom;
@@ -1257,6 +1274,7 @@ static int lxcNodeGetSecurityModel(virConnectPtr conn,
virSecurityModelPtr secmodel)
{
virLXCDriverPtr driver = conn->privateData;
+ virCapsPtr caps = NULL;
int ret = 0;
lxcDriverLock(driver);
@@ -1265,12 +1283,15 @@ static int lxcNodeGetSecurityModel(virConnectPtr conn,
if (virNodeGetSecurityModelEnsureACL(conn) < 0)
goto cleanup;
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
/* we treat no driver as success, but simply return no data in *secmodel */
- if (driver->caps->host.nsecModels == 0
- || driver->caps->host.secModels[0].model == NULL)
+ if (caps->host.nsecModels == 0
+ || caps->host.secModels[0].model == NULL)
goto cleanup;
- if (!virStrcpy(secmodel->model, driver->caps->host.secModels[0].model,
+ if (!virStrcpy(secmodel->model, caps->host.secModels[0].model,
VIR_SECURITY_MODEL_BUFLEN)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("security model string exceeds max %d bytes"),
@@ -1279,7 +1300,7 @@ static int lxcNodeGetSecurityModel(virConnectPtr conn,
goto cleanup;
}
- if (!virStrcpy(secmodel->doi, driver->caps->host.secModels[0].doi,
+ if (!virStrcpy(secmodel->doi, caps->host.secModels[0].doi,
VIR_SECURITY_DOI_BUFLEN)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("security DOI string exceeds max %d bytes"),
@@ -1289,6 +1310,7 @@ static int lxcNodeGetSecurityModel(virConnectPtr conn,
}
cleanup:
+ virObjectUnref(caps);
lxcDriverUnlock(driver);
return ret;
}
@@ -1498,6 +1520,7 @@ static int lxcStateInitialize(bool privileged,
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
+ virCapsPtr caps = NULL;
char *ld;
virLXCDriverConfigPtr cfg = NULL;
@@ -1557,7 +1580,7 @@ static int lxcStateInitialize(bool privileged,
if ((lxc_driver->activeUsbHostdevs = virUSBDeviceListNew()) == NULL)
goto cleanup;
- if ((lxc_driver->caps = lxcCapsInit(lxc_driver)) == NULL)
+ if ((virLXCDriverGetCapabilities(lxc_driver, true)) == NULL)
goto cleanup;
if (!(lxc_driver->xmlopt = lxcDomainXMLConfInit()))
@@ -1566,11 +1589,14 @@ static int lxcStateInitialize(bool privileged,
if (!(lxc_driver->closeCallbacks = virCloseCallbacksNew()))
goto cleanup;
+ if (!(caps = virLXCDriverGetCapabilities(lxc_driver, false)))
+ goto cleanup;
+
/* Get all the running persistent or transient configs first */
if (virDomainObjListLoadAllConfigs(lxc_driver->domains,
cfg->stateDir,
NULL, 1,
- lxc_driver->caps,
+ caps,
lxc_driver->xmlopt,
1 << VIR_DOMAIN_VIRT_LXC,
NULL, NULL) < 0)
@@ -1582,7 +1608,7 @@ static int lxcStateInitialize(bool privileged,
if (virDomainObjListLoadAllConfigs(lxc_driver->domains,
cfg->configDir,
cfg->autostartDir, 0,
- lxc_driver->caps,
+ caps,
lxc_driver->xmlopt,
1 << VIR_DOMAIN_VIRT_LXC,
NULL, NULL) < 0)
@@ -1596,6 +1622,7 @@ static int lxcStateInitialize(bool privileged,
return 0;
cleanup:
+ virObjectUnref(caps);
lxcDriverUnlock(lxc_driver);
lxcStateCleanup();
return -1;
@@ -1624,21 +1651,28 @@ static void lxcNotifyLoadDomain(virDomainObjPtr vm, int newVM,
void *opaque)
static int
lxcStateReload(void) {
virLXCDriverConfigPtr cfg = NULL;
+ virCapsPtr caps = NULL;
if (!lxc_driver)
return 0;
lxcDriverLock(lxc_driver);
+ if (!(caps = virLXCDriverGetCapabilities(lxc_driver, false))) {
+ lxcDriverUnlock(lxc_driver);
+ return -1;
+ }
+
cfg = virLXCDriverGetConfig(lxc_driver);
virDomainObjListLoadAllConfigs(lxc_driver->domains,
cfg->configDir,
cfg->autostartDir, 0,
- lxc_driver->caps,
+ caps,
lxc_driver->xmlopt,
1 << VIR_DOMAIN_VIRT_LXC,
lxcNotifyLoadDomain, lxc_driver);
lxcDriverUnlock(lxc_driver);
+ virObjectUnref(caps);
virObjectUnref(cfg);
return 0;
}
@@ -1866,6 +1900,7 @@ lxcDomainSetSchedulerParametersFlags(virDomainPtr dom,
unsigned int flags)
{
virLXCDriverPtr driver = dom->conn->privateData;
+ virCapsPtr caps = NULL;
size_t i;
virDomainObjPtr vm = NULL;
virDomainDefPtr vmdef = NULL;
@@ -1902,13 +1937,16 @@ lxcDomainSetSchedulerParametersFlags(virDomainPtr dom,
if (virDomainSetSchedulerParametersFlagsEnsureACL(dom->conn, vm->def, flags)
< 0)
goto cleanup;
- if (virDomainLiveConfigHelperMethod(driver->caps, driver->xmlopt,
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
+ if (virDomainLiveConfigHelperMethod(caps, driver->xmlopt,
vm, &flags, &vmdef) < 0)
goto cleanup;
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
/* Make a copy for updated domain. */
- vmdef = virDomainObjCopyPersistentDef(vm, driver->caps, driver->xmlopt);
+ vmdef = virDomainObjCopyPersistentDef(vm, caps, driver->xmlopt);
if (!vmdef)
goto cleanup;
}
@@ -1987,6 +2025,7 @@ cleanup:
virDomainDefFree(vmdef);
if (vm)
virObjectUnlock(vm);
+ virObjectUnref(caps);
lxcDriverUnlock(driver);
virObjectUnref(cfg);
return ret;
@@ -2007,6 +2046,7 @@ lxcDomainGetSchedulerParametersFlags(virDomainPtr dom,
unsigned int flags)
{
virLXCDriverPtr driver = dom->conn->privateData;
+ virCapsPtr caps = NULL;
virDomainObjPtr vm = NULL;
virDomainDefPtr persistentDef;
unsigned long long shares = 0;
@@ -2042,7 +2082,10 @@ lxcDomainGetSchedulerParametersFlags(virDomainPtr dom,
cpu_bw_status = !!rc;
}
- if (virDomainLiveConfigHelperMethod(driver->caps, driver->xmlopt,
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
+ if (virDomainLiveConfigHelperMethod(caps, driver->xmlopt,
vm, &flags, &persistentDef) < 0)
goto cleanup;
@@ -2105,6 +2148,7 @@ out:
cleanup:
if (vm)
virObjectUnlock(vm);
+ virObjectUnref(caps);
lxcDriverUnlock(driver);
return ret;
}
@@ -2125,6 +2169,7 @@ lxcDomainSetBlkioParameters(virDomainPtr dom,
unsigned int flags)
{
virLXCDriverPtr driver = dom->conn->privateData;
+ virCapsPtr caps = NULL;
size_t i;
virDomainObjPtr vm = NULL;
virDomainDefPtr persistentDef = NULL;
@@ -2156,7 +2201,10 @@ lxcDomainSetBlkioParameters(virDomainPtr dom,
if (virDomainSetBlkioParametersEnsureACL(dom->conn, vm->def, flags) < 0)
goto cleanup;
- if (virDomainLiveConfigHelperMethod(driver->caps, driver->xmlopt,
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
+ if (virDomainLiveConfigHelperMethod(caps, driver->xmlopt,
vm, &flags, &persistentDef) < 0)
goto cleanup;
@@ -2214,6 +2262,7 @@ lxcDomainSetBlkioParameters(virDomainPtr dom,
cleanup:
if (vm)
virObjectUnlock(vm);
+ virObjectUnref(caps);
lxcDriverUnlock(driver);
virObjectUnref(cfg);
return ret;
@@ -2228,6 +2277,7 @@ lxcDomainGetBlkioParameters(virDomainPtr dom,
unsigned int flags)
{
virLXCDriverPtr driver = dom->conn->privateData;
+ virCapsPtr caps = NULL;
size_t i;
virDomainObjPtr vm = NULL;
virDomainDefPtr persistentDef = NULL;
@@ -2259,7 +2309,10 @@ lxcDomainGetBlkioParameters(virDomainPtr dom,
goto cleanup;
}
- if (virDomainLiveConfigHelperMethod(driver->caps, driver->xmlopt,
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
+ if (virDomainLiveConfigHelperMethod(caps, driver->xmlopt,
vm, &flags, &persistentDef) < 0)
goto cleanup;
@@ -2320,6 +2373,7 @@ lxcDomainGetBlkioParameters(virDomainPtr dom,
cleanup:
if (vm)
virObjectUnlock(vm);
+ virObjectUnref(caps);
lxcDriverUnlock(driver);
return ret;
}
@@ -4320,6 +4374,7 @@ static int lxcDomainAttachDeviceFlags(virDomainPtr dom,
unsigned int flags)
{
virLXCDriverPtr driver = dom->conn->privateData;
+ virCapsPtr caps = NULL;
virDomainObjPtr vm = NULL;
virDomainDefPtr vmdef = NULL;
virDomainDeviceDefPtr dev = NULL, dev_copy = NULL;
@@ -4363,6 +4418,9 @@ static int lxcDomainAttachDeviceFlags(virDomainPtr dom,
}
}
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && !vm->persistent) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("cannot modify device on transient domain"));
@@ -4370,7 +4428,7 @@ static int lxcDomainAttachDeviceFlags(virDomainPtr dom,
}
dev = dev_copy = virDomainDeviceDefParse(xml, vm->def,
- driver->caps, driver->xmlopt,
+ caps, driver->xmlopt,
VIR_DOMAIN_XML_INACTIVE);
if (dev == NULL)
goto cleanup;
@@ -4382,7 +4440,7 @@ static int lxcDomainAttachDeviceFlags(virDomainPtr dom,
* to CONFIG takes one instance.
*/
dev_copy = virDomainDeviceDefCopy(dev, vm->def,
- driver->caps, driver->xmlopt);
+ caps, driver->xmlopt);
if (!dev_copy)
goto cleanup;
}
@@ -4392,7 +4450,7 @@ static int lxcDomainAttachDeviceFlags(virDomainPtr dom,
goto cleanup;
/* Make a copy for updated domain. */
- vmdef = virDomainObjCopyPersistentDef(vm, driver->caps, driver->xmlopt);
+ vmdef = virDomainObjCopyPersistentDef(vm, caps, driver->xmlopt);
if (!vmdef)
goto cleanup;
if ((ret = lxcDomainAttachDeviceConfig(vmdef, dev)) < 0)
@@ -4432,6 +4490,7 @@ cleanup:
virDomainDeviceDefFree(dev);
if (vm)
virObjectUnlock(vm);
+ virObjectUnref(caps);
lxcDriverUnlock(driver);
virObjectUnref(cfg);
return ret;
@@ -4451,6 +4510,7 @@ static int lxcDomainUpdateDeviceFlags(virDomainPtr dom,
unsigned int flags)
{
virLXCDriverPtr driver = dom->conn->privateData;
+ virCapsPtr caps = NULL;
virDomainObjPtr vm = NULL;
virDomainDefPtr vmdef = NULL;
virDomainDeviceDefPtr dev = NULL, dev_copy = NULL;
@@ -4501,8 +4561,11 @@ static int lxcDomainUpdateDeviceFlags(virDomainPtr dom,
goto cleanup;
}
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
dev = dev_copy = virDomainDeviceDefParse(xml, vm->def,
- driver->caps, driver->xmlopt,
+ caps, driver->xmlopt,
VIR_DOMAIN_XML_INACTIVE);
if (dev == NULL)
goto cleanup;
@@ -4514,7 +4577,7 @@ static int lxcDomainUpdateDeviceFlags(virDomainPtr dom,
* to CONFIG takes one instance.
*/
dev_copy = virDomainDeviceDefCopy(dev, vm->def,
- driver->caps, driver->xmlopt);
+ caps, driver->xmlopt);
if (!dev_copy)
goto cleanup;
}
@@ -4524,7 +4587,7 @@ static int lxcDomainUpdateDeviceFlags(virDomainPtr dom,
goto cleanup;
/* Make a copy for updated domain. */
- vmdef = virDomainObjCopyPersistentDef(vm, driver->caps, driver->xmlopt);
+ vmdef = virDomainObjCopyPersistentDef(vm, caps, driver->xmlopt);
if (!vmdef)
goto cleanup;
if ((ret = lxcDomainUpdateDeviceConfig(vmdef, dev)) < 0)
@@ -4557,6 +4620,7 @@ cleanup:
virDomainDeviceDefFree(dev);
if (vm)
virObjectUnlock(vm);
+ virObjectUnref(caps);
lxcDriverUnlock(driver);
virObjectUnref(cfg);
return ret;
@@ -4568,6 +4632,7 @@ static int lxcDomainDetachDeviceFlags(virDomainPtr dom,
unsigned int flags)
{
virLXCDriverPtr driver = dom->conn->privateData;
+ virCapsPtr caps = NULL;
virDomainObjPtr vm = NULL;
virDomainDefPtr vmdef = NULL;
virDomainDeviceDefPtr dev = NULL, dev_copy = NULL;
@@ -4617,8 +4682,11 @@ static int lxcDomainDetachDeviceFlags(virDomainPtr dom,
goto cleanup;
}
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
dev = dev_copy = virDomainDeviceDefParse(xml, vm->def,
- driver->caps, driver->xmlopt,
+ caps, driver->xmlopt,
VIR_DOMAIN_XML_INACTIVE);
if (dev == NULL)
goto cleanup;
@@ -4630,7 +4698,7 @@ static int lxcDomainDetachDeviceFlags(virDomainPtr dom,
* to CONFIG takes one instance.
*/
dev_copy = virDomainDeviceDefCopy(dev, vm->def,
- driver->caps, driver->xmlopt);
+ caps, driver->xmlopt);
if (!dev_copy)
goto cleanup;
}
@@ -4640,7 +4708,7 @@ static int lxcDomainDetachDeviceFlags(virDomainPtr dom,
goto cleanup;
/* Make a copy for updated domain. */
- vmdef = virDomainObjCopyPersistentDef(vm, driver->caps, driver->xmlopt);
+ vmdef = virDomainObjCopyPersistentDef(vm, caps, driver->xmlopt);
if (!vmdef)
goto cleanup;
@@ -4681,6 +4749,7 @@ cleanup:
virDomainDeviceDefFree(dev);
if (vm)
virObjectUnlock(vm);
+ virObjectUnref(caps);
lxcDriverUnlock(driver);
virObjectUnref(cfg);
return ret;
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 931aee9..3c4a71a 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -976,6 +976,7 @@ int virLXCProcessStart(virConnectPtr conn,
char *timestamp;
virCommandPtr cmd = NULL;
virLXCDomainObjPrivatePtr priv = vm->privateData;
+ virCapsPtr caps = NULL;
virErrorPtr err = NULL;
virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
@@ -1017,12 +1018,15 @@ int virLXCProcessStart(virConnectPtr conn,
cfg->logDir, vm->def->name) < 0)
return -1;
+ if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
/* Do this up front, so any part of the startup process can add
* runtime state to vm->def that won't be persisted. This let's us
* report implicit runtime defaults in the XML, like vnc listen/socket
*/
VIR_DEBUG("Setting current domain def as transient");
- if (virDomainObjSetDefTransient(driver->caps, driver->xmlopt, vm, true) <
0)
+ if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm, true) < 0)
goto cleanup;
/* Run an early hook to set-up missing devices */
@@ -1216,7 +1220,7 @@ int virLXCProcessStart(virConnectPtr conn,
conn, lxcProcessAutoDestroy) < 0)
goto error;
- if (virDomainObjSetDefTransient(driver->caps, driver->xmlopt,
+ if (virDomainObjSetDefTransient(caps, driver->xmlopt,
vm, false) < 0)
goto error;
@@ -1290,6 +1294,7 @@ cleanup:
VIR_FORCE_CLOSE(handshakefds[1]);
VIR_FREE(logfile);
virObjectUnref(cfg);
+ virObjectUnref(caps);
if (err) {
virSetError(err);
--
1.8.1.5