SCSI 磁帶驅動程式

此檔案包含關於 SCSI 磁帶驅動程式的簡要資訊。該驅動程式目前由 Kai Mäkisara 維護(電子郵件 Kai.Makisara@kolumbus.fi

上次修改時間:2016 年 2 月 9 日星期二 21:54:16,作者 kai.makisara

基本原理

該驅動程式是通用的,即它不包含任何針對特定磁帶驅動器的程式碼。磁帶引數可以使用以下三種方法之一指定

1. 每個使用者可以直接使用 ioctl 指定他/她想要使用的磁帶引數。這在管理上是一種非常簡單靈活的方法,適用於單使用者工作站。但是,在多使用者環境中,下一個使用者會發現磁帶引數處於上一個使用者離開時的狀態。

2. 系統管理員 (root) 可以使用 MTSETDRVBUFFER ioctl 為某些磁帶引數定義預設值,例如塊大小和密度。可以對這些引數進行程式設計,使其在新磁帶載入到驅動器中時生效,或者如果在磁帶開頭開始寫入時生效。如果磁帶驅動器能夠很好地自動檢測磁帶格式(如某些 QIC 驅動器),則第二種方法適用。結果是任何磁帶都可以讀取,可以使用現有格式繼續寫入,並且如果從頭開始重寫磁帶(或首次寫入新磁帶),則使用預設格式。如果驅動器不能很好地執行自動檢測,並且裝置的單個“合理”模式,則第一種方法適用。一個例子是僅在可變塊模式下使用的 DAT 驅動器(我不知道這是否合理 :-)。

使用者可以覆蓋系統管理員定義的引數。這些更改會持續存在,直到預設值再次生效。

3. 預設情況下,最多可以定義四種模式,並使用次要數字(位 5 和 6)選擇。可以透過更改 st.h 中的 ST_NBR_MODE_BITS 來更改模式數量。模式 0 對應於上面討論的預設值。其他模式處於休眠狀態,直到系統管理員 (root) 定義它們。啟動新模式的規範時,模式 0 的配置用於為新模式的定義提供起點。

使用模式允許系統管理員讓使用者可以選擇某些使用者無法直接訪問的緩衝引數(緩衝和非同步寫入)。這些模式還允許在多磁帶操作中選擇格式(當載入新磁帶時,顯式覆蓋的引數會被重置)。

如果使用多個模式,則所有模式應包含相同引數集的定義。

許多 Unix 包含內部表,將不同的模式與支援的裝置相關聯。Linux SCSI 磁帶驅動程式不包含此類表(並且將來也不會這樣做)。相反,可以製作一個實用程式,用於獲取裝置傳送的查詢資料,掃描其資料庫,並使用 ioctl 設定模式。另一種方法是建立一個使用 mt 設定針對系統定製的預設值的小指令碼。

該驅動程式支援固定和可變塊大小(在緩衝區限制範圍內)。自動倒帶(次要等於裝置號)和非倒帶裝置(次要為 128 + 裝置號)都已實現。

在可變塊模式下,write() 中的位元組數決定了磁帶上的物理塊大小。讀取時,如果 read() 位元組數至少為塊大小,則驅動器將讀取下一個磁帶塊並將資料返回給使用者。否則,將返回錯誤 ENOMEM。

在固定塊模式下,驅動器和驅動程式之間的資料傳輸是塊大小的倍數。write() 位元組數必須是塊大小的倍數。讀取時不需要這樣做,但為了可移植性,可能建議這樣做。

提供對更改磁帶分割槽和使用一個或兩個分割槽對磁帶進行分割槽的支援。預設情況下,每個驅動程式都停用對分割槽磁帶的支援,可以使用 ioctl MTSETDRVBUFFER 啟用。

預設情況下,驅動程式在寫入後關閉裝置並且上次操作是寫入時寫入一個檔案標記。可以選擇寫入兩個檔案標記。在這兩種情況下,資料的結尾都透過為兩個連續讀取返回零位元組來表示。

在 SCSI 命令塊中寫入沒有設定立即位的檔案標記充當同步點,即,驅動器緩衝區中的所有剩餘資料在命令返回之前都寫入到磁帶。這確保了在該點捕獲寫入錯誤,但這需要時間。在某些應用程式中,必須快速寫入幾個連續的檔案。MTWEOFI 操作可用於在不重新整理驅動器緩衝區的情況下寫入檔案標記。在 close() 寫入檔案標記始終會重新整理驅動器緩衝區。但是,如果之前的操作是 MTWEOFI,則 close() 不寫入檔案標記。如果程式想要在檔案之間關閉/開啟磁帶裝置並且想要跳過等待,可以使用此方法。

如果完成倒帶、離線、bsf 或 seek,並且之前的磁帶操作是寫入,則在移動磁帶之前會寫入檔案標記。

編譯選項在檔案 linux/drivers/scsi/st_options.h 中定義。

4. 如果使用開啟選項 O_NONBLOCK,即使驅動器未準備好,開啟也會成功。如果不使用 O_NONBLOCK,驅動程式會等待驅動器準備就緒。如果 ST_BLOCK_SECONDS 秒內未發生這種情況,則開啟失敗,errno 值為 EIO。使用 O_NONBLOCK,即使驅動器中有防寫磁帶,也可以開啟裝置進行寫入(嘗試寫入任何內容的命令如果嘗試則返回錯誤)。

次要數字

如果每個驅動器使用 4 種模式,則磁帶驅動程式當前支援最多 2^17 個驅動器。

次要數字由以下位欄位組成

dev_upper non-rew mode dev-lower
20 -  8     7    6 5  4      0

非倒帶位始終是位 7(最下面的位元組中的最高位)。定義模式的位低於非倒帶位。其餘位定義磁帶裝置號。此編號與次要數字僅 8 位寬時使用的編號向後相容。

Sysfs 支援

該驅動程式建立目錄 /sys/class/scsi_tape 並使用對應於現有磁帶裝置的目錄填充它。每個模式都有自動倒帶和非倒帶條目。名稱是 stxy 和 nstxy,其中 x 是磁帶編號,y 是對應於模式的字元(none、l、m、a)。例如,第一個磁帶裝置的目錄是(假設有四種模式):st0 nst0 st0l nst0l st0m nst0m st0a nst0a。

每個目錄包含以下條目:default_blksize default_compression default_density defined dev device driver。檔案“defined”包含 1(如果模式已定義),否則包含 0。檔案“default_*”包含使用者設定的預設值。值 -1 表示未設定預設值。檔案“dev”包含對應於此裝置的裝置號。連結“device”和“driver”指向 SCSI 裝置和驅動程式條目。

每個目錄還包含條目“options”,它顯示當前啟用的驅動程式和模式選項。檔案中的值是一個位掩碼,其中位定義與 MTSETDRVBUFFER 中設定選項時使用的位定義相同。

每個目錄都包含條目“position_lost_in_reset”。如果此值為 1,則在裝置重置後阻止對裝置的讀取和寫入。大多數裝置在重置後會倒帶磁帶,並且寫入/讀取不會訪問使用者期望的磁帶位置。

從 SCSI 裝置目錄到對應於模式 0 自動倒帶裝置的類目錄(例如,st0)建立一個名為“tape”的連結。

磁帶裝置的 Sysfs 和統計資訊

st 驅動程式維護 sysfs 檔案系統中的磁帶驅動器統計資訊。可以使用以下方法來找到可用的統計資訊(假設 sysfs 安裝在 /sys 上)

  1. 在目錄 /sys/class/scsi_tape 上使用 opendir(3)

  2. 使用 readdir(3) 讀取目錄內容

  3. 使用 regcomp(3)/regexec(3) 將目錄條目與擴充套件的正則表示式“^st[0-9]+$”匹配

  4. 從 /sys/class/scsi_tape/<match>/stats 目錄訪問統計資訊(其中 <match> 是 /sys/class/scsi_tape 中與擴充套件正則表示式匹配的目錄條目)

使用此方法的原因是,指向同一磁帶驅動器的所有字元裝置都使用相同的統計資訊。這意味著 st0 將具有與 nst0 相同的統計資訊。

該目錄包含以下統計資訊檔案

  1. in_flight
    • 當前傳送到此裝置的 I/O 數量。

  2. io_ns
    • 等待所有 I/O 完成所花費的時間(以納秒為單位)(包括讀取和寫入)。這包括磁帶移動命令,例如在檔案或集合標記之間尋找,以及隱式磁帶移動,例如在使用關閉時倒帶磁帶裝置時。

  3. other_cnt
    • 除了讀取或寫入命令之外,傳送到磁帶驅動器的 I/O 數量。完成這些命令所花費的時間使用以下計算 io_ms-read_ms-write_ms。

  4. read_byte_cnt
    • 從磁帶驅動器讀取的位元組數。

  5. read_cnt
    • 傳送到磁帶驅動器的讀取請求數量。

  6. read_ns
    • 等待讀取請求完成所花費的時間(以納秒為單位)。

  7. write_byte_cnt
    • 寫入到磁帶驅動器的位元組數。

  8. write_cnt
    • 傳送到磁帶驅動器的寫入請求數量。

  9. write_ns
    • 等待寫入請求完成所花費的時間(以納秒為單位)。

  10. resid_cnt
    • 在讀取或寫入過程中,我們發現剩餘數量非零的次數。這應該意味著程式正在發出大於磁帶上塊大小的讀取。對於寫入,並非所有資料都已寫入到磁帶。

注意

在 I/O 啟動時增加 in_flight 值,I/O 本身在完成之前不會新增到統計資訊中。

read_cnt、write_cnt 和 other_cnt 的總和可能與裝置級別的 iodone_cnt 的值不同。磁帶統計資訊僅計算透過 st 模組發出的 I/O。

當讀取統計資訊時,當 I/O 正在進行時,它們在時間上可能不一致。單獨的值是原子地讀取和寫入的,但是當透過 sysfs 將它們讀回時,它們可能在啟動 I/O 或完成 I/O 時正在被更新。

在更新任何統計資訊之前增加 in_flight 中顯示的值,並在完成 I/O 時更新統計資訊後減少該值。當沒有 st 驅動程式發出的未完成 I/O 時,in_flight 的值為 0。磁帶統計資訊不考慮透過 sg 裝置執行的任何 I/O。

BSD 和 Sys V 語義

使用者可以透過定義符號 ST_SYSV 的值來選擇磁帶驅動程式的這兩種行為。當正在讀取的檔案關閉時,語義不同。BSD 語義將磁帶留在當前位置,而 SYS V 語義將磁帶移動到下一個檔案標記之後,除非剛剛越過該檔案標記。

預設設定為 BSD 語義。

緩衝

該驅動程式嘗試直接從使用者空間執行傳輸。如果不可能,則使用在執行時分配的驅動程式緩衝區。如果整個傳輸不可能進行直接 i/o,則使用驅動程式緩衝區(即,不使用單個頁面的跳轉緩衝區)。由於多種原因,直接 i/o 可能不可能,例如

  • 一個或多個頁面位於 HBA 無法訪問的地址。

  • 傳輸中的頁面數超過了 HBA 允許的散點/收集段數。

  • 一個或多個頁面無法鎖定到記憶體中(在任何合理的情況下都不應發生)。

驅動程式緩衝區的大小始終至少為一個磁帶塊。在固定塊模式下,最小緩衝區大小由 ST_FIXED_BUFFER_BLOCKS(以 1024 位元組為單位)定義。對於小塊大小,這允許緩衝多個塊並使用一個 SCSI 讀取或寫入來傳輸所有塊。如果 ST_BUFFER_WRITES 為非零並且未使用直接 i/o,則允許跨固定塊模式下的寫入呼叫緩衝資料。緩衝區分配使用大小為 2^n *(頁面大小)的記憶體塊。因此,實際緩衝區大小可能大於最小允許緩衝區大小。

請注意,如果使用直接 i/o,則不會緩衝小寫入。從 2.4 遷移時,這可能會導致意外。在那裡,小寫入(例如,沒有 -b 選項的 tar)可能具有良好的吞吐量,但在 2.6 中不再是這樣。可以關閉直接 i/o 來解決此問題,但更好的解決方案是使用更大的 write() 位元組數(例如,tar -b 64)。

非同步寫入。啟動將緩衝區內容寫入到磁帶,並且寫入呼叫立即返回。在下一個磁帶操作中檢查狀態。非同步寫入不是使用直接 i/o 完成的,也不是在固定塊模式下完成的。

如果早期警告標記後沒有足夠的空間來重新整理驅動程式緩衝區,則緩衝寫入和非同步寫入在某些罕見情況下可能會導致多卷操作出現問題。

固定塊模式的預讀 (ST_READ_AHEAD)。即使使用者不想在此讀取命令中獲取所有資料,也會嘗試填充緩衝區。對於那些不喜歡檔案標記截斷讀取請求或不喜歡退回的驅動器,應停用此功能。

如果無法分配連續緩衝區,則使用散點/收集緩衝區(由物理記憶體中不連續的塊組成的緩衝區)。為了支援所有 SCSI 介面卡(包括那些不支援散點/收集的介面卡),緩衝區分配使用以下三種塊

  1. 初始段,用於所有 SCSI 介面卡,包括那些不支援散點/收集的介面卡。如果系統可以提供此大小的塊(並且它不大於 ST_BUFFER_BLOCKS 指定的緩衝區大小),則此緩衝區的大小將為 (PAGE_SIZE << ST_FIRST_ORDER) 位元組。如果此大小不可用,則驅動程式將大小減半並重試,直到大小為一個頁面。st_options.h 中的預設設定使驅動程式嘗試將所有緩衝區分配為一個塊。

  2. 分配散點/收集段以填充指定的緩衝區大小,以便使用盡可能多的段,但段數不超過 ST_FIRST_SG。

  3. ST_MAX_SG(或模組引數 max_sg_segs)與階段 1 和 2 中使用的段數之間的剩餘段用於在執行時擴充套件緩衝區(如果需要)。如果允許用於 SCSI 介面卡的散點/收集段數小於指定的最大散點/收集段數,則不會超過該數量。如果允許用於 SCSI 介面卡的最大段數小於階段 1 和 2 中使用的段數,則擴充套件緩衝區將始終失敗。

寫入時的 EOM 行為

當遇到介質早期警告的末尾時,將完成當前寫入並返回位元組數。下一個寫入返回 -1,並且 errno 設定為 ENOSPC。要啟用寫入尾部,允許下一個寫入繼續進行,並且如果成功,則返回位元組數。此後,交替返回 -1 和位元組數,直到遇到介質的物理末尾(或其他一些錯誤)。

模組引數

當驅動程式作為模組載入時,可以配置緩衝區大小、寫入閾值和分配的最大緩衝區數。關鍵詞是

buffer_kbs=xxx

固定塊模式的緩衝區大小設定為 xxx KB

write_threshold_kbs=xxx

寫入閾值(以 KB 為單位)設定為 xxx

max_sg_segs=xxx

最大散點/收集段數

try_direct_io=x

如果此值為非零,則嘗試在使用者緩衝區和磁帶驅動器之間進行直接傳輸

請注意,如果更改了緩衝區大小但未設定寫入閾值,則寫入閾值將設定為新的緩衝區大小 - 2 KB。

啟動時配置

如果驅動程式已編譯到核心中,則也可以使用 LILO 命令列設定相同的引數。首選語法是使用與作為模組載入時使用的關鍵字相同的關鍵字,但前面加上“st.”。例如,要設定最大散點/收集段數,應使用引數“st.max_sg_segs=xx”(xx 是散點/收集段數)。

為了相容性,支援早期 2.5 和 2.4 核心版本的舊語法。可以使用與將驅動程式作為模組載入時相同的關鍵字。如果設定了多個引數,則關鍵字-值對用逗號分隔(不允許有空格)。可以使用冒號代替等號。定義前面加上字串 st=。這是一個例子

st=buffer_kbs:64,write_threshold_kbs:60

還支援舊核心版本使用的以下語法

st=aa[,bb[,dd]]

其中

  • aa 是固定塊模式的緩衝區大小(以 1024 位元組為單位)

  • bb 是寫入閾值(以 1024 位元組為單位)

  • dd 是最大散點/收集段數

IOCTL

磁帶的位置和驅動器引數使用 mtio.h 中定義的 ioctl 設定。磁帶控制程式“mt”使用這些 ioctl。嘗試找到一個 mt,它支援所有 Linux SCSI 磁帶 ioctl,並且如果將修改磁帶內容,則開啟裝置進行寫入(從 Linux ftp 站點查詢程式包 mt-st*;GNU mt 不開啟進行寫入,例如,擦除)。

支援的 ioctl 是

以下使用結構 mtop

MTFSF

向前跳過計數檔案標記。磁帶位於檔案標記之後。

MTFSFM

與上述相同,但磁帶位於檔案標記之前。

MTBSF

向後跳過計數檔案標記。磁帶位於檔案標記之前。

MTBSFM

與上述相同,但磁帶位於檔案標記之後。

MTFSR

向前跳過計數記錄。

MTBSR

向後跳過計數記錄。

MTFSS

向前跳過計數集合標記。

MTBSS

向後跳過計數集合標記。

MTWEOF

寫入計數檔案標記。

MTWEOFI

寫入設定了立即位的檔案標記計數(即,不等待資料寫入磁帶)

MTWSM

寫入計數集合標記。

MTREW

倒帶磁帶。

MTOFFL

將裝置設定為離線(通常是倒帶加上彈出)。

MTNOP

除了重新整理緩衝區之外,什麼也不做。

MTRETEN

重新拉緊磁帶。

MTEOM

跳到記錄資料的末尾。

MTERASE

擦除磁帶。如果引數為零,則使用短擦除命令。長擦除命令與引數的所有其他值一起使用。

MTSEEK

尋找磁帶塊計數。對 SCSI-1 驅動器使用 Tandberg 相容的 seek (QFA),對 SCSI-2 驅動器使用 SCSI-2 seek。seek 之後的檔案的檔案號和塊號無效。

MTSETBLK

設定驅動器塊大小。設定為零將驅動器設定為可變塊模式(如果適用)。

MTSETDENSITY

將驅動器密度程式碼設定為 arg。有關可用程式碼,請參閱驅動器文件。

MTLOCK 和 MTUNLOCK

顯式鎖定/解鎖磁帶驅動器門。

MTLOAD 和 MTUNLOAD

顯式載入和解除安裝磁帶。如果命令引數 x 介於 MT_ST_HPLOADER_OFFSET + 1 和 MT_ST_HPLOADER_OFFSET + 6 之間,則編號 x 用於隨命令傳送到驅動器,並選擇 HP C1553A 切換器要使用的磁帶插槽。

MTCOMPRESSION

使用 SCSI 模式頁 15 設定壓縮或解壓縮驅動器模式。請注意,某些驅動器使用其他方法來控制壓縮。某些驅動器(如 Exabytes)使用密度程式碼進行壓縮控制。某些驅動器使用另一個模式頁,但此頁尚未在驅動程式中實現。某些沒有壓縮功能的驅動器將接受任何壓縮模式而不會出錯。

MTSETPART

在下一個磁帶操作時將磁帶移動到引數給定的分割槽。磁帶定位的塊是在新的活動分割槽中先前磁帶定位的塊,除非下一個磁帶操作是 MTSEEK。在這種情況下,磁帶將直接移動到 MTSEEK 指定的塊。除非設定 MT_ST_CAN_PARTITIONS,否則 MTSETPART 無效。

MTMKPART

使用一個分割槽(引數為零)或兩個分割槽(引數為非零)格式化磁帶。如果引數為正數,則它指定分割槽 1 的大小(以 MB 為單位)。對於 DDS 驅動器和幾個早期驅動器,這是磁帶的物理上第一個分割槽。如果引數為負數,則其絕對值指定分割槽 0 的大小(以 MB 為單位)。這是許多後來的驅動器(如 LTO-5 及以上的 LTO 驅動器)的物理上第一個分割槽。該驅動器必須支援由啟動器指定大小的分割槽。除非設定 MT_ST_CAN_PARTITIONS,否則無效。

MTSETDRVBUFFER

用於多種目的。該命令從帶有掩碼 MT_SET_OPTIONS 的計數獲得,低位用作引數。此命令僅允許超級使用者 (root) 使用。子命令是

  • 0

    驅動器緩衝區選項設定為引數。零表示沒有緩衝。

  • MT_ST_BOOLEANS

    設定緩衝選項。這些位是以下選項的新狀態(已啟用/已停用)(括號中指定選項是全域性的還是可以針對每種模式指定不同的選項)

    MT_ST_BUFFER_WRITES

    寫入緩衝(模式)

    MT_ST_ASYNC_WRITES

    非同步寫入(模式)

    MT_ST_READ_AHEAD

    預讀(模式)

    MT_ST_TWO_FM

    寫入兩個檔案標記(全域性)

    MT_ST_FAST_EOM

    使用 SCSI 間距到 EOD(全域性)

    MT_ST_AUTO_LOCK

    自動鎖定驅動器門(全域性)

    MT_ST_DEF_WRITES

    預設值僅用於寫入(模式)

    MT_ST_CAN_BSR

    可以使用跨多個記錄的退回操作來重新定位磁帶(全域性)

    MT_ST_NO_BLKLIMS

    驅動程式不從驅動器詢問塊限制(只能將塊大小更改為可變)(全域性)

    MT_ST_CAN_PARTITIONS

    啟用對分割槽磁帶的支援(全域性)

    MT_ST_SCSI2LOGICAL

    對於 SCSI-2 驅動器,在 MTSEEK 和 MTIOCPOS 中使用邏輯塊號,而不是裝置相關的地址。建議設定此標誌,除非存在使用裝置相關的磁帶(來自舊時代)(全域性)

    MT_ST_SYSV

    設定 SYSV 語義(模式)

    MT_ST_NOWAIT

    為某些命令(例如,倒帶)啟用立即模式(即,不等待命令完成)

    MT_ST_NOWAIT_EOF

    啟用立即檔案標記模式(即,在寫入檔案標記時,不等待它完成)。請參閱關於 MTWEOFI 的基本原理註釋,瞭解寫入立即檔案標記的可能危險。

    MT_ST_SILI

    在可變塊模式下讀取時,啟用在 SCSI 命令中設定 SILI 位,以提高讀取短於位元組數的塊時的效能;僅當您確定驅動器支援 SILI 並且 HBA 正確返回傳輸殘留時才設定此值

    MT_ST_DEBUGGING

    除錯(全域性;必須將除錯編譯到驅動程式中)

  • MT_ST_SETBOOLEANS、MT_ST_CLEARBOOLEANS

    設定或清除選項位。

  • MT_ST_WRITE_THRESHOLD

    將此裝置的寫入閾值設定為最低位指定的 KB 數。

  • MT_ST_DEF_BLKSIZE

    定義自動設定的預設塊大小。值 0xffffff 表示不再使用預設值。

  • MT_ST_DEF_DENSITY、MT_ST_DEF_DRVBUFFER

    用於設定或清除密度(8 位)和驅動器緩衝區狀態(3 位)。如果該值為 MT_ST_CLEAR_DEFAULT (0xfffff),則不再使用預設值。否則,該值的最低位包含引數的新值。

  • MT_ST_DEF_COMPRESSION

    如果最低位元組的值為 0xff,則不使用壓縮預設值。否則,最低位包含新的預設值。如果位 8-15 設定為非零數字,並且此數字不是 0xff,則該數字用作壓縮演算法。可以使用值 MT_ST_CLEAR_DEFAULT 清除壓縮預設值。

  • MT_ST_SET_TIMEOUT

    為此裝置設定正常超時(以秒為單位)。預設值為 900 秒(15 分鐘)。超時應足夠長,以便裝置在讀取/寫入時完成重試。

  • MT_ST_SET_LONG_TIMEOUT

    設定用於已知需要長時間操作的長超時。預設值為 14000 秒(3.9 小時)。對於擦除,此值還要乘以 8。

  • MT_ST_SET_CLN

    使用引數的最低 24 位設定清理請求解釋引數。如果從擴充套件檢測資料中找到清理請求位模式,驅動程式可以設定通用狀態位 GMT_CLN。當驅動器需要清理時,許多驅動器在擴充套件檢測資料中設定一個或多個位。這些位取決於裝置。驅動程式會獲得檢測資料位元組的編號(引數的最低 8 位;必須 >= 18(保留值 1 - 17)且 <= 最大請求的檢測資料大小)、用於選擇相關位的掩碼(位 9-16)和位模式(位 17-23)。如果位模式為零,則掩碼下的一個或多個位指示清理請求。如果模式為非零,則模式必須與遮蔽的檢測資料位元組匹配。

    (如果看到附加的檢測程式碼和限定符 00h 17h,則無論 MT_ST_SET_CLN 的設定如何,都會設定清理位。)

以下 ioctl 使用結構 mtpos

MTIOCPOS

從驅動器讀取當前位置。對 SCSI-1 驅動器使用 Tandberg 相容的 QFA,對 SCSI-2 驅動器使用 SCSI-2 命令。

以下 ioctl 使用結構 mtget 返回狀態

MTIOCGET

返回一些狀態資訊。返回檔案號和檔案中的塊號。當無法確定塊時(例如,在 MTBSF 之後),塊為 -1。驅動器型別為 MTISSCSI1 或 MTISSCSI2。自上次狀態呼叫以來恢復的錯誤數儲存在欄位 mt_erreg 的低字中。當前塊大小和密度程式碼儲存在欄位 mt_dsreg 中(子欄位的偏移量為 MT_ST_BLKSIZE_SHIFT 和 MT_ST_DENSITY_SHIFT)。GMT_xxx 狀態位反映驅動器狀態。如果沒有磁帶在驅動器中,則設定 GMT_DR_OPEN。GMT_EOD 表示記錄資料的末尾或磁帶的末尾。GMT_EOT 表示磁帶的末尾。

其他編譯選項

如果定義了 ST_RECOVERED_WRITE_FATAL,則恢復的寫入錯誤被認為是致命的。

磁帶裝置的最大數量由 define ST_MAX_TAPES 確定。如果在驅動程式初始化時檢測到更多磁帶,則會相應地調整最大值。

可以透過定義 ST_NOWAIT 來啟用從磁帶定位 SCSI 命令立即返回。如果定義了此值,則使用者應注意在上一個磁帶操作完成之前未啟動下一個磁帶操作。驅動器和 SCSI 介面卡應正常處理這種情況,但已知某些驅動器/介面卡組合會在這種情況下掛起 SCSI 匯流排。

預設情況下,MTEOM 命令實現為跨 32767 個檔案標記的間距。使用此方法,狀態中的檔案號是正確的。使用者可以透過設定 ST_FAST_EOM 1(或使用 MT_ST_OPTIONS ioctl)來請求使用直接間距到 EOD。在這種情況下,檔案號將無效。

當使用預讀或緩衝寫入時,關閉檔案後,檔案中的位置可能不正確(正確的位置可能需要退回多個記錄)。如果在編譯時定義了 ST_IN_FILE_POS,或者驅動器的 MT_ST_CAN_BSR 位設定為 ioctl,則可以獲得檔案中正確的位置。(如果使用者沒有請求那麼遠的資料,則驅動程式始終退回預讀越過的檔案標記。)

除錯提示

除錯程式碼現在預設編譯,但使用核心模組引數 debug_flag(預設為 0)關閉除錯。仍然可以使用 ioctl 開啟和關閉除錯。要在模組載入時啟用除錯,請將 debug_flag=1 新增到模組載入選項,除錯輸出並不多。還可以透過向 sysfs 檔案 /sys/bus/scsi/drivers/st/debug_flag 寫入“0”(停用)或“1”(啟用)來啟用和停用除錯。

如果磁帶似乎掛起,我將非常感興趣地聽到驅動程式在何處等待。使用命令“ps -l”,您可以檢視使用磁帶的程序的狀態。如果狀態為 D,則程序正在等待某些內容。欄位 WCHAN 告訴驅動程式在何處等待。如果您在正確的位置(對於我使用的 procps,在 /boot 中)有當前的 System.map,或者已經更新了 /etc/psdatabase(對於 kmem ps),則 ps 會在 WCHAN 欄位中寫入函式名稱。如果沒有,您必須從 System.map 中查詢該函式。

還要注意,與其他大多數驅動程式相比,超時時間非常長。這意味著 Linux 驅動程式可能顯示為掛起,儘管真正的原因是磁帶韌體已感到困惑。