The reasoning here is the same as in qemu driver fixed in
previous commit. Long story short, changing an XML of a domain
requires modify job to be acquired.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/lxc/lxc_domain.c | 57 ++++++++++++++++++++++++++++++++++++++++++++
src/lxc/lxc_domain.h | 7 ++++++
src/lxc/lxc_driver.c | 11 +++------
3 files changed, 67 insertions(+), 8 deletions(-)
diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c
index 51a9fd36eb..800999cbed 100644
--- a/src/lxc/lxc_domain.c
+++ b/src/lxc/lxc_domain.c
@@ -47,6 +47,63 @@ VIR_ENUM_IMPL(virLXCDomainJob,
VIR_LOG_INIT("lxc.lxc_domain");
+
+/**
+ * lxcDomainObjListAdd:
+ * @driver: LXC driver
+ * @def: domain definition
+ * @oldDef: previous domain definition
+ * @live: whether @def is live definition
+ * @flags: an bitwise-OR of virDomainObjListAdd flags
+ *
+ * Add a domain onto the list of domain object and sets its
+ * definition. If @oldDef is not NULL and there was pre-existing
+ * definition it's returned in @oldDef.
+ *
+ * In addition to that, if definition of an existing domain is
+ * changed a MODIFY job is acquired prior to that.
+ *
+ * Returns: domain object pointer on success,
+ * NULL otherwise.
+ */
+virDomainObjPtr
+lxcDomainObjListAdd(virLXCDriverPtr driver,
+ virDomainDefPtr def,
+ virDomainDefPtr *oldDef,
+ bool live,
+ unsigned int flags)
+{
+ virDomainObjPtr vm = NULL;
+
+ if (!(vm = virDomainObjListAdd(driver->domains, def, driver->xmlopt, flags)))
+ return NULL;
+
+ /* At this point, @vm is locked. If it doesn't have any
+ * definition set, then the call above just added it and
+ * there can't be anybody else using the object. It's safe to
+ * just set the definition without acquiring job. */
+ if (!vm->def) {
+ virDomainObjAssignDef(vm, def, live, oldDef);
+ VIR_RETURN_PTR(vm);
+ }
+
+ /* Bad luck. Domain was pre-existing and this call is trying
+ * to update its definition. Modify job MUST be acquired. */
+ if (virLXCDomainObjBeginJob(driver, vm, LXC_JOB_MODIFY) < 0) {
+ if (!vm->persistent)
+ virDomainObjListRemove(driver->domains, vm);
+ virDomainObjEndAPI(&vm);
+ return NULL;
+ }
+
+ virDomainObjAssignDef(vm, def, live, oldDef);
+
+ virLXCDomainObjEndJob(driver, vm);
+
+ return vm;
+}
+
+
static int
virLXCDomainObjInitJob(virLXCDomainObjPrivatePtr priv)
{
diff --git a/src/lxc/lxc_domain.h b/src/lxc/lxc_domain.h
index 2048481829..522cf7917d 100644
--- a/src/lxc/lxc_domain.h
+++ b/src/lxc/lxc_domain.h
@@ -96,6 +96,13 @@ extern virDomainXMLNamespace virLXCDriverDomainXMLNamespace;
extern virDomainXMLPrivateDataCallbacks virLXCDriverPrivateDataCallbacks;
extern virDomainDefParserConfig virLXCDriverDomainDefParserConfig;
+virDomainObjPtr
+lxcDomainObjListAdd(virLXCDriverPtr driver,
+ virDomainDefPtr def,
+ virDomainDefPtr *oldDef,
+ bool live,
+ unsigned int flags);
+
int
virLXCDomainObjBeginJob(virLXCDriverPtr driver,
virDomainObjPtr obj,
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index eaf26563f5..41e6b59927 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -444,12 +444,10 @@ lxcDomainDefineXMLFlags(virConnectPtr conn, const char *xml,
unsigned int flags)
goto cleanup;
}
- if (!(vm = virDomainObjListAdd(driver->domains, def,
- driver->xmlopt, 0)))
+ if (!(vm = lxcDomainObjListAdd(driver, def, &oldDef, false, 0)))
goto cleanup;
-
- virDomainObjAssignDef(vm, def, false, &oldDef);
def = NULL;
+
vm->persistent = 1;
if (virDomainSaveConfig(cfg->configDir, driver->caps,
@@ -1191,12 +1189,9 @@ lxcDomainCreateXMLWithFiles(virConnectPtr conn,
}
- if (!(vm = virDomainObjListAdd(driver->domains, def,
- driver->xmlopt,
+ if (!(vm = lxcDomainObjListAdd(driver, def, NULL, true,
VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE)))
goto cleanup;
-
- virDomainObjAssignDef(vm, def, true, NULL);
def = NULL;
if (virLXCDomainObjBeginJob(driver, vm, LXC_JOB_MODIFY) < 0) {
--
2.21.0