Add VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED event

Since we didn't opt to use one single event for device lifecycle for a
VM we are missing one last event if the device removal failed. This
event will be emitted once we asked to eject the device but for some
reason it is not possible.
This commit is contained in:
Peter Krempa 2016-03-30 18:09:45 +02:00
parent 1ac3864025
commit 5be120710e
9 changed files with 217 additions and 1 deletions

View File

@ -1136,6 +1136,41 @@ remoteRelayDomainEventJobCompleted(virConnectPtr conn,
}
static int
remoteRelayDomainEventDeviceRemovalFailed(virConnectPtr conn,
virDomainPtr dom,
const char *devAlias,
void *opaque)
{
daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_callback_device_removal_failed_msg data;
if (callback->callbackID < 0 ||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain device removal failed event %s %d %s, callback %d",
dom->name, dom->id, devAlias, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
if (VIR_STRDUP(data.devAlias, devAlias) < 0)
return -1;
make_nonnull_domain(&data.dom, dom);
data.callbackID = callback->callbackID;
remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED,
(xdrproc_t)xdr_remote_domain_event_callback_device_removal_failed_msg,
&data);
return 0;
}
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
@ -1159,6 +1194,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceAdded),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventMigrationIteration),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventJobCompleted),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceRemovalFailed),
};
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);

View File

@ -3342,6 +3342,26 @@ typedef void (*virConnectDomainEventDeviceAddedCallback)(virConnectPtr conn,
const char *devAlias,
void *opaque);
/**
* virConnectDomainEventDeviceRemovalFailedCallback:
* @conn: connection object
* @dom: domain on which the event occurred
* @devAlias: device alias
* @opaque: application specified data
*
* This callback occurs when it's certain that removal of a device failed.
*
* The callback signature to use when registering for an event of type
* VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED with
* virConnectDomainEventRegisterAny().
*/
typedef void (*virConnectDomainEventDeviceRemovalFailedCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *devAlias,
void *opaque);
/**
* virConnectDomainEventMigrationIterationCallback:
* @conn: connection object
@ -3687,6 +3707,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_DEVICE_ADDED = 19, /* virConnectDomainEventDeviceAddedCallback */
VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION = 20, /* virConnectDomainEventMigrationIterationCallback */
VIR_DOMAIN_EVENT_ID_JOB_COMPLETED = 21, /* virConnectDomainEventJobCompletedCallback */
VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED = 22, /* virConnectDomainEventDeviceRemovalFailedCallback */
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_ID_LAST

View File

