Add VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED event

This commit is contained in:
Jiri Denemark 2013-06-19 15:27:29 +02:00
parent d077cda4e9
commit 4421e257dd
10 changed files with 233 additions and 20 deletions

View File

@ -600,6 +600,37 @@ static int remoteRelayDomainEventPMSuspendDisk(virConnectPtr conn ATTRIBUTE_UNUS
return 0;
}
static int
remoteRelayDomainEventDeviceRemoved(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
const char *devAlias,
void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_device_removed_msg data;
if (!client)
return -1;
VIR_DEBUG("Relaying domain device removed event %s %d %s",
dom->name, dom->id, devAlias);
/* build return data */
memset(&data, 0, sizeof(data));
if (VIR_STRDUP(data.devAlias, devAlias) < 0)
return -1;
make_nonnull_domain(&data.dom, dom);
remoteDispatchDomainEventSend(client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED,
(xdrproc_t)xdr_remote_domain_event_device_removed_msg,
&data);
return 0;
}
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
@ -617,6 +648,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMSuspend),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBalloonChange),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMSuspendDisk),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceRemoved),
};
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);

View File

@ -4864,6 +4864,23 @@ typedef void (*virConnectDomainEventPMSuspendDiskCallback)(virConnectPtr conn,
int reason,
void *opaque);
/**
* virConnectDomainEventDeviceRemovedCallback:
* @conn: connection object
* @dom: domain on which the event occurred
* @devAlias: device alias
* @opaque: application specified data
*
* This callback occurs when a device is removed from the domain.
*
* The callback signature to use when registering for an event of type
* VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED with virConnectDomainEventRegisterAny()
*/
typedef void (*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *devAlias,
void *opaque);
/**
* VIR_DOMAIN_EVENT_CALLBACK:
@ -4890,6 +4907,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_PMSUSPEND = 12, /* virConnectDomainEventPMSuspendCallback */
VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE = 13, /* virConnectDomainEventBalloonChangeCallback */
VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK = 14, /* virConnectDomainEventPMSuspendDiskCallback */
VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED = 15, /* virConnectDomainEventDeviceRemovedCallback */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_ID_LAST

View File

@ -179,6 +179,15 @@
cb(self, virDomain(self, _obj=dom), reason, opaque)
return 0
def _dispatchDomainEventDeviceRemovedCallback(self, dom, devAlias, cbData):
"""Dispatches event to python user domain device removed event callbacks
"""
cb = cbData["cb"]
opaque = cbData["opaque"]
cb(self, virDomain(self, _obj=dom), devAlias, opaque)
return 0
def domainEventDeregisterAny(self, callbackID):
"""Removes a Domain Event Callback. De-registering for a
domain callback will disable delivery of this event type """

View File

