ScanDevices scans for SMART devices Scan devices using `smartctl --scan -j` If scan fails, return error If scan succeeds, parse the output and update the SmartDevices slice
(force bool)
| 153 | // If scan fails, return error |
| 154 | // If scan succeeds, parse the output and update the SmartDevices slice |
| 155 | func (sm *SmartManager) ScanDevices(force bool) error { |
| 156 | if !force && time.Since(sm.lastScanTime) < 30*time.Minute { |
| 157 | return nil |
| 158 | } |
| 159 | sm.lastScanTime = time.Now() |
| 160 | currentDevices := sm.devicesSnapshot() |
| 161 | |
| 162 | var configuredDevices []*DeviceInfo |
| 163 | if configuredRaw, ok := utils.GetEnv("SMART_DEVICES"); ok { |
| 164 | slog.Info("SMART_DEVICES", "value", configuredRaw) |
| 165 | config := strings.TrimSpace(configuredRaw) |
| 166 | if config == "" { |
| 167 | return errNoValidSmartData |
| 168 | } |
| 169 | |
| 170 | parsedDevices, err := sm.parseConfiguredDevices(config) |
| 171 | if err != nil { |
| 172 | return err |
| 173 | } |
| 174 | configuredDevices = parsedDevices |
| 175 | } |
| 176 | |
| 177 | var ( |
| 178 | scanErr error |
| 179 | scannedDevices []*DeviceInfo |
| 180 | hasValidScan bool |
| 181 | ) |
| 182 | |
| 183 | if sm.smartctlPath != "" { |
| 184 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) |
| 185 | defer cancel() |
| 186 | |
| 187 | cmd := exec.CommandContext(ctx, sm.smartctlPath, "--scan", "-j") |
| 188 | output, err := cmd.Output() |
| 189 | if err != nil { |
| 190 | scanErr = err |
| 191 | } else { |
| 192 | scannedDevices, hasValidScan = sm.parseScan(output) |
| 193 | if !hasValidScan { |
| 194 | scanErr = errNoValidSmartData |
| 195 | } |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | // Add eMMC devices (Linux only) by reading sysfs health fields. This does not |
| 200 | // require smartctl and does not scan the whole device. |
| 201 | if emmcDevices := scanEmmcDevices(); len(emmcDevices) > 0 { |
| 202 | scannedDevices = append(scannedDevices, emmcDevices...) |
| 203 | hasValidScan = true |
| 204 | } |
| 205 | |
| 206 | // Add Linux mdraid arrays by reading sysfs health fields. This does not |
| 207 | // require smartctl and does not scan the whole device. |
| 208 | if raidDevices := scanMdraidDevices(); len(raidDevices) > 0 { |
| 209 | scannedDevices = append(scannedDevices, raidDevices...) |
| 210 | hasValidScan = true |
| 211 | } |
| 212 |