go.d smartctl: improve checking scsi-sat in scan (#18269)
Ilya Mashchenko committed
Aug 6, 2024 at 22:40 UTC
b0ce4f395850b2d2ff671a1655e038791179faab
1 file changed
+40
-13
src/go/plugin/go.d/modules/smartctl/scan.go
+40
-13
@@ -5,6 +5,7 @@ package smartctl
5
import (
6
"errors"
7
"fmt"
8
+ "slices"
9
"strings"
10
)
11
@@ -56,21 +57,18 @@ func (s *Smartctl) scanDevices() (map[string]*scanDevice, error) {
57
continue
58
}
59
60
+ if i := slices.IndexFunc(s.ExtraDevices, func(d ConfigExtraDevice) bool { return d.Name == dev.name }); i >= 0 {
61
+ s.Debugf("device %s exists in extra devices", dev.infoName)
62
+ continue
63
+ }
64
+
65
if !scanOpen && dev.typ == "scsi" {
66
// `smartctl --scan` attempts to guess the device type based on the path, but this can be unreliable.
67
// Accurate device type information is crucial because we use the `--device` option to gather data.
68
// Using the wrong type can lead to issues.
69
// For example, using 'scsi' for 'sat' devices prevents `smartctl` from issuing the necessary ATA commands.
64
- d := scanDevice{name: dev.name, typ: "sat"}
65
- if _, ok := s.scannedDevices[d.key()]; ok {
66
- dev.typ = "sat"
67
- } else {
68
- resp, _ := s.exec.deviceInfo(dev.name, dev.typ, s.NoCheckPowerMode)
69
- if resp != nil && isExitStatusHasBit(resp, 2) {
70
- s.Debugf("changing device '%s' type 'scsi' -> 'sat'", dev.name)
71
- dev.typ = "sat"
72
- }
73
- }
70
+
71
+ s.handleGuessedScsiScannedDevice(dev)
72
}
73
74
s.Debugf("smartctl scan found device '%s' type '%s' info_name '%s'", dev.name, dev.typ, dev.infoName)
@@ -81,10 +79,8 @@ func (s *Smartctl) scanDevices() (map[string]*scanDevice, error) {
79
s.Debugf("smartctl scan found %d devices", len(devices))
80
81
for _, v := range s.ExtraDevices {
84
- if v.Name == "" || v.Type == "" {
85
- continue
86
- }
82
dev := &scanDevice{name: v.Name, typ: v.Type, extra: true}
83
+
84
if _, ok := devices[dev.key()]; !ok {
85
devices[dev.key()] = dev
86
}
@@ -96,3 +92,34 @@ func (s *Smartctl) scanDevices() (map[string]*scanDevice, error) {
92
93
return devices, nil
94
}
95
+
96
+func (s *Smartctl) handleGuessedScsiScannedDevice(dev *scanDevice) {
97
+ if dev.typ != "scsi" || s.hasScannedDevice(dev) {
98
+ return
99
+ }
100
+
101
+ d := &scanDevice{name: dev.name, typ: "sat"}
102
+
103
+ if s.hasScannedDevice(d) {
104
+ dev.typ = d.typ
105
+ return
106
+ }
107
+
108
+ resp, _ := s.exec.deviceInfo(dev.name, "sat", s.NoCheckPowerMode)
109
+ if resp == nil || resp.Get("smartctl.exit_status").Int() != 0 {
110
+ return
111
+ }
112
+
113
+ atts, ok := newSmartDevice(resp).ataSmartAttributeTable()
114
+ if !ok || len(atts) == 0 {
115
+ return
116
+ }
117
+
118
+ s.Debugf("changing device '%s' type 'scsi' -> 'sat'", dev.name)
119
+ dev.typ = "sat"
120
+}
121
+
122
+func (s *Smartctl) hasScannedDevice(d *scanDevice) bool {
123
+ _, ok := s.scannedDevices[d.key()]
124
+ return ok
125
+}