]> xenbits.xensource.com Git - libvirt.git/commitdiff
Change public API for virEventAddHandle to allow multiple registrations per FD
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 19 Nov 2008 16:19:36 +0000 (16:19 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 19 Nov 2008 16:19:36 +0000 (16:19 +0000)
17 files changed:
ChangeLog
examples/domain-events/events-c/event-test.c
examples/domain-events/events-python/event-test.py
include/libvirt/libvirt.h
include/libvirt/libvirt.h.in
python/libvir.c
qemud/event.c
qemud/event.h
qemud/mdns.c
qemud/qemud.c
qemud/qemud.h
src/domain_conf.h
src/event.c
src/event.h
src/lxc_driver.c
src/qemu_driver.c
src/remote_internal.c

index c8cff8cdc0672799cc497b0e9c9e91e87304013d..c589c38fcbbab1267707adc137f4d399353b2c07 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Wed Nov 19 16:15:00 GMT 2008 Daniel Berrange <berrange@redhat.com>
+
+       * include/libvirt/libvirt.h.in: Change semantics of AddHandle
+       to allow for same FD to be registered more than once with
+       varying flags.
+       * qemud/event.c, qemud/event.h, qemud/mdns.c, qemud/qemud.c,
+       qemud/qemud.h, src/domain_conf.h, src/event.c, src/event.h,
+       src/lxc_driver.c, src/qemu_driver.c, src/remote_internal.c:
+       Update to track file handle events via the watch number
+       as per new public API contract
+
 Wed Nov 19 15:25:00 GMT 2008 Daniel Berrange <berrange@redhat.com>
 
        Add a callback for freeing the user data for callbacks
index 11d62c7cdc4aba393039dfb52d02997105471336..df463cf2cd16cda6df8ac59558b9de33aa411d07 100644 (file)
@@ -42,8 +42,8 @@ int myDomainEventCallback2 (virConnectPtr conn, virDomainPtr dom,
                             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);
@@ -334,7 +334,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);
         }
index d78ff60b05081ae7d333d2fe01dc743d635831d0..45aaa93d877fd04ed46ae0d8c00d383b95afe9d3 100644 (file)
@@ -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"
index c1970ab6d91b67f4b319a1ec1b9fcfb9b639a8c4..af2ee2cfd5d9899d68a453c5b1d598b457661e1f 100644 (file)
@@ -1124,13 +1124,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:
@@ -1140,29 +1142,33 @@ typedef void (*virEventHandleCallback)(int fd, int events, void *opaque);
  * @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:
index d3e351d2aa8b419e9411a6deeadd17a225884aca..08712d03b70364261cad87c71381499a57a4f0b8 100644 (file)
@@ -1124,13 +1124,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:
@@ -1140,29 +1142,33 @@ typedef void (*virEventHandleCallback)(int fd, int events, void *opaque);
  * @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:
index 3888af5b4e7723d8d917a2da10f5f6f3937b0210..8fb9d60d931d3f8ad6898949c1190c7e742fde76 100644 (file)
@@ -1940,15 +1940,15 @@ static PyObject *
 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(PyObject *self ATTRIBUTE_UNUSED,
     opaque = (void *) PyvirVoidPtr_Get(py_opaque);
 
     if(cb)
-        cb (fd, event, opaque);
+        cb (watch, fd, event, opaque);
 
     return VIR_PY_INT_SUCCESS;
 }
index 9b4dee71bf2920a92aacaf58908ae1c70d4b215f..3054064a943f8e58200235296368d4453b401bdf 100644 (file)
@@ -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 events, virEventHandleCallback cb,
         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 events, virEventHandleCallback cb,
 
     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, int events) {
  * 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(struct pollfd *fds) {
 
         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);
         }
     }
