提交 fcabc1ca 编写于 作者: J Jovanka Gulicoska 提交者: Cole Robinson

Introduce node device lifecycle event APIs

Node device lifecycle event API entry points for registering and
deregistering node deivce events, as well as types of events
associated with node device.
These entry points will be used for implementing asynchronous
lifecycle events.

Node device API:
virConnectNodeDeviceEventRegisterAny
virConnectNodeDeviceEventDeregisterAny
virNodeDeviceEventLifecycleType which has events CREATED and DELETED
上级 b0c144c5
......@@ -121,5 +121,95 @@ virNodeDevicePtr virNodeDeviceCreateXML (virConnectPtr conn,
int virNodeDeviceDestroy (virNodeDevicePtr dev);
/**
* VIR_NODE_DEVICE_EVENT_CALLBACK:
*
* Used to cast the event specific callback into the generic one
* for use for virConnectNodeDeviceEventRegisterAny()
*/
# define VIR_NODE_DEVICE_EVENT_CALLBACK(cb)((virConnectNodeDeviceEventGenericCallback)(cb))
/**
* virNodeDeviceEventID:
*
* An enumeration of supported eventId parameters for
* virConnectNodeDeviceEventRegisterAny(). Each event id determines which
* signature of callback function will be used.
*/
typedef enum {
VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE = 0, /* virConnectNodeDeviceEventLifecycleCallback */
# ifdef VIR_ENUM_SENTINELS
VIR_NODE_DEVICE_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
} virNodeDeviceEventID;
/**
* virConnectNodeDeviceEventGenericCallback:
* @conn: the connection pointer
* @dev: the node device pointer
* @opaque: application specified data
*
* A generic node device event callback handler, for use with
* virConnectNodeDeviceEventRegisterAny(). Specific events usually
* have a customization with extra parameters, often with @opaque being
* passed in a different parameter position; use
* VIR_NODE_DEVICE_EVENT_CALLBACK() when registering an appropriate handler.
*/
typedef void (*virConnectNodeDeviceEventGenericCallback)(virConnectPtr conn,
virNodeDevicePtr dev,
void *opaque);
/* Use VIR_NODE_DEVICE_EVENT_CALLBACK() to cast the 'cb' parameter */
int virConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
virNodeDevicePtr dev, /* optional, to filter */
int eventID,
virConnectNodeDeviceEventGenericCallback cb,
void *opaque,
virFreeCallback freecb);
int virConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,
int callbackID);
/**
* virNodeDeviceEventLifecycleType:
*
* a virNodeDeviceEventLifecycleType is emitted during node device
* lifecycle events
*/
typedef enum {
VIR_NODE_DEVICE_EVENT_CREATED = 0,
VIR_NODE_DEVICE_EVENT_DELETED = 1,
# ifdef VIR_ENUM_SENTINELS
VIR_NODE_DEVICE_EVENT_LAST
# endif
} virNodeDeviceEventLifecycleType;
/**
* virConnectNodeDeviceEventLifecycleCallback:
* @conn: connection object
* @dev: node device on which the event occurred
* @event: The specific virNodeDeviceEventLifeCycleType which occurred
* @detail: contains some details on the reason of the event.
* @opaque: application specified data
*
* This callback is called when a node device lifecycle action is performed,
* like added or removed.
*
* The callback signature to use when registering for an event of type
* VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE with
* virConnectNodeDeviceEventRegisterAny()
*/
typedef void (*virConnectNodeDeviceEventLifecycleCallback)(virConnectPtr conn,
virNodeDevicePtr dev,
int event,
int detail,
void *opaque);
#endif /* __VIR_LIBVIRT_NODEDEV_H__ */
......@@ -70,6 +70,7 @@ src/libvirt-domain.c
src/libvirt-host.c
src/libvirt-lxc.c
src/libvirt-network.c
src/libvirt-nodedev.c
src/libvirt-nwfilter.c
src/libvirt-qemu.c
src/libvirt-secret.c
......
......@@ -196,6 +196,19 @@ extern virClassPtr virAdmClientClass;
} \
} while (0)
# define virCheckNodeDeviceGoto(obj, label) \
do { \
virNodeDevicePtr _dev= (obj); \
if (!virObjectIsClass(_dev, virNodeDeviceClass) || \
!virObjectIsClass(_dev->conn, virConnectClass)) { \
virReportErrorHelper(VIR_FROM_NODEDEV, \
VIR_ERR_INVALID_NODE_DEVICE, \
__FILE__, __FUNCTION__, __LINE__, \
__FUNCTION__); \
goto label; \
} \
} while (0)
# define virCheckSecretReturn(obj, retval) \
do { \
virSecretPtr _secret = (obj); \
......
......@@ -75,6 +75,18 @@ typedef virNodeDevicePtr
typedef int
(*virDrvNodeDeviceDestroy)(virNodeDevicePtr dev);
typedef int
(*virDrvConnectNodeDeviceEventRegisterAny)(virConnectPtr conn,
virNodeDevicePtr dev,
int eventID,
virConnectNodeDeviceEventGenericCallback cb,
void *opaque,
virFreeCallback freecb);
typedef int
(*virDrvConnectNodeDeviceEventDeregisterAny)(virConnectPtr conn,
int callbackID);
typedef struct _virNodeDeviceDriver virNodeDeviceDriver;
......@@ -92,6 +104,8 @@ struct _virNodeDeviceDriver {
virDrvNodeNumOfDevices nodeNumOfDevices;
virDrvNodeListDevices nodeListDevices;
virDrvConnectListAllNodeDevices connectListAllNodeDevices;
virDrvConnectNodeDeviceEventRegisterAny connectNodeDeviceEventRegisterAny;
virDrvConnectNodeDeviceEventDeregisterAny connectNodeDeviceEventDeregisterAny;
virDrvNodeDeviceLookupByName nodeDeviceLookupByName;
virDrvNodeDeviceLookupSCSIHostByWWN nodeDeviceLookupSCSIHostByWWN;
virDrvNodeDeviceGetXMLDesc nodeDeviceGetXMLDesc;
......
......@@ -753,3 +753,130 @@ virNodeDeviceDestroy(virNodeDevicePtr dev)
virDispatchError(dev->conn);
return -1;
}
/**
* virConnectNodeDeviceEventRegisterAny:
* @conn: pointer to the connection
* @dev: pointer to the node device
* @eventID: the event type to receive
* @cb: callback to the function handling node device 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 node device events
* occurring on a node device. This function requires that an event loop
* has been previously registered with virEventRegisterImpl() or
* virEventRegisterDefaultImpl().
*
* If @dev is NULL, then events will be monitored for any node device.
* If @dev is non-NULL, then only the specific node device will be monitored.
*
* Most types of events have a callback providing a custom set of parameters
* for the event. When registering an event, it is thus necessary to use
* the VIR_NODE_DEVICE_EVENT_CALLBACK() macro to cast the
* supplied function pointer to match the signature of this method.
*
* The virNodeDevicePtr 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 node device object after the callback
* returns, it shall take a reference to it, by calling virNodeDeviceRef().
* The reference can be released once the object is no longer required
* by calling virNodeDeviceFree().
*
* 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 virConnectNodeDeviceEventDeregisterAny() method.
*
* Returns a callback identifier on success, -1 on failure.
*/
int
virConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
virNodeDevicePtr dev,
int eventID,
virConnectNodeDeviceEventGenericCallback cb,
void *opaque,
virFreeCallback freecb)
{
VIR_DEBUG("conn=%p, nodeDevice=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p",
conn, dev, eventID, cb, opaque, freecb);
virResetLastError();
virCheckConnectReturn(conn, -1);
if (dev) {
virCheckNodeDeviceGoto(dev, error);
if (dev->conn != conn) {
virReportInvalidArg(dev,
_("node device '%s' in %s must match connection"),
dev->name, __FUNCTION__);
goto error;
}
}
virCheckNonNullArgGoto(cb, error);
virCheckNonNegativeArgGoto(eventID, error);
if (eventID >= VIR_NODE_DEVICE_EVENT_ID_LAST) {
virReportInvalidArg(eventID,
_("eventID in %s must be less than %d"),
__FUNCTION__, VIR_NODE_DEVICE_EVENT_ID_LAST);
goto error;
}
if (conn->nodeDeviceDriver &&
conn->nodeDeviceDriver->connectNodeDeviceEventRegisterAny) {
int ret;
ret = conn->nodeDeviceDriver->connectNodeDeviceEventRegisterAny(conn,
dev,
eventID,
cb,
opaque,
freecb);
if (ret < 0)
goto error;
return ret;
}
virReportUnsupportedError();
error:
virDispatchError(conn);
return -1;
}
/**
* virConnectNodeDeviceEventDeregisterAny:
* @conn: pointer to the connection
* @callbackID: the callback identifier
*
* Removes an event callback. The callbackID parameter should be the
* value obtained from a previous virConnectNodeDeviceEventRegisterAny() method.
*
* Returns 0 on success, -1 on failure.
*/
int
virConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,
int callbackID)
{
VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
virResetLastError();
virCheckConnectReturn(conn, -1);
virCheckNonNegativeArgGoto(callbackID, error);
if (conn->nodeDeviceDriver &&
conn->nodeDeviceDriver->connectNodeDeviceEventDeregisterAny) {
int ret;
ret = conn->nodeDeviceDriver->connectNodeDeviceEventDeregisterAny(conn,
callbackID);
if (ret < 0)
goto error;
return ret;
}
virReportUnsupportedError();
error:
virDispatchError(conn);
return -1;
}
......@@ -740,4 +740,10 @@ LIBVIRT_2.0.0 {
virDomainSetGuestVcpus;
} LIBVIRT_1.3.3;
LIBVIRT_2.2.0 {
global:
virConnectNodeDeviceEventRegisterAny;
virConnectNodeDeviceEventDeregisterAny;
} LIBVIRT_2.0.0;
# .... define new API here using predicted next version number ....
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册