Skip to content

Commit

Permalink
feat: Make handling of invalid devices configurable
Browse files Browse the repository at this point in the history
Currently, whenever there are devices that are invalid, smartctl_exporter will
log an error stating that the device can not be opened, refering to potential
issues with missing IDENTIFY_DEVICE structures or low-power-mode-devices.

There are, however, also situations where (virtual) devices disappear
from the host and are not properly cleaned up. Here, `open()`ing the
device in smartctl fails with ENXIO, resulting in the error message
"No such device or address" being returned. In this case, the error
just clutters the log output for no reason, as there is no reasonable
action that can be taken.

This MR makes the experienced behavior for such cases configurable.
One can either specify the newly added flag `--smartctl.exclude-enxio`
to ensure that devices with such problems are simply silently ignored,
or decide to ignore the flag and continue experiencing the current
behavior.
  • Loading branch information
Hayajiro committed Jan 29, 2025
1 parent 0c86f73 commit 35746fc
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
10 changes: 10 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ var (
"smartctl.scan-device-type",
"Device type to use during automatic scan. Special by-id value forces predictable device names. (repeatable)",
).Strings()
smartctlExcludeENXIO = kingpin.Flag("smartctl.exclude-enxio",
"Whether or not to exclude devices where open() returns with ENXIO",
).Default("false").Bool()
smartctlFakeData = kingpin.Flag("smartctl.fake-data",
"The device to monitor (repeatable)",
).Default("false").Hidden().Bool()
Expand All @@ -132,6 +135,13 @@ func scanDevices(logger *slog.Logger) []Device {
for _, d := range scanDevices {
deviceName := d.Get("name").String()
deviceType := d.Get("type").String()
deviceOpenError := d.Get("open_error").String()

if *smartctlExcludeENXIO && deviceOpenError == "No such device or address" {
// Ignore devices that do not exist (anymore) or were not properly cleaned up
// This effectively means open(device) returned ENXIO
continue
}

// SATA devices are reported as SCSI during scan - fallback to auto scraping
if deviceType == "scsi" {
Expand Down
2 changes: 1 addition & 1 deletion readjson.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func readSMARTctl(logger *slog.Logger, device Device) (gjson.Result, bool) {

func readSMARTctlDevices(logger *slog.Logger) gjson.Result {
logger.Debug("Scanning for devices")
var scanArgs []string = []string{"--json", "--scan"}
var scanArgs []string = []string{"--json", "--scan-open"}
for _, d := range *smartctlScanDeviceTypes {
scanArgs = append(scanArgs, "--device", d)
}
Expand Down

0 comments on commit 35746fc

Please sign in to comment.