diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 937b0da012..b434ada8f0 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -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 diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index 8a4328faa0..d44c36e2e9 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -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. diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index b4e09e21fe..61cd0a07e5 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -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); diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h index ec0902e301..7d9172d664 100644 --- a/src/util/vircgroup.h +++ b/src/util/vircgroup.h @@ -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 diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c index 79015ddaa4..f8bdca4e78 100644 --- a/src/util/vircgroupv1.c +++ b/src/util/vircgroupv1.c @@ -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); diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index 24c7e64c67..669bf1b52e 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -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);