使用 SCSI 封装 IP
大约七年前,我开始接触 UNIX 操作系统,并很快熟悉了 UNIX 的网络伙伴:TCP/IP(传输控制协议/互联网协议)。随着时间的推移,我从 UNIX 命令行 TCP/IP 实用程序(即 TELNET 和 FTP)的用户,逐渐深入了解了这些协议的内部工作原理。
我读过的每一本关于 TCP/IP 的书都强调了一个观点,那就是 IP 被设计为可以封装在几乎任何可用的数据链路协议中。这种设计使其成为一种互联网协议;地球另一端的计算机连接到令牌环,而您的机器连接到以太网,这无关紧要。我发现这个概念非常令人印象深刻,因此我研究了各种现有的 IP 封装类型。当时,有 IP in IP、IP in IPX、IP in PPP、使用 NCR WaveLAN 扩频网络适配器的 IP over Ethernet 等等。
在 ATM(异步传输模式)和 100 Mbps 以太网普及之前,我开始思考还有哪些总线网络可用于计算机联网。有 ARCnet 和令牌环,但这些介质提供的吞吐量能力与以太网相当。此外,我对使用一组廉价 PC 在同一房间进行粗粒度并行处理实验很感兴趣,在这种情况中,应用程序不仅需要分派作业,还需要交换大型数据集才能完成任务。在这种情况下,网络延迟不是主要问题,但吞吐量是。
或许是由于其与以太网的类似操作,SCSI(小型计算机系统接口)协议突然出现在我的脑海中。它非常快——SCSI-2 适配器在当时很常见。SCSI 与以太网有一些共同的属性,使其适合作为网络数据链路:每个“站”都有一个标识符,任何时候只有一个“站”可以使用总线,并且总线的每一端都必须用具有特征阻抗的终端电阻器端接。SCSI 提供了一个微型以太网,只是速度快得多。
我获得了 ANSI SCSI 标准文档,并开始进行必要的背景研究,以便开展这样的项目。在阅读了大量资料并从 SCSI-1 升级到 SCSI-2 后,我开始思考一种可以优雅地处理 IP 版本 4 封装的设计。我立即认识到即将到来的 IP 版本 6 的问题,但选择忽略它们,因为我想立即让一些东西运行起来。我还认为,开发另一种会被 IP 版本 6 打断的协议不会造成太大的危害。
我的设计促成了 RFC(请求评论)草案文档,题为“IP Encapsulation over the Small Computer Systems Interface”,可以在 ftp://ftp.internic.net/rfc/rfc2143.txt 找到。
SCSI 是一种外围设备互连技术,旨在为硬件制造商提供标准化的协议和硬件描述,以便构建可以互连的外围设备和计算机。例如,Apple Macintosh 是早期大规模生产的计算机,允许连接 SCSI 设备。
SCSI 设备通过在共享总线上发送数据包来相互通信。设备使用硬件握手来获取总线——当另一个设备使用总线时,所有其他设备必须保持沉默。与以太网不同,总线不是使用冲突检测机制来访问的。相反,设备遵循有状态算法来获取总线。空闲时,总线处于一种状态或阶段,称为 总线空闲阶段。如果设备希望访问总线,它将进入 仲裁阶段,但前提是总线之前处于 总线空闲阶段。显然,这里存在互斥的经典问题,即两个设备检查总线的状态,都发现它处于总线空闲阶段,然后都进入仲裁。在这种情况下,SCSI ID 最高的设备总是获胜。这在设计运行 IP over SCSI 的机器网络时可能显得很重要。
仲裁后,设备进入 选择阶段,其中目标 SCSI 设备的 ID 被放置在数据总线上。命令阶段 用于将命令数据传输到目标。重选 阶段在目标设备希望响应发起者时进入。这允许总线在设备执行其任务时被其他设备使用。数据输入 和 数据输出 阶段用于在发起者和目标之间实际传输数据。消息输入 和 消息输出 阶段可用于在发起者和目标之间传输额外的控制信息。状态 阶段用于将状态字节从目标传输回发起者,以指示操作的结果。例如,磁带驱动器可能会返回一个状态代码,指示介质未加载。
在项目开始时,我指定了一些总体目标。这些目标对我的“IP over SCSI”项目的范围产生了重大影响。有些人发现了一些值得批评的地方——有时,他们是对的。最重要的是要意识到,提出的一些问题只是不符合当前项目的范围。它们将在以后的实现中解决。我设定的目标是
采取纯粹主义的方法,开发一种在 SCSI 总线上承载 IP 数据报的方法。这意味着必须接受 SCSI 的局限性,例如可寻址站点的数量,并且需要使用传统的策略(例如在这些小型 SCSI 网络之间设置 IP 网关)来构建更大的网络。这有一个有趣的后果,稍后将讨论。
开发一种易于指定且易于实现的协议。
在 Linux 内核中将协议实现为模块化网络接口(从可以使用内核模块工具加载和卸载的意义上来说)。我使用 Linux 的原因非常明显:基于 PC 的 SCSI 适配器比任何其他系统的 SCSI 适配器都更容易获得,并且 Linux 内核源代码可以免费研究和修改。此外,大多数内核开发人员都乐于通过电子邮件进行交流,以解释源代码块或文档不足的领域。
以这样一种方式实现网络接口,使其无论 SCSI 主机适配器的型号如何,都能正确运行。这可能会带来进一步的性能损失,但对于大多数应用程序来说,这显然是可取的。
鉴于这些设计目标,我开发了一个具有以下属性的网络驱动程序
利用 Linux SCSI 中间层来满足与主机适配器接口的要求,而无需考虑制造商。这无疑会引发一些性能问题,但我尚未确定这些问题。SCSI 中间层不承认将主机适配器初始化为 目标模式 的要求,这意味着,不幸的是,如果每个 Linux 底层 SCSI 设备驱动程序确实要能够支持目标模式或支持 IP over SCSI,则需要对其进行修改。我以这种方式修改了 Adaptec 1522 设备驱动程序,但修改所有 Linux SCSI 驱动程序似乎需要大量工作。
IP 数据报可以从任何 SCSI 主机适配器传输到任何其他主机适配器。这些适配器可能在同一主机中,或者更可能在独立的主机中。
当我设计 IP over SCSI 时,我的目的是允许许多位置接近的运行 Linux 的机器使用其现有的基础软件应用程序进行通信,而无需修改,但速度要快得多。然而,这的价值很小,因为以太网等网络似乎满足了大多数人的需求。
其他尚未充分利用的应用可能会从主机之间的高速互连中获益匪浅。我最近亲眼目睹了 PVM(并行虚拟机)管理器在 31 台基于奔腾的 Linux 机器上运行大规模计算的演示,我们观察到瓶颈是用于在机器之间传输“工作”单元和后续结果的网络。
因此,我认为 IP over SCSI 有许多直接的应用
用于通用应用程序的高速网络设施(例如,在研究实验室中使用它作为 NFS 文件共享的专用网络),而以太网可用于所有其他应用程序。
一种连接现有、位置接近的机器以用于高速应用程序(例如 FTP 镜像或 Web 搜索引擎)的方法。
使用互联网概念构建的集群和粗粒度超立方体:通过 SCSI 连接的小型主机网络,并通过一个或多个 SCSI 互连连接到所有其他此类网络。在这里,每个配备多个 SCSI 适配器的多宿主主机充当连接网络之间的 IP 网关。可以设想如下结构
.----+---+---+---+---+---. | | | | | | B C D E A | F G H I | | | | | .----+---+---+---+---+---.
在这里,主机 [B-E] 可以与主机 [F-I] 通信,尽管例如 SCSI-1 总线无法支持总共九台主机。
更有创意
A---B---C---D---E---. | F---G---H---I---J---. | K---L---M---N---O---. | P---Q---R---S---T---. | U---V---W---X---Y---.
通过至少向网关主机 {A,F,K,P,U} 添加第三个 SCSI 接口,这种安排自然可以扩展到三个维度。
IP over SCSI 的封装协议已被记录和起草多次,并通过了互联网工程任务组,现在作为 RFC 文档(RFC 2143)发布。
人们对这个概念产生了浓厚的兴趣。另一位 Linux 用户和最近的计算机科学毕业生 Randy Scott 成功地实现了 IP over SCSI 协议。他的项目并不完全符合 RFC 中给出的协议,但它确实证明了这个概念是可行的。然而,Randy 的工作表明,在 Linux 内核中进行 IP 网络连接时存在性能问题,其中大部分超出了他的控制范围。据了解,对于网络接口是否可以具有 64KB 的最大传输单元 (MTU) 存在一些疑问。
我自己的实现并没有像我希望的那样受到我的关注。直到最近,工作进展顺利。我有一个模块化的网络接口,可以使用 insmod 和 ifconfig 启动,并且可以使用我实现的地址解析协议 (ARP) 将 IP 数据包发送到 SCSI 总线并选择正确的 SCSI ID。
下一步是验证对设备驱动程序进行的初始化目标模式的修改,然后从 SCSI 总线接收数据并将其传递到协议栈。我将不胜感激任何有兴趣的个人在完成此项目方面提供的帮助。
Ben Elliston 是一位软件工程师,目前在 Cygnus Solutions 工作。他对计算机的兴趣只是给他带来了麻烦,所以在业余时间,他喜欢攀岩、山地自行车、弹吉他和观看拉力赛。可以通过 bje@cygnus.com 与他联系。