Added Network events API and virNetworkEventLifecycle.

Define the public API for (de-)registering network events
and the callbacks for receiving lifecycle events. The lifecycle
event includes a 'detail' parameter to match the domain lifecycle
event data, but this is currently unused.

The network events related code goes into its own set of internal
files src/conf/network_event.[ch]
This commit is contained in:
Cédric Bosdonnat 2013-12-11 11:37:58 +01:00 committed by Daniel P. Berrange
parent fb2125902f
commit 9ff38c5428
10 changed files with 448 additions and 0 deletions

View File

@ -4974,6 +4974,86 @@ 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
* @detail: contains some details on the reason of the event.
* It will be 0 for the while.
* @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,
int detail,
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:

View File

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

154
src/conf/network_event.c Normal file
View File

@ -0,0 +1,154 @@
/*
* 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 "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,
0,
cbopaque);
goto cleanup;
}
case VIR_NETWORK_EVENT_ID_LAST:
break;
}
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)
{
int nsEventID = (VIR_EVENT_NAMESPACE_NETWORK << 8) + eventID;
if (net)
return virObjectEventStateRegisterID(conn, state,
net->uuid, net->name, 0, nsEventID,
cb, opaque, freecb, callbackID);
else
return virObjectEventStateRegisterID(conn, state,
NULL, NULL, 0, nsEventID,
cb, opaque, freecb, callbackID);
}
virObjectEventPtr
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 (virObjectEventPtr)event;
}

51
src/conf/network_event.h Normal file
View File

@ -0,0 +1,51 @@
/*
* 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);
virObjectEventPtr
virNetworkEventLifecycleNew(const char *name,
const unsigned char *uuid,
int type);
void
virNetworkEventDispatchDefaultFunc(virConnectPtr conn,
virObjectEventPtr event,
virConnectNetworkEventGenericCallback cb,
void *cbopaque,
void *opaque);
#endif

View File

@ -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)
@ -635,6 +637,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);
}
@ -787,6 +793,9 @@ virObjectEventStateEventID(virConnectPtr conn,
virObjectEventStateLock(state);
ret = virObjectEventCallbackListEventID(conn,
state->callbacks, callbackID);
/* Callers don't need to know we are namespacing the event Ids */
if (ret >= 0)
ret = (0xFF & ret);
virObjectEventStateUnlock(state);
return ret;
}

View File

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

View File

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

View File

@ -19176,6 +19176,131 @@ error:
return -1;
}
/**
* 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,
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

View File

@ -624,6 +624,8 @@ virNWFilterVarValueGetSimple;
# conf/object_event.h
virNetworkEventLifecycleNew;
virNetworkEventStateRegisterID;
virObjectEventStateDeregisterID;
virObjectEventStateEventID;
virObjectEventStateFree;

View File

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