问题现象
在使用LSISAS1068E的服务器上(驱动名称为mptsas),为了业务运行可靠性,将第1、2块盘做RAID1,并且希望把Linux系统安装在RAID1,且硬盘盘符为/dev/sda。
但部署完系统后,发现RAID1的盘符并不是/dev/sda,而是/dev/sdk(假设机器插满12块硬盘),即系统没有部署在RAID1上,而不是安装在了第3块硬盘上。
问题原因
从问题现象看,Linux内核并没有像我们希望的那样给硬盘分配盘符,而是把RAID 1的盘符放在了最后。在文章Linux硬盘盘符分配()介绍了内核给硬盘分配盘符原则,即按照内核扫描到的硬盘顺序,按照/dev/sda,/dev/sdb … …顺序分配盘符。
把RAID 1盘符放到了最后,与LSISAS1068E驱动mptsas有关。我们来看驱动加载过程中调用的扫描硬盘拓扑函数mptsas_scan_sas_topology(),在文件drivers/message/fusion/mptsas.c文件中。
03753:/**
03754:* mptsas_scan_sas_topology-
03755:* @ioc:PointertoMPT_ADAPTERstructure
03757:*
03758:**/
03759:staticvoid
03760:mptsas_scan_sas_topology(MPT_ADAPTER*ioc)
03761:{
03762:structscsi_device*sdev;
03763:inti;
03764:
03765:mptsas_probe_hba_phys(ioc);
03766:mptsas_probe_expanders(ioc);
03767:mptsas_probe_devices(ioc);
03768:
03769:/*
03770:ReportingRAIDvolumes.
03771:*/
03772:if(!ioc–>ir_firmware|| !ioc–>raid_data.pIocPg2 ||
03773:!ioc–>raid_data.pIocPg2->NumActiveVolumes)
03774:return;
03775:for(i=0;iraid_data.pIocPg2->NumActiveVolumes;i++){
03776:sdev=scsi_device_lookup(ioc–>sh,MPTSAS_RAID_CHANNEL,
03777:ioc–>raid_data.pIocPg2->RaidVolume[i].VolumeID,0);
03778:if(sdev){
03779:scsi_device_put(sdev);
03780:continue;
03781:}
03782:printk(MYIOC_s_INFO_FMT“attachingraidvolume,channel%d,”
03783:“id%d\n“,ioc–>name,MPTSAS_RAID_CHANNEL,
03784:ioc–>raid_data.pIocPg2->RaidVolume[i].VolumeID);
03785:scsi_add_device(ioc–>sh,MPTSAS_RAID_CHANNEL,
03786:ioc–>raid_data.pIocPg2->RaidVolume[i].VolumeID,0);
03787:}
03788:}? endmptsas_scan_sas_topology ?
03789:
从上面的代码可以看出驱动先扫描HBA卡下面的设备(3765行)、Expander上的设备(3766行)和直连设备后(3767行),再扫描RAID设备(包括RAID 0,RAID 1和RAID 10)。前面提到内核是按照扫描到的硬盘设备顺序,来顺序分配盘符的,而RAID 1的设备最后才扫描,因此盘符变成了/dev/sdk,而不是/dev/sda。
解决办法
解决办法:在扫描硬盘拓扑函数mptsas_scan_sas_topology()中首先扫描RAID设备即可。
下面是参考修改代码。
04697:/**
04698:* mptsas_scan_sas_topology-
04699:* @ioc:PointertoMPT_ADAPTERstructure
04701:*
04702:**/
04703:staticvoid
04704:mptsas_scan_sas_topology(MPT_ADAPTER*ioc)
04705:{
04706:structscsi_device*sdev;
04707:inti;
04708:
04709:/*ReportRAIDvolumesfirstly*/
04710:/*
04711:ReportingRAIDvolumes.
04712:*/
04713:if(!ioc–>ir_firmware|| !ioc–>raid_data.pIocPg2 ||
04714:!ioc–>raid_data.pIocPg2->NumActiveVolumes)
04715:goto¯noraid;
04716:for(i=0;iraid_data.pIocPg2->NumActiveVolumes;i++){
04717:sdev=scsi_device_lookup(ioc–>sh,MPTSAS_RAID_CHANNEL,
04718:ioc–>raid_data.pIocPg2->RaidVolume[i].VolumeID,0);
04719:if(sdev){
04720:scsi_device_put(sdev);
04721:continue;
04722:}
04723:printk(MYIOC_s_INFO_FMT“attachingraidvolume,channel%d,”
04724:“id%d\n“,ioc–>name,MPTSAS_RAID_CHANNEL,
04725:ioc–>raid_data.pIocPg2->RaidVolume[i].VolumeID);
04726:scsi_add_device(ioc–>sh,MPTSAS_RAID_CHANNEL,
04727:ioc–>raid_data.pIocPg2->RaidVolume[i].VolumeID,0);
04728:}
04729:
04730:
04731:
04732:noraid:
04733:mptsas_probe_hba_phys(ioc);
04734:mptsas_probe_expanders(ioc);
04735:mptsas_probe_devices(ioc);
04736:}? endmptsas_scan_sas_topology ?
对于RHEL6, SLES11系列版本,可使用修改好的mpt-4.26版本,下载请点击:
RHEL5, SLES10系列版本,可下载已修改好的mpt-4.18版本,下载请点击: