From b0fedab7867769a4032c8ee4f6398c53744bc6f7 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 21 Sep 2018 15:16:41 +0300 Subject: [PATCH] sources/pci: make device label format configurable Add new config option for specifying the device label, i.e. the part in node.alpha.kubernetes-incubator.io/nfd-pci-.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"] } } }' --- README.md | 17 ++++++++---- node-feature-discovery.conf.example | 6 ++++ source/pci/pci.go | 43 +++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 220b96f99..f83ec903d 100644 --- a/README.md +++ b/README.md @@ -183,16 +183,21 @@ such as restricting discovered features with the --label-whitelist option._ | -------------------- | --------- | ----------------------------------------- | | <device label> | present | PCI device is detected -The `` part is composed of raw PCI IDs, and has the following -format: `_`. E.g. +The `` part is composed of raw PCI IDs, separated by dashes. +The set of fields used in `` 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 ``` -The set of PCI device classes that the feature source detects is configurable. -By default, device classes (0x)03, (0x)0b40 and (0x)12, i.e. GPUs, -co-processors and accelerator cards are deteted. -See [configuration options](#configuration-options) for more information. +Also the set of PCI device classes that the feature source detects is +configurable. By default, device classes (0x)03, (0x)0b40 and (0x)12, i.e. +GPUs, co-processors and accelerator cards are deteted. + +See [configuration options](#configuration-options) +for more information on NFD config. ### RDT (Intel Resource Director Technology) Features diff --git a/node-feature-discovery.conf.example b/node-feature-discovery.conf.example index 6339a6b03..a7419c3fb 100644 --- a/node-feature-discovery.conf.example +++ b/node-feature-discovery.conf.example @@ -4,3 +4,9 @@ # - "0200" # - "03" # - "12" +# deviceLabelFields: +# - "class" +# - "vendor" +# - "device" +# - "subsystem_vendor" +# - "subsystem_device" diff --git a/source/pci/pci.go b/source/pci/pci.go index 9889921b1..bd1e4ad4a 100644 --- a/source/pci/pci.go +++ b/source/pci/pci.go @@ -31,12 +31,16 @@ var logger = log.New(os.Stderr, "", log.LstdFlags) type NFDConfig struct { DeviceClassWhitelist []string `json:"deviceClassWhitelist,omitempty"` + DeviceLabelFields []string `json:"deviceLabelFields,omitempty"` } var Config = NFDConfig{ DeviceClassWhitelist: []string{"03", "0b40", "12"}, + DeviceLabelFields: []string{"class", "vendor"}, } +var devLabelAttrs = []string{"class", "vendor", "device", "subsystem_vendor", "subsystem_device"} + // Implement FeatureSource interface 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()) } + // 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 _, white := range Config.DeviceClassWhitelist { if strings.HasPrefix(class, strings.ToLower(white)) { 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) { info := pciDeviceInfo{} - attrs := []string{"class", "vendor", "device", "subsystem_vendor", "subsystem_device"} - for _, attr := range attrs { + for _, attr := range devLabelAttrs { data, err := ioutil.ReadFile(path.Join(devPath, attr)) if err != nil { return info, fmt.Errorf("Failed to read device %s: %s", attr, err)