Blob Blame History Raw
From 808e539a93e7e886763721852f68450afd958a1a Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Fri, 26 Sep 2014 14:17:16 +0100
Subject: [PATCH] Add virConnectDomainEventTunable event callback & constants

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 8a55270db52966d8de67fa2b6ddca4b5c1cdd3d6)
---
 Virt.xs                | 290 ++++++++++++++++++++++++++++++-------------------
 lib/Sys/Virt/Domain.pm |  72 ++++++++++++
 t/030-api-coverage.t   |   1 +
 3 files changed, 249 insertions(+), 114 deletions(-)

diff --git a/Virt.xs b/Virt.xs
index ed7c75b..e5d2293 100644
--- a/Virt.xs
+++ b/Virt.xs
@@ -158,6 +158,120 @@ _populate_constant_ull(HV *stash, const char *name, unsigned long long val)
 #define REGISTER_CONSTANT_STR(name, key) _populate_constant_str(stash, #key, name)
 #define REGISTER_CONSTANT_ULL(name, key) _populate_constant_ull(stash, #key, name)
 
+static HV *
+vir_typed_param_to_hv(virTypedParameter *params, int nparams)
+{
+    HV *ret = (HV *)sv_2mortal((SV*)newHV());
+    unsigned int i;
+    const char *field;
+    STRLEN val_length;
+
+    for (i = 0 ; i < nparams ; i++) {
+        SV *val = NULL;
+
+        switch (params[i].type) {
+        case VIR_TYPED_PARAM_INT:
+            val = newSViv(params[i].value.i);
+            break;
+
+        case VIR_TYPED_PARAM_UINT:
+            val = newSViv((int)params[i].value.ui);
+            break;
+
+        case VIR_TYPED_PARAM_LLONG:
+            val = virt_newSVll(params[i].value.l);
+            break;
+
+        case VIR_TYPED_PARAM_ULLONG:
+            val = virt_newSVull(params[i].value.ul);
+            break;
+
+        case VIR_TYPED_PARAM_DOUBLE:
+            val = newSVnv(params[i].value.d);
+            break;
+
+        case VIR_TYPED_PARAM_BOOLEAN:
+            val = newSViv(params[i].value.b);
+            break;
+
+        case VIR_TYPED_PARAM_STRING:
+            val_length = strlen(params[i].value.s);
+            val = newSVpv(params[i].value.s, val_length);
+            break;
+
+        }
+
+        field = params[i].field;
+        (void)hv_store(ret, field, strlen(params[i].field), val, 0);
+    }
+
+    return ret;
+}
+
+
+static int
+vir_typed_param_from_hv(HV *newparams, virTypedParameter *params, int nparams)
+{
+    unsigned int i;
+    char * ptr;
+    STRLEN len;
+
+    /* We only want to set parameters which we're actually changing
+     * so here we figure out which elements of 'params' we need to
+     * update, and overwrite the others
+     */
+    for (i = 0 ; i < nparams ;) {
+        if (!hv_exists(newparams, params[i].field, strlen(params[i].field))) {
+            if ((nparams-i) > 1)
+                memmove(params+i, params+i+1, sizeof(*params)*(nparams-(i+1)));
+            nparams--;
+            continue;
+        }
+
+        i++;
+    }
+
+    for (i = 0 ; i < nparams ; i++) {
+        SV **val;
+
+        val = hv_fetch (newparams, params[i].field, strlen(params[i].field), 0);
+
+        switch (params[i].type) {
+        case VIR_TYPED_PARAM_INT:
+            params[i].value.i = SvIV(*val);
+            break;
+
+        case VIR_TYPED_PARAM_UINT:
+            params[i].value.ui = SvIV(*val);
+            break;
+
+        case VIR_TYPED_PARAM_LLONG:
+            params[i].value.l = virt_SvIVll(*val);
+            break;
+
+        case VIR_TYPED_PARAM_ULLONG:
+            params[i].value.ul = virt_SvIVull(*val);
+            break;
+
+        case VIR_TYPED_PARAM_DOUBLE:
+            params[i].value.d = SvNV(*val);
+            break;
+
+        case VIR_TYPED_PARAM_BOOLEAN:
+            params[i].value.b = SvIV(*val);
+            break;
+
+        case VIR_TYPED_PARAM_STRING:
+            ptr = SvPV(*val, len);
+            params[i].value.s = (char *)ptr;
+            break;
+        }
+    }
+
+    return nparams;
+}
+
+
 static int
 _domain_event_lifecycle_callback(virConnectPtr con,
                                  virDomainPtr dom,
@@ -782,6 +896,49 @@ _domain_event_device_removed_callback(virConnectPtr con,
 
 
 static int
+_domain_event_tunable_callback(virConnectPtr con,
+			       virDomainPtr dom,
+			       virTypedParameterPtr params,
+			       size_t nparams,
+			       void *opaque)
+{
+    AV *data = opaque;
+    SV **self;
+    SV **cb;
+    HV *params_hv;
+    SV *domref;
+    dSP;
+
+    self = av_fetch(data, 0, 0);
+    cb = av_fetch(data, 1, 0);
+
+    SvREFCNT_inc(*self);
+
+    ENTER;
+    SAVETMPS;
+
+    PUSHMARK(SP);
+    XPUSHs(*self);
+    domref = sv_newmortal();
+    sv_setref_pv(domref, "Sys::Virt::Domain", (void*)dom);
+    virDomainRef(dom);
+
+    params_hv = vir_typed_param_to_hv(params, nparams);
+
+    XPUSHs(domref);
+    XPUSHs(newRV(( SV*)params_hv));
+    PUTBACK;
+
+    call_sv(*cb, G_DISCARD);
+
+    FREETMPS;
+    LEAVE;
+
+    return 0;
+}
+
+
+static int
 _network_event_lifecycle_callback(virConnectPtr con,
 				  virNetworkPtr net,
 				  int event,
@@ -1358,120 +1515,6 @@ _stream_recv_all_sink(virStreamPtr st,
 }
 
 
-static HV *
-vir_typed_param_to_hv(virTypedParameter *params, int nparams)
-{
-    HV *ret = (HV *)sv_2mortal((SV*)newHV());
-    unsigned int i;
-    const char *field;
-    STRLEN val_length;
-
-    for (i = 0 ; i < nparams ; i++) {
-        SV *val = NULL;
-
-        switch (params[i].type) {
-        case VIR_TYPED_PARAM_INT:
-            val = newSViv(params[i].value.i);
-            break;
-
-        case VIR_TYPED_PARAM_UINT:
-            val = newSViv((int)params[i].value.ui);
-            break;
-
-        case VIR_TYPED_PARAM_LLONG:
-            val = virt_newSVll(params[i].value.l);
-            break;
-
-        case VIR_TYPED_PARAM_ULLONG:
-            val = virt_newSVull(params[i].value.ul);
-            break;
-
-        case VIR_TYPED_PARAM_DOUBLE:
-            val = newSVnv(params[i].value.d);
-            break;
-
-        case VIR_TYPED_PARAM_BOOLEAN:
-            val = newSViv(params[i].value.b);
-            break;
-
-        case VIR_TYPED_PARAM_STRING:
-            val_length = strlen(params[i].value.s);
-            val = newSVpv(params[i].value.s, val_length);
-            break;
-
-        }
-
-        field = params[i].field;
-        (void)hv_store(ret, field, strlen(params[i].field), val, 0);
-    }
-
-    return ret;
-}
-
-
-static int
-vir_typed_param_from_hv(HV *newparams, virTypedParameter *params, int nparams)
-{
-    unsigned int i;
-    char * ptr;
-    STRLEN len;
-
-    /* We only want to set parameters which we're actually changing
-     * so here we figure out which elements of 'params' we need to
-     * update, and overwrite the others
-     */
-    for (i = 0 ; i < nparams ;) {
-        if (!hv_exists(newparams, params[i].field, strlen(params[i].field))) {
-            if ((nparams-i) > 1)
-                memmove(params+i, params+i+1, sizeof(*params)*(nparams-(i+1)));
-            nparams--;
-            continue;
-        }
-
-        i++;
-    }
-
-    for (i = 0 ; i < nparams ; i++) {
-        SV **val;
-
-        val = hv_fetch (newparams, params[i].field, strlen(params[i].field), 0);
-
-        switch (params[i].type) {
-        case VIR_TYPED_PARAM_INT:
-            params[i].value.i = SvIV(*val);
-            break;
-
-        case VIR_TYPED_PARAM_UINT:
-            params[i].value.ui = SvIV(*val);
-            break;
-
-        case VIR_TYPED_PARAM_LLONG:
-            params[i].value.l = virt_SvIVll(*val);
-            break;
-
-        case VIR_TYPED_PARAM_ULLONG:
-            params[i].value.ul = virt_SvIVull(*val);
-            break;
-
-        case VIR_TYPED_PARAM_DOUBLE:
-            params[i].value.d = SvNV(*val);
-            break;
-
-        case VIR_TYPED_PARAM_BOOLEAN:
-            params[i].value.b = SvIV(*val);
-            break;
-
-        case VIR_TYPED_PARAM_STRING:
-            ptr = SvPV(*val, len);
-            params[i].value.s = (char *)ptr;
-            break;
-        }
-    }
-
-    return nparams;
-}
-
-
 MODULE = Sys::Virt  PACKAGE = Sys::Virt
 
 PROTOTYPES: ENABLE
@@ -2821,6 +2864,9 @@ PREINIT:
       case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED:
           callback = VIR_DOMAIN_EVENT_CALLBACK(_domain_event_device_removed_callback);
           break;
+      case VIR_DOMAIN_EVENT_ID_TUNABLE:
+	  callback = VIR_DOMAIN_EVENT_CALLBACK(_domain_event_tunable_callback);
+	  break;
       default:
           callback = VIR_DOMAIN_EVENT_CALLBACK(_domain_event_generic_callback);
           break;
@@ -7288,6 +7334,7 @@ BOOT:
       REGISTER_CONSTANT(VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, EVENT_ID_TRAY_CHANGE);
       REGISTER_CONSTANT(VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE, EVENT_ID_BALLOON_CHANGE);
       REGISTER_CONSTANT(VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED, EVENT_ID_DEVICE_REMOVED);
+      REGISTER_CONSTANT(VIR_DOMAIN_EVENT_ID_TUNABLE, EVENT_ID_TUNABLE);
 
       REGISTER_CONSTANT(VIR_DOMAIN_EVENT_WATCHDOG_NONE, EVENT_WATCHDOG_NONE);
       REGISTER_CONSTANT(VIR_DOMAIN_EVENT_WATCHDOG_PAUSE, EVENT_WATCHDOG_PAUSE);
@@ -7522,6 +7569,21 @@ BOOT:
 
       REGISTER_CONSTANT(VIR_DOMAIN_TIME_SYNC, TIME_SYNC);
 
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES, TUNABLE_CPU_CPU_SHARES);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN, TUNABLE_CPU_EMULATORPIN);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_CPU_EMULATOR_PERIOD, TUNABLE_CPU_EMULATOR_PERIOD);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_CPU_EMULATOR_QUOTA, TUNABLE_CPU_EMULATOR_QUOTA);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_CPU_VCPUPIN, TUNABLE_CPU_VCPUPIN);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_CPU_VCPU_PERIOD, TUNABLE_CPU_VCPU_PERIOD);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_CPU_VCPU_QUOTA, TUNABLE_CPU_VCPU_QUOTA);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_BLKDEV_DISK, TUNABLE_BLKDEV_DISK);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_BLKDEV_READ_BYTES_SEC, TUNABLE_BLKDEV_READ_BYTES_SEC);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_BLKDEV_READ_IOPS_SEC, TUNABLE_BLKDEV_READ_IOPS_SEC);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_BYTES_SEC, TUNABLE_BLKDEV_TOTAL_BYTES_SEC);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_IOPS_SEC, TUNABLE_BLKDEV_TOTAL_IOPS_SEC);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_BYTES_SEC, TUNABLE_BLKDEV_WRITE_BYTES_SEC);
+      REGISTER_CONSTANT_STR(VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_IOPS_SEC, TUNABLE_BLKDEV_WRITE_IOPS_SEC);
+
       stash = gv_stashpv( "Sys::Virt::DomainSnapshot", TRUE );
       REGISTER_CONSTANT(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, DELETE_CHILDREN);
       REGISTER_CONSTANT(VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY, DELETE_METADATA_ONLY);
