ELRepoのspecを参考にkmod対応ドライバをビルドした話
Intelのigbドライバなんかは、tarballにspecが含まれていて
rpmbuild -ta ./SOURCES/igb-3.4.7.tar.gz
こんな感じですぐビルドできるステキな感じになっています。
が、これをやるとビルド時のkernelに依存するドライバができてしまうため、
エラッタでカーネルのアップデートが入った場合に既定のドライバに戻ってしまいます。
Redhat/CentOSには、KMP (Kernel Module Package)、kmodというカーネルに追従するための仕組みがあるので、これをやってみました。
KMP/kmodの仕組み自体はこちらのページがよくまとめていただいています。
http://d.hatena.ne.jp/dayflower/20090728/1248754899
KMP対応のモジュールをビルドするための手引きがCentOSの公式Wikiにあります。*1
http://wiki.centos.org/HowTos/BuildingKernelModules#head-b86b6eec08d5719cf1838929f26a64af88e2b7f0
で、手引きをもとに対応のためのいろいろな手順をやってみていたのですが、けっこう難しく苦戦していたところ以下のようなものがありました。
ELRepo
http://elrepo.org/
名前だけは知っていたのですがハードウェアに関するパッケージを提供するプロジェクトとのことで、上記のCentOSのWikiページを記述された方*2がfounderの一人になっていらっしゃるみたい。
ここにkmod対応版のigbやe1000eなど、各種のパッケージがあります。そのまま使えそうですが、勉強になるのでSRPMから再パッケージしてみました。
SRPMをインストールすると、こんな感じのファイルが展開されます。igbの場合、
SPECS/igb-kmod.spec SOURCES/igb-X.X.X.tar.gz SOURCES/kmodtool-igb-el6.sh
kmodtool-igb-el6.shがkmodのためのヘルパースクリプト。
詳細は割愛しますが、kmodtoolスクリプト中でProvidesなどの指定も行われています。私は以下の変更だけ入れてみました。
Provides: ${kmod_name}-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
Provides: ${kmod_name}-kmod = %{?epoch:%{epoch}:}%{version}-%{release} Obsoletes: ${kmod_name}
上記のSRPMをそのままビルドするとkmod-igbというパッケージですが、この変更で既存のigbもkmod対応にyumが入れ替えてくれるようになりました。
めでたしめでたし。
ちなみにRHEL/CentOSのデフォルトのドライバは当然ながらkmodが使われています。igb-3.0.6_k-2.el6_1.src.rpmとかそのあたり。今回は見てないですが、そちらをベースに使ってもよさそう。
次はリビルドじゃなくて一からやってみたいなー。
PXE/kickstartによるネットワークインストール時にドライバを追加する
CentOS6.2の場合。オプションはほぼ5.x系でも同じ。
boot: linux ks=hd:partition:/path/ks.cfg dd
この場合、ネットワーク上の場所は指定できないっぽい。
driverdisk (オプション) driverdisk <partition> --source=<url> --biospart=<biospart> [--type=<fstype>] 別の方法として、ネットワークの場所をドライバーディスク用に指定できます。 driverdisk --source=http://path/to/dd.img
■おまけ
追加したドライバやユーティリティがRHEL用とかでWARNINGが出る場合は、packagesセクションにignoremissingフラグを追加するとプロンプトを回避できます。
http://docs.redhat.com/docs/ja-JP/Red_Hat_Enterprise_Linux/6/html/Installation_Guide/s1-kickstart2-packageselection.html
%packages --ignoremissing
LinuxサーバーにSSDを使うための情報メモ
Trim周りが最近どうなっているのか調べていましたが、それ以外の情報もまとまっているもののが案外少なかったので。
Trimをサーバーで使える?
# Trimコマンドのサポートの確認(SSD側) hdparm -I /dev/sda | grep -i TRIM * Data Set Management TRIM supported
Trimコマンドの発行にはSSDをSATAのAHCIモードで接続することが必要。
RAIDカード経由でSSDを接続した場合、SSDを直接扱えないのでTrimは使えない。
2012/05現在、Trimに対応したRAIDカードはないようだ。
(ただし、ext4のdiscardコマンドは内部的にはSCSIデバイスに対してUNMAPコマンドが発行されるので、今後RAIDカード側がATAコマンドのTrimに再度変換してくれれば…?無理かな)
一般的な1UサーバーではほとんどがフロントベイからバックプレーンのminiSAS経由で内蔵のRAIDカードへ接続する形態が取られているため、M/BのSATAポートへSingle Connectできない。つまり、この状態ではどうあがいてもTrimを利用することは不可能。
RAIDカードを省略し、オンボードのチップでRAIDを実現しているタイプの安価なサーバー(1U/ハーフU等)では、ドライブとM/BのSATAポートが直接接続されている場合がある。この場合は内蔵のRAID機能をOFFにすることでAHCIが利用できる場合もあるし、BIOSに設定がなくジャンパピンを変更しなければいけないものもある。
TrimコマンドのLinux側サポートはKernel 2.6.33から。
CentOSの場合6系から。(2.6.32だがバックポート有り)
かつ、ファイルシステムにext4を利用の場合のみ。
マウントオプションにdiscardを指定。
Trimコマンドの動作確認
こちらが詳しい。
http://d.hatena.ne.jp/sh2/20110123
戻り値が0の場合、Trimが有効になっている。それ以外の場合(return=-95が1回だけ等)は、Trimができないと返されている。
上述の理由で、SSDがTrim対応でも殆どの場合サーバーでは使えない。確認必須。
その他LinuxのSSDに関すること
設定の確認など
# SSDかどうか cat /sys/block/sda/queue/rotational 0 -> SSD 1 -> HDD hdparm -I /dev/sda | grep -i ssd # 大抵は型番だけ # 使えない場合はyum install hdparm
SecureErase (SSDリフレッシュ)
hdparmを使う
# SecurityCommand発行可能な状態をセット hdparm --user-master u --security-set-pass xxxxxxxx /dev/sdx # SecureEraseを実行 hdparm --user-master u --security-erase xxxxxxxx /dev/sdx
PartedMagic
http://sourceforge.jp/projects/sfnet_partedmagic/
KnoppixとかUbuntuのLiveCDよりはおすすめ
I/Oスケジューラーの設定
I/Oをキューするかどうか
cat /sys/block/sdb/queue/scheduler # default noop anticipatory deadline [cfq] # 設定の変更 echo deadline > /sys/block/sda/queue/scheduler cat /sys/block/sdb/queue/scheduler noop anticipatory [deadline] cfq
SSDではnoopやdeadlineが推奨されていることが多い。
http://www.velobit.com/storage-performance-blog/bid/126135/Effects-Of-Linux-IO-Scheduler-On-SSD-Performance
ここの結果を見ると、cfqが劇的に遅いわけではないのであえてnoopに変えなくてもよさそうではある。
noopに変えたら5倍早いとかはないです。シングルスレッドで書き込んでいるとかいないとか、テスト項目の問題。
AHCIの有効化
だいたいBIOSで変更するだけ。
運用に関すること
冗長化/RAID
内蔵のRAIDカードがエントリクラスであればRAID1等で逆に足を引っ張るので、ミドルクラス以上のRAIDカード(WriteCache付きのもの)が推奨。
RAIDカード経由でかつRAID構築済みだと性能劣化をリフレッシュする手段がないので、大手メーカー製でSSDがオプションで選択可能なサーバー群では性能劣化の少なく、信頼性も高い(とされる)Intel製を使っているよう。
あんまり推奨してない。要は、RAID構築時にすべてのブロックに書き込みが発生するので性能劣化するんじゃないか?ということらしい。Redhatのドキュメントを参照のこと
http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/newmds-ssdtuning.html
割りきってRAIDなどの冗長化をせずに使うのも十分あり。
故障
故障率のデータ。HDDに比べると半分程度で、さらにその内Intelは一桁違うレベルで信頼性が高いようだ。
http://raven.air-nifty.com/night/2011/08/ssdhdd-3085.html
http://www.tomshardware.com/reviews/ssd-reliability-failure-rate,2923-3.html
監視
smartmontoolsでsmart値の拡張を監視する。
予約領域の残りと、平均消去回数のインジケーター。
# smartctl -a /dev/sda 232 Available_Reservd_Space 0x0003 100 100 010 Pre-fail Always - 0 233 Media_Wearout_Indicator 0x0002 099 099 000 Old_age Always - 0
RAIDカードでArrayを構築済みだと当然だが値は取得できない。
RAID有無でのパフォーマンスの差異などの検証結果は別項で書く予定。
もっといい情報ありましたら教えて下さい。
CentOS6.2にMySQL5.5公式バイナリをインストール時、mysql-libsの依存関係を気にしなくてよくなってた件
半日かかったのに若干しにたい。
CentOS6.2にMySQL公式のバイナリをインストールするしようとすると、下記のような依存性エラーが発生していて、解決を先延ばしにしていた。
Scientific LinuxにMySQL5.5をインストール - cyber_snufkinの日記
postfixはどうしても入ってしまうし、削除するのも気持ち悪いし、remiは本番には使わないことにしているのでどうしようか試行錯誤していたが、結局RHEL系のパッケージ名が問題なのでrpmを直しましょうということになった。
http://bugs.mysql.com/bug.php?id=63433
rpmrebuildというツールでrpmを再パッケージするなどして、できた!と思っていたところだったのだが…先延ばしにしている間にMySQLの5.5.23がリリースされていたので、リリースノートをチェックしてみた。
The MySQL-shared-compat RPM package enables users of Red Hat-privided mysql-*-5.1 RPM packages to migrate to Oracle-provided MySQL-*-5.5 packages. MySQL-shared-compat now replaces the Red Hat mysql-libs package by replacing libmysqlclient.so files of the latter package, thus satisfying dependencies of other packages on mysql-libs. This change affects only users of Red Hat (or Red Hat-compatible) RPM packages. Nothing is different for users of Oracle RPM packages. (Bug #13867506)
MySQL 5.5.23 がリリースされました | MySQL, SkySQL, Navicat, チューニング, 保守サポート
…アルェー、コレ公式で解決しちゃってない?
試しにダウンロードしてきたものをそのまま使ってみる。
# yum localinstall --nogpgcheck MySQL-shared-compat-5.5.23-1.el6.x86_64.rpm =========================================================================================================================================================================== Package Arch Version Repository Size =========================================================================================================================================================================== Installing: MySQL-shared-compat x86_64 5.5.23-1.el6 /MySQL-shared-compat-5.5.23-1.el6.x86_64 11 M replacing mysql-libs.x86_64 5.1.52-1.el6_0.1 Transaction Summary =========================================================================================================================================================================== Install 1 Package(s)
どう見ても完璧です。…わーい。このままMySQL-server突っ込めました。
ていうか採用されたってスレッドに一言書いといて欲しかった…orz
ちなみに、rpmrebuildってツールは既存のバイナリにお手軽に設定ファイルを同梱できる面白いツールでした。EPELで入るので使ってみると良いかも。
http://sourceforge.jp/magazine/07/06/05/0119229/2
kernel: TCP: time wait bucket table overflow の解消とTIME_WAITを減らすチューニング
整理がてら。
httpdが動いているあるホスト上で、 /var/log/messages に以下のようなメッセージが出ていた。
kernel: TCP: time wait bucket table overflow kernel: printk: 50078 messages suppressed.
"netstat -tna |grep TIME_WAIT"すると、10万以上の数でTIME_WAITが出ている。これを解消するまでの流れ。
そもそもこの値は、カーネルパラメータの
net.ipv4.tcp_max_tw_buckets
で設定されている。デフォルトは16384。
(↑の通り、エラーが出た環境では既にかなり大きな値が設定されていたのだが。)
/proc/sys/net/ipv4/tcp_max_tw_buckets システムが同時に保持する time-wait ソケットの最大数。この数を越えると、time-wait ソケットは直ちに破棄され、警告が表示されます。この制限は単純な DoS 攻撃を防ぐためにあります。わざと制限を小さくしてはいけません。ネットワークの状況によって必要な場合は、 (できればメモリを追加してから) デフォルトより増やすのはかまいません。 http://archive.linux.or.jp/JF/JFdocs/Adv-Routing-HOWTO/lartc.kernel.obscure.html
単純に値を増やして対応しても良いのだが、ホストと動いているサービスの状況によって対応策を使い分けたほうが良いと思う。
- net.ipv4.tcp_max_tw_buckets を増やす
内部NWで閉じて利用しているか、DoS攻撃を防ぐための機能が上位のFirewall等で確実に機能している場合はこれでもよさそう。
- TIME_WAITを減らすようにkernelパラメータをチューニングする
おおまかなパターンとしては以下の二つがあり、今回は後者を採用した。
1. TIME_WAITが自然解消されるまでの時間を減らす
これはかなり難解で、LinuxではTIME_WAITの保持時間を減らすにはカーネルをリビルドするしかない。
http://d.hatena.ne.jp/ono51/20111012/p1
この件を調べている途中、tcp_fin_timeoutを減らしたらOKという記事をたくさん見かけたが、どうも一緒に指定しているtcp_tw_recycleの作用が出ているだけに思える。
tcp_fin_timeout自体は、FIN-WAIT2からTIME_WAITに状態変化する時間のパラメータであり、TIME_WAIT状態が継続する時間とは関係ない。
2. TIME_WAITになったポートを再利用する
サーバ側で net.ipv4.tcp_tw_recycle を有効にする。
これで10万以上あったTIME_WAITが一気に100以下のレベルに。これは、閉じた環境で100ホスト程度がアクセスしてきているという環境だったから。
ただし、サーバ側で net.ipv4.tcp_tw_recycle が有効で、クライアント側でTCPのタイムスタンプオプションが有効(Linuxの場合net.ipv4.tcp_timestamps = 1)だと、NAT/LBを超えたときにSYNを落としてしまい、接続障害になる。
ユーザー向けに使っているとSB携帯などで障害が発生してしまうようなので、使わないほうがいいかも。
net.ipv4.tcp_tw_reuseを有効にしてもほとんど効果がなかった。これはおそらく、クライアント側も同じソケットをTIME_WAITしているため、クライアント側からの接続は新規セッションが使われるからだと思う。(ということは、クライアントとサーバー両方でONにしないとダメなんじゃないか?という疑問が。誰か検証してくれないかなー。)
- アプリケーション側でコネクションの総数を減らす工夫をする
HTTPなので、keepaliveを有効にすることもできる。今回はHTTPを呼び出している側のシステムがコネクションプール的な概念を持たないので断念。
net.ipv4.tcp_tw_recycleを使う時の注意点はこのへんが詳しい。先達に感謝。
どさにっき
2007-05-21 - LowPriority