summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2008-11-19 16:19:36 +0000
committerDaniel P. Berrange <berrange@redhat.com>2008-11-19 16:19:36 +0000
commit6d41cb87d326c96fbf6e01446508f3c408c5b018 (patch)
tree70b74d466f496676123fc057f48d6717de5d9486 /src
parentAdd a virFreeCallback to virDomainEventRegister (from David Lively) (diff)
downloadlibvirt-6d41cb87d326c96fbf6e01446508f3c408c5b018.tar.gz
libvirt-6d41cb87d326c96fbf6e01446508f3c408c5b018.tar.bz2
libvirt-6d41cb87d326c96fbf6e01446508f3c408c5b018.zip
Change public API for virEventAddHandle to allow multiple registrations per FD
Diffstat (limited to 'src')
-rw-r--r--src/domain_conf.h3
-rw-r--r--src/event.c8
-rw-r--r--src/event.h8
-rw-r--r--src/lxc_driver.c25
-rw-r--r--src/qemu_driver.c43
-rw-r--r--src/remote_internal.c27
6 files changed, 69 insertions, 45 deletions
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 448723f62..88fd6d5da 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -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;
diff --git a/src/event.c b/src/event.c
index ac6f88626..b0ee8b669 100644
--- a/src/event.c
+++ b/src/event.c
@@ -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) {
diff --git a/src/event.h b/src/event.h
index f54038425..fc804c2a7 100644
--- a/src/event.h
+++ b/src/event.h
@@ -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
diff --git a/src/lxc_driver.c b/src/lxc_driver.c
index e8aa018b7..ec206b715 100644
--- a/src/lxc_driver.c
+++ b/src/lxc_driver.c
@@ -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;
}
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 641690e6b..d43119040 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -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
diff --git a/src/remote_internal.c b/src/remote_internal.c
index 63e7c4a42..08f6aeca0 100644
--- a/src/remote_internal.c
+++ b/src/remote_internal.c
@@ -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;