|
|
c401cc |
From 192667c53a356a2bc3aa389312345453dd1c3bd5 Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <192667c53a356a2bc3aa389312345453dd1c3bd5.1390394206.git.jdenemar@redhat.com>
|
|
|
c401cc |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
c401cc |
Date: Fri, 17 Jan 2014 14:28:18 +0100
|
|
|
c401cc |
Subject: [PATCH] qemu: Avoid operations on NULL monitor if VM fails early
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1054785 [7.0]
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1047659 [6.6]
|
|
|
c401cc |
|
|
|
c401cc |
If a VM dies very early during an attempted connect to the guest agent
|
|
|
c401cc |
while the locks are down the domain monitor object will be freed. The
|
|
|
c401cc |
object is then accessed later as any failure during guest agent startup
|
|
|
c401cc |
isn't considered fatal.
|
|
|
c401cc |
|
|
|
c401cc |
In the current upstream version this doesn't lead to a crash as
|
|
|
c401cc |
virObjectLock called when entering the monitor in
|
|
|
c401cc |
qemuProcessDetectVcpuPIDs checks the pointer before attempting to
|
|
|
c401cc |
dereference (lock) it. The NULL pointer is then caught in the monitor
|
|
|
c401cc |
helper code.
|
|
|
c401cc |
|
|
|
c401cc |
Before the introduction of virObjectLockable - observed on 0.10.2 - the
|
|
|
c401cc |
pointer is locked directly via virMutexLock leading to a crash.
|
|
|
c401cc |
|
|
|
c401cc |
To avoid this problem we need to differentiate between the guest agent
|
|
|
c401cc |
not being present and the VM quitting when the locks were down. The fix
|
|
|
c401cc |
reorganizes the code in qemuConnectAgent to add the check and then adds
|
|
|
c401cc |
special handling to the callers.
|
|
|
c401cc |
|
|
|
c401cc |
(cherry picked from commit b952cbbccafd5ead8b5a70b2608a1d5a7f03b31e)
|
|
|
c401cc |
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
src/qemu/qemu_process.c | 34 +++++++++++++++++++++++++---------
|
|
|
c401cc |
1 file changed, 25 insertions(+), 9 deletions(-)
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|
|
c401cc |
index a4b757c..af66e0d 100644
|
|
|
c401cc |
--- a/src/qemu/qemu_process.c
|
|
|
c401cc |
+++ b/src/qemu/qemu_process.c
|
|
|
c401cc |
@@ -245,6 +245,17 @@ qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm)
|
|
|
c401cc |
virObjectLock(vm);
|
|
|
c401cc |
priv->agentStart = 0;
|
|
|
c401cc |
|
|
|
c401cc |
+ if (agent == NULL)
|
|
|
c401cc |
+ virObjectUnref(vm);
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (!virDomainObjIsActive(vm)) {
|
|
|
c401cc |
+ qemuAgentClose(agent);
|
|
|
c401cc |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
c401cc |
+ _("guest crashed while connecting to the guest agent"));
|
|
|
c401cc |
+ ret = -2;
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
if (virSecurityManagerClearSocketLabel(driver->securityManager,
|
|
|
c401cc |
vm->def) < 0) {
|
|
|
c401cc |
VIR_ERROR(_("Failed to clear security context for agent for %s"),
|
|
|
c401cc |
@@ -252,13 +263,7 @@ qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm)
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
- if (agent == NULL)
|
|
|
c401cc |
- virObjectUnref(vm);
|
|
|
c401cc |
|
|
|
c401cc |
- if (!virDomainObjIsActive(vm)) {
|
|
|
c401cc |
- qemuAgentClose(agent);
|
|
|
c401cc |
- goto cleanup;
|
|
|
c401cc |
- }
|
|
|
c401cc |
priv->agent = agent;
|
|
|
c401cc |
|
|
|
c401cc |
if (priv->agent == NULL) {
|
|
|
c401cc |
@@ -3092,6 +3097,7 @@ qemuProcessReconnect(void *opaque)
|
|
|
c401cc |
int reason;
|
|
|
c401cc |
virQEMUDriverConfigPtr cfg;
|
|
|
c401cc |
size_t i;
|
|
|
c401cc |
+ int ret;
|
|
|
c401cc |
|
|
|
c401cc |
memcpy(&oldjob, &data->oldjob, sizeof(oldjob));
|
|
|
c401cc |
|
|
|
c401cc |
@@ -3116,7 +3122,10 @@ qemuProcessReconnect(void *opaque)
|
|
|
c401cc |
goto error;
|
|
|
c401cc |
|
|
|
c401cc |
/* Failure to connect to agent shouldn't be fatal */
|
|
|
c401cc |
- if (qemuConnectAgent(driver, obj) < 0) {
|
|
|
c401cc |
+ if ((ret = qemuConnectAgent(driver, obj)) < 0) {
|
|
|
c401cc |
+ if (ret == -2)
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+
|
|
|
c401cc |
VIR_WARN("Cannot connect to QEMU guest agent for %s",
|
|
|
c401cc |
obj->def->name);
|
|
|
c401cc |
virResetLastError();
|
|
|
c401cc |
@@ -4005,7 +4014,10 @@ int qemuProcessStart(virConnectPtr conn,
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
|
|
|
c401cc |
/* Failure to connect to agent shouldn't be fatal */
|
|
|
c401cc |
- if (qemuConnectAgent(driver, vm) < 0) {
|
|
|
c401cc |
+ if ((ret = qemuConnectAgent(driver, vm)) < 0) {
|
|
|
c401cc |
+ if (ret == -2)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
VIR_WARN("Cannot connect to QEMU guest agent for %s",
|
|
|
c401cc |
vm->def->name);
|
|
|
c401cc |
virResetLastError();
|
|
|
c401cc |
@@ -4463,6 +4475,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
c401cc |
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
|
|
c401cc |
virCapsPtr caps = NULL;
|
|
|
c401cc |
bool active = false;
|
|
|
c401cc |
+ int ret;
|
|
|
c401cc |
|
|
|
c401cc |
VIR_DEBUG("Beginning VM attach process");
|
|
|
c401cc |
|
|
|
c401cc |
@@ -4577,7 +4590,10 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
c401cc |
goto error;
|
|
|
c401cc |
|
|
|
c401cc |
/* Failure to connect to agent shouldn't be fatal */
|
|
|
c401cc |
- if (qemuConnectAgent(driver, vm) < 0) {
|
|
|
c401cc |
+ if ((ret = qemuConnectAgent(driver, vm)) < 0) {
|
|
|
c401cc |
+ if (ret == -2)
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+
|
|
|
c401cc |
VIR_WARN("Cannot connect to QEMU guest agent for %s",
|
|
|
c401cc |
vm->def->name);
|
|
|
c401cc |
virResetLastError();
|
|
|
c401cc |
--
|
|
|
c401cc |
1.8.5.3
|
|
|
c401cc |
|