@ -58,6 +58,7 @@ static virClassPtr virDomainEventAgentLifecycleClass;
static virClassPtr virDomainEventDeviceAddedClass;
static virClassPtr virDomainEventMigrationIterationClass;
static virClassPtr virDomainEventJobCompletedClass;
static virClassPtr virDomainEventDeviceRemovalFailedClass;
static void virDomainEventDispose(void *obj);
static void virDomainEventLifecycleDispose(void *obj);
@ -77,6 +78,7 @@ static void virDomainEventAgentLifecycleDispose(void *obj);
static void virDomainEventDeviceAddedDispose(void *obj);
static void virDomainEventMigrationIterationDispose(void *obj);
static void virDomainEventJobCompletedDispose(void *obj);
static void virDomainEventDeviceRemovalFailedDispose(void *obj);
static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
@ -256,6 +258,16 @@ struct _virDomainEventJobCompleted {
typedef struct _virDomainEventJobCompleted virDomainEventJobCompleted;
typedef virDomainEventJobCompleted *virDomainEventJobCompletedPtr;
struct _virDomainEventDeviceRemovalFailed {
virDomainEvent parent;
char *devAlias;
};
typedef struct _virDomainEventDeviceRemovalFailed virDomainEventDeviceRemovalFailed;
typedef virDomainEventDeviceRemovalFailed *virDomainEventDeviceRemovalFailedPtr;
static int
virDomainEventsOnceInit(void)
{
@ -367,6 +379,12 @@ virDomainEventsOnceInit(void)
sizeof(virDomainEventJobCompleted),
virDomainEventJobCompletedDispose)))
return -1;
if (!(virDomainEventDeviceRemovalFailedClass =
virClassNew(virDomainEventClass,
"virDomainEventDeviceRemovalFailed",
sizeof(virDomainEventDeviceRemovalFailed),
virDomainEventDeviceRemovalFailedDispose)))
return -1;
return 0;
}
@ -494,6 +512,17 @@ virDomainEventDeviceAddedDispose(void *obj)
VIR_FREE(event->devAlias);
}
static void
virDomainEventDeviceRemovalFailedDispose(void *obj)
{
virDomainEventDeviceRemovalFailedPtr event = obj;
VIR_DEBUG("obj=%p", event);
VIR_FREE(event->devAlias);
}
static void
virDomainEventPMDispose(void *obj)
{
@ -1340,6 +1369,50 @@ virDomainEventDeviceAddedNewFromDom(virDomainPtr dom,
devAlias);
}
static virObjectEventPtr
virDomainEventDeviceRemovalFailedNew(int id,
const char *name,
unsigned char *uuid,
const char *devAlias)
{
virDomainEventDeviceRemovalFailedPtr ev;
if (virDomainEventsInitialize() < 0)
return NULL;
if (!(ev = virDomainEventNew(virDomainEventDeviceAddedClass,
VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED,
id, name, uuid)))
return NULL;
if (VIR_STRDUP(ev->devAlias, devAlias) < 0)
goto error;
return (virObjectEventPtr)ev;
error:
virObjectUnref(ev);
return NULL;
}
virObjectEventPtr
virDomainEventDeviceRemovalFailedNewFromObj(virDomainObjPtr obj,
const char *devAlias)
{
return virDomainEventDeviceRemovalFailedNew(obj->def->id, obj->def->name,
obj->def->uuid, devAlias);
}
virObjectEventPtr
virDomainEventDeviceRemovalFailedNewFromDom(virDomainPtr dom,
const char *devAlias)
{
return virDomainEventDeviceRemovalFailedNew(dom->id, dom->name, dom->uuid,
devAlias);
}
static virObjectEventPtr
virDomainEventAgentLifecycleNew(int id,
const char *name,
@ -1768,6 +1841,17 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
goto cleanup;
}
case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED:
{
virDomainEventDeviceRemovalFailedPtr deviceRemovalFailedEvent;
deviceRemovalFailedEvent = (virDomainEventDeviceRemovalFailedPtr)event;
((virConnectDomainEventDeviceRemovalFailedCallback)cb)(conn, dom,
deviceRemovalFailedEvent->devAlias,
cbopaque);
goto cleanup;
}
case VIR_DOMAIN_EVENT_ID_LAST:
break;
}

View File

@ -191,6 +191,13 @@ virObjectEventPtr
virDomainEventDeviceAddedNewFromDom(virDomainPtr dom,
const char *devAlias);
virObjectEventPtr
virDomainEventDeviceRemovalFailedNewFromObj(virDomainObjPtr obj,
const char *devAlias);
virObjectEventPtr
virDomainEventDeviceRemovalFailedNewFromDom(virDomainPtr dom,
const char *devAlias);
virObjectEventPtr
virDomainEventTunableNewFromObj(virDomainObjPtr obj,
virTypedParameterPtr params,
int nparams);

View File

@ -492,6 +492,8 @@ virDomainEventControlErrorNewFromDom;
virDomainEventControlErrorNewFromObj;
virDomainEventDeviceAddedNewFromDom;
virDomainEventDeviceAddedNewFromObj;
virDomainEventDeviceRemovalFailedNewFromDom;
virDomainEventDeviceRemovalFailedNewFromObj;
virDomainEventDeviceRemovedNewFromDom;
virDomainEventDeviceRemovedNewFromObj;
virDomainEventDiskChangeNewFromDom;

View File

