virDomainCreateXML: Don't remove persistent domains on error

https://bugzilla.redhat.com/show_bug.cgi?id=871452

Okay, so we allow users to 'virsh create' an already existing
domain, providing completely different XML than the one stored in
Libvirt. Well, as long as name and UUID matches. However, in some
drivers the code that handles errors unconditionally removes the
domain that failed to start even though the domain might have
been persistent. Fortunately, the domain is removed just from the
internal list of domains and the config file is kept around.

Steps to reproduce:

1) virsh dumpxml $dom > /tmp/dom.xml
2) change XML so that it is still parse-able but won't boot, e.g.
change guest agent path to /foo/bar
3) virsh create /tmp/dom.xml
4) virsh dumpxml $dom
5) Observe "No such domain" error

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 37405b9109)
This commit is contained in:
Michal Privoznik 2015-09-22 16:52:03 +02:00 committed by Cole Robinson
parent c22a4bb523
commit e89b42ccc6
5 changed files with 22 additions and 10 deletions

View File

@ -1239,8 +1239,10 @@ lxcDomainCreateXMLWithFiles(virConnectPtr conn,
(flags & VIR_DOMAIN_START_AUTODESTROY),
VIR_DOMAIN_RUNNING_BOOTED) < 0) {
virDomainAuditStart(vm, "booted", false);
virDomainObjListRemove(driver->domains, vm);
vm = NULL;
if (!vm->persistent) {
virDomainObjListRemove(driver->domains, vm);
vm = NULL;
}
goto cleanup;
}

View File

@ -1751,7 +1751,8 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
def = NULL;
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) {
qemuDomainRemoveInactive(driver, vm);
if (!vm->persistent)
qemuDomainRemoveInactive(driver, vm);
goto cleanup;
}
@ -1761,7 +1762,8 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
start_flags) < 0) {
virDomainAuditStart(vm, "booted", false);
qemuDomainObjEndJob(driver, vm);
qemuDomainRemoveInactive(driver, vm);
if (!vm->persistent)
qemuDomainRemoveInactive(driver, vm);
goto cleanup;
}

View File

@ -1621,8 +1621,13 @@ testDomainCreateXML(virConnectPtr conn, const char *xml,
goto cleanup;
def = NULL;
if (testDomainStartState(privconn, dom, VIR_DOMAIN_RUNNING_BOOTED) < 0)
if (testDomainStartState(privconn, dom, VIR_DOMAIN_RUNNING_BOOTED) < 0) {
if (!dom->persistent) {
virDomainObjListRemove(privconn->domains, dom);
dom = NULL;
}
goto cleanup;
}
event = virDomainEventLifecycleNewFromObj(dom,
VIR_DOMAIN_EVENT_STARTED,

View File

@ -1623,9 +1623,10 @@ static virDomainPtr umlDomainCreateXML(virConnectPtr conn, const char *xml,
if (umlStartVMDaemon(conn, driver, vm,
(flags & VIR_DOMAIN_START_AUTODESTROY)) < 0) {
virDomainAuditStart(vm, "booted", false);
virDomainObjListRemove(driver->domains,
vm);
vm = NULL;
if (!vm->persistent) {
virDomainObjListRemove(driver->domains, vm);
vm = NULL;
}
goto cleanup;
}
virDomainAuditStart(vm, "booted", true);

View File

@ -710,8 +710,10 @@ vmwareDomainCreateXML(virConnectPtr conn, const char *xml,
vmdef = NULL;
if (vmwareStartVM(driver, vm) < 0) {
virDomainObjListRemove(driver->domains, vm);
vm = NULL;
if (!vm->persistent) {
virDomainObjListRemove(driver->domains, vm);
vm = NULL;
}
goto cleanup;
}