diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 86be86ffaef096a58ca029568937b39434fbca65..898f8b5af79e96ca632088c08f7d4b6314a91d01 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -5203,6 +5203,66 @@ typedef void (*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn, const char *devAlias, void *opaque); +/** + * VIR_DOMAIN_EVENT_CPUTUNE_VCPUPIN: + * + * Macro represents formatted pinning for one vcpu specified by id which is + * appended to the parameter name, for example "cputune.vcpupin1", + * as VIR_TYPED_PARAM_STRING. + */ +#define VIR_DOMAIN_EVENT_CPUTUNE_VCPUPIN "cputune.vcpupin%u" + +/** + * VIR_DOMAIN_EVENT_CPUTUNE_EMULATORIN: + * + * Macro represents formatted pinning for emulator process, + * as VIR_TYPED_PARAM_STRING. + */ +#define VIR_DOMAIN_EVENT_CPUTUNE_EMULATORIN "cputune.emulatorpin" + +/** + * VIR_DOMAIN_EVENT_CPUTUNE_CPU_SHARES: + * + * Macro represents proportional weight of the scheduler used on the + * host cpu, when using the posix scheduler, as VIR_TYPED_PARAM_ULLONG. + */ +#define VIR_DOMAIN_EVENT_CPUTUNE_CPU_SHARES "cputune.cpu_shares" + +/** + * VIR_DOMAIN_EVENT_CPUTUNE_VCPU_PERIOD: + * + * Macro represents the enforcement period for a quota, in microseconds, + * for vcpus only, when using the posix scheduler, as VIR_TYPED_PARAM_ULLONG. + */ +#define VIR_DOMAIN_EVENT_CPUTUNE_VCPU_PERIOD "cputune.vcpu_period" + +/** + * VIR_DOMAIN_EVENT_CPUTUNE_VCPU_QUOTA: + * + * Macro represents the maximum bandwidth to be used within a period for + * vcpus only, when using the posix scheduler, as VIR_TYPED_PARAM_LLONG. + */ +#define VIR_DOMAIN_EVENT_CPUTUNE_VCPU_QUOTA "cputune.vcpu_quota" + +/** + * VIR_DOMAIN_EVENT_CPUTUNE_EMULATOR_PERIOD: + * + * Macro represents the enforcement period for a quota in microseconds, + * when using the posix scheduler, for all emulator activity not tied to + * vcpus, as VIR_TYPED_PARAM_ULLONG. + */ +#define VIR_DOMAIN_EVENT_CPUTUNE_EMULATOR_PERIOD "cputune.emulator_period" + +/** + * VIR_DOMAIN_EVENT_CPUTUNE_EMULATOR_QUOTA: + * + * Macro represents the maximum bandwidth to be used within a period for + * all emulator activity not tied to vcpus, when using the posix scheduler, + * as an VIR_TYPED_PARAM_LLONG. + */ +#define VIR_DOMAIN_EVENT_CPUTUNE_EMULATOR_QUOTA "cputune.emulator_quota" + + /** * virConnectDomainEventTunableCallback: * @conn: connection object @@ -5215,6 +5275,9 @@ typedef void (*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn, * be freed in the callback handler as it's done internally after the callback * handler is executed. * + * Currently supported name spaces: + * "cputune.*" + * * The callback signature to use when registering for an event of type * VIR_DOMAIN_EVENT_ID_TUNABLE with virConnectDomainEventRegisterAny() */ diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 7c6b2c16c6e314c85f8501980e8fba752ffab7bd..300946a6fefb95dd88ae0e384139f61db0ca0564 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -34,6 +34,7 @@ #include "virscsi.h" #include "virstring.h" #include "virfile.h" +#include "virtypedparam.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -676,6 +677,10 @@ static int qemuSetupCpuCgroup(virDomainObjPtr vm) { qemuDomainObjPrivatePtr priv = vm->privateData; + virObjectEventPtr event = NULL; + virTypedParameterPtr eventParams = NULL; + int eventNparams = 0; + int eventMaxparams = 0; if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) { if (vm->def->cputune.sharesSpecified) { @@ -694,7 +699,19 @@ qemuSetupCpuCgroup(virDomainObjPtr vm) if (virCgroupGetCpuShares(priv->cgroup, &val) < 0) return -1; - vm->def->cputune.shares = val; + if (vm->def->cputune.shares != val) { + vm->def->cputune.shares = val; + if (virTypedParamsAddULLong(&eventParams, &eventNparams, + &eventMaxparams, + VIR_DOMAIN_EVENT_CPUTUNE_CPU_SHARES, + val) < 0) + return -1; + + event = virDomainEventTunableNewFromObj(vm, eventParams, eventNparams); + } + + if (event) + qemuDomainEventQueue(vm->privateData, event); } return 0; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e73d4f91789ff050dd5db93bdd9bfee9b86f30b1..d1a0657a6ead113c818307b0c81da7ad50aba0ff 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4538,6 +4538,12 @@ qemuDomainPinVcpuFlags(virDomainPtr dom, virBitmapPtr pcpumap = NULL; virQEMUDriverConfigPtr cfg = NULL; virCapsPtr caps = NULL; + virObjectEventPtr event = NULL; + char paramField[VIR_TYPED_PARAM_FIELD_LENGTH] = ""; + char *str = NULL; + virTypedParameterPtr eventParams = NULL; + int eventNparams = 0; + int eventMaxparams = 0; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -4645,6 +4651,18 @@ qemuDomainPinVcpuFlags(virDomainPtr dom, if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) goto cleanup; + + if (snprintf(paramField, VIR_TYPED_PARAM_FIELD_LENGTH, + VIR_DOMAIN_EVENT_CPUTUNE_VCPUPIN, vcpu) < 0) { + goto cleanup; + } + + str = virBitmapFormat(pcpumap); + if (virTypedParamsAddString(&eventParams, &eventNparams, + &eventMaxparams, paramField, str) < 0) + goto cleanup; + + event = virDomainEventTunableNewFromDom(dom, eventParams, eventNparams); } if (flags & VIR_DOMAIN_AFFECT_CONFIG) { @@ -4680,6 +4698,9 @@ qemuDomainPinVcpuFlags(virDomainPtr dom, virCgroupFree(&cgroup_vcpu); if (vm) virObjectUnlock(vm); + if (event) + qemuDomainEventQueue(driver, event); + VIR_FREE(str); virBitmapFree(pcpumap); virObjectUnref(caps); virObjectUnref(cfg); @@ -4804,6 +4825,12 @@ qemuDomainPinEmulator(virDomainPtr dom, virBitmapPtr pcpumap = NULL; virQEMUDriverConfigPtr cfg = NULL; virCapsPtr caps = NULL; + virObjectEventPtr event = NULL; + char * str = NULL; + virTypedParameterPtr eventParams = NULL; + int eventNparams = 0; + int eventMaxparams = 0; + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -4909,6 +4936,15 @@ qemuDomainPinEmulator(virDomainPtr dom, if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) goto cleanup; + + str = virBitmapFormat(pcpumap); + if (virTypedParamsAddString(&eventParams, &eventNparams, + &eventMaxparams, + VIR_DOMAIN_EVENT_CPUTUNE_EMULATORIN, + str) < 0) + goto cleanup; + + event = virDomainEventTunableNewFromDom(dom, eventParams, eventNparams); } if (flags & VIR_DOMAIN_AFFECT_CONFIG) { @@ -4938,6 +4974,9 @@ qemuDomainPinEmulator(virDomainPtr dom, cleanup: if (cgroup_emulator) virCgroupFree(&cgroup_emulator); + if (event) + qemuDomainEventQueue(driver, event); + VIR_FREE(str); virBitmapFree(pcpumap); virObjectUnref(caps); if (vm) @@ -9202,6 +9241,10 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, virQEMUDriverConfigPtr cfg = NULL; virCapsPtr caps = NULL; qemuDomainObjPrivatePtr priv; + virObjectEventPtr event = NULL; + virTypedParameterPtr eventParams = NULL; + int eventNparams = 0; + int eventMaxNparams = 0; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -9272,6 +9315,12 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, vm->def->cputune.shares = val; vm->def->cputune.sharesSpecified = true; + + if (virTypedParamsAddULLong(&eventParams, &eventNparams, + &eventMaxNparams, + VIR_DOMAIN_EVENT_CPUTUNE_CPU_SHARES, + val) < 0) + goto cleanup; } if (flags & VIR_DOMAIN_AFFECT_CONFIG) { @@ -9289,6 +9338,12 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, goto cleanup; vm->def->cputune.period = value_ul; + + if (virTypedParamsAddULLong(&eventParams, &eventNparams, + &eventMaxNparams, + VIR_DOMAIN_EVENT_CPUTUNE_VCPU_PERIOD, + value_ul) < 0) + goto cleanup; } if (flags & VIR_DOMAIN_AFFECT_CONFIG) @@ -9303,6 +9358,12 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, goto cleanup; vm->def->cputune.quota = value_l; + + if (virTypedParamsAddLLong(&eventParams, &eventNparams, + &eventMaxNparams, + VIR_DOMAIN_EVENT_CPUTUNE_VCPU_QUOTA, + value_l) < 0) + goto cleanup; } if (flags & VIR_DOMAIN_AFFECT_CONFIG) @@ -9318,6 +9379,12 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, goto cleanup; vm->def->cputune.emulator_period = value_ul; + + if (virTypedParamsAddULLong(&eventParams, &eventNparams, + &eventMaxNparams, + VIR_DOMAIN_EVENT_CPUTUNE_EMULATOR_PERIOD, + value_ul) < 0) + goto cleanup; } if (flags & VIR_DOMAIN_AFFECT_CONFIG) @@ -9333,6 +9400,12 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, goto cleanup; vm->def->cputune.emulator_quota = value_l; + + if (virTypedParamsAddLLong(&eventParams, &eventNparams, + &eventMaxNparams, + VIR_DOMAIN_EVENT_CPUTUNE_EMULATOR_QUOTA, + value_l) < 0) + goto cleanup; } if (flags & VIR_DOMAIN_AFFECT_CONFIG) @@ -9343,6 +9416,12 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) goto cleanup; + if (eventNparams) { + event = virDomainEventTunableNewFromDom(dom, eventParams, eventNparams); + eventNparams = 0; + if (event) + qemuDomainEventQueue(driver, event); + } if (flags & VIR_DOMAIN_AFFECT_CONFIG) { rc = virDomainSaveConfig(cfg->configDir, vmdef); @@ -9359,6 +9438,8 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, virDomainDefFree(vmdef); if (vm) virObjectUnlock(vm); + if (eventNparams) + virTypedParamsFree(eventParams, eventNparams); virObjectUnref(caps); virObjectUnref(cfg); return ret;