[libvirt] [v3 26/32] Added Network events API and virNetworkEventLifecycle.

Cédric Bosdonnat cbosdonnat at suse.com
Mon Dec 2 16:39:44 UTC 2013


Put all network-events related code in src/conf/network_event.[ch]
---
 include/libvirt/libvirt.h.in |  77 ++++++++++++++++++++++
 src/Makefile.am              |   5 ++
 src/conf/network_event.c     | 152 +++++++++++++++++++++++++++++++++++++++++++
 src/conf/network_event.h     |  50 ++++++++++++++
 src/conf/object_event.c      |   6 ++
 src/conf/object_event.h      |   1 +
 src/driver.h                 |  14 ++++
 src/libvirt.c                | 125 +++++++++++++++++++++++++++++++++++
 src/libvirt_private.syms     |   2 +
 src/libvirt_public.syms      |   7 ++
 10 files changed, 439 insertions(+)
 create mode 100644 src/conf/network_event.c
 create mode 100644 src/conf/network_event.h

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 5aad75c..5b38dd7 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -4972,6 +4972,83 @@ int virConnectDomainEventRegisterAny(virConnectPtr conn,
 int virConnectDomainEventDeregisterAny(virConnectPtr conn,
                                        int callbackID);
 
+/**
+ * virNetworkEventLifecycleType:
+ *
+ * a virNetworkEventLifecycleType is emitted during network lifecycle events
+ */
+typedef enum {
+    VIR_NETWORK_EVENT_DEFINED = 0,
+    VIR_NETWORK_EVENT_UNDEFINED = 1,
+    VIR_NETWORK_EVENT_STARTED = 2,
+    VIR_NETWORK_EVENT_STOPPED = 3,
+
+#ifdef VIR_ENUM_SENTINELS
+    VIR_NETWORK_EVENT_LAST
+#endif
+} virNetworkEventLifecycleType;
+
+/**
+ * virConnectNetworkEventLifecycleCallback:
+ * @conn: connection object
+ * @net: network on which the event occurred
+ * @event: The specific virNetworkEventLifeCycleType which occurred
+ * @opaque: application specified data
+ *
+ * This callback occurs when the network is started or stopped.
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_NETWORK_EVENT_ID_LIFECYCLE with virConnectNetworkEventRegisterAny()
+ */
+typedef void (*virConnectNetworkEventLifecycleCallback)(virConnectPtr conn,
+                                                        virNetworkPtr net,
+                                                        int event,
+                                                        void *opaque);
+
+/**
+ * VIR_NETWORK_EVENT_CALLBACK:
+ *
+ * Used to cast the event specific callback into the generic one
+ * for use for virNetworkEventRegister
+ */
+#define VIR_NETWORK_EVENT_CALLBACK(cb) ((virConnectNetworkEventGenericCallback)(cb))
+
+typedef enum {
+    VIR_NETWORK_EVENT_ID_LIFECYCLE = 0,       /* virConnectNetworkEventLifecycleCallback */
+
+#ifdef VIR_ENUM_SENTINELS
+    VIR_NETWORK_EVENT_ID_LAST
+    /*
+     * NB: this enum value will increase over time as new events are
+     * added to the libvirt API. It reflects the last event ID supported
+     * by this version of the libvirt API.
+     */
+#endif
+} virNetworkEventID;
+
+/*
+ * virConnectNetworkEventGenericCallback:
+ * @conn: the connection pointer
+ * @net: the network pointer
+ * @opaque: application specified data
+ *
+ * A generic network event callback handler. Specific events usually
+ * have a customization with extra parameters
+ */
+typedef void (*virConnectNetworkEventGenericCallback)(virConnectPtr conn,
+                                                      virNetworkPtr net,
+                                                      void *opaque);
+
+/* Use VIR_NETWORK_EVENT_CALLBACK() to cast the 'cb' parameter  */
+int virConnectNetworkEventRegisterAny(virConnectPtr conn,
+                                      virNetworkPtr net, /* Optional, to filter */
+                                      int eventID,
+                                      virConnectNetworkEventGenericCallback cb,
+                                      void *opaque,
+                                      virFreeCallback freecb);
+
+int virConnectNetworkEventDeregisterAny(virConnectPtr conn,
+                                        int callbackID);
 
 /**
  * virNWFilter:
diff --git a/src/Makefile.am b/src/Makefile.am
index a3ea55c..57e163f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -248,6 +248,9 @@ OBJECT_EVENT_SOURCES =						\
 DOMAIN_EVENT_SOURCES =						\
 		conf/domain_event.c conf/domain_event.h
 
+NETWORK_EVENT_SOURCES =						\
+		conf/network_event.c conf/network_event.h
+
 # Network driver generic impl APIs
 NETWORK_CONF_SOURCES =						\
 		conf/network_conf.c conf/network_conf.h
@@ -298,6 +301,7 @@ CONF_SOURCES =							\
 		$(DOMAIN_CONF_SOURCES)				\
 		$(OBJECT_EVENT_SOURCES)				\
 		$(DOMAIN_EVENT_SOURCES)				\
+		$(NETWORK_EVENT_SOURCES)			\
 		$(NETWORK_CONF_SOURCES)				\
 		$(NWFILTER_CONF_SOURCES)			\
 		$(NODE_DEVICE_CONF_SOURCES)			\
@@ -2026,6 +2030,7 @@ libvirt_setuid_rpc_client_la_SOURCES = 		\
 		util/virutil.c			\
 		util/viruuid.c			\
 		conf/domain_event.c		\
+		conf/network_event.c		\
 		conf/object_event.c		\
 		rpc/virnetsocket.c		\
 		rpc/virnetsocket.h		\
diff --git a/src/conf/network_event.c b/src/conf/network_event.c
new file mode 100644
index 0000000..fb17837
--- /dev/null
+++ b/src/conf/network_event.c
@@ -0,0 +1,152 @@
+/*
+ * network_event.c: network event queue processing helpers
+ *
+ * Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Cedric Bosdonnat
+ */
+
+#include <config.h>
+
+#include "network_event.h"
+#include "network_event.h"
+#include "object_event.h"
+#include "object_event_private.h"
+#include "datatypes.h"
+#include "virlog.h"
+
+struct _virNetworkEventLifecycle {
+    virObjectEvent parent;
+
+    int type;
+};
+typedef struct _virNetworkEventLifecycle virNetworkEventLifecycle;
+typedef virNetworkEventLifecycle *virNetworkEventLifecyclePtr;
+
+static virClassPtr virNetworkEventLifecycleClass;
+static void virNetworkEventLifecycleDispose(void *obj);
+
+static int virNetworkEventsOnceInit(void)
+{
+    if (!(virNetworkEventLifecycleClass = virClassNew(
+                                             virClassForObjectEvent(),
+                                             "virNetworkEventLifecycle",
+                                             sizeof(virNetworkEventLifecycle),
+                                             virNetworkEventLifecycleDispose)))
+        return -1;
+    return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virNetworkEvents)
+
+void virNetworkEventLifecycleDispose(void *obj)
+{
+    virNetworkEventLifecyclePtr event = obj;
+    VIR_DEBUG("obj=%p", event);
+}
+
+
+void
+virNetworkEventDispatchDefaultFunc(virConnectPtr conn,
+                                   virObjectEventPtr event,
+                                   virConnectNetworkEventGenericCallback cb ATTRIBUTE_UNUSED,
+                                   void *cbopaque ATTRIBUTE_UNUSED,
+                                   void *opaque ATTRIBUTE_UNUSED)
+{
+    virNetworkPtr net = virGetNetwork(conn, event->meta.name, event->meta.uuid);
+    if (!net)
+        return;
+
+    switch ((virNetworkEventID) (event->eventID &0xFF) ) {
+    case VIR_NETWORK_EVENT_ID_LIFECYCLE:
+        {
+            virNetworkEventLifecyclePtr networkLifecycleEvent;
+
+            networkLifecycleEvent = (virNetworkEventLifecyclePtr)event;
+            ((virConnectNetworkEventLifecycleCallback)cb)(conn, net,
+                                                          networkLifecycleEvent->type,
+                                                          cbopaque);
+            goto cleanup;
+        }
+
+#ifdef VIR_ENUM_SENTINELS
+    case VIR_NETWORK_EVENT_ID_LAST:
+        break;
+#endif
+    }
+    VIR_WARN("Unexpected event ID %d", event->eventID);
+
+cleanup:
+    virNetworkFree(net);
+}
+
+
+/**
+ * virNetworkEventStateRegisterID:
+ * @conn: connection to associate with callback
+ * @state: object event state
+ * @net: network to filter on or NULL for all networks
+ * @eventID: ID of the event type to register for
+ * @cb: function to add to event
+ * @opaque: data blob to pass to callback
+ * @freecb: callback to free @opaque
+ * @callbackID: filled with callback ID
+ *
+ * Register the function @callbackID with connection @conn,
+ * from @state, for events of type @eventID.
+ *
+ * Returns: the number of callbacks now registered, or -1 on error
+ */
+int
+virNetworkEventStateRegisterID(virConnectPtr conn,
+                              virObjectEventStatePtr state,
+                              virNetworkPtr net,
+                              int eventID,
+                              virConnectObjectEventGenericCallback cb,
+                              void *opaque,
+                              virFreeCallback freecb,
+                              int *callbackID)
+{
+    if (net)
+        return virObjectEventStateRegisterID(conn, state,
+                                             net->uuid, net->name, 0, eventID,
+                                             cb, opaque, freecb, callbackID);
+    else
+        return virObjectEventStateRegisterID(conn, state,
+                                             NULL, NULL, 0, eventID,
+                                             cb, opaque, freecb, callbackID);
+}
+
+void *virNetworkEventLifecycleNew(const char *name,
+                                  const unsigned char *uuid,
+                                  int type)
+{
+    virNetworkEventLifecyclePtr event;
+    int eventId = (VIR_EVENT_NAMESPACE_NETWORK << 8) + VIR_NETWORK_EVENT_ID_LIFECYCLE;
+
+    if (virNetworkEventsInitialize() < 0)
+        return NULL;
+
+    if (!(event = virObjectEventNew(virNetworkEventLifecycleClass,
+                                    eventId,
+                                    0, name, uuid)))
+        return NULL;
+
+    event->type = type;
+
+    return event;
+}
diff --git a/src/conf/network_event.h b/src/conf/network_event.h
new file mode 100644
index 0000000..f3ec24a
--- /dev/null
+++ b/src/conf/network_event.h
@@ -0,0 +1,50 @@
+/*
+ * network_event.h: network event queue processing helpers
+ *
+ * Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Cedric Bosdonnat
+ */
+
+#include "internal.h"
+#include "object_event.h"
+#include "object_event_private.h"
+
+#ifndef __NETWORK_EVENT_H__
+# define __NETWORK_EVENT_H__
+
+int
+virNetworkEventStateRegisterID(virConnectPtr conn,
+                              virObjectEventStatePtr state,
+                              virNetworkPtr net,
+                              int eventID,
+                              virConnectObjectEventGenericCallback cb,
+                              void *opaque,
+                              virFreeCallback freecb,
+                              int *callbackID);
+
+void *virNetworkEventLifecycleNew(const char *name,
+                                  const unsigned char *uuid,
+                                  int type);
+
+void
+virNetworkEventDispatchDefaultFunc(virConnectPtr conn,
+                                   virObjectEventPtr event,
+                                   virConnectNetworkEventGenericCallback cb,
+                                   void *cbopaque,
+                                   void *opaque);
+#endif
diff --git a/src/conf/object_event.c b/src/conf/object_event.c
index a23b2af..94993cf 100644
--- a/src/conf/object_event.c
+++ b/src/conf/object_event.c
@@ -25,6 +25,7 @@
 #include <config.h>
 
 #include "domain_event.h"
+#include "network_event.h"
 #include "object_event.h"
 #include "object_event_private.h"
 #include "virlog.h"
@@ -42,6 +43,7 @@ struct _virObjectEventQueue {
 
 static virClassPtr virObjectEventClass;
 
+static virClassPtr virObjectEventClass;
 static void virObjectEventDispose(void *obj);
 
 static int virObjectEventOnceInit(void)
@@ -634,6 +636,10 @@ virObjectEventStateDispatchFunc(virConnectPtr conn,
             virDomainEventDispatchDefaultFunc(conn, event,
                     VIR_DOMAIN_EVENT_CALLBACK(cb), cbopaque, NULL);
             break;
+        case VIR_EVENT_NAMESPACE_NETWORK:
+            virNetworkEventDispatchDefaultFunc(conn, event,
+                    VIR_NETWORK_EVENT_CALLBACK(cb), cbopaque, NULL);
+            break;
     }
     virObjectEventStateLock(state);
 }
diff --git a/src/conf/object_event.h b/src/conf/object_event.h
index 52a31b2..cfeae67 100644
--- a/src/conf/object_event.h
+++ b/src/conf/object_event.h
@@ -32,6 +32,7 @@
   */
 typedef enum {
     VIR_EVENT_NAMESPACE_DOMAIN = 0, /* 0 to keep value of virDomainEventId unchanged */
+    VIR_EVENT_NAMESPACE_NETWORK = 1,
 } virEventNamespaceID;
 
 typedef struct _virObjectEventCallback virObjectEventCallback;
diff --git a/src/driver.h b/src/driver.h
index 8cd164a..3c7b536 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -1366,6 +1366,18 @@ typedef int
                                 virNetworkPtr **nets,
                                 unsigned int flags);
 
