[libvirt] [PATCH v5 2/4] event: introduce new event for tunable values
Pavel Hrdina
phrdina at redhat.com
Tue Sep 23 20:06:59 UTC 2014
On 09/23/2014 09:36 PM, John Ferlan wrote:
>
>
> On 09/23/2014 02:46 PM, Pavel Hrdina wrote:
>> 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 at redhat.com>
>> ---
>>
>> since v4:
>> - changed cpu-tune to tunable in virsh-domain.c
>> - added REMOTE_DOMAIN_EVENT_TUNABLE_MAX to limit maximal length of tunable
>> event msg
>>
>> daemon/remote.c | 45 +++++++++++++++++++++
>> include/libvirt/libvirt.h.in | 22 +++++++++++
>> src/conf/domain_event.c | 93 ++++++++++++++++++++++++++++++++++++++++++++
>> src/conf/domain_event.h | 9 +++++
>> src/libvirt_private.syms | 2 +
>> src/remote/remote_driver.c | 42 ++++++++++++++++++++
>> src/remote/remote_protocol.x | 17 +++++++-
>> src/remote_protocol-structs | 9 +++++
>> tools/virsh-domain.c | 33 ++++++++++++++++
>> 9 files changed, 271 insertions(+), 1 deletion(-)
>>
>> diff --git a/daemon/remote.c b/daemon/remote.c
>> index daa4b60..ddd510c 100644
>> --- a/daemon/remote.c
>> +++ b/daemon/remote.c
>> @@ -111,6 +111,13 @@ remoteDeserializeTypedParameters(remote_typed_param *args_params_val,
>> 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,
>> remote_domain_disk_error **ret_errors_val,
>> @@ -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);
>> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
>> index 6371b7b..86be86f 100644
>> --- a/include/libvirt/libvirt.h.in
>> +++ b/include/libvirt/libvirt.h.in
>> @@ -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
>> diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
>> index 73ae289..bf187cd 100644
>> --- a/src/conf/domain_event.c
>> +++ b/src/conf/domain_event.c
>> @@ -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;
>> }
>> diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
>> index a3330ca..dc0109c 100644
>> --- a/src/conf/domain_event.h
>> +++ b/src/conf/domain_event.h
>> @@ -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,
>> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
>> index 51a692b..a339ced 100644
>> --- a/src/libvirt_private.syms
>> +++ b/src/libvirt_private.syms
>> @@ -473,6 +473,8 @@ virDomainEventStateRegister;
>> virDomainEventStateRegisterID;
>> virDomainEventTrayChangeNewFromDom;
>> virDomainEventTrayChangeNewFromObj;
>> +virDomainEventTunableNewFromDom;
>> +virDomainEventTunableNewFromObj;
>> virDomainEventWatchdogNewFromDom;
>> virDomainEventWatchdogNewFromObj;
>> virDomainQemuMonitorEventNew;
>> diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
>> index 75a3a7b..79e3fd4 100644
>> --- a/src/remote/remote_driver.c
>> +++ b/src/remote/remote_driver.c
>> @@ -331,6 +331,11 @@ remoteDomainBuildEventBlockJob2(virNetClientProgramPtr prog,
>> 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,
>> void *evdata, void *opaque);
>> @@ -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 },
>> };
>>
>>
>> @@ -5514,6 +5523,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_CPUMAPS_MAX,
>
> s/REMOTE_CPUMAPS_MAX/REMOTE_DOMAIN_EVENT_TUNABLE_MAX
>
> ACK w/ that.
>
Ouch, thanks for caching it. Pushed,
Pavel
> John
>
>> + ¶ms, &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,
>> void *evdata, void *opaque)
>> diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
>> index a4ca0c3..0c6a91e 100644
>> --- a/src/remote/remote_protocol.x
>> +++ b/src/remote/remote_protocol.x
>> @@ -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
>> };
>> diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
>> index e960415..6128a85 100644
>> --- a/src/remote_protocol-structs
>> +++ b/src/remote_protocol-structs
>> @@ -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,
>> };
>> diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
>> index a6ced5f..ce59406 100644
>> --- a/tools/virsh-domain.c
>> +++ b/tools/virsh-domain.c
>> @@ -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(¶ms[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));
>>
>>
More information about the libvir-list
mailing list