diff --git a/ChangeLog b/ChangeLog index 13a854d4dc..ed86cafea7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Tue Feb 10 11:14:07 GMT 2009 Daniel P. Berrange + + Fix I/O errors in libvirtd daemon, and hang/crash in remote + client upon I/O error. + * qemud/event.c: Treat POLLNVAL as VIR_EVENT_HANDLE_ERROR + * src/domain_conf.c: Initialize monitor FD to -1 + * src/remote_internal.c: Remove call object from waitDispatch + queue upon I/O failure, since call is about to free it. + Mon Feb 16 17:59:04 EST 2009 Cole Robinson * src/virsh.c, src/Makefile.am: Don't pass flags to DumpXML diff --git a/qemud/event.c b/qemud/event.c index 550d28c07e..c9ea5638d5 100644 --- a/qemud/event.c +++ b/qemud/event.c @@ -657,6 +657,8 @@ virPollEventToEventHandleType(int events) ret |= VIR_EVENT_HANDLE_WRITABLE; if(events & POLLERR) ret |= VIR_EVENT_HANDLE_ERROR; + if(events & POLLNVAL) /* Treat NVAL as error, since libvirt doesn't distinguish */ + ret |= VIR_EVENT_HANDLE_ERROR; if(events & POLLHUP) ret |= VIR_EVENT_HANDLE_HANGUP; return ret; diff --git a/src/domain_conf.c b/src/domain_conf.c index e46bf43b28..622665c4c4 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -504,6 +504,7 @@ virDomainObjPtr virDomainAssignDef(virConnectPtr conn, domain->state = VIR_DOMAIN_SHUTOFF; domain->def = def; domain->monitor_watch = -1; + domain->monitor = -1; if (VIR_REALLOC_N(doms->objs, doms->count + 1) < 0) { virReportOOMError(conn); diff --git a/src/remote_internal.c b/src/remote_internal.c index a14822ae48..eda6177808 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -6192,17 +6192,17 @@ processCalls(virConnectPtr conn, continue; virReportSystemError(in_open ? NULL : conn, errno, "%s", _("poll on socket failed")); - return -1; + goto error; } if (fds[0].revents & POLLOUT) { if (processCallSend(conn, priv, in_open) < 0) - return -1; + goto error; } if (fds[0].revents & POLLIN) { if (processCallRecv(conn, priv, in_open) < 0) - return -1; + goto error; } /* Iterate through waiting threads and if @@ -6253,9 +6253,21 @@ processCalls(virConnectPtr conn, if (fds[0].revents & (POLLHUP | POLLERR)) { errorf(in_open ? NULL : conn, VIR_ERR_INTERNAL_ERROR, "%s", _("received hangup / error event on socket")); - return -1; + goto error; } } + + +error: + priv->waitDispatch = thiscall->next; + DEBUG("Giving up the buck due to I/O error %d %p %p", thiscall->proc_nr, thiscall, priv->waitDispatch); + /* See if someone else is still waiting + * and if so, then pass the buck ! */ + if (priv->waitDispatch) { + DEBUG("Passing the buck to %d %p", priv->waitDispatch->proc_nr, priv->waitDispatch); + virCondSignal(&priv->waitDispatch->cond); + } + return -1; } /*