新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 學習方法與實踐 > Linux SCSI 子系統(tǒng)剖析

Linux SCSI 子系統(tǒng)剖析

作者:M. Tim Jones 時間:2008-01-29 來源:IBM DW中國 收藏

   Small Computer Systems Interface (SCSI) 是一組標準集,它定義了與大量設備(主要是與存儲相關的設備)通信所需的接口和協(xié)議。 Linux® 提供了一種 SCSI 子系統(tǒng),用于與這些設備通信。Linux 是分層架構的一個很好的例子,它將高層的驅動器(比如磁盤驅動器或光驅)連接到物理接口,比如 Fibre Channel 或 Serial Attached SCSI(SAS)。本文向您介紹了 Linux SCSI 子系統(tǒng),并且討論了這些子系統(tǒng)將來的發(fā)展方向。
  GNU/Linux 和 SCSI 是很好的一個組合,因為二者在各自的環(huán)境中具有類似的特征。GNU/Linux 是一種安全可靠的操作系統(tǒng),可以不間斷地運行。SCSI 適合于可靠和高性能存儲。二者都是開源的。您可以下載和查閱 International Committee on Information Technology Standards (INCITS) T10 Technical Committee 的各種 SCSI 規(guī)范。同樣地,您也可以下載 GNU/Linux 源代碼以理解其實現(xiàn)。它們在各自的行業(yè)都具有主導性,所以相對其他操作系統(tǒng)而言,GNU/Linux 能更好地支持 SCSI,這一點就不足為奇了。

本文引用地址:http://www.butianyuan.cn/article/78202.htm

          SCSI 的演化

  SCSI 是一種很有趣的接口,它是早期的接口之一,如今還在不斷演化。第一種 SCSI 標準稱為 SCSI-1,是由 Shugart Associates 在 1979 年前后創(chuàng)建的。SCSI-1 定義了一種具有 5MHz 數(shù)據(jù)時鐘的 8-bit 并行接口,能提供最高 5 兆字節(jié)每秒(5 MB/s)的數(shù)據(jù)傳輸速率。

  SCSI-2 標準出現(xiàn)于 1985 年,它的出現(xiàn)使數(shù)據(jù)速率更快(10MHz),總線也更寬(16 位)。被稱為 Fast/Wide 的 SCSI-2 允許的數(shù)據(jù)傳輸速率高達 20 MB/s,并具有與 SCSI-1 的向后兼容性,但是速率也會限制到 SCSI-1 的數(shù)據(jù)速率。

  SCSI-3 的開發(fā)開始于 1993 年,現(xiàn)已成為了一組標準集,可以定義協(xié)議、命令集和信令方法。在 SCSI-3 中,包含一組命名為 Ultra 的并行 SCSI 標準和基于串行 SCSI 的協(xié)議,比如 IEEE 1394 (FireWire)、Fibre Channel, 、Internet SCSI (iSCSI) 和新興的 SAS。這些標準通過引入存儲網(wǎng)絡技術(比如 FC-AL 或 iSCSI)改變了傳統(tǒng)的存儲理念,將數(shù)據(jù)速率擴展到了 1 Gbit/s,將最大的可尋址設備數(shù)增加到了 100 以上,并將最大的電纜長度擴展到了 25 米。圖 1 展示了從 1986 至 2007 年 SCSI 的數(shù)據(jù)速率的變化

