☰
跨平台存储对账:Linux与Windows下的WWN号查看指南
2026/10/17 4:39:53 网站建设 项目流程

多年维护SAN存储的老手应该都遇到过这种场景:客户在Windows上明明看到磁盘是“磁盘3”,叫到Linux那边就变成了/dev/sdd,稍不清醒一点,把盘符填错写坏数据也是可能的。要在一堆裸设备里精准认出物理LUN,最靠得住的凭据就是WWN号。它相当于块存储设备的全球唯一身份证,从存储阵列到主机端,从Linux到Windows,只要路径管理没错,WWN永远能对上。

这篇内容我会把Linux和Windows两条线拿到一起说,从最简单的一条命令到生产环境里真正能用的对账方法都过一遍。不是单纯罗列命令,我会把为什么这么查、在什么场景下会踩坑、以及WWN和WWPN之类的概念怎么区分也一并讲清楚。适合刚接手存储环境的新人,也适合正在为双机或跨平台共享存储发愁的同学。

1. 块存储与WWN:先把这个东西的来龙去脉搞清楚

1.1 WWN号到底是什么:一个全球唯一的存储身份证

WWN的全称是World Wide Name,也叫World Wide Identifier。它的格式是一串十六进制数,通常以冒号或连字符分隔,比如5000c50012345678。乍一看像MAC地址,但两者的定位逻辑完全不同。MAC地址是网络接口卡的硬件地址,WWN却是存储设备、光纤通道HBA卡、交换机端口等存储网络对象的身份标识。

在FC(Fibre Channel,光纤通道)和SAS(Serial Attached SCSI)体系里,WWN由IEEE注册的OUI前缀加厂商自定义后缀构成。也就是说,WWN不是随意编的,它带有厂商身份信息,也能保证全局唯一。一个LUN从存储阵列上划分出来,阵列控制端口给它分配一个WWN;主机侧的光纤HBA卡也有自己的WWN,这张卡上的每个物理端口又往往对应一个WWPN(World Wide Port Name)。很多故障排查到最后,问题就出在“WWN”和“WWPN”两个名字没分清上。

块存储里的WWN,实际是存储侧通过SCSI查询命令上报给操作系统的。无论走FC、iSCSI还是SAS协议,只要数据路径是通的,操作系统总能把LUN的标识读出来。Linux的UDEV设施会自动捕获这个标识,Windows的系统设备机制也会把这个标识挂在设备实例上。所以,WWN不依赖人为命名,不依赖操作系统私有配置,它是从存储阵列一直延续到主机上的天然线索。

1.2 跨平台查看WWN的常见场景:从多路径到设备对应

实际工作中,查WWN最常见的场景有这么几类。

第一类是存储多路径配置。服务器同时通过两块HBA接存储,系统里就会看到一个盘的两条路径,比如Linux下的/dev/sda和/dev/sdb其实是同一块LUN的双路径。配置multipath时,系统要用WWN作为设备的唯一定位依据,把所有虚拟盘路径绑定到同一个dm设备上。Windows加载厂商的MPIO驱动后也要基于WWN维护伪设备,才能在盘里看到单一块磁盘。如果两个平台的WWN看不到、认不准,多路径基本没法收尾。

第二类是跨平台共享存储。一套数据库集群,Linux节点跑应用,Windows节点跑管理端,两边同时挂同一批LUN。要确保两边访问的是同一个LUN,光靠设备名称不可靠,靠容量和大小猜更危险。只有把两边的WWN拉出来逐项比对,才能确认磁盘映射关系没有错位。

第三类是资产台账和故障定位。批量接管一套既有环境时,存量裸设备几十个甚至上百个,人工逐个去猜“哪个盘是哪块存储”效率极低。用脚本批量采集所有磁盘的WWN,再和存储侧导出的LUN清单交叉匹配,几分钟就能完成存量盘点。以后哪块盘出现IO异常,直接按WWN去存储侧查状态,比在主机端反复fdisk要快得多。

2. 在Linux上查WWN号:从入门到生产环境的完整打法

2.1 最快速的查法:lsscsi和sysfs

Linux下查WWN,新手最开始接触的往往是lsscsi。绝大多数发行版默认没有装,需要自己装一下:

