ablog

不器用で落着きのない技術者のメモ

キャラクタデバイスだとブロックバッファをバッファページにキャッシュしない

タイトルが変ですがあまり気にしないでくださいw
キャラクタデバイスはブロックデバイスじゃないんだからブロックバッファなんかなくて当たり前ですよね。
そんなことを現在勉強中です><

準備

oel11gr2 root% ls -l /dev/sdb
brw-r----- 1 root disk 8, 16 Nov 13 00:16 /dev/sdb
oel11gr2 root% fdisk /dev/sdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): p

Disk /dev/sdb: 1073 MB, 1073741824 bytes
255 heads, 63 sectors/track, 130 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-130, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-130, default 130):
Using default value 130

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
oel11gr2 root% vi /etc/udev/rules.d/60-raw.rules
ACTION=="add",KERNEL=="sdb1",RUN+="/bin/raw /dev/raw/raw1 %N"
ACTION=="add",KERNEL=="raw1",OWNER="root",GROUP="root",MODE="0640"
oel11gr2 root% start_udev
Starting udev:                                             [  OK  ]
oel11gr2 root% raw -qa
/dev/raw/raw1:  bound to major 8, minor 17
oel11gr2 root% ls -l /dev/raw
total 0
crw-r----- 1 root root 162, 1 Nov 13 00:34 raw1
  • raw デバイスをフォーマットする。
oel11gr2 root% dd if=/dev/zero of=/dev/raw/raw1 bs=1024k count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 2.09604 seconds, 50.0 MB/s

検証

  • キャッシュを解放する。
oel11gr2 root% echo 3 > /proc/sys/vm/drop_caches
  • free コマンドで、buffers と cached の値を確認する。
oel11gr2 root% free
             total       used       free     shared    buffers     cached
Mem:       1035064      59028     976036          0        240      11604
-/+ buffers/cache:      47184     987880
Swap:      2096472          0    2096472
  • dd コマンドで raw デバイスを読み込む。
oel11gr2 root% dd if=/dev/raw/raw1 of=/dev/null count=100 bs=1M
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 2.01251 seconds, 52.1 MB/s
  • free コマンドで、buffers と cached の値を確認する。ほとんど変化なし。
oel11gr2 root% free
             total       used       free     shared    buffers     cached
Mem:       1035064      59436     975628          0        364      12544
-/+ buffers/cache:      46528     988536
Swap:      2096472          0    2096472
  • あれ、dd コマンドで /dev/sdb1 を読み込んでもバッファページが増えていない!?
oel11gr2 root% dd if=/dev/sdb1 of=/dev/null count=100 bs=1M
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 2.29402 seconds, 45.7 MB/s
oel11gr2 root% free
             total       used       free     shared    buffers     cached
Mem:       1035064      60268     974796          0        796      13192
-/+ buffers/cache:      46280     988784
Swap:      2096472          0    2096472
  • dd で /dev/sda1 を読み込むとバッファページにキャッシュされてる!?
oel11gr2 root% dd if=/dev/sda1 of=/dev/null count=100 bs=1M
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 2.25518 seconds, 46.5 MB/s
oel11gr2 root% free
             total       used       free     shared    buffers     cached
Mem:       1035064     163776     871288          0     102976      13200
-/+ buffers/cache:      47600     987464
Swap:      2096472          0    2096472
oel11gr2 root% strace -e open dd if=/dev/raw/raw1 of=/dev/null count=100 bs=1M
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/librt.so.1", O_RDONLY)       = 3
open("/lib/libc.so.6", O_RDONLY)        = 3
open("/lib/libpthread.so.0", O_RDONLY)  = 3
open("/dev/raw/raw1", O_RDONLY|O_LARGEFILE) = 0
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 1
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 2.10091 seconds, 49.9 MB/s
oel11gr2 root% strace -e open dd if=/dev/sdb1 of=/dev/null count=100 bs=1M
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/librt.so.1", O_RDONLY)       = 3
open("/lib/libc.so.6", O_RDONLY)        = 3
open("/lib/libpthread.so.0", O_RDONLY)  = 3
open("/dev/sdb1", O_RDONLY|O_LARGEFILE) = 0
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 1
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 7.1724 seconds, 14.6 MB/s

まとめ

  • キャラクタデバイス(/dev/raw/raw1など)を読み込んでもページキャッシュやバッファページにキャッシュされない。
  • キャラクタデバイスに使われているデバイスファイル(/dev/sdb1など)を読み込んでもページキャッシュやバッファページにキャッシュされない。
  • バイスファイルに対して読み書きする場合、そのデバイスファイルがファイルシステムとして使われているか、キャラクタデバイスとして使われているかなどの違いにより挙動(ページキャッシュやバッファページにキャッシュされるか否かなど)が変わる。