2

I have onboard SATA controller, and also an additional RAID controller card:

00:17.0 SATA controller: Intel Corporation Device a282
...
04:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS-3 3108 [Invader] (rev 02)

When linux kernel boots, disks connected on the LSI raid controller are recognized/enumerated first (sda,sdb,...), and disk hanging on the SATA controller after that (sde).

My kernel is monolithic, without loadable modules. Is it possible to tell the kernel, the disk on the SATA controller should be first (sda) ?

What affects the order? Is this just an accident, that LSI raid is recognized first, or can this be changed?

Martin Vegter
  • 358
  • 75
  • 236
  • 411
  • 1
    Can you use an initrd? If so, referencing the partitions using UUID or LABEL might be an easier choice. PARTUUID may work if not, according to this thread. – ErikF Oct 24 '20 at 05:39
  • @ErikF - thanks, but referencing partitions by UUID will not solve my problem. I need the SATA disk to be first (/dev/sda). – Martin Vegter Oct 26 '20 at 05:31
  • Order is first come first served. You can unbind and bind through the sysfs interface (in initramfs, when drives are not yet in use), but you really need to stop relying on drive names. There's too many cases where they can go out of order, so just don't rely on it. – frostschutz Oct 26 '20 at 19:58
  • https://stackoverflow.com/a/11645715/1048799 – rfmodulator Oct 26 '20 at 20:19

2 Answers2

2

I was looking into something similar in the past - changing the order of the disks and the network cards for a monolithic kernel.

The order how the drivers are loaded gets decided during compilation - by initcall_levels (from lower to higher, include/linux/init.h) and then by positions in the Makefiles.

I do not think there is much room for playing with initcall_levels - there are too many dependencies.

SATA level 4 in drivers/ata/libata-core.c at subsys_initcall(ata_init)

MEGASAS level 6 in drivers/scsi/megaraid/megaraid_sas_base.cat module_init(megasas_init)

Pointers in System.map:

ffffffff829545cd t megasas_init
ffffffff8295547c t ata_init
ffffffff829e7688 t __initcall_megasas_init6
ffffffff829e8288 t __initcall_ata_init4

Changing the order in the Makefile should be an option, for example in drivers/net/ethernet/intel/Makefile switching the lines for e1000 and e1000e will change the order for eth0 and eth1 (using net.ifnames=0)

obj-$(CONFIG_E1000) += e1000/
obj-$(CONFIG_E1000E) += e1000e/

So in drivers/Makefile moving ata before scsi

obj-$(CONFIG_ATA)               += ata/
obj-y                           += scsi/

should change the order of the host controllers (SATAs first). Check by

ls -l /sys/class/scsi_host/
lsscsi

But even when having SATA as host0 the disks at LSI controller were found first, I am not sure how the asynchronous SCSI probe works, but adding a little delay (e.g. 700 ms) somewhere at the beginning of megasas_init() in drivers/scsi/megaraid/megaraid_sas_base.c made the SATA disk to be /dev/sda

static int __init megasas_init(void)
{
        int rval;
        msleep(700);
...

I hope it does not cause any issues in the kernel, it worked for me but be careful. Of course there are dependencies, not everything is possible. For example I know when I tried mptsas (drivers/message/fusion/) before scsi, it would compile, but the kernel immediately crashed at boot.

Hope this helps.

1

The only way to achieve this without udev is to change the order of the drivers the kernel loads. Since you want to use a "monolithic" kernel, this is probably not that easy. If you would have the drivers loaded as modules, you could change the order of the modules per /etc/modprobe.*, but this only helps as long as the disks need different drivers. If you add another disk using the same driver, you will have the same problem again.

On systems using systemd-udev it is not possible anymore to change the device-name to a different sd* like you could before (or maybe on current non-systemd-distributions like OpenRC on gentoo or alpine or SysVInit on devuan, …)

Why is it necessary to have the device named as /dev/sda? Can't you use /dev/disk/by-*/* or write you own udev-rules to generate your own symlinks? What distribution are you using?

some links:

blaimi
  • 1,175