FreeBSD QandA 1084

FreeBSD QandA

Q. raw デバイスって何ですか?

A. デバイスには「ブロック型デバイス」と「キャラクタ型デバイス」があります
   が、「raw デバイス」とは「キャラクタ型デバイス」のことを指します。

   以下、フロッピーディスク (/dev/fd*) を例にあげて説明します。Unix の慣例
   でデバイス名に「r」を付けたもの、例えば /dev/fd0 なら、/dev/rfd0* が
   raw デバイスであり、/dev/fd0* はブロック型デバイスです。これは ls(1) に
   -l オプションを指定するか、file(1) コマンドなどで確認できます。

     % ls -l /dev/rfd0 /dev/fd0
     brw-r-----  9 root  operator    2,   0 Oct 18  1998 /dev/fd0
     crw-r-----  9 root  operator    9,   0 Jan  9 16:47 /dev/rfd0

     % file /dev/rfd0 /dev/fd0
     /dev/rfd0: character special (9/0)
     /dev/fd0:  block special (2/0)

   raw デバイスに対する入出力 (フロッピーの場合 /dev/rfd*) は、デバイスに
   対して直接行われます。カーネルによるバッファリングは行われません。この
   ため、入出力の際には必ず、デバイスの許容するブロックサイズの倍数単位で
   行う必要があります。(*1)

   また、書き込みのシステムコールが完了した時には、実際にデバイスへの書き
   込みも終了しています。

   一方、ブロック型デバイスに対する入出力 (フロッピーの場合 /dev/fd*) は、
   カーネル中の buffer cache でいったん、バッファリングされます。このため、
   デバイスに許可されたブロックサイズの倍数でなくても入出力できます。
   ただし、buffer cache で書き込みもキャッシュされているので、コマンドが
   終了しても、フロッピーへの書き込みは終了しているとは限りません(というか、
   普通は終了していません)。

   普通は、適切な (=十分大きな) ブロックサイズを指定すれば、raw デバイス
   を使った入出力の方が高速です。この事と、書き込みの完了を保障できる
   ことから、本格的なデータベースでは、raw デバイスを使うのが普通です。(*2)

   まあ、/dev/fd* に書いても、buffer cache が全て書き終わるのを待てば
   (sync コマンドを実行して、フロッピーディスクが動き出し、停止するまで
    待てば) いいかもしれませんが、普通は raw デバイスを使う方が適切ですね。

   とりあえず、ファイルシステムとして使う場合はブロック型デバイスを使い、
   特定のファイル等を意識しない装置そのものとして使う場合はキャラクタ型
   デバイスを使う、という感じで覚えておけばいいでしょう。

   ------
   *1 例えば
        % tar cf /dev/fd0 .  (この使い方はよくない)
        % tar zcf /dev/fd0 . (この使い方はよくない)
        % tar cf /dev/rfd0 . (rawデバイスを使っているので望ましい)
      はできますが、
        % tar zcf /dev/rfd0 .
      はエラーになります。これは
        % tar zcf - . | gzip > /dev/rfd0a
      と等価であるからです。

      tar 自身は書き込む対象が,ファイル/rawデバイス/ブロック型デバイス
      のいずれの場合でもブロックサイズの倍数単位で書き込みするが、gzip は
      そうではない、ということです。
      (この場合は、tar(1) の --block-compress オプションを使えばうまく
      いきます)

   *2 ちなみに Linux には raw デバイスがありません。
      Linux の大きな弱点の一つ。
   ------

間違い・追加情報を見付けた場合は、 修正案の投稿のしかた を読んだ上で、
QandA@jp.FreeBSD.org まで お知らせください。