[libvirt] [PATCH v3 2/4] event: introduce new event for cputune

Pavel Hrdina phrdina at redhat.com
Mon Sep 15 15:12:14 UTC 2014


This new event will use typedParameters to expose what has been actually
updated and the reason is that we can in the future extend the cputune.
With typedParameters we don't have to worry about creating some sort of
v2 of cputune event if there will be new features implemented for cputune.

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 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 | 14 ++++++-
 src/remote_protocol-structs  |  9 +++++
 tools/virsh-domain.c         | 33 ++++++++++++++++
 9 files changed, 268 insertions(+), 1 deletion(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 0ea2815..798738e 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
+remoteRelayDomainEventCputune(virConnectPtr conn,
+                              virDomainPtr dom,
+                              virTypedParameterPtr params,
+                              int nparams,
+                              void *opaque)
+{
+    daemonClientEventCallbackPtr callback = opaque;
+    remote_domain_event_callback_cputune_msg data;
+
+    if (callback->callbackID < 0 ||
+        !remoteRelayDomainEventCheckACL(callback->client, conn, dom))
+        return -1;
+
+    VIR_DEBUG("Relaying domain cputune 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_CPUTUNE,
+                                  (xdrproc_t)xdr_remote_domain_event_callback_cputune_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(remoteRelayDomainEventCputune),
 };
 
 verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index c2f9d26..454acc8 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -5172,6 +5172,27 @@ typedef void (*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn,
                                                            const char *devAlias,
                                                            void *opaque);
 
+/**
+ * virConnectDomainEventCputuneCallback:
+ * @conn: connection object
+ * @dom: domain on which the event occurred
+ * @params: changed cpupin values stored as array of virTypedParameter
+ * @nparams: size of the array
+ * @opaque: application specified data
+ *
+ * This callback occurs when cpu tune is 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_CPUTUNE with virConnectDomainEventRegisterAny()
+ */
+typedef void (*virConnectDomainEventCputuneCallback)(virConnectPtr conn,
+                                                     virDomainPtr dom,
+                                                     virTypedParameterPtr params,
+                                                     int nparams,
+                                                     void *opaque);
+
 
 /**
  * VIR_DOMAIN_EVENT_CALLBACK:
@@ -5207,6 +5228,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_CPUTUNE = 17,        /* virConnectDomainEventCputuneCallback */
 
 #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..a84d791 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 virDomainEventCputuneClass;
 
 
 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 virDomainEventCputuneDispose(void *obj);
 
 static void
 virDomainEventDispatchDefaultFunc(virConnectPtr conn,
@@ -203,6 +206,15 @@ struct _virDomainQemuMonitorEvent {
 typedef struct _virDomainQemuMonitorEvent virDomainQemuMonitorEvent;
 typedef virDomainQemuMonitorEvent *virDomainQemuMonitorEventPtr;
 
+struct _virDomainEventCputune {
+    virDomainEvent parent;
+
+    virTypedParameterPtr params;
+    int nparams;
+};
+typedef struct _virDomainEventCputune virDomainEventCputune;
+typedef virDomainEventCputune *virDomainEventCputunePtr;
+
 
 static int
 virDomainEventsOnceInit(void)
@@ -285,6 +297,12 @@ virDomainEventsOnceInit(void)
                       sizeof(virDomainQemuMonitorEvent),
                       virDomainQemuMonitorEventDispose)))
         return -1;
+    if (!(virDomainEventCputuneClass =
+          virClassNew(virDomainEventClass,
+                      "virDomainEventCputune",
+                      sizeof(virDomainEventCputune),
+                      virDomainEventCputuneDispose)))
+        return -1;
     return 0;
 }
 
@@ -420,6 +438,15 @@ virDomainQemuMonitorEventDispose(void *obj)
     VIR_FREE(event->details);
 }
 
