I have some internal drivers, which typically take the names /dev/sda ... /dev/sdc. However, if I plug in an external HDD and reboot, this gets reordered, with the external drive taking up /dev/sdb for some reason.

Now, I know I can also refer to devices by their UUIDs somehow - but that's difficult to memorize. I want to prevent this reordering - unless I change my internal hardware. At the very least, I want to prevent that external HDD from butting into the first four.

  • 2
    UUIDs or labels are designed specifically for this use case: use them for your internal drives. – jasonwryan May 6 '18 at 20:56
  • @jasonwryan: UUIDs are not memorable, so that's not my use case. Can you link to some information about device "labels"? – einpoklum May 6 '18 at 21:21
  • 2
    UUIDs don't need to be memorable: you don't have to remember them, the kernel does... wiki.archlinux.org/index.php/… – jasonwryan May 6 '18 at 21:23
  • 1
    Read the entire wiki page I linked to: all the options are discussed there. – jasonwryan May 6 '18 at 21:27
  • 2
    To the best of my knowledge, Linux has never made any guarantees about the order of driver loading, other than the lowest-level ones get loaded before the higher-level ones; the naming of drives from different drivers has always been unreliable (my server sometimes enumerates FireWire and USB first, sometimes last; there seems to be no rhyme or reason to it!) If this issue is due to booting issues, you'll probably need an initramfs helper to find the drives based on label/UUID (I use dracut for this.) – ErikF May 7 '18 at 4:58

The /dev/sd* device names are assigned in a first-come, first-served order by default, as the storage controller drivers are initialized. If you have several different storage controllers, you might be able to manipulate their loading order.

If that's not possible, it's time to learn writing udev rules. It's not that difficult.

First, run udevadm info -q all -a -n /dev/sda. This will list all the attributes you can use in identifying the /dev/sda disk for udev. The command will start from the /dev/sda disk device, and then work its way up the device tree, outputting a block of attributes each time. You can use attributes from the first block and one other block of your choice.

The first block is always the actual block device. It tends to not have too many useful attributes, but we can use the SUBSYSTEM attribute to ensure that our rule will only trigger for the actual block device. So the first condition for our udev rule will be SUBSYSTEM=="block".

The second block, for a typical SATA disk, contains information at the sd driver level. It has ATTRS{model} and/or ATTRS{wwid}, which could be used to uniquely identify that particular disk. The ATTRS{wwid} might be a long string with many spaces, but it should include the serial number or other unique identifier for the drive - that would be the best candidate. If the serial number is surrounded by spaces or other unimportant strings, you could match it like this:

ATTRS{wwid}=="*<serial number>*"

Once there are enough conditions to uniquely identify your disk device, you can decide what to do with it. The best solution would probably be to use SYMLINK+="custom_name" to create a link that automatically points to the actual device name, whatever it might be this time.

You could also use something like NAME="sda" to hardcode the actual device name, but if you do that, you'd better to create such rules for all your current disks, so that a disk that does not yet have a custom udev rule would not get an overlapping assignment. (If you do this, you should also update your /etc/fstab to match the new names, and know how to boot from an external media to fix things in case you make a typo. Symlinks are safer in this regard.)

So, for a disk with a serial number S12345 and model string "HyperDisk ", you could assign it an alias name of /dev/dsk_sys with a rule like this:(note: if udevadm info reports that an attribute has trailing spaces, you must either include a wildcard or include them in the rulestring exactly as listed.)

SUBSYSTEM=="block", ATTRS{model}=="HyperDisk   ", ATTRS{wwid}="*S12345*", SYMLINK+="dsk_sys"

Place your custom rules into e.g. /etc/udev/rules.d/custom.rules, then reboot (or perhaps run partprobe /dev/sda) and you now should have a /dev/dsk_sys symlink pointing to that disk - and it will keep pointing to that disk even if the /dev/sd* naming changes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.