diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f562323657..44752b948d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1570,6 +1570,42 @@ virDomainDefGetVcpuPinInfoHelper(virDomainDefPtr def, } +/** + * virDomainDeGetVcpusTopology: + * @def: domain definition + * @maxvcpus: optionally filled with number of vcpus the domain topology describes + * + * Calculates and validates that the vcpu topology is in sane bounds and + * optionally returns the total number of vcpus described by given topology. + * + * Returns 0 on success, 1 if topology is not configured and -1 on error. + */ +int +virDomainDefGetVcpusTopology(const virDomainDef *def, + unsigned int *maxvcpus) +{ + unsigned long long tmp; + + if (!def->cpu || def->cpu->sockets == 0) + return 1; + + tmp = def->cpu->sockets; + + /* multiplication of 32bit numbers fits into a 64bit variable */ + if ((tmp *= def->cpu->cores) > UINT_MAX || + (tmp *= def->cpu->threads) > UINT_MAX) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("cpu topology results in more than %u cpus"), UINT_MAX); + return -1; + } + + if (maxvcpus) + *maxvcpus = tmp; + + return 0; +} + + virDomainDiskDefPtr virDomainDiskDefNew(virDomainXMLOptionPtr xmlopt) { @@ -4786,6 +4822,9 @@ virDomainDefValidateInternal(const virDomainDef *def) if (virDomainDefCheckDuplicateDiskInfo(def) < 0) return -1; + if (virDomainDefGetVcpusTopology(def, NULL) < 0) + return -1; + return 0; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a70bc2182a..54c9502ce4 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2488,6 +2488,8 @@ virBitmapPtr virDomainDefGetOnlineVcpumap(const virDomainDef *def); virDomainVcpuDefPtr virDomainDefGetVcpu(virDomainDefPtr def, unsigned int vcpu) ATTRIBUTE_RETURN_CHECK; void virDomainDefVcpuOrderClear(virDomainDefPtr def); +int virDomainDefGetVcpusTopology(const virDomainDef *def, + unsigned int *maxvcpus); virDomainObjPtr virDomainObjNew(virDomainXMLOptionPtr caps) ATTRIBUTE_NONNULL(1); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b88e903744..11a90b1874 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -247,6 +247,7 @@ virDomainDefGetVcpu; virDomainDefGetVcpuPinInfoHelper; virDomainDefGetVcpus; virDomainDefGetVcpusMax; +virDomainDefGetVcpusTopology; virDomainDefHasDeviceAddress; virDomainDefHasMemballoon; virDomainDefHasMemoryHotplug;