UdevNameAttr option of disk plugin is very useful with storage systems. However relying on UdevNameAttr causes problems with partitions because most ID attributes ares exactly same for partitions and disks, for example ID_SERIAL and ID_SCSI_COMPAT are all identical for the disk and it's partitions. The main problem here is that when using ID_SCSI_COMPAT or ID_SERIAL you get multiple updates to the same file and flaky/skewed/erroneous statistics.
This necessitates some sort of additional classification by DEVTYPE and MINOR udev properties, for example if we'd use MINOR when DEVTYPE is "partition" appended to ID_SCSI_COMPAT we'd get a sane formatting like (suppose the disk has 1 partition):
{{ID_SCSI_COMPAT}}-part{{MINOR}}
=> SATA_ST3000DM001-1CH_W1F3P4AY-part1
And when we have DEVTYPE "disk" we can just use ID_SCSI_COMPAT by itself.
This feature would be nice. For my case, I want to use ID_SERIAL since device name often change upon boot. Also, plugins such as smart should also have such capabilities. (hddtemp daemon only reports model, which is unfortunate.)
Indeed. Since udev can assign arbitrary /dev/sd* device names at reboot, which differ from what might be in place before reboot (/dev/sdx being usb drive which was hotplugged, and then becomes /dev/sdc after reboot) the disk stats get all messed up quickly with hddtemp and other disk stat plugins.
I tried to work around this by creating custom udev rules for setting a custom devname for usb sticks, but what I have seen so far indicates its not possible without using a very old udev version.
+1 just spend two hours debugging why my disk stats were all out of whack and I was seeing multiple updates to the same metric names over the wire, turned out to be because UdevNameAttr "ID_SERIAL" pushes out an update for the disk and each partition using the same name.
Fortunately, udev is pluggable so here's a workaround:
cat << EOF > /etc/udev/rules.d/99-ID_SERIAL_PATH.rules
SUBSYSTEM=="block",ENV{DEVTYPE}=="disk",ENV{ID_SERIAL_PATH}="%E{ID_SERIAL}"
SUBSYSTEM=="block",ENV{DEVTYPE}=="partition",ENV{ID_SERIAL_PATH}="%E{ID_SERIAL}-part%E{PARTN}"
EOF
udevadm control --reload-rules && udevadm trigger
Now use UdevNameAttr "ID_SERIAL_PATH" for collectd. Note I haven't tested this for various block device types, such as dm or lvm mapped partitions. I'm using Disk "/^WDC/" to make sure I only match my physical (WD) disks, and this works well enough at the moment.
Most helpful comment
Fortunately, udev is pluggable so here's a workaround:
Now use
UdevNameAttr "ID_SERIAL_PATH"for collectd. Note I haven't tested this for various block device types, such as dm or lvm mapped partitions. I'm usingDisk "/^WDC/"to make sure I only match my physical (WD) disks, and this works well enough at the moment.