def numa_get_constraints(flavor, image_meta): """Return topology related to input request :param flavor: Flavor object to read extra specs from :param image_meta: nova.objects.ImageMeta object instance May raise exception.ImageNUMATopologyIncomplete() if the image properties are not correctly specified, or exception.ImageNUMATopologyForbidden if an attempt is made to override flavor settings with image properties. :returns: InstanceNUMATopology or None """ nodes = flavor.get('extra_specs', {}).get("hw:numa_nodes") props = image_meta.properties if nodes is not None: if props.obj_attr_is_set("hw_numa_nodes"): raise exception.ImageNUMATopologyForbidden( name='hw_numa_nodes') nodes = int(nodes) else: nodes = props.get("hw_numa_nodes") pagesize = _numa_get_pagesize_constraints( flavor, image_meta) numa_topology = None if nodes or pagesize: nodes = nodes or 1 cpu_list = _numa_get_cpu_map_list(flavor, image_meta) mem_list = _numa_get_mem_map_list(flavor, image_meta) # If one property list is specified both must be if ((cpu_list is None and mem_list is not None) or (cpu_list is not None and mem_list is None)): raise exception.ImageNUMATopologyIncomplete() # If any node has data set, all nodes must have data set if ((cpu_list is not None and len(cpu_list) != nodes) or (mem_list is not None and len(mem_list) != nodes)): raise exception.ImageNUMATopologyIncomplete() if cpu_list is None: numa_topology = _numa_get_constraints_auto( nodes, flavor) else: numa_topology = _numa_get_constraints_manual( nodes, flavor, cpu_list, mem_list) # We currently support same pagesize for all cells. [setattr(c, 'pagesize', pagesize) for c in numa_topology.cells] return _add_cpu_pinning_constraint(flavor, image_meta, numa_topology)
def _numa_get_constraints_auto(nodes, flavor, image_meta): if ((flavor['vcpus'] % nodes) > 0 or (flavor['memory_mb'] % nodes) > 0): raise exception.ImageNUMATopologyAsymmetric() cells = [] for node in range(nodes): cpus = _numa_get_flavor_or_image_prop(flavor, image_meta, "numa_cpus.%d" % node) mem = _numa_get_flavor_or_image_prop(flavor, image_meta, "numa_mem.%d" % node) # We're not expecting any properties set, so # raise an error if there are any if cpus is not None or mem is not None: raise exception.ImageNUMATopologyIncomplete() ncpus = int(flavor['vcpus'] / nodes) mem = int(flavor['memory_mb'] / nodes) start = node * ncpus cpuset = set(range(start, start + ncpus)) cells.append( objects.InstanceNUMACell(id=node, cpuset=cpuset, memory=mem)) return objects.InstanceNUMATopology(cells=cells)
def _get_constraints_auto(cls, nodes, flavor, image_meta): if ((flavor.vcpus % nodes) > 0 or (flavor.memory_mb % nodes) > 0): raise exception.ImageNUMATopologyAsymmetric() cells = [] for node in range(nodes): cpus = cls._get_flavor_or_image_prop( flavor, image_meta, "numa_cpus.%d" % node) mem = cls._get_flavor_or_image_prop( flavor, image_meta, "numa_mem.%d" % node) # We're not expecting any properties set, so # raise an error if there are any if cpus is not None or mem is not None: raise exception.ImageNUMATopologyIncomplete() ncpus = int(flavor.vcpus / nodes) mem = int(flavor.memory_mb / nodes) start = node * ncpus cpuset = set(range(start, start + ncpus)) cells.append(VirtNUMATopologyCell(node, cpuset, mem)) return cls(cells)
def _numa_get_constraints_manual(nodes, flavor, image_meta): cells = [] totalmem = 0 availcpus = set(range(flavor['vcpus'])) for node in range(nodes): cpus = _numa_get_flavor_or_image_prop( flavor, image_meta, "numa_cpus.%d" % node) mem = _numa_get_flavor_or_image_prop( flavor, image_meta, "numa_mem.%d" % node) # We're expecting both properties set, so # raise an error if either is missing if cpus is None or mem is None: raise exception.ImageNUMATopologyIncomplete() mem = int(mem) cpuset = parse_cpu_spec(cpus) for cpu in cpuset: if cpu > (flavor['vcpus'] - 1): raise exception.ImageNUMATopologyCPUOutOfRange( cpunum=cpu, cpumax=(flavor['vcpus'] - 1)) if cpu not in availcpus: raise exception.ImageNUMATopologyCPUDuplicates( cpunum=cpu) availcpus.remove(cpu) cells.append(objects.InstanceNUMACell( id=node, cpuset=cpuset, memory=mem)) totalmem = totalmem + mem if availcpus: raise exception.ImageNUMATopologyCPUsUnassigned( cpuset=str(availcpus)) if totalmem != flavor['memory_mb']: raise exception.ImageNUMATopologyMemoryOutOfRange( memsize=totalmem, memtotal=flavor['memory_mb']) return objects.InstanceNUMATopology(cells=cells)