憶えがき。
参考にしたサイト
SCSTのインストール
http://homepage1.nifty.com/~ayumi/article0001.html
855 cd
856 mkdir work
857 cd work
858 svn co https://scst.svn.sourceforge.net/svnroot/scst
カーネル 2.6.28 のビルド
808 tar xvzf linux-2.6.28.3.tar.gz
814 ln -s linux-2.6.28.3 linux-2.6.28
815 patch -p0 < work/scst/trunk/scst/kernel/scst_exec_req_fifo-2.6.28.patch
816 cd linux-2.6.28/drivers/
819 cd scsi
821 mv qla2xxx/ qla2xxx_orig
822 ln -s ~/work/scst/trunk/qla2x00t/ qla2xxx
823 cd ..
824 cd ..
825 pwd
826 cp /boot/config-2.6.18-274.el5 .config
827 make menuconfig
828 vim .config
カーネルコンフィグレーションオプションの指定
829 vi Makefile
EXTRAVERSIONの変更
830 make -j8 bzImage; make -j8 modules && make -j8 modules_install
831 make install
832 cd /boot
833 ls -l
834 zcat initrd-2.6.18-274.el5.img | cpio -it
835 zcat initrd-2.6.28.3-scst.img | cpio -it
836 vi /boot/grub/menu.lst
自動起動するカーネルの指定
SCST関連のビルド
1. scst
941 cd work/scst/trunk/scst
943 cd src
944 make
945 vim +1654 scst_sysfs.c
バージョン判定でコケているので修正
946 make
947 make all
948 make install
2. qla2x00t
951 cd ..
952 cd qla2x00t/
961 make -C /root/linux-2.6.28/ M=$PWD
962 make -C /root/linux-2.6.28/ M=$PWD modules_install
3. qla2x00-target
963 cd ..
964 cd qla2x00t/qla2x00-target/
967 make
968 make install
4. scstadmin 972 cd scstadmin/
973 make
974 make install
975 cd /lib/modules/2.6.28.3-scst/extra/
976 ls -l
カーネルモジュールのロード
1002 modprobe scst
1007 modprobe qla2x00tgt
1010 modprobe scst_disk
1011 modprobe scst_vdisk
ターゲットの操作
1012 scstadmin
1014 dd if=/dev/zero of=/vdisk1.dsk bs=1024k count=64
1018 scstadmin --help
1019 scstadmin -open_dev vdisk1 -handler vdisk_fileio -attributes filename=/vdisk1.dsk
1021 scstadmin -set_dev_attr vdisk1 -attributes t10_dev_id=0x1234
1022 dmesg
1025 scstadmin -add_group HOST01 -driver qla2x00t -target 21:00:00:e0:8b:82:87:08
1026 scstadmin -add_lun 1 -driver qla2x00t -target 21:00:00:e0:8b:82:87:08 -group HOST01 -device vdisk1
この先は FC ケーブルが必要と思われる。
2012年3月4日日曜日
2012年3月3日土曜日
ML110 G7を買ってみた
ML115 G1 クラスタの処分も視野に入れて NTT-X で特価になってるのを一台ポチってみました。
他の方がレビューされているので基本はそれを見ればいいと思いますがヘタレとして自分が気づいた点のみまとめます。
システムボード仕様は 3xx シリーズ並?
POST画面のほかBIOSコンフィグレーションも 3xx シリーズと同じように見えます。 3xx シリーズをいじりたいけど手が届かない人には入門機としてありじゃないでしょうか。
スクリューレスで快適メンテ
度々構成を変えるような使い方には無手居るケースだと思います。ただ PCIe スロットまわり、とくに一番下のスロットは抜き差し大変かもしれない。
電源は 350W
350W の電源がのっています。あと PCIe 用の 6 ピン電源コネクタはないので SLI とか CorssFire とか想定して買うとちょっとガッカリします。まあそこまでやるなら電源ごと交換するのでしょうが。
PCI スロットなし
新品で数千円レベルで入手できるカードは刺さらないということです。イーサネットは標準で2系統ありますが、スループット度外視でお手軽に追加したいような時には注意。
PCIe バスのレーン数が....
しっかり確認していませんが電気的に PCIe x16, PCIe x8, PCIe x8, PCIe x4 なのですが、もしかするとその上流で帯域が足りないブリッジチップがあるかもしれない感じです。 PCIe x16, PCIe x8, PCIe x4, PCIe x4 ぐらいのつもりで買っていたほうがいいよ。なお、いわずもがな Gen2 ですね。
下の方のスロットほど帯域幅は大きくなっているので、高負荷なデバイスはそちらに優先的に挿しましょう。
まとめ
ほとんど PCIe といえばビデオカードぐらいしか想定していないパーソナルユースで売ってる程度のシステムボードと比べれば、ごついカードを挿しても安定して動きました。ちょっとした検証やオモチャにするには十分なスペックですが、 CPU やメモリや電源を変えても PCIe バス幅だけはどうにもならないので、本気ならサーバ用システムボードもしくは相当品を買いましょう。
補足
製品スペックをよくみたら PCIe のスロットは x16, x4 ,x4, x1 と書いてあった。納得。
他の方がレビューされているので基本はそれを見ればいいと思いますがヘタレとして自分が気づいた点のみまとめます。
システムボード仕様は 3xx シリーズ並?
POST画面のほかBIOSコンフィグレーションも 3xx シリーズと同じように見えます。 3xx シリーズをいじりたいけど手が届かない人には入門機としてありじゃないでしょうか。
スクリューレスで快適メンテ
度々構成を変えるような使い方には無手居るケースだと思います。ただ PCIe スロットまわり、とくに一番下のスロットは抜き差し大変かもしれない。
電源は 350W
350W の電源がのっています。あと PCIe 用の 6 ピン電源コネクタはないので SLI とか CorssFire とか想定して買うとちょっとガッカリします。まあそこまでやるなら電源ごと交換するのでしょうが。
PCI スロットなし
新品で数千円レベルで入手できるカードは刺さらないということです。イーサネットは標準で2系統ありますが、スループット度外視でお手軽に追加したいような時には注意。
PCIe バスのレーン数が....
しっかり確認していませんが電気的に PCIe x16, PCIe x8, PCIe x8, PCIe x4 なのですが、もしかするとその上流で帯域が足りないブリッジチップがあるかもしれない感じです。 PCIe x16, PCIe x8, PCIe x4, PCIe x4 ぐらいのつもりで買っていたほうがいいよ。なお、いわずもがな Gen2 ですね。
下の方のスロットほど帯域幅は大きくなっているので、高負荷なデバイスはそちらに優先的に挿しましょう。
まとめ
ほとんど PCIe といえばビデオカードぐらいしか想定していないパーソナルユースで売ってる程度のシステムボードと比べれば、ごついカードを挿しても安定して動きました。ちょっとした検証やオモチャにするには十分なスペックですが、 CPU やメモリや電源を変えても PCIe バス幅だけはどうにもならないので、本気ならサーバ用システムボードもしくは相当品を買いましょう。
補足
製品スペックをよくみたら PCIe のスロットは x16, x4 ,x4, x1 と書いてあった。納得。
2012年2月20日月曜日
フラッシュメモリのストライピングは善か悪か?
SSDなど、フラッシュメモリを用いたストレージデバイスは非常に高速です。このようなデバイスをストライピングするとさらに上を目指せる、、、ように感じられますが、実はストライピングで常にアプリケーションの性能が上がるわけではありません。
デバイス単体、2台ストライプのレイテンシ特性
以下のグラフは、フラッシュメモリデバイスへのランダム4KB書き込み時のレイテンシ分布(ドライブ単体および2台をストライプ)を示したものです。
グラフ1

