How to make sure that certain devices always use the same device file

block-devicedevicesmount

When mounting a hard drive via UUID and another via device file, how can I make sure, that the first one is always /dev/sdaX and the second /dev/sdbX and not the other way round?

Some explanation of what I'm trying to do: I'm plugging together a raspberry pi zero, a USB hub, an external hard drive and a sd card (all powered by a power bank). Then when I power up the raspberry, it should automatically take a backup of the sd card on the external hard drive.
A simplified fstab would look like this:

...
uuid=123123   /mnt/exthd   ntfs   rw,... 0 0
/dev/sdb1     /mnt/sdcard  vfat   ro,... 0 0

I can't mount the sd card via UUID, because it will change when I format the card or of course use another card.

Question is, can I be sure, that the external drive is always mounted using /dev/sda1?

Or do I have to parse for example the output of lsblk, look which device is smaller in size, and use this device file?

Note, that I won't have any feedback from the raspberry or whatever. I have to make sure, this always works. And I think I can do the parsing myself, if necessary. The question is solely, if I have to deal with it or if there's an easier way.

Best Answer

I noticed that the devpath attribute is constant for my USB ports. You could add a new udev rule and create specific symlinks based on the ports the devices are plugged in then. Just add a new file into your /etc/udev/rules.d directory, that looks like this:

#new symlink for my front USB port:
KERNELS=="2-1.8", SUBSYSTEMS=="usb", ATTRS{devpath}=="1.8", SYMLINK+="usb_port1"

and make sure it's name ends in .rules, e.g. port1.rules. From now on you can make the fstab entry using /dev/usb_port1 as any device plugged into that specific port will be listed under said symlink in /dev/ . Same for the SD card and you should be settled.

What is happening is that we check for unique properties of the specific port ( the == parts), and once these match add (+=) a new symlink to /dev/.

The information on attributes you want to match canbe retrieved via udevadm info -a /dev/sdb1 (for a device sdb1). Make sure you take attributes from only one parent device block, and that should be the one that have unique devpath and KERNELS entries - try with a few USB ports if available to see which ones change.

PS: udev will also allow to run a script when plugging in a device - might come in handy for your backup needs. However I do not know if booting your system will count as plugging in, so you'll have to check the behaviour.

Related Question