1
0
Fork 0
mirror of https://github.com/kubernetes-sigs/node-feature-discovery.git synced 2025-03-05 16:27:05 +00:00

sources/pci: make device label format configurable

Add new config option for specifying the device label, i.e. the
<device-label> part in
    node.alpha.kubernetes-incubator.io/nfd-pci-<device label>.present

The option is a list of field names:
    "class"             PCI device class
    "vendor"            Vendor ID
    "device"            Device ID
    "subsystem_vendor"  Subsystem vendor ID
    "subsystem_device"  Subsystem device ID

E.g. the following command line flag can be used to use all of the
above:
  --options='{"sources": {"pci": {"deviceLabelFields": ["class", "vendor", "device", "subsystem_vendor", "subsystem_device"] } } }'
This commit is contained in:
Markus Lehtonen 2018-09-21 15:16:41 +03:00
parent b0d0797936
commit b0fedab786
3 changed files with 57 additions and 9 deletions

View file

@ -183,16 +183,21 @@ such as restricting discovered features with the --label-whitelist option._
| -------------------- | --------- | ----------------------------------------- | | -------------------- | --------- | ----------------------------------------- |
| &lt;device label&gt; | present | PCI device is detected | &lt;device label&gt; | present | PCI device is detected
The `<device label>` part is composed of raw PCI IDs, and has the following The `<device label>` part is composed of raw PCI IDs, separated by dashes.
format: `<class>_<vendor>`. E.g. The set of fields used in `<device label>` is configurable, valid fields being
`class`, `vendor`, `device`, `subsystem_vendor` and `subsystem_device`.
Defaults fields are `class` and `vendor`. An example label using the default
label fields:
``` ```
node.alpha.kubernetes-incubator.io/nfd-pci-1200_8086.present=true node.alpha.kubernetes-incubator.io/nfd-pci-1200_8086.present=true
``` ```
The set of PCI device classes that the feature source detects is configurable. Also the set of PCI device classes that the feature source detects is
By default, device classes (0x)03, (0x)0b40 and (0x)12, i.e. GPUs, configurable. By default, device classes (0x)03, (0x)0b40 and (0x)12, i.e.
co-processors and accelerator cards are deteted. GPUs, co-processors and accelerator cards are deteted.
See [configuration options](#configuration-options) for more information.
See [configuration options](#configuration-options)
for more information on NFD config.
### RDT (Intel Resource Director Technology) Features ### RDT (Intel Resource Director Technology) Features

View file

@ -4,3 +4,9 @@
# - "0200" # - "0200"
# - "03" # - "03"
# - "12" # - "12"
# deviceLabelFields:
# - "class"
# - "vendor"
# - "device"
# - "subsystem_vendor"
# - "subsystem_device"

View file

@ -31,12 +31,16 @@ var logger = log.New(os.Stderr, "", log.LstdFlags)
type NFDConfig struct { type NFDConfig struct {
DeviceClassWhitelist []string `json:"deviceClassWhitelist,omitempty"` DeviceClassWhitelist []string `json:"deviceClassWhitelist,omitempty"`
DeviceLabelFields []string `json:"deviceLabelFields,omitempty"`
} }
var Config = NFDConfig{ var Config = NFDConfig{
DeviceClassWhitelist: []string{"03", "0b40", "12"}, DeviceClassWhitelist: []string{"03", "0b40", "12"},
DeviceLabelFields: []string{"class", "vendor"},
} }
var devLabelAttrs = []string{"class", "vendor", "device", "subsystem_vendor", "subsystem_device"}
// Implement FeatureSource interface // Implement FeatureSource interface
type Source struct{} type Source struct{}
@ -52,11 +56,45 @@ func (s Source) Discover() ([]string, error) {
return nil, fmt.Errorf("Failed to detect PCI devices: %s", err.Error()) return nil, fmt.Errorf("Failed to detect PCI devices: %s", err.Error())
} }
// Construct a device label format, a sorted list of valid attributes
deviceLabelFields := []string{}
configLabelFields := map[string]bool{}
for _, field := range Config.DeviceLabelFields {
configLabelFields[field] = true
}
for _, attr := range devLabelAttrs {
if _, ok := configLabelFields[attr]; ok {
deviceLabelFields = append(deviceLabelFields, attr)
delete(configLabelFields, attr)
}
}
if len(configLabelFields) > 0 {
keys := []string{}
for key := range configLabelFields {
keys = append(keys, key)
}
log.Printf("WARNING: invalid fields '%v' in deviceLabelFields, ignoring...", keys)
}
if len(deviceLabelFields) == 0 {
log.Printf("WARNING: no valid fields in deviceLabelFields defined, using the defaults")
deviceLabelFields = []string{"class", "vendor"}
}
// Iterate over all device classes
for class, classDevs := range devs { for class, classDevs := range devs {
for _, white := range Config.DeviceClassWhitelist { for _, white := range Config.DeviceClassWhitelist {
if strings.HasPrefix(class, strings.ToLower(white)) { if strings.HasPrefix(class, strings.ToLower(white)) {
for _, dev := range classDevs { for _, dev := range classDevs {
features[fmt.Sprintf("%s_%s.present", dev["class"], dev["vendor"])] = true devLabel := ""
for i, attr := range deviceLabelFields {
devLabel += dev[attr]
if i < len(deviceLabelFields)-1 {
devLabel += "_"
}
}
devLabel += ".present"
features[devLabel] = true
} }
} }
} }
@ -74,8 +112,7 @@ func (s Source) Discover() ([]string, error) {
func readDevInfo(devPath string) (pciDeviceInfo, error) { func readDevInfo(devPath string) (pciDeviceInfo, error) {
info := pciDeviceInfo{} info := pciDeviceInfo{}
attrs := []string{"class", "vendor", "device", "subsystem_vendor", "subsystem_device"} for _, attr := range devLabelAttrs {
for _, attr := range attrs {
data, err := ioutil.ReadFile(path.Join(devPath, attr)) data, err := ioutil.ReadFile(path.Join(devPath, attr))
if err != nil { if err != nil {
return info, fmt.Errorf("Failed to read device %s: %s", attr, err) return info, fmt.Errorf("Failed to read device %s: %s", attr, err)