On Mon, Dec 02, 2013 at 05:39:44PM +0100, Cédric Bosdonnat wrote:
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);
For the domain events, we have an 'int detail' argument too. I can't help
thinking we should allow for the same with network lifecycle events, even
if we don't have more than one detail reason to start with. It has been
quite helpful for domain lifecycle events.
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 @@
+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
No need to have the ifdef - the sentinels are guaranteed to exist
for libvirt internal code
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,
The internal driver.h entry points should take the same data as the public
API. So we don't want to add in VIR_EVENT_NAMESPACE_NETWORK values here.
Doing this means that the VIR_EVENT_NAMESPACE_NETWORK value becomes visible
on the RPC protocol wire, which forces us into maintaining these values
forever more. We really want to avoid that, so we can change the way we
deal with this if we need to in the future.
We should only translate to add VIR_EVENT_NAMESPACE_NETWORK in the actual
hypervisor drivers
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|