diff --git a/go.mod b/go.mod index 573c9b3..53d82bd 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/prometheus/client_model v0.4.0 github.com/prometheus/procfs v0.9.0 github.com/prometheus/prom2json v1.3.3 + github.com/safchain/ethtool v0.3.0 github.com/secure-io/sio-go v0.3.1 github.com/shirou/gopsutil/v3 v3.23.1 github.com/tinylib/msgp v1.1.8 diff --git a/go.sum b/go.sum index 84c3e46..3b86ae4 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,8 @@ github.com/prometheus/prom2json v1.3.3 h1:IYfSMiZ7sSOfliBoo89PcufjWO4eAR0gznGcET github.com/prometheus/prom2json v1.3.3/go.mod h1:Pv4yIPktEkK7btWsrUTWDDDrnpUrAELaOCj+oFwlgmc= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0= +github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs= github.com/secure-io/sio-go v0.3.1 h1:dNvY9awjabXTYGsTF1PiCySl9Ltofk9GA3VdWlo7rRc= github.com/secure-io/sio-go v0.3.1/go.mod h1:+xbkjDzPjwh4Axd07pRKSNriS9SCiYksWnZqdnfpQxs= github.com/shirou/gopsutil/v3 v3.23.1 h1:a9KKO+kGLKEvcPIs4W62v0nu3sciVDOOOPUD0Hz7z/4= @@ -109,6 +111,7 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/health.go b/health.go index c546d13..4fce805 100644 --- a/health.go +++ b/health.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2015-2022 MinIO, Inc. +// Copyright (c) 2015-2023 MinIO, Inc. // // This file is part of MinIO Object Storage stack // @@ -232,6 +232,7 @@ type Partition struct { Device string `json:"device,omitempty"` Model string `json:"model,omitempty"` + Revision string `json:"revision,omitempty"` Mountpoint string `json:"mountpoint,omitempty"` FSType string `json:"fs_type,omitempty"` MountOptions string `json:"mount_options,omitempty"` @@ -242,6 +243,14 @@ type Partition struct { InodeFree uint64 `json:"inode_free,omitempty"` } +// NetInfo contains information about a network inerface +type NetInfo struct { + NodeCommon + Interface string `json:"interface,omitempty"` + Driver string `json:"driver,omitempty"` + FirmwareVersion string `json:"firmware_version,omitempty"` +} + // Partitions contains all disk partitions information of a node. type Partitions struct { NodeCommon @@ -249,41 +258,48 @@ type Partitions struct { Partitions []Partition `json:"partitions,omitempty"` } -func getDeviceModel(partDevice string) (string, error) { - var model string - +func getDeviceInfo(partDevice string) (model string, revision string, err error) { partDevName := strings.ReplaceAll(partDevice, devDir, "") devPath := path.Join(sysClassBlock, partDevName, "dev") - _, err := os.Stat(devPath) + _, err = os.Stat(devPath) if err != nil { - return model, err + return } - data, err := ioutil.ReadFile(devPath) + var data []byte + data, err = ioutil.ReadFile(devPath) if err != nil { - return model, err + return } majorMinor := strings.TrimSpace(string(data)) driveInfoPath := runDevDataPfx + majorMinor - f, err := os.Open(driveInfoPath) + var f *os.File + f, err = os.Open(driveInfoPath) if err != nil { - return model, err + return } defer f.Close() buf := bufio.NewScanner(f) for buf.Scan() { field := strings.SplitN(buf.Text(), "=", 2) - if len(field) == 2 && field[0] == "E:ID_MODEL" { - model = field[1] - break + if len(field) == 2 { + if field[0] == "E:ID_MODEL" { + model = field[1] + } + if field[0] == "E:ID_REVISION" { + revision = field[1] + } + if len(model) > 0 && len(revision) > 0 { + break + } } } - return model, err + return } // GetPartitions returns all disk partitions information of a node running linux only operating system. @@ -317,11 +333,11 @@ func GetPartitions(ctx context.Context, addr string) Partitions { Error: err.Error(), }) } else { - var model string + var model, revision string device := parts[i].Device if strings.HasPrefix(device, devDir) && !strings.HasPrefix(device, devLoopDir) { // ignore any error in finding device model - model, _ = getDeviceModel(device) + model, revision, _ = getDeviceInfo(device) } partitions = append(partitions, Partition{ @@ -335,6 +351,7 @@ func GetPartitions(ctx context.Context, addr string) Partitions { InodeTotal: usage.InodesTotal, InodeFree: usage.InodesFree, Model: model, + Revision: revision, }) } } @@ -885,6 +902,7 @@ type SysInfo struct { OSInfo []OSInfo `json:"osinfo,omitempty"` MemInfo []MemInfo `json:"meminfo,omitempty"` ProcInfo []ProcInfo `json:"procinfo,omitempty"` + NetInfo []NetInfo `json:"netinfo,omitempty"` SysErrs []SysErrors `json:"errors,omitempty"` SysServices []SysServices `json:"services,omitempty"` SysConfig []SysConfig `json:"config,omitempty"` diff --git a/net_linux.go b/net_linux.go new file mode 100644 index 0000000..97ea0ae --- /dev/null +++ b/net_linux.go @@ -0,0 +1,52 @@ +//go:build linux +// +build linux + +// Copyright (c) 2015-2023 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package madmin + +import ( + "fmt" + + "github.com/safchain/ethtool" +) + +// GetNetInfo returns information of the given network interface +func GetNetInfo(addr string, iface string) (ni NetInfo) { + ni.Addr = addr + ni.Interface = iface + + ethHandle, err := ethtool.NewEthtool() + if err != nil { + ni.Error = err.Error() + return + } + defer ethHandle.Close() + + di, err := ethHandle.DriverInfo(ni.Interface) + if err != nil { + ni.Error = fmt.Sprintf("Error getting driver info for %s: %s", ni.Interface, err.Error()) + return + } + + ni.Driver = di.Driver + ni.FirmwareVersion = di.FwVersion + + return +} diff --git a/net_nolinux.go b/net_nolinux.go new file mode 100644 index 0000000..ca5e2d3 --- /dev/null +++ b/net_nolinux.go @@ -0,0 +1,35 @@ +//go:build !linux +// +build !linux + +// +// Copyright (c) 2015-2023 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package madmin + +// GetNetInfo returns information of the given network interface +// Not implemented for non-linux platforms +func GetNetInfo(addr string, iface string) NetInfo { + return NetInfo{ + NodeCommon: NodeCommon{ + Addr: addr, + Error: "Not implemented for non-linux platforms", + }, + Interface: iface, + } +}