diff --git a/pkg/kubelet/util/swap/swap_util.go b/pkg/kubelet/util/swap/swap_util.go index 62aaed45cfc..db7fdc9fcc9 100644 --- a/pkg/kubelet/util/swap/swap_util.go +++ b/pkg/kubelet/util/swap/swap_util.go @@ -17,8 +17,10 @@ limitations under the License. package swap import ( + "bytes" "os" sysruntime "runtime" + "strings" "sync" "k8s.io/apimachinery/pkg/util/version" @@ -83,3 +85,14 @@ func IsTmpfsNoswapOptionSupported(mounter mount.Interface) bool { return tmpfsNoswapOptionSupported } + +// gets /proc/swaps's content as an input, returns true if swap is enabled. +func isSwapOnAccordingToProcSwaps(procSwapsContent []byte) bool { + procSwapsContent = bytes.TrimSpace(procSwapsContent) // extra trailing \n + procSwapsStr := string(procSwapsContent) + procSwapsLines := strings.Split(procSwapsStr, "\n") + + // If there is more than one line (table headers) in /proc/swaps then swap is enabled + klog.InfoS("Swap is on", "/proc/swaps contents", procSwapsStr) + return len(procSwapsLines) > 1 +} diff --git a/pkg/kubelet/util/swap/swap_util_test.go b/pkg/kubelet/util/swap/swap_util_test.go new file mode 100644 index 00000000000..611c464b70f --- /dev/null +++ b/pkg/kubelet/util/swap/swap_util_test.go @@ -0,0 +1,66 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package swap + +import "testing" + +func TestIsSwapEnabled(t *testing.T) { + testCases := []struct { + name string + procSwapsContent string + expectedEnabled bool + }{ + { + name: "empty", + procSwapsContent: "", + expectedEnabled: false, + }, + { + name: "with swap enabled, one partition", + procSwapsContent: ` +Filename Type Size Used Priority +/dev/dm-1 partition 33554428 0 -2 +`, + expectedEnabled: true, + }, + { + name: "with swap enabled, 2 partitions", + procSwapsContent: ` +Filename Type Size Used Priority +/dev/dm-1 partition 33554428 0 -2 +/dev/zram0 partition 8388604 0 100 +`, + expectedEnabled: true, + }, + { + name: "empty lines", + procSwapsContent: ` + +`, + expectedEnabled: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + isEnabled := isSwapOnAccordingToProcSwaps([]byte(tc.procSwapsContent)) + if isEnabled != tc.expectedEnabled { + t.Errorf("expected %v, got %v", tc.expectedEnabled, isEnabled) + } + }) + } +}