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 }