index c359089b55e4584ae7140f821b4e3de6ab29a0f6..3bad23238098494b5ffc8ae99fe04dd1d8a69715 100644 (file)
@@ -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 events, virEventHandleCallback cb,
 /**
  * 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
index 06eb9f0d24eb046d3a17dd88d2804c6c8a5a13c2..2e7480897195fba639310b3b6456e16f4002a977 100644 (file)
@@ -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_callback(AvahiClient *c, AvahiClientState state
 }
 
 
-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_new(const AvahiPoll *api ATTRIBUTE_UNUSED
 
     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 AvahiWatch *libvirtd_mdns_watch_new(const AvahiPoll *api ATTRIBUTE_UNUSED
 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 AvahiWatchEvent libvirtd_mdns_watch_get_events(AvahiWatch *w)
 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);
 }
 
index a247dce792e7556ed3c2e7b60a9f0bde46713479..c3ef35cdbc21f3622c5901159646fe4c974061d1 100644 (file)
@@ -142,8 +142,8 @@ static void sig_handler(int sig, siginfo_t * 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_server *server,
         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 *server,
             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(struct qemud_server *server, struct qemud
         tmp = tmp->next;
     }
 
-    virEventRemoveHandleImpl(client->fd);
+    virEventRemoveHandleImpl(client->watch);
 
     /* Deregister event delivery callback */
     if(client->conn) {
@@ -1596,12 +1597,12 @@ qemudDispatchClientWrite(struct qemud_server *server,
 
 
 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;
@@ -1610,6 +1611,9 @@ qemudDispatchClientEvent(int fd, int events, void *opaque) {
     if (!client)
         return;
 
+    if (client->fd != fd)
+        return;
+
     if (events == VIR_EVENT_HANDLE_WRITABLE)
         qemudDispatchClientWrite(server, client);
     else if (events == VIR_EVENT_HANDLE_READABLE)
@@ -1644,26 +1648,26 @@ static int qemudRegisterClientEvent(struct qemud_server *server,
     }
 
     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;
@@ -1672,6 +1676,9 @@ qemudDispatchServerEvent(int fd, int events, void *opaque) {
     if (!sock)
         return;
 
+    if (sock->fd != fd)
+        return;
+
     if (events)
         qemudDispatchServer(server, sock);
 }
index 700d2ee0465a548edd845140d301b96f91e18fe1..ef5379184cd9ebe59f5a1b15f897699171eb09d5 100644 (file)
@@ -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;
index 448723f6225531dd7a5ef4a345e70ab5ba73bc61..88fd6d5da96beb944d5cbf3ec4d6ee34742ea48a 100644 (file)
@@ -455,8 +455,11 @@ typedef virDomainObj *virDomainObjPtr;
 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;
index ac6f886264870f88cd86bc3f37a0e1df13f241b4..b0ee8b669defce5ec33616d74a6a11564664c676 100644 (file)
@@ -42,15 +42,15 @@ int virEventAddHandle(int fd, int events, virEventHandleCallback cb,
     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) {
index f5403842594139e2d741621ea78d934909e0fb0b..fc804c2a79073c5eedce26eaf5c763bd7f633ab2 100644 (file)
@@ -40,21 +40,21 @@ int virEventAddHandle(int fd, int events, virEventHandleCallback cb,
 /**
  * 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
index e8aa018b7c15e7ca13e579503df656e21e1eb3a2..ec206b715c448f37d946d2e4167f79a909839819 100644 (file)
@@ -387,7 +387,7 @@ static int lxcVMCleanup(virConnectPtr conn,
         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 conn,
     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;
     }
index 641690e6be80b644abed236c59f31825a6a164d1..d43119040b11a73eda80ad4a42d43e696e6014e8 100644 (file)
@@ -110,7 +110,8 @@ static void qemudDomainEventDispatch (struct qemud_driver *driver,
                                       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(virConnectPtr conn,
     }
 
     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(virConnectPtr conn ATTRIBUTE_UNUSED,
     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 qemud_driver *driver, virDomainObjPtr v
 
 
 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;
         }
@@ -1089,6 +1090,12 @@ qemudDispatchVMEvent(int fd, int events, void *opaque) {
     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);
     else
index 63e7c4a426552aaab8fe24b57674aa784747ba92..08f6aeca0e37ee93ba514151e782d291362277d9 100644 (file)
@@ -95,6 +95,7 @@ static int inside_daemon = 0;
 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_domain (remote_nonnull_domain *dom_dst, virDomainPtr do
 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 {
@@ -5266,7 +5267,8 @@ remoteDomainQueueEvent(virConnectPtr conn, XDR *xdr)
  * for event data
  */
 void
-remoteDomainEventFired(int fd ATTRIBUTE_UNUSED,
+remoteDomainEventFired(int watch,
+                       int fd,
                        int event,
                        void *opaque)
 {
@@ -5279,15 +5281,20 @@ remoteDomainEventFired(int fd ATTRIBUTE_UNUSED,
     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. */
     if (really_read (conn, priv, 0, buffer2, sizeof buffer2) == -1)
         return;