我有板载 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.c
在subsys_initcall(ata_init)
drivers/scsi/megaraid/megaraid_sas_base.c
MEGASAS 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/Makefile
scsi之前移动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 规则来生成自己的符号链接吗?您使用什么发行版?
一些链接: