Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion internal/env.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package internal

import "os"
import (
"os"
"path/filepath"
)

// GetProcPath returns the path stored in HOST_PROC env variable, or /proc if HOST_PROC has not been set.
func GetProcPath() string {
Expand All @@ -15,5 +18,36 @@ func GetSysPath() string {
if hostSys := os.Getenv("HOST_SYS"); hostSys != "" {
return hostSys
}
if prefix := os.Getenv("HOST_MOUNT_PREFIX"); prefix != "" {
return filepath.Join(prefix, "sys")
}
return "/sys"
}

// GetDevPath returns the path of the host /dev tree when telegraf is
// running inside a container. It prefers the explicit HOST_DEV env var
// (matching the gopsutil convention), falls back to
// HOST_MOUNT_PREFIX/dev so a single HOST_MOUNT_PREFIX covers /dev,
// /proc, /sys, /run in one go, and finally defaults to /dev on bare
// metal. See influxdata/telegraf#18671.
func GetDevPath() string {
if hostDev := os.Getenv("HOST_DEV"); hostDev != "" {
return hostDev
}
if prefix := os.Getenv("HOST_MOUNT_PREFIX"); prefix != "" {
return filepath.Join(prefix, "dev")
}
return "/dev"
}

// GetRunPath returns the path of the host /run tree. Mirrors GetDevPath
// and is used by plugins that read /run/udev entries.
func GetRunPath() string {
if hostRun := os.Getenv("HOST_RUN"); hostRun != "" {
return hostRun
}
if prefix := os.Getenv("HOST_MOUNT_PREFIX"); prefix != "" {
return filepath.Join(prefix, "run")
}
return "/run"
}
20 changes: 13 additions & 7 deletions plugins/inputs/diskio/diskio_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"strings"

"golang.org/x/sys/unix"

"github.com/influxdata/telegraf/internal"
)

type diskInfoCache struct {
Expand All @@ -21,8 +23,12 @@ type diskInfoCache struct {
}

func (d *DiskIO) diskInfo(devName string) (map[string]string, error) {
devPath := internal.GetDevPath()
runPath := internal.GetRunPath()
sysPath := internal.GetSysPath()

// Check if the device exists
path := "/dev/" + devName
path := filepath.Join(devPath, devName)
var stat unix.Stat_t
if err := unix.Stat(path, &stat); err != nil {
return nil, fmt.Errorf("error reading %s: %w", path, err)
Expand All @@ -43,10 +49,10 @@ func (d *DiskIO) diskInfo(devName string) (map[string]string, error) {
} else {
major := unix.Major(uint64(stat.Rdev)) //nolint:unconvert // Conversion needed for some architectures
minor := unix.Minor(uint64(stat.Rdev)) //nolint:unconvert // Conversion needed for some architectures
udevDataPath = fmt.Sprintf("/run/udev/data/b%d:%d", major, minor)
udevDataPath = filepath.Join(runPath, "udev", "data", fmt.Sprintf("b%d:%d", major, minor))
if _, err := os.Stat(udevDataPath); err != nil {
// This path failed, try the fallback .udev style (non-systemd)
udevDataPath = "/dev/.udev/db/block:" + devName
udevDataPath = filepath.Join(devPath, ".udev", "db", "block:"+devName)
if _, err := os.Stat(udevDataPath); err != nil {
// Giving up, cannot retrieve disk info
return nil, fmt.Errorf("error reading %s: %w", udevDataPath, err)
Expand All @@ -66,7 +72,7 @@ func (d *DiskIO) diskInfo(devName string) (map[string]string, error) {
// This allows us to also "poison" it during test scenarios
sysBlockPath = ic.sysBlockPath
} else {
sysBlockPath = "/sys/class/block/" + devName
sysBlockPath = filepath.Join(sysPath, "class", "block", devName)
}

devInfo, err := readDevData(sysBlockPath)
Expand Down Expand Up @@ -173,8 +179,8 @@ func resolveName(name string) string {
if !errors.Is(err, fs.ErrNotExist) {
return name
}
// Try to prepend "/dev"
resolved, err = filepath.EvalSymlinks("/dev/" + name)
// Try to prepend the host /dev path (HOST_DEV / HOST_MOUNT_PREFIX).
resolved, err = filepath.EvalSymlinks(filepath.Join(internal.GetDevPath(), name))
if err != nil {
return name
}
Expand All @@ -183,7 +189,7 @@ func resolveName(name string) string {
}

func getDeviceWWID(name string) string {
path := fmt.Sprintf("/sys/block/%s/wwid", filepath.Base(name))
path := filepath.Join(internal.GetSysPath(), "block", filepath.Base(name), "wwid")
buf, err := os.ReadFile(path)
if err != nil {
return ""
Expand Down
Loading