mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 03:25:20 +00:00
Introduce a new public API for domain events
The current API for domain events has a number of problems - Only allows for domain lifecycle change events - Does not allow the same callback to be registered multiple times - Does not allow filtering of events to a specific domain This introduces a new more general purpose domain events API typedef enum { VIR_DOMAIN_EVENT_ID_LIFECYCLE = 0, /* virConnectDomainEventCallback */ ...more events later.. } int virConnectDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, /* Optional, to filter */ int eventID, virConnectDomainEventGenericCallback cb, void *opaque, virFreeCallback freecb); int virConnectDomainEventDeregisterAny(virConnectPtr conn, int callbackID); Since different event types can received different data in the callback, the API is defined with a generic callback. Specific events will each have a custom signature for their callback. Thus when registering an event it is neccessary to cast the callback to the generic signature eg int myDomainEventCallback(virConnectPtr conn, virDomainPtr dom, int event, int detail, void *opaque) { ... } virConnectDomainEventRegisterAny(conn, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_CALLBACK(myDomainEventCallback) NULL, NULL); The VIR_DOMAIN_EVENT_CALLBACK() macro simply does a "bad" cast to the generic signature * include/libvirt/libvirt.h.in: Define new APIs for registering domain events * src/driver.h: Internal driver entry points for new events APIs * src/libvirt.c: Wire up public API to driver API for events APIs * src/libvirt_public.syms: Export new APIs * src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/opennebula/one_driver.c, src/openvz/openvz_driver.c, src/phyp/phyp_driver.c, src/qemu/qemu_driver.c, src/remote/remote_driver.c, src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c, src/xen/xen_driver.c, src/xenapi/xenapi_driver.c: Stub out new API entries
This commit is contained in:
parent
271945a148
commit
4445723811
@ -1857,6 +1857,44 @@ int virDomainGetJobInfo(virDomainPtr dom,
|
||||
int virDomainAbortJob(virDomainPtr dom);
|
||||
|
||||
|
||||
/* A generic callback definition. Specific events usually have a customization
|
||||
* with extra parameters */
|
||||
typedef void (*virConnectDomainEventGenericCallback)(virConnectPtr conn,
|
||||
virDomainPtr dom,
|
||||
void *opaque);
|
||||
|
||||
/**
|
||||
* VIR_DOMAIN_EVENT_CALLBACK:
|
||||
*
|
||||
* Used to cast the event specific callback into the generic one
|
||||
* for use for virDomainEventRegister
|
||||
*/
|
||||
#define VIR_DOMAIN_EVENT_CALLBACK(cb) ((virConnectDomainEventGenericCallback)(cb))
|
||||
|
||||
|
||||
typedef enum {
|
||||
VIR_DOMAIN_EVENT_ID_LIFECYCLE = 0, /* virConnectDomainEventCallback */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
VIR_DOMAIN_EVENT_ID_LAST
|
||||
} virDomainEventID;
|
||||
|
||||
|
||||
/* Use VIR_DOMAIN_EVENT_CALLBACK() to cast the 'cb' parameter */
|
||||
int virConnectDomainEventRegisterAny(virConnectPtr conn,
|
||||
virDomainPtr dom, /* Optional, to filter */
|
||||
int eventID,
|
||||
virConnectDomainEventGenericCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback freecb);
|
||||
|
||||
int virConnectDomainEventDeregisterAny(virConnectPtr conn,
|
||||
int callbackID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -169,6 +169,7 @@ skipped_modules = {
|
||||
skipped_types = {
|
||||
# 'int *': "usually a return type",
|
||||
'virConnectDomainEventCallback': "No function types in python",
|
||||
'virConnectDomainEventGenericCallback': "No function types in python",
|
||||
'virEventAddHandleFunc': "No function types in python",
|
||||
}
|
||||
|
||||
@ -330,6 +331,8 @@ skip_function = (
|
||||
'virNodeGetSecurityModel', # Needs investigation...
|
||||
'virConnectDomainEventRegister', # overridden in virConnect.py
|
||||
'virConnectDomainEventDeregister', # overridden in virConnect.py
|
||||
'virConnectDomainEventRegisterAny', # overridden in virConnect.py
|
||||
'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
|
||||
'virSaveLastError', # We have our own python error wrapper
|
||||
'virFreeError', # Only needed if we use virSaveLastError
|
||||
'virStreamEventAddCallback',
|
||||
|
14
src/driver.h
14
src/driver.h
@ -386,6 +386,18 @@ typedef int
|
||||
unsigned long long downtime,
|
||||
unsigned int flags);
|
||||
|
||||
typedef int
|
||||
(*virDrvDomainEventRegisterAny)(virConnectPtr conn,
|
||||
virDomainPtr dom,
|
||||
int eventID,
|
||||
virConnectDomainEventGenericCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback freecb);
|
||||
|
||||
typedef int
|
||||
(*virDrvDomainEventDeregisterAny)(virConnectPtr conn,
|
||||
int callbackID);
|
||||
|
||||
/**
|
||||
* _virDriver:
|
||||
*
|
||||
@ -480,6 +492,8 @@ struct _virDriver {
|
||||
virDrvDomainGetJobInfo domainGetJobInfo;
|
||||
virDrvDomainAbortJob domainAbortJob;
|
||||
virDrvDomainMigrateSetMaxDowntime domainMigrateSetMaxDowntime;
|
||||
virDrvDomainEventRegisterAny domainEventRegisterAny;
|
||||
virDrvDomainEventDeregisterAny domainEventDeregisterAny;
|
||||
};
|
||||
|
||||
typedef int
|
||||
|
@ -3399,6 +3399,8 @@ static virDriver esxDriver = {
|
||||
NULL, /* domainGetJobInfo */
|
||||
NULL, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
|
||||
|
133
src/libvirt.c
133
src/libvirt.c
@ -9338,8 +9338,12 @@ error:
|
||||
* @opaque: opaque data to pass on to the callback
|
||||
* @freecb: optional function to deallocate opaque when not used anymore
|
||||
*
|
||||
* Adds a Domain Event Callback.
|
||||
* Registering for a domain callback will enable delivery of the events
|
||||
* Adds a callback to receive notifications of domain lifecycle events
|
||||
* occurring on a connection
|
||||
*
|
||||
* Use of this method is no longer recommended. Instead applications
|
||||
* should try virConnectDomainEventRegisterAny which has a more flexible
|
||||
* API contract
|
||||
*
|
||||
* The virDomainPtr object handle passed into the callback upon delivery
|
||||
* of an event is only valid for the duration of execution of the callback.
|
||||
@ -9388,9 +9392,12 @@ error:
|
||||
* @conn: pointer to the connection
|
||||
* @cb: callback to the function handling domain events
|
||||
*
|
||||
* Removes a Domain Event Callback.
|
||||
* De-registering for a domain callback will disable
|
||||
* delivery of this event type
|
||||
* Removes a callback previously registered with the virConnectDomainEventRegister
|
||||
* funtion.
|
||||
*
|
||||
* Use of this method is no longer recommended. Instead applications
|
||||
* should try virConnectDomainEventUnregisterAny which has a more flexible
|
||||
* API contract
|
||||
*
|
||||
* Returns 0 on success, -1 on failure
|
||||
*/
|
||||
@ -11356,7 +11363,121 @@ virDomainMigrateSetMaxDowntime(virDomainPtr domain,
|
||||
}
|
||||
|
||||
virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
|
||||
error:
|
||||
virDispatchError(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* virConnectDomainEventRegisterAny:
|
||||
* @conn: pointer to the connection
|
||||
* @dom: pointer to the domain
|
||||
* @eventID: the event type to receive
|
||||
* @cb: callback to the function handling domain 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 domain events
|
||||
* occurring on a domain.
|
||||
*
|
||||
* If dom is NULL, then events will be monitored for any domain. If dom
|
||||
* is non-NULL, then only the specific domain 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 neccessary to use
|
||||
* the VIR_DOMAIN_EVENT_CALLBACK() macro to cast the supplied function pointer
|
||||
* to match the signature of this method.
|
||||
*
|
||||
* The virDomainPtr 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 domain object after the callback
|
||||
* returns, it shall take a reference to it, by calling virDomainRef.
|
||||
* The reference can be released once the object is no longer required
|
||||
* by calling virDomainFree.
|
||||
*
|
||||
* 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 virDomainEventUnregisterAny method
|
||||
*
|
||||
* Returns a callback identifier on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
virConnectDomainEventRegisterAny(virConnectPtr conn,
|
||||
virDomainPtr dom,
|
||||
int eventID,
|
||||
virConnectDomainEventGenericCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback freecb)
|
||||
{
|
||||
DEBUG("conn=%p dom=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p", conn, dom, eventID, cb, opaque, freecb);
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECT(conn)) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return (-1);
|
||||
}
|
||||
if (dom != NULL &&
|
||||
!(VIR_IS_CONNECTED_DOMAIN(dom) && dom->conn == conn)) {
|
||||
virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||
virDispatchError(conn);
|
||||
return (-1);
|
||||
}
|
||||
if (eventID < 0 || eventID >= VIR_DOMAIN_EVENT_ID_LAST || cb == NULL) {
|
||||
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((conn->driver) && (conn->driver->domainEventRegisterAny)) {
|
||||
int ret;
|
||||
ret = conn->driver->domainEventRegisterAny(conn, dom, eventID, cb, opaque, freecb);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
error:
|
||||
virDispatchError(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* virConnectDomainEventDeregisterAny:
|
||||
* @conn: pointer to the connection
|
||||
* @callbackID: the callback identifier
|
||||
*
|
||||
* Removes an event callback. The callbackID parameter should be the
|
||||
* vaule obtained from a previous virDomainEventRegisterAny method.
|
||||
*
|
||||
* Returns 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
virConnectDomainEventDeregisterAny(virConnectPtr conn,
|
||||
int callbackID)
|
||||
{
|
||||
DEBUG("conn=%p, callbackID=%d", conn, callbackID);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECT(conn)) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return (-1);
|
||||
}
|
||||
if (callbackID < 0) {
|
||||
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
if ((conn->driver) && (conn->driver->domainEventDeregisterAny)) {
|
||||
int ret;
|
||||
ret = conn->driver->domainEventDeregisterAny(conn, callbackID);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
error:
|
||||
virDispatchError(conn);
|
||||
return -1;
|
||||
|
@ -362,6 +362,8 @@ LIBVIRT_0.7.8 {
|
||||
global:
|
||||
virStorageVolWipe;
|
||||
virDomainMigrateSetMaxDowntime;
|
||||
virConnectDomainEventRegisterAny;
|
||||
virConnectDomainEventDeregisterAny;
|
||||
} LIBVIRT_0.7.7;
|
||||
|
||||
# .... define new API here using predicted next version number ....
|
||||
|
@ -2460,6 +2460,8 @@ static virDriver lxcDriver = {
|
||||
NULL, /* domainGetJobInfo */
|
||||
NULL, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
static virStateDriver lxcStateDriver = {
|
||||
|
@ -789,6 +789,8 @@ static virDriver oneDriver = {
|
||||
NULL, /* domainGetJobInfo */
|
||||
NULL, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
static virStateDriver oneStateDriver = {
|
||||
|
@ -1541,6 +1541,8 @@ static virDriver openvzDriver = {
|
||||
NULL, /* domainGetJobInfo */
|
||||
NULL, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
int openvzRegister(void) {
|
||||
|
@ -1648,6 +1648,8 @@ virDriver phypDriver = {
|
||||
NULL, /* domainGetJobInfo */
|
||||
NULL, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
int
|
||||
|
@ -9676,6 +9676,8 @@ static virDriver qemuDriver = {
|
||||
qemuDomainGetJobInfo, /* domainGetJobInfo */
|
||||
qemuDomainAbortJob, /* domainAbortJob */
|
||||
qemuDomainMigrateSetMaxDowntime, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
|
||||
|
@ -9189,6 +9189,8 @@ static virDriver remote_driver = {
|
||||
remoteDomainGetJobInfo, /* domainGetJobInfo */
|
||||
remoteDomainAbortJob, /* domainFinishJob */
|
||||
remoteDomainMigrateSetMaxDowntime, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
static virNetworkDriver network_driver = {
|
||||
|
@ -5245,6 +5245,8 @@ static virDriver testDriver = {
|
||||
NULL, /* domainGetJobInfo */
|
||||
NULL, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
static virNetworkDriver testNetworkDriver = {
|
||||
|
@ -1933,6 +1933,8 @@ static virDriver umlDriver = {
|
||||
NULL, /* domainGetJobInfo */
|
||||
NULL, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
|
||||
|
@ -7073,6 +7073,8 @@ virDriver NAME(Driver) = {
|
||||
NULL, /* domainGetJobInfo */
|
||||
NULL, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
virNetworkDriver NAME(NetworkDriver) = {
|
||||
|
@ -1907,6 +1907,8 @@ static virDriver xenUnifiedDriver = {
|
||||
NULL, /* domainGetJobInfo */
|
||||
NULL, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1748,6 +1748,8 @@ static virDriver xenapiDriver = {
|
||||
NULL, /* domainGetJobInfo */
|
||||
NULL, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
NULL, /* domainEventRegisterAny */
|
||||
NULL, /* domainEventDeregisterAny */
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user