collector/diskstats: Only get device properties from udev

When parsing udev data, skip lines that don't start with `E:`.

Lines prefixed with `E:` represent device properties, as documented in
udevadm(8).

Signed-off-by: Benoît Knecht <bknecht@protonmail.ch>
This commit is contained in:
Benoît Knecht 2022-06-16 11:40:51 +02:00 committed by Johannes 'fish' Ziemke
parent 296aa35dd2
commit 9ec7d6ba3c

View file

@ -38,28 +38,31 @@ const (
diskstatsDefaultIgnoredDevices = "^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$" diskstatsDefaultIgnoredDevices = "^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$"
// udev attributes // See udevadm(8).
udevDMLVLayer = "E:DM_LV_LAYER" udevDevicePropertyPrefix = "E:"
udevDMLVName = "E:DM_LV_NAME"
udevDMName = "E:DM_NAME" // Udev device properties.
udevDMUUID = "E:DM_UUID" udevDMLVLayer = "DM_LV_LAYER"
udevDMVGName = "E:DM_VG_NAME" udevDMLVName = "DM_LV_NAME"
udevIDATA = "E:ID_ATA" udevDMName = "DM_NAME"
udevIDATARotationRateRPM = "E:ID_ATA_ROTATION_RATE_RPM" udevDMUUID = "DM_UUID"
udevIDATASATA = "E:ID_ATA_SATA" udevDMVGName = "DM_VG_NAME"
udevIDATASATASignalRateGen1 = "E:ID_ATA_SATA_SIGNAL_RATE_GEN1" udevIDATA = "ID_ATA"
udevIDATASATASignalRateGen2 = "E:ID_ATA_SATA_SIGNAL_RATE_GEN2" udevIDATARotationRateRPM = "ID_ATA_ROTATION_RATE_RPM"
udevIDATAWriteCache = "E:ID_ATA_WRITE_CACHE" udevIDATASATA = "ID_ATA_SATA"
udevIDATAWriteCacheEnabled = "E:ID_ATA_WRITE_CACHE_ENABLED" udevIDATASATASignalRateGen1 = "ID_ATA_SATA_SIGNAL_RATE_GEN1"
udevIDFSType = "E:ID_FS_TYPE" udevIDATASATASignalRateGen2 = "ID_ATA_SATA_SIGNAL_RATE_GEN2"
udevIDFSUsage = "E:ID_FS_USAGE" udevIDATAWriteCache = "ID_ATA_WRITE_CACHE"
udevIDFSUUID = "E:ID_FS_UUID" udevIDATAWriteCacheEnabled = "ID_ATA_WRITE_CACHE_ENABLED"
udevIDFSVersion = "E:ID_FS_VERSION" udevIDFSType = "ID_FS_TYPE"
udevIDModel = "E:ID_MODEL" udevIDFSUsage = "ID_FS_USAGE"
udevIDPath = "E:ID_PATH" udevIDFSUUID = "ID_FS_UUID"
udevIDRevision = "E:ID_REVISION" udevIDFSVersion = "ID_FS_VERSION"
udevIDSerialShort = "E:ID_SERIAL_SHORT" udevIDModel = "ID_MODEL"
udevIDWWN = "E:ID_WWN" udevIDPath = "ID_PATH"
udevIDRevision = "ID_REVISION"
udevIDSerialShort = "ID_SERIAL_SHORT"
udevIDWWN = "ID_WWN"
) )
type typedFactorDesc struct { type typedFactorDesc struct {
@ -268,7 +271,7 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
continue continue
} }
info, err := udevDeviceInformation(stats.MajorNumber, stats.MinorNumber) info, err := getUdevDeviceProperties(stats.MajorNumber, stats.MinorNumber)
if err != nil { if err != nil {
level.Error(c.logger).Log("msg", "Failed to parse udev info", "err", err) level.Error(c.logger).Log("msg", "Failed to parse udev info", "err", err)
} }
@ -348,7 +351,7 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
return nil return nil
} }
func udevDeviceInformation(major, minor uint32) (udevInfo, error) { func getUdevDeviceProperties(major, minor uint32) (udevInfo, error) {
filename := udevDataFilePath(fmt.Sprintf("b%d:%d", major, minor)) filename := udevDataFilePath(fmt.Sprintf("b%d:%d", major, minor))
data, err := os.Open(filename) data, err := os.Open(filename)
@ -361,13 +364,22 @@ func udevDeviceInformation(major, minor uint32) (udevInfo, error) {
scanner := bufio.NewScanner(data) scanner := bufio.NewScanner(data)
for scanner.Scan() { for scanner.Scan() {
line := scanner.Text()
// We're only interested in device properties.
if !strings.HasPrefix(line, udevDevicePropertyPrefix) {
continue
}
line = strings.TrimPrefix(line, udevDevicePropertyPrefix)
/* TODO: After we drop support for Go 1.17, the condition below can be simplified to: /* TODO: After we drop support for Go 1.17, the condition below can be simplified to:
if name, value, found := strings.Cut(scanner.Text(), "="); found { if name, value, found := strings.Cut(line, "="); found {
info[name] = value info[name] = value
} }
*/ */
if fields := strings.SplitN(scanner.Text(), "=", 2); len(fields) == 2 { if fields := strings.SplitN(line, "=", 2); len(fields) == 2 {
info[fields[0]] = fields[1] info[fields[0]] = fields[1]
} }
} }