}
+int
+qemuDomainObjStartWorker(virDomainObjPtr dom)
+{
+ qemuDomainObjPrivatePtr priv = dom->privateData;
+
+ if (!priv->eventThread) {
+ g_autofree char *threadName = g_strdup_printf("vm-%s", dom->def->name);
+ if (!(priv->eventThread = virEventThreadNew(threadName)))
+ return -1;
+ }
+
+ return 0;
+}
+
+
+void
+qemuDomainObjStopWorker(virDomainObjPtr dom)
+{
+ qemuDomainObjPrivatePtr priv = dom->privateData;
+
+ if (priv->eventThread) {
+ g_object_unref(priv->eventThread);
+ priv->eventThread = NULL;
+ }
+}
+
+
static void *
qemuDomainObjPrivateAlloc(void *opaque)
{
virHashFree(priv->blockjobs);
virHashFree(priv->dbusVMStates);
+ /* This should never be non-NULL if we get here, but just in case... */
+ if (priv->eventThread) {
+ VIR_ERROR(_("Unexpected event thread still active during domain deletion"));
+ g_object_unref(priv->eventThread);
+ }
+
VIR_FREE(priv);
}
#include "logging/log_manager.h"
#include "virdomainmomentobjlist.h"
#include "virenum.h"
+#include "vireventthread.h"
#define QEMU_DOMAIN_FORMAT_LIVE_FLAGS \
(VIR_DOMAIN_XML_SECURE)
virBitmapPtr namespaces;
+ virEventThread *eventThread;
+
qemuMonitorPtr mon;
virDomainChrSourceDefPtr monConfig;
bool monError;
char **capsdel;
};
+int qemuDomainObjStartWorker(virDomainObjPtr dom);
+void qemuDomainObjStopWorker(virDomainObjPtr dom);
+
virDomainObjPtr qemuDomainObjFromDomain(virDomainPtr domain);
qemuDomainSaveCookiePtr qemuDomainSaveCookieNew(virDomainObjPtr vm);
qemuDomainDestroyNamespace(driver, vm);
cleanup:
+ /* Now we got EOF we're not expecting more I/O, so we
+ * can finally kill the event thread */
+ qemuDomainObjStopWorker(vm);
virObjectUnlock(vm);
}
if (rv == -1) /* The VM failed to start */
goto cleanup;
+ if (qemuDomainObjStartWorker(vm) < 0)
+ goto cleanup;
+
VIR_DEBUG("Waiting for monitor to show up");
if (qemuProcessWaitForMonitor(driver, vm, asyncJob, logCtxt) < 0)
goto cleanup;
priv->monConfig = NULL;
}
+ /*
+ * We cannot stop the event thread at this time. When
+ * we are in this code, we may not yet have processed the
+ * STOP event or EOF from the monitor. So the event loop
+ * may have pending input that we need to process still.
+ * The qemuProcessHandleMonitorEOF method will kill
+ * the event thread because at that point we don't
+ * expect any more I/O from the QEMU monitor. We are
+ * assuming we don't need to get any more events from the
+ * QEMU agent at that time.
+ */
+
/* Remove the master key */
qemuDomainMasterKeyRemove(priv);
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CHARDEV_FD_PASS))
retry = false;
+ if (qemuDomainObjStartWorker(obj) < 0)
+ goto error;
+
VIR_DEBUG("Reconnect monitor to def=%p name='%s' retry=%d",
obj, obj->def->name, retry);