yum install -y lsscsi # CentOS / RHEL / Rocky 系 apt install -y lsscsi # Debian / Ubuntu 系

装好后执行:

lsscsi --list

能看到大致这样的输出:

[0:0:0:0] disk storageVendor ModelName rev /dev/sda [2:0:0:0] disk storageVendor ModelName rev /dev/sdb

如果加载了多路径,还可以加参数:

lsscsi -v

不是所有lsscsi版本都直接显示WWN,较新版本支持:

lsscsi -i

它输出里会有scsi_id、WWN之类的信息。但不同发行版上lsscsi版本差异比较大,不一定都支持,稳妥的办法还是直接读sysfs。

sysfs是Linux把内核对象导出成文件系统的地方。块设备的信息都在/sys/block下。查某块盘的WWN,可以这样:

cat /sys/block/sda/device/wwid

也有的是:

cat /sys/class/scsi_device/2:0:0:0/device/wwid

这里2:0:0:0是SCSI设备的HBA:总线:目标:LUN地址。看到的结果通常是这样的:

naa.5000c50012345678

注意这个前缀。Linux里存储设备标识经常带协议前缀,naa.表示这是NAA格式的WWN,还有eui.前缀的。比对的WWN号时,不要只对后半段,建议连同前缀一起对比,因为不同工具返回的格式会有细微差别。

SATA盘在/sys/block下通常没有wwid文件,这时可以尝试:

cat /sys/block/sda/device/vpd_pg83

或者使用sg3_utils工具(见下文2.2节)。总之在Linux下,一个通用的排查顺序是:先lsscsi看盘符和SCSI地址,再看/sys/block对应设备的wwid。

2.2 路径细节:/dev/disk/by-id 与 udev 属性

Linux还有一套很直观的查询方式,那就是/dev/disk/by-id目录。几乎所有识别正常、带WWN的磁盘,都会在那里生成一个带WWN的软链接:

ls -l /dev/disk/by-id/

能看到类似这样的条目:

lrwxrwxrwx 1 root root 9 Dec 20 10:25 scsi-35000c50012345678 -> ../../sdg lrwxrwxrwx 1 root root 10 Dec 20 10:25 scsi-35000c50012345678-part1 -> ../../sdg1

看到scsi-3开头后面跟一串数字,那串数字就是WWN号,3表示SCSI规范第3版定义的结构化标识。很多维保脚本判断“某个WWN对应哪个盘符”直接就用这种方式:

ls -l /dev/disk/by-id/ | grep 5000c50012345678

除了这个目录,还可以用udevadm读取设备属性,这是生产环境排障里经常用到的,因为udev属性的字段比一个单独文件要丰富得多:

udevadm info --query=property --name=/dev/sdc | grep -E "ID_WWN|ID_SERIAL|ID_SCSI"

通常输出的内容包含ID_WWN、ID_WWN_WITH_EXTENSION等字段。ID_WWN_WITH_EXTENSION里可能带扩展后缀,它表示某个LUN下更细分的命名空间;在做精确设备匹配时,这个字段有时反而比ID_WWN更可靠。如果你有自己的维护脚本,建议采集时把ID_WWN、ID_WWN_WITH_EXTENSION都记录下来,避免后面遇到“怎么多了一个后缀”的困惑。

这里忍不住提一下:很多新手喜欢直接用fdisk -l或者lsblk看设备,但这两个命令默认不显示WWN。lsblk需要加-S参数:

lsblk -S

它显示的是每个SCSI设备挂载的HBA、通道、LUN序号,也就是模型、序列号等,但不一定都有WWN。和上面几种方法组合起来才能拿到完整信息。

2.3 多路径环境下的WWN读取:multipath ll和scsi_id

服务器接FC存储时几乎都会启用多路径软件。Linux下的device-mapper-multipath用WWN生成映射设备的别名,所以可以直接从multipath的输出来反查WWN:

multipath -ll

典型输出:

