1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-22 17:34:18 +03:00

event: introduce new event for tunable values

This new event will use typedParameters to expose what has been actually
updated and the reason is that we can in the future extend any tunable
values or add new tunable values. With typedParameters we don't have to
worry about creating some other events, we will just use this universal
event to inform user about updates.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Pavel Hrdina 2014-09-10 13:28:24 +02:00
parent ad56f86378
commit e426718129
9 changed files with 271 additions and 1 deletions

View File

@ -110,6 +110,13 @@ remoteDeserializeTypedParameters(remote_typed_param *args_params_val,
int limit,
int *nparams);
static int
remoteSerializeTypedParameters(virTypedParameterPtr params,
int nparams,
remote_typed_param **ret_params_val,
u_int *ret_params_len,
unsigned int flags);
static int
remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors,
int nerrors,
@ -969,6 +976,43 @@ remoteRelayDomainEventBlockJob2(virConnectPtr conn,
}
static int
remoteRelayDomainEventTunable(virConnectPtr conn,
virDomainPtr dom,
virTypedParameterPtr params,
int nparams,
void *opaque)
{
daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_callback_tunable_msg data;
if (callback->callbackID < 0 ||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain tunable event %s %d, callback %d",
dom->name, dom->id, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
data.callbackID = callback->callbackID;
make_nonnull_domain(&data.dom, dom);
if (remoteSerializeTypedParameters(params, nparams,
&data.params.params_val,
&data.params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0)
return -1;
remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE,
(xdrproc_t)xdr_remote_domain_event_callback_tunable_msg,
&data);
return 0;
}
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
@ -987,6 +1031,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMSuspendDisk),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceRemoved),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob2),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTunable),
};
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);

View File

@ -5203,6 +5203,27 @@ typedef void (*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn,
const char *devAlias,
void *opaque);
/**
* virConnectDomainEventTunableCallback:
* @conn: connection object
* @dom: domain on which the event occurred
* @params: changed tunable values stored as array of virTypedParameter
* @nparams: size of the array
* @opaque: application specified data
*
* This callback occurs when tunable values are updated. The params must not
* be freed in the callback handler as it's done internally after the callback
* handler is executed.
*
* The callback signature to use when registering for an event of type
* VIR_DOMAIN_EVENT_ID_TUNABLE with virConnectDomainEventRegisterAny()
*/
typedef void (*virConnectDomainEventTunableCallback)(virConnectPtr conn,
virDomainPtr dom,
virTypedParameterPtr params,
int nparams,
void *opaque);
/**
* VIR_DOMAIN_EVENT_CALLBACK:
@ -5238,6 +5259,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK = 14, /* virConnectDomainEventPMSuspendDiskCallback */
VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED = 15, /* virConnectDomainEventDeviceRemovedCallback */
VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2 = 16, /* virConnectDomainEventBlockJobCallback */
VIR_DOMAIN_EVENT_ID_TUNABLE = 17, /* virConnectDomainEventTunableCallback */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_ID_LAST

View File

