예제 #1
0
func (c *Config) SetTopologySingleVirtualNUMA(numas host.NUMANodes, singleNuma bool) error {
	// file, _ := os.Create("/tmp/1SetTopologyMultipleVirtualNUMAs.txt")
	// defer file.Close()
	// file.WriteString("SetTopologySingleVirtualNUMA\n")

	if c.CPUs == 0 {
		return errors.New("A data memeber (CPUs) is not initialized")
	}
	if c.RamMb == 0 {
		return errors.New("A data memeber (RamMb) is not initialized")
	}

	c.NUMAs = nil
	gn := new(NUMA)
	gn.CellID = 0
	gn.MemoryMb = c.RamMb
	gn.NICs = nil
	gn.CPUPin = make(map[int][]int, 0)
	nicNumaMapping, _ := numaNicsMapping(c, numas)

	for _, n := range numas {
		l, ok := nicNumaMapping[n.CellID]
		if ok {
			gn.NICs.AppendList(l)
		}
	}

	if singleNuma {
		// file.WriteString("SetTopologySingleVirtualNUMA singleNuma\n")
		cpusNuma0, err := numas.CpusOnNUMA(0)
		if err != nil {
			// file.WriteString("SetTopologySingleVirtualNUMA  cpusNuma0 err: " + err.Error() + "\n")
			return err
		}
		// file.WriteString("SetTopologySingleVirtualNUMA len(cpusNuma0): " + strconv.Itoa(len(cpusNuma0)) + "\n")
		// file.WriteString("SetTopologySingleVirtualNUMA c.CPUs: " + strconv.Itoa(c.CPUs) + "\n")
		if c.CPUs <= len(cpusNuma0) {
			// file.WriteString("c.CPUs <= len(cpusNuma0) \n")
			for i := 0; i < c.CPUs; i++ {
				gn.CPUPin[i] = append(gn.CPUPin[i], i)
			}

		} else {
			// file.WriteString("c.CPUs > len(cpusNuma0) \n")
			for i := 0; i < c.CPUs; i++ {
				gn.CPUPin[i] = append(gn.CPUPin[i], i)
			}
		}
		c.HostNUMAIds = []int{0}
	} else {
		// file.WriteString("SetTopologySingleVirtualNUMA not singleNuma\n")
		// file.WriteString("SetTopologySingleVirtualNUMA c.CPUs " + strconv.Itoa(c.CPUs) + "\n")
		for i := 0; i < c.CPUs; i++ {
			// file.WriteString("SetTopologySingleVirtualNUMA i: " + strconv.Itoa(i) + "\n")
			for _, n := range numas {
				gn.CPUPin[i] = append(gn.CPUPin[i], n.CPUs...)
				c.HostNUMAIds = append(c.HostNUMAIds, n.CellID)
			}
		}
	}

	c.NUMAs = append(c.NUMAs, gn)
	return nil
}
예제 #2
0
func (c *Config) SetTopologyMultipleVirtualNUMAs(numas host.NUMANodes) error {
	// file, _ := os.Create("/tmp/1SetTopologyMultipleVirtualNUMAs.txt")
	// defer file.Close()
	if c.CPUs == 0 {
		return errors.New("A data memeber (CPUs) is not initialized")
	}
	if c.RamMb == 0 {
		return errors.New("A data memeber (RamMb) is not initialized")
	}
	if len(c.NICLists) == 0 {
		return errors.New("A data memeber (NICLists) is not initialized")
	}
	// file.WriteString("SetTopologyMultipleVirtualNUMAs(): \n")

	if c.CPUs > numas.TotalCPUs() {
		// file.WriteString("c.CPUs > numas.TotalCPUs() \n")
		c.OptimizationFailureCPU = true
		c.OptimizationFailureMemory = true
		c.OptimizationFailureMsg = fmt.Sprintf("Amount of requested CPUs (%d) is greater than installed(%d).", c.CPUs, numas.TotalCPUs())
		return c.SetTopologySingleVirtualNUMA(numas, false)
	}

	nicNumaMapping, totalAmountOfPorts := numaNicsMapping(c, numas)
	if totalAmountOfPorts == 0 {
		// file.WriteString("totalAmountOfPorts == 0 \n")
		return c.SetTopologySingleVirtualNUMA(numas, true)
	}

	cellID := 0
	vcpuID := 0
	allocatedCpus := 0
	for _, n := range numas {
		// file.WriteString("n.CellID: (" + strconv.Itoa(n.CellID) + ") \n")
		if portsList, ok := nicNumaMapping[n.CellID]; ok {
			percentage, err := utils.FloatStringsSliceToInt(strings.Split(fmt.Sprintf("%0.1f", float32(len(portsList))*float32(100)/float32(totalAmountOfPorts)), "."))
			if err != nil {
				// file.WriteString("percentage, err " + err.Error() + " \n")
				return nil
			}

			amountOfMemoryMb, err := utils.FloatStringsSliceToInt(strings.Split(fmt.Sprintf("%0.1f", float32(c.RamMb)/float32(100)*float32(percentage)), "."))
			if err != nil {
				// file.WriteString("amountOfMemoryMb, err " + err.Error() + " \n")
				return err
			}

			amountOfCpus, err := utils.FloatStringsSliceToInt(strings.Split(fmt.Sprintf("%0.1f", float32(c.CPUs)/float32(100)*float32(percentage)), "."))
			if err != nil {
				// file.WriteString("amountOfCpus, err " + err.Error() + " \n")
				return err
			}
			// fmt.Printf("total amount of ports = %d\n", totalAmountOfPorts)
			// fmt.Printf("amount of ports on NUMA %d = %d\n", n.CellID, len(portsList))
			// fmt.Printf("percentage = %d\n", percentage)
			// fmt.Printf("amount of MemoryMb = %d\n", amountOfMemoryMb)
			// fmt.Printf("amount of CPUS = %d\n", amountOfCpus)
			// fmt.Printf("required CPUS = %d\n", c.CPUs)

			cpusOnNuma := len(n.CPUs)
			switch {
			case amountOfCpus > cpusOnNuma && amountOfMemoryMb > n.TotalRAM:
				c.OptimizationFailureCPU = true
				c.OptimizationFailureMemory = true
				c.OptimizationFailureMsg = fmt.Sprintf("Not enough CPUs and memory on NUMA %d (requested CPUs %d, installed CPUs %d\nrequested memory %dMB , installed %dMB).", n.CellID, amountOfCpus, cpusOnNuma, amountOfMemoryMb, n.TotalRAM)
				return c.SetTopologySingleVirtualNUMA(numas, false)
			case amountOfCpus > cpusOnNuma && amountOfMemoryMb <= n.TotalRAM:
				c.OptimizationFailureCPU = true
				c.OptimizationFailureMsg = fmt.Sprintf("%d CPUs are required on NUMA %d, but just %d CPUs are available.", amountOfCpus, n.CellID, cpusOnNuma)
				return c.SetTopologySingleVirtualNUMA(numas, false)
			case amountOfMemoryMb > n.TotalRAM && amountOfCpus <= cpusOnNuma:
				c.OptimizationFailureMemory = true
				c.OptimizationFailureMsg = fmt.Sprintf("Not enough memory on NUMA %d (requested memory %dMB , installed %dMB).", n.CellID, amountOfMemoryMb, n.TotalRAM)
				return c.SetTopologySingleVirtualNUMA(numas, true)
			case amountOfCpus == 0:
				c.OptimizationFailureCPU = true
				c.OptimizationFailureMsg = "The Virtual Machine is configured with a single vCPU."
				if amountOfMemoryMb > n.TotalRAM {
					c.OptimizationFailureMemory = true
				}
				return c.SetTopologySingleVirtualNUMA(numas, true)
			}

			gn := new(NUMA)
			gn.CellID = cellID
			gn.CPUPin = make(map[int][]int, 0)
			gn.NICs = portsList

			sort.Ints(n.CPUs)
			vcpusPerNUMA := len(n.CPUs[0:amountOfCpus])
			gn.MemoryMb = amountOfMemoryMb

			for x := 0; x < vcpusPerNUMA; x++ {
				gn.CPUPin[vcpuID] = append(gn.CPUPin[vcpuID], n.CPUs[x])
				vcpuID++
			}

			allocatedCpus += amountOfCpus
			c.NUMAs = append(c.NUMAs, gn)
			c.HostNUMAIds = append(c.HostNUMAIds, n.CellID)
			cellID++
		}
	}

	if allocatedCpus != c.CPUs {
		// file.WriteString("allocatedCpus != c.CPUs\n")
		c.OptimizationFailureCPU = true
		c.OptimizationFailureMsg = "Cannot distribute vCPUs among the vNUMAS."
		return c.SetTopologySingleVirtualNUMA(numas, false)
	}
	// file.WriteString("return nil\n")
	return nil
}