diff --git a/README.md b/README.md
index 383b794bb..961381619 100644
--- a/README.md
+++ b/README.md
@@ -172,16 +172,17 @@ such as restricting discovered features with the --label-whitelist option._
### Kernel Features
-| Feature | Attribute | Description |
-| ------- | ----------- | ---------------------------------------------------- |
-| config | NO_HZ | Kernel config option is enabled
-|
| NO_HZ_FULL |
-|
| NO_HZ_IDLE |
-|
| PREEMPT |
-| version | full | Full kernel version as reported by `/proc/sys/kernel/osrelease` (e.g. '4.5.6-7-g123abcde')
-|
| major | First component of the kernel version (e.g. '4')
-|
| minor | Second component of the kernel version (e.g. '5')
-|
| revision | Third component of the kernel version (e.g. '6')
+| Feature | Attribute | Description |
+| ------- | ------------------- | -------------------------------------------- |
+| config | <option name> | Kernel config option is enabled (set 'y' or 'm').
Default options are `NO_HZ`, `NO_HZ_IDLE`, `NO_HZ_FULL` and `PREEMPT`
+| version | full | Full kernel version as reported by `/proc/sys/kernel/osrelease` (e.g. '4.5.6-7-g123abcde')
+|
| major | First component of the kernel version (e.g. '4')
+|
| minor | Second component of the kernel version (e.g. '5')
+|
| revision | Third component of the kernel version (e.g. '6')
+
+Kernel config file to use, and, the set of config options to be detected are
+configurable.
+See [configuration options](#configuration-options) for more information.
### Local (User-specific Features)
@@ -381,7 +382,7 @@ Configuration options specified from the command line will override those read
from the config file.
Currently, the only available configuration options are related to the
-[PCI feature source](#pci-features).
+[PCI](#pci-features) and [Kernel](#kernel-features) feature sources.
## Building from source
diff --git a/main.go b/main.go
index a8b7792df..a088619ec 100644
--- a/main.go
+++ b/main.go
@@ -60,7 +60,8 @@ var (
// Global config
type NFDConfig struct {
Sources struct {
- Pci *pci.NFDConfig `json:"pci,omitempty"`
+ Kernel *kernel.NFDConfig `json:"kernel,omitempty"`
+ Pci *pci.NFDConfig `json:"pci,omitempty"`
} `json:"sources,omitempty"`
}
@@ -223,6 +224,7 @@ func argsParse(argv []string) (args Args) {
// Parse configuration options
func configParse(filepath string, overrides string) error {
+ config.Sources.Kernel = &kernel.Config
config.Sources.Pci = &pci.Config
data, err := ioutil.ReadFile(filepath)
diff --git a/main_test.go b/main_test.go
index 5f36cadde..212f80453 100644
--- a/main_test.go
+++ b/main_test.go
@@ -205,6 +205,9 @@ func TestConfigParse(t *testing.T) {
defer os.Remove(f.Name())
So(err, ShouldBeNil)
f.WriteString(`sources:
+ kernel:
+ configOpts:
+ - "DMI"
pci:
deviceClassWhitelist:
- "ff"`)
@@ -215,6 +218,7 @@ func TestConfigParse(t *testing.T) {
Convey("Should return error", func() {
So(err, ShouldBeNil)
+ So(config.Sources.Kernel.ConfigOpts, ShouldResemble, []string{"DMI"})
So(config.Sources.Pci.DeviceClassWhitelist, ShouldResemble, []string{"ff"})
})
})
diff --git a/node-feature-discovery.conf.example b/node-feature-discovery.conf.example
index a7419c3fb..d510799e6 100644
--- a/node-feature-discovery.conf.example
+++ b/node-feature-discovery.conf.example
@@ -1,4 +1,10 @@
#sources:
+# kernel:
+# kconfigFile: "/path/to/kconfig"
+# configOpts:
+# - "NO_HZ"
+# - "X86"
+# - "DMI"
# pci:
# deviceClassWhitelist:
# - "0200"
diff --git a/source/kernel/kernel.go b/source/kernel/kernel.go
index b308f6638..dc0812a24 100644
--- a/source/kernel/kernel.go
+++ b/source/kernel/kernel.go
@@ -28,16 +28,24 @@ import (
"github.com/kubernetes-incubator/node-feature-discovery/source"
)
-// Default kconfig flags
-var defaultKconfigFlags = [...]string{
- "NO_HZ",
- "NO_HZ_IDLE",
- "NO_HZ_FULL",
- "PREEMPT",
+// Configuration file options
+type NFDConfig struct {
+ KconfigFile string
+ ConfigOpts []string `json:"configOpts,omitempty"`
}
var logger = log.New(os.Stderr, "", log.LstdFlags)
+var Config = NFDConfig{
+ KconfigFile: "",
+ ConfigOpts: []string{
+ "NO_HZ",
+ "NO_HZ_IDLE",
+ "NO_HZ_FULL",
+ "PREEMPT",
+ },
+}
+
// Implement FeatureSource interface
type Source struct{}
@@ -63,9 +71,9 @@ func (s Source) Discover() (source.Features, error) {
}
// Check flags
- for _, flag := range defaultKconfigFlags {
- if _, ok := kconfig[flag]; ok {
- features["config."+flag] = true
+ for _, opt := range Config.ConfigOpts {
+ if _, ok := kconfig[opt]; ok {
+ features["config."+opt] = true
}
}
@@ -121,11 +129,22 @@ func readKconfigGzip(filename string) ([]byte, error) {
func parseKconfig() (map[string]bool, error) {
kconfig := map[string]bool{}
raw := []byte(nil)
+ err := error(nil)
- // First, try to read from /proc as this is the most reliable source
- raw, err := readKconfigGzip("/proc/config.gz")
- if err != nil {
- logger.Printf("ERROR: Failed to read /proc/config.gz: %s", err)
+ // First, try kconfig specified in the config file
+ if len(Config.KconfigFile) > 0 {
+ raw, err = ioutil.ReadFile(Config.KconfigFile)
+ if err != nil {
+ logger.Printf("ERROR: Failed to read kernel config from %s: %s", Config.KconfigFile, err)
+ }
+ }
+
+ // Then, try to read from /proc
+ if raw == nil {
+ raw, err = readKconfigGzip("/proc/config.gz")
+ if err != nil {
+ logger.Printf("Failed to read /proc/config.gz: %s", err)
+ }
}
// Last, try to read from /boot/