13
votes

Boy, this is such. a. trivial. question, and yet nobody seems to be able to answer it correctly.

How do you swap /dev/sda with /dev/sdb ?

Someone can suggest to use permanent labelling (eg. /dev/disk/by-* ), but despite the best intentions, this does NOT answer the question. Yes, permanent labellings works where you can use them, but if a program is hardcoded to use eg. /dev/sda, this question persists.

To illustrate the problem further from what I found on the internet: http://ubuntuforums.org/showthread.php?t=1569238&page=2 (Reminds me of 'Schadenfreude')

This chap seems to have found the solution, just didn't share it (boo!): http://ubuntuforums.org/showthread.php?t=944515

And tbh, I have a potential similar hazard. I use CloneZilla, and if a program asks: Would you like to backup /dev/sda to /dev/sdb or /dev/sdb to /dev/sda ?, guess how nervous I get knowing that linux seems to randomly assign disk orders. I haven't overwritten my data with my own backup yet, but this is just waiting to happen.

What within Linux assigns /dev/sd* to disks, and how do you influence this process? Has this got something to do with udev (/etc/udev/, udevadm)? My OS is CentOS, but I need to know this also for Ubuntu and CloneZilla (http://clonezilla.org), and this problem occurs on all systems, so my guess is that this problem is not related to the distribution, but rather to the kernel, kernel modules, or something very close to the kernel. Please help!

------------------ EDIT: 25 August 2013 After advising the link that ypnos gave, I read it all, tried out one command, and the kernel just 'vommitted' udev rules all over my screen. Then prompted for root password to allow maintenance, or exit for restart. This is evidence that this stuff is indeed not for the Novice person.

I also looked it up a bit further. I don't understand how or when the linux kernel loads, but several messages on the internet indicate that the BIOS (!! believe it or not) is passing the list of booteable disks down to grub, which then uses the device.map file to assign which devices to which grub (hd*,). Note that /dev/sd have already been defined at this stage, as you can use permanent dev symlinks. These device maps seem to somehow pass on to the actual root file system. So is this a bootloader thing now?

Going back to the udev as a potential solution, I found a bugreport on google http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=578826, that resulted in a resolution where it was DISadviced to change the udev NAME (that ultimately will become /dev/sd* as we know it).

For the suggested udev MAN pages:

| The following keys can get values assigned:
| 
| NAME
|  The name of the node to be created, or the name the network
|  interface should be renamed to.
   NOTE: changing the kernel-provided name of device nodes
   (except for network devices) is not supported and can result
   in unexpected behavior.
   Today, the kernel defines the device nodes names, and udev
   is expected to only manage the node's permissions and
   additional symlinks.

...But I went out to do it anyway in a slightly altered way.

# vi /etc/udev/rules.d/00-corrections.rules

KERNEL=="sd?", ATTRS{model}=="SAMSUNG SP0411N", NAME="sda"
KERNEL=="sd??", ATTRS{model}=="SAMSUNG SP0411N", NAME="sda%n"
KERNEL=="sda", ATTRS{model}!="SAMSUNG SP0411N", NAME="sdb"
KERNEL=="sda?", ATTRS{model}!="SAMSUNG SP0411N", NAME="sdb%n"

Essentially, what it does is "If model is samsung, assign it NAME sda*. If model is not Samsung, but has been assigned sda*, assign it NAME sdb*." This rule was placed before all other rules as much as possible. Note that I am not sure about this, because there seem to be some 'invisible' rule files also, AND although you have renamed the devices, the kernel somewhere in 'kernel-loaded-memory', still might have the references wrong. This might be evident when you look at the /var/log/boot.log file, where in my case, the beginning it says:

%G      Welcome to [0;36mCentOS[0;39m 
Starting udev: %G[60G[[0;32m  OK  [0;39m]Setting hostname UncleFloServer:  [60G[[0;32m  OK  [0;39m]ERROR: asr: seeking device "/dev/sda" to 5999998795264
ERROR: ddf1: seeking device "/dev/sda" to 5999998795264
ERROR: ddf1: seeking device "/dev/sda" to 5999998664192
ERROR: hpt45x: seeking device "/dev/sda" to 5999998790144
ERROR: isw: seeking device "/dev/sda" to 5999998794752
ERROR: jmicron: seeking device "/dev/sda" to 5999998795264
ERROR: lsi: seeking device "/dev/sda" to 5999998795264
ERROR: nvidia: seeking device "/dev/sda" to 5999998794752
ERROR: pdc: seeking device "/dev/sda" to 137438913024
ERROR: pdc: seeking device "/dev/sda" to 137438920192
ERROR: pdc: seeking device "/dev/sda" to 137438927360
ERROR: pdc: seeking device "/dev/sda" to 137438934528
ERROR: sil: seeking device "/dev/sda" to 5999998795264
ERROR: via: seeking device "/dev/sda" to 5999998795264
Setting up Logical Volume Management:   No volume groups found
[60G[[0;32m  OK  [0;39m]Checking filesystems
_CentOS-6.4-x86_: clean, 85517/655360 files, 662649/2621440 blocks
/dev/sda1: clean, 56/65536 files, 33367/262144 blocks
[60G[[0;32m  OK  [0;39m]Remounting root filesystem in read-write mode:  [60G[[0;32m  OK  [0;39m]Mounting local filesystems:  [60G[[0;32m  OK  [0;39m]Enabling local filesystem quotas:  [60G[[0;32m  OK  [0;39m]Enabling /etc/fstab swaps:  [60G[[0;32m  OK  [0;39m]

Here, my Samsung device is 40GB (that I would like as /dev/sda), and my big Areca Raid is 6TB (that I would like as /dev/sdb).

Some remaining questions remain

  1. What do the errors mean?

  2. Are these errors the cause of the kernel, or the cause of a rule file still running before my 00-corrections.rules from udev?

  3. Do these errors indicate something data- threatening? The Areca partition mounted no problems on one of my folders in fstab.

  4. Is there a better, earlier device-assignment method?

4
Actually, this does sound very close to what I need. But how to use it? en.wikipedia.org/wiki/UdevFlorian Mertens
Sorry, I forgot to mention: The final described 00-corrections.rules from my Edit as of 25 Aug seemed to work, aside from the mentioned errors.Florian Mertens
Instead of trying to get stable device names with udev it is usually easier to use labels or IDs in order to mount filesystems instead of device names. (Or use lvm volumes which also have a static naming).eckes

4 Answers

15
votes

These days, the Linux kernel dynamically populates /dev/ according to UDEV rules.

Let me first explain how device files work. Each device file, typically a block device file, has a major and a minor number. These numbers actually describe what device the file points to. The name does not play any role in this. Let's have a look at our specific case of disks:

# ls -l sd*
brw-rw---- 1 root disk 8, 0 Aug 22 15:45 sda
brw-rw---- 1 root disk 8, 1 Aug 22 15:45 sda1
brw-rw---- 1 root disk 8, 2 Aug 22 15:45 sda2
brw-rw---- 1 root disk 8, 3 Aug 22 15:45 sda3
brw-rw---- 1 root disk 8, 5 Aug 22 15:45 sda5
brw-rw---- 1 root disk 8, 6 Aug 22 15:45 sda6

Here you see that my first disk has various partitions and that I booted on Aug 22, at 3pm, which is when the kernel created the files according to rules. You can also see that the major number is 8 and the minor numbers are used to access partitions (0 pointing to the whole disk). The 'b' in the beginning of each line tells that each of these is a special "block device" file.

As I said, the kernel creates the files dynamically "these days". It was not always like that and it is not like that on other Unix systems. There, files would be created statically, and, the user would create or manipulate these files.

It is perfectly possible to create your own device files, with your own name, and major/minor numbers. See mknod (man mknod) for that. However, after you boot again, your custom files will disappear.

The second possibility is to change UDEV rules. The rules will be processed during system boot, and guarantee you a permanently consistent behavior. A good guide on these rules ca be found here: http://www.reactivated.net/writing_udev_rules.html

You will see that it is possible to define a rule that creates "sda*" given specific hardware info that matches your device. You will need to replace the original rules that would create sda with yours. How this works depends on your distribution.

As I think this is a dangerous business for the novice, I will not explain you specific steps; the document I linked above will give you all information you need, and you should indeed read it all.

2
votes

I have the same problem to exchange the sda and sdb disk name. I tried to write some similar udev rules with the above post on my own HP servers. But I used the size of the disk in /etc/udev/rules.d/00-corrections.rules

KERNEL=="sd?", ATTR{size}=="781357232", NAME="sda"
KERNEL=="sd??", ATTRS{size}=="781357232", NAME="sda%n"
KERNEL=="sda", ATTR{size}=="3125515952", NAME="sdb"
KERNEL=="sda?", ATTRS{size}=="3125515952", NAME="sdb%n"

Before this rule I find the size of devices by cat /sys/block/sda/size and cat /sys/block/sdb/size which is described here : Finding information from sysfs.

But when I try to test the udev rule by udevadm test /sys/block/sdb I see this line in the output:

NAME="sda" ignored, kernel device nodes cannot be renamed; please fix it in /etc/udev/rules.d/00-corrections.rules:1

I have ubuntu 18.04 and I found that this is impossible (at least in ubuntu 18.04) based on this post: Is there a way to change device names in /dev directory?

-1
votes

Why don't you use UUID instead of relying on dynamic assignment ? SD? is always dynamic, while UUID is fixed value and don't change, even if you change, distro or if you install your hard drive in other Linux machine the UUID will be the same.

sudo blkid will show you the UUID then you can use it on you fstab to mount the partitions wherever you want.

-2
votes

As far as I know it's not possible. The system will pick SATA port 1 as SDA and so forth. You can however use smartctl to identify the serial number of SDA/B or flash the drive LEDs where possible.