左側がいちばんレイテンシが低い状態、右にいけばいくほどレンテンシが増えていった状態を示していおり、線が左に寄っているのは、すなわち高速に応答していることを示しています。
デバイス単体の場合(赤)、レイテンシ分布は非常に高速な状態(1)に偏っており良好な状態です。ストライプした場合(青)、先と比べると(2)の値が高くなっていて、つまりレイテンシが大きくなっていると言うことになります。この状態であれば間違いなく赤、つまりデバイス単体の性能のほうが応答が早いことになります。
この結果ですが、すこし条件を変えて測定してみると —— 以下のようになります。
グラフ2

このグラフでは、ストライプ構成(青)のほうがデバイス単体(赤)よりよいレイテンシ性能を示しています。
条件の違いは?
この先の2つのグラフ、一体何を変えたと思いますか? 答えはI/Oスレッド数です。
グラフ1 …… 1スレッド
グラフ2 …… 64スレッド
つまりグラフ1の場合よりグラフ2の場合のほうが大きなワークロードがかかっています。つまりワークロード次第でレイテンシ分布は変化します。
さて。
デバイス単体で使ったほうがお得でしょうか?
それとも、ストライピングしておいたほうがお得でしょうか?
ヒント
デバイス単体、2台ストライプのレイテンシ特性
以下のグラフは、フラッシュメモリデバイスへのランダム4KB書き込み時のレイテンシ分布(ドライブ単体および2台をストライプ)を示したものです。
グラフ1
左側がいちばんレイテンシが低い状態、右にいけばいくほどレンテンシが増えていった状態を示していおり、線が左に寄っているのは、すなわち高速に応答していることを示しています。
デバイス単体の場合(赤)、レイテンシ分布は非常に高速な状態(1)に偏っており良好な状態です。ストライプした場合(青)、先と比べると(2)の値が高くなっていて、つまりレイテンシが大きくなっていると言うことになります。この状態であれば間違いなく赤、つまりデバイス単体の性能のほうが応答が早いことになります。
この結果ですが、すこし条件を変えて測定してみると —— 以下のようになります。
グラフ2
このグラフでは、ストライプ構成(青)のほうがデバイス単体(赤)よりよいレイテンシ性能を示しています。
条件の違いは?
この先の2つのグラフ、一体何を変えたと思いますか? 答えはI/Oスレッド数です。
グラフ1 …… 1スレッド
グラフ2 …… 64スレッド
つまりグラフ1の場合よりグラフ2の場合のほうが大きなワークロードがかかっています。つまりワークロード次第でレイテンシ分布は変化します。
さて。
デバイス単体で使ったほうがお得でしょうか?
それとも、ストライピングしておいたほうがお得でしょうか?
ヒント
- 複数デバイスにストライプすると、各デバイスからの応答を待ち合わせる必要があるため、レイテンシが幾らか悪化する。
- 転送するデータのサイズに比例して、フラッシュメモリのレイテンシは変化する。
2012年2月19日日曜日
フラッシュメモリデバイスのレイテンシ差がアプリケーションに与える影響
たまにはブログを書こうかと。今日はこのブログではじめてフラッシュメモリの話題を扱うことにしましょう。
個人的に大好きなプレゼンテーションがあります。タイトルは Mythbusting Flash Performance 、元Sun(現Oracle)の Solaris プラットフォーム エンジニアリングのバイスプレジデント Bill Neshim 氏が Flash Memory Summit 2011 のキーノートとして講演した際のスライドのようです。
このプレゼンテーションには衝撃的なグラフが入っていて、これを見たとき衝撃を受けました。それ以来このプレゼンテーションはお気に入りとして常にマシンの中に入っています:)
予期可能なレイテンシ性能のフラッシュメモリデバイス、そうでないフラッシュメモリデバイス
フラッシュメモリデバイスは、使用されているNANDフラッシュメモリのパッケージごとの性能もありますが、それを管理・制御するコントローラにより、最終的なデバイスの仕上がりが大きく変わることが知られています。
フラッシュメモリデバイスの性能は IOPS (単位時間あたりのIO回数)と帯域幅で語られがちですが、さらにレイテンシという軸で探ってみると、デバイスの本当の性能がよく見えてきます。
IOPSの比較
以下は、先のプレゼンテーションからの引用です。具体的なデバイスの機種名は明かされていませんが、2つのフラッシュメモリデバイスのIOPS性能を比較しています。
Device A

