启动 Linux 内核时更改 SATA 和 RAID 控制器的顺序

启动 Linux 内核时更改 SATA 和 RAID 控制器的顺序

我有板载 SATA 控制器,还有一个额外的 RAID 控制器卡:

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)

当 Linux 内核启动时,首先识别/枚举 LSI raid 控制器上连接的磁盘 ( sda, sdb,...),然后挂在 SATA 控制器上的磁盘 ( sde)。

我的内核是整体的,没有可加载的模块。是否可以告诉内核,SATA 控制器上的磁盘应该是第一个 ( sda) ?

什么影响订单?这只是一个意外,LSI raid 首先被识别,还是可以改变?

答案1

我过去一直在研究类似的事情 - 更改单个内核的磁盘和网卡的顺序。

驱动程序的加载顺序是在编译期间决定的 - 由 initcall_levels (从低到高)include/linux/init.h,然后由 Makefile 中的位置决定。

我认为 initcall_levels 没有太多发挥的空间 - 有太多的依赖项。

SATA 4 级drivers/ata/libata-core.csubsys_initcall(ata_init)

drivers/scsi/megaraid/megaraid_sas_base.cMEGASAS 6 级 module_init(megasas_init)

System.map 中的指针:

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

更改 Makefile 中的顺序应该是一个选项,例如,drivers/net/ethernet/intel/Makefile切换 e1000 和 e1000e 的行将更改 eth0 和 eth1 的顺序(使用 net.ifnames=0)

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

所以在drivers/Makefilescsi之前移动ata

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

应更改主机控制器的顺序(SATA 首先)。检查依据

ls -l /sys/class/scsi_host/
lsscsi

但是,即使将 SATA 作为 host0,首先找到 LSI 控制器上的磁盘,我不确定异步 SCSI 探针如何工作,但在megasas_init() in开头的某处添加一点延迟(例如 700 毫秒)drivers/scsi/megaraid/megaraid_sas_base.c会使 SATA 磁盘成为 /开发/sda

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

我希望它不会在内核中引起任何问题,它对我有用,但要小心。当然有依赖性,并不是一切皆有可能。例如,我知道当我drivers/message/fusion/在 scsi 之前尝试 mptsas ( ) 时,它会编译,但内核在启动时立即崩溃。

希望这可以帮助。

答案2

在没有 udev 的情况下实现此目的的唯一方法是更改​​内核加载的驱动程序的顺序。由于您想使用“整体”内核,这可能并不那么容易。如果您将驱动程序作为模块加载,则可以更改每个模块的顺序/etc/modprobe.*,但这仅在磁盘需要不同驱动程序时才有用。如果您使用相同的驱动程序添加另一个磁盘,您将再次遇到相同的问题。

在使用 systemd-udev 的系统上,不可能再像以前那样将设备名称更改为不同的 sd* (或者可能在当前的非 systemd 发行版上,例如 gentoo 或 alpine 上的 OpenRC 或 devuan 上的 SysVInit,...)

为什么需要将设备命名为/dev/sda?您不能使用/dev/disk/by-*/*或编写自己的 udev 规则来生成自己的符号链接吗?您使用什么发行版?

一些链接:

相关内容