[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
[libvirt] Re: [PATCH 03/12] Domain Events - daemon changes
- From: Ben Guthro <bguthro virtualiron com>
- To: libvir-list redhat com
- Subject: [libvirt] Re: [PATCH 03/12] Domain Events - daemon changes
- Date: Fri, 17 Oct 2008 11:56:22 -0400
This code changes the daemaon to:
use the pulic def of virEventRegisterImpl
Add functionality to dispatch events to connected remote drivers
qemud.c | 28 ++++++++---
qemud.h | 14 +++++
remote.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 193 insertions(+), 7 deletions(-)
diff --git a/qemud/qemud.c b/qemud/qemud.c
index 9da27d2..3020d81 100644
--- a/qemud/qemud.c
+++ b/qemud/qemud.c
@@ -723,12 +723,12 @@ static struct qemud_server *qemudInitialize(int sigread) {
server->sigread = sigread;
- __virEventRegisterImpl(virEventAddHandleImpl,
- virEventUpdateHandleImpl,
- virEventRemoveHandleImpl,
- virEventAddTimeoutImpl,
- virEventUpdateTimeoutImpl,
- virEventRemoveTimeoutImpl);
+ virEventRegisterImpl(virEventAddHandleImpl,
+ virEventUpdateHandleImpl,
+ virEventRemoveHandleImpl,
+ virEventAddTimeoutImpl,
+ virEventUpdateTimeoutImpl,
+ virEventRemoveTimeoutImpl);
virStateInitialize();
@@ -1105,7 +1105,12 @@ static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket
client->auth = sock->auth;
memcpy (&client->addr, &addr, sizeof addr);
client->addrlen = addrlen;
+ client->server = server;
+ if(VIR_ALLOC(client->domainEventCallbacks)<0) {
+ qemudLog(QEMUD_ERR, _("Error allocating domainEventCallbacks: %s"), strerror(errno));
+ goto cleanup;
+ }
#if HAVE_POLKIT
/* Only do policy checks for non-root - allow root user
through with no checks, as a fail-safe - root can easily
@@ -1199,6 +1204,15 @@ static void qemudDispatchClientFailure(struct qemud_server *server, struct qemud
virEventRemoveHandleImpl(client->fd);
+ /* Deregister event delivery callback */
+ if(client->conn) {
+ qemudDebug("Deregistering to relay remote events");
+ virConnectDomainEventDeregister(client->conn, remoteRelayDomainEvent);
+ }
+
+ /* Free domain callback list */
+ __virDomainEventCallbackListFree(client->domainEventCallbacks);
+
if (client->conn)
virConnectClose(client->conn);
@@ -1503,7 +1517,7 @@ static int qemudClientWrite(struct qemud_server *server,
}
-static void qemudDispatchClientWrite(struct qemud_server *server, struct qemud_client *client) {
+void qemudDispatchClientWrite(struct qemud_server *server, struct qemud_client *client) {
switch (client->mode) {
case QEMUD_MODE_TX_PACKET: {
if (qemudClientWrite(server, client) < 0)
diff --git a/qemud/qemud.h b/qemud/qemud.h
index 91cb939..2fb3ca9 100644
--- a/qemud/qemud.h
+++ b/qemud/qemud.h
@@ -132,6 +132,12 @@ struct qemud_client {
*/
virConnectPtr conn;
+ /* This is the list of remote callbacks registered */
+ virDomainEventCallbackListPtr domainEventCallbacks;
+
+ /* back-pointer to our server */
+ struct qemud_server *server;
+
struct qemud_client *next;
};
@@ -179,8 +185,16 @@ void qemudLog(int priority, const char *fmt, ...)
void remoteDispatchClientRequest (struct qemud_server *server,
struct qemud_client *client);
+void qemudDispatchClientWrite(struct qemud_server *server,
+ struct qemud_client *client);
+
#if HAVE_POLKIT
int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid);
#endif
+int remoteRelayDomainEvent (virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int event,
+ void *opaque);
+
#endif
diff --git a/qemud/remote.c b/qemud/remote.c
index 72e064e..eeed5fd 100644
--- a/qemud/remote.c
+++ b/qemud/remote.c
@@ -75,6 +75,13 @@ typedef int (*dispatch_fn) (struct qemud_server *server,
char *args,
char *ret);
+/* Prototypes */
+static void
+remoteDispatchDomainEventSend (struct qemud_client *client,
+ virDomainPtr dom,
+ virDomainEventType event,
+ virDomainEventCallbackPtr callback);
+
/* This function gets called from qemud when it detects an incoming
* remote protocol message. At this point, client->buffer contains
* the full call message (including length word which we skip).
@@ -405,6 +412,24 @@ remoteDispatchError (struct qemud_client *client,
remoteDispatchSendError (client, req, VIR_ERR_RPC, msg);
}
+int remoteRelayDomainEvent (virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int event,
+ void *opaque)
+{
+ int i;
+ struct qemud_client *c = opaque;
+ REMOTE_DEBUG("Relaying domain event %d", event);
+
+ if(c && c->domainEventCallbacks) {
+ for(i=0; i < c->domainEventCallbacks->count; i++) {
+ remoteDispatchDomainEventSend (c, dom, event,
+ c->domainEventCallbacks->callbacks[i]);
+ qemudDispatchClientWrite(c->server,c);
+ }
+ }
+ return 0;
+}
/*----- Functions. -----*/
@@ -3620,6 +3645,139 @@ remoteDispatchStorageVolLookupByPath (struct qemud_server *server ATTRIBUTE_UNUS
}
+/**************************
+ * Async Events
+ **************************/
+static int remoteDispatchDomainEvent (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ remote_message_header *req ATTRIBUTE_UNUSED,
+ void *args ATTRIBUTE_UNUSED,
+ remote_domain_event_ret *ret ATTRIBUTE_UNUSED)
+{
+ /* This call gets dispatched from a client call.
+ * This does not make sense, as this should not be intiated
+ * from the client side in generated code.
+ */
+ return -1;
+}
+
+/***************************
+ * Register / deregister events
+ ***************************/
+static int remoteDispatchDomainEventsRegister (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client,
+ remote_message_header *req ATTRIBUTE_UNUSED,
+ remote_domain_events_register_args *args ATTRIBUTE_UNUSED,
+ void *ret ATTRIBUTE_UNUSED)
+{
+ CHECK_CONN(client);
+
+ if( __virDomainEventCallbackListAdd(client->conn, client->domainEventCallbacks,
+ (virConnectDomainEventCallback)args->callback,
+ (void *)args->user_data) < 0 ) {
+ REMOTE_DEBUG("%s","Error adding event callback");
+ return -1;
+ }
+
+ /* Register event delivery callback
+ * This is redundant if already registered for this client
+ */
+ REMOTE_DEBUG("%s","Registering to relay remote events");
+ virConnectDomainEventRegister(client->conn, remoteRelayDomainEvent, client);
+
+ return 0;
+}
+
+static int remoteDispatchDomainEventsDeregister (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client,
+ remote_message_header *req ATTRIBUTE_UNUSED,
+ remote_domain_events_deregister_args *args ATTRIBUTE_UNUSED,
+ void *ret ATTRIBUTE_UNUSED)
+{
+ CHECK_CONN(client);
+
+ if( __virDomainEventCallbackListRemove(client->conn, client->domainEventCallbacks,
+ (virConnectDomainEventCallback)args->callback) < 0 ) {
+ REMOTE_DEBUG("%s","WARNING: Could not remove event callback from list");
+ }
+
+ /* Deregister event delivery callback */
+ REMOTE_DEBUG("%s","Deregistering to relay remote events");
+ virConnectDomainEventDeregister(client->conn, remoteRelayDomainEvent);
+
+ return 0;
+}
+
+static void
+remoteDispatchDomainEventSend (struct qemud_client *client,
+ virDomainPtr dom,
+ virDomainEventType event,
+ virDomainEventCallbackPtr callback)
+{
+ remote_message_header rep;
+ XDR xdr;
+ int len;
+ remote_domain_event_ret data;
+
+ if(!client) {
+ remoteDispatchError (client, NULL, "%s", _("Invalid Client"));
+ return;
+ }
+
+ rep.prog = REMOTE_PROGRAM;
+ rep.vers = REMOTE_PROTOCOL_VERSION;
+ rep.proc = REMOTE_PROC_DOMAIN_EVENT;
+ rep.direction = REMOTE_MESSAGE;
+ rep.serial = 1;
+ rep.status = REMOTE_OK;
+
+ /* Serialise the return header and event. */
+ xdrmem_create (&xdr, client->buffer, sizeof client->buffer, XDR_ENCODE);
+
+ len = 0; /* We'll come back and write this later. */
+ if (!xdr_int (&xdr, &len)) {
+ remoteDispatchError (client, NULL, "%s", _("xdr_int failed (1)"));
+ xdr_destroy (&xdr);
+ return;
+ }
+
+ if (!xdr_remote_message_header (&xdr, &rep)) {
+ xdr_destroy (&xdr);
+ return;
+ }
+
+ /* build return data */
+ make_nonnull_domain (&data.dom, dom);
+ data.event = (int) event;
+ data.callback = (unsigned long) callback->cb;
+ data.user_data = (unsigned long) callback->opaque;
+
+ if (!xdr_remote_domain_event_ret(&xdr, &data)) {
+ remoteDispatchError (client, NULL, "%s", _("serialise return struct"));
+ xdr_destroy (&xdr);
+ return;
+ }
+
+ len = xdr_getpos (&xdr);
+ if (xdr_setpos (&xdr, 0) == 0) {
+ remoteDispatchError (client, NULL, "%s", _("xdr_setpos failed"));
+ xdr_destroy (&xdr);
+ return;
+ }
+
+ if (!xdr_int (&xdr, &len)) {
+ remoteDispatchError (client, NULL, "%s", _("xdr_int failed (2)"));
+ xdr_destroy (&xdr);
+ return;
+ }
+
+ xdr_destroy (&xdr);
+
+ /* Send it. */
+ client->mode = QEMUD_MODE_TX_PACKET;
+ client->bufferLength = len;
+ client->bufferOffset = 0;
+}
/*----- Helpers. -----*/
/* get_nonnull_domain and get_nonnull_network turn an on-wire
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]