テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

dm-lcの紹介 (9) sysfs

目次

dm-lcは, カーネル空間の挙動をsysfsから制御します. マイグレーションの自動制御も, Pythonで実装されたデーモンがこのインターフェイスを操作することによって実現しています. この記事では, sysfsの詳細について説明します.

階層

sysfsの階層は以下のようになっています. dm-lcは, /sys/module/dm_lc以下にsysfsを構築します. devices, cachesともに, その下に, 番号を持っています. これは, 仮想デバイス, キャッシュ作成時に外から割り与える一意なIDです*1.

/sys/module/dm_lc/devices/
└── 1
    ├── cache_id
    ├── dev
    ├── device -> ../../../../devices/virtual/block/dm-0
    ├── migrate_threshold
    ├── nr_dirty_caches
    └── readonly
/sys/module/dm_lc/caches/
└── 1
    ├── allow_migrate
    ├── barrier_deadline_ms
    ├── commit_super_block
    ├── commit_super_block_interval
    ├── device -> ../../../../devices/virtual/block/dm-1
    ├── flush_current_buffer
    ├── flush_current_buffer_interval
    ├── force_migrate
    ├── last_flushed_segment_id
    ├── last_migrated_segment_id
    └── update_interval

devices(仮想デバイス)

名前 役割
cache_id この仮想デバイスが使っているキャッシュのID. キャッシュを使ってない場合は0です. この情報を利用することで, 仮想デバイスとキャッシュの接続状態を取得することが出来ます.
dev 仮想デバイスの番号(major:minor). 例 253:5
device backing storeの/sys/devicesへのシンボリックリンクです(#1).
migrate_threshold このデバイスについてmigrateを行うしきい値(整数%).
nr_dirty_caches この仮想デバイスが持っているダーティなキャッシュの数です. 0にならないと, 仮想デバイスを消去出来ないなどの制御に使っています.
readonly 1/0. もし1ならば, この仮想デバイスは書き込みを拒絶します. ふつうはfilesystemのレイヤで調整するものだと思うので要らないかも, 消すかも. シンプルかつ正しい実装が難しい.

(#1)について, これは, みなさんおなじみ/sys/blockへのシンボリックとも言えます. 実際問題として, /sys/block/dm-0は, /sys/devices/virtual/block/dm-0へのシンボリックリンクなのです.

akira@Paptimus:~$ ls /sys/block/ -l
total 0
lrwxrwxrwx 1 root root 0 Jun  2 00:24 dm-0 -> ../devices/virtual/block/dm-0
lrwxrwxrwx 1 root root 0 Jun  2 00:24 dm-1 -> ../devices/virtual/block/dm-1
lrwxrwxrwx 1 root root 0 Jun  2 00:24 dm-2 -> ../devices/virtual/block/dm-2
lrwxrwxrwx 1 root root 0 Jun  2 00:24 dm-3 -> ../devices/virtual/block/dm-3

caches(キャッシュデバイス)

名前 役割
allow_migrate 1/0. もし0ならば, 非常時以外はmigrateしません. ふつうは, 自動制御スクリプトによって1/0を制御されるため自動で設定する必要はありません.
barrier_deadline_ms ms. ライトバリアI/Oが来た場合, 遅延処理しますが, 最悪ケースでもこのdeadlineでは処理されます.
commit_super_block 強制的に, super blockをcommitします.
commit_super_block_interval sec. この時間間隔ごとにsuper blockをcommitするようになります. super blockには, どのセグメントまでmigrateしたかが書かれているため, クラッシュ時のリカバリが高速になるかも知れません. リカバリ時の線引き(どこどこより前は無視してよい)が出来るからです.
device このキャッシュが利用しているデバイスの/sys/devicesへのリンクです. 仮想デバイスのものと同様.
force_migrate 1/0. 1にすると, 自動制御を無視して常にmigrateします.
flush_current_buffer 強制的に, 現在のバッファをフラッシュします.
flush_current_buffer_interval sec. この間隔で, flush_current_bufferを叩き続けます.
update_interval sec. 自動制御に使う情報(backing storeの負荷など)を更新する頻度を調整します.

まとめ

以上です. ユーザランドとカーネルの界面を決定するのは簡単ではありません. カーネルは非常に繊細なソフトウェアであり, 界面の決定によっては, その界面を維持するためにカーネル実装が難しくなり*2, 結果としてカーネルが不安定になります. dm-lcでは, 界面をsysfsとdevice-mapperのmessage機構で実現しています. シンプルに実装出来たと私は思います.

*1:ID=0は特別な場合に使うので禁止です

*2:というバランス感覚を持った開発者は多くありません. 結果として, 界面に関する一貫性のなさ, どうしてこんなところに実装された感で満たされたソフトウェアが出来上がります. ソフトウェアのすべてを横断的に思考出来る開発者が必要なのです. 適切な設計が出来れば, ソフトウェアというのはとても美しいものだと思っています.