@ -34,6 +34,7 @@
#include "viralloc.h"
#include "virerror.h"
#include "virstring.h"
#include "virtypedparam.h"
#define VIR_FROM_THIS VIR_FROM_NONE
@ -52,6 +53,7 @@ static virClassPtr virDomainEventBalloonChangeClass;
static virClassPtr virDomainEventDeviceRemovedClass;
static virClassPtr virDomainEventPMClass;
static virClassPtr virDomainQemuMonitorEventClass;
static virClassPtr virDomainEventTunableClass;
static void virDomainEventDispose(void *obj);
@ -67,6 +69,7 @@ static void virDomainEventBalloonChangeDispose(void *obj);
static void virDomainEventDeviceRemovedDispose(void *obj);
static void virDomainEventPMDispose(void *obj);
static void virDomainQemuMonitorEventDispose(void *obj);
static void virDomainEventTunableDispose(void *obj);
static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
@ -203,6 +206,15 @@ struct _virDomainQemuMonitorEvent {
typedef struct _virDomainQemuMonitorEvent virDomainQemuMonitorEvent;
typedef virDomainQemuMonitorEvent *virDomainQemuMonitorEventPtr;
struct _virDomainEventTunable {
virDomainEvent parent;
virTypedParameterPtr params;
int nparams;
};
typedef struct _virDomainEventTunable virDomainEventTunable;
typedef virDomainEventTunable *virDomainEventTunablePtr;
static int
virDomainEventsOnceInit(void)
@ -285,6 +297,12 @@ virDomainEventsOnceInit(void)
sizeof(virDomainQemuMonitorEvent),
virDomainQemuMonitorEventDispose)))
return -1;
if (!(virDomainEventTunableClass =
virClassNew(virDomainEventClass,
"virDomainEventTunable",
sizeof(virDomainEventTunable),
virDomainEventTunableDispose)))
return -1;
return 0;
}
@ -420,6 +438,15 @@ virDomainQemuMonitorEventDispose(void *obj)
VIR_FREE(event->details);
}
static void
virDomainEventTunableDispose(void *obj)
{
virDomainEventTunablePtr event = obj;
VIR_DEBUG("obj=%p", event);
virTypedParamsFree(event->params, event->nparams);
}
static void *
virDomainEventNew(virClassPtr klass,
@ -1175,6 +1202,61 @@ virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
devAlias);
}
/* This function consumes the params so caller don't have to care about
* freeing it even if error occurs. The reason is to not have to do deep
* copy of params.
*/
static virObjectEventPtr
virDomainEventTunableNew(int id,
const char *name,
unsigned char *uuid,
virTypedParameterPtr params,
int nparams)
{
virDomainEventTunablePtr ev;
if (virDomainEventsInitialize() < 0)
goto error;
if (!(ev = virDomainEventNew(virDomainEventTunableClass,
VIR_DOMAIN_EVENT_ID_TUNABLE,
id, name, uuid)))
goto error;
ev->params = params;
ev->nparams = nparams;
return (virObjectEventPtr)ev;
error:
virTypedParamsFree(params, nparams);
return NULL;
}
virObjectEventPtr
virDomainEventTunableNewFromObj(virDomainObjPtr obj,
virTypedParameterPtr params,
int nparams)
{
return virDomainEventTunableNew(obj->def->id,
obj->def->name,
obj->def->uuid,
params,
nparams);
}
virObjectEventPtr
virDomainEventTunableNewFromDom(virDomainPtr dom,
virTypedParameterPtr params,
int nparams)
{
return virDomainEventTunableNew(dom->id,
dom->name,
dom->uuid,
params,
nparams);
}
static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
@ -1366,6 +1448,17 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
goto cleanup;
}
case VIR_DOMAIN_EVENT_ID_TUNABLE:
{
virDomainEventTunablePtr tunableEvent;
tunableEvent = (virDomainEventTunablePtr)event;
((virConnectDomainEventTunableCallback)cb)(conn, dom,
tunableEvent->params,
tunableEvent->nparams,
cbopaque);
goto cleanup;
}
case VIR_DOMAIN_EVENT_ID_LAST:
break;
}

View File

@ -184,6 +184,15 @@ virDomainEventDeviceRemovedNewFromObj(virDomainObjPtr obj,
virObjectEventPtr
virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
const char *devAlias);
virObjectEventPtr
virDomainEventTunableNewFromObj(virDomainObjPtr obj,
virTypedParameterPtr params,
int nparams);
virObjectEventPtr
virDomainEventTunableNewFromDom(virDomainPtr dom,
virTypedParameterPtr params,
int nparams);
int
virDomainEventStateRegister(virConnectPtr conn,

View File

@ -473,6 +473,8 @@ virDomainEventStateRegister;
virDomainEventStateRegisterID;
virDomainEventTrayChangeNewFromDom;
virDomainEventTrayChangeNewFromObj;
virDomainEventTunableNewFromDom;
virDomainEventTunableNewFromObj;
virDomainEventWatchdogNewFromDom;
virDomainEventWatchdogNewFromObj;
virDomainQemuMonitorEventNew;

View File

@ -330,6 +330,11 @@ remoteDomainBuildEventBlockJob2(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
static void
remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
static void
remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
@ -481,6 +486,10 @@ static virNetClientProgramEvent remoteEvents[] = {
remoteDomainBuildEventBlockJob2,
sizeof(remote_domain_event_block_job_2_msg),
(xdrproc_t)xdr_remote_domain_event_block_job_2_msg },
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE,
remoteDomainBuildEventCallbackTunable,
sizeof(remote_domain_event_callback_tunable_msg),
(xdrproc_t)xdr_remote_domain_event_callback_tunable_msg },
};
@ -5513,6 +5522,39 @@ remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgramPtr prog ATTRIBUT
}
static void
remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque)
{
virConnectPtr conn = opaque;
remote_domain_event_callback_tunable_msg *msg = evdata;
struct private_data *priv = conn->privateData;
virDomainPtr dom;
virTypedParameterPtr params = NULL;
int nparams = 0;
virObjectEventPtr event = NULL;
if (remoteDeserializeTypedParameters(msg->params.params_val,
msg->params.params_len,
REMOTE_DOMAIN_EVENT_TUNABLE_MAX,
&params, &nparams) < 0)
return;
dom = get_nonnull_domain(conn, msg->dom);
if (!dom) {
virTypedParamsFree(params, nparams);
return;
}
event = virDomainEventTunableNewFromDom(dom, params, nparams);
virDomainFree(dom);
remoteEventQueue(priv, event, msg->callbackID);
}
static void
remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,