+static void
+virDomainEventCputuneDispose(void *obj)
+{
+    virDomainEventCputunePtr 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
+virDomainEventCputuneNew(int id,
+                         const char *name,
+                         unsigned char *uuid,
+                         virTypedParameterPtr params,
+                         int nparams)
+{
+    virDomainEventCputunePtr ev;
+
+    if (virDomainEventsInitialize() < 0)
+        goto error;
+
+    if (!(ev = virDomainEventNew(virDomainEventCputuneClass,
+                                 VIR_DOMAIN_EVENT_ID_CPUTUNE,
+                                 id, name, uuid)))
+        goto error;
+
+    ev->params = params;
+    ev->nparams = nparams;
+
+    return (virObjectEventPtr)ev;
+
+ error:
+    virTypedParamsFree(params, nparams);
+    return NULL;
+}
+
+virObjectEventPtr
+virDomainEventCputuneNewFromObj(virDomainObjPtr obj,
+                                virTypedParameterPtr params,
+                                int nparams)
+{
+    return virDomainEventCputuneNew(obj->def->id,
+                                    obj->def->name,
+                                    obj->def->uuid,
+                                    params,
+                                    nparams);
+}
+
+virObjectEventPtr
+virDomainEventCputuneNewFromDom(virDomainPtr dom,
+                                virTypedParameterPtr params,
+                                int nparams)
+{
+    return virDomainEventCputuneNew(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_CPUTUNE:
+        {
+            virDomainEventCputunePtr cputuneEvent;
+            cputuneEvent = (virDomainEventCputunePtr)event;
+            ((virConnectDomainEventCputuneCallback)cb)(conn, dom,
+                                                       cputuneEvent->params,
+                                                       cputuneEvent->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..bf8c30e 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
+virDomainEventCputuneNewFromObj(virDomainObjPtr obj,
+                                virTypedParameterPtr params,
+                                int nparams);
+virObjectEventPtr
+virDomainEventCputuneNewFromDom(virDomainPtr dom,
+                                virTypedParameterPtr params,
+                                int nparams);
+
 
 int
 virDomainEventStateRegister(virConnectPtr conn,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f128b0c..e854234 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -443,6 +443,8 @@ virDomainEventBlockJobNewFromDom;
 virDomainEventBlockJobNewFromObj;
 virDomainEventControlErrorNewFromDom;
 virDomainEventControlErrorNewFromObj;
+virDomainEventCputuneNewFromDom;
+virDomainEventCputuneNewFromObj;
 virDomainEventDeviceRemovedNewFromDom;
 virDomainEventDeviceRemovedNewFromObj;
 virDomainEventDiskChangeNewFromDom;
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 8221683..efce6ad 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -326,6 +326,11 @@ remoteDomainBuildEventBlockJob2(virNetClientProgramPtr prog,
                                 void *evdata, void *opaque);
 
 static void
+remoteDomainBuildEventCallbackCputune(virNetClientProgramPtr prog,
+                                      virNetClientPtr client,
+                                      void *evdata, void *opaque);
+
+static void
 remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
                                  virNetClientPtr client ATTRIBUTE_UNUSED,
                                  void *evdata, void *opaque);
@@ -476,6 +481,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_CPUTUNE,
+      remoteDomainBuildEventCallbackCputune,
+      sizeof(remote_domain_event_callback_cputune_msg),
+      (xdrproc_t)xdr_remote_domain_event_callback_cputune_msg },
 };
 
 
@@ -5500,6 +5509,39 @@ remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgramPtr prog ATTRIBUT
 
 
 static void
+remoteDomainBuildEventCallbackCputune(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
+                                      virNetClientPtr client ATTRIBUTE_UNUSED,
+                                      void *evdata, void *opaque)
+{
+    virConnectPtr conn = opaque;
+    remote_domain_event_callback_cputune_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,
+                                         &params, &nparams) < 0)
+        return;
+
+    dom = get_nonnull_domain(conn, msg->dom);
+    if (!dom) {
+        virTypedParamsFree(params, nparams);
+        return;
+    }
+
+    event = virDomainEventCputuneNewFromDom(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..7e13822 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2990,6 +2990,12 @@ struct remote_domain_event_block_job_2_msg {
     int status;
 };
 
+struct remote_domain_event_callback_cputune_msg {
+    int callbackID;
+    remote_nonnull_domain dom;
+    remote_typed_param params<REMOTE_CPUMAPS_MAX>;
+};
+
 struct remote_connect_get_cpu_model_names_args {
     remote_nonnull_string arch;
     int need_results;
@@ -5472,5 +5478,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_CPUTUNE = 346
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index e960415..d878874 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_cputune_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_CPUTUNE = 346,
 };
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index f80741c..bd8981b 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -11414,6 +11414,37 @@ vshEventDeviceRemovedPrint(virConnectPtr conn ATTRIBUTE_UNUSED,
         vshEventDone(data->ctl);
 }
 
+static void
+vshEventCputunePrint(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 'cpu-tune' 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), },
@@ -11447,6 +11478,8 @@ static vshEventCallback vshEventCallbacks[] = {
       VIR_DOMAIN_EVENT_CALLBACK(vshEventDeviceRemovedPrint), },
     { "block-job-2",
       VIR_DOMAIN_EVENT_CALLBACK(vshEventBlockJobPrint), },
+    { "cpu-tune",
+      VIR_DOMAIN_EVENT_CALLBACK(vshEventCputunePrint), },
 };
 verify(VIR_DOMAIN_EVENT_ID_LAST == ARRAY_CARDINALITY(vshEventCallbacks));
 
-- 
1.8.5.5




More information about the libvir-list mailing list