mirror of
https://github.com/henrygd/beszel.git
synced 2026-10-02 06:17:47 +02:00
72 lines
1.7 KiB
Go
72 lines
1.7 KiB
Go
//go:build linux
|
|
|
|
package agent
|
|
|
|
import (
|
|
"log/slog"
|
|
"math"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/safchain/ethtool"
|
|
psutilNet "github.com/shirou/gopsutil/v4/net"
|
|
)
|
|
|
|
// correctNvethernetCounters replaces the inflated sysfs byte counters of an
|
|
// nvethernet NIC with its MAC octet counters.
|
|
func correctNvethernetCounters(v *psutilNet.IOCountersStat) {
|
|
tx, rx, ok := readEthtoolMACOctets(v.Name)
|
|
if !ok {
|
|
return
|
|
}
|
|
v.BytesSent = tx
|
|
v.BytesRecv = rx
|
|
}
|
|
|
|
func isNvidiaEthernet(name string) bool {
|
|
if name == "" || strings.Contains(name, "/") {
|
|
return false
|
|
}
|
|
|
|
driverPath := filepath.Join("/sys/class/net", name, "device/driver")
|
|
target, err := os.Readlink(driverPath)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return filepath.Base(target) == "nvethernet"
|
|
}
|
|
|
|
func readEthtoolMACOctets(name string) (tx, rx uint64, ok bool) {
|
|
stats, err := ethtool.Stats(name)
|
|
if err != nil {
|
|
slog.Debug("Failed to read ethtool network counters", "interface", name, "err", err)
|
|
return 0, 0, false
|
|
}
|
|
|
|
tx, okTx := ethtoolCounter(stats, "mmc_tx_octetcount_gb", "mmc_tx_octetcount_gb_h")
|
|
rx, okRx := ethtoolCounter(stats, "mmc_rx_octetcount_gb", "mmc_rx_octetcount_gb_h")
|
|
if !okTx || !okRx {
|
|
return 0, 0, false
|
|
}
|
|
return tx, rx, true
|
|
}
|
|
|
|
// ethtoolCounter combines nvethernet's split MMC counters. The driver accumulates
|
|
// the low and high registers into independent 64-bit fields, so the low value can
|
|
// exceed 32 bits and must be added rather than OR'd into the shifted high word.
|
|
func ethtoolCounter(stats map[string]uint64, lowKey, highKey string) (uint64, bool) {
|
|
low, ok := stats[lowKey]
|
|
if !ok {
|
|
return 0, false
|
|
}
|
|
high, hasHigh := stats[highKey]
|
|
if !hasHigh {
|
|
return low, true
|
|
}
|
|
if high > (math.MaxUint64-low)>>32 {
|
|
return 0, false
|
|
}
|
|
return high<<32 + low, true
|
|
}
|