[libvirt] [PATCH 2/2] avoid closing monitor twice

Daniel P. Berrange berrange at redhat.com
Wed Jan 26 10:49:28 UTC 2011


On Wed, Jan 26, 2011 at 09:46:52AM +0800, Wen Congyang wrote:
> At 01/26/2011 01:02 AM, Daniel P. Berrange Write:
> > On Tue, Jan 25, 2011 at 02:57:34PM +0800, Wen Congyang wrote:
> >> When we kill the qemu, the function qemuMonitorSetCapabilities()
> >> failed and then we close monitor.
> >>
> >> In another thread, mon->fd is broken and the function
> >> qemuHandleMonitorEOF() is called. The function qemuHandleMonitorEOF() calls
> >> qemudShutdownVMDaemon() to shutdown vm. The monitor will be
> >> closed in the function qemudShutdownVMDaemon().
> >>
> >> The monitor close twice and the reference is decreased to 0 unexpectedly.
> >> The memory will be freed when reference is decreased to 0.
> >>
> >> We will remove the watch of mon->fd when the monitor is closed. This
> >> request will be done in the function qemuMonitorUnwatch() in the qemuloop
> >> thread. In the function qemuMonitorUnwatch(), we will lock monitor, but
> >> the lock is destroyed and we will block here,
> >>
> >> In the main thread, we may add some watch or timeout, and will be blocked
> >> because the lock of eventLoop is hold by qemuLoop thread.
> >>
> >> We should close monitor only once.
> > 
> > I think the problem actually lies in the qemuConnectMonitor()
> > call. This method calls  qemuMonitorSetCapabilities() and
> > if that fails it calls qemuMonitorClose().
> > 
> > The caller of qemuConnectMonitor() will see the error
> > code and also try to kill the QEMU process, by calling
> > qemuShutdownVMDaemon(), which calls qemuMonitorClose()
> > again.
> > 
> > So I think we need to remove the call to qemuMonitorClose()
> > from qemuConnectMonitor() and just let the calls cleanup
> > up via normal VM shutdown procedure.
> 
> The function qemudWaitForMonitor() calls qemuConnectMonitor(),
> but it does not shutdown VM if qemuConnectMonitor() failed.

You need to look further up the call chain.  If the call
to qemuMonitorSetCapabilities() fails, qemuConnectMOnitor()
returns -1. If qemuConnectMonitor() returns -1, then
qemuWaitForMonitor() also returns -1. If qemuWaitForMonitor
returns -1, then qemudStartVMDaemon will call qemudShutdownVMDaemon
which kills the guest and closes the monitor.

So, by having qemuConnectMonitor() close the monitor when
SetCapabilities() fails, AFAICT, we get a double-close.

Regards,
Daniel




More information about the libvir-list mailing list