vircgroup: enforce range limit for cpu.shares

Before the conversion to using systemd DBus API to set the cpu.shares
there was some magic conversion done by kernel which was documented in
virsh manpage as well. Now systemd errors out if the value is out of
range.

Since we enforce the range for other cpu cgroup attributes 'quota' and
'period' it makes sense to do the same for 'shares' as well.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Pavel Hrdina 2021-03-03 14:10:15 +01:00
parent b5abf9a192
commit 1d9d9961ad
6 changed files with 35 additions and 5 deletions

View File

@ -742,7 +742,8 @@ CPU Tuning
the domain. If this is omitted, it defaults to the OS provided defaults. NB,
There is no unit for the value, it's a relative measure based on the setting
of other VM, e.g. A VM configured with value 2048 will get twice as much CPU
time as a VM configured with value 1024. :since:`Since 0.9.0`
time as a VM configured with value 1024. The value should be in range
[2, 262144]. :since:`Since 0.9.0`
``period``
The optional ``period`` element specifies the enforcement interval (unit:
microseconds). Within ``period``, each vCPU of the domain will not be allowed

View File

@ -3807,10 +3807,7 @@ If *--config* is specified, affect the next start of a persistent guest.
If *--current* is specified, it is equivalent to either *--live* or
*--config*, depending on the current state of the guest.
``Note``: The cpu_shares parameter has a valid value range of 0-262144; Negative
values are wrapped to positive, and larger values are capped at the maximum.
Therefore, -1 is a useful shorthand for 262144. On the Linux kernel, the
values 0 and 1 are automatically converted to a minimal value of 2.
``Note``: The cpu_shares parameter has a valid value range of 2-262144.
``Note``: The weight and cap parameters are defined only for the
XEN_CREDIT scheduler.

View File

@ -1229,6 +1229,16 @@ virDomainDefOSValidate(const virDomainDef *def,
static int
virDomainDefCputuneValidate(const virDomainDef *def)
{
if (def->cputune.shares > 0 &&
(def->cputune.shares < VIR_CGROUP_CPU_SHARES_MIN ||
def->cputune.shares > VIR_CGROUP_CPU_SHARES_MAX)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Value of cputune 'shares' must be in range [%llu, %llu]"),
VIR_CGROUP_CPU_SHARES_MIN,
VIR_CGROUP_CPU_SHARES_MAX);
return -1;
}
CPUTUNE_VALIDATE_PERIOD(period);
CPUTUNE_VALIDATE_PERIOD(global_period);
CPUTUNE_VALIDATE_PERIOD(emulator_period);

View File

@ -230,6 +230,8 @@ int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares);
int virCgroupSetupCpuShares(virCgroupPtr cgroup, unsigned long long shares,
unsigned long long *realValue);
#define VIR_CGROUP_CPU_SHARES_MIN 2LL
#define VIR_CGROUP_CPU_SHARES_MAX 262144LL
#define VIR_CGROUP_CPU_PERIOD_MIN 1000LL
#define VIR_CGROUP_CPU_PERIOD_MAX 1000000LL
#define VIR_CGROUP_CPU_QUOTA_MIN 1000LL

View File

@ -1917,6 +1917,16 @@ static int
virCgroupV1SetCpuShares(virCgroupPtr group,
unsigned long long shares)
{
if (shares < VIR_CGROUP_CPU_SHARES_MIN ||
shares > VIR_CGROUP_CPU_SHARES_MAX) {
virReportError(VIR_ERR_INVALID_ARG,
_("shares '%llu' must be in range [%llu, %llu]"),
shares,
VIR_CGROUP_CPU_SHARES_MIN,
VIR_CGROUP_CPU_SHARES_MAX);
return -1;
}
if (group->unitName) {
GVariant *value = g_variant_new("t", shares);

View File

@ -1505,6 +1505,16 @@ static int
virCgroupV2SetCpuShares(virCgroupPtr group,
unsigned long long shares)
{
if (shares < VIR_CGROUP_CPU_SHARES_MIN ||
shares > VIR_CGROUP_CPU_SHARES_MAX) {
virReportError(VIR_ERR_INVALID_ARG,
_("shares '%llu' must be in range [%llu, %llu]"),
shares,
VIR_CGROUP_CPU_SHARES_MIN,
VIR_CGROUP_CPU_SHARES_MAX);
return -1;
}
if (group->unitName) {
GVariant *value = g_variant_new("t", shares);