iSCSI协议中的流量控制和命令的可靠性的机制

iSCSI 设备是支持使用者同时向 iSCSI 设备发送多个请求,如同时发送多个读请求,也就是,当第一个读请求还没有返回时,可以同时发送第二个读请求。 由于可以同时发送多个请求,而请求包中包装的 SCSI 命令,而 SCSI 命令是有顺序的,所以需要有一个序号来表示这个顺序。同时一下子发送太多的请求,也有可能把 iSCSI Target 端压跨。所以 iSCSI 协议设计了使用序号来控制命令的顺序性及流量控制的一种方法。下面就详细介绍 iSCSI 是如何通过这种方法解决以上这几个问题的。

在 iSCSI 中, 命令、状态和数据传送都是有序号的。对命令的编号是以会话为单位的,不管这个会话上包含有多少个连接(MC/S),其上的命令都被统一编号。 后面我们会讲解,通过命令序号如何实现的命令的流量控制和命令传送的有序性。

对状态的编号是以连接为单位的,即每个连接上都有自己独立的状态序号。

在iSCSI中数据可以与命令分开传送。为了让一个命令传送的较大的数据量,iSCSI 设计为一个命令中的多个数据可以分多次传送。因为对多次传送的数据也有一个编号,这个编号是以命令为单位的。

下面我们主要讲解命令的编号。

命令序号是一个 32 位的无符号序号,在 iSCSI 的请求 PDU 中,命令序号记录在 CmdSN(Command Sequence Number) 域中,命令序号开始于第一个连接的第一个 Login 请求,此后每发送一个命令其序号就加 1,但立即命令除外。立即命令 (Immediate) 是一种紧急命令,是要求 iSCSI 服务立即响应的命令,这个命令不编号,除立即命令外,iSCSI 层必须按命令序号的顺序向它的下层 SCSI 层传送命令。而立即命令是接收到后,不排队就马上发送到 SCSI 层。

在 iSCSI 协议的原理上说,发送的命令可以在途中的顺序发生变化,而不会出现错误。也就是说,发送请求的顺序是 R1、R2,但 R2 的数据包可以被先接收到,然后再接收到 R1,这样不会导致错误。同时返回的响应包的顺序在传输中也可以改变,而不会导致 iSCSI 的错误。

具体实现方法如下:

iSCSI Initiator 和 iSCSI Target 中都存在三个变量:

  • CmdSN:当前命令序号
  • ExpCmdSN:iSCSI Target 期望接收到的命令。
  • MaxCmdSN:iSCSI Target 能接收到的最大序号。主要是限制 iSCSI Initiator 能发送的最大 CmdSN 号。如果 iSCSI Initiator 想发送命令时,如果命令的 CmdSN 大于的本地变量 MaxCmdSN 的值,则等待。这个变量就是做流控制。
iSCSI Initiator 按如下的方式处理来自 iSCSI Target 的回包:
  1. 如果 PDU 中的 MaxCmdSN 小于 ExpCmdSN -1,两者都被忽略。这种情况一般不该出现。
  2. 如果 PDU 中的 MaxCmdSN 大于本地的 MaxCmdSN,将本地的变量 MaxCmdSN 的值改为 PDU 中 MaxCmdSN
  3. 如果 PDU 中的 ExpCmdSN 大于本地的 ExcCmdSN,将本地的变量 ExpCmdSN 的值改为 PDU 中的 ExpCmdSN
  4. 其它情况忽略。
例子:

假设 iSCSI Target 设备的端的队列深度为 16,即 QueueSize=16,iSCSI Initiator 同时发送请求 R1 (CmdSN=55)、R2(CmdSN=56) 到 iSCSI Target

有可能 iSCSI Target 先接收到 R2,再接收到 R1。

在接收到 R2 时,由于 iSCSI Target 是期望接收到 R1(CmdSN=55) 的命令,而此时接到收到的是 R2(CmdSN=56) 的命令,所以此时不更新 MaxCmdSN 和 ExpectCmdSN,而把 R2 放到自己的接收队列中。

当接收到 R1 时,此时接收到的是 CmdSN=55 的命令,而此时的 ExpectCmdSN 也是 55,则更新 ExpectCmdSN 为 56,然后再查找自己队列,发现 CmdSN=56 的请求 R2 也收到了,此时再把 ExpecetCmdSN 改为 57。

这时 R1 命令会先发送到 SCSI 层,然后再发送 R2 命令到 SCSI 层,这个次序不能弄错。这时假设 R2 命令先被 SCSI 处理完了,这时就可以把 R2 的命令的响应包 A2 返回给 Initiator 了。在返回 A2 包中填写如下数据:
ExpectCmdSN=57

MaxCmdSn = ExpectCmdSN + QueueSize -1= 57 + 16 -1 =72

这时 Initiator 端接收到这个响应包: ExpectCmdSN=57 说明命令序号 57 之前的命令(55,56)Target端都收到了。MaxCmdSN=72,说明 Initiator 可以连接发送命令序号为 57~72 的命令,而不必等 Target 的任何响应包。可以发 R3(CmdSN=57),R4(CmdSN=58),.....R18(CmdSN=72),但当发送到 R18 后,CmdSN 为 72 了,到达 MaxCmdSN 了,那么就不能再发包了,则必须等待 Target 的响应包。

由此可见,iSCSI 协议通过序号很好的处理的命令的顺序性问题和流量控制问题。

本文转载自http://blog.osdba.net/122.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值