Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
daemon/remote.c | 87 +++++++++++++++++++++++++++++++
include/libvirt/libvirt.h.in | 62 ++++++++++++++++++++++
src/conf/domain_event.c | 120 +++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_event.h | 7 +++
src/libvirt_private.syms | 2 +
src/remote/remote_driver.c | 110 +++++++++++++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 39 +++++++++++++-
src/remote_protocol-structs | 32 ++++++++++++
tools/virsh-domain.c | 49 ++++++++++++++++++
9 files changed, 507 insertions(+), 1 deletion(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 89714ca..ae42c4d 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -969,6 +969,92 @@ remoteRelayDomainEventBlockJob2(virConnectPtr conn,
}
+static int
+remoteRelayDomainEventCputune(virConnectPtr conn,
+ virDomainPtr dom,
+ virDomainCputuneInfoPtr cputune,
+ void *opaque)
+{
+ daemonClientEventCallbackPtr callback = opaque;
+ remote_domain_event_cputune_msg data;
+ size_t i;
+
+ 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));
+ make_nonnull_domain(&data.dom, dom);
+
+ data.shares = cputune->shares;
+ data.sharesSpecified = cputune->sharesSpecified;
+ data.period = cputune->period;
+ data.quota = cputune->quota;
+ data.emulatorPeriod = cputune->emulatorPeriod;
+ data.emulatorQuota = cputune->emulatorQuota;
+ data.nvcpupin = cputune->nvcpupin;
+
+ if (cputune->emulatorpin.map) {
+ if (VIR_ALLOC_N(data.emulatorpin.map.map_val,
+ cputune->emulatorpin.mapLen) < 0)
+ goto error;
+ memcpy(data.emulatorpin.map.map_val, cputune->emulatorpin.map,
+ cputune->emulatorpin.mapLen);
+ data.emulatorpin.map.map_len = cputune->emulatorpin.mapLen;
+ data.emulatorpin.mapLen = cputune->emulatorpin.mapLen;
+ }
+ if (cputune->vcpupin) {
+ if (VIR_ALLOC_N(data.vcpupin.vcpupin_val, data.nvcpupin) < 0)
+ goto error;
+ data.vcpupin.vcpupin_len = data.nvcpupin;
+
+ for (i = 0; i < data.nvcpupin; i++) {
+ data.vcpupin.vcpupin_val[i].vcpuid = cputune->vcpupin[i].vcpuid;
+ if (VIR_ALLOC_N(data.vcpupin.vcpupin_val[i].cpumask.map.map_val,
+ cputune->vcpupin[i].cpumask.mapLen) < 0)
+ goto error;
+ memcpy(data.vcpupin.vcpupin_val[i].cpumask.map.map_val,
+ cputune->vcpupin[i].cpumask.map,
+ cputune->vcpupin[i].cpumask.mapLen);
+ data.vcpupin.vcpupin_val[i].cpumask.map.map_len =
+ cputune->vcpupin[i].cpumask.mapLen;
+ data.vcpupin.vcpupin_val[i].cpumask.mapLen =
+ cputune->vcpupin[i].cpumask.mapLen;
+ }
+ }
+
+ if (callback->legacy) {
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
+ REMOTE_PROC_DOMAIN_EVENT_CPUTUNE,
+ (xdrproc_t)xdr_remote_domain_event_cputune_msg,
+ &data);
+ } else {
+ remote_domain_event_callback_cputune_msg msg = { callback->callbackID,
+ data };
+
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
+ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CPUTUNE,
+
(xdrproc_t)xdr_remote_domain_event_callback_cputune_msg,
+ &msg);
+ }
+
+ return 0;
+
+ error:
+ VIR_FREE(data.emulatorpin.map.map_val);
+ if (data.vcpupin.vcpupin_val) {
+ for (i = 0; i < data.nvcpupin; i++)
+ VIR_FREE(data.vcpupin.vcpupin_val[i].cpumask.map.map_val);
+ VIR_FREE(data.vcpupin.vcpupin_val);
+ }
+ return -1;
+}
+
+
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
@@ -987,6 +1073,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 9358314..636b89b 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -5127,7 +5127,68 @@ typedef void
(*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *devAlias,
void *opaque);
+/**
+ * _virDomainCpumaksInfo
+ *
+ * This structure stores a mask with pinning information for emulator
+ * or vcpus.
+ */
+struct _virDomainCpumaskInfo {
+ int mapLen;
+ unsigned char *map;
+};
+typedef struct _virDomainCpumaskInfo virDomainCpumaskInfo;
+typedef virDomainCpumaskInfo *virDomainCpumaskInfoPtr;
+
+/**
+ * _virDomainVcpupinInfo
+ *
+ * This structure stores cpumask with pinning information
+ * for each vcpu where the pinning has been set.
+ */
+struct _virDomainVcpupinInfo {
+ int vcpuid;
+ virDomainCpumaskInfo cpumask;
+};
+typedef struct _virDomainVcpupinInfo virDomainVcpupinInfo;
+typedef virDomainVcpupinInfo *virDomainVcpupinInfoPtr;
+
+/**
+ * _virDomainCputuneInfo
+ *
+ * Structure containing all infromation about cputune for
+ * specific domain.
+ */
+struct _virDomainCputuneInfo {
+ unsigned long long shares;
+ int sharesSpecified;
+ unsigned long long period;
+ long long quota;
+ unsigned long long emulatorPeriod;
+ long long emulatorQuota;
+ size_t nvcpupin;
+ virDomainVcpupinInfoPtr vcpupin;
+ virDomainCpumaskInfo emulatorpin;
+};
+typedef struct _virDomainCputuneInfo virDomainCputuneInfo;
+typedef virDomainCputuneInfo *virDomainCputuneInfoPtr;
+/**
+ * virConnectDomainEventCputuneCallback:
+ * @conn: connection object
+ * @dom: domain on which the event occurred
+ * @cputune: cputune informations
+ * @opaque: application specified data
+ *
+ * This callback occurs when cpu tune is updated.
+ *
+ * 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,
+ virDomainCputuneInfoPtr cputune,
+ void *opaque);
/**
* VIR_DOMAIN_EVENT_CALLBACK:
@@ -5163,6 +5224,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..966562f 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -52,6 +52,7 @@ static virClassPtr virDomainEventBalloonChangeClass;
static virClassPtr virDomainEventDeviceRemovedClass;
static virClassPtr virDomainEventPMClass;
static virClassPtr virDomainQemuMonitorEventClass;
+static virClassPtr virDomainEventCputuneClass;
static void virDomainEventDispose(void *obj);
@@ -67,6 +68,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 +205,14 @@ struct _virDomainQemuMonitorEvent {
typedef struct _virDomainQemuMonitorEvent virDomainQemuMonitorEvent;
typedef virDomainQemuMonitorEvent *virDomainQemuMonitorEventPtr;
+struct _virDomainEventCputune {
+ virDomainEvent parent;
+
+ virDomainCputuneInfo cputune;
+};
+typedef struct _virDomainEventCputune virDomainEventCputune;
+typedef virDomainEventCputune *virDomainEventCputunePtr;
+
static int
virDomainEventsOnceInit(void)
@@ -285,6 +295,12 @@ virDomainEventsOnceInit(void)
sizeof(virDomainQemuMonitorEvent),
virDomainQemuMonitorEventDispose)))
return -1;
+ if (!(virDomainEventCputuneClass =
+ virClassNew(virDomainEventClass,
+ "virDomainEventCputune",
+ sizeof(virDomainEventCputune),
+ virDomainEventCputuneDispose)))
+ return -1;
return 0;
}
@@ -420,6 +436,22 @@ virDomainQemuMonitorEventDispose(void *obj)
VIR_FREE(event->details);
}
+static void
+virDomainEventCputuneDispose(void *obj)
+{
+ virDomainEventCputunePtr event = obj;
+ VIR_DEBUG("obj=%p", event);
+
+ VIR_FREE(event->cputune.emulatorpin.map);
+ if (event->cputune.vcpupin) {
+ size_t i;
+ for (i = 0; i < event->cputune.nvcpupin; i++) {
+ VIR_FREE(event->cputune.vcpupin[i].cpumask.map);
+ }
+ VIR_FREE(event->cputune.vcpupin);
+ }
+}
+
static void *
virDomainEventNew(virClassPtr klass,
@@ -1175,6 +1207,84 @@ virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
devAlias);
}
+static virObjectEventPtr
+virDomainEventCputuneNew(int id,
+ const char *name,
+ unsigned char *uuid,
+ virDomainCputune cputune)
+{
+ virDomainEventCputunePtr ev;
+ size_t i;
+
+ if (virDomainEventsInitialize() < 0)
+ return NULL;
+
+ if (!(ev = virDomainEventNew(virDomainEventCputuneClass,
+ VIR_DOMAIN_EVENT_ID_CPUTUNE,
+ id, name, uuid)))
+ return NULL;
+
+ ev->cputune.shares = cputune.shares;
+ ev->cputune.sharesSpecified = cputune.sharesSpecified;
+ ev->cputune.period = cputune.period;
+ ev->cputune.quota = cputune.quota;
+ ev->cputune.emulatorPeriod = cputune.emulator_period;
+ ev->cputune.emulatorQuota = cputune.emulator_quota;
+ ev->cputune.nvcpupin = cputune.nvcpupin;
+ ev->cputune.vcpupin = NULL;
+
+ if (cputune.emulatorpin) {
+ if (virBitmapToData(cputune.emulatorpin->cpumask,
+ &ev->cputune.emulatorpin.map,
+ &ev->cputune.emulatorpin.mapLen) < 0)
+ goto error;
+ }
+
+ if (cputune.vcpupin) {
+ if (VIR_ALLOC_N(ev->cputune.vcpupin, ev->cputune.nvcpupin) < 0)
+ goto error;
+ for (i = 0; i < ev->cputune.nvcpupin; i++) {
+ ev->cputune.vcpupin[i].vcpuid = cputune.vcpupin[i]->vcpuid;
+ if (virBitmapToData(cputune.vcpupin[i]->cpumask,
+ &ev->cputune.vcpupin[i].cpumask.map,
+ &ev->cputune.vcpupin[i].cpumask.mapLen) < 0)
+ goto error;
+ }
+ }
+
+ return (virObjectEventPtr)ev;
+
+ error:
+ VIR_FREE(ev->cputune.emulatorpin.map);
+ if (ev->cputune.vcpupin) {
+ for (i = 0; i < ev->cputune.nvcpupin; i++)
+ VIR_FREE(ev->cputune.vcpupin[i].cpumask.map);
+ VIR_FREE(ev->cputune.vcpupin);
+ }
+ virObjectUnref(ev);
+
+ return NULL;
+}
+
+virObjectEventPtr
+virDomainEventCputuneNewFromObj(virDomainObjPtr obj,
+ virDomainCputune cputune)
+{
+ return virDomainEventCputuneNew(obj->def->id,
+ obj->def->name,
+ obj->def->uuid,
+ cputune);
+}
+
+virObjectEventPtr
+virDomainEventCputuneNewFromDom(virDomainPtr dom,
+ virDomainCputune cputune)
+{
+ return virDomainEventCputuneNew(dom->id,
+ dom->name,
+ dom->uuid,
+ cputune);
+}
static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
@@ -1366,6 +1476,16 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
goto cleanup;
}
+ case VIR_DOMAIN_EVENT_ID_CPUTUNE:
+ {
+ virDomainEventCputunePtr cputuneEvent;
+ cputuneEvent = (virDomainEventCputunePtr)event;
+ ((virConnectDomainEventCputuneCallback)cb)(conn, dom,
+ &cputuneEvent->cputune,
+ 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..44c6a7b 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -184,6 +184,13 @@ virDomainEventDeviceRemovedNewFromObj(virDomainObjPtr obj,
virObjectEventPtr
virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
const char *devAlias);
+virObjectEventPtr
+virDomainEventCputuneNewFromObj(virDomainObjPtr obj,
+ virDomainCputune cputune);
+virObjectEventPtr
+virDomainEventCputuneNewFromDom(virDomainPtr dom,
+ virDomainCputune cputune);
+
int
virDomainEventStateRegister(virConnectPtr conn,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 71fc063..74a5487 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -439,6 +439,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 fda27f7..ba8a738 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -326,6 +326,16 @@ remoteDomainBuildEventBlockJob2(virNetClientProgramPtr prog,
void *evdata, void *opaque);
static void
+remoteDomainBuildEventCputune(virNetClientProgramPtr prog,
+ virNetClientPtr client,
+ 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);
@@ -395,6 +405,10 @@ static virNetClientProgramEvent remoteEvents[] = {
remoteDomainBuildEventDeviceRemoved,
sizeof(remote_domain_event_device_removed_msg),
(xdrproc_t)xdr_remote_domain_event_device_removed_msg },
+ { REMOTE_PROC_DOMAIN_EVENT_CPUTUNE,
+ remoteDomainBuildEventCputune,
+ sizeof(remote_domain_event_cputune_msg),
+ (xdrproc_t)xdr_remote_domain_event_cputune_msg },
/* All events above here are legacy events, missing the callback
* ID, which means the server has a single global registration and
* we do full filtering in the client. If the server lacks
@@ -476,6 +490,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 +5518,98 @@ remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgramPtr
prog ATTRIBUT
static void
+remoteDomainBuildEventCputuneHelper(virConnectPtr conn,
+ remote_domain_event_cputune_msg *msg,
+ int callbackID)
+{
+ struct private_data *priv = conn->privateData;
+ virDomainPtr dom;
+ virDomainCputune cputune;
+ virObjectEventPtr event = NULL;
+ size_t i;
+
+ dom = get_nonnull_domain(conn, msg->dom);
+ if (!dom)
+ return;
+
+ memset(&cputune, 0, sizeof(cputune));
+
+ cputune.shares = msg->shares;
+ cputune.sharesSpecified = msg->sharesSpecified;
+ cputune.period = msg->period;
+ cputune.quota = msg->quota;
+ cputune.emulator_period = msg->emulatorPeriod;
+ cputune.emulator_quota = msg->emulatorQuota;
+ cputune.nvcpupin = msg->nvcpupin;
+
+ if (msg->nvcpupin != msg->vcpupin.vcpupin_len)
+ goto cleanup;
+
+ if (msg->emulatorpin.map.map_val) {
+ if (VIR_ALLOC(cputune.emulatorpin) < 0)
+ goto cleanup;
+ cputune.emulatorpin->cpumask =
virBitmapNewData(msg->emulatorpin.map.map_val,
+
msg->emulatorpin.map.map_len);
+ if (!cputune.emulatorpin->cpumask)
+ goto cleanup;
+ }
+
+ if (msg->vcpupin.vcpupin_val) {
+ if (VIR_ALLOC_N(cputune.vcpupin, cputune.nvcpupin) < 0)
+ goto cleanup;
+
+ for (i = 0; i < cputune.nvcpupin; i++) {
+ if (VIR_ALLOC(cputune.vcpupin[i]) < 0)
+ goto cleanup;
+ cputune.vcpupin[i]->vcpuid = msg->vcpupin.vcpupin_val[i].vcpuid;
+ cputune.vcpupin[i]->cpumask =
virBitmapNewData(msg->vcpupin.vcpupin_val[i].cpumask.map.map_val,
+
msg->vcpupin.vcpupin_val[i].cpumask.map.map_len);
+ if (!cputune.vcpupin[i]->cpumask)
+ goto cleanup;
+ }
+ }
+
+ event = virDomainEventCputuneNewFromDom(dom, cputune);
+
+ remoteEventQueue(priv, event, callbackID);
+
+ cleanup:
+ virDomainFree(dom);
+ if (cputune.emulatorpin) {
+ virBitmapFree(cputune.emulatorpin->cpumask);
+ VIR_FREE(cputune.emulatorpin);
+ }
+ if (cputune.vcpupin) {
+ for (i = 0; i < cputune.nvcpupin; i++) {
+ if (cputune.vcpupin[i]) {
+ virBitmapFree(cputune.vcpupin[i]->cpumask);
+ VIR_FREE(cputune.vcpupin[i]);
+ }
+ }
+ VIR_FREE(cputune.vcpupin);
+ }
+}
+static void
+remoteDomainBuildEventCputune(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
+ virNetClientPtr client ATTRIBUTE_UNUSED,
+ void *evdata, void *opaque)
+{
+ virConnectPtr conn = opaque;
+ remote_domain_event_cputune_msg *msg = evdata;
+ remoteDomainBuildEventCputuneHelper(conn, msg, -1);
+}
+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;
+ remoteDomainBuildEventCputuneHelper(conn, &msg->msg, 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 8fc552f..5c2d8f5 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2980,6 +2980,31 @@ struct remote_domain_event_block_job_2_msg {
int status;
};
+struct remote_domain_cpumask {
+ int mapLen;
+ unsigned char map<REMOTE_CPUMAP_MAX>;
+};
+struct remote_domain_vcpupin {
+ int vcpuid;
+ remote_domain_cpumask cpumask;
+};
+struct remote_domain_event_cputune_msg {
+ remote_nonnull_domain dom;
+ unsigned hyper shares;
+ int sharesSpecified;
+ unsigned hyper period;
+ hyper quota;
+ unsigned hyper emulatorPeriod;
+ hyper emulatorQuota;
+ unsigned int nvcpupin;
+ remote_domain_vcpupin vcpupin<REMOTE_VCPUINFO_MAX>;
+ remote_domain_cpumask emulatorpin;
+};
+struct remote_domain_event_callback_cputune_msg {
+ int callbackID;
+ remote_domain_event_cputune_msg msg;
+};
+
struct remote_connect_get_cpu_model_names_args {
remote_nonnull_string arch;
int need_results;
@@ -5456,5 +5481,17 @@ enum remote_procedure {
* @acl: connect:search_domains
* @aclfilter: domain:read
*/
- REMOTE_PROC_CONNECT_GET_ALL_DOMAIN_STATS = 344
+ REMOTE_PROC_CONNECT_GET_ALL_DOMAIN_STATS = 344,
+
+ /**
+ * @generate: both
+ * @acl: none
+ */
+ REMOTE_PROC_DOMAIN_EVENT_CPUTUNE = 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 899f1cc..8dacdd5 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2435,6 +2435,36 @@ struct remote_domain_event_block_job_2_msg {
int type;
int status;
};
+struct remote_domain_cpumask {
+ int mapLen;
+ struct {
+ u_int map_len;
+ u_char * map_val;
+ } map;
+};
+struct remote_domain_vcpupin {
+ int vcpuid;
+ remote_domain_cpumask cpumask;
+};
+struct remote_domain_event_cputune_msg {
+ remote_nonnull_domain dom;
+ uint64_t shares;
+ int sharesSpecified;
+ uint64_t period;
+ int64_t quota;
+ uint64_t emulatorPeriod;
+ int64_t emulatorQuota;
+ u_int nvcpupin;
+ struct {
+ u_int vcpupin_len;
+ remote_domain_vcpupin * vcpupin_val;
+ } vcpupin;
+ remote_domain_cpumask emulatorpin;
+};
+struct remote_domain_event_callback_cputune_msg {
+ int callbackID;
+ remote_domain_event_cputune_msg msg;
+};
struct remote_connect_get_cpu_model_names_args {
remote_nonnull_string arch;
int need_results;
@@ -2890,4 +2920,6 @@ enum remote_procedure {
REMOTE_PROC_CONNECT_GET_DOMAIN_CAPABILITIES = 342,
REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD = 343,
REMOTE_PROC_CONNECT_GET_ALL_DOMAIN_STATS = 344,
+ REMOTE_PROC_DOMAIN_EVENT_CPUTUNE = 345,
+ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CPUTUNE = 346,
};
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index c75cd73..d2d2d96 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -11170,6 +11170,53 @@ vshEventDeviceRemovedPrint(virConnectPtr conn ATTRIBUTE_UNUSED,
vshEventDone(data->ctl);
}
+static void
+vshEventCputunePrint(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ virDomainCputuneInfoPtr cputune,
+ void *opaque)
+{
+ vshDomEventData *data = opaque;
+
+ if (!data->loop && *data->count)
+ return;
+
+ vshPrint(data->ctl,
+ _("event 'cpu-tune' for domain %s:\n"),
+ virDomainGetName(dom));
+ if (cputune->sharesSpecified) {
+ vshPrint(data->ctl, _("\tshares: %llu\n"), cputune->shares);
+ } else {
+ vshPrint(data->ctl, _("\tshares: not specified\n"));
+ }
+ vshPrint(data->ctl, _("\tperiod: %llu\n\tquota: %lld\n"),
+ cputune->period, cputune->quota);
+ vshPrint(data->ctl,
+ _("\temulator_period: %llu\n\temulator_quota: %lld\n"),
+ cputune->emulatorPeriod, cputune->emulatorQuota);
+ if (cputune->emulatorpin.map) {
+ char *str = virBitmapDataToString(cputune->emulatorpin.map,
+ cputune->emulatorpin.mapLen);
+ vshPrint(data->ctl, _("\temulatorpin: %s\n"), str);
+ VIR_FREE(str);
+ }
+
+ if (cputune->vcpupin) {
+ size_t i;
+ for (i = 0; i < cputune->nvcpupin; i++) {
+ char *str = virBitmapDataToString(cputune->vcpupin[i].cpumask.map,
+ cputune->vcpupin[i].cpumask.mapLen);
+ vshPrint(data->ctl, _("\tvcpupin (vcpuid: %d): %s\n"),
+ cputune->vcpupin[i].vcpuid, str);
+ VIR_FREE(str);
+ }
+ }
+
+ (*data->count)++;
+ if (!data->loop)
+ vshEventDone(data->ctl);
+}
+
static vshEventCallback vshEventCallbacks[] = {
{ "lifecycle",
VIR_DOMAIN_EVENT_CALLBACK(vshEventLifecyclePrint), },
@@ -11203,6 +11250,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