mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2024-12-14 11:57:51 +00:00
Add swap support in nfd
This commit is contained in:
parent
e0b8a52f8b
commit
187f65f94e
9 changed files with 86 additions and 1 deletions
|
@ -4,6 +4,9 @@
|
|||
- name: host-boot
|
||||
hostPath:
|
||||
path: "/boot"
|
||||
- name: host-proc-swaps
|
||||
hostPath:
|
||||
path: "/proc/swaps"
|
||||
- name: host-os-release
|
||||
hostPath:
|
||||
path: "/etc/os-release"
|
||||
|
@ -38,6 +41,9 @@
|
|||
- name: host-sys
|
||||
mountPath: "/host-sys"
|
||||
readOnly: true
|
||||
- name: host-proc-swaps
|
||||
mountPath: "/host-proc/swaps"
|
||||
readOnly: true
|
||||
- name: host-usr-lib
|
||||
mountPath: "/host-usr/lib"
|
||||
readOnly: true
|
||||
|
|
|
@ -87,6 +87,9 @@ spec:
|
|||
- name: host-lib
|
||||
mountPath: "/host-lib"
|
||||
readOnly: true
|
||||
- name: host-proc-swaps
|
||||
mountPath: "/host-proc/swaps"
|
||||
readOnly: true
|
||||
{{- if .Values.worker.mountUsrSrc }}
|
||||
- name: host-usr-src
|
||||
mountPath: "/host-usr/src"
|
||||
|
@ -122,6 +125,9 @@ spec:
|
|||
- name: host-lib
|
||||
hostPath:
|
||||
path: "/lib"
|
||||
- name: host-proc/swaps
|
||||
hostPath:
|
||||
path: "/proc/swaps"
|
||||
{{- if .Values.worker.mountUsrSrc }}
|
||||
- name: host-usr-src
|
||||
hostPath:
|
||||
|
|
|
@ -966,6 +966,8 @@ The following features are available for matching:
|
|||
| **`memory.numa`** | attribute | | | NUMA nodes |
|
||||
| | | **`is_numa`** | bool | `true` if NUMA architecture, `false` otherwise |
|
||||
| | | **`node_count`** | int | Number of NUMA nodes |
|
||||
| **`memory.swap`** | attribute | | | Swap enabled on node |
|
||||
| | | **`enabled`** | bool | `true` if swap partition detected, `false` otherwise |
|
||||
| **`network.device`** | instance | | | Physical (non-virtual) network interfaces present in the system |
|
||||
| | | **`name`** | string | Name of the network interface |
|
||||
| | | **`<sysfs-attribute>`** | string | Sysfs network interface attribute, available attributes: `operstate`, `speed`, `sriov_numvfs`, `sriov_totalvfs` |
|
||||
|
|
|
@ -177,6 +177,7 @@ configuration options for details.
|
|||
| **`memory-numa`** | true | Multiple memory nodes i.e. NUMA architecture detected |
|
||||
| **`memory-nv.present`** | true | NVDIMM device(s) are present |
|
||||
| **`memory-nv.dax`** | true | NVDIMM region(s) configured in DAX mode are present |
|
||||
| **`memory-swap.enabled`** | true | Swap is enabled on the node |
|
||||
|
||||
### Network
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ var (
|
|||
VarDir = HostDir(pathPrefix + "var")
|
||||
// LibDir is where the /lib directory of the system to be inspected is located
|
||||
LibDir = HostDir(pathPrefix + "lib")
|
||||
// ProcDir is where the /proc directory of the system to be inspected is located
|
||||
ProcDir = HostDir(pathPrefix + "proc")
|
||||
)
|
||||
|
||||
// HostDir is a helper for handling host system directories
|
||||
|
|
|
@ -40,6 +40,9 @@ const NvFeature = "nv"
|
|||
// NumaFeature is the name of the feature set that holds all NUMA related features.
|
||||
const NumaFeature = "numa"
|
||||
|
||||
// SwapFeature is the name of the feature set that holds all Swap related features
|
||||
const SwapFeature = "swap"
|
||||
|
||||
// memorySource implements the FeatureSource and LabelSource interfaces.
|
||||
type memorySource struct {
|
||||
features *nfdv1alpha1.Features
|
||||
|
@ -68,6 +71,11 @@ func (s *memorySource) GetLabels() (source.FeatureLabels, error) {
|
|||
labels["numa"] = true
|
||||
}
|
||||
|
||||
// Swap
|
||||
if isSwap, ok := features.Attributes[SwapFeature].Elements["enabled"]; ok && isSwap == "true" {
|
||||
labels["swap"] = true
|
||||
}
|
||||
|
||||
// NVDIMM
|
||||
if len(features.Instances[NvFeature].Elements) > 0 {
|
||||
labels["nv.present"] = true
|
||||
|
@ -93,6 +101,13 @@ func (s *memorySource) Discover() error {
|
|||
s.features.Attributes[NumaFeature] = nfdv1alpha1.AttributeFeatureSet{Elements: numa}
|
||||
}
|
||||
|
||||
// Detect Swap
|
||||
if swap, err := detectSwap(); err != nil {
|
||||
klog.ErrorS(err, "failed to detect Swap nodes")
|
||||
} else {
|
||||
s.features.Attributes[SwapFeature] = nfdv1alpha1.AttributeFeatureSet{Elements: swap}
|
||||
}
|
||||
|
||||
// Detect NVDIMM
|
||||
if nv, err := detectNv(); err != nil {
|
||||
klog.ErrorS(err, "failed to detect nvdimm devices")
|
||||
|
@ -113,6 +128,20 @@ func (s *memorySource) GetFeatures() *nfdv1alpha1.Features {
|
|||
return s.features
|
||||
}
|
||||
|
||||
// detectSwap detects Swap node information
|
||||
func detectSwap() (map[string]string, error) {
|
||||
procBasePath := hostpath.ProcDir.Path("swaps")
|
||||
lines, err := getNumberOfLinesFromFile(procBasePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read swaps file: %w", err)
|
||||
}
|
||||
// /proc/swaps has a header row
|
||||
// If there is more than a header then we assume we have swap.
|
||||
return map[string]string{
|
||||
"enabled": strconv.FormatBool(lines > 1),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// detectNuma detects NUMA node information
|
||||
func detectNuma() (map[string]string, error) {
|
||||
sysfsBasePath := hostpath.SysfsDir.Path("bus/node/devices")
|
||||
|
@ -166,6 +195,14 @@ func readNdDeviceInfo(path string) nfdv1alpha1.InstanceFeature {
|
|||
return *nfdv1alpha1.NewInstanceFeature(attrs)
|
||||
}
|
||||
|
||||
func getNumberOfLinesFromFile(path string) (int, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(strings.Split(string(data), "\n")), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
source.Register(&src)
|
||||
}
|
||||
|
|
|
@ -31,5 +31,33 @@ func TestMemorySource(t *testing.T) {
|
|||
|
||||
assert.Nil(t, err, err)
|
||||
assert.Empty(t, l)
|
||||
|
||||
}
|
||||
|
||||
func TestGetNumberofLinesFromFile(t *testing.T) {
|
||||
type testCase struct {
|
||||
path string
|
||||
expectedLines int
|
||||
expectErr bool
|
||||
}
|
||||
tc := []testCase{
|
||||
{
|
||||
path: "testdata/swap",
|
||||
expectedLines: 2,
|
||||
},
|
||||
{
|
||||
path: "testdata/noswap",
|
||||
expectedLines: 1,
|
||||
},
|
||||
{
|
||||
path: "file_not_exist",
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
for _, tc := range tc {
|
||||
actual, err := getNumberOfLinesFromFile(tc.path)
|
||||
if tc.expectErr {
|
||||
assert.NotNil(t, err, "should get an error")
|
||||
}
|
||||
assert.Equal(t, tc.expectedLines, actual, "lines should match")
|
||||
}
|
||||
}
|
||||
|
|
1
source/memory/testdata/noswap
vendored
Normal file
1
source/memory/testdata/noswap
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Filename Type Size Used Priority
|
2
source/memory/testdata/swap
vendored
Normal file
2
source/memory/testdata/swap
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
Filename Type Size Used Priority
|
||||
dummyfile partition 65555 0 -1
|
Loading…
Reference in a new issue