|
|
43fe83 |
From ecc34514032017857dcf514d8b7a83973f084e41 Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <ecc34514032017857dcf514d8b7a83973f084e41.1380112457.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: Eric Blake <eblake@redhat.com>
|
|
|
43fe83 |
Date: Mon, 23 Sep 2013 11:10:06 -0600
|
|
|
43fe83 |
Subject: [PATCH] qemu: don't leak vm on failure
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=1010617
|
|
|
43fe83 |
|
|
|
43fe83 |
Failure to attach to a domain during 'virsh qemu-attach' left
|
|
|
43fe83 |
the list of domains in an odd state:
|
|
|
43fe83 |
|
|
|
43fe83 |
$ virsh qemu-attach 4176
|
|
|
43fe83 |
error: An error occurred, but the cause is unknown
|
|
|
43fe83 |
|
|
|
43fe83 |
$ virsh list --all
|
|
|
43fe83 |
Id Name State
|
|
|
43fe83 |
----------------------------------------------------
|
|
|
43fe83 |
2 foo shut off
|
|
|
43fe83 |
|
|
|
43fe83 |
$ virsh qemu-attach 4176
|
|
|
43fe83 |
error: Requested operation is not valid: domain is already active as 'foo'
|
|
|
43fe83 |
|
|
|
43fe83 |
$ virsh undefine foo
|
|
|
43fe83 |
error: Failed to undefine domain foo
|
|
|
43fe83 |
error: Requested operation is not valid: cannot undefine transient domain
|
|
|
43fe83 |
|
|
|
43fe83 |
$ virsh shutdown foo
|
|
|
43fe83 |
error: Failed to shutdown domain foo
|
|
|
43fe83 |
error: invalid argument: monitor must not be NULL
|
|
|
43fe83 |
|
|
|
43fe83 |
It all stems from leaving the list of domains unmodified on
|
|
|
43fe83 |
the initial failure; we should follow the lead of createXML
|
|
|
43fe83 |
which removes vm on failure (the actual initial failure still
|
|
|
43fe83 |
needs to be fixed in a later patch, but at least this patch
|
|
|
43fe83 |
gets us to the point where we aren't getting stuck with an
|
|
|
43fe83 |
unremovable "shut off" transient domain).
|
|
|
43fe83 |
|
|
|
43fe83 |
While investigating, I also found a leak in qemuDomainCreateXML;
|
|
|
43fe83 |
the two functions should behave similarly. Note that there are
|
|
|
43fe83 |
still two unusual paths: if dom is not allocated, the user will
|
|
|
43fe83 |
see an OOM error even though the vm remains registered (but oom
|
|
|
43fe83 |
errors already indicate tricky cleanup); and if the vm starts
|
|
|
43fe83 |
and then quits again all before the job ends, it is possible
|
|
|
43fe83 |
to return a non-NULL dom even though the dom will no longer be
|
|
|
43fe83 |
useful for anything (but this at least lets the user know their
|
|
|
43fe83 |
short-lived vm ran).
|
|
|
43fe83 |
|
|
|
43fe83 |
* src/qemu/qemu_driver.c (qemuDomainCreateXML): Don't leak vm on
|
|
|
43fe83 |
failure to obtain job.
|
|
|
43fe83 |
(qemuDomainQemuAttach): Match cleanup of qemuDomainCreateXML.
|
|
|
43fe83 |
|
|
|
43fe83 |
Signed-off-by: Eric Blake <eblake@redhat.com>
|
|
|
43fe83 |
(cherry picked from commit d047b2d9835cbe5090e9eedb11ab69e7e4522f76)
|
|
|
43fe83 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/qemu/qemu_driver.c | 33 ++++++++++++++++++++-------------
|
|
|
43fe83 |
1 file changed, 20 insertions(+), 13 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
43fe83 |
index eb1a2ce..693dd85 100644
|
|
|
43fe83 |
--- a/src/qemu/qemu_driver.c
|
|
|
43fe83 |
+++ b/src/qemu/qemu_driver.c
|
|
|
43fe83 |
@@ -1602,8 +1602,11 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
|
|
|
43fe83 |
|
|
|
43fe83 |
def = NULL;
|
|
|
43fe83 |
|
|
|
43fe83 |
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
|
|
|
43fe83 |
- goto cleanup; /* XXXX free the 'vm' we created ? */
|
|
|
43fe83 |
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) {
|
|
|
43fe83 |
+ qemuDomainRemoveInactive(driver, vm);
|
|
|
43fe83 |
+ vm = NULL;
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
|
|
|
43fe83 |
if (qemuProcessStart(conn, driver, vm, NULL, -1, NULL, NULL,
|
|
|
43fe83 |
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
|
|
|
43fe83 |
@@ -1631,10 +1634,10 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
|
|
|
43fe83 |
virDomainAuditStart(vm, "booted", true);
|
|
|
43fe83 |
|
|
|
43fe83 |
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
|
|
43fe83 |
- if (dom) dom->id = vm->def->id;
|
|
|
43fe83 |
+ if (dom)
|
|
|
43fe83 |
+ dom->id = vm->def->id;
|
|
|
43fe83 |
|
|
|
43fe83 |
- if (vm &&
|
|
|
43fe83 |
- qemuDomainObjEndJob(driver, vm) == 0)
|
|
|
43fe83 |
+ if (qemuDomainObjEndJob(driver, vm) == 0)
|
|
|
43fe83 |
vm = NULL;
|
|
|
43fe83 |
|
|
|
43fe83 |
cleanup:
|
|
|
43fe83 |
@@ -13885,34 +13888,38 @@ static virDomainPtr qemuDomainQemuAttach(virConnectPtr conn,
|
|
|
43fe83 |
|
|
|
43fe83 |
def = NULL;
|
|
|
43fe83 |
|
|
|
43fe83 |
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
|
|
|
43fe83 |
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) {
|
|
|
43fe83 |
+ qemuDomainRemoveInactive(driver, vm);
|
|
|
43fe83 |
+ vm = NULL;
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
|
|
|
43fe83 |
if (qemuProcessAttach(conn, driver, vm, pid,
|
|
|
43fe83 |
pidfile, monConfig, monJSON) < 0) {
|
|
|
43fe83 |
+ if (qemuDomainObjEndJob(driver, vm) > 0)
|
|
|
43fe83 |
+ qemuDomainRemoveInactive(driver, vm);
|
|
|
43fe83 |
+ vm = NULL;
|
|
|
43fe83 |
monConfig = NULL;
|
|
|
43fe83 |
- goto endjob;
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
monConfig = NULL;
|
|
|
43fe83 |
|
|
|
43fe83 |
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
|
|
43fe83 |
- if (dom) dom->id = vm->def->id;
|
|
|
43fe83 |
+ if (dom)
|
|
|
43fe83 |
+ dom->id = vm->def->id;
|
|
|
43fe83 |
|
|
|
43fe83 |
-endjob:
|
|
|
43fe83 |
- if (qemuDomainObjEndJob(driver, vm) == 0) {
|
|
|
43fe83 |
+ if (qemuDomainObjEndJob(driver, vm) == 0)
|
|
|
43fe83 |
vm = NULL;
|
|
|
43fe83 |
- goto cleanup;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
|
|
|
43fe83 |
cleanup:
|
|
|
43fe83 |
virDomainDefFree(def);
|
|
|
43fe83 |
- virObjectUnref(qemuCaps);
|
|
|
43fe83 |
virDomainChrSourceDefFree(monConfig);
|
|
|
43fe83 |
if (vm)
|
|
|
43fe83 |
virObjectUnlock(vm);
|
|
|
43fe83 |
VIR_FREE(pidfile);
|
|
|
43fe83 |
virObjectUnref(caps);
|
|
|
43fe83 |
+ virObjectUnref(qemuCaps);
|
|
|
43fe83 |
return dom;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|