Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture network info in health report #240

Merged
merged 2 commits into from
Oct 30, 2023
Merged
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
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down Expand Up @@ -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=
Expand Down
56 changes: 40 additions & 16 deletions health.go
Original file line number Diff line number Diff line change
@@ -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
//
Expand Down Expand Up @@ -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"`
Expand All @@ -242,48 +243,69 @@ 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

Partitions []Partition `json:"partitions,omitempty"`
}

func getDeviceModel(partDevice string) (string, error) {
var model string
// driveHwInfo contains hardware information about a drive
type driveHwInfo struct {
Model string
Revision string
}

func getDriveHwInfo(partDevice string) (info driveHwInfo, 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" {
info.Model = field[1]
}
if field[0] == "E:ID_REVISION" {
info.Revision = field[1]
}
if len(info.Model) > 0 && len(info.Revision) > 0 {
break
}
}
}

return model, err
return
}

// GetPartitions returns all disk partitions information of a node running linux only operating system.
Expand Down Expand Up @@ -317,11 +339,11 @@ func GetPartitions(ctx context.Context, addr string) Partitions {
Error: err.Error(),
})
} else {
var model string
var di driveHwInfo
device := parts[i].Device
if strings.HasPrefix(device, devDir) && !strings.HasPrefix(device, devLoopDir) {
// ignore any error in finding device model
model, _ = getDeviceModel(device)
di, _ = getDriveHwInfo(device)
}

partitions = append(partitions, Partition{
Expand All @@ -334,7 +356,8 @@ func GetPartitions(ctx context.Context, addr string) Partitions {
SpaceFree: usage.Free,
InodeTotal: usage.InodesTotal,
InodeFree: usage.InodesFree,
Model: model,
Model: di.Model,
Revision: di.Revision,
})
}
}
Expand Down Expand Up @@ -885,6 +908,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"`
Expand Down
52 changes: 52 additions & 0 deletions net_linux.go
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
//

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
}
35 changes: 35 additions & 0 deletions net_nolinux.go
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
//

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,
}
}