How to apply udev rule to a non-partitioned local disk?

I've made this config in udev:

KERNEL=="sdd", SYMLINK+="QUORUML", OWNER="test", GROUP="gtest", MODE="0660"
KERNEL=="sde", SYMLINK+="QUORUMR", OWNER="test", GROUP="gtest", MODE="0660"

and after, I've added other disk and the new disk became the /dev/sde and the old /dev/sde became /dev/sdf, so the udev rule above became wrong since the name of sde has changed to sdf. How can I insure the correct disk? is there some other id? I've tried something like blkid, but since there is no partition it don't return any id.

[[email protected] rules.d]# blkid /dev/sdd
[[email protected] rules.d]#

I look for something like when there is iscsi disks, we can do it using iscsi id:

KERNEL=="sd?1", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d /dev/$parent", RESULT=="360014054187384e668f45e58d036f19a", SYMLINK+="disk4", OWNER="xxxx", GROUP="xxxx", MODE="0660"

Answers 1

  • You should be matching on SUBSYSTEM=="block", ENV{ID_SERIAL}=="xxx" (the brand/model AND serial number) anyway. Or ENV{ID_SERIAL_SHORT} (only the serial number). Or ENV{ID_WWN} (a globally unique identifier for the drive). Or maybe ENV{ID_PART_TABLE_UUID}.

    I tend to use ID_SERIAL_SHORT because it's unique enough for my needs (drive manufactures tend not to re-use serial numbers and different manufacturers have different styles for their serial numbers), and it's what I print on sticky labels so I can easily identify drives in my hot-swap bays. I don't use the WWNs because IMO they look too much alike, they're hard to distinguish from each other.

    Device names are explicitly not guaranteed to persist across reboots - they often do stay the same for months or even years, but it is not safe to rely on that. Kernel developers have documented and stated several times that there is no guarantee that they won't change the next time you boot. Why? Because a drive might die (or just take a little longer to spin up or respond when the kernel scans for devices), you might add or remove a drive, a new kernel version might detect devices in a different order, or any number of other reasons. This is why the advice for many years now has been "Don't use /dev/sdX names in /etc/fstab. Use a UUID or LABEL". The same advice, use a unique identifier, applies to udev rules.

    You can find the attributes for any given drive with udevadm info /dev/sdX. There's a whole lot of interesting and useful properties/attributes there, but for now I'm only interested in the serial number.

    e.g. I have an 8TB Seagate drive on my system which is currently /dev/sda. I can find its short serial number with:

    $ udevadm info -q property --property=ID_SERIAL_SHORT /dev/sda 
    ID_SERIAL_SHORT=ZA9EL9YL
    

    To use that with a udev rule would look like:

    SUBSYTEM=="block", ENV{ID_SERIAL_SHORT}=="ZA9EL9YL", SYMLINK+="QUORUML", OWNER="test", GROUP="gtest", MODE="0660"
    

    Note the == for the first two attributes, they're a comparison rather than an assignment (See man 7 udev, especially the Operators sub-section).

    If I wanted the full serial number with model etc, I could use the following instead:

    $ udevadm info -q property --property=ID_SERIAL /dev/sda 
    ID_SERIAL=ST8000VN0022-2EL112_ZA9EL9YL
    

    and a udev rule would be something like this:

    SUBSYTEM=="block", ENV{ID_SERIAL}=="ST8000VN0022-2EL112_ZA9EL9YL", SYMLINK+="QUORUML", OWNER="test", GROUP="gtest", MODE="0660"
    

    If I'm making a udev rule for one specific device (or type of device), I find it useful to add a commented out version of the output for udevadm info /dev/name in the rule file, just in case I need it for future reference. Use # for comments.


    BTW, if you need to, you can extract the value alone (without the property name) with tools like awk or cut:

    $ udevadm info -q property --property=ID_SERIAL_SHORT /dev/sda | awk -F= '{print $2}'
    ZA9EL9YL
    
    $ udevadm info -q property --property=ID_SERIAL_SHORT /dev/sda | cut -d= -f2
    ZA9EL9YL
    

Related Questions