Change public API for virEventAddHandle to allow multiple registrations per FD

This commit is contained in:
Daniel P. Berrange 2008-11-19 16:19:36 +00:00
parent 3d41e86534
commit 6d41cb87d3
17 changed files with 187 additions and 119 deletions

View File

@ -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

View 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);
}

View 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"

View 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:

View 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:

View 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;
}

View 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);
}
}

View 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

View 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);
}

View 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,
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);
}

View 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;

View 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;

View 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) {

View 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

View 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,
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;
}

View 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,
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

View 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,
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;
}