[libvirt] [PATCH v5 2/4] event: introduce new event for tunable values

John Ferlan jferlan at redhat.com
Tue Sep 23 19:36:57 UTC 2014



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.

John

> +                                         &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,
>                                   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(&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));
>  
> 




More information about the libvir-list mailing list