Files
nomad/client/lib/numalib/detect.go
Juana De La Cuesta 3b44090156 Avoid panic during startup with 1.10.2 (#26219)
* fix: initalize the topology of teh processors to avoid nil pointers

* func: initialize topology to avoid nil pointers

* fix: update the new public method for NodeProcessorResources
2025-07-08 16:07:14 +02:00

85 lines
2.7 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package numalib
import (
"github.com/hashicorp/nomad/client/lib/idset"
"github.com/hashicorp/nomad/client/lib/numalib/hw"
)
// A SystemScanner represents one methodology of detecting CPU hardware on a
// system. Detectable information is accumulated into a given Topology.
type SystemScanner interface {
ScanSystem(*Topology)
}
// Scan each of the given scanners in order and accumulate the results into
// a single Topology, which can then be used to answer questions about the CPU
// topology of the system.
func Scan(scanners []SystemScanner) *Topology {
top := &Topology{}
for _, scanner := range scanners {
scanner.ScanSystem(top)
}
return top
}
// ConfigScanner provides override values coming from Nomad Client configuration.
// This scanner must run last as the client configuration has the final say if
// values there are set by an operator.
type ConfigScanner struct {
// ReservableCores comes from client.reservable_cores.
//
// Not yet documented as of 1.6.
//
// Only meaningful on Linux, this value can be used to override the set of
// CPU core IDs we may make use of. Normally these are detected by reading
// Nomad parent cgroup cpuset interface file.
ReservableCores *idset.Set[hw.CoreID]
// TotalCompute comes from client.cpu_total_compute.
//
// Used to set the total MHz of available CPU bandwidth on a system. This
// value is used by the scheduler for fitment, and by the client for computing
// task / alloc / client resource utilization. Therefor this value:
// - Should NOT be set if Nomad was able to fingerprint a value.
// - Should NOT be used to over/under provision compute resources.
TotalCompute hw.MHz
// ReservedCores comes from client.reserved.cores.
//
// Used to withhold a set of cores from being used by Nomad for scheduling.
ReservedCores *idset.Set[hw.CoreID]
// ReservedCompute comes from client.reserved.cpu.
//
// Used to withhold an amount of MHz of CPU bandwidth from being used by
// Nomad for scheduling.
ReservedCompute hw.MHz
}
func (cs *ConfigScanner) ScanSystem(top *Topology) {
// disable cores that are not reservable (i.e. override effective cpuset)
if cs.ReservableCores != nil {
for i := 0; i < len(top.Cores); i++ {
if !cs.ReservableCores.Contains(top.Cores[i].ID) {
top.Cores[i].Disable = true
}
}
}
// disable cores that are not usable (i.e. hide from scheduler)
for i := 0; i < len(top.Cores); i++ {
if cs.ReservedCores.Contains(top.Cores[i].ID) {
top.Cores[i].Disable = true
}
}
// set total compute from client configuration
top.OverrideTotalCompute = cs.TotalCompute
// set the reserved compute from client configuration
top.OverrideWitholdCompute = cs.ReservedCompute
}