View File

@ -247,6 +247,9 @@ const REMOTE_NETWORK_DHCP_LEASES_MAX = 65536;
/* Upper limit on count of parameters returned via bulk stats API */
const REMOTE_CONNECT_GET_ALL_DOMAIN_STATS_MAX = 4096;
/* Upper limit of message size for tunable event. */
const REMOTE_DOMAIN_EVENT_TUNABLE_MAX = 8388608;
/* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */
typedef opaque remote_uuid[VIR_UUID_BUFLEN];
@ -2990,6 +2993,12 @@ struct remote_domain_event_block_job_2_msg {
int status;
};
struct remote_domain_event_callback_tunable_msg {
int callbackID;
remote_nonnull_domain dom;
remote_typed_param params<REMOTE_DOMAIN_EVENT_TUNABLE_MAX>;
};
struct remote_connect_get_cpu_model_names_args {
remote_nonnull_string arch;
int need_results;
@ -5472,5 +5481,11 @@ enum remote_procedure {
* @generate: both
* @acl: domain:block_write
*/
REMOTE_PROC_DOMAIN_BLOCK_COPY = 345
REMOTE_PROC_DOMAIN_BLOCK_COPY = 345,
/**
* @generate: both
* @acl: none
*/
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE = 346
};

View File

@ -2445,6 +2445,14 @@ struct remote_domain_event_block_job_2_msg {
int type;
int status;
};
struct remote_domain_event_callback_tunable_msg {
int callbackID;
remote_nonnull_domain dom;
struct {
u_int params_len;
remote_typed_param * params_val;
} params;
};
struct remote_connect_get_cpu_model_names_args {
remote_nonnull_string arch;
int need_results;
@ -2901,4 +2909,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD = 343,
REMOTE_PROC_CONNECT_GET_ALL_DOMAIN_STATS = 344,
REMOTE_PROC_DOMAIN_BLOCK_COPY = 345,
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE = 346,
};

View File

@ -11454,6 +11454,37 @@ vshEventDeviceRemovedPrint(virConnectPtr conn ATTRIBUTE_UNUSED,
vshEventDone(data->ctl);
}
static void
vshEventTunablePrint(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
virTypedParameterPtr params,
int nparams,
void *opaque)
{
vshDomEventData *data = opaque;
size_t i;
char *value = NULL;
if (!data->loop && *data->count)
return;
vshPrint(data->ctl,
_("event 'tunable' for domain %s:\n"),
virDomainGetName(dom));
for (i = 0; i < nparams; i++) {
value = virTypedParameterToString(&params[i]);
if (value) {
vshPrint(data->ctl, _("\t%s: %s\n"), params[i].field, value);
VIR_FREE(value);
}
}
(*data->count)++;
if (!data->loop)
vshEventDone(data->ctl);
}
static vshEventCallback vshEventCallbacks[] = {
{ "lifecycle",
VIR_DOMAIN_EVENT_CALLBACK(vshEventLifecyclePrint), },
@ -11487,6 +11518,8 @@ static vshEventCallback vshEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(vshEventDeviceRemovedPrint), },
{ "block-job-2",
VIR_DOMAIN_EVENT_CALLBACK(vshEventBlockJobPrint), },
{ "tunable",
VIR_DOMAIN_EVENT_CALLBACK(vshEventTunablePrint), },
};
verify(VIR_DOMAIN_EVENT_ID_LAST == ARRAY_CARDINALITY(vshEventCallbacks));