From 08dfc80724a6ca8a327298e5c4528c0e691319a0 Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Mon, 24 Aug 2020 11:09:13 +0900 Subject: [PATCH 1/2] lookup kernel builtin modules too --- client/fingerprint/bridge_linux.go | 43 ++++++++++++++++++++++++- client/fingerprint/bridge_linux_test.go | 1 + 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/client/fingerprint/bridge_linux.go b/client/fingerprint/bridge_linux.go index f07d58106..8b8996b46 100644 --- a/client/fingerprint/bridge_linux.go +++ b/client/fingerprint/bridge_linux.go @@ -7,6 +7,7 @@ import ( "regexp" "github.com/hashicorp/nomad/nomad/structs" + "github.com/shirou/gopsutil/host" ) const bridgeKernelModuleName = "bridge" @@ -35,6 +36,20 @@ func (f *BridgeFingerprint) Fingerprint(req *FingerprintRequest, resp *Fingerpri } func (f *BridgeFingerprint) checkKMod(mod string) error { + dynErr := f.checkKDynMod(mod) + if dynErr == nil { + return nil + } + + builtinErr := f.checkKBuiltinMod(mod) + if builtinErr == nil { + return nil + } + + return fmt.Errorf("%v, %v", dynErr, builtinErr) +} + +func (f *BridgeFingerprint) checkKDynMod(mod string) error { file, err := os.Open("/proc/modules") if err != nil { return fmt.Errorf("could not read /proc/modules: %v", err) @@ -51,5 +66,31 @@ func (f *BridgeFingerprint) checkKMod(mod string) error { } } - return fmt.Errorf("could not detect kernel module %s", mod) + return fmt.Errorf("could not detect dynamic kernel module %s", mod) +} + +func (f *BridgeFingerprint) checkKBuiltinMod(mod string) error { + hostInfo, err := host.Info() + if err != nil { + return err + } + + fileName := fmt.Sprintf("/lib/modules/%s/modules.builtin", hostInfo.KernelVersion) + file, err := os.Open(fileName) + if err != nil { + return fmt.Errorf("could not read %s: %v", fileName, err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + pattern := fmt.Sprintf(".+\\/%s.ko$", mod) + for scanner.Scan() { + if matched, err := regexp.MatchString(pattern, scanner.Text()); matched { + return nil + } else if err != nil { + return fmt.Errorf("could not parse %s: %v", fileName, err) + } + } + + return fmt.Errorf("could not detect builtin kernel module %s", mod) } diff --git a/client/fingerprint/bridge_linux_test.go b/client/fingerprint/bridge_linux_test.go index 4e55c92dc..98ead3149 100644 --- a/client/fingerprint/bridge_linux_test.go +++ b/client/fingerprint/bridge_linux_test.go @@ -10,5 +10,6 @@ func TestBridgeFingerprint_checkKMod(t *testing.T) { require := require.New(t) f := &BridgeFingerprint{} require.NoError(f.checkKMod("ip_tables")) + require.NoError(f.checkKMod("bridge")) require.Error(f.checkKMod("nonexistentmodule")) } From 893d4d102f72d043a8e0772e2d51968e0ef5bae6 Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Mon, 24 Aug 2020 12:24:16 +0900 Subject: [PATCH 2/2] refactor lookup code --- client/fingerprint/bridge_linux.go | 42 +++++++------------------ client/fingerprint/bridge_linux_test.go | 1 - 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/client/fingerprint/bridge_linux.go b/client/fingerprint/bridge_linux.go index 8b8996b46..39eeb4e1c 100644 --- a/client/fingerprint/bridge_linux.go +++ b/client/fingerprint/bridge_linux.go @@ -36,12 +36,19 @@ func (f *BridgeFingerprint) Fingerprint(req *FingerprintRequest, resp *Fingerpri } func (f *BridgeFingerprint) checkKMod(mod string) error { - dynErr := f.checkKDynMod(mod) + hostInfo, err := host.Info() + if err != nil { + return err + } + + dynErr := f.checkKModFile(mod, "/proc/modules", fmt.Sprintf("%s\\s+.*$", mod)) if dynErr == nil { return nil } - builtinErr := f.checkKBuiltinMod(mod) + builtinErr := f.checkKModFile(mod, + fmt.Sprintf("/lib/modules/%s/modules.builtin", hostInfo.KernelVersion), + fmt.Sprintf(".+\\/%s.ko$", mod)) if builtinErr == nil { return nil } @@ -49,33 +56,7 @@ func (f *BridgeFingerprint) checkKMod(mod string) error { return fmt.Errorf("%v, %v", dynErr, builtinErr) } -func (f *BridgeFingerprint) checkKDynMod(mod string) error { - file, err := os.Open("/proc/modules") - if err != nil { - return fmt.Errorf("could not read /proc/modules: %v", err) - } - defer file.Close() - - scanner := bufio.NewScanner(file) - pattern := fmt.Sprintf("%s\\s+.*$", mod) - for scanner.Scan() { - if matched, err := regexp.MatchString(pattern, scanner.Text()); matched { - return nil - } else if err != nil { - return fmt.Errorf("could not parse /proc/modules: %v", err) - } - } - - return fmt.Errorf("could not detect dynamic kernel module %s", mod) -} - -func (f *BridgeFingerprint) checkKBuiltinMod(mod string) error { - hostInfo, err := host.Info() - if err != nil { - return err - } - - fileName := fmt.Sprintf("/lib/modules/%s/modules.builtin", hostInfo.KernelVersion) +func (f *BridgeFingerprint) checkKModFile(mod, fileName, pattern string) error { file, err := os.Open(fileName) if err != nil { return fmt.Errorf("could not read %s: %v", fileName, err) @@ -83,7 +64,6 @@ func (f *BridgeFingerprint) checkKBuiltinMod(mod string) error { defer file.Close() scanner := bufio.NewScanner(file) - pattern := fmt.Sprintf(".+\\/%s.ko$", mod) for scanner.Scan() { if matched, err := regexp.MatchString(pattern, scanner.Text()); matched { return nil @@ -92,5 +72,5 @@ func (f *BridgeFingerprint) checkKBuiltinMod(mod string) error { } } - return fmt.Errorf("could not detect builtin kernel module %s", mod) + return fmt.Errorf("could not detect kernel module %s", mod) } diff --git a/client/fingerprint/bridge_linux_test.go b/client/fingerprint/bridge_linux_test.go index 98ead3149..4e55c92dc 100644 --- a/client/fingerprint/bridge_linux_test.go +++ b/client/fingerprint/bridge_linux_test.go @@ -10,6 +10,5 @@ func TestBridgeFingerprint_checkKMod(t *testing.T) { require := require.New(t) f := &BridgeFingerprint{} require.NoError(f.checkKMod("ip_tables")) - require.NoError(f.checkKMod("bridge")) require.Error(f.checkKMod("nonexistentmodule")) }