圖1SCSI 數(shù)據(jù)速率的演化

         SCSI 工作原理

  SCSI 實現(xiàn)了一種客戶機/服務器風格的通信架構。發(fā)起者向目標設備發(fā)送命令請求。該目標處理此請求并向發(fā)起者返回響應。發(fā)起者可以是托管計算機中的一個 SCSI 設備,而 SCSI 目標則可以是一個磁盤、光盤和磁帶設備或特殊設備(比如箱體設備)。

         SCSI 命令

  SCSI 傳輸所采用的協(xié)議已經(jīng)時過境遷,SCSI 命令卻保持了最初的元素。SCSI 命令是在 Command Descriptor Block (CDB) 中定義的。CDB 包含了用來定義要執(zhí)行的特定操作的操作代碼,以及大量特定于操作的參數(shù)。

  SCSI 命令支持讀寫數(shù)據(jù)(各有四個變量)以及很多非數(shù)據(jù)命令,比如 test-unit-ready(設備是否已就緒)、inquiry(檢索有關目標設備的基本信息)、read-capacity(檢索目標設備的存儲容量)等等。目標設備支持何種命令取決于設備的類型。發(fā)起者通過 inquiry 命令識別設備類型。表 1 列出了最常用的 SCSI 命令。

        表 1. 常見 SCSI 命令
  命令             用途
  Test unit ready    查詢設備是否已經(jīng)準備好進行傳輸
  Inquiry        請求設備基本信息
  Request sense    請求之前命令的錯誤信息
  Read capacity     請求存儲容量信息
  Read         從設備讀取數(shù)據(jù)
  Write         向設備寫入數(shù)據(jù)
  Mode sense      請求模式頁面(設備參數(shù))
  Mode select      在模式頁面配置設備參數(shù)

        借助大約 60 種可用命令,SCSI 可適用于許多設備(包括隨機存取設備,比如磁盤和像磁帶這樣的順序存儲設備)。SCSI 也提供了專門的命令以訪問箱體服務(比如存儲箱體內(nèi)部當前的傳感和溫度)。更多信息,請參見 參考資料 部分。

        Linux 內(nèi)核中的 SCSI 架構

  圖2 顯示了 SCSI 子系統(tǒng)在 Linux 內(nèi)核中的位置。內(nèi)核的頂部是系統(tǒng)調用接口,處理用戶空間調用到內(nèi)核中合適的目的地的路由(例如 open、read 或 write)。而虛擬文件系統(tǒng)(VFS) 是內(nèi)核中支持的大多數(shù)文件系統(tǒng)的抽象層。它負責將請求路由到合適的文件系統(tǒng)。大多數(shù)文件系統(tǒng)都通過緩沖區(qū)緩存來相互通信,這種緩存通過緩存最近使用的數(shù)據(jù)來優(yōu)化對物理設備的訪問。接下來是塊設備驅動器層,它包括針對底層設備的各種塊驅動器。SCSI 子系統(tǒng)是這種塊設備驅動器之一。
            

                                           圖 2. SCSI 子系統(tǒng)在 Linux 內(nèi)核中的位置

      與 Linux 內(nèi)核中的其他主流子系統(tǒng)不同,SCSI 子系統(tǒng)是一種分層的架構,共分為三層。頂部的那層叫做較高層,代表的是內(nèi)核針對 SCSI 和主要設備類型的驅動器的最高接口。接下來的是中間層,也稱為公共層或統(tǒng)一層。在這一層包含 SCSI 堆棧的較高層和較低層的一些公共服務。最后是較低層,代表的是適用于 SCSI 的物理接口的實際驅動器(參見圖 3)。
  

        圖 3. Linux SCSI 子系統(tǒng)的分層架構

       在 ./linux/drivers/scsi 可以找到 SCSI 子系統(tǒng)(SCSI 較高層、中間層和各種驅動器)的源代碼。SCSI 數(shù)據(jù)結構則位于 SCSI 源目錄,在 ./linux/include/scsi 也可以找到。

       SCSI 較高層

  SCSI 子系統(tǒng)的較高層代表的是內(nèi)核(設備級)最高級別的接口。它由一組驅動器組成,比如塊設備(SCSI 磁盤和 SCSI CD-ROM)和字符設備(SCSI 磁帶和 SCSI generic)。較高層接受來自上層(比如 VFS)的請求并將其轉換成 SCSI 請求。較高層負責完成 SCSI 命令并將狀態(tài)信息通知上層。

  SCSI 磁盤驅動器在 ./linux/drivers/scsi/sd.c 內(nèi)實現(xiàn)。SCSI 磁盤驅動器通過調用 register_blkdev(作為塊驅動器)進行自初始化并通過 scsi_register_driver 提供一組函數(shù)以表示所有 SCSI 設備。其中 sd_probe 和 sd_init_command 這兩個函數(shù)很重要。只要有新的 SCSI 設備附加到系統(tǒng), SCSI 中間層就會調用 sd_probe 函數(shù)。sd_probe 函數(shù)可決定此設備是否由 SCSI 磁盤驅動器管理,如果是,就創(chuàng)建新的 scsi_disk 結構來表示它。sd_init_command 函數(shù)將來自文件系統(tǒng)層的請求轉變成 SCSI 讀或寫命令(為完成這個 I/O 請求,sd_rw_intr 會被調用)。

  SCSI 磁帶驅動器在 ./linux/drivers/scsi/st.c 內(nèi)實現(xiàn)。磁帶驅動器是順序存取設備,會通過 register_chrdev_region 將自身注冊為字符設備。SCSI 磁帶驅動器還提供了一個 probe 函數(shù),稱為 st_probe。該函數(shù)會創(chuàng)建一種新磁帶設備并將其添加到稱為 scsi_tapes 的向量。SCSI 磁帶驅動器的獨特之處在于,如果可能,它可以直接從用戶空間執(zhí)行 I/O 傳輸。否則,數(shù)據(jù)會通過驅動器緩沖被分段。

  SCSI CD-ROM 驅動器在 ./linux/drivers/scsi/sr.c 內(nèi)實現(xiàn)。CD-ROM 驅動器是另一種塊設備并為 SCSI 磁盤驅動器提供類似的函數(shù)集。sr_probe 函數(shù)可用來創(chuàng)建 scsi_sd 結構以表示 CD-ROM 設備,并用 register_cdrom 注冊此 CD-ROM。SCSI 磁帶驅動器還會導出 sr_init_command,以將請求轉換成 SCSI CD-ROM 讀或寫請求。

  SCSI generic 驅動器在 ./linux/drivers/scsi/sg.c 內(nèi)實現(xiàn)。該驅動器允許用戶應用程序向設備發(fā)送 SCSI 命令(比如格式化、模式感知或診斷命令)。通過 sg3utils 包還可以從用戶空間利用 SCSI generic 驅動器。這個用戶空間包包括多種實用工具,可用來發(fā)送 SCSI 命令和解析這些命令的響應。

  SCSI 中間層

  SCSI 中間層是 SCSI 較高層和較低層的公共服務層(可以在 ./linux/drivers/scsi/scsi.c 內(nèi)部分地實現(xiàn))。它提供了很多可供較高層和較低層驅動器使用的函數(shù),因而可以充當這兩層間的連接層。中間層很重要,原因是它抽象化了較低層驅動器(LLD)的實現(xiàn),可以在 ./linux/drivers/scsi/hosts.c 中部分地實現(xiàn)。這意味著可以以同樣的方式使用帶不同接口的 Fibre Channel 主機總線適配器(HBA)。

  低層驅動器注冊和錯誤處理都由 SCSI 中間層提供。中間層還提供了較高層和較低層間的 SCSI 命令排隊。SCSI 中間層的一個重要功能是將來自較高層的命令請求轉換成 SCSI 請求。它也負責管理特定于 SCSI 的錯誤恢復。

  中間層可以連接 SCSI 子系統(tǒng)的較高層和較低層。它接受對 SCSI 事務的請求并對這些請求進行排隊以便處理 (如 ./linux/drivers/scsi/scsi_lib.c 中所示)。當這些命令完成后,它接受來自 LLD 的 SCSI 響應并通知較較高層此請求已經(jīng)完成。

  中間層最重要的職責之一是錯誤和超時處理。如果 SCSI 命令沒有在合理的時間內(nèi)完成或者 SCSI 請求返回錯誤,中間層就會管理錯誤或重新發(fā)送此請求。中間層還可管理較高層恢復,比如請求 HBA (LLD) 或 SCSI 設備重置。SCSI 錯誤和超時處理程序在 ./linux/drivers/scsi/scsi_error.c 內(nèi)實現(xiàn)。

  SCSI 較低層

  在最低層的是一組驅動器,稱為 SCSI 低層驅動器。它們是一些可與物理設備(比如 HBA)鏈接的特定驅動器。LLD 提供了自公共中間層到特定于設備的 HBA 的一種抽象。每個 LLD 都提供了到特定底層硬件的接口,但所使用的到中間層的接口卻是一組標準接口。

  較低層包含大量代碼,原因是它要負責處理各種不同的 SCSI 適配器類型。例如,F(xiàn)ibre Channel 協(xié)議包含了針對 Emulex 和 QLogic 的各種適配器的 LLD。面向 Adaptec 和 LSI 的 SAS 適配器的 LLD 也包括在內(nèi)。

  Linux 和 SCSI 的未來展望

  毫無疑問,SCSI 的發(fā)展前景很好,并且它會與 Linux 緊密相關。隨著 SCSI 的演化,Linux 將會一如既往地為不斷發(fā)展的技術提供支持。Linux 借助面向 HBA 的驅動器為新的 SAS 協(xié)議提供支持。隨著協(xié)議向更快的速度發(fā)展(比如 6 Gb SAS 或 8 Gb FC),Linux 必將處在發(fā)展和部署的前沿。

  您還會發(fā)現(xiàn) Linux 恰恰就是新 SCSI 協(xié)議的先進之處。FCoE(Fibre Channel over Ethernet)頗值得一提。FCoE 是全雙工 Ethernet 網(wǎng)絡(通常是 1Gb 或 10Gb Ethernet)上的一種 Fibre Channel 框架的映射。FCoE 之所以重要,是因為它將主流的網(wǎng)絡媒介與主流的企業(yè)存儲協(xié)議連接起來。這種新技術必然受人矚目,而且 Linux 也將不會例外。

  針對 SCSI 的端到端數(shù)據(jù)保護也在開發(fā)中,它源于 T10 的新數(shù)據(jù)完整性標準。這個標準為每扇區(qū)都增加了一個數(shù)據(jù)完整性字段(DIF)以保護介質上的數(shù)據(jù)。這個新的 8 字節(jié) DIF 字段包括一個循環(huán)冗余代碼(CRC)用以保護數(shù)據(jù),一個參考標簽用以保護數(shù)據(jù)免遭誤導寫入,以及一個應用程序標簽。應用程序標簽特定于應用程序,并且可以定義數(shù)據(jù)的用途,例如,一個 PDF 文件的一部分。請參見 參考資料 部分以獲取更多信息。

       結束語

  Linux 內(nèi)核是抽象的分層結構的另一個典型示例。它將各種文件系統(tǒng)連接到不同的物理存儲介質。若這些存儲介質與 SCSI 相關,SCSI 子系統(tǒng)會將公共 Linux 塊請求轉化為針對特定底層設備的 SCSI 請求。SCSI 子系統(tǒng)本身在過去若干年中經(jīng)歷了很多變化,而且這些變化還在繼續(xù)。諸如端到端數(shù)據(jù)保護這樣的新技術,與 FCoE 這樣的新協(xié)議一樣,都在想方設法尋找與 Linux 建立關系的途徑。 

linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)


關鍵詞: Linux SCSI 剖析 嵌入式

評論


相關推薦

技術專區(qū)

關閉