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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list