[olug] controlling Linux's assignments of sda, sdb, etc.

Lou Duchez lou at paprikash.com
Wed Jul 27 13:52:51 UTC 2011


This issue came up a few months back, and I don't know that any answer 
was confidently arrived at.  Let's say Linux arbitrarily starts changing 
your drive names, so that what was once sda is now sdb, your USB drive 
(formerly sdc) is now sda, and the like.  Is there any way to force 
Linux to assign sda only to one single drive, and never to any other drive?

I think the answer is: it can't be done.  Can anyone confirm?  I say it 
can't be done for the following reasons:

-    Trying to switch sdb to sda via udev, I got the following error 
message:

     udev_event_execute_rules: kernel-provided name 'sdb' and NAME= 
'sda' disagree, please use SYMLINK+= or change the kernel to provide the 
proper name

     That's an interesting error message: it doesn't say to change the 
KERNEL parameter, it says to change the kernel.  As in, I think it's 
telling me I'd have to rebuild the kernel.  If I could simply change the 
KERNEL parameter, I would imagine the error message would recommend 
doing so.

-    I have never been able to change the KERNEL parameter without 
getting an error.

-    Nobody seems to have an example of switching sda and sdb.

So it looks like the solution is to abandon all hope of controlling sda 
and sdb, and instead creating your own symbolic links that you can count 
on.  Then you never reference sda or sdb again because you have reliable 
symbolic links you can use in their place.  Here are the udev rules I 
created on a server with a main drive, a gigantic data drive, and a USB 
drive:

---

# /etc/udev/rules.d/aa-local.rules

KERNEL=="sd[a-z]",      SUBSYSTEM=="block", 
ENV{ID_SERIAL}=="3600508e000000000ebf986dc63d2910f", SYMLINK+="bootdrive"
KERNEL=="sd[a-z][1-9]", SUBSYSTEM=="block", 
ENV{ID_SERIAL}=="3600508e000000000ebf986dc63d2910f", SYMLINK+="bootdrive%n"

KERNEL=="sd[a-z]",      SUBSYSTEM=="block", 
ENV{ID_SERIAL}=="35000cca222df20f5", SYMLINK+="datadrive"
KERNEL=="sd[a-z][1-9]", SUBSYSTEM=="block", 
ENV{ID_SERIAL}=="35000cca222df20f5", SYMLINK+="datadrive%n"

KERNEL=="sd[a-z]",      SUBSYSTEM=="block", 
ENV{ID_MODEL}=="ST31000520AS", SYMLINK+="usbdrive"
KERNEL=="sd[a-z][1-9]", SUBSYSTEM=="block", 
ENV{ID_MODEL}=="ST31000520AS", SYMLINK+="usbdrive%n"

---

The first two lines create "/dev/bootdrive" and partitions like 
"/dev/bootdrive1".  The next two create "datadrive" and its partitions, 
and the last two create "usbdrive" and its partitions.  The only 
question is how to find the serial numbers or model numbers of my 
drives, and it turns out that's pretty simple:

1)    Figure out which drive is currently sda, which is currently sdb, etc.

2)    Run the following to get the ID_SERIAL parameter for sda (and 
modify as appropriate to get sdb or to get an ID_MODEL instead):

     udevadm info --query=env --name=sda | grep ID_SERIAL=

For the USB drives, I am relying on ID_MODEL instead of ID_SERIAL 
because I actually have two identical drives that I use for backups on 
alternating days.  By going after ID_MODEL, Linux doesn't care which of 
the two drives it is, and so treats them exactly the same.





More information about the OLUG mailing list