mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
Change public API for virEventAddHandle to allow multiple registrations per FD
This commit is contained in:
parent
3d41e86534
commit
6d41cb87d3
11
ChangeLog
11
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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
16
qemud/mdns.c
16
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_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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
if ((sock->watch = virEventAddHandleImpl(sock->fd,
|
||||
VIR_EVENT_HANDLE_READABLE |
|
||||
VIR_EVENT_HANDLE_ERROR |
|
||||
VIR_EVENT_HANDLE_HANGUP,
|
||||
qemudDispatchServerEvent,
|
||||
server) < 0) {
|
||||
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,
|
||||
if ((sock->watch = virEventAddHandleImpl(sock->fd,
|
||||
VIR_EVENT_HANDLE_READABLE |
|
||||
VIR_EVENT_HANDLE_ERROR |
|
||||
VIR_EVENT_HANDLE_HANGUP,
|
||||
qemudDispatchServerEvent,
|
||||
server) < 0) {
|
||||
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,
|
||||
if ((client->watch = virEventAddHandleImpl(client->fd,
|
||||
mode | VIR_EVENT_HANDLE_ERROR |
|
||||
VIR_EVENT_HANDLE_HANGUP,
|
||||
qemudDispatchClientEvent,
|
||||
server) < 0)
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
if ((vm->monitorWatch = virEventAddHandle(
|
||||
vm->monitor,
|
||||
VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
|
||||
lxcMonitorEvent,
|
||||
driver) < 0) {
|
||||
driver)) < 0) {
|
||||
lxcVmTerminate(conn, driver, vm, 0);
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -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,
|
||||
if (((vm->stdout_watch = virEventAddHandle(vm->stdout_fd,
|
||||
VIR_EVENT_HANDLE_READABLE |
|
||||
VIR_EVENT_HANDLE_ERROR |
|
||||
VIR_EVENT_HANDLE_HANGUP,
|
||||
qemudDispatchVMEvent,
|
||||
driver) < 0) ||
|
||||
(virEventAddHandle(vm->stderr_fd,
|
||||
driver)) < 0) ||
|
||||
((vm->stderr_watch = virEventAddHandle(vm->stderr_fd,
|
||||
VIR_EVENT_HANDLE_READABLE |
|
||||
VIR_EVENT_HANDLE_ERROR |
|
||||
VIR_EVENT_HANDLE_HANGUP,
|
||||
qemudDispatchVMEvent,
|
||||
driver) < 0) ||
|
||||
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
|
||||
|
@ -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,
|
||||
if ((priv->watch = virEventAddHandle(priv->sock,
|
||||
VIR_EVENT_HANDLE_READABLE |
|
||||
VIR_EVENT_HANDLE_ERROR |
|
||||
VIR_EVENT_HANDLE_HANGUP,
|
||||
remoteDomainEventFired,
|
||||
conn) < 0) {
|
||||
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,12 +5281,17 @@ 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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user