From 8f23fff1c93bc4767ae7f68d20bc8a7991397c2a Mon Sep 17 00:00:00 2001 From: henrygd Date: Fri, 27 Feb 2026 13:48:42 -0500 Subject: [PATCH] refactor: mdraid comments and organization also hide serial / firmware in smart details if empty, remove a few unnecessary ops, and add a few more passed state values --- agent/file_utils.go | 24 ---------- agent/fs_utils.go | 41 ++++++++++++++++ agent/mdraid_linux.go | 36 +++++--------- .../components/routes/system/smart-table.tsx | 48 +++++++++++-------- 4 files changed, 80 insertions(+), 69 deletions(-) delete mode 100644 agent/file_utils.go create mode 100644 agent/fs_utils.go diff --git a/agent/file_utils.go b/agent/file_utils.go deleted file mode 100644 index 89dc4692..00000000 --- a/agent/file_utils.go +++ /dev/null @@ -1,24 +0,0 @@ -package agent - -import ( - "os" - "strings" -) - -func readStringFile(path string) string { - content, _ := readStringFileOK(path) - return content -} - -func readStringFileOK(path string) (string, bool) { - b, err := os.ReadFile(path) - if err != nil { - return "", false - } - return strings.TrimSpace(string(b)), true -} - -func fileExists(path string) bool { - _, err := os.Stat(path) - return err == nil -} diff --git a/agent/fs_utils.go b/agent/fs_utils.go new file mode 100644 index 00000000..4b954fc6 --- /dev/null +++ b/agent/fs_utils.go @@ -0,0 +1,41 @@ +package agent + +import ( + "os" + "strconv" + "strings" +) + +// readStringFile returns trimmed file contents or empty string on error. +func readStringFile(path string) string { + content, _ := readStringFileOK(path) + return content +} + +// readStringFileOK returns trimmed file contents and read success. +func readStringFileOK(path string) (string, bool) { + b, err := os.ReadFile(path) + if err != nil { + return "", false + } + return strings.TrimSpace(string(b)), true +} + +// fileExists reports whether the given path exists. +func fileExists(path string) bool { + _, err := os.Stat(path) + return err == nil +} + +// readUintFile parses a decimal uint64 value from a file. +func readUintFile(path string) (uint64, bool) { + raw, ok := readStringFileOK(path) + if !ok { + return 0, false + } + parsed, err := strconv.ParseUint(raw, 10, 64) + if err != nil { + return 0, false + } + return parsed, true +} diff --git a/agent/mdraid_linux.go b/agent/mdraid_linux.go index 08a402e4..184d1e77 100644 --- a/agent/mdraid_linux.go +++ b/agent/mdraid_linux.go @@ -16,7 +16,6 @@ import ( var mdraidSysfsRoot = "/sys" type mdraidHealth struct { - name string level string arrayState string degraded uint64 @@ -28,6 +27,7 @@ type mdraidHealth struct { capacity uint64 } +// scanMdraidDevices discovers Linux md arrays exposed in sysfs. func scanMdraidDevices() []*DeviceInfo { blockDir := filepath.Join(mdraidSysfsRoot, "block") entries, err := os.ReadDir(blockDir) @@ -58,6 +58,7 @@ func scanMdraidDevices() []*DeviceInfo { return devices } +// collectMdraidHealth reads mdraid health and stores it in SmartDataMap. func (sm *SmartManager) collectMdraidHealth(deviceInfo *DeviceInfo) (bool, error) { if deviceInfo == nil || deviceInfo.Name == "" { return false, nil @@ -115,19 +116,16 @@ func (sm *SmartManager) collectMdraidHealth(deviceInfo *DeviceInfo) (bool, error if health.level != "" { data.ModelName = "Linux MD RAID (" + health.level + ")" } - data.SerialNumber = "" - data.FirmwareVersion = "" data.Capacity = health.capacity - data.Temperature = 0 data.SmartStatus = status data.DiskName = filepath.Join("/dev", base) data.DiskType = "mdraid" data.Attributes = attrs - sm.SmartDataMap[key] = data return true, nil } +// readMdraidHealth reads md array health fields from sysfs. func readMdraidHealth(blockName string) (mdraidHealth, bool) { var out mdraidHealth @@ -141,7 +139,6 @@ func readMdraidHealth(blockName string) (mdraidHealth, bool) { return out, false } - out.name = blockName out.arrayState = arrayState out.level = readStringFile(filepath.Join(mdDir, "level")) out.syncAction = readStringFile(filepath.Join(mdDir, "sync_action")) @@ -165,6 +162,7 @@ func readMdraidHealth(blockName string) (mdraidHealth, bool) { return out, true } +// mdraidSmartStatus maps md state/sync signals to a SMART-like status. func mdraidSmartStatus(health mdraidHealth) string { state := strings.ToLower(strings.TrimSpace(health.arrayState)) switch state { @@ -174,18 +172,18 @@ func mdraidSmartStatus(health mdraidHealth) string { if health.degraded > 0 { return "FAILED" } - switch strings.ToLower(strings.TrimSpace(health.syncAction)) { case "resync", "recover", "reshape", "check", "repair": return "WARNING" } - - if state == "clean" || state == "active" || state == "readonly" { + switch state { + case "clean", "active", "active-idle", "write-pending", "read-auto", "readonly": return "PASSED" } return "UNKNOWN" } +// isMdraidBlockName matches /dev/mdN-style block device names. func isMdraidBlockName(name string) bool { if !strings.HasPrefix(name, "md") { return false @@ -202,18 +200,7 @@ func isMdraidBlockName(name string) bool { return true } -func readUintFile(path string) (uint64, bool) { - raw, ok := readStringFileOK(path) - if !ok { - return 0, false - } - parsed, err := strconv.ParseUint(strings.TrimSpace(raw), 10, 64) - if err != nil { - return 0, false - } - return parsed, true -} - +// readMdraidBlockCapacityBytes converts block size metadata into bytes. func readMdraidBlockCapacityBytes(blockName, root string) (uint64, bool) { sizePath := filepath.Join(root, "block", blockName, "size") lbsPath := filepath.Join(root, "block", blockName, "queue", "logical_block_size") @@ -222,15 +209,14 @@ func readMdraidBlockCapacityBytes(blockName, root string) (uint64, bool) { if !ok { return 0, false } - sectors, err := strconv.ParseUint(strings.TrimSpace(sizeStr), 10, 64) + sectors, err := strconv.ParseUint(sizeStr, 10, 64) if err != nil || sectors == 0 { return 0, false } - lbsStr, ok := readStringFileOK(lbsPath) logicalBlockSize := uint64(512) - if ok { - if parsed, err := strconv.ParseUint(strings.TrimSpace(lbsStr), 10, 64); err == nil && parsed > 0 { + if lbsStr, ok := readStringFileOK(lbsPath); ok { + if parsed, err := strconv.ParseUint(lbsStr, 10, 64); err == nil && parsed > 0 { logicalBlockSize = parsed } } diff --git a/internal/site/src/components/routes/system/smart-table.tsx b/internal/site/src/components/routes/system/smart-table.tsx index ae422936..dad92bf5 100644 --- a/internal/site/src/components/routes/system/smart-table.tsx +++ b/internal/site/src/components/routes/system/smart-table.tsx @@ -621,8 +621,8 @@ function DiskSheet({ const deviceName = disk?.name || unknown const model = disk?.model || unknown const capacity = disk?.capacity ? formatCapacity(disk.capacity) : unknown - const serialNumber = disk?.serial || unknown - const firmwareVersion = disk?.firmware || unknown + const serialNumber = disk?.serial + const firmwareVersion = disk?.firmware const status = disk?.state || unknown return ( @@ -636,24 +636,32 @@ function DiskSheet({ {model} {capacity} - - - - {serialNumber} - - - Serial Number - - - - - - {firmwareVersion} - - - Firmware - - + {serialNumber && ( + <> + + + + {serialNumber} + + + Serial Number + + + + )} + {firmwareVersion && ( + <> + + + + {firmwareVersion} + + + Firmware + + + + )}