well, that was a lot of fallout. All looks necessary though. +1 from me Daniel P. Berrange wrote on 11/17/2008 11:58 AM: > As discussed previously, this patch changes the semantics of the public > API for dealing with file handle watches. Previously we would track the > watch based on the file handle number directly. With this change, the > virEventAddHandle method returns an integer 'watch' number. This watch > number is required when unregistering or updating a watch. The watch is > also passed into the callback when an event occurrs. This allows for > multiple watches to be registered against the same file descriptor. > > There was quite alot of fallout from this patch requiring many callers > to be updated to comply with the new semantics. > > examples/domain-events/events-c/event-test.c | 7 +- > examples/domain-events/events-python/event-test.py | 12 ++-- > include/libvirt/libvirt.h | 20 ++++--- > include/libvirt/libvirt.h.in | 20 ++++--- > python/libvir.c | 8 +- > qemud/event.c | 27 ++++++--- > qemud/event.h | 10 +-- > qemud/mdns.c | 16 +++-- > qemud/qemud.c | 59 +++++++++++---------- > qemud/qemud.h | 2 > src/domain_conf.h | 3 + > src/event.c | 8 +- > src/event.h | 8 +- > src/lxc_driver.c | 25 +++++--- > src/qemu_driver.c | 43 ++++++++------- > src/remote_internal.c | 27 ++++++--- > 16 files changed, 176 insertions(+), 119 deletions(-) > > > Daniel > > diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c > --- a/examples/domain-events/events-c/event-test.c > +++ b/examples/domain-events/events-c/event-test.c > @@ -40,8 +40,8 @@ int myDomainEventCallback2 (virConnectPt > int event, int detail, void *opaque); > int myEventAddHandleFunc (int fd, int event, > virEventHandleCallback cb, void *opaque); > -void myEventUpdateHandleFunc(int fd, int event); > -int myEventRemoveHandleFunc(int fd); > +void myEventUpdateHandleFunc(int watch, int event); > +int myEventRemoveHandleFunc(int watch); > > int myEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb, > void *opaque); > @@ -308,7 +308,8 @@ int main(int argc, char **argv) > } > > if(h_cb) { > - h_cb(h_fd, > + h_cb(0, > + h_fd, > myPollEventToEventHandleType(pfd.revents & h_event), > h_opaque); > } > diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py > --- a/examples/domain-events/events-python/event-test.py > +++ b/examples/domain-events/events-python/event-test.py > @@ -75,19 +75,19 @@ def myAddHandle(fd, events, cb, opaque): > > mypoll.register(fd, myEventHandleTypeToPollEvent(events)) > > -def myUpdateHandle(fd, event): > +def myUpdateHandle(watch, event): > global h_fd, h_events > #print "Updating Handle %s %s" % (str(fd), str(events)) > h_fd = fd > h_events = event > - mypoll.unregister(fd) > - mypoll.register(fd, myEventHandleTypeToPollEvent(event)) > + mypoll.unregister(watch) > + mypoll.register(watch, myEventHandleTypeToPollEvent(event)) > > -def myRemoveHandle(fd): > +def myRemoveHandle(watch): > global h_fd > #print "Removing Handle %s" % str(fd) > h_fd = 0 > - mypoll.unregister(fd) > + mypoll.unregister(watch) > > def myAddTimeout(timeout, cb, opaque): > global t_active, t_timeout, t_cb, t_opaque > @@ -175,7 +175,7 @@ def main(): > > if h_cb != None: > #print "Invoking Handle CB" > - h_cb(h_fd, myPollEventToEventHandleType(revents & h_events), > + h_cb(0, h_fd, myPollEventToEventHandleType(revents & h_events), > h_opaque[0], h_opaque[1]) > > #print "DEBUG EXIT" > diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h > --- a/include/libvirt/libvirt.h > +++ b/include/libvirt/libvirt.h > @@ -1121,13 +1121,15 @@ typedef enum { > /** > * virEventHandleCallback: > * > + * @watch: watch on which the event occurred > * @fd: file handle on which the event occurred > * @events: bitset of events from virEventHandleType constants > * @opaque: user data registered with handle > * > - * callback for receiving file handle events > + * Callback for receiving file handle events. The callback will > + * be invoked once for each event which is pending. > */ > -typedef void (*virEventHandleCallback)(int fd, int events, void *opaque); > +typedef void (*virEventHandleCallback)(int watch, int fd, int events, void *opaque); > > /** > * virEventAddHandleFunc: > @@ -1137,29 +1139,33 @@ typedef void (*virEventHandleCallback)(i > * @opaque: user data to pass to the callback > * > * Part of the EventImpl, this callback Adds a file handle callback to > - * listen for specific events > + * listen for specific events. The same file handle can be registered > + * multiple times provided the requested event sets are non-overlapping > + * > + * Returns a handle watch number to be used for updating > + * and unregistering for events > */ > typedef int (*virEventAddHandleFunc)(int fd, int event, > virEventHandleCallback cb, void *opaque); > > /** > * virEventUpdateHandleFunc: > - * @fd: file descriptor to modify > + * @watch: file descriptor watch to modify > * @event: new events to listen on > * > * Part of the EventImpl, this user-provided callback is notified when > * events to listen on change > */ > -typedef void (*virEventUpdateHandleFunc)(int fd, int event); > +typedef void (*virEventUpdateHandleFunc)(int watch, int event); > > /** > * virEventRemoveHandleFunc: > - * @fd: file descriptor to stop listening on > + * @watch: file descriptor watch to stop listening on > * > * Part of the EventImpl, this user-provided callback is notified when > * an fd is no longer being listened on > */ > -typedef int (*virEventRemoveHandleFunc)(int fd); > +typedef int (*virEventRemoveHandleFunc)(int watch); > > /** > * virEventTimeoutCallback: > diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in > --- a/include/libvirt/libvirt.h.in > +++ b/include/libvirt/libvirt.h.in > @@ -1121,13 +1121,15 @@ typedef enum { > /** > * virEventHandleCallback: > * > + * @watch: watch on which the event occurred > * @fd: file handle on which the event occurred > * @events: bitset of events from virEventHandleType constants > * @opaque: user data registered with handle > * > - * callback for receiving file handle events > + * Callback for receiving file handle events. The callback will > + * be invoked once for each event which is pending. > */ > -typedef void (*virEventHandleCallback)(int fd, int events, void *opaque); > +typedef void (*virEventHandleCallback)(int watch, int fd, int events, void *opaque); > > /** > * virEventAddHandleFunc: > @@ -1137,29 +1139,33 @@ typedef void (*virEventHandleCallback)(i > * @opaque: user data to pass to the callback > * > * Part of the EventImpl, this callback Adds a file handle callback to > - * listen for specific events > + * listen for specific events. The same file handle can be registered > + * multiple times provided the requested event sets are non-overlapping > + * > + * Returns a handle watch number to be used for updating > + * and unregistering for events > */ > typedef int (*virEventAddHandleFunc)(int fd, int event, > virEventHandleCallback cb, void *opaque); > > /** > * virEventUpdateHandleFunc: > - * @fd: file descriptor to modify > + * @watch: file descriptor watch to modify > * @event: new events to listen on > * > * Part of the EventImpl, this user-provided callback is notified when > * events to listen on change > */ > -typedef void (*virEventUpdateHandleFunc)(int fd, int event); > +typedef void (*virEventUpdateHandleFunc)(int watch, int event); > > /** > * virEventRemoveHandleFunc: > - * @fd: file descriptor to stop listening on > + * @watch: file descriptor watch to stop listening on > * > * Part of the EventImpl, this user-provided callback is notified when > * an fd is no longer being listened on > */ > -typedef int (*virEventRemoveHandleFunc)(int fd); > +typedef int (*virEventRemoveHandleFunc)(int watch); > > /** > * virEventTimeoutCallback: > diff --git a/python/libvir.c b/python/libvir.c > --- a/python/libvir.c > +++ b/python/libvir.c > @@ -1940,15 +1940,15 @@ libvirt_virEventInvokeHandleCallback(PyO > libvirt_virEventInvokeHandleCallback(PyObject *self ATTRIBUTE_UNUSED, > PyObject *args) > { > - int fd, event; > + int watch, fd, event; > PyObject *py_f; > PyObject *py_opaque; > virEventHandleCallback cb; > void *opaque; > > if (!PyArg_ParseTuple > - (args, (char *) "iiOO:virEventInvokeHandleCallback", > - &fd, &event, &py_f, &py_opaque > + (args, (char *) "iiiOO:virEventInvokeHandleCallback", > + &watch, &fd, &event, &py_f, &py_opaque > )) > return VIR_PY_INT_FAIL; > > @@ -1956,7 +1956,7 @@ libvirt_virEventInvokeHandleCallback(PyO > opaque = (void *) PyvirVoidPtr_Get(py_opaque); > > if(cb) > - cb (fd, event, opaque); > + cb (watch, fd, event, opaque); > > return VIR_PY_INT_SUCCESS; > } > diff --git a/qemud/event.c b/qemud/event.c > --- a/qemud/event.c > +++ b/qemud/event.c > @@ -37,6 +37,7 @@ > > /* State for a single file handle being monitored */ > struct virEventHandle { > + int watch; > int fd; > int events; > virEventHandleCallback cb; > @@ -71,6 +72,9 @@ struct virEventLoop { > /* Only have one event loop */ > static struct virEventLoop eventLoop; > > +/* Unique ID for the next FD watch to be registered */ > +static int nextWatch = 0; > + > /* Unique ID for the next timer to be registered */ > static int nextTimer = 0; > > @@ -91,6 +95,7 @@ int virEventAddHandleImpl(int fd, int ev > eventLoop.handlesAlloc += EVENT_ALLOC_EXTENT; > } > > + eventLoop.handles[eventLoop.handlesCount].watch = nextWatch++; > eventLoop.handles[eventLoop.handlesCount].fd = fd; > eventLoop.handles[eventLoop.handlesCount].events = > virEventHandleTypeToPollEvent(events); > @@ -100,13 +105,13 @@ int virEventAddHandleImpl(int fd, int ev > > eventLoop.handlesCount++; > > - return 0; > + return nextWatch-1; > } > > -void virEventUpdateHandleImpl(int fd, int events) { > +void virEventUpdateHandleImpl(int watch, int events) { > int i; > for (i = 0 ; i < eventLoop.handlesCount ; i++) { > - if (eventLoop.handles[i].fd == fd) { > + if (eventLoop.handles[i].watch == watch) { > eventLoop.handles[i].events = > virEventHandleTypeToPollEvent(events); > break; > @@ -120,15 +125,15 @@ void virEventUpdateHandleImpl(int fd, in > * For this reason we only ever set a flag in the existing list. > * Actual deletion will be done out-of-band > */ > -int virEventRemoveHandleImpl(int fd) { > +int virEventRemoveHandleImpl(int watch) { > int i; > - EVENT_DEBUG("Remove handle %d", fd); > + EVENT_DEBUG("Remove handle %d", watch); > for (i = 0 ; i < eventLoop.handlesCount ; i++) { > if (eventLoop.handles[i].deleted) > continue; > > - if (eventLoop.handles[i].fd == fd) { > - EVENT_DEBUG("mark delete %d", i); > + if (eventLoop.handles[i].watch == watch) { > + EVENT_DEBUG("mark delete %d %d", i, eventLoop.handles[i].fd); > eventLoop.handles[i].deleted = 1; > return 0; > } > @@ -356,9 +361,13 @@ static int virEventDispatchHandles(struc > > if (fds[i].revents) { > hEvents = virPollEventToEventHandleType(fds[i].revents); > - EVENT_DEBUG("Dispatch %d %d %p", fds[i].fd, fds[i].revents, > + EVENT_DEBUG("Dispatch %d %d %d %p", > + eventLoop.handles[i].watch, > + fds[i].fd, fds[i].revents, > eventLoop.handles[i].opaque); > - (eventLoop.handles[i].cb)(fds[i].fd, hEvents, > + (eventLoop.handles[i].cb)(eventLoop.handles[i].watch, > + fds[i].fd, > + hEvents, > eventLoop.handles[i].opaque); > } > } > diff --git a/qemud/event.h b/qemud/event.h > --- a/qemud/event.h > +++ b/qemud/event.h > @@ -24,7 +24,7 @@ > #ifndef __VIRTD_EVENT_H__ > #define __VIRTD_EVENT_H__ > > -#include "../src/event.h" > +#include "internal.h" > > /** > * virEventAddHandleImpl: register a callback for monitoring file handle events > @@ -42,21 +42,21 @@ int virEventAddHandleImpl(int fd, int ev > /** > * virEventUpdateHandleImpl: change event set for a monitored file handle > * > - * @fd: file handle to monitor for events > + * @watch: watch whose handle to update > * @events: bitset of events to watch from POLLnnn constants > * > * Will not fail if fd exists > */ > -void virEventUpdateHandleImpl(int fd, int events); > +void virEventUpdateHandleImpl(int watch, int events); > > /** > * virEventRemoveHandleImpl: unregister a callback from a file handle > * > - * @fd: file handle to stop monitoring for events > + * @watch: watch whose handle to remove > * > * returns -1 if the file handle was not registered, 0 upon success > */ > -int virEventRemoveHandleImpl(int fd); > +int virEventRemoveHandleImpl(int watch); > > /** > * virEventAddTimeoutImpl: register a callback for a timer event > diff --git a/qemud/mdns.c b/qemud/mdns.c > --- a/qemud/mdns.c > +++ b/qemud/mdns.c > @@ -68,6 +68,7 @@ struct libvirtd_mdns { > > /* Avahi API requires this struct names in the app :-( */ > struct AvahiWatch { > + int watch; > int fd; > int revents; > AvahiWatchCallback callback; > @@ -228,17 +229,18 @@ static void libvirtd_mdns_client_callbac > } > > > -static void libvirtd_mdns_watch_dispatch(int fd, int events, void *opaque) > +static void libvirtd_mdns_watch_dispatch(int watch, int fd, int events, void *opaque) > { > AvahiWatch *w = (AvahiWatch*)opaque; > int fd_events = virEventHandleTypeToPollEvent(events); > - AVAHI_DEBUG("Dispatch watch FD %d Event %d", fd, fd_events); > + AVAHI_DEBUG("Dispatch watch %d FD %d Event %d", watch, fd, fd_events); > w->revents = fd_events; > w->callback(w, fd, fd_events, w->userdata); > } > > static AvahiWatch *libvirtd_mdns_watch_new(const AvahiPoll *api ATTRIBUTE_UNUSED, > - int fd, AvahiWatchEvent event, AvahiWatchCallback cb, void *userdata) { > + int fd, AvahiWatchEvent event, > + AvahiWatchCallback cb, void *userdata) { > AvahiWatch *w; > virEventHandleType hEvents; > if (VIR_ALLOC(w) < 0) > @@ -251,8 +253,8 @@ static AvahiWatch *libvirtd_mdns_watch_n > > AVAHI_DEBUG("New handle %p FD %d Event %d", w, w->fd, event); > hEvents = virPollEventToEventHandleType(event); > - if (virEventAddHandleImpl(fd, hEvents, > - libvirtd_mdns_watch_dispatch, w) < 0) { > + if ((w->watch = virEventAddHandleImpl(fd, hEvents, > + libvirtd_mdns_watch_dispatch, w)) < 0) { > VIR_FREE(w); > return NULL; > } > @@ -263,7 +265,7 @@ static void libvirtd_mdns_watch_update(A > static void libvirtd_mdns_watch_update(AvahiWatch *w, AvahiWatchEvent event) > { > AVAHI_DEBUG("Update handle %p FD %d Event %d", w, w->fd, event); > - virEventUpdateHandleImpl(w->fd, event); > + virEventUpdateHandleImpl(w->watch, event); > } > > static AvahiWatchEvent libvirtd_mdns_watch_get_events(AvahiWatch *w) > @@ -275,7 +277,7 @@ static void libvirtd_mdns_watch_free(Ava > static void libvirtd_mdns_watch_free(AvahiWatch *w) > { > AVAHI_DEBUG("Free handle %p %d", w, w->fd); > - virEventRemoveHandleImpl(w->fd); > + virEventRemoveHandleImpl(w->watch); > VIR_FREE(w); > } > > diff --git a/qemud/qemud.c b/qemud/qemud.c > --- a/qemud/qemud.c > +++ b/qemud/qemud.c > @@ -142,8 +142,8 @@ static void sig_handler(int sig, siginfo > errno = origerrno; > } > > -static void qemudDispatchClientEvent(int fd, int events, void *opaque); > -static void qemudDispatchServerEvent(int fd, int events, void *opaque); > +static void qemudDispatchClientEvent(int watch, int fd, int events, void *opaque); > +static void qemudDispatchServerEvent(int watch, int fd, int events, void *opaque); > static int qemudRegisterClientEvent(struct qemud_server *server, > struct qemud_client *client, > int removeFirst); > @@ -245,7 +245,8 @@ remoteInitializeGnuTLS (void) > } > > static void > -qemudDispatchSignalEvent(int fd ATTRIBUTE_UNUSED, > +qemudDispatchSignalEvent(int watch ATTRIBUTE_UNUSED, > + int fd ATTRIBUTE_UNUSED, > int events ATTRIBUTE_UNUSED, > void *opaque) { > struct qemud_server *server = (struct qemud_server *)opaque; > @@ -534,12 +535,12 @@ static int qemudListenUnix(struct qemud_ > goto cleanup; > } > > - if (virEventAddHandleImpl(sock->fd, > - VIR_EVENT_HANDLE_READABLE | > - VIR_EVENT_HANDLE_ERROR | > - VIR_EVENT_HANDLE_HANGUP, > - qemudDispatchServerEvent, > - server) < 0) { > + if ((sock->watch = virEventAddHandleImpl(sock->fd, > + VIR_EVENT_HANDLE_READABLE | > + VIR_EVENT_HANDLE_ERROR | > + VIR_EVENT_HANDLE_HANGUP, > + qemudDispatchServerEvent, > + server)) < 0) { > qemudLog(QEMUD_ERR, "%s", > _("Failed to add server event callback")); > goto cleanup; > @@ -666,12 +667,12 @@ remoteListenTCP (struct qemud_server *se > goto cleanup; > } > > - if (virEventAddHandleImpl(sock->fd, > - VIR_EVENT_HANDLE_READABLE | > - VIR_EVENT_HANDLE_ERROR | > - VIR_EVENT_HANDLE_HANGUP, > - qemudDispatchServerEvent, > - server) < 0) { > + if ((sock->watch = virEventAddHandleImpl(sock->fd, > + VIR_EVENT_HANDLE_READABLE | > + VIR_EVENT_HANDLE_ERROR | > + VIR_EVENT_HANDLE_HANGUP, > + qemudDispatchServerEvent, > + server)) < 0) { > qemudLog(QEMUD_ERR, "%s", _("Failed to add server event callback")); > goto cleanup; > } > @@ -1232,7 +1233,7 @@ static void qemudDispatchClientFailure(s > tmp = tmp->next; > } > > - virEventRemoveHandleImpl(client->fd); > + virEventRemoveHandleImpl(client->watch); > > /* Deregister event delivery callback */ > if(client->conn) { > @@ -1596,18 +1597,21 @@ qemudDispatchClientWrite(struct qemud_se > > > static void > -qemudDispatchClientEvent(int fd, int events, void *opaque) { > +qemudDispatchClientEvent(int watch, int fd, int events, void *opaque) { > struct qemud_server *server = (struct qemud_server *)opaque; > struct qemud_client *client = server->clients; > > while (client) { > - if (client->fd == fd) > + if (client->watch == watch) > break; > > client = client->next; > } > > if (!client) > + return; > + > + if (client->fd != fd) > return; > > if (events == VIR_EVENT_HANDLE_WRITABLE) > @@ -1644,32 +1648,35 @@ static int qemudRegisterClientEvent(stru > } > > if (removeFirst) > - if (virEventRemoveHandleImpl(client->fd) < 0) > + if (virEventRemoveHandleImpl(client->watch) < 0) > return -1; > > - if (virEventAddHandleImpl(client->fd, > - mode | VIR_EVENT_HANDLE_ERROR | > - VIR_EVENT_HANDLE_HANGUP, > - qemudDispatchClientEvent, > - server) < 0) > + if ((client->watch = virEventAddHandleImpl(client->fd, > + mode | VIR_EVENT_HANDLE_ERROR | > + VIR_EVENT_HANDLE_HANGUP, > + qemudDispatchClientEvent, > + server)) < 0) > return -1; > > return 0; > } > > static void > -qemudDispatchServerEvent(int fd, int events, void *opaque) { > +qemudDispatchServerEvent(int watch, int fd, int events, void *opaque) { > struct qemud_server *server = (struct qemud_server *)opaque; > struct qemud_socket *sock = server->sockets; > > while (sock) { > - if (sock->fd == fd) > + if (sock->watch == watch) > break; > > sock = sock->next; > } > > if (!sock) > + return; > + > + if (sock->fd != fd) > return; > > if (events) > diff --git a/qemud/qemud.h b/qemud/qemud.h > --- a/qemud/qemud.h > +++ b/qemud/qemud.h > @@ -96,6 +96,7 @@ struct qemud_client { > int magic; > > int fd; > + int watch; > int readonly; > enum qemud_mode mode; > > @@ -141,6 +142,7 @@ struct qemud_client { > > struct qemud_socket { > int fd; > + int watch; > int readonly; > int type; /* qemud_sock_type */ > int auth; > diff --git a/src/domain_conf.h b/src/domain_conf.h > --- a/src/domain_conf.h > +++ b/src/domain_conf.h > @@ -455,8 +455,11 @@ struct _virDomainObj { > struct _virDomainObj { > int stdin_fd; > int stdout_fd; > + int stdout_watch; > int stderr_fd; > + int stderr_watch; > int monitor; > + int monitorWatch; > int logfile; > int pid; > int state; > diff --git a/src/event.c b/src/event.c > --- a/src/event.c > +++ b/src/event.c > @@ -42,15 +42,15 @@ int virEventAddHandle(int fd, int events > return addHandleImpl(fd, events, cb, opaque); > } > > -void virEventUpdateHandle(int fd, int events) { > - updateHandleImpl(fd, events); > +void virEventUpdateHandle(int watch, int events) { > + updateHandleImpl(watch, events); > } > > -int virEventRemoveHandle(int fd) { > +int virEventRemoveHandle(int watch) { > if (!removeHandleImpl) > return -1; > > - return removeHandleImpl(fd); > + return removeHandleImpl(watch); > } > > int virEventAddTimeout(int timeout, virEventTimeoutCallback cb, void *opaque) { > diff --git a/src/event.h b/src/event.h > --- a/src/event.h > +++ b/src/event.h > @@ -40,21 +40,21 @@ int virEventAddHandle(int fd, int events > /** > * virEventUpdateHandle: change event set for a monitored file handle > * > - * @fd: file handle to monitor for events > + * @watch: watch whose file handle to update > * @events: bitset of events to watch from virEventHandleType constants > * > * Will not fail if fd exists > */ > -void virEventUpdateHandle(int fd, int events); > +void virEventUpdateHandle(int watch, int events); > > /** > * virEventRemoveHandle: unregister a callback from a file handle > * > - * @fd: file handle to stop monitoring for events > + * @watch: watch whose file handle to remove > * > * returns -1 if the file handle was not registered, 0 upon success > */ > -int virEventRemoveHandle(int fd); > +int virEventRemoveHandle(int watch); > > /** > * virEventAddTimeout: register a callback for a timer event > diff --git a/src/lxc_driver.c b/src/lxc_driver.c > --- a/src/lxc_driver.c > +++ b/src/lxc_driver.c > @@ -387,7 +387,7 @@ static int lxcVMCleanup(virConnectPtr co > DEBUG("container exited with rc: %d", rc); > } > > - virEventRemoveHandle(vm->monitor); > + virEventRemoveHandle(vm->monitorWatch); > close(vm->monitor); > > virFileDeletePid(driver->stateDir, vm->def->name); > @@ -582,7 +582,8 @@ static int lxcVmTerminate(virConnectPtr > return lxcVMCleanup(conn, driver, vm); > } > > -static void lxcMonitorEvent(int fd, > +static void lxcMonitorEvent(int watch, > + int fd, > int events ATTRIBUTE_UNUSED, > void *data) > { > @@ -591,18 +592,23 @@ static void lxcMonitorEvent(int fd, > unsigned int i; > > for (i = 0 ; i < driver->domains.count ; i++) { > - if (driver->domains.objs[i]->monitor == fd) { > + if (driver->domains.objs[i]->monitorWatch == watch) { > vm = driver->domains.objs[i]; > break; > } > } > if (!vm) { > - virEventRemoveHandle(fd); > + virEventRemoveHandle(watch); > + return; > + } > + > + if (vm->monitor != fd) { > + virEventRemoveHandle(watch); > return; > } > > if (lxcVmTerminate(NULL, driver, vm, SIGINT) < 0) > - virEventRemoveHandle(fd); > + virEventRemoveHandle(watch); > } > > > @@ -810,10 +816,11 @@ static int lxcVmStart(virConnectPtr conn > vm->def->id = vm->pid; > vm->state = VIR_DOMAIN_RUNNING; > > - if (virEventAddHandle(vm->monitor, > - VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP, > - lxcMonitorEvent, > - driver) < 0) { > + if ((vm->monitorWatch = virEventAddHandle( > + vm->monitor, > + VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP, > + lxcMonitorEvent, > + driver)) < 0) { > lxcVmTerminate(conn, driver, vm, 0); > goto cleanup; > } > diff --git a/src/qemu_driver.c b/src/qemu_driver.c > --- a/src/qemu_driver.c > +++ b/src/qemu_driver.c > @@ -110,7 +110,8 @@ static void qemudDomainEventDispatch (st > int event, > int detail); > > -static void qemudDispatchVMEvent(int fd, > +static void qemudDispatchVMEvent(int watch, > + int fd, > int events, > void *opaque); > > @@ -946,18 +947,18 @@ static int qemudStartVMDaemon(virConnect > } > > if (ret == 0) { > - if ((virEventAddHandle(vm->stdout_fd, > - VIR_EVENT_HANDLE_READABLE | > - VIR_EVENT_HANDLE_ERROR | > - VIR_EVENT_HANDLE_HANGUP, > - qemudDispatchVMEvent, > - driver) < 0) || > - (virEventAddHandle(vm->stderr_fd, > - VIR_EVENT_HANDLE_READABLE | > - VIR_EVENT_HANDLE_ERROR | > - VIR_EVENT_HANDLE_HANGUP, > - qemudDispatchVMEvent, > - driver) < 0) || > + if (((vm->stdout_watch = virEventAddHandle(vm->stdout_fd, > + VIR_EVENT_HANDLE_READABLE | > + VIR_EVENT_HANDLE_ERROR | > + VIR_EVENT_HANDLE_HANGUP, > + qemudDispatchVMEvent, > + driver)) < 0) || > + ((vm->stderr_watch = virEventAddHandle(vm->stderr_fd, > + VIR_EVENT_HANDLE_READABLE | > + VIR_EVENT_HANDLE_ERROR | > + VIR_EVENT_HANDLE_HANGUP, > + qemudDispatchVMEvent, > + driver)) < 0) || > (qemudWaitForMonitor(conn, driver, vm) < 0) || > (qemudDetectVcpuPIDs(conn, driver, vm) < 0) || > (qemudInitCpus(conn, driver, vm, migrateFrom) < 0)) { > @@ -1008,8 +1009,8 @@ static void qemudShutdownVMDaemon(virCon > qemudVMData(driver, vm, vm->stdout_fd); > qemudVMData(driver, vm, vm->stderr_fd); > > - virEventRemoveHandle(vm->stdout_fd); > - virEventRemoveHandle(vm->stderr_fd); > + virEventRemoveHandle(vm->stdout_watch); > + virEventRemoveHandle(vm->stderr_watch); > > if (close(vm->logfile) < 0) > qemudLog(QEMUD_WARN, _("Unable to close logfile %d: %s\n"), > @@ -1072,15 +1073,15 @@ static int qemudDispatchVMFailure(struct > > > static void > -qemudDispatchVMEvent(int fd, int events, void *opaque) { > +qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) { > struct qemud_driver *driver = (struct qemud_driver *)opaque; > virDomainObjPtr vm = NULL; > unsigned int i; > > for (i = 0 ; i < driver->domains.count ; i++) { > if (virDomainIsActive(driver->domains.objs[i]) && > - (driver->domains.objs[i]->stdout_fd == fd || > - driver->domains.objs[i]->stderr_fd == fd)) { > + (driver->domains.objs[i]->stdout_watch == watch || > + driver->domains.objs[i]->stderr_watch == watch)) { > vm = driver->domains.objs[i]; > break; > } > @@ -1088,6 +1089,12 @@ qemudDispatchVMEvent(int fd, int events, > > if (!vm) > return; > + > + if (vm->stdout_fd != fd && > + vm->stderr_fd != fd) { > + qemudDispatchVMFailure(driver, vm, fd); > + return; > + } > > if (events == VIR_EVENT_HANDLE_READABLE) > qemudDispatchVMLog(driver, vm, fd); > diff --git a/src/remote_internal.c b/src/remote_internal.c > --- a/src/remote_internal.c > +++ b/src/remote_internal.c > @@ -95,6 +95,7 @@ struct private_data { > struct private_data { > int magic; /* Should be MAGIC or DEAD. */ > int sock; /* Socket. */ > + int watch; /* File handle watch */ > pid_t pid; /* PID of tunnel process */ > int uses_tls; /* TLS enabled on socket? */ > gnutls_session_t session; /* GnuTLS session (if uses_tls != 0). */ > @@ -175,7 +176,7 @@ static void make_nonnull_network (remote > static void make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src); > static void make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr vol_src); > static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src); > -void remoteDomainEventFired(int fd, int event, void *data); > +void remoteDomainEventFired(int watch, int fd, int event, void *data); > static void remoteDomainProcessEvent(virConnectPtr conn, XDR *xdr); > static void remoteDomainQueueEvent(virConnectPtr conn, XDR *xdr); > void remoteDomainEventQueueFlush(int timer, void *opaque); > @@ -756,12 +757,12 @@ doRemoteOpen (virConnectPtr conn, > > DEBUG0("Adding Handler for remote events"); > /* Set up a callback to listen on the socket data */ > - if (virEventAddHandle(priv->sock, > - VIR_EVENT_HANDLE_READABLE | > - VIR_EVENT_HANDLE_ERROR | > - VIR_EVENT_HANDLE_HANGUP, > - remoteDomainEventFired, > - conn) < 0) { > + if ((priv->watch = virEventAddHandle(priv->sock, > + VIR_EVENT_HANDLE_READABLE | > + VIR_EVENT_HANDLE_ERROR | > + VIR_EVENT_HANDLE_HANGUP, > + remoteDomainEventFired, > + conn)) < 0) { > DEBUG0("virEventAddHandle failed: No addHandleImpl defined." > " continuing without events."); > } else { > @@ -5265,7 +5266,8 @@ remoteDomainQueueEvent(virConnectPtr con > * for event data > */ > void > -remoteDomainEventFired(int fd ATTRIBUTE_UNUSED, > +remoteDomainEventFired(int watch, > + int fd, > int event, > void *opaque) > { > @@ -5278,13 +5280,18 @@ remoteDomainEventFired(int fd ATTRIBUTE_ > virConnectPtr conn = opaque; > struct private_data *priv = conn->privateData; > > - DEBUG("%s : Event fired %d %X", __FUNCTION__, event, event); > + DEBUG("Event fired %d %d %d %X", watch, fd, event, event); > > if (event & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR)) { > DEBUG("%s : VIR_EVENT_HANDLE_HANGUP or " > "VIR_EVENT_HANDLE_ERROR encountered", __FUNCTION__); > - virEventRemoveHandle(fd); > + virEventRemoveHandle(watch); > return; > + } > + > + if (fd != priv->sock) { > + virEventRemoveHandle(watch); > + return; > } > > /* Read and deserialise length word. */ > -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list