c401cc
From 8e0614121dfd5061407bdcdae574a76d3f17c349 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <8e0614121dfd5061407bdcdae574a76d3f17c349.1385135432.git.jdenemar@redhat.com>
c401cc
From: Michal Privoznik <mprivozn@redhat.com>
c401cc
Date: Fri, 15 Nov 2013 13:52:27 +0100
c401cc
Subject: [PATCH] qemuMonitorIO: Don't use @mon after it's unrefed
c401cc
c401cc
https://bugzilla.redhat.com/show_bug.cgi?id=1018267
c401cc
c401cc
The aim of virObject refing and urefing is to tell where the object is
c401cc
to be used and when is no longer needed. Hence any object shouldn't be
c401cc
used after it has been unrefed, as we might be the last to hold the
c401cc
reference. The better way is to call virObjectUnref() *after* the last
c401cc
object usage. In this specific case, the monitor EOF handler was called
c401cc
after the qemuMonitorIO called virObjectUnref. Not only that @mon was
c401cc
disposed (which is not used in the handler anyway) but the @mon->vm
c401cc
which is causing a SIGSEGV:
c401cc
c401cc
2013-11-15 10:17:54.425+0000: 20110: error : qemuMonitorIO:688 : internal error: early end of file from monitor: possible problem:
c401cc
qemu-kvm: -incoming tcp:01.01.01.0:49152: Failed to bind socket: Cannot assign requested address
c401cc
c401cc
Program received signal SIGSEGV, Segmentation fault.
c401cc
qemuProcessHandleMonitorEOF (mon=<optimized out>, vm=0x7fb728004170) at qemu/qemu_process.c:299
c401cc
299         if (priv->beingDestroyed) {
c401cc
(gdb) p *priv
c401cc
Cannot access memory at address 0x0
c401cc
(gdb) p vm
c401cc
$1 = (virDomainObj *) 0x7fb728004170
c401cc
(gdb) p *vm
c401cc
$2 = {parent = {parent = {magic = 3735928559, refs = 0, klass = 0xdeadbeef}, lock = {lock = {__data = {__lock = 2, __count = 0, __owner = 20110, __nusers = 1, __kind = 0, __spins = 0, __list = {__prev = 0x0,
c401cc
            __next = 0x0}}, __size = "\002\000\000\000\000\000\000\000\216N\000\000\001", '\000' <repeats 26 times>, __align = 2}}}, pid = 0, state = {state = 0, reason = 0}, autostart = 0, persistent = 0,
c401cc
  updated = 0, def = 0x0, newDef = 0x0, snapshots = 0x0, current_snapshot = 0x0, hasManagedSave = false, privateData = 0x0, privateDataFreeFunc = 0x0, taint = 304}
c401cc
c401cc
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
c401cc
(cherry picked from commit f417ad07df7c5aa3879ff8237c1a1cea50f093bb)
c401cc
c401cc
Conflicts:
c401cc
	src/qemu/qemu_monitor.c: Context as 1cfd5a00 is not bacported yet.
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 src/qemu/qemu_monitor.c | 4 ++--
c401cc
 1 file changed, 2 insertions(+), 2 deletions(-)
c401cc
c401cc
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
c401cc
index 4384ab4..adc9cca 100644
c401cc
--- a/src/qemu/qemu_monitor.c
c401cc
+++ b/src/qemu/qemu_monitor.c
c401cc
@@ -727,9 +727,9 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
c401cc
         /* Make sure anyone waiting wakes up now */
c401cc
         virCondSignal(&mon->notify);
c401cc
         virObjectUnlock(mon);
c401cc
-        virObjectUnref(mon);
c401cc
         VIR_DEBUG("Triggering EOF callback");
c401cc
         (eofNotify)(mon, vm);
c401cc
+        virObjectUnref(mon);
c401cc
     } else if (error) {
c401cc
         void (*errorNotify)(qemuMonitorPtr, virDomainObjPtr)
c401cc
             = mon->cb->errorNotify;
c401cc
@@ -738,9 +738,9 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
c401cc
         /* Make sure anyone waiting wakes up now */
c401cc
         virCondSignal(&mon->notify);
c401cc
         virObjectUnlock(mon);
c401cc
-        virObjectUnref(mon);
c401cc
         VIR_DEBUG("Triggering error callback");
c401cc
         (errorNotify)(mon, vm);
c401cc
+        virObjectUnref(mon);
c401cc
     } else {
c401cc
         virObjectUnlock(mon);
c401cc
         virObjectUnref(mon);
c401cc
-- 
c401cc
1.8.4.4
c401cc