Device B

このふたつの違いは明白です。前者は書き込みスレッド数により IOPS 性能が決まってくる、つまり性能が予期できることがわかります。後者は、もちろんスレッド数が少ない方がIOPS数が多いもののおよそランダムな状態です。これが、性能が予期できないフラッシュメモリデバイスの特性です。
レイテンシの比較
続いて、次のスライドは2つのデバイスのレイテンシ性能を比較しています。

縦軸は頻度、横軸はIO時に発生したレイテンシの大きさです。つまりグラフが左側に寄っていればそれだけ応答が速いデバイスである、と見ることができます。
このグラフで登場している2つのデバイスは、実際に Oracle の本番環境で利用されており、非常にレイテンシ特性が似ています。しかし、 OLTP ワークロードをかけた際のグラフを見ると、 Dev1 はレイテンシが大きくなる頻度が Dev2 より大きい —— つまり、実際のアプリケーション負荷をかけるとレイテンシがより悪化するデバイスである、ということです。
これについて Bill 氏は「I/Oのうち最も遅い 1% がデバイスの性能を決める。しかし、多くのデバイスベンダはこの部分の軽く見がちだ」と述べています。
どうして氏が 1% に拘るのか……それは次のスライドに答えがあります。

このスライドは、さきほどの「最も遅い1%」が データベースの OLTP に性能にどのような影響をもたらすかを示しています。縦軸はデバイスのレスポンスタイムタイム、横軸は時間です。このグラフでは、 Dev 2 が非常に安定したレスポンスタイムで応答しているのに対し Dev 1 のレスポンスタイムは明らかにムラがあります。
Dev 2 を使ったデータベースでは一定の間隔で応答してきますが、 Dev 1 は、まるで混雑した道路で渋滞にハマっているかのように動いたり止まったり……を繰り返しているのです。この結果、データベースの実行速度には大きな差が現れるのです。
まとめ
フラッシュメモリデバイスの性能は IOPS (単位時間あたりのIO回数)と帯域幅で語られがちです。しかし、それだけでなく、レイテンシが安定しているか、という観点での評価もとても重要です。それも一定時間の平均値ではなく、レスポンスタイムの分布まで含めてはじめて、アプリケーション性能への影響がわかります。
p.s. @yoshikaw さんにエントリ中のバグをご指摘いただき修正しました。ありがとうございます!
個人的に大好きなプレゼンテーションがあります。タイトルは Mythbusting Flash Performance 、元Sun(現Oracle)の Solaris プラットフォーム エンジニアリングのバイスプレジデント Bill Neshim 氏が Flash Memory Summit 2011 のキーノートとして講演した際のスライドのようです。
このプレゼンテーションには衝撃的なグラフが入っていて、これを見たとき衝撃を受けました。それ以来このプレゼンテーションはお気に入りとして常にマシンの中に入っています:)
予期可能なレイテンシ性能のフラッシュメモリデバイス、そうでないフラッシュメモリデバイス
フラッシュメモリデバイスは、使用されているNANDフラッシュメモリのパッケージごとの性能もありますが、それを管理・制御するコントローラにより、最終的なデバイスの仕上がりが大きく変わることが知られています。
フラッシュメモリデバイスの性能は IOPS (単位時間あたりのIO回数)と帯域幅で語られがちですが、さらにレイテンシという軸で探ってみると、デバイスの本当の性能がよく見えてきます。
IOPSの比較
以下は、先のプレゼンテーションからの引用です。具体的なデバイスの機種名は明かされていませんが、2つのフラッシュメモリデバイスのIOPS性能を比較しています。
Device A
Device B
このふたつの違いは明白です。前者は書き込みスレッド数により IOPS 性能が決まってくる、つまり性能が予期できることがわかります。後者は、もちろんスレッド数が少ない方がIOPS数が多いもののおよそランダムな状態です。これが、性能が予期できないフラッシュメモリデバイスの特性です。
レイテンシの比較
続いて、次のスライドは2つのデバイスのレイテンシ性能を比較しています。
縦軸は頻度、横軸はIO時に発生したレイテンシの大きさです。つまりグラフが左側に寄っていればそれだけ応答が速いデバイスである、と見ることができます。
このグラフで登場している2つのデバイスは、実際に Oracle の本番環境で利用されており、非常にレイテンシ特性が似ています。しかし、 OLTP ワークロードをかけた際のグラフを見ると、 Dev1 はレイテンシが大きくなる頻度が Dev2 より大きい —— つまり、実際のアプリケーション負荷をかけるとレイテンシがより悪化するデバイスである、ということです。
これについて Bill 氏は「I/Oのうち最も遅い 1% がデバイスの性能を決める。しかし、多くのデバイスベンダはこの部分の軽く見がちだ」と述べています。
どうして氏が 1% に拘るのか……それは次のスライドに答えがあります。
このスライドは、さきほどの「最も遅い1%」が データベースの OLTP に性能にどのような影響をもたらすかを示しています。縦軸はデバイスのレスポンスタイムタイム、横軸は時間です。このグラフでは、 Dev 2 が非常に安定したレスポンスタイムで応答しているのに対し Dev 1 のレスポンスタイムは明らかにムラがあります。
Dev 2 を使ったデータベースでは一定の間隔で応答してきますが、 Dev 1 は、まるで混雑した道路で渋滞にハマっているかのように動いたり止まったり……を繰り返しているのです。この結果、データベースの実行速度には大きな差が現れるのです。
まとめ
フラッシュメモリデバイスの性能は IOPS (単位時間あたりのIO回数)と帯域幅で語られがちです。しかし、それだけでなく、レイテンシが安定しているか、という観点での評価もとても重要です。それも一定時間の平均値ではなく、レスポンスタイムの分布まで含めてはじめて、アプリケーション性能への影響がわかります。
p.s. @yoshikaw さんにエントリ中のバグをご指摘いただき修正しました。ありがとうございます!
2012年1月13日金曜日
変なファイル名によるイタズラ
へぇぇぇぇ。
[sandbox@proliant2 work]$ touch -- '-rf' '~'
[sandbox@proliant2 work]$ strace rm *
execve("/bin/rm", ["rm", "-rf", "~"], [/* 23 vars */]) = 0
brk(0) = 0x87c000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f840a966000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=94094, ...}) = 0
mmap(NULL, 94094, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f840a94f000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\357\1n?\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1995840, ...}) = 0
mmap(0x3f6e000000, 3814616, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3f6e000000
mprotect(0x3f6e19a000, 2093056, PROT_NONE) = 0
mmap(0x3f6e399000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x199000) = 0x3f6e399000
mmap(0x3f6e39e000, 21720, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3f6e39e000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f840a94e000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f840a94c000
arch_prctl(ARCH_SET_FS, 0x7f840a94c720) = 0
mprotect(0x3f6e399000, 16384, PROT_READ) = 0
mprotect(0x3f6de20000, 4096, PROT_READ) = 0
munmap(0x7f840a94f000, 94094) = 0
brk(0) = 0x87c000
brk(0x89d000) = 0x89d000
brk(0) = 0x89d000
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=99154656, ...}) = 0
mmap(NULL, 99154656, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8404abc000
close(3) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 opost isig icanon echo ...}) = 0
lstat("/", {st_mode=S_IFDIR|0555, st_size=4096, ...}) = 0
newfstatat(AT_FDCWD, "~", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
unlinkat(AT_FDCWD, "~", 0) = 0
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
[sandbox@proliant2 work]$
シェルによりワイルドカード指定で見つかったファイルの ~ カレントディレクトリパスに置き換えられないため問題ないのね。
しかし意図的にファイルを置いておくことで -i を迂回できるね。怖い……!
※Fedora 14 の環境でためしました。
[sandbox@proliant2 work]$ touch -- '-rf' '~'
[sandbox@proliant2 work]$ strace rm *
execve("/bin/rm", ["rm", "-rf", "~"], [/* 23 vars */]) = 0
brk(0) = 0x87c000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f840a966000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=94094, ...}) = 0
mmap(NULL, 94094, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f840a94f000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\357\1n?\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1995840, ...}) = 0
mmap(0x3f6e000000, 3814616, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3f6e000000
mprotect(0x3f6e19a000, 2093056, PROT_NONE) = 0
mmap(0x3f6e399000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x199000) = 0x3f6e399000
mmap(0x3f6e39e000, 21720, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3f6e39e000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f840a94e000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f840a94c000
arch_prctl(ARCH_SET_FS, 0x7f840a94c720) = 0
mprotect(0x3f6e399000, 16384, PROT_READ) = 0
mprotect(0x3f6de20000, 4096, PROT_READ) = 0
munmap(0x7f840a94f000, 94094) = 0
brk(0) = 0x87c000
brk(0x89d000) = 0x89d000
brk(0) = 0x89d000
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=99154656, ...}) = 0
mmap(NULL, 99154656, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8404abc000
close(3) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 opost isig icanon echo ...}) = 0
lstat("/", {st_mode=S_IFDIR|0555, st_size=4096, ...}) = 0
newfstatat(AT_FDCWD, "~", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
unlinkat(AT_FDCWD, "~", 0) = 0
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
[sandbox@proliant2 work]$
シェルによりワイルドカード指定で見つかったファイルの ~ カレントディレクトリパスに置き換えられないため問題ないのね。
しかし意図的にファイルを置いておくことで -i を迂回できるね。怖い……!
※Fedora 14 の環境でためしました。
2012年1月10日火曜日
Tabキーでウインドウ上のボタンにフォーカスをあてるには
「えっ、いまさら?」と言われそうなネタで自分への備忘録がてら一本。。。。
MacOS XのUIでボタンなどをフォーカスしたいときに Tab キーで反応してくれないのに割と困っていたんですが、設定ひとつで挙動が変えられるんですね。感動しました。。。。
たとえば次のウインドウの場合、このダイアログにはチェックボックスとボタン2つ、合計3つのコントロールがあります。 Windows であれば標準設定でもこの3コントロール間を Tab で行き来できるのですが、 Mac OS X ではデフォルトでは Tab によるコントロール移動が効きません。なおこの画像は実際に Cancel にフォーカスをあてている状態です。

これは、設定>キーボードで変更できます。

教えてくださった @akisutesama さん、ありがとうございます _o_
MacOS XのUIでボタンなどをフォーカスしたいときに Tab キーで反応してくれないのに割と困っていたんですが、設定ひとつで挙動が変えられるんですね。感動しました。。。。
たとえば次のウインドウの場合、このダイアログにはチェックボックスとボタン2つ、合計3つのコントロールがあります。 Windows であれば標準設定でもこの3コントロール間を Tab で行き来できるのですが、 Mac OS X ではデフォルトでは Tab によるコントロール移動が効きません。なおこの画像は実際に Cancel にフォーカスをあてている状態です。
これは、設定>キーボードで変更できます。
教えてくださった @akisutesama さん、ありがとうございます _o_
2012年1月5日木曜日
FreeBSDで使うLinux KVM準仮想化タイマ
こんにちわ。@hasegawです。あけましておめでとうございます。今年もよろしくお願いします!
かなり久々のブログ更新となりますが、本日は カーネル/VM Advent Calendar にてまたまた私の当番!ってことで、今回は FreeBSD 8.1-RELEASE に Linux KVM 用のタイムカウンタを実装してみたというネタでお話しようかと思います。
昨年のネタ: FreeBSD VIMAGEを使ったTCP/IPのルーティング デモンストレーション
■ Linux KVM のタイマ機能
まずバックグラウンドについて説明しておきましょう。 FreeBSD のはじめとする殆どの OS では、以下の計算式でシステム時間(年月日・時分秒)を把握しています。
システム時間 = システム起動時の時間 + システム起動後の経過時間
このうち「システム起動時の時間」はRTC(リアルタイムクロック)の値で初期化し、「システム起動後の経過時間」はOSが定期的にカウンタをインクリメントしています。しかし、仮想化環境ではこの仕組みをそのまま適用すると時刻ズレの原因となりやすいことは、この記事を読むような方であればご存じのことでしょう。
そこで、タイマの仮想化です。 Linux KVM でもタイマの準仮想化機能があります。
KVM PVclock
http://www.linux-kvm.org/page/KVMClock
これは、ゲスト OS が「おいら時間情報がほしいから、メモリのここに定期的に書いておいてちょ」と仮想マシンモニタにお願いすると、適当な間隔で仮想マシンモニタが指定されたメモリ上に時刻情報を書いておいてくれる、という仕組みです。
ただ、 KVM のサイトを見るとこの機能は Linux guests only. と書いてあります。
どうして
Linux でしか使えないの?
それは、ゲスト OS が KVM PV Clock に対応する必要があるからです。
しかし KVM の PV Clock は決して難しいものではありません。もともと Xen にインスパイアされて殆ど同じ汎用的なデータ構造を持っているので、すでに BSDL で Xen 対応のコードがある FreeBSD であれば私のヘナチョコがちょろちょろっとコピペして済むレベルです。対応するかしないかは仮想マシンモニタ開発側&ゲスト OS 開発側のモチベーション次第なだけなのです!よっしゃ、私は最近 FreeBSD 使っていないけど、やってみるかー。
ってことでとりあえず動くモノを作ってみましたとさ。
■ FreeBSD 用 timecounter: kvmclock 失敗編
時は 2011 年 10 月。今回のモノは FreeBSD の timecounter として実装しました。 Linux で言う clocksource ですね。システム起動時には以下のイメージで初期化されます。
Timecounter "kvmclock" frequency 1800000536 Hz quality 900

このタイムカウンタは、 Linux KVM が定期的に TSC のカウンタをメモリに書いてくれるので、それを使って時を刻んでいます。
struct pvclock_vcpu_time_info {
u32 version;
u32 pad0;
u64 tsc_timestamp;
u64 system_time;
u32 tsc_to_system_mul;
s8 tsc_shift;
u8 pad[3];
} __attribute__((__packed__)); /* 32 bytes */
とりあえず動いたのですが、しかし実際には問題が起きて使い物になりませんでした。理由は桁あふれです。1.8GHzでカウントアップされていくタイマだと、あっという間に32ビットのカウンタは一週してゼロに戻ります。この結果、アイドル時間が多いと時計が遅れるという最高にイケていないタイムカウンタになりました。なお while true; do date > /dev/null ; done とかしていると非常に精度が高いカウンタであったことは申し添えておきます!
■ FreeBSD用timecounter: kvmclock その2
時は2011年12月29日。年末年始はスノーボードに行くので今作らなかったら Advent Calendar のネタがありません。ってことで、とりあえずバージョンアップしました。
Timecounter "kvmclock" frequency 1000000 Hz quality 900

このタイマはゲストOSに対して仮想的にマイクロ秒精度のタイマ機能を提供します。
前回は Linux KVM がシャドウしてくれた TSC の値を使って時を刻んでいましたが、今回は Linux KVM がシャドウしてくれたシステム時間をベースに時を刻みます。
struct pvclock_wall_clock {
u32 version;
u32 sec;
u32 nsec;
} __attribute__((__packed__));
このデータ自体はナノ秒オーダーのものですが、 t = sec * 1000 + nsec / 1000 としてマイクロ秒のオーダーに変換し、これの情報を OS 側に食わせます。この形であればカーネルが気づかないうちに桁あふれなんてことがそうそう起きません。
■ 評価
早速作ったタイムカウンタで仮想マシンを動かしてみました。素人ハックの結果としては割と良好かと思います。

これは while true; do date; sleep 1; done の結果をゲスト(上)とホスト(下)で実行しっぱなしにした結果です。
5時8分0秒が飛んでいるので不安定っぽく見えますが、 sleep 1 の待ち時間がフラついているという問題はあるもののホスト OS から 1 秒以上時間がずれることは無くなりました。 sleep の精度が低い問題はありつつも gettimeofday は安定しているようです。
また、vCPUがアイドルの場合も、負荷をかけた場合でも、システムの時刻がホストとゲストの間で大きくズレることはないようです。
12 月 29 日から 1 月 4 日までの 5 日間放置しても、システム時間のずれは生じなかった

■ もっと頑張らないといけないこと
とりあえず自覚している課題は以下の部分です。
現時点のやるきのないコードの一部(試行錯誤の跡付き)

■ おわりに
というわけで、「タイマ作りました、動いてます」というとっても退屈な記事ですが、、こんな事してみましたよ、ってことで。私のようなヘボでもいじくれる所があるというのは有り難いものです。
Advent Calendar 参加者の皆さんの記事、楽しく読ませていただきました。今後ともよろしくお願いします。
かなり久々のブログ更新となりますが、本日は カーネル/VM Advent Calendar にてまたまた私の当番!ってことで、今回は FreeBSD 8.1-RELEASE に Linux KVM 用のタイムカウンタを実装してみたというネタでお話しようかと思います。
昨年のネタ: FreeBSD VIMAGEを使ったTCP/IPのルーティング デモンストレーション
■ Linux KVM のタイマ機能
まずバックグラウンドについて説明しておきましょう。 FreeBSD のはじめとする殆どの OS では、以下の計算式でシステム時間(年月日・時分秒)を把握しています。
システム時間 = システム起動時の時間 + システム起動後の経過時間
このうち「システム起動時の時間」はRTC(リアルタイムクロック)の値で初期化し、「システム起動後の経過時間」はOSが定期的にカウンタをインクリメントしています。しかし、仮想化環境ではこの仕組みをそのまま適用すると時刻ズレの原因となりやすいことは、この記事を読むような方であればご存じのことでしょう。
そこで、タイマの仮想化です。 Linux KVM でもタイマの準仮想化機能があります。
KVM PVclock
http://www.linux-kvm.org/page/KVMClock
これは、ゲスト OS が「おいら時間情報がほしいから、メモリのここに定期的に書いておいてちょ」と仮想マシンモニタにお願いすると、適当な間隔で仮想マシンモニタが指定されたメモリ上に時刻情報を書いておいてくれる、という仕組みです。
ただ、 KVM のサイトを見るとこの機能は Linux guests only. と書いてあります。
どうして
Linux でしか使えないの?
それは、ゲスト OS が KVM PV Clock に対応する必要があるからです。
しかし KVM の PV Clock は決して難しいものではありません。もともと Xen にインスパイアされて殆ど同じ汎用的なデータ構造を持っているので、すでに BSDL で Xen 対応のコードがある FreeBSD であれば私のヘナチョコがちょろちょろっとコピペして済むレベルです。対応するかしないかは仮想マシンモニタ開発側&ゲスト OS 開発側のモチベーション次第なだけなのです!よっしゃ、私は最近 FreeBSD 使っていないけど、やってみるかー。
ってことでとりあえず動くモノを作ってみましたとさ。
■ FreeBSD 用 timecounter: kvmclock 失敗編
時は 2011 年 10 月。今回のモノは FreeBSD の timecounter として実装しました。 Linux で言う clocksource ですね。システム起動時には以下のイメージで初期化されます。
Timecounter "kvmclock" frequency 1800000536 Hz quality 900
このタイムカウンタは、 Linux KVM が定期的に TSC のカウンタをメモリに書いてくれるので、それを使って時を刻んでいます。
struct pvclock_vcpu_time_info {
u32 version;
u32 pad0;
u64 tsc_timestamp;
u64 system_time;
u32 tsc_to_system_mul;
s8 tsc_shift;
u8 pad[3];
} __attribute__((__packed__)); /* 32 bytes */
とりあえず動いたのですが、しかし実際には問題が起きて使い物になりませんでした。理由は桁あふれです。1.8GHzでカウントアップされていくタイマだと、あっという間に32ビットのカウンタは一週してゼロに戻ります。この結果、アイドル時間が多いと時計が遅れるという最高にイケていないタイムカウンタになりました。なお while true; do date > /dev/null ; done とかしていると非常に精度が高いカウンタであったことは申し添えておきます!
■ FreeBSD用timecounter: kvmclock その2
時は2011年12月29日。年末年始はスノーボードに行くので今作らなかったら Advent Calendar のネタがありません。ってことで、とりあえずバージョンアップしました。
Timecounter "kvmclock" frequency 1000000 Hz quality 900
このタイマはゲストOSに対して仮想的にマイクロ秒精度のタイマ機能を提供します。
前回は Linux KVM がシャドウしてくれた TSC の値を使って時を刻んでいましたが、今回は Linux KVM がシャドウしてくれたシステム時間をベースに時を刻みます。
struct pvclock_wall_clock {
u32 version;
u32 sec;
u32 nsec;
} __attribute__((__packed__));

このデータ自体はナノ秒オーダーのものですが、 t = sec * 1000 + nsec / 1000 としてマイクロ秒のオーダーに変換し、これの情報を OS 側に食わせます。この形であればカーネルが気づかないうちに桁あふれなんてことがそうそう起きません。
■ 評価
早速作ったタイムカウンタで仮想マシンを動かしてみました。素人ハックの結果としては割と良好かと思います。
これは while true; do date; sleep 1; done の結果をゲスト(上)とホスト(下)で実行しっぱなしにした結果です。
5時8分0秒が飛んでいるので不安定っぽく見えますが、 sleep 1 の待ち時間がフラついているという問題はあるもののホスト OS から 1 秒以上時間がずれることは無くなりました。 sleep の精度が低い問題はありつつも gettimeofday は安定しているようです。
また、vCPUがアイドルの場合も、負荷をかけた場合でも、システムの時刻がホストとゲストの間で大きくズレることはないようです。
12 月 29 日から 1 月 4 日までの 5 日間放置しても、システム時間のずれは生じなかった
■ もっと頑張らないといけないこと
とりあえず自覚している課題は以下の部分です。
- 実はまだ KVM のプローブをしていない。 MSR を一発たたけばいいので、いつでもできます。
- vCPU != 1 の場合を想定していないし、評価していない。vCPU ごとにカウンタを進める必要がありますので、今のコードのままではまずい。このままでも動くかもしれないけど。
- sleep 1 が不安定 ゚+.(・ω・)゚+.゚ ヘボグラマなので細かい修正はエキスパートにお願いすればいいかなっと。
現時点のやるきのないコードの一部(試行錯誤の跡付き)
■ おわりに
というわけで、「タイマ作りました、動いてます」というとっても退屈な記事ですが、、こんな事してみましたよ、ってことで。私のようなヘボでもいじくれる所があるというのは有り難いものです。
Advent Calendar 参加者の皆さんの記事、楽しく読ませていただきました。今後ともよろしくお願いします。
登録:
投稿 (Atom)