mpatha (3600508b400105e210000900000fc0000) dm-0 storageVendor,ModelName size=200G features='0' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=1 status=active | `- 1:0:0:0 sda 8:0 active ready running `-+- policy='service-time 0' prio=1 status=enabled `- 1:0:1:0 sdb 8:16 active ready running

括号里的3600508b400105e210000900000fc0000就是WWN,通常3开头是因为它符合SCSI-3的NAA格式。后面可以看到两条路径sda和sdb指向同一个WWN,这就是多路径的正常工作状态。

还有scsi_id命令,它从SCSI层直接读取设备标识:

/usr/lib/udev/scsi_id --page=0x83 --whitelisted --device=/dev/sda

注意不同发行版scsi_id位置有差异,很多在/usr/lib/udev/scsi_id,老一些系统在/sbin/scsi_id。这个命令输出的也是对应该设备的结构化标识之一。在生产环境里,我更习惯用multipath -ll做初步确认,再用scsi_id在单路径设备上验证,因为multipath的映射信息已经是内核层处理过的,基本不会错。

2.4 Linux查WWN的小坑:SATA盘、虚拟磁盘和wwid缺失

Linux下查WWN不是每次都顺顺利利,我实际踩过的坑有几个,拿出来说。

第一,SATA盘经常没有wwid文件。普通SATA盘不是标准的SCSI磁盘,sysfs里不会生成wwid,/dev/disk/by-id下只能看到ata-前缀的软链。这时候要用sg_inq工具去探测:

sg_inq -p 0x83 /dev/sda

sg_inq来自sg3_utils包:

yum install -y sg3_utils

它能直接发SCSI INQUIRY指令给设备,拿到VPD 0x83页,里面有最原始的设备标识符。SATA盘如果支持的话,也能从这里读到带前缀的WWN。

第二,虚拟化平台的虚拟磁盘,比如KVM、VMware的虚拟SCSI盘,不一定向客户机透传WWN。这类盘在Linux下可能只有Vendor和Model,没有真正的全球唯一号。这时候硬要“查WWN”是查不出来的,只能查虚拟化平台里的UUID。两台物理机器上如果都跑虚机、都看到同样的虚拟盘标识,千万别拿它当物理存储层证据。

第三,多路径没配置好时,同一个LUN的多个路径可能会各自自成设备,比如sda和sdb是两个单路径设备,没有合并成mpatha。这时候对每个sd设备分别读wwid,结果会是一样的。有些脚本写得不严谨,只取了其中一个sd设备做WWN对比,一旦两个sd都出现在结果里,记录就会混乱。所以写采集脚本时一定要对WWN去重,最终以dm设备或by-id链接为准。

3. 在Windows上查WWN号:别只盯着磁盘管理那一个地方

3.1 PowerShell里的快速解法:Get-Disk与UniqueId

Windows下查WWN,最直接的是PowerShell的Get-Disk。打开管理员模式的PowerShell窗口,执行:

Get-Disk | Select-Object Number, FriendlyName, UniqueId, BusType, HealthStatus

输出的UniqueId字段就是WWN。比如:

Number FriendlyName UniqueId BusType ------ ------------ -------- ------- 0 ST2000NM0011 5000C50012345678 SAS 1 storageVendor ModelName 5000C50087654321 Fibre Channel

需要注意的是:UniqueId不是在所有操作系统版本上都是WWN格式。Windows Server 2012之后的版本,对FC/SAS盘,UniqueId基本就是WWN那串十六进制数;对某些老设备或非标准设备,可能会显示一串带“Id:”前缀的字符串。这和Linux的naa.前缀有些类似,但Windows拿来显示的字段更裸一些,有时就只是数字。

还可以用更精细的格式化输出,展示成表格或导出CSV资产台账:

Get-Disk | Select-Object Number, @{N='WWN';E={$_.UniqueId -replace '^Id:',''}}, FriendlyName, Size, BusType | Export-Csv -Path disk-wwan.csv -NoTypeInformation

这就相当实用了。Windows图形界面里磁盘管理看不到WWN,因为磁盘管理面板倾向于显示磁盘号、容量和总线类型,基本不显示标识符。想在图形界面看,得要打开设备管理器,在磁盘驱动器列表里双击具体磁盘,查看详细信息,选“设备实例路径”,有时能看到带PCI标识的路径;但那个字段太底层,包含了很多主机端PCI地址信息,不如Get-Disk直接。

3.2 WMI与注册表:拿到更深一层的设备标识

PowerShell的Get-Disk封装了好几个底层来源,有时候它给出的UniqueId不是我们想要的WWN,而是另一个叫“DeviceId”的值。这时可以绕到底层WMI去查:

Get-WmiObject Win32_DiskDrive | Select-Object DeviceID, Model, SerialNumber, InterfaceType

这个输出的SerialNumber字段更接近硬件序列号,但不是WWN。要看到WWN,可以用更底层的MSFT_Disk:

Get-CimInstance -ClassName MSFT_Disk -Namespace root/microsoft/windows/storage | Select-Object Number, FriendlyName, UniqueId, BusType

MSFT_Disk的UniqueId和Get-Disk的UniqueId来源一致,所以正常情况两者能对上。如果Get-Disk在某些环境下报错,这个CIM查询可以作为替代方案。

还有少见的注册表方式。磁盘的标识信息会出现在设备实例相关的注册表项里,但路径深且字段编码不直观,一般不建议日常去翻。只有做底层设备驱动排障时才会用到,这里不展开。

3.3 HBA卡层面的WWPN查看办法

前面说的都是LUN的WWN,其实HBA卡端口自己的WWPN也是存储运维里的常见查询项。Windows下查看HBA端口的WWPN,单靠PowerShell原生命令不够,通常用HBA厂商提供的管理工具,比如某些HBA厂商的管理软件。也可以查看系统里的FC端口设备实例详情。

如果装了厂商工具,一般会有类似这样的命令或GUI界面查看端口WWN:

# 示意,实际工具名随厂商而变化 Get-HbaPort QLogic.Cmdlets 的管理命令

这类工具的准确名称不同厂商不一样,因此不能直接给固定命令。但原理是一样的:HBA卡驱动会向操作系统暴露一个或多个端口属性,所有管理工具最终读取的都是内核驱动报告的值。

为什么协作时HBA的WWPN这么重要?因为存储阵列侧做LUN映射时,看的是“哪个WWPN能访问哪个LUN”,而不是看主机名或IP。如果Windows换了块HBA,WWPN变了,即便主机名还是那台机器,阵列上的映射也可能会丢失。所以换卡前,记录旧WWPN,在阵列GUI里修改映射关系,再拔旧卡,这是存储工程师的铁律。

3.4 Windows环境里的常见坑:总线类型、重复UniqueId等

Windows查WWN时,有几个实际问题很常见。

其一,UniqueId可能出现重复。Windows下某些老版本系统或特殊驱动下,不同磁盘的UniqueId可能都是同一种格式的占位符,比如直接显示BusType为“File Backed Virtual”的虚拟盘。这种情况下用WWN鉴别多个磁盘会失效,你得换用SerialNumber字段配合容量综合判断。

其二,iSCSI盘的UniqueId不是传统WWN。iSCSI LUN的标识符格式可能是“iqn.”之类,和FC/SAS的WWN格式相差很多。如果你拿FC盘的WWN格式去找iSCSI盘的UniqueId,找不到很正常,它们本质是两套命名体系。

其三,Windows显示格式和Linux不一致。举例来说,Linux侧是naa.5000c50012345678,Windows侧可能是5000c50012345678,少了前缀。你用“包含匹配”方法比对是可以的,但直接做字符串完全相等就会失败。记账脚本里务必统一做去前缀处理,这是跨平台对账最容易漏的细节。

4. 跨平台对账:如何让Linux和Windows指向同一个LUN

4.1 一台机器部署Linux、一台部署Windows时的WWN对照表

很多业务环境是Linux机器做数据节点、Windows机器做管理节点,两边同时挂同一批存储LUN。这时候需要一个稳定的对账流程。

基本做法是:两边各自生成WWN清单,然后按WWN匹配。Linux侧执行:

for disk in /sys/block/sd*; do name=$(basename "$disk") wwid=$(cat "$disk/device/wwid" 2>/dev/null) [ -n "$wwid" ] && echo "$name $wwid" done | sort -k2

注意这里对wwid做了按WWN排序,方便观察哪些设备WWN重复(也就是多路径)。Windows侧执行类似PowerShell导出:

Get-Disk | Sort-Object UniqueId | Select-Object Number, UniqueId, FriendlyName, Size | Format-Table

两边拿到的清单如果包含同一串WWN,就可以确认是对应同一个LUN。实际操作时,我习惯在Windows侧把UniqueId里的非数字字符清理干净,在Linux侧去掉naa.前缀,两边统一成16位十六进制大写字面量再比对。

为了更直观,可以构建一个这样的对应关系表:

Linux设备Linux WWN(统一格式)Windows唯一ID说明
/dev/sda5000C500123456785000C50012345678FC LUN,多路径合并为mpatha
/dev/sdc5000C500876543215000C50087654321SAS共享LUN
/dev/sde(无)0035a11c-...虚拟磁盘,无物理WWN

4.2 多路径、LUN ID与WWN三者的映射要点

跨平台对账里,最容易混淆的是把WWN、LUN ID和路径ID三者混为一谈。

LUN ID是存储阵列分配LUN的编号,比如“LUN 10”,它只在阵列内部有意义。WWN是这个LUN的身份,在整个SAN网络中唯一。路径ID是操作系统为一条物理IO通路分配的序号,比如Linux的“1:0:0:0”,Windows的“PathId 0”。

这三个值的关系有点像:LUN ID是门牌号,WWN是房产证编号,路径ID是去往这间房的不同路线编号。同一个WWN可以有多条路径,不同路径ID指向同一个LUN ID。在Linux的multipath -ll里,括号内的WWN是唯一识别的核心;在Windows的MPIO配置里,系统会根据WWN把多条路径合并成同一个伪设备。

排查“为什么同一个LUN在Windows里出现好几个磁盘”时,原因往往是MPIO驱动没生效或者没安装。此时Windows不把多路径合并,同一个WWN对应多个磁盘条目。解决的方向不是去修改WWN,而是检查多路径驱动和磁盘管理策略。

4.3 常见场景:从存储划分到OS识别的完整流程

拿一次新增存储LUN的流程举例。在存储侧划好一个200GB的LUN,映射给某台数据库服务器,数据库服务器同时运行Linux和Windows的虚机,虚机使用同一物理HBA。

第一步,在Linux里执行“echo 1 > /sys/class/scsi_device/2:0:0:0/device/rescan”或使用“echo '- - -' > /sys/class/scsi_host/host2/scan”之类的命令重新扫描。新盘会以一个新的sd设备出现。查看lsscsi确认容量200G、SCSI地址和LUN号均匹配。

第二步,在Windows里打开设备管理器,操作“扫描检测硬件改动”(或“重新扫描磁盘”)。此时磁盘管理中会多出一块200GB的未初始化磁盘,磁盘编号可能是新的,也可能是中间空号,不必在意编号位置。

第三步,用Linux的multipath -ll和Windows的Get-Disk分别查看WWN。两边看到的这串200GB对应WWN应该完全一致。此时才算真正确认“存储划出来的LUN到了操作系统里是哪一个”。然后再进行分区格式化、多路径测试、压力读写,才相对安全。如果两边WWN不一致,多半是映射配错或中间还有虚拟化层过滤,千万不要继续初始化磁盘。

5. 常见问题与排查技巧实录

5.1 WWN号对不上?先看是不是WWPN与LUN WWN搞混了

我见过最频繁的“WWN对不上”,根本不是LUN的WWN出问题,而是把WWPN当成了磁盘的WWN。HBA卡端口有自己的WWPN,存储的LUN也有自己的WWN,两边数值完全不同,长度也可能不一样。执行:

cat /sys/class/fc_host/host2/port_name

得到的是HBA端口的WWPN。而:

cat /sys/block/sda/device/wwid

得到的是LUN的WWN。一个是主机侧端口身份,一个是存储LUN身份。如果非要两者相等,自然永远不相等。

正确的对应关系是:LUN的WWN对LUN,端口的WWPN对端口。存储侧LUN映射时用的是WWPN来匹配主机端口,阵列自身或主机的端口WWN和LUN WWN分属不同命名空间。这个搞清了,很多“对不上”问题其实就解决了。

5.2 Linux里看不到WWN:检查驱动、bus和HBA固件

Linux下某个盘没有wwid文件时,常见的几个排查方向:

先检查SCSI设备是否存在:

cat /sys/class/scsi_device/2:0:0:0/device/vendor cat /sys/class/scsi_device/2:0:0:0/device/model

如果vendor和model也读不到,说明SCSI层还没完整识别这个设备。可以触发重新扫描:

echo 1 > /sys/class/scsi_device/2:0:0:0/device/rescan

如果是FC设备,还要确认HBA卡链路状态正常:

cat /sys/class/fc_host/host2/port_state

正常应显示Online。如果显示Offline或Linkdown,链路先恢复再说。

然后是驱动和固件层面的检查。HBA卡旧固件、旧驱动对VPD 0x83页的处理可能存在缺陷,导致wwid不生成。可以用sg_inq直接发INQUIRY:

sg_inq -p 0x83 /dev/sda

如果返回空数据,多半是设备侧没正确响应VPD页,这时应重点排查存储侧LUN映射是否正确,或者该盘是否被其他主机独占。如果sg_inq能返回数,但是udev没生成wwid,那就和内核版本、驱动、udev规则有关了,需要更新驱动并重新触发udev事件:

udevadm trigger

5.3 Windows里UniqueId为空或全是0怎么办

Windows的UniqueId为空白或全是0,通常意味着设备没有正常的SCSI标识,常见于某些非标驱动、虚拟磁盘、以及SATA盘直通的场景。

解决办法分两种路径。第一种是无所谓场景,如果只是普通SATA盘要在Windows里区分,直接用磁盘序列号SerialNumber就够,不一定非要WWN。第二种是FC/SAS盘出现这种情况,那就不是查法的问题,而是驱动或硬件链路的问题。需要确认HBA驱动版本、主板BIOS引导时是否完整枚举到设备、存储映射主机设置是否允许读取设备标识。如果阵列侧把LUN映射成“不报告序列号”,Windows也可能拿不到UniqueId。这时修改存储主机设置后,再把Windows设备管理器里的磁盘驱动禁用再启用,让设备重新枚举。

还有一点:让某个磁盘完全脱机再重新上线,会重新触发SCSI INQUIRY,有时异常消失后会看到WWN重新出现。但生产环境做这个动作前,一定要确认该磁盘上没有活动IO,否则可能造成应用中断。

5.4 资产管理小技巧:批量采集WWN并自动生成台账

最后分享一个适合批量环境的做法。用脚本把当前主机的磁盘信息统一采集到表格里,作为后续变更的基线数据。

Linux侧可以这样采集:

for disk in $(lsblk -dno NAME); do wwid=$(cat /sys/block/$disk/device/wwid 2>/dev/null) serial=$(cat /sys/block/$disk/device/serial 2>/dev/null) size=$(lsblk -dno SIZE /dev/$disk) printf "%s %s %s %s\n" "$disk" "${wwid:-N/A}" "${serial:-N/A}" "$size" done

Windows侧用PowerShell:

Get-Disk | ForEach-Object { [PSCustomObject]@{ DiskNumber = $_.Number WWN = ($_.UniqueId -replace '^Id:','') FriendlyName = $_.FriendlyName SizeGB = [math]::Round($_.Size/1GB,2) BusType = $_.BusType } } | Export-Csv -NoTypeInformation -Path wwn-audit.csv

之后只需要把Linux和Windows导出的结果用一个简单的脚本或Excel按WWN列匹配,就能清楚看到两边设备对应关系。在实际的月度巡检或存储扩容评审中,这个表格非常有用。它能在一个小时之内完成几百块盘的对账,比人工一个个看盘符再猜WWN要可靠太多了。

从这个角度看,WWN号算不上一个“高级”的企业级存储知识点,但它在系统管理员和存储工程师日常协作之间的价值,被很多人低估了。看盘前先查WWN,就像搬家前先确认门牌号一样,省下的不只是核对时间,还有那些因为弄错盘而造成的不可挽回的数据损失和对业务的影响。能在Linux和Windows两边都熟练、准确地拿到WWN并做好对应,处理存储问题时就真正有了底气。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询