From c170c0d0886980ea577a41ae6d76c349914e80b1 Mon Sep 17 00:00:00 2001 From: joey Date: Fri, 6 Sep 2024 10:02:20 +0800 Subject: [PATCH] recover from hwmon linux read file panic #3108 Signed-off-by: joey --- collector/hwmon_linux.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/collector/hwmon_linux.go b/collector/hwmon_linux.go index ed46f0f808..646e12c372 100644 --- a/collector/hwmon_linux.go +++ b/collector/hwmon_linux.go @@ -18,6 +18,7 @@ package collector import ( "errors" + "fmt" "os" "path/filepath" "regexp" @@ -91,19 +92,29 @@ func addValueFile(data map[string]map[string]string, sensor string, prop string, } // sysReadFile is a simplified os.ReadFile that invokes syscall.Read directly. -func sysReadFile(file string) ([]byte, error) { +func sysReadFile(file string) (b []byte, err error) { f, err := os.Open(file) if err != nil { return nil, err } defer f.Close() + defer func() { + if r := recover(); r != nil { + level.Error(log.NewNopLogger()).Log("msg", "recovered from panic", "err", r) + if rErr, ok := r.(error); ok { + err = rErr + } else { + err = fmt.Errorf("%v", r) + } + } + }() // On some machines, hwmon drivers are broken and return EAGAIN. This causes // Go's os.ReadFile implementation to poll forever. // // Since we either want to read data or bail immediately, do the simplest // possible read using system call directly. - b := make([]byte, 128) + b = make([]byte, 128) n, err := unix.Read(int(f.Fd()), b) if err != nil { return nil, err