
干这行的人应该都有过这种经历业务那边火急火燎地过来说“存储上已经加了盘怎么机器上看不到”你跑到Linux主机上一敲fdisk -l新磁盘连个影子都没有。大部分情况下不是存储没加好而是主机这边的SCSI层压根没去“重新认识”存储甚至存储端可能连你这台主机的HBA卡WWN都没映射对。这篇文章就是来彻底解决这个问题的。我会从HBA卡和WWN的基本概念说起再到具体怎么查看WWN以及如何正确地扫描存储空间让系统识别新磁盘最后把我这些年踩过的坑和排查思路一并整理出来。适合刚接触存储管理的Linux运维也适合那些平时只操作虚拟机、第一次接触FC SAN物理服务器的人。1. 先把概念理清HBA卡和WWN到底是什么1.1 HBA卡在存储链路中的角色HBAHost Bus Adapter主机总线适配器说白了就是服务器和存储阵列之间的“桥”。普通的SATA/SAS硬盘直连时主板上的控制器直接就能识别但在FCFibre Channel光纤通道存储网络中服务器不能直接看到存储设备必须通过光纤线缆连到FC交换机再连到存储阵列的前端端口。而HBA卡就是服务器这一侧负责把PCIe总线上的数据转换成FC协议帧的硬件设备。你可以把HBA卡理解成网卡只不过网卡转的是以太网帧HBA转的是FC帧。常见的HBA卡厂商有QLogic、Emulex现在归Broadcom、Brocade等服务器上几万块钱一块的卡干的活说穿了就是这么回事。还有一部分是CNAConverged Network Adapter融合网卡既能走FCFCoE也能走以太网但在存储层面观察到的方式本质是一样的。1.2 WWN、WWPN、WWNN到底在说谁WWNWorld Wide Name是光纤通道网络中每个设备或端口的全球唯一标识符类似以太网网卡的MAC地址但长度更长通常是8字节64位或16字节128位在FC网络中实际使用的大多是8字节的形式。命名上通常带0x前缀比如0x10000090fa123456看起来是16个十六进制字符其实前面0x后面对应的就是8字节。WWN又分两种WWPNWorld Wide Port Name端口级标识。每块HBA卡上有多少个物理端口就有多少个WWPN。WWNNWorld Wide Node Name节点级标识。它标识的是整个HBA卡设备本身同一块卡上的所有端口通常共享同一个WWNN。为什么这两个要分开因为在FC存储环境里存储阵列做LUN映射时基本上只认WWPN。你把一块双口HBA卡的端口1和端口2分别接到两台FC交换机上存储端做主机组配置时就要让这个“主机”包含这两个WWPN这样两个端口都能看到存储才能做多路径。我在刚开始接触这块时也迷糊过老是混用两个概念直到有一次在存储端把WWNN填进去做映射结果怎么都扫不到盘才彻底记住存储认的是端口级WWPN而不是WWNN。当然也有一些老设备、老存储管理界面会让你填WWNN但绝大多数情况下你要找的是WWPN。1.3 Linux内核里和FC相关的内容Linux系统对FC HBA卡的支持主要靠两个内核模块qla2xxx对应QLogic的卡和lpfc对应Emulex的卡。系统启动时驱动会加载把每个HBA物理端口注册成一个SCSI主机适配器host在/sys/class/scsi_host/目录下面就能看到host0、host1这样的目录每个host对应一个物理端口也对应一个独立的WWPN。在你查看WWN之前先确认驱动加载正常、端口链路起来了否则后面所有操作都是在跟空气较劲。2. 查看HBA卡WWN的实操方法先说结论查看HBA卡WWN最干净、最可靠的方式不是装第三方工具而是直接读内核导出的sysfs接口。以下方法在RHEL、CentOS、Rocky、Ubuntu、SUSE等主流发行版上都通用。2.1 先确认HBA卡被系统识别首先查看系统里有多少个FC HBA端口ls /sys/class/fc_host/正常输出是host0、host1这样的目录。如果这个目录不存在说明系统里没有FC HBA卡或者驱动没加载成功。可以用lspci看硬件本身有没有被识别到lspci | grep -i fibre lspci | grep -i storage controllerQLogic的卡在lspci里一般会显示类似“QLogic Corp. ISP2722-based 16G Fibre Channel to PCIe Adapter”的字段Emulex会显示“Emulex Corporation OneConnect 10Gbps/16Gbps ...”如果是系统里的其他RAID卡也会出现在storage controller下面注意区分。这块卡如果连lspci都看到不那就是硬件层面的事先检查PCIe插槽接触、服务器BIOS里PCI设备是否被禁用等而本文后续所说的查看和扫描就无从谈起。2.2 从sysfs读取WWN确认fc_host目录存在后逐个host读port_name和node_namecat /sys/class/fc_host/host0/port_name cat /sys/class/fc_host/host0/node_name输出是类似这样的0x10000090fa123456 0x20000090fa123456第一个是WWPN第二个是WWNN。如果机器上有多个host就逐个读取。也可以一条命令看全部for host in /sys/class/fc_host/*; do echo $(basename $host) - WWPN: $(cat $host/port_name) WWNN: $(cat $host/node_name); done这里我特别说明一下市面上很多人的习惯是用systool -fc_host host0 -v或者cat /sys/class/fc_host/host0/port_name两者结果一样。但systool需要额外安装sysfsutils工具包有些最小化安装的服务器没有这个命令而/sys目录是内核虚拟文件系统每个Linux都必然存在所以直接用cat是最不会出错的做法。注意port_name文件里读出的是带0x前缀的WWN。在存储阵列上填写主机WWPN时有的存储界面需要带0x有的不需要还有的要求中间加冒号分隔。建议你先确认存储端界面是什么格式要求再对着填免得因为格式问题导致映射不生效。2.3 用systool看更详细的HBA信息如果你需要更多诊断信息比如HBA卡的型号、固件版本、端口状态、协商速率systool确实更方便yum install -y sysfsutils # RHEL系 apt install -f sysfsutils # Debian/Ubuntu systool -fc_host host0 -v输出看到的信息会包括port_name、node_name、port_state、speed等。其中port_state如果是Online说明光纤链路已经和FC交换机成功通信如果是Offline那光纤没通或者交换机端口的zone没放通后面扫描存储也必然失败。说实话生产环境里我用得最多的其实是另外两个文件cat /sys/class/fc_host/host0/port_state cat /sys/class/fc_host/host0/fabric_nameport_state表示链路状态fabric_name表示登录到的FC交换机Fabric的WWN。如果fabric_name为空或者显示0x0000000000000000说明这个HBA端口根本没登录进交换机那查WWN之后再怎么弄也是白搭。2.4 多端口HBA卡如何对应物理位置一块双口HBA卡在系统里通常是两个host比如host0和host1。怎么知道哪个host对应物理上的哪个SFP光模块一个简单思路是看PCI地址再对应到服务器槽位ls -l /sys/class/scsi_host/host0输出中会带一个指向PCI设备的软链接里面能看到类似0000:04:00.0的地址这个代表PCI总线地址。再到服务器BMC/BIOS里看PCI槽位布局图就能对应上物理位置。不过大多数情况下你不用分这么细因为无论哪个物理端口只要链路都是通的存储扫描都能正常工作你要的只是每个端口自己的WWN而已。但如果只有其中一个端口配置了接入交换机、另一个空着那你需要能区分看port_state是Online的那个host对应插线了的端口这样记录WWN时就不会把没接线的端口WWN也交给存储管理员。2.5 再往前一步确认驱动与固件信息想看驱动的模块名、版本可以lsmod | grep -E qla2xxx|lpfc modinfo qla2xxx | grep version这条信息在排查“HBA卡温度过高导致端口随机掉线”之类问题时很有用。但在查看WWN这一步确认驱动加载即可不必深究。3. 扫描存储空间让新LUN现身WWN查到了存储端也告诉你映射已经做好了那下一步就是在Linux主机上扫描存储空间让内核重新去存储那里“串门”把新的LUN拉出来。3.1 扫描前必须做的准备动作先别急着敲扫描命令我遇到过太多因为跳过了这一步而误操作的情况。准备动作不多但每一条都在关键时刻救过我在存储端确认主机WWPN已经加入主机组LUN映射已下发有些存储还需要手动“应用”配置千万别只保存就关界面。在FC交换机侧确认zone已配置主机端口和目标存储前端端口在同一zone内zone配置是实时生效的但有些老交换机需要active保存。在主机上先记录当前磁盘状态最简单是lsblk和fdisk -l各执行一次把输出留存。为什么要留扫描完成后你看到新增了sdd、sde但万一之前就有这些名字呢先留存一份现状快照能避免把老磁盘当新磁盘来折腾。确认多路径软件的状态如果生产环境都在用多路径执行systemctl status multipathd确认进程活着。3.2 核心扫描命令解析扫描FC存储最核心的命令是往sysfs里写“重新扫描”指令echo - - - /sys/class/scsi_host/host0/scan这个命令的意思是让host0这个SCSI主机适配器去总线上的所有target、所有LUN重新扫描一遍。三个“-”依次代表通道channel、目标target、LUNlun写成通配符就表示全部扫描。如果你想精准一点比如存储端告诉你在某个target下新增的LUN ID是5也可以这样echo 0 0 5 /sys/class/scsi_host/host0/scan第一个0是channel第二个0是target这个值一般是存储前端口映射出来的target id第三個5是LUN ID。我自己很少用这种精准模式因为多路径环境下target id不好判断直接用“- - -”扫就行代价只是多占用一点点总线的带宽内核层面不会有其他副作用。如果host0、host1对应两个光纤端口而两个端口都连到了同一个存储那就两个host都扫一遍for host in /sys/class/scsi_host/host*/scan; do echo - - - $host; done注意不要扫/sys/class/scsi_host下面的非FC hosts比如服务器本身的SAS控制器也会注册成host盲目对整个系统所有SCSI主机都扫一遍其实也没问题但生产环境还是精准一点好只扫你自己确认过是FC的那几个host。3.3 扫描后怎么确认是否识别成功扫描命令执行后先等一两秒让内核完成设备注册然后查看新出现的磁盘lsblk fdisk -l lsscsilsscsi这个命令非常直观它把SCSI设备和对应的host、channel、target、lun都列出来。例如输出中出现[2:0:0:5] disk IBM 2107 0000就说明是host2下发现的LUN 5对应一台IBM存储卷。如果输出的sd设备里有新面孔再看lsblk确认大小是不是你刚才在存储上创建的那个LUN容量。我习惯用multipath -ll来看多路径盘multipath -ll输出里如果出现类似mpatha (360050768028103c0b8000000000000) dm-2 IBM,2107说明新盘已经被多路径接管了路径数、设备大小、优先生效路径都显示得很清楚。3.4 关于多路径的一点点补充如果这台机器装了multipath扫描到的新LUN通常不会以裸盘的sdX直接提供服务而是被device-mapper多路径设备名接管比如/dev/mapper/mpatha。真正给数据库、给文件系统用的那块盘是/dev/mapper/下面的设备不是sdX。以下情况可以说明为什么多路径重要线上机器的HBA卡几乎都是至少两个端口接两台交换机存储那边也至少映射给两个前端端口。结果就是你在Linux里会同时看到sdd和sde它们大小一样其实是同一个LUN的两条路径。如果没有多路径软件直接对sdd格式化、挂载是极其危险的做法一旦某根光纤链路中断数据就可能损坏。有了multipath这两条路径被抽象成一个dm设备系统只认那个dm设备某一条路径断了会自动切换不影响业务。这里有个坑需要单独提醒如果你在扫描之前multipathd没起来或者multipath.conf里没有匹配这个盘的配置规则新扫出的盘就会以裸盘形式暴露这样最直接的后果是设备号混乱。也就是说你原本应该用/dev/mapper/mpatha做LVM的现在系统控制不住它了。正确做法是确认multipathd正常、检查multipath -ll之后再做后续动作任何情况下都不要直接对一条路径的sdX做格式化。3.5 通过WWN名找到新磁盘Linux下其实提供了更方便的对应关系扫描成功后/dev/disk/by-id/目录里会生成以wwn开头的符号链接ls -l /dev/disk/by-id/ | grep wwn输出类似wwn-0x60050768028103c0b8000000000000 - ../../sdd这个wwn就是存储LUN的WWN和HBA卡的WWN不是一个概念别搞混。它帮助你确认这个磁盘确实就是存储上那个LUN。在给磁盘分区、建LVM之前建议先看这个链接对应哪个设备确认设备号没有变化。注意每次重启服务器sdX这种设备名都可能因为探测顺序变化而变化但by-id这种方式是稳定的。写fstab、做multipath配置、配LVM时能不用/dev/sdX就不用尽量用/dev/disk/by-id/或/dev/mapper/下的稳定名称。3.6 完整示例从扫描到让LVM识别新空间假设这台机器装了multipath存储上已经把一块新LUN映射给主机LUN大小为500GB现在要在主机上完成扫描并扩展给数据库使用。第一步查看当前SCSI主机和链路状态ls /sys/class/fc_host/ cat /sys/class/fc_host/host0/port_state cat /sys/class/fc_host/host0/fabric_name确认host0、host1都是Online且能连上fabric。第二步扫描所有FC hostfor host in /sys/class/scsi_host/host{0,1}/scan; do echo - - - $host; done第三步等两秒查看新磁盘lsblk lsscsi multipath -ll正常情况下能看到新多路径设备比如mpathb大小500G。第四步把它加入LVM并扩展逻辑卷。如果之前这个卷组里已经有很多物理卷用如下命令pvcreate /dev/mapper/mpathb vgextend vgdata /dev/mapper/mpathb lvextend -l 100%FREE /dev/vgdata/lvdata如果这块盘之前已经做过pv且有数据那就用pvresize扩展pvresize /dev/mapper/mpathb第五步文件系统扩容。XFS用xfs_growfsext4用resize2fsxfs_growfs /data # 如果是XFS挂载点直接扩 resize2fs /dev/vgdata/lvdata # 如果是ext4到这里存储上新加的空间就算真正被系统用上了。3.7 扫描命令以外的另一种方式rescan-scsi-bus.sh部分发行版上有sg3_utils提供的一个脚本叫rescan-scsi-bus.sh在RHEL/CentOS上路径通常是/usr/bin/rescan-scsi-bus.shDebian系在/usr/bin/rescan-scsi-bus.sh也常见。它的本质还是对系统里所有SCSI主机执行扫描但多了对已存在设备大小变化的重扫描逻辑。yum install -y sg3_utils rescan-scsi-bus.sh --all这条命令会遍历所有SCSI主机执行scan。好处是省得自己写循环坏处是它可能把非FC的SCSI主机也扫一遍。如果你明确知道只需要扫FC的host那自己写for循环更精确。我一般把这两种方式结合在一起用先for循环扫FC host然后rescan-scsi-bus.sh --all兜底确保任何设备变更都能被发现。4. 扫不到新盘一套完整的排查思路扫描命令执行完了lsblk还是没看到新盘这是最常见的问题。我从问题表象出发按排查顺序说能省下不少瞎折腾的时间。4.1 先看链路再看映射最后才看主机我见过太多人一上来就在主机端反复扫描、重启服务器折腾两小时还是看不到盘结果一查FC交换机发现zone根本没配。所以请按下面的顺序排查第一步主机端看链路状态和登录状态cat /sys/class/fc_host/host0/port_state cat /sys/class/fc_host/host0/fabric_nameport_state要是Onlinefabric_name要是一串非全0的WWN。如果port_state是Offline说明光纤链路都没通后面就可以不看了先解决物理链路和交换机端口注册的问题。第二步看dmesg里有没有FC登录或SCSI错误信息dmesg | grep -i -E qla2xxx|lpfc|scsi如果看到类似“qla2xxx 0000:04:00.0: entered - aborting the command directly”之类的内容说明链路是好的但可能有命令超时或端口被禁用需要进一步看交换机和存储端的配置。第三步到FC交换机上看主机端口是否登录成功以及zone是否包含目标存储端口。不同厂商交换机命令不同但都会有对应的“show flogi database”和“show zone”之类的功能。这一步需要交换机管理权限如果你是主机运维可以跟网络/存储管理员配合。第四步到存储端确认LUN映射确实包含主机的WWPN很多存储界面需要点“应用”或“确定”才真正生成映射关系而且可能有一定的配置下发延迟等一两分钟再刷新看看。4.2 我扫描了多个host但只有其中一个看到盘这种情况很典型。比如host0扫到了新LUNhost1没扫到。原因很可能是存储端给主机映射时只把WWPN之一加到了主机组里或者FC交换机上zone只包含了主机的一个端口。这时回到第2部分再核对一遍把每个host的WWPN都记下来交给存储管理员确认是否都在主机组里。我碰到的另一个原因是HBA端口速率协商不一致比如交换机端口强制8G、HBA端口协商成了4G也会导致连接不上或掉线但这通常会在FC交换机上有告警日志排查时需要留意。4.3 扫描之后smdev出现了但multipath -ll看不到它先看multipathd是否在运行systemctl status multipathd再确认配置是否有匹配规则。有时候系统自动识别了sdX但没有匹配到multipath.conf里的配置它就会作为普通磁盘暴露。可以把wwid找到手动添加规则然后reload multipathd/sbin/multipath -l /usr/lib/udev/scsi_id -g -u /dev/sdd拿到wwid之后在/etc/multipath.conf里加一条multipaths配置指定alias和wwid然后systemctl reload multipathd这个坑在混合厂商存储环境里特别常见因为Linux默认的配置模板只识别一部分常见的设备类型小众存储需要手动加规则才行。4.4 扩容时发现磁盘容量没变如果原本已经有一个LUN映射给主机后来在存储端把LUN扩容了但主机上看到的大小还是旧值这时要做的不是重新scan整个host而是对这个具体的SCSI设备做rescanecho 1 /sys/block/sdd/device/rescan如果是多路径设备下的路径要分别对每一条路径的sdX执行rescan然后multipathd会自动感知容量变化。之后再multipathd reconfigure pvresize /dev/mapper/mpatha就能看到卷组可用空间变大了。记住一点不要在LVM已经挂载使用的状态下直接做host扫描某些场景下面可能会造成系统I/O路径上的短暂阻塞影响业务。在线扩盘的正确姿势是精准rescan目标设备。4.5 虚拟机上关于HBA和存储扫描的区别如果你是在虚拟机里做测试比如VMware虚机、KVM虚机里试图用本文的方式扫描FC存储需要分辨两种情况虚拟机使用的是虚拟SCSI控制器通常的默认方式这种环境下/sys/class/fc_host/目录不存在也谈不上HBA卡WWN你看到的SCSI设备是虚拟出来的一般不用扫描也能识别新添加的虚拟磁盘。虚拟机直通了物理HBA卡PCI Passthrough这种情况下虚机才能看到真实的FC HBA和WWN扫描方式才和物理机一致。换句话说如果你在VMware ESXi上的虚拟机里找不到fc_host目录不用怀疑操作问题先确认是不是没有做PCI直通。对于直接使用虚拟磁盘的虚机新加虚拟磁盘后只需要在系统里执行echo - - - /sys/class/scsi_host/hostX/scan即可这个操作路径一样但概念上跟FC存储完全是两回事。4.6 扫描FC存储的常见误解有些同事总以为扫描存储就是把服务器重启一下或者重新插拔一下光纤线。这些动作在生产环境里代价非常大而且没必要。理解内核的扫描机制之后你就会明白所谓扫描就是向内核的SCSI子系统发出“重新枚举总线”的请求根本不用动硬件更不用重启。再一个误解是认为WWN只有存储工程师才需要。其实作为Linux运维你必须能随时把本机HBA的WWPN准确报给存储工程师否则存储那边没法做映射两边扯皮半天才发现原来是你没有正确把WWN发给对方。学会自己查WWN很多问题就不再需要拉一堆人开会了。5. 顺手总结几个可靠的小技巧说点实操中值得记住的细节。查看WWN和扫描存储这件事本身命令不多但执行顺序和记录习惯才是真正拉开运维水平的地方。我在处理几百台服务器的存储映射时养成了一套自己的固定流程先把所有主机的WWPN统一记录下来按机器名、机房位置、机房机柜编号整理成表格再发给存储管理员做映射。这个习惯帮我避免过无数次设备搞混、端口搞错的问题。具体记录时推荐用heredoc脚本一次采集所有信息for host in /sys/class/fc_host/*; do echo Host: $(basename $host) echo WWPN: $(cat $host/port_name) echo WWNN: $(cat $host/node_name) echo State: $(cat $host/port_state) echo Speed: $(cat $host/speed) echo --- done执行完之后把输出整理到文档里这就是这台服务器的HBA信息清单。服务器维保更换HBA卡之前也建议先采集这样一份清单换完卡之后对比能快速发现WWN是否变化从而判断需要让存储端运维更新哪些映射关系。扫描存储空间时我的另一个心得是“先并行扫所有FC host不要一个一个试”。有些人不确定哪条链路承载了存储路径就host0扫一下没看到host1扫一下没看到反反复复浪费很多时间。一次性把两个端口都扫了再看结果效率高得多。还有一个我踩过坑的细节扫描之后如果发现新盘但fdisk -l里看不到它的容量大概率是这条路径只是部分LUN映射成功了或者多路径路径数不对。这时用multipath -ll看清楚路径数量理想条件下应该看到两条active路径如果只看到一条说明另一个HBA端口、交换机或者存储前端端口根本没真正连通别急着继续往下做格式化先解决路径问题。最后一个建议也是我反复跟团队强调的在生产环境做任何存储扫描、分区、格式化操作之前保留现场信息是一个好习惯。最简单的做法是执行扫描前把lsblk、multipath -ll、pvs、vgs、df -h这几条命令的输出都重定向到文件留存一旦操作过程中发现不对劲还能回到之前的现场数据对照。扫描命令本身是无害的后续的分区、格式化、挂载才是真正影响数据安全的地方谨慎一点总没有坏处。