多路径(multipath)
如果没有 DM Multipath,系统会将从服务器节点到存储控制器的每条路径视为单独的设备,即使 I/O 路径将同一服务器节点连接到同一存储控制器也是如此。
DM Multipath 通过在底层设备上创建单个多路径设备,提供了一种逻辑组织 I/O 路径的方法。
要使多路径工作,请确保已加载以下模块
# lsmod | grep dm_multipath dm_multipath 27427 4 dm_round_robin,dm_service_time
# modinfo dm_multipath filename: /lib/modules/3.10.0-693.21.1.el7.x86_64/kernel/drivers/md/dm-multipath.ko.xz license: GPL author: Sistina Software <dm-devel@redhat.com> description: device-mapper multipath target retpoline: Y rhelversion: 7.4 srcversion: 063067F9F167E7B653A4773 depends: dm-mod intree: Y vermagic: 3.10.0-693.21.1.el7.x86_64 SMP mod_unload modversions signer: Red Hat Enterprise Linux kernel signing key sig_key: B1:C3:31:09:FB:DA:94:AD:2F:E1:E8:E5:C1:E5:52:BD:22:57:60:FE sig_hashalgo: sha256
下面是主要的设备映射器 rpm
device-mapper-multipath device-mapper
主配置文件
/etc/multipath.conf
查看连接和扫描的多路径设备
# multipath -l
获取连接/扫描的 LUN 的 WWID
每个多路径设备都有一个全球标识符 (WWID),它保证全球唯一且不变。
我们可以使用以下命令获取 WWID
# multipath -l | grep dm 3600c0ff00013b88f9058e35a01000000 dm-0 HP ,P2000 G3 FC 3600c0ff00013b88f9c58e35a01000000 dm-6 HP ,P2000 G3 FC
或者使用以下命令
# ls -ld /dev/disk/by-id/scsi-* lrwxrwxrwx 1 root root 9 Jan 22 18:29 /dev/disk/by-id/scsi-3600c0ff00013b88f9058e35a01000000 -> ../../sde lrwxrwxrwx 1 root root 9 Jan 22 18:29 /dev/disk/by-id/scsi-3600c0ff00013b88f9c58e35a01000000 -> ../../sdd
获取磁盘的 WWID
每个 LUN 都映射到一个磁盘,该磁盘还为其生成一个唯一的 WWID,并且可以在配置中使用相同的名称来表示它们,因为设备名称可能会在重新启动后更改,而 WWID 不会更改并且重新启动持久。
# lsscsi --scsi_id [0:0:0:0] disk HP P2000 G3 FC T252 /dev/sda 3600c0ff00013b88f9058e35a01000000 [0:0:0:1] disk HP P2000 G3 FC T252 /dev/sdb 3600c0ff00013b88f9c58e35a01000000 [0:0:1:0] disk HP P2000 G3 FC T252 /dev/sdc 3600c0ff00013b88f9058e35a01000000 [0:0:1:1] disk HP P2000 G3 FC T252 /dev/sdd 3600c0ff00013b88f9c58e35a01000000 [1:0:0:0] disk HP P2000 G3 FC T252 /dev/sde 3600c0ff00013b88f9058e35a01000000 [1:0:0:1] disk HP P2000 G3 FC T252 /dev/sdf 3600c0ff00013b88f9c58e35a01000000 [1:0:1:0] disk HP P2000 G3 FC T252 /dev/sdg 3600c0ff00013b88f9058e35a01000000 [1:0:1:1] disk HP P2000 G3 FC T252 /dev/sdh 3600c0ff00013b88f9c58e35a01000000
要获取磁盘的 WWID,我们还可以使用以下命令
# /usr/lib/udev/scsi_id -g -u -d /dev/sda 3600c0ff00013b88f9058e35a01000000
获取通过 HBA 映射到 Linux box 的磁盘列表
具有两个 HBA 的节点通过单个未分区 FC 交换机连接到具有两个端口的存储控制器,可以看到四个设备:/dev/sda、/dev/sdb、dev/sdc 和 /dev/sdd。
DM Multipath 创建具有唯一 WWID 的单个设备,根据多路径配置将 I/O 重新路由到这四个底层设备。
对于我们的案例,因为我们有两个 LUN 连接到 Linux 机器,因此我们看到 8 个设备
# ls -ld /sys/block/sd*/device lrwxrwxrwx 1 root root 0 Jan 22 18:29 /sys/block/sda/device -> ../../../0:0:0:0 lrwxrwxrwx 1 root root 0 Jan 22 18:29 /sys/block/sdb/device -> ../../../0:0:0:1 lrwxrwxrwx 1 root root 0 Jan 22 18:29 /sys/block/sdc/device -> ../../../0:0:1:0 lrwxrwxrwx 1 root root 0 Jan 22 18:29 /sys/block/sdd/device -> ../../../0:0:1:1 lrwxrwxrwx 1 root root 0 Jan 22 18:29 /sys/block/sde/device -> ../../../1:0:0:0 lrwxrwxrwx 1 root root 0 Jan 22 18:29 /sys/block/sdf/device -> ../../../1:0:0:1 lrwxrwxrwx 1 root root 0 Jan 22 18:29 /sys/block/sdg/device -> ../../../1:0:1:0 lrwxrwxrwx 1 root root 0 Jan 22 18:29 /sys/block/sdh/device -> ../../../1:0:1:1
通过下面的命令可以看到同样的情况,其中 LUN 到设备的映射在眼睛上更容易
# ls -l /dev/disk/by-path/ total 0 lrwxrwxrwx 1 root root 9 Jan 22 18:29 pci-0000:04:00.2-fc-0x207000c0ff13d3a7-lun-0 -> ../../sda lrwxrwxrwx 1 root root 9 Jan 22 18:29 pci-0000:04:00.2-fc-0x207000c0ff13d3a7-lun-1 -> ../../sdb lrwxrwxrwx 1 root root 9 Jan 22 18:29 pci-0000:04:00.2-fc-0x247000c0ff13d3a7-lun-0 -> ../../sdc lrwxrwxrwx 1 root root 9 Jan 22 18:29 pci-0000:04:00.2-fc-0x247000c0ff13d3a7-lun-1 -> ../../sdd lrwxrwxrwx 1 root root 9 Jan 22 18:29 pci-0000:04:00.3-fc-0x217000c0ff13d3a7-lun-0 -> ../../sdg lrwxrwxrwx 1 root root 9 Jan 22 18:29 pci-0000:04:00.3-fc-0x217000c0ff13d3a7-lun-1 -> ../../sdh lrwxrwxrwx 1 root root 9 Jan 22 18:29 pci-0000:04:00.3-fc-0x257000c0ff13d3a7-lun-0 -> ../../sde lrwxrwxrwx 1 root root 9 Jan 22 18:29 pci-0000:04:00.3-fc-0x257000c0ff13d3a7-lun-1 -> ../../sdf
了解设备 ID
在多路径输出中,我们看到下面突出显示的条目正在使用(并且在上面的命令中我们会看到类似的表示)
# multipath -l 3600c0ff00013b88f9058e35a01000000 dm-0 HP ,P2000 G3 FC size=102G features='1 queue_if_no_path' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=0 status=active | |- 0:0:0:0 sda 8:0 active undef unknown | `- 1:0:1:0 sdg 8:96 active undef unknown `-+- policy='service-time 0' prio=0 status=enabled |- 0:0:1:0 sdc 8:32 active undef unknown `- 1:0:0:0 sde 8:64 active undef unknown 3600c0ff00013b88f9c58e35a01000000 dm-6 HP ,P2000 G3 FC size=359G features='1 queue_if_no_path' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=0 status=active | |- 0:0:0:1 sdb 8:16 active undef unknown | `- 1:0:1:1 sdh 8:112 active undef unknown `-+- policy='service-time 0' prio=0 status=enabled |- 0:0:1:1 sdd 8:48 active undef unknown `- 1:0:0:1 sdf 8:80 active undef unknown
下面的值解释了每个字段的含义
1:0:0:1 ^ ^ ^ ^ | | | | H C T L
其中 H 是 HBA 编号,C 是 HBA 上的通道,T 是 SCSI 目标 ID,L 是存储中的 LUN。
刷新/删除所有多路径设备
# multipath -F
刷新/删除选定的多路径设备。
首先是要使用 multipath -ll 刷新的多路径设备的 WWID
# multipath -ll 3600c0ff00013b88fdc53e35a01000000 dm-0 HP ,P2000 G3 FC size=186G features='1 queue_if_no_path' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=50 status=active | |- 1:0:0:0 sda 8:0 active ready running | `- 2:0:1:0 sdd 8:48 active ready running `-+- policy='service-time 0' prio=10 status=enabled |- 1:0:1:0 sdb 8:16 active ready running `- 2:0:0:0 sdc 8:32 active ready running
接下来使用以下命令刷新选定的多路径
# multipath -f 3600c0ff000144876065be35a01000000
注意:此多路径不得处于使用状态
详细显示现有配置
下面的命令将显示 Linux 机器上加载的现有配置
# multipathd show config defaults { verbosity 2 polling_interval 5 max_polling_interval 20 reassign_maps "yes" multipath_dir "/lib64/multipath" path_selector "service-time 0" path_grouping_policy "failover" uid_attribute "ID_SERIAL" prio "const" bindings_file "/etc/multipath/bindings" wwids_file /etc/multipath/wwids prkeys_file /etc/multipath/prkeys log_checker_err always find_multipaths no retain_attached_hw_handler no detect_prio no detect_path_checker no hw_str_match no force_sync no deferred_remove no ignore_new_boot_devs no remove_retries 0 disable_changed_wwids no unpriv_sgio no } blacklist { devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" devnode "^hd[a-z][[0-9]*]" devnode "^cciss!c[0-9]d[0-9]*[p[0-9]*]" devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" devnode "^(td|hd|vd)[a-z]" devnode "^dcssblk[0-9]*" device { vendor "DGC" product "LUNZ" } device { vendor "EMC" product "LUNZ" } device { vendor "SUN" product "Universal Xport" } device { vendor "(NETAPP|LSI|ENGENIO)" product "Universal Xport" } } blacklist_exceptions { } devices { device { vendor "HP" product "MSA2012sa|MSA23(12|24)(fc|i|sa)|MSA2000s VOLUME" path_grouping_policy "group_by_prio" path_checker "tur" features "0" hardware_handler "0" prio "alua" failback immediate rr_weight "uniform" no_path_retry 18 rr_min_io 100 } device { vendor "HP" product "MSA (1|2)040 SA(N|S)" path_grouping_policy "group_by_prio" path_checker "tur" features "0" hardware_handler "0" prio "alua" failback immediate rr_weight "uniform" no_path_retry 18 rr_min_io 100 } device { vendor "PURE" product "FlashArray" path_grouping_policy "multibus" path_selector "queue-length 0" path_checker "tur" features "0" hardware_handler "0" prio "const" failback immediate fast_io_fail_tmo 10 dev_loss_tmo 60 user_friendly_names no } device { vendor "Ceph" product "RBD" path_grouping_policy "failover" path_checker "rbd" no_path_retry "fail" } } multipaths { }
获取完整的 HBA 详细信息
systool 使用 libsysfs 提供的 API 来收集信息,并将提供有关可用 HBA 和 LUN 状态的详细信息
注意:systool 随 sysfsutils rpm 一起提供,因此请确保在使用此工具之前已安装它
# systool -c fc_host -v Class = "fc_host" Class Device = "host0" Class Device path = "/sys/devices/pci0000:00/0000:00:02.0/0000:04:00.2/host0/fc_host/host0" active_fc4s = "0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 " dev_loss_tmo = "30" fabric_name = "0x2003547fee1188d9" issue_lip = <store method only> max_npiv_vports = "255" maxframe_size = "2048 bytes" node_name = "0x50060b0000c2a67d" npiv_vports_inuse = "0" port_id = "0x310305" port_name = "0x50060b0000c2a67c" port_state = "Online" port_type = "NPort (fabric via point-to-point)" speed = "unknown" supported_classes = "Class 3" supported_fc4s = "0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 " supported_speeds = "10 Gbit" symbolic_name = "Emulex 554FLB FV11.1.183.23 DV11.2.0.6 HN:ban33-be002-2b OS:Linux" tgtid_bind_type = "wwpn (World Wide Port Name)" uevent = vport_create = <store method only> vport_delete = <store method only> Device = "host0" Device path = "/sys/devices/pci0000:00/0000:00:02.0/0000:04:00.2/host0" uevent = "DEVTYPE=scsi_host" Class Device = "host1" Class Device path = "/sys/devices/pci0000:00/0000:00:02.0/0000:04:00.3/host1/fc_host/host1" active_fc4s = "0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 " dev_loss_tmo = "30" fabric_name = "0x2003547fee357a81" issue_lip = <store method only> max_npiv_vports = "255" maxframe_size = "2048 bytes" node_name = "0x50060b0000c2a67f" npiv_vports_inuse = "0" port_id = "0x25030f" port_name = "0x50060b0000c2a67e" port_state = "Online" port_type = "NPort (fabric via point-to-point)" speed = "unknown" supported_classes = "Class 3" supported_fc4s = "0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 " supported_speeds = "10 Gbit" symbolic_name = "Emulex 554FLB FV11.1.183.23 DV11.2.0.6 HN:ban33-be002-2b OS:Linux" tgtid_bind_type = "wwpn (World Wide Port Name)" uevent = vport_create = <store method only> vport_delete = <store method only> Device = "host1" Device path = "/sys/devices/pci0000:00/0000:00:02.0/0000:04:00.3/host1" uevent = "DEVTYPE=scsi_host"
此工具还可用于使用以下语法获取其他值
获取端口名称
# systool -c fc_host -A port_name Class = "fc_host" Class Device = "host0" port_name = "0x50060b0000c2a67c" Device = "host0" Class Device = "host1" port_name = "0x50060b0000c2a67e" Device = "host1"
获取端口ID
# systool -c fc_host -A port_id Class = "fc_host" Class Device = "host0" port_id = "0x310305" Device = "host0" Class Device = "host1" port_id = "0x25030f" Device = "host1"
简要显示现有配置
这是一个备用命令,可用于检查所选值的加载配置,如下所示。
# mpathconf multipath is enabled find_multipaths is disabled user_friendly_names is enabled dm_multipath module is loaded multipathd is running
为多路径使用用户友好名称
每个多路径设备都有一个全球标识符 (WWID),它保证全球唯一且不变。
默认情况下,多路径设备的名称设置为其 WWID。
或者,我们可以在多路径配置文件中设置 user_friendly_names 选项,该选项将别名设置为 mpathn 形式的节点唯一名称
禁用 user_friendly 名称后,我们将只能看到连接的多路径的 WWID
# multipath -l 3600c0ff000144876f85ae35a01000000 dm-0 HP ,P2000 G3 FC size=102G features='1 queue_if_no_path' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=0 status=active | `- 2:0:0:0 sda 8:0 active undef unknown `-+- policy='service-time 0' prio=0 status=enabled `- 2:0:1:0 sdc 8:32 active undef unknown 3600c0ff000144876065be35a01000000 dm-6 HP ,P2000 G3 FC size=359G features='1 queue_if_no_path' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=0 status=active | `- 2:0:0:1 sdb 8:16 active undef unknown `-+- policy='service-time 0' prio=0 status=enabled `- 2:0:1:1 sdd 8:48 active undef unknown
接下来启用用户友好名称
# /sbin/mpathconf --user_friendly_names y
检查多路径
# multipath -l mpathb (3600c0ff000144876065be35a01000000) dm-6 HP ,P2000 G3 FC size=359G features='1 queue_if_no_path' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=0 status=active | `- 2:0:0:1 sdb 8:16 active undef unknown `-+- policy='service-time 0' prio=0 status=enabled `- 2:0:1:1 sdd 8:48 active undef unknown mpatha (3600c0ff000144876f85ae35a01000000) dm-0 HP ,P2000 G3 FC size=102G features='1 queue_if_no_path' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=0 status=active | `- 2:0:0:0 sda 8:0 active undef unknown `-+- policy='service-time 0' prio=0 status=enabled `- 2:0:1:0 sdc 8:32 active undef unknown
映射是使用 /etc/multipath/bindings 完成的。
检查 Linux 机器上的 HBA 数量
# ls -l /sys/class/fc_host/ total 0 lrwxrwxrwx 1 root root 0 Jan 22 18:29 host0 -> ../../devices/pci0000:00/0000:00:02.0/0000:04:00.2/host0/fc_host/host0 lrwxrwxrwx 1 root root 0 Jan 22 18:29 host1 -> ../../devices/pci0000:00/0000:00:02.0/0000:04:00.3/host1/fc_host/host1
我们也可以使用
# lspci -nn |grep -i "Fibre" 04:00.2 Fibre Channel [0c04]: Emulex Corporation OneConnect 10Gb FCoE Initiator (be3) [19a2:0714] (rev 01) 04:00.3 Fibre Channel [0c04]: Emulex Corporation OneConnect 10Gb FCoE Initiator (be3) [19a2:0714] (rev 01)
在某些 Linux 变体上,我们还可以 grep 获取 HBA
# lspci -nn |grep -i "HBA"
所以这里我有两个 HBA
检查多路径的 WWPN
全球端口号 (WWPN) 是任何光纤通道设备的每个 FC 端口的唯一标识符。
- 对于服务器,我们为 HBA 的每个端口都有一个 WWPN。
- 对于 SAN 交换机,WWPN 可用于机箱中的每个端口。
- 对于存储,每个主机端口都有一个单独的 WWPN
这里我们有两个 HBA,因此每个 HBA 将具有唯一的全球端口名称 (WWPN),该名称将连接到 SAN 交换机,然后连接到存储盒。
在我的服务器上:
# cat /sys/class/fc_host/host0/port_name 0x50060b0000c2a67c # cat /sys/class/fc_host/host1/port_name 0x50060b0000c2a67e
这些是 WWPN 编号。
检查多路径的WWNN
全球节点名称 (WWNN) 是分配给每个光纤通道节点或者设备的全球唯一 64 位标识符。
- 对于服务器和主机,每个HBA(主机总线适配器)的WWNN都是唯一的,如果服务器有两个HBA,则它们有两个WWNN。
- 对于 SAN 交换机,WWNN 是机箱通用的。
- 对于存储,中端存储的每个控制器单元通用WWNN
由于这里我有两个 HBA,因此每个 HBA 有两个 WWNN
在我的服务器上:
# cat /sys/class/fc_host/host1/node_name 0x50060b0000c2a67f # cat /sys/class/fc_host/host0/node_name 0x50060b0000c2a67d
为新 LUN 重新扫描连接的 HBA
如果我们有新的 LUN 连接到 Linux 机器,那么我们将需要重新扫描 HBA
假设我们知道为其添加新 LUN 的 WWPN
# echo 1 > /sys/class/fc_host/host2/issue_lip # systemctl reload multipathd # multipath -v2
接下来验证新 LUN 是否可见,使用
# multipath -ll
将设备列入黑名单
在 /etc/multipath.conf 中创建一个如下所示的函数,我们可以其中提供我们希望列入黑名单的设备列表
在这里,我将多个我不想创建为多路径的设备列入黑名单
blacklist { devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" devnode "^hd[a-z][[0-9]*]" devnode "^cciss!c[0-9]d[0-9]*[p[0-9]*]" }
使用 WWID 加入黑名单
我们可以使用以下命令获取设备的 WWID
# /usr/lib/udev/scsi_id -g -u -d /dev/sda 3600c0ff000144876f85ae35a01000000
这里我们将 /dev/sda 列入黑名单,这是我们的内部磁盘,我不希望它成为多路径
blacklist { wwid 3600c0ff000144876f85ae35a01000000 }
执行多路径重新加载以使更改生效
# systemctl reload multipathd.service
为所选磁盘添加黑名单例外
与黑名单类似,我们也可以添加黑名单例外,以便这些设备不被列入黑名单
在 /etc/multipath.conf 中添加以下功能,其中包含我们希望添加为黑名单例外的 wwid 列表
blacklist_exceptions { wwid "3600d0230000000000e13955cc3757803" }
其次是重新加载multipathd
# systemctl reload multipathd.service
更改多路径设备的配置(路径选择器)
以下是支持的 path_selector 的总列表
在 /etc/multipath.conf 中添加我们选择的 path_selector,如下所示
defaults { user_friendly_names yes failback immediate path_selector "round-robin 0" }
我们可以在默认功能下添加它,也可以添加设备功能,如果我们希望添加更改路径选择器仅适用于选定的设备
devices { device { vendor "HP" product "P2000 G3 FC|P2000G3 FC/iSCSI|P2000 G3 SAS|P2000 G3 iSCSI" path_grouping_policy "failover" path_selector "round-robin 0" } }
注意:我们可以从“multipathd show config”中获取设备详细信息
添加以下更改
devices { device { vendor "HP" product "P2000 G3 FC|P2000G3 FC/iSCSI|P2000 G3 SAS|P2000 G3 iSCSI" user_friendly_names yes } }