diff --git a/lib/Sys/Virt/Domain.pm b/lib/Sys/Virt/Domain.pm
index dd7d19d..67bbe52 100644
--- a/lib/Sys/Virt/Domain.pm
+++ b/lib/Sys/Virt/Domain.pm
@@ -2556,6 +2556,13 @@ Balloon target changes
 
 Asynchronous guest device removal
 
+=item Sys::Virt::Domain::EVENT_ID_TUNABLE
+
+Changes of any domain tuning parameters. The callback
+will be provided with a hash listing all changed parameters.
+The later DOMAIN TUNABLE constants can be useful when accessing
+the hash keys
+
 =back
 
 =head2 IO ERROR EVENT CONSTANTS
@@ -3532,6 +3539,71 @@ SIGRT32
 
 =back
 
+=head2 DOMAIN TUNABLE CONSTANTS
+
+The following constants are useful when accessing domain
+tuning parameters in APIs and events
+
+=over 4
+
+=item Sys::Virt::Domain::TUNABLE_CPU_CPU_SHARES
+
+Proportional CPU weight
+
+=item Sys::Virt::Domain::TUNABLE_CPU_EMULATORPIN
+
+Emulator thread CPU pinning mask
+
+=item Sys::Virt::Domain::TUNABLE_CPU_EMULATOR_PERIOD
+
+Emulator thread CPU period
+
+=item Sys::Virt::Domain::TUNABLE_CPU_EMULATOR_QUOTA
+
+Emulator thread CPU quota
+
+=item Sys::Virt::Domain::TUNABLE_CPU_VCPUPIN
+
+VCPU thread pinning mask
+
+=item Sys::Virt::Domain::TUNABLE_CPU_VCPU_PERIOD
+
+VCPU thread period
+
+=item Sys::Virt::Domain::TUNABLE_CPU_VCPU_QUOTA
+
+VCPU thread quota
+
+=item Sys::Virt::Domain::TUNABLE_BLKDEV_DISK
+
+The name of guest disks
+
+=item Sys::Virt::Domain::TUNABLE_BLKDEV_READ_BYTES_SEC
+
+Read throughput in bytes per sec
+
+=item Sys::Virt::Domain::TUNABLE_BLKDEV_READ_IOPS_SEC
+
+Read throughput in I/O operations per sec
+
+=item Sys::Virt::Domain::TUNABLE_BLKDEV_TOTAL_BYTES_SEC
+
+Total throughput in bytes per sec
+
+=item Sys::Virt::Domain::TUNABLE_BLKDEV_TOTAL_IOPS_SEC
+
+Total throughput in I/O operations per sec
+
+=item Sys::Virt::Domain::TUNABLE_BLKDEV_WRITE_BYTES_SEC
+
+Write throughput in bytes per sec
+
+=item Sys::Virt::Domain::TUNABLE_BLKDEV_WRITE_IOPS_SEC
+
+Write throughput in I/O operations per sec
+
+=back
+
 =head1 AUTHORS
 
 Daniel P. Berrange <berrange@redhat.com>
diff --git a/t/030-api-coverage.t b/t/030-api-coverage.t
index 34b8d4d..6d8bd53 100644
--- a/t/030-api-coverage.t
+++ b/t/030-api-coverage.t
@@ -88,6 +88,7 @@ virConnectDomainEventPMWakeupCallback
 virConnectDomainEventTrayChangeCallback
 virConnectDomainEventBalloonChangeCallback
 virConnectDomainEventDeviceRemovedCallback
+virConnectDomainEventTunableCallback
 
 virConnectNetworkEventLifecycleCallback