• M
    qemu: Fix @vm locking issue when connecting to the monitor · 75dd5958
    Michal Privoznik 提交于
    When connecting to qemu's monitor the @vm object is unlocked.
    This is justified - connecting may take a long time and we don't
    want to wait with the domain object locked. However, just before
    the domain object is locked again, the monitor's FD is registered
    in the event loop. Therefore, there is a small window where the
    event loop has a chance to call a handler for an event that
    occurred on the monitor FD but vm is not initalized properly just
    yet (i.e. priv->mon is not set). For instance, if there's an
    incoming migration, qemu creates its socket but then fails to
    initialize (for various reasons, I'm reproducing this by using
    hugepages but leaving the HP pool empty) then the following may
    happen:
    
    1) qemuConnectMonitor() unlocks @vm
    
    2) qemuMonitorOpen() connects to the monitor socket and by
       calling qemuMonitorOpenInternal() which subsequently calls
       qemuMonitorRegister() the event handler is installed
    
    3) qemu fails to initialize and exit()-s, which closes the
       monitor
    
    4) The even loop sees EOF on the monitor and the control gets to
       qemuProcessEventHandler() which locks @vm and calls
       processMonitorEOFEvent() which then calls
       qemuMonitorLastError(priv->mon). But priv->mon is not set just
       yet.
    
    5) qemuMonitorLastError() dereferences NULL pointer
    
    The solution is to unlock the domain object for a shorter time
    and most importantly, register event handler with domain object
    locked so that any possible event processing is done only after
    @vm's private data was properly initialized.
    
    This issue is also mentioned in v4.2.0-99-ga5a777a8.
    
    Since we are unlocking @vm and locking it back, another thread
    might have destroyed the domain meanwhile. Therefore we have to
    check if domain is still active, and we have to do it at the
    same place where domain lock is acquired back, i.e. in
    qemuMonitorOpen(). This creates a small problem for our test
    suite which calls qemuMonitorOpen() directly and passes @vm which
    has no definition. This makes virDomainObjIsActive() call crash.
    Fortunately, allocating empty domain definition is sufficient.
    Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
    Reviewed-by: NDaniel Henrique Barboza <danielhb413@gmail.com>
    75dd5958
qemumonitortestutils.c 38.9 KB