SRP - SCSI RDMA 协议
SCSI RDMA 协议 (SRP) 旨在充分利用 InfiniBand 架构提供的协议卸载和 RDMA 功能。SRP 允许大量 SCSI 软件在 InfiniBand 架构上轻松使用。SRP 发起程序控制与 SRP 目标的连接,以便通过 InfiniBand 结构访问远程存储设备。kSRP 目标驻留在 IO 单元中并提供存储服务。
此 SRP 发起程序基于 OpenFabrics(www.openfabrics.org)的开源代码,该代码实现了 SCSI RDMA 协议-2 (SRP-2)。SRP-2 在文档 # T10/1524-D 中描述,可从 http://www.t10.org 获取。
SRP 发起程序支持
基本 SCSI 主命令 -3 (SPC-3)
基本 SCSI 块命令 -2 (SBC-2)
基本功能、任务管理和有限的错误处理
此软件包不包含 SRP 目标。
加载 SRP 发起程序
要加载 SRP 模块,请执行以下操作之一
在 OFED 驱动程序启动后执行
modprobe ib_srp
命令。
或
将
/etc/infiniband/openib.conf
中的SRP_LOAD
的值更改为 “yes
”。运行
/etc/init.d/openibd restart
以使更改生效。
加载 ib_srp
模块时,可以设置模块参数 srp_sg_tablesize。
这是每个 I/O 的最大收集/分散条目数(默认值:12)。
SRP 模块参数
加载 SRP 模块时,可以设置以下参数(可通过 “modinfo ib_srp” 命令查看)
| SRP 命令中收集/分散条目的默认数量(默认值为 12,最大值为 255) |
| 当映射后 S/G 条目超过 cmd_sg_entries 时的默认行为;如果为 false,则请求失败(默认为 false) |
| 启用 Topspin/Cisco SRP 目标错误的解决方法 |
| 连续重连尝试之间的时间。SRP 发起程序在断开连接的目标上连续重连尝试之间的时间,直到 dev_loss_tmo 计时器过期(如果启用),之后将删除 SCSI 目标 |
| 观察到传输层错误和所有 I/O 失败之间的秒数。增加此超时时间可以提高对传输错误的容忍度,但是,这样做会增加严重传输故障情况下的总故障转移时间。 注意:fast_io_fail_tmo 值必须小于 reconnect_delay 的值 |
| SRP 传输应隔离传输层错误的最大秒数。超过此时间后,将删除 SCSI 目标。通常建议将其设置为 -1(禁用),这将永远不会删除 scsi_host。在频繁连接和断开不同 SRP 目标的环境中,可能需要启用此超时以清理表示不再存在的目标的旧 scsi_host |
参数之间的约束
dev_loss_tmo、fast_io_fail_tmo、reconnect_delay 不能全部禁用或为负值。
reconnect_delay 必须为正数。
fast_io_fail_tmo 必须小于 SCSI 块设备超时时间。
fast_io_fail_tmo 必须小于 dev_loss_tmo。
SRP 远程端口参数
多个 SRP 远程端口参数可以在现有连接上在线修改。
echo 600
> /sys/class
/srp_remote_ports/port-xxx/dev_loss_tmo
要将 fast_io_fail_tmo 修改为 15 秒
echo 15
> /sys/class
/srp_remote_ports/port-xxx/fast_io_fail_tmo
要将 reconnect_delay 修改为 10 秒
echo 20
> /sys/class
/srp_remote_ports/port-xxx/reconnect_delay
手动建立 SRP 连接
以下步骤描述了如何在发起程序和 SRP 目标之间手动加载 SRP 连接。“自动发现和连接到目标” 部分解释了如何自动执行此操作。
确保 ib_srp 模块已加载,SRP 发起程序可被 SRP 目标访问,并且 SM 正在运行。
要建立与 SRP 目标的连接并在 /dev 下为该目标创建 SRP (SCSI) 设备,请使用以下命令
echo -n id_ext=[GUID value],ioc_guid=[GUID value],dgid=[port GID value],\ pkey=ffff,service_id=[service[
0
] value] > \ /sys/class
/infiniband_srp/srp-mlx[hca number]-[port number]/add_target
有关如何获取此 echo 命令中参数的说明,请参阅“SRP 工具 - ibsrpdm、srp_daemon 和 srpd 服务脚本” 部分。
注意:
执行上述 “echo” 命令可能需要一些时间
SM 必须在命令执行时运行
可以在 echo 命令中包含其他参数
max_cmd_per_lun - 默认值:62
max_sect (max_sectors 的缩写) - 设置命令的请求大小
io_class - 默认值:0x100,如规范修订版 16A 中所示(在修订版 10 中,默认值为 0xff00)
tl_retry_count - 范围为 2..7 的数字,指定 IB RC 重试计数。默认值:2
comp_vector,范围为 0..n-1 的数字,指定 MSI-X 完成向量。某些 HCA 为每个 HCA 端口分配多个 (n) MSI-X 向量。如果这些中断的 IRQ 亲和性掩码已配置为使每个 MSI-X 中断由不同的 CPU 处理,则 comp_vector 参数可用于将 SRP 完成工作负载分散到多个 CPU 上。
cmd_sg_entries,范围为 1..255 的数字,指定存储在 SRP_CMD 信息单元本身中的最大数据缓冲区描述符数。使用 allow_ext_sg=0,参数 cmd_sg_entries 定义单个 SRP_CMD 的最大 S/G 列表长度,并且 S/G 列表长度在 S/G 列表折叠后超过此限制的命令将失败。
initiator_ext - 请参阅 “从发起程序 InfiniBand 端口到目标的多个连接” 部分。
要列出 echo 命令添加的新 SCSI 设备,可以使用以下两种方法中的任何一种
执行 “fdisk -l”。此命令列出所有设备;新设备包含在此列表中。
执行 “dmesg” 或查看 /var/log/messages 以查找包含新设备名称的消息。
SRP sysfs 参数
用于使 ib_srp 连接到新目标的接口。可以通过将逗号分隔的登录参数列表写入此 sysfs 属性来请求 ib_srp 连接到新目标。支持的参数有
id_ext | 一个 16 位十六进制数字,指定 16 字节 SRP 目标端口标识符中的八字节标识符扩展。目标端口标识符由 ib_srp 在 SRP_LOGIN_REQ 请求中发送到目标。 |
ioc_guid | 一个 16 位十六进制数字,指定 16 字节目标端口标识符的八字节 I/O 控制器 GUID 部分。 |
dgid | 一个 32 位十六进制数字,指定目标 GID。 |
pkey | 一个四位十六进制数字,指定 InfiniBand 分区密钥。 |
service_id | 一个 16 位十六进制数字,指定用于建立与 SRP 目标通信的 InfiniBand 服务 ID。如何查找服务 ID 的值在 SRP 目标的文档中指定。 |
max_sect | 一个十进制数字,指定要通过单个 SCSI 命令传输的最大 512 字节扇区数。 |
max_cmd_per_lun | 一个十进制数字,指定单个 LUN 的最大未完成命令数。 |
io_class | 一个十六进制数字,指定 SRP I/O 类。必须为 0xff00 (rev 10) 或 0x0100 (rev 16a)。I/O 类定义 SRP 发起程序和目标端口标识符的格式。 |
initiator_ext | 一个 16 位十六进制数字,指定 SRP 发起程序端口标识符的标识符扩展部分。此数据由发起程序在 SRP_LOGIN_REQ 请求中发送到目标。 |
cmd_sg_entries | 范围为 1..255 的数字,指定存储在 SRP_CMD 信息单元本身中的最大数据缓冲区描述符数。使用 allow_ext_sg=0,参数 cmd_sg_entries 定义单个 SRP_CMD 的最大 S/G 列表长度,并且 S/G 列表长度在 S/G 列表折叠后超过此限制的命令将失败。 |
allow_ext_sg | 是否允许 ib_srp 在 SRP_CMD 中包含部分内存描述符列表而不是整个列表。如果在 SRP_CMD 中包含部分内存描述符列表,则剩余的内存描述符通过额外的 RDMA 传输从发起程序传输到目标。将 allow_ext_sg 设置为 1 会增加可以通过单个 SCSI 命令在发起程序和目标之间传输的最大数据量。由于并非所有 SRP 目标实现都支持部分内存描述符列表,因此此选项的默认值为 0。 |
sg_tablesize | 范围为 1..2048 的数字,指定 SCSI 层允许传递给 ib_srp 的最大 S/G 列表长度。仅当启用部分内存描述符列表支持 (allow_ext_sg=1) 时,指定超过 cmd_sg_entries 的值才是安全的。 |
comp_vector | 范围为 0..n-1 的数字,指定 MSI-X 完成向量。某些 HCA 为每个 HCA 端口分配多个 (n) MSI-X 向量。如果这些中断的 IRQ 亲和性掩码已配置为使每个 MSI-X 中断由不同的 CPU 处理,则 comp_vector 参数可用于将 SRP 完成工作负载分散到多个 CPU 上。 |
tl_retry_count | 范围为 2..7 的数字,指定 IB RC 重试计数。 |
SRP 工具 - ibsrpdm、srp_daemon 和 srpd 服务脚本
OFED 发行版提供两个实用程序:ibsrpdm 和 srp_daemon
它们检测发起程序可访问的结构上的目标(步骤 1)
以适合在上述 “echo” 命令中使用的格式输出目标属性(步骤 2)
一个服务脚本 srpd,可以在堆栈启动时启动
这些实用程序可以在 /usr/sbin/ 下找到,并且是 srptools RPM 的一部分,可以使用 OFED 安装进行安装。有关这些实用程序的各种选项的详细信息,请参阅其手册页。
下面介绍了这些实用程序的几种使用场景。
ibsrpdm
ibsrpdm 具有以下任务
检测可访问的目标。
要检测 SRP 发起程序通过默认 umad 设备 (/sys/class/infiniband_mad/umad0) 可访问的所有目标,请执行以下命令
ibsrpdm
此命令将生成有关检测到的每个 SRP 目标的易读输出信息。示例
IO Unit Info: port LID:
0103
port GID: fe800000000000000002c90200402bd5 change ID:0002
max controllers:0x10
controller[1
] GUID: 0002c90200402bd4 vendor ID: 0002c9 device ID: 005a44 IOclass
:0100
ID: LSI Storage Systems SRP Driver 200400a0b81146a1 service entries:1
service[0
]: 200400a0b81146a1 / SRP.T10:200400A0B81146A1要检测 SRP 发起程序通过另一个 umad 设备可访问的所有 SRP 目标,请使用以下命令
ibsrpdm -d <umad device>
协助创建 SRP 连接。
要在 “手动建立 SRP 连接” 部分的 “echo” 命令中生成适合使用的输出,请将 ‘-c’ 选项添加到 ibsrpdm
ibsrpdm -c
示例输出
id_ext=200400A0B81146A1,ioc_guid=0002c90200402bd4, dgid=fe800000000000000002c90200402bd5,pkey=ffff,service_id=200400a0b81146a1
要使用上面 ‘ibsrpdm -c’ 示例的输出建立与 SRP 目标的连接,请执行以下命令
echo -n id_ext=200400A0B81146A1,ioc_guid=0002c90200402bd4, dgid=fe800000000000000002c90200402bd5,pkey=ffff,service_id=200400a0b81146a1 > /sys/
class
/infiniband_srp/srp-mlx5_0-1
/add_targetSRP 连接现在应该已启动;新创建的 SCSI 设备应出现在从 ‘
fdisk -l
’ 命令获得的列表中。
给定 InfiniBand HCA 名称和端口,而不是仅运行
/sys/class/infiniband_mad/umad<N>
,其中<N>
是数字,来发现可访问的 SRP 目标。
srpd
srpd 服务脚本允许在所有系统活动 InfiniBand 端口上自动激活和终止 srp_daemon 实用程序。
srp_daemon
srp_daemon 实用程序基于 ibsrpdm 并扩展了其功能。除了上面描述的 ibsrpdm 功能外,srp_daemon 还可以
自行建立 SRP 连接(无需发出 “手动建立 SRP 连接” 部分中描述的 “echo” 命令)
在后台继续运行,检测新目标并与它们建立 SRP 连接(守护程序模式)
给定 infiniband HCA 名称和端口,而不是仅通过
/dev/umad<N>
(其中<N>
是数字)来发现可访问的 SRP 目标启用高可用性操作(与 Device-Mapper Multipath 一起使用)
具有配置文件,用于确定要连接的目标
与 ibsrpdm 等效的 srp_daemon 命令
"srp_daemon -a -o"
is equivalent to"ibsrpdm"
"srp_daemon -c -a -o"
is equivalent to"ibsrpdm -c"
注意:当 /etc/srp_daemon.conf 不为空时,这些 srp_daemon 命令的行为可能与等效的 ibsrpdm 命令不同。
srp_daemon 对 ibsrpdm 的扩展。
要发现从 HCA 设备 <InfiniBand HCA 名称> 和端口 <端口号> 可访问的 SRP 目标(并生成适合 “echo” 的输出),请执行
host1# srp_daemon -c -a -o -i <InfiniBand HCA name> -p <port number>
注意:要获取 InfiniBand HCA 设备名称的列表,可以使用 ibstat 工具或运行 ‘ls /sys/class/infiniband’。
要同时发现 SRP 目标并建立与其的连接,只需将 -e 选项添加到上述命令即可。
在没有 -a 选项的情况下通过端口执行 srp_daemon 将仅显示通过端口可访问且发起程序未连接的目标。如果使用 -e 选项执行,则最好省略 -a。
建议使用 -n 选项。此选项将 initiator_ext 添加到连接字符串(请参阅 “从发起程序 InfiniBand 端口到目标的多个连接” 部分)。
srp_daemon 有一个配置文件可以设置,默认值为 /etc/srp_daemon.conf。使用 -f 提供不同的配置文件,该文件配置 srp_daemon 允许连接的目标。配置文件还可以用于设置其他参数的值(例如,max_cmd_per_lun、max_sect)。
连续后台(守护程序)操作,提供自动持续检测和连接功能。请参阅 “自动发现和连接到目标” 部分。
自动发现和连接到目标
确保 ib_srp 模块已加载,SRP 发起程序可以访问 SRP 目标,并且 SM 正在运行。
要连接到结构中的所有现有目标,请运行 “
srp_daemon -e -o
”。此实用程序将扫描结构一次,连接到它检测到的每个目标,然后退出。注意srp_daemon 将遵循其在 /etc/srp_daemon.conf 中找到的配置。因此,它将忽略配置文件中不允许的目标。
要连接到结构中的所有现有目标并连接到将加入结构的新目标,请执行 srp_daemon -e。此实用程序将继续执行,直到用户终止它或遇到连接错误(例如结构中没有 SM)。
要在所有端口上作为守护程序执行 SRP 守护程序
srp_daemon.sh(在 /usr/sbin/ 下找到)。srp_daemon.sh 将其日志发送到 /var/log/srp_daemon.log。
启动 srpd 服务脚本,运行 service srpd start
要使 openib.conf 中的更改生效,请运行
/etc/init.d/openibd restart
从发起程序 InfiniBand 端口到目标的多个连接
某些系统配置可能需要从 SRP 发起程序到同一 SRP 目标的多个 SRP 连接:到同一目标 IB 端口,或到同一目标 HCA 上的不同 IB 端口。
对于单个目标 IB 端口的情况,即 SRP 连接使用相同的路径,可以通过为每个 SRP 连接使用不同的 initiator_ext 值来启用配置。initiator_ext 值是在连接命令中指定的 16 位十六进制数字值。
同样,在从单个发起程序 IB 端口到同一目标 HCA 上两个不同 IB 端口的两个物理连接(即网络路径)的情况下,每个路径都需要不同的 initiator_ext 值。约定是将目标端口 GUID 用作相关路径的 initiator_ext 值。
如果您将 srp_daemon 与 -n 标志一起使用,它会根据此约定自动分配 initiator_ext 值。例如
id_ext=200500A0B81146A1,ioc_guid=0002c90200402bec,\
dgid=fe800000000000000002c90200402bed,pkey=ffff,\ service_id=200500a0b81146a1,initiator_ext=ed2b400002c90200
注意:
建议对所有 srp_daemon 调用使用 -n 标志。
ibsrpdm 没有相应的选项。
srp_daemon.sh 始终使用 -n 选项(无论是用户手动调用,还是通过将 SRP_DAEMON_ENABLE 设置为 yes 在启动时自动调用)。
高可用性 (HA)
高可用性使用 Device-Mapper (DM) multipath 和 SRP 守护程序工作。每个发起程序都从多个端口/HCA 连接到同一目标。DM multipath 负责将同一目标的不同路径连接在一起,并在其中一个路径脱机时在路径之间进行故障转移。Multipath 将在新加入的 SCSI 设备上执行。
每个发起程序应执行多个 SRP 守护程序实例,每个端口一个。在启动时,每个 SRP 守护程序都会检测结构中的 SRP 目标,并向 ib_srp 模块发送请求以连接到每个目标。这些 SRP 守护程序还会检测随后加入结构的目标,并向 ib_srp 模块发送请求以连接到它们。
操作
当到目标的路径(从端口 1)失败时,ib_srp 模块会启动错误恢复过程。如果此过程到达 reset_host 阶段,并且没有来自此端口的到目标的路径,则 ib_srp 将删除此 scsi_host。删除 scsi_host 后,multipath 会切换到此目标的另一条路径(来自另一个端口/HCA)。
当失败的路径恢复时,SRP 守护程序将检测到它。然后,SRP 守护程序将请求 ib_srp 连接到此目标。一旦连接建立,将为此目标创建一个新的 scsi_host。Multipath 将在此主机的设备上执行,返回到原始状态(在失败路径之前)。
手动激活高可用性
初始化 - 在每次启动驱动程序后执行
执行
modprobe dm-multipath
执行
modprobe ib-srp
确保您已创建如上所述的 /etc/udev/rules.d/91-srp.rules 文件
为每个端口和每个 HCA 执行
srp_daemon -c -e -R
300
-i <InfiniBand HCA name> -p <port number>此步骤可以通过执行 srp_daemon.sh 来执行,该脚本将其日志发送到 /var/log/srp_daemon.log。
现在可以访问 /dev/mapper/ 上的 SRP LUN。
也可能存在常规(非 SRP)LUN;SRP LUN 可以通过其名称来识别。您可以配置 /etc/multipath.conf 文件以更改 multipath 行为。
SRP LUN 也可能不会出现在 /dev/mapper/ 下。如果 SRP LUN 在 multipath 的黑名单中,则可能会发生这种情况。编辑 /etc/multipath.conf 中的 “blacklist” 部分,并确保 SRP LUN 未列入黑名单。
自动激活高可用性
启动 srpd 服务,运行
service srpd start
从下次加载驱动程序开始,可以访问 /dev/mapper/ 上的 SRP LUN
注意也可能存在常规(非 SRP)LUN。SRP LUN 可以通过其名称来识别。
可以在 /var/log/srp_daemon.log 中查看 SRP 守护程序的输出
可以通过使用 “rmmod ib_srp” 或停止 OFED 驱动程序(“/etc/init.d/openibd stop”)或作为完整系统关闭的副产品来关闭 SRP。
在关闭 SRP 之前,请删除对其的所有引用。您需要采取的操作取决于 SRP 的加载方式。有三种情况
不带高可用性
在不使用高可用性时,应卸载在关闭 SRP 之前挂载的 SRP 分区。
手动激活高可用性后
如果您手动激活了 SRP 高可用性,请执行以下步骤
卸载所有已挂载的 SRP 分区。
停止服务 srpd(终止 SRP 守护程序实例)。
确保没有 multipath 实例正在运行。如果有多个实例,请等待它们结束或终止它们。
运行:
multipath -F
自动激活高可用性后
如果 SRP 高可用性是自动激活的,则 SRP 关闭必须是驱动程序关闭(“/etc/init.d/openibd stop”)的一部分,它执行上述情况 b 的步骤 2-4。但是,您仍然必须卸载驱动程序关闭之前挂载的所有 SRP 分区。