@ -322,6 +322,10 @@ static void
remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
static void
remoteDomainBuildEventCallbackDeviceRemovalFailed(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
static void
remoteDomainBuildEventBlockJob2(virNetClientProgramPtr prog,
@ -528,6 +532,10 @@ static virNetClientProgramEvent remoteEvents[] = {
remoteDomainBuildEventCallbackJobCompleted,
sizeof(remote_domain_event_callback_job_completed_msg),
(xdrproc_t)xdr_remote_domain_event_callback_job_completed_msg },
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED,
remoteDomainBuildEventCallbackDeviceRemovalFailed,
sizeof(remote_domain_event_callback_device_removal_failed_msg),
(xdrproc_t)xdr_remote_domain_event_callback_device_removal_failed_msg },
};
static void
@ -4829,6 +4837,28 @@ remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgramPtr prog ATTRIBUTE_
remoteEventQueue(priv, event, msg->callbackID);
}
static void
remoteDomainBuildEventCallbackDeviceRemovalFailed(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque)
{
virConnectPtr conn = opaque;
remote_domain_event_callback_device_added_msg *msg = evdata;
struct private_data *priv = conn->privateData;
virDomainPtr dom;
virObjectEventPtr event = NULL;
if (!(dom = get_nonnull_domain(conn, msg->dom)))
return;
event = virDomainEventDeviceRemovalFailedNewFromDom(dom, msg->devAlias);
virObjectUnref(dom);
remoteEventQueue(priv, event, msg->callbackID);
}
static void
remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,

View File

@ -3261,6 +3261,12 @@ struct remote_domain_migrate_start_post_copy_args {
unsigned int flags;
};
struct remote_domain_event_callback_device_removal_failed_msg {
int callbackID;
remote_nonnull_domain dom;
remote_nonnull_string devAlias;
};
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@ -5781,5 +5787,11 @@ enum remote_procedure {
* @generate: both
* @acl: domain:write
*/
REMOTE_PROC_DOMAIN_SET_PERF_EVENTS = 366
REMOTE_PROC_DOMAIN_SET_PERF_EVENTS = 366,
/**
* @generate: both
* @acl: none
*/
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED = 367
};

View File

@ -2730,6 +2730,11 @@ struct remote_domain_migrate_start_post_copy_args {
remote_nonnull_domain dom;
u_int flags;
};
struct remote_domain_event_callback_device_removal_failed_msg {
int callbackID;
remote_nonnull_domain dom;
remote_nonnull_string devAlias;
};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
@ -3097,4 +3102,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_MIGRATE_START_POST_COPY = 364,
REMOTE_PROC_DOMAIN_GET_PERF_EVENTS = 365,
REMOTE_PROC_DOMAIN_SET_PERF_EVENTS = 366,
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED = 367,
};

View File

@ -12301,6 +12301,22 @@ virshEventJobCompletedPrint(virConnectPtr conn ATTRIBUTE_UNUSED,
virshEventPrint(opaque, &buf);
}
static void
virshEventDeviceRemovalFailedPrint(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
const char *alias,
void *opaque)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
virBufferAsprintf(&buf, _("event 'device-removal-failed' for domain %s: %s\n"),
virDomainGetName(dom),
alias);
virshEventPrint(opaque, &buf);
}
static vshEventCallback vshEventCallbacks[] = {
{ "lifecycle",
VIR_DOMAIN_EVENT_CALLBACK(virshEventLifecyclePrint), },
@ -12344,6 +12360,8 @@ static vshEventCallback vshEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(virshEventMigrationIterationPrint), },
{ "job-completed",
VIR_DOMAIN_EVENT_CALLBACK(virshEventJobCompletedPrint), },
{ "device-removal-failed",
VIR_DOMAIN_EVENT_CALLBACK(virshEventDeviceRemovalFailedPrint), },
};
verify(VIR_DOMAIN_EVENT_ID_LAST == ARRAY_CARDINALITY(vshEventCallbacks));