/** * virCPUGetHost: * * @arch: CPU architecture * @type: requested type of the CPU * @nodeInfo: simplified CPU topology (optional) * @models: list of CPU models that can be considered for host CPU * * Create CPU definition describing the host's CPU. * * The @type (either VIR_CPU_TYPE_HOST or VIR_CPU_TYPE_GUEST) specifies what * type of CPU definition should be created. Specifically, VIR_CPU_TYPE_HOST * CPUs may contain only features without any policy attribute. Requesting * VIR_CPU_TYPE_GUEST provides better results because the CPU is allowed to * contain disabled features. * * If @nodeInfo is not NULL (which is only allowed for VIR_CPU_TYPE_HOST CPUs), * the CPU definition will have topology (sockets, cores, threads) filled in * according to the content of @nodeInfo. The function fails only if @nodeInfo * was not passed in and the assigned CPU driver was not able to detect the * host CPU model. In other words, a CPU definition containing just the * topology is a successful result even if detecting the host CPU model fails. * * It possible to limit the CPU model which may appear in the created CPU * definition by passing non-NULL @models list. This is useful when requesting * a CPU model usable on a specific hypervisor. If @models is NULL, any CPU * model known to libvirt may appear in the result. * * Returns host CPU definition or NULL on error. */ virCPUDefPtr virCPUGetHost(virArch arch, virCPUType type, virNodeInfoPtr nodeInfo, virDomainCapsCPUModelsPtr models) { struct cpuArchDriver *driver; virCPUDefPtr cpu = NULL; VIR_DEBUG("arch=%s, type=%s, nodeInfo=%p, models=%p", virArchToString(arch), virCPUTypeToString(type), nodeInfo, models); if (!(driver = cpuGetSubDriver(arch))) return NULL; if (VIR_ALLOC(cpu) < 0) return NULL; switch (type) { case VIR_CPU_TYPE_HOST: cpu->arch = arch; cpu->type = type; break; case VIR_CPU_TYPE_GUEST: if (nodeInfo) { virReportError(VIR_ERR_INVALID_ARG, _("cannot set topology for CPU type '%s'"), virCPUTypeToString(type)); goto error; } cpu->type = type; break; case VIR_CPU_TYPE_AUTO: case VIR_CPU_TYPE_LAST: virReportError(VIR_ERR_INVALID_ARG, _("unsupported CPU type: %s"), virCPUTypeToString(type)); goto error; } if (nodeInfo) { cpu->sockets = nodeInfo->sockets; cpu->cores = nodeInfo->cores; cpu->threads = nodeInfo->threads; } /* Try to get the host CPU model, but don't really fail if nodeInfo is * filled in. */ if (driver->getHost) { if (driver->getHost(cpu, models) < 0 && !nodeInfo) goto error; } else if (nodeInfo) { VIR_DEBUG("cannot detect host CPU model for %s architecture", virArchToString(arch)); } else { virReportError(VIR_ERR_NO_SUPPORT, _("cannot detect host CPU model for %s architecture"), virArchToString(arch)); goto error; } return cpu; error: virCPUDefFree(cpu); return NULL; }
bool virCPUDefIsEqual(virCPUDefPtr src, virCPUDefPtr dst) { bool identical = false; int i; if (!src && !dst) return true; if ((src && !dst) || (!src && dst)) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Target CPU does not match source")); goto cleanup; } if (src->type != dst->type) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU type %s does not match source %s"), virCPUTypeToString(dst->type), virCPUTypeToString(src->type)); goto cleanup; } if (src->mode != dst->mode) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU mode %s does not match source %s"), virCPUModeTypeToString(dst->mode), virCPUModeTypeToString(src->mode)); goto cleanup; } if (STRNEQ_NULLABLE(src->arch, dst->arch)) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU arch %s does not match source %s"), NULLSTR(dst->arch), NULLSTR(src->arch)); goto cleanup; } if (STRNEQ_NULLABLE(src->model, dst->model)) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU model %s does not match source %s"), NULLSTR(dst->model), NULLSTR(src->model)); goto cleanup; } if (STRNEQ_NULLABLE(src->vendor, dst->vendor)) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU vendor %s does not match source %s"), NULLSTR(dst->vendor), NULLSTR(src->vendor)); goto cleanup; } if (src->sockets != dst->sockets) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU sockets %d does not match source %d"), dst->sockets, src->sockets); goto cleanup; } if (src->cores != dst->cores) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU cores %d does not match source %d"), dst->cores, src->cores); goto cleanup; } if (src->threads != dst->threads) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU threads %d does not match source %d"), dst->threads, src->threads); goto cleanup; } if (src->nfeatures != dst->nfeatures) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU feature count %zu does not match source %zu"), dst->nfeatures, src->nfeatures); goto cleanup; } for (i = 0 ; i < src->nfeatures ; i++) { if (STRNEQ(src->features[i].name, dst->features[i].name)) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU feature %s does not match source %s"), dst->features[i].name, src->features[i].name); goto cleanup; } if (src->features[i].policy != dst->features[i].policy) { virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target CPU feature policy %s does not match source %s"), virCPUFeaturePolicyTypeToString(dst->features[i].policy), virCPUFeaturePolicyTypeToString(src->features[i].policy)); goto cleanup; } } identical = true; cleanup: return identical; }
bool virCPUDefIsEqual(virCPUDefPtr src, virCPUDefPtr dst, bool reportError) { bool identical = false; size_t i; if (!src && !dst) return true; #define MISMATCH(fmt, ...) \ if (reportError) \ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, fmt, __VA_ARGS__) if ((src && !dst) || (!src && dst)) { MISMATCH("%s", _("Target CPU does not match source")); goto cleanup; } if (src->type != dst->type) { MISMATCH(_("Target CPU type %s does not match source %s"), virCPUTypeToString(dst->type), virCPUTypeToString(src->type)); goto cleanup; } if (src->mode != dst->mode) { MISMATCH(_("Target CPU mode %s does not match source %s"), virCPUModeTypeToString(dst->mode), virCPUModeTypeToString(src->mode)); goto cleanup; } if (src->check != dst->check) { MISMATCH(_("Target CPU check %s does not match source %s"), virCPUCheckTypeToString(dst->check), virCPUCheckTypeToString(src->check)); goto cleanup; } if (src->arch != dst->arch) { MISMATCH(_("Target CPU arch %s does not match source %s"), virArchToString(dst->arch), virArchToString(src->arch)); goto cleanup; } if (STRNEQ_NULLABLE(src->model, dst->model)) { MISMATCH(_("Target CPU model %s does not match source %s"), NULLSTR(dst->model), NULLSTR(src->model)); goto cleanup; } if (STRNEQ_NULLABLE(src->vendor, dst->vendor)) { MISMATCH(_("Target CPU vendor %s does not match source %s"), NULLSTR(dst->vendor), NULLSTR(src->vendor)); goto cleanup; } if (STRNEQ_NULLABLE(src->vendor_id, dst->vendor_id)) { MISMATCH(_("Target CPU vendor id %s does not match source %s"), NULLSTR(dst->vendor_id), NULLSTR(src->vendor_id)); goto cleanup; } if (src->sockets != dst->sockets) { MISMATCH(_("Target CPU sockets %d does not match source %d"), dst->sockets, src->sockets); goto cleanup; } if (src->cores != dst->cores) { MISMATCH(_("Target CPU cores %d does not match source %d"), dst->cores, src->cores); goto cleanup; } if (src->threads != dst->threads) { MISMATCH(_("Target CPU threads %d does not match source %d"), dst->threads, src->threads); goto cleanup; } if (src->nfeatures != dst->nfeatures) { MISMATCH(_("Target CPU feature count %zu does not match source %zu"), dst->nfeatures, src->nfeatures); goto cleanup; } for (i = 0; i < src->nfeatures; i++) { if (STRNEQ(src->features[i].name, dst->features[i].name)) { MISMATCH(_("Target CPU feature %s does not match source %s"), dst->features[i].name, src->features[i].name); goto cleanup; } if (src->features[i].policy != dst->features[i].policy) { MISMATCH(_("Target CPU feature policy %s does not match source %s"), virCPUFeaturePolicyTypeToString(dst->features[i].policy), virCPUFeaturePolicyTypeToString(src->features[i].policy)); goto cleanup; } } if ((src->cache && !dst->cache) || (!src->cache && dst->cache) || (src->cache && dst->cache && (src->cache->level != dst->cache->level || src->cache->mode != dst->cache->mode))) { MISMATCH("%s", _("Target CPU cache does not match source")); goto cleanup; } #undef MISMATCH identical = true; cleanup: return identical; }