mirror of
				https://github.com/ClusterCockpit/cc-metric-collector.git
				synced 2025-11-04 02:35:07 +01:00 
			
		
		
		
	Correctly handle lists from /sys
This commit is contained in:
		@@ -36,6 +36,70 @@ var cache struct {
 | 
			
		||||
	CpuData []HwthreadEntry
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// fileToInt reads an integer value from a file
 | 
			
		||||
// In case of an error -1 is returned
 | 
			
		||||
// Used internally for sysfs file reads
 | 
			
		||||
func fileToInt(path string) int {
 | 
			
		||||
	buffer, err := os.ReadFile(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Print(err)
 | 
			
		||||
		cclogger.ComponentError("ccTopology", "Reading", path, ":", err.Error())
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
	stringBuffer := strings.TrimSpace(string(buffer))
 | 
			
		||||
	id, err := strconv.Atoi(stringBuffer)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cclogger.ComponentError("ccTopology", "Parsing", path, ":", stringBuffer, err.Error())
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
	return id
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// fileToList reads a list from a file
 | 
			
		||||
// A list consists of value ranges separated by colon
 | 
			
		||||
// A range can be a single value or a range of values given by a startValue-endValue
 | 
			
		||||
// In case of an error nil is returned
 | 
			
		||||
// Used internally for sysfs file reads
 | 
			
		||||
func fileToList(path string) []int {
 | 
			
		||||
	// Read thread sibling list
 | 
			
		||||
	buffer, err := os.ReadFile(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Print(err)
 | 
			
		||||
		cclogger.ComponentError("ccTopology", "fileToList", "Reading", path, ":", err.Error())
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create list
 | 
			
		||||
	list := make([]int, 0)
 | 
			
		||||
	stringBuffer := strings.TrimSpace(string(buffer))
 | 
			
		||||
	for _, valueRangeString := range strings.Split(stringBuffer, ",") {
 | 
			
		||||
		valueRange := strings.Split(valueRangeString, "-")
 | 
			
		||||
		switch len(valueRange) {
 | 
			
		||||
		case 1:
 | 
			
		||||
			singleValue, err := strconv.Atoi(valueRange[0])
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				cclogger.ComponentError("CCTopology", "fileToList", err.Error())
 | 
			
		||||
			}
 | 
			
		||||
			list = append(list, singleValue)
 | 
			
		||||
		case 2:
 | 
			
		||||
			startValue, err := strconv.Atoi(valueRange[0])
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				cclogger.ComponentError("CCTopology", "fileToList", err.Error())
 | 
			
		||||
			}
 | 
			
		||||
			endValue, err := strconv.Atoi(valueRange[1])
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				cclogger.ComponentError("CCTopology", "fileToList", err.Error())
 | 
			
		||||
			}
 | 
			
		||||
			for value := startValue; value <= endValue; value++ {
 | 
			
		||||
				list = append(list, value)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return list
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// init initializes the cache structure
 | 
			
		||||
func init() {
 | 
			
		||||
 | 
			
		||||
@@ -76,30 +140,6 @@ func init() {
 | 
			
		||||
			return hwThreadIDs
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	getSMT :=
 | 
			
		||||
		func(cpuID int, basePath string) int {
 | 
			
		||||
			// Read thread sibling list
 | 
			
		||||
			buffer, err := os.ReadFile(filepath.Join(basePath, "thread_siblings_list"))
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				cclogger.ComponentError("CCTopology", "init", err.Error())
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Create thread sibling list
 | 
			
		||||
			threadList := make([]int, 0)
 | 
			
		||||
			stringBuffer := strings.TrimSpace(string(buffer))
 | 
			
		||||
			for _, x := range strings.Split(stringBuffer, ",") {
 | 
			
		||||
				id, err := strconv.Atoi(x)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					cclogger.ComponentError("CCTopology", "init", err.Error())
 | 
			
		||||
				}
 | 
			
		||||
				threadList = append(threadList, id)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Find index of CPU ID in thread sibling list
 | 
			
		||||
			// if not found return -1
 | 
			
		||||
			return slices.Index(threadList, cpuID)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	getNumaDomain :=
 | 
			
		||||
		func(basePath string) int {
 | 
			
		||||
			globPath := filepath.Join(basePath, "node*")
 | 
			
		||||
@@ -155,8 +195,12 @@ func init() {
 | 
			
		||||
			cache.DieList[i] = cache.SocketList[i]
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Lookup SMT thread id
 | 
			
		||||
		cache.SMTList[i] = getSMT(c, topoBase)
 | 
			
		||||
		// Lookup thread siblings list
 | 
			
		||||
		threadList := fileToList(filepath.Join(topoBase, "thread_siblings_list"))
 | 
			
		||||
 | 
			
		||||
		// Find index of CPU ID in thread sibling list
 | 
			
		||||
		// if not found return -1
 | 
			
		||||
		cache.SMTList[i] = slices.Index(threadList, c)
 | 
			
		||||
 | 
			
		||||
		// Lookup NUMA domain id
 | 
			
		||||
		cache.NumaDomainList[i] = getNumaDomain(base)
 | 
			
		||||
@@ -200,25 +244,6 @@ func init() {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// fileToInt reads an integer value from a file
 | 
			
		||||
// In case of an error -1 is returned
 | 
			
		||||
// Used internally for sysfs file reads
 | 
			
		||||
func fileToInt(path string) int {
 | 
			
		||||
	buffer, err := os.ReadFile(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Print(err)
 | 
			
		||||
		cclogger.ComponentError("ccTopology", "Reading", path, ":", err.Error())
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
	stringBuffer := strings.TrimSpace(string(buffer))
 | 
			
		||||
	id, err := strconv.Atoi(stringBuffer)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cclogger.ComponentError("ccTopology", "Parsing", path, ":", stringBuffer, err.Error())
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
	return id
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SocketList gets the list of CPU socket IDs
 | 
			
		||||
func SocketList() []int {
 | 
			
		||||
	return slices.Clone(cache.uniqSocketList)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user