「tar でテープにバックアップ・リストアしてみる」という記事で、FreeBSD の mt と Linux の mt に違いがある、と書きました。
FreeBSD 使いとして FreeBSD で動作している様子を解説することにしたのですが、FreeBSD で mt を操作する解説はあまり見つかりませんでした。Linux の mt を使っている解説と、FreeBSD と Linux の man ページを見ながらテープの操作を理解していったつもりですが、その際「mt status の表示の違い」と「man ページの説明の違い」が気になったので、この違いを整理するためにこの記事を書きました。
mt の実装の種類
まず、Web 検索して出てくる Linux の man mt の内容が、ウェブサイトによって違うことに気づきました。そこで、OS に含まれている mt の実装の種類について調べました。
OS | mt の実装 | この記事で使用 |
---|---|---|
FreeBSD1 | BSD 4.4 Lite 由来2 | FreeBSD 12.1 の userland の mt |
CentOS, Debian3 | mt-st4 | CentOS 8.2 に含まれる mt-st 1.1 の mt |
Ubuntu5 | GNU cpio の mt6 | Utuntu 20.04 に含まれる cpio 2.13 の mt |
Linux のディストリビューションによって、違う mt の実装が採用されていました。どうりで man ページの内容が違っているわけです。
mt status の表示の違い
次に、テープの状態を表示する mt status コマンドの表示の違いを比較してみます。
FreeBSD
# mt -f /dev/nsa0 status
Drive: sa0: <QUANTUM ULTRIUM 3 1960> Serial Number: JN0750AME50062
---------------------------------
Mode Density Blocksize bpi Compression
Current: 0x44:LTO-3 variable 244805 enabled (0x1)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition: 0 Calc File Number: 0 Calc Record Number: 0
Residual: 0 Reported File Number: 0 Reported Record Number: 0
Flags: BOP
# mt -f /dev/nsa0 fsf
# mt -f /dev/nsa0 status
Drive: sa0: <QUANTUM ULTRIUM 3 1960> Serial Number: JN0750AME50062
---------------------------------
Mode Density Blocksize bpi Compression
Current: 0x44:LTO-3 variable 244805 enabled (0x1)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition: 0 Calc File Number: 1 Calc Record Number: 0
Residual: 0 Reported File Number: 1 Reported Record Number: 20501
Flags: None
テープヘッドがテープの先頭にあると、BOT ではなく BOP
というフラグが表示されます。
テープヘッドが EOF にあっても、そのことはフラグに表示されません。
Reported Record Number
は BOP からのレコード番号を表し、Calculated Record Number
は EOF からのレコード番号を表します。
mt-st
# mt -f /dev/nst0 status
SCSI 2 tape drive:
File number=0, block number=0, partition=0.
Tape block size 512 bytes. Density code 0x44 (LTO-3).
Soft error count since last status=0
General status bits on (41010000):
BOT ONLINE IM_REP_EN
# mt -f /dev/nst0 fsf
# mt -f /dev/nst0 status
SCSI 2 tape drive:
File number=1, block number=0, partition=0.
Tape block size 512 bytes. Density code 0x44 (LTO-3).
Soft error count since last status=0
General status bits on (81010000):
EOF ONLINE IM_REP_EN
テープヘッドがテープの先頭にあると、BOT
フラグが表示されます。
テープヘッドが EOF にあると EOF
フラグが表示されます。
block number
は file 内のブロック番号を表します。テープ先頭からのブロック番号は表示されません。
GNU cpio
# mt -f /dev/nst0 status
drive type = 114
drive status = 1140851200
sense key error = 0
residue count = 0
file number = 0
block number = 0
# mt -f /dev/nst0 fsf
# mt -f /dev/nst0 status
drive type = 114
drive status = 1140851200
sense key error = 0
residue count = 0
file number = 1
block number = 0
テープヘッドがテープの先頭にあっても、そのことはフラグに表示されません。
テープヘッドが EOF にあっても、そのことはフラグに表示されません。
block number
は file 内のブロック番号を表します。テープ先頭からのブロック番号は表示されません。
man ページの巻き戻し系サブコマンドの説明の違い
各実装の man ページの説明を比較すると、同じサブコマンドが違う動きをするように読める部分がありました。
man ページはどのように説明しているのか、また各実装の動作が同じなのかを確かめます。
FreeBSD
bsf
man mt より引用
fsf Forward space count files.
bsf Backward space count files.
戻ると説明していますが、ヘッドの位置については記述されていません。
# mt -f /dev/nsa0 rewind
# mt -f /dev/nsa0 fsf 3
# mt -f /dev/nsa0 bsf
# mt -f /dev/nsa0 status
Drive: sa0: <QUANTUM ULTRIUM 3 1960> Serial Number: JN0750AME50062
---------------------------------
Mode Density Blocksize bpi Compression
Current: 0x44:LTO-3 variable 244805 enabled (0x1)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition: 0 Calc File Number: 2 Calc Record Number: 0
Residual: 0 Reported File Number: 2 Reported Record Number: 61502
Flags: None
%<--file 0-->|<--file 1-->|<--file 2-->|
^
mt bsf
%<--file 0-->|<--file 1-->|<--file 2-->|
^
ヘッドは前のファイルの末尾に移動しています。
bsfm
FreeBSD の mt には bsfm コマンドは存在しません。
mt-st(CentOS, Debian)
bsf
man mt より引用
fsf Forward space count files. The tape is positioned on the
first block of the next file.
bsf Backward space count files. The tape is positioned on the
last block of the previous file.
previous file
の last block
に来ると説明しています。
# mt -f /dev/nst0 rewind
# mt -f /dev/nst0 fsf 3
# mt -f /dev/nst0 bsf
# mt -f /dev/nst0 status
SCSI 2 tape drive:
File number=2, block number=-1, partition=0.
Tape block size 512 bytes. Density code 0x44 (LTO-3).
Soft error count since last status=0
General status bits on (1010000):
ONLINE IM_REP_EN
%<--file 0-->|<--file 1-->|<--file 2-->|
^
mt bsf
%<--file 0-->|<--file 1-->|<--file 2-->|
^
この説明は、動作と一致しています。
block number=-1 は「不明」という意味で、man st には「MTBSF などの後にこの値になる」と書かれています。巻き戻しているので、ファイルの先頭からのブロック番号は分からないということでしょう。
bsfm
man mt より引用
fsfm Forward space count files, then backward space one record.
This leaves the tape positioned at the last block of the file
that is count - 1 files past the current file.
bsfm Backward space past count file marks, then forward space one
file record. This leaves the tape positioned on the first
block of the file that is count-1 files before the current
file.
bsmf
は count 回 mark (EOF) を戻ってから 1 つ進み first block
に来ると説明しています。
# mt -f /dev/nst0 rewind
# mt -f /dev/nst0 fsf 3
# mt -f /dev/nst0 bsfm 2
# mt -f /dev/nst0 status
SCSI 2 tape drive:
File number=2, block number=0, partition=0.
Tape block size 512 bytes. Density code 0x44 (LTO-3).
Soft error count since last status=0
General status bits on (81010000):
EOF ONLINE IM_REP_EN
%<--file 0-->|<--file 1-->|<--file 2-->|
^
mt bsfm 2
%<--file 0-->|<--file 1-->|<--file 2-->|
^
この説明も、動作と一致しています。
GNU cpio
bsf
man mt より引用
fsf Forward space count files. The tape is positioned on the first
block of the next file.
bsf Backward space count files. The tape is positioned on the first
block of the next file.
bsf
は next file
の first block
に来ると説明しています。
# mt -f /dev/nst0 rewind
# mt -f /dev/nst0 fsf 3
# mt -f /dev/nst0 bsf
# mt -f /dev/nst0 status
drive type = 114
drive status = 1140851200
sense key error = 0
residue count = 0
file number = 2
block number = -1
%<--file 0-->|<--file 1-->|<--file 2-->|
^
mt bsf
%<--file 0-->|<--file 1-->|<--file 2-->|
^
mt status で確認すると、前のファイルの末尾に移動しています。これは mt-st の動作と同様です。
mt-st の動作 == mt-st の説明 == GNU cpio の動作 != GNU cpio の説明
というふうに見えます。この説明は、以下のように解釈すると整合性が保てるものと思われますが、前後を取り違えているように感じられます。
- bsf は巻き戻し操作なので、
next file
というのは後ろから前に見て次のファイル
、つまりテープの先頭から見たら前のファイルのことである -
first block
というのも後ろから前に見て最初のブロック
、つまりファイルの先頭から見たら最後のブロックのことである
bsfm
man mt より引用
fsfm Forward space count file marks. The tape is positioned on the
beginning-of-the-tape side of the file mark.
bsfm Backward space count file marks. The tape is positioned on the
beginning-of-the-tape side of the file mark.
man mt(日本語)より引用
fsfm count で指定された数のファイルマーク分だけ進める。 テープの位置は
ファイルマークのテープ先頭側になる。
bsfm count で指定された数のファイルマーク分だけ戻す。 テープの位置は
ファイルマークのテープ先頭側になる。
bsfm
は count 回 mark(EOF) を戻ってから、mark(EOF) のテープ先頭側に来ると説明しています。
# mt -f /dev/nst0 rewind
# mt -f /dev/nst0 fsf 3
# mt -f /dev/nst0 bsfm 2
# mt -f /dev/nst0 status
drive type = 114
drive status = 1140851200
sense key error = 0
residue count = 0
file number = 2
block number = 0
%<--file 0-->|<--file 1-->|<--file 2-->|
^
mt bsfm 2
%<--file 0-->|<--file 1-->|<--file 2-->|
^
実際に動かして mt status で確認すると file 2 の block 0 に移動しています。これも mt-st の bsfm と同じ動作です7。
bsfm についても、mt-st の動作 == mt-st の説明 == GNU cpio の動作 != GNU cpio の説明
というふうに見えます。テープヘッドは mark のテープ終端側に停止しているので、man の説明の the beginning-of-the-tape side of the file mark
は前後を取り違えているように感じられます。
AIX
突然 AIX が出てきてましたが、"beginning-of-the-tape side of the file mark" とはいったいどこなのか調べるために Web を検索していたら、AIX の tctl コマンドの説明もヒットしました。
tctl の説明より引用
fsf Moves the tape forward the number of file marks specified
by the Count parameter and positions it on the end-of-tape
(EOT) side of the file mark.
bsf Moves the tape backward the number of file marks specified
by the Count parameter and positions it on the beginning-of-tape
(BOT) side of the file mark.
この説明にも end-of-tape (EOT) side of the file mark
, beginning-of-tape (BOT) side of the file mark
という、GNU cpio と同様の表現が出てきます。
AIX での動作を検証することはできませんでしたが、fsf, bsf の動作は FreeBSD や Linux (mt-st, GNU cpio) と同じだと思われます。bsfm の停止位置は mark のテープ終端側で fsf と同じですので、GNU cpio の man の bsfm の説明は正しくないように思えます。
Solaris
Solaris も突然の登場ですが、Web 検索で Solaris の mt の man もヒットしました。
man mt より引用
fsf Forward spaces over count EOF marks. The tape is
positioned on the first block of the file.
bsf Back spaces over count EOF marks. The tape is
positioned on the beginning-of-tape side of the
EOF mark.
この man にも beginning-of-tape side of the EOF mark
という表現が出てきます。fsf では first block
に、bsf では beginning-of-tape side of the EOF mark
に来ると説明しています。
Solaris の動作も検証できていませんが、fsf, bsf の動作は FreeBSD や Linux (mt-st, GNU cpio) と同じだと思われます。bsfm の停止位置は mark のテープ終端側で fsf と同じですので、やはり GNU cpio の man の bsfm の説明は正しくないように思えます。
まとめ
テープの構造とテープヘッドの停止位置
細かく書くとこのようになっているものと思われます。
___ position A:
/ the beginning-of-tape side of mark.
/ stop position by bsf (BSD style),
/ and called `last block' of file 1
/
/ __ position B:
/ / the end-of-tape side of mark.
/ / stop position by fsf,
/ / and called `first block' (block 0) of file 2,
/ / and EOF flag is displayed by `mt status' of mt-st
/ /
~--+-----+-----+-----+-----+-----+-----+-----+-~
file 1 data blocks | EOF | file 2 data blocks
~--+-----+-----+-----+-----+-----+-----+-----+-~
file 1 | file 2 file number of mt status
~--+-----+-----+-----+-----+-----+-----+-----+-~
- ファイルはテープ上に 1 個以上のブロックとして保存されます。
- ファイルとファイルを区切るために EOF というブロックが記録されます。EOF ブロックを超えるとファイル番号がインクリメントされます。
- テープヘッドはブロックとブロックの間に停止します。
- mt status が block 0 を示しているとき、テープヘッドは block 0 の中ではなく block 0 の直前に停止しています。
- mt-st の mt status で EOF フラグが表示されているとき、テープヘッドは EOF ブロックの直後(テープ終端側)に停止しています。EOF ブロックの直前(テープ先頭側)ではなく、EOF ブロックの中でもありません。
- ブロックとしての EOF と、mt-st で EOF フラグが表示される位置に違いがあることに注意してください。
- 位置としての
last block
は「ファイルの最後のブロックの前」ではなく「ファイルの最後のブロックと EOF ブロックの間(EOF のテープ先頭側)」を差しています。 - ドキュメント(実装)によって呼び方が違う EOF mark と file mark は同じものを差しています。
- ドキュメント(実装)によって呼び方が違う block と record は同じものを差しています。
今まで簡易的に書いてきた図は、こう書いた方がもっと正確かもしれません。
%<--file 0-->|M|<--file 1-->|M|<--file 2-->|
^ position A
^ position B
各実装の man ページの説明
mt | fsf | bsf | fsfm | bsfm |
---|---|---|---|---|
FreeBSD | Forward space count files. | Backward space count files. | - | - |
mt-st | the first block of the next file. | the last block of the previous file. | the last block of the file that is ... | the first block of the file that is ... |
GNU cpio | the first block of the next file. | the first block of the next file. | the beginning-of-the-tape side of the file mark. | the beginning-of-the-tape side of the file mark. |
AIX tctl | the end-of-tape (EOT) side of the file mark. | the beginning-of-tape (BOT) side of the file mark. | - | - |
Solaris | the first block of the file. | the beginning-of-tape side of the EOF mark. | - | - |
- FreeBSD の説明はヘッドの停止位置について述べていません。
- mt-st の説明は一貫して "block" を用いています。
- GNU cpio の説明が最も複雑に思えます。
- AIX の説明は一貫して "file mark" を用いています。
- Solaris の説明には "block" と "EOF mark" が混在しています。
おわりに
mt status コマンドによるステータスの表示のフォーマットは実装によって違いますが、慣れればテープヘッダがどこにあるのか読み取れるようになります。
実装によって使用できるサブコマンドの違いはあるものの、(確認できた範囲では)同じサブコマンドで違う動作をすることはありません。しかし、同じ動作を別の用語で説明していたり、説明が誤っているように思えるため、理解するのが難しく感じました。
自分がなにか説明の文章を書くとき、正しい説明であると同時に、別の意味に取られかねない表現になっていないか、これからも気をつけようと思いました。
-
https://svnweb.freebsd.org/base/head/usr.bin/mt/mt.c?view=log#rev1590 ↩
-
http://manpages.ubuntu.com/manpages/focal/en/man1/mt.1.html ↩
-
同じ mtio.h を参照しているので、同じ結果になるのは当たり前と言えるかもしれません。 ↩