@ -6225,6 +6225,51 @@ libvirt_virConnectDomainEventPMSuspendDiskCallback(virConnectPtr conn ATTRIBUTE_
return ret;
}
static int
libvirt_virConnectDomainEventDeviceRemovedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
const char *devAlias,
void *opaque)
{
PyObject *pyobj_cbData = (PyObject*)opaque;
PyObject *pyobj_dom;
PyObject *pyobj_ret;
PyObject *pyobj_conn;
PyObject *dictKey;
int ret = -1;
LIBVIRT_ENSURE_THREAD_STATE;
/* Create a python instance of this virDomainPtr */
virDomainRef(dom);
pyobj_dom = libvirt_virDomainPtrWrap(dom);
Py_INCREF(pyobj_cbData);
dictKey = libvirt_constcharPtrWrap("conn");
pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey);
Py_DECREF(dictKey);
/* Call the Callback Dispatcher */
pyobj_ret = PyObject_CallMethod(pyobj_conn,
(char*)"_dispatchDomainEventDeviceRemovedCallback",
(char*)"OsO",
pyobj_dom, devAlias, pyobj_cbData);
Py_DECREF(pyobj_cbData);
Py_DECREF(pyobj_dom);
if (!pyobj_ret) {
DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
PyErr_Print();
} else {
Py_DECREF(pyobj_ret);
ret = 0;
}
LIBVIRT_RELEASE_THREAD_STATE;
return ret;
}
static PyObject *
libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
PyObject * args)
@ -6254,7 +6299,7 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
else
dom = PyvirDomain_Get(pyobj_dom);
switch (eventID) {
switch ((virDomainEventID) eventID) {
case VIR_DOMAIN_EVENT_ID_LIFECYCLE:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventLifecycleCallback);
break;
@ -6300,6 +6345,11 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
case VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMSuspendDiskCallback);
break;
case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventDeviceRemovedCallback);
case VIR_DOMAIN_EVENT_ID_LAST:
break;
}
if (!cb) {

View File

@ -122,6 +122,9 @@ struct _virDomainEvent {
/* In unit of 1024 bytes */
unsigned long long actual;
} balloonChange;
struct {
char *devAlias;
} deviceRemoved;
} data;
};
@ -1157,6 +1160,44 @@ virDomainEventPtr virDomainEventBalloonChangeNewFromObj(virDomainObjPtr obj,
return ev;
}
static virDomainEventPtr
virDomainEventDeviceRemovedNew(int id,
const char *name,
unsigned char *uuid,
const char *devAlias)
{
virDomainEventPtr ev =
virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
id, name, uuid);
if (ev) {
if (VIR_STRDUP(ev->data.deviceRemoved.devAlias, devAlias) < 0)
goto error;
}
return ev;
error:
virDomainEventFree(ev);
return NULL;
}
virDomainEventPtr
virDomainEventDeviceRemovedNewFromObj(virDomainObjPtr obj,
const char *devAlias)
{
return virDomainEventDeviceRemovedNew(obj->def->id, obj->def->name,
obj->def->uuid, devAlias);
}
virDomainEventPtr
virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
const char *devAlias)
{
return virDomainEventDeviceRemovedNew(dom->id, dom->name, dom->uuid,
devAlias);
}
/**
* virDomainEventQueuePush:
* @evtQueue: the dom event queue
@ -1204,30 +1245,30 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
return;
dom->id = event->dom.id;
switch (event->eventID) {
switch ((virDomainEventID) event->eventID) {
case VIR_DOMAIN_EVENT_ID_LIFECYCLE:
((virConnectDomainEventCallback)cb)(conn, dom,
event->data.lifecycle.type,
event->data.lifecycle.detail,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_REBOOT:
(cb)(conn, dom,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_RTC_CHANGE:
((virConnectDomainEventRTCChangeCallback)cb)(conn, dom,
event->data.rtcChange.offset,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_WATCHDOG:
((virConnectDomainEventWatchdogCallback)cb)(conn, dom,
event->data.watchdog.action,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_IO_ERROR:
((virConnectDomainEventIOErrorCallback)cb)(conn, dom,
@ -1235,7 +1276,7 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
event->data.ioError.devAlias,
event->data.ioError.action,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
((virConnectDomainEventIOErrorReasonCallback)cb)(conn, dom,
@ -1244,7 +1285,7 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
event->data.ioError.action,
event->data.ioError.reason,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_GRAPHICS:
((virConnectDomainEventGraphicsCallback)cb)(conn, dom,
@ -1254,12 +1295,12 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
event->data.graphics.authScheme,
event->data.graphics.subject,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR:
(cb)(conn, dom,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
((virConnectDomainEventBlockJobCallback)cb)(conn, dom,
@ -1267,7 +1308,7 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
event->data.blockJob.type,
event->data.blockJob.status,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
((virConnectDomainEventDiskChangeCallback)cb)(conn, dom,
@ -1276,38 +1317,46 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
event->data.diskChange.devAlias,
event->data.diskChange.reason,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
((virConnectDomainEventTrayChangeCallback)cb)(conn, dom,
event->data.trayChange.devAlias,
event->data.trayChange.reason,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_PMWAKEUP:
((virConnectDomainEventPMWakeupCallback)cb)(conn, dom, 0, cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_PMSUSPEND:
((virConnectDomainEventPMSuspendCallback)cb)(conn, dom, 0, cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE:
((virConnectDomainEventBalloonChangeCallback)cb)(conn, dom,
event->data.balloonChange.actual,
cbopaque);
break;
goto cleanup;
case VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK:
((virConnectDomainEventPMSuspendDiskCallback)cb)(conn, dom, 0, cbopaque);
break;
goto cleanup;
default:
VIR_WARN("Unexpected event ID %d", event->eventID);
case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED:
((virConnectDomainEventDeviceRemovedCallback)cb)(conn, dom,
event->data.deviceRemoved.devAlias,
cbopaque);
goto cleanup;
case VIR_DOMAIN_EVENT_ID_LAST:
break;
}
VIR_WARN("Unexpected event ID %d", event->eventID);
cleanup:
virDomainFree(dom);
}

View File

@ -132,6 +132,11 @@ virDomainEventPtr virDomainEventBalloonChangeNewFromObj(virDomainObjPtr obj, uns
virDomainEventPtr virDomainEventPMSuspendDiskNewFromObj(virDomainObjPtr obj);
virDomainEventPtr virDomainEventPMSuspendDiskNewFromDom(virDomainPtr dom);
virDomainEventPtr virDomainEventDeviceRemovedNewFromObj(virDomainObjPtr obj,
const char *devAlias);
virDomainEventPtr virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
const char *devAlias);
void virDomainEventFree(virDomainEventPtr event);
void virDomainEventStateFree(virDomainEventStatePtr state);

View File

@ -408,6 +408,8 @@ virDomainEventBlockJobNewFromDom;
virDomainEventBlockJobNewFromObj;
virDomainEventControlErrorNewFromDom;
virDomainEventControlErrorNewFromObj;
virDomainEventDeviceRemovedNewFromDom;
virDomainEventDeviceRemovedNewFromObj;
virDomainEventDiskChangeNewFromDom;
virDomainEventDiskChangeNewFromObj;
virDomainEventFree;

View File

@ -268,6 +268,11 @@ remoteDomainBuildEventPMSuspendDisk(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
static void
remoteDomainBuildEventDeviceRemoved(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
static virNetClientProgramEvent remoteDomainEvents[] = {
{ REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
remoteDomainBuildEventRTCChange,
@ -329,6 +334,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = {
remoteDomainBuildEventPMSuspendDisk,
sizeof(remote_domain_event_pmsuspend_disk_msg),
(xdrproc_t)xdr_remote_domain_event_pmsuspend_disk_msg },
{ REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED,
remoteDomainBuildEventDeviceRemoved,
sizeof(remote_domain_event_device_removed_msg),
(xdrproc_t)xdr_remote_domain_event_device_removed_msg },
};
enum virDrvOpenRemoteFlags {
@ -4683,6 +4692,29 @@ remoteDomainBuildEventPMSuspendDisk(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
}
static void
remoteDomainBuildEventDeviceRemoved(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque)
{
virConnectPtr conn = opaque;
struct private_data *priv = conn->privateData;
remote_domain_event_device_removed_msg *msg = evdata;
virDomainPtr dom;
virDomainEventPtr event = NULL;
dom = get_nonnull_domain(conn, msg->dom);
if (!dom)
return;
event = virDomainEventDeviceRemovedNewFromDom(dom, msg->devAlias);
virDomainFree(dom);
remoteDomainEventQueue(priv, event);
}
static virDrvOpenStatus ATTRIBUTE_NONNULL(1)
remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth,
unsigned int flags)

View File

@ -2832,6 +2832,11 @@ struct remote_domain_migrate_confirm3_params_args {
int cancelled;
};
struct remote_domain_event_device_removed_msg {
remote_nonnull_domain dom;
remote_nonnull_string devAlias;
};
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@ -4989,5 +4994,11 @@ enum remote_procedure {
* @generate: none
* @acl: domain:start
*/
REMOTE_PROC_DOMAIN_CREATE_WITH_FILES = 310
REMOTE_PROC_DOMAIN_CREATE_WITH_FILES = 310,
/**
* @generate: both
* @acl: none
*/
REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311
};

View File

@ -2312,6 +2312,10 @@ struct remote_domain_migrate_confirm3_params_args {
u_int flags;
int cancelled;
};
struct remote_domain_event_device_removed_msg {
remote_nonnull_domain dom;
remote_nonnull_string devAlias;
};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
@ -2623,4 +2627,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SET_MEMORY_STATS_PERIOD = 308,
REMOTE_PROC_DOMAIN_CREATE_XML_WITH_FILES = 309,
REMOTE_PROC_DOMAIN_CREATE_WITH_FILES = 310,
REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311,
};