+typedef int
+(*virDrvConnectNetworkEventRegisterAny)(virConnectPtr conn,
+                                        virNetworkPtr dom,
+                                        int eventID,
+                                        virConnectNetworkEventGenericCallback cb,
+                                        void *opaque,
+                                        virFreeCallback freecb);
+
+typedef int
+(*virDrvConnectNetworkEventDeregisterAny)(virConnectPtr conn,
+                                         int callbackID);
+
 typedef virNetworkPtr
 (*virDrvNetworkLookupByUUID)(virConnectPtr conn,
                              const unsigned char *uuid);
@@ -1444,6 +1456,8 @@ struct _virNetworkDriver {
     virDrvConnectNumOfDefinedNetworks connectNumOfDefinedNetworks;
     virDrvConnectListDefinedNetworks connectListDefinedNetworks;
     virDrvConnectListAllNetworks connectListAllNetworks;
+    virDrvConnectNetworkEventRegisterAny connectNetworkEventRegisterAny;
+    virDrvConnectNetworkEventDeregisterAny connectNetworkEventDeregisterAny;
     virDrvNetworkLookupByUUID networkLookupByUUID;
     virDrvNetworkLookupByName networkLookupByName;
     virDrvNetworkCreateXML networkCreateXML;
diff --git a/src/libvirt.c b/src/libvirt.c
index eff44eb..a8feb36 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -68,6 +68,7 @@
 #include "virstring.h"
 #include "virutil.h"
 #include "virtypedparam.h"
+#include "object_event.h"
 
 #ifdef WITH_TEST
 # include "test/test_driver.h"
@@ -19176,6 +19177,130 @@ error:
 }
 
 /**
+ * virConnectNetworkEventRegisterAny:
+ * @conn: pointer to the connection
+ * @net: pointer to the network
+ * @eventID: the event type to receive
+ * @cb: callback to the function handling network events
+ * @opaque: opaque data to pass on to the callback
+ * @freecb: optional function to deallocate opaque when not used anymore
+ *
+ * Adds a callback to receive notifications of arbitrary network events
+ * occurring on a network.
+ *
+ * If net is NULL, then events will be monitored for any network. If net
+ * is non-NULL, then only the specific network will be monitored
+ *
+ * Most types of event have a callback providing a custom set of parameters
+ * for the event. When registering an event, it is thus necessary to use
+ * the VIR_NETWORK_EVENT_CALLBACK() macro to cast the supplied function pointer
+ * to match the signature of this method.
+ *
+ * The virNetworkPtr object handle passed into the callback upon delivery
+ * of an event is only valid for the duration of execution of the callback.
+ * If the callback wishes to keep the network object after the callback
+ * returns, it shall take a reference to it, by calling virNetworkRef.
+ * The reference can be released once the object is no longer required
+ * by calling virNetworkFree.
+ *
+ * The return value from this method is a positive integer identifier
+ * for the callback. To unregister a callback, this callback ID should
+ * be passed to the virNetworkEventUnregisterAny method
+ *
+ * Returns a callback identifier on success, -1 on failure
+ */
+int
+virConnectNetworkEventRegisterAny(virConnectPtr conn,
+                                  virNetworkPtr net,
+                                  int eventID,
+                                  virConnectNetworkEventGenericCallback cb,
+                                  void *opaque,
+                                  virFreeCallback freecb)
+{
+    VIR_DEBUG("conn=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p",
+              conn, eventID, cb, opaque, freecb);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+    if (net != NULL &&
+        !(VIR_IS_CONNECTED_NETWORK(net) && net->conn == conn)) {
+        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+        virDispatchError(conn);
+        return -1;
+    }
+    virCheckNonNullArgGoto(cb, error);
+    virCheckNonNegativeArgGoto(eventID, error);
+
+    if (eventID >= VIR_NETWORK_EVENT_ID_LAST) {
+        virReportInvalidArg(eventID,
+                            _("eventID in %s must be less than %d"),
+                            __FUNCTION__, VIR_NETWORK_EVENT_ID_LAST);
+        goto error;
+    }
+
+    if ((conn->networkDriver) && (conn->networkDriver->connectNetworkEventRegisterAny)) {
+        int ret;
+        ret = conn->networkDriver->connectNetworkEventRegisterAny(conn, net,
+                                          (VIR_EVENT_NAMESPACE_NETWORK << 8) +eventID,
+                                          cb, opaque, freecb);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+    virDispatchError(conn);
+    return -1;
+}
+
+/**
+ * virConnectNetworkEventDeregisterAny:
+ * @conn: pointer to the connection
+ * @callbackID: the callback identifier
+ *
+ * Removes an event callback. The callbackID parameter should be the
+ * vaule obtained from a previous virNetworkEventRegisterAny method.
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+virConnectNetworkEventDeregisterAny(virConnectPtr conn,
+                                    int callbackID)
+{
+    VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+    virCheckNonNegativeArgGoto(callbackID, error);
+
+    if ((conn->networkDriver) &&
+            (conn->networkDriver->connectNetworkEventDeregisterAny)) {
+        int ret;
+        ret = conn->networkDriver->connectNetworkEventDeregisterAny(conn,
+                                                                    callbackID);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+    virDispatchError(conn);
+    return -1;
+}
+
+/**
  * virDomainManagedSave:
  * @dom: pointer to the domain
  * @flags: bitwise-OR of virDomainSaveRestoreFlags
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b511c8a..22ec0ab 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -621,6 +621,8 @@ virNWFilterVarValueGetSimple;
 
 
 # conf/object_event.h
+virNetworkEventLifecycleNew;
+virNetworkEventStateRegisterID;
 virObjectEventStateDeregisterID;
 virObjectEventStateEventID;
 virObjectEventStateFree;
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index fe9b497..6ed6ce6 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -639,4 +639,11 @@ LIBVIRT_1.1.3 {
         virConnectGetCPUModelNames;
 } LIBVIRT_1.1.1;
 
+LIBVIRT_1.2.1 {
+    global:
+        virConnectNetworkEventRegisterAny;
+        virConnectNetworkEventDeregisterAny;
+} LIBVIRT_1.1.3;
+
+
 # .... define new API here using predicted next version number ....
-- 
1.8.4.4




More information about the libvir-list mailing list