int watch;
bool connectPending;
+ bool running;
virDomainObjPtr vm;
goto cleanup;
}
+ mon->running = true;
VIR_DEBUG("New mon %p fd =%d watch=%d", mon, mon->fd, mon->watch);
return mon;
}
+static void
+qemuAgentNotifyCloseLocked(qemuAgentPtr mon)
+{
+ if (mon) {
+ mon->running = false;
+
+ /* If there is somebody waiting for a message
+ * wake him up. No message will arrive anyway. */
+ if (mon->msg && !mon->msg->finished) {
+ mon->msg->finished = 1;
+ virCondSignal(&mon->notify);
+ }
+ }
+}
+
+
+void
+qemuAgentNotifyClose(qemuAgentPtr mon)
+{
+ if (!mon)
+ return;
+
+ VIR_DEBUG("mon=%p", mon);
+
+ virObjectLock(mon);
+ qemuAgentNotifyCloseLocked(mon);
+ virObjectUnlock(mon);
+}
+
+
void qemuAgentClose(qemuAgentPtr mon)
{
if (!mon)
VIR_FORCE_CLOSE(mon->fd);
}
- /* If there is somebody waiting for a message
- * wake him up. No message will arrive anyway. */
- if (mon->msg && !mon->msg->finished) {
- mon->msg->finished = 1;
- virCondSignal(&mon->notify);
- }
+ qemuAgentNotifyCloseLocked(mon);
virObjectUnlock(mon);
virObjectUnref(mon);
*reply = NULL;
+ if (!mon->running) {
+ virReportError(VIR_ERR_AGENT_UNRESPONSIVE, "%s",
+ _("Guest agent disappeared while executing command"));
+ return -1;
+ }
+
if (qemuAgentGuestSync(mon) < 0)
return -1;
if (await_event && !needReply) {
VIR_DEBUG("Woken up by event %d", await_event);
} else {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Missing monitor reply object"));
+ if (mon->running)
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Missing monitor reply object"));
+ else
+ virReportError(VIR_ERR_AGENT_UNRESPONSIVE, "%s",
+ _("Guest agent disappeared while executing command"));
ret = -1;
}
} else {
VIR_DEBUG("Changing serial port state %s in domain %p %s",
devAlias, vm, vm->def->name);
+ if (newstate == VIR_DOMAIN_CHR_DEVICE_STATE_DISCONNECTED &&
+ virDomainObjIsActive(vm) && priv->agent) {
+ /* Close agent monitor early, so that other threads
+ * waiting for the agent to reply can finish and our
+ * job we acquire below can succeed. */
+ qemuAgentNotifyClose(priv->agent);
+ }
+
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;