OS層~障害解析の手順・ツール評価編

2005 年度上期
オープンソースソフトウェア活用基盤整備事業
「OSS 性能・信頼性評価 / 障害解析ツール開発」
OS 層
~障害解析の手順・ツール評価編~
作成
OSS 技術開発・評価コンソーシアム
商標表記
・ Alicia は、ユニアデックス株式会社の登録商標です。
・ Asianux は、ミラクル・リナックス株式会社の日本における登録商標です。
・ Intel、Itanium および Intel
Xeon は、アメリカ合衆国およびその他の国におけるイ
ンテルコーポレーションまたはその子会社の商標または登録商標です。
・ Intel は、Intel Corporation の会社名です。
・ Linux は、Linus Torvalds の米国およびその他の国における登録商標あるいは商標です。
・ MIRACLE LINUX は、ミラクル・リナックス株式会社が使用許諾を受けている登録商
標です。
・ Pentium は、Intel Corporation のアメリカ合衆国及びその他の国における登録商標で
す。
・ Red Hat は、米国およびその他の国で Red Hat, Inc. の登録商標若しくは商標です。
・ Solaris は、米国 Sun Microsystems, Inc. の米国およびその他の国における商標または
登録商標です。
・ SUSE は、米国 Novell, Inc.の一部門である SUSE LINUX AG.の登録商標です。
・ Turbolinux は、ターボリナックス株式会社の商標または登録商標です。
・ UNIX は、X/Open Company Limited が独占的にライセンスしている米国ならびに他
の国における登録商標です。
・ Windows は、米国およびその他の国における米国 Microsoft Corp.の登録商標です。
・ その他記載の会社名、製品名は、それぞれの会社の商号、商標もしくは登録商標です。
- i -
目次
1
障害解析の概要 ..........................................................................................................1-1
1.1
障害解析の一般的手順.........................................................................................1-3
1.2
準備 .....................................................................................................................1-4
1.3
障害情報収集および初期切り分け.......................................................................1-5
1.4
再現および障害解析 ............................................................................................1-6
1.5
使用可能なツールとその分類..............................................................................1-7
1.5.1
2
3 章で評価するツールについて..................................................................1-15
障害解析手法と考察 ...................................................................................................2-1
2.1
障害事例の最近の傾向.........................................................................................2-1
2.2
一般的な障害解析手法.........................................................................................2-2
2.2.1
エラーメッセージ関連 .................................................................................2-2
2.2.2
アプリケーション異常終了 ..........................................................................2-4
2.2.3
スローダウン................................................................................................2-6
2.2.4
フリーズ.......................................................................................................2-9
2.2.5
カーネルパニック....................................................................................... 2-11
2.2.6
ネットワーク障害.......................................................................................2-13
2.2.7
ディスク障害..............................................................................................2-15
2.3
エラーメッセージ関連.......................................................................................2-17
2.3.1
2.4
スレッド生成不可(manページにないエラー)が発生する障害の解析 ....2-17
アプリケーション異常終了 ...............................................................................2-24
2.4.1
高負荷時にアプリケーションが異常終了する障害の解析(コアダンプなし)
2-24
2.4.2
高負荷時にアプリケーションが異常終了する障害の解析(コアダンプあり)
2-30
2.4.3
高負荷時にアプリケーションがOut of Memoryで強制終了された障害の解析
(コアダンプなし) .................................................................................................2-32
2.5
スローダウン.....................................................................................................2-34
2.5.1
パフォーマンス監視ツールの障害解析 ......................................................2-34
2.5.2
システムコールトレーサがトレース対象プロセスを遅延させる障害の解析
2-73
2.5.3
2.6
フリーズ ............................................................................................................2-94
2.6.1
2.7
フリーズ障害の解析 ...................................................................................2-94
カーネルパニック............................................................................................2-103
2.7.1
2.8
性能障害.....................................................................................................2-90
カーネルパニック障害の解析...................................................................2-103
ネットワーク障害............................................................................................ 2-112
2.8.1
障害概要................................................................................................... 2-112
2.8.2
障害検知................................................................................................... 2-112
2.8.3
障害切り分け............................................................................................ 2-113
- ii -
2.8.4
2.9
3
障害回復手順............................................................................................ 2-115
ディスク障害................................................................................................... 2-119
2.9.1
H/W RAID 5/1 ......................................................................................... 2-119
2.9.2
S/W RAID5/1 ...........................................................................................2-123
2.9.3
LVM .........................................................................................................2-127
ツール評価..................................................................................................................3-1
3.1
パフォーマンス監視ツールの信頼性評価 ............................................................3-1
3.1.1
ツールの概要................................................................................................3-1
3.1.2
評価環境.......................................................................................................3-4
3.1.3
評価項目.......................................................................................................3-7
3.1.4
評価手順.......................................................................................................3-7
3.1.5
評価結果.......................................................................................................3-8
3.2
プロファイラの機能評価 ...................................................................................3-39
3.2.1
ツール概要 .................................................................................................3-39
3.2.2
評価環境.....................................................................................................3-39
3.2.3
評価項目.....................................................................................................3-40
3.2.4
評価手順.....................................................................................................3-53
3.2.5
評価結果.....................................................................................................3-55
3.2.6
readprofile .................................................................................................3-66
3.2.7
考察 ............................................................................................................3-68
3.3
システムコールトレーサの評価 ........................................................................3-69
3.3.1
システムコールトレーサの概要 .................................................................3-69
3.3.2
strace評価環境 ...........................................................................................3-69
3.3.3
strace機能評価 ...........................................................................................3-69
3.3.4
strace信頼性評価(前提条件) ..................................................................3-73
3.3.5
strace信頼性評価(CPU負荷時)..............................................................3-76
3.3.6
strace信頼性評価(I/O負荷時) ................................................................3-79
3.3.7
strace信頼性評価(メモリ負荷時)...........................................................3-83
3.4
ネットワーク情報収集ツールの評価 .................................................................3-87
3.4.1
ツールの使用方法.......................................................................................3-87
3.4.2
bonding環境での機能評価 .........................................................................3-95
3.4.3
bonding機能検証手順 ..............................................................................3-102
3.4.4
bonding機能検証結果と考察....................................................................3-102
3.5
ディスク情報収集ツールの評価 ......................................................................3-105
3.5.1
ツールの使用方法.....................................................................................3-105
3.5.2
H/W RAID 5/1 評価環境 ......................................................................... 3-117
3.5.3
S/W RAID 5/1 ディスク評価環境............................................................3-122
3.5.4
LVM機能評価環境....................................................................................3-124
3.6
ダンプツールの評価 ........................................................................................3-134
3.6.1
ダンプ採取ツール.....................................................................................3-134
- iii -
3.6.2
3.7
4
ダンプ解析ツール.....................................................................................3-158
OSS障害解析ツールの問題点と対策 ...............................................................3-179
付録
<crash/lcrash/mdbコマンド結果比較>.........................................................4-1
- iv -
1 障害解析の概要
最近 OSS がエンタープライズ向けシステムへ適用される事例が多数見られるようになっ
てきており、Linux の安定度は増してきていると思われる。しかし障害が発生した場合、そ
の障害の種別によっては解析が困難な場合があり、エンタープライズ向けシステムに要求
される迅速な障害対応が実現できないことがある。また、ユーザもこのような状況に、OSS
のサポートに対して漠然とした不安を持っていると思われる。
このような状況を作り出している要因として、以下が挙げられると考えた。
(1) 障害解析ノウハウの蓄積が不足している
解析ノウハウについて公開されているものもあるが、各種障害事例について集約/網
羅されているものは、今回は見出すことができなかった
(2) 障害解析ツールの使用方法や問題点などが整理されていない
解析ツールに関する総括的な情報、たとえばどのようなツールを使うことによって、
どのような情報が得られるのか、また、ツール自体の問題点や不足している機能はない
か、等が整理されていない
この問題点をふまえ、本評価報告書では下記の点を目的とした。
(1) 代表的な障害事象について、事象毎にそれぞれ代表的な障害解析手法を示す
(2) 障害解析事例を通じて、具体的な障害解析ノウハウを公開する
(本報告書で取り上げた障害解析事例の一覧については、表 1.1-1 を参照)
(3) OSS の障害解析ツールに絞って、現在普及している解析ツールの分類、および問題点や
不足している機能等をまとめた上で公開する
本評価報告書は、マニュアルを参照し障害切り分けを行うレベルから、ソースコード解
析を行うレベルまでの幅広い障害解析者を対象としており、障害解析時の参考資料および、
障害解析者の教育資料として活用されることを想定している。
これまで OSS においては、この種の報告書は存在しなかったと思われる。この報告書で
各種ノウハウを明示化することによって、より多くのフィードバックが重ねられ、それに
よって OSS が更に発展することを期待する。
- 1-1 -
表 1.1-1
#
事象分類
1
障害事例および使用した解析ツール一覧
障害事例の概要
使用した主なツール
備考
エラーメッセージ
ある特定の処理(多数のスレッドを生成)を行うとアプ
strace
2.3.1
関連
リケーションが必ずエラーを出力する。仕様書には特に
strace
2.4.1、2.4.2
/var/log/messages
2.4.3
lkst,ps
2.5.1
制限等の記載はない
2
アプリケーション
通常は何の問題もなく動くアプリケーションが、負荷が
異常終了
高くなるとセグメンテーションフォールトとなる(コア
ダンプあり/なし)
3
通常は何の問題もなく動くアプリケーションが、メモリ
負荷が高くなると強制終了してしまう(コアダンプなし)
4
スローダウン
通常は何の問題もなく動くアプリケーション(sar、
iostat)が、負荷が高くなると計測タイミングの遅延が生
じる
通常は何の問題もなく動くアプリケーション(strace)が、 strace, lkst
2.5.2
負荷が高くなるとトレース対象のプロセス処理を遅延さ
せてしまう
I/O 負荷が高いとき性能がでない。
oprofile
2.5.3
5
フリーズ
性能情報採取コマンドを実行中にフリーズが発生した
diskdump, Alicia
2.6.1
6
カーネルパニック
突然、カーネルパニックが発生した
diskdump, Alicia,
2.7.1
objdump
7
ネットワーク障害
ネットワークリンクダウンが発生する
ping, traceroute, netstat,
2.8.1
ifconfig, ethtool
8
ディスク障害
ディスク I/O エラーが発生(H/W RAID、S/W RAID、
StorageManager,swatch,
LVM)
mdadm,raidtool,df,lvm
- 1-2 -
2.9.1、2.9.2、2.9.3
1.1 障害解析の一般的手順
エンタープライズシステムにおける、障害解析の際の一般的な手順を 図 1.1-1 に示す。
システム管理者
障害解析者
1. 準備
2. 稼働開始
障害
発生
3. 障害情報収集
2'. 稼働再開
障害情報
4. 初期切り分け
障害情報
障害情報から
解析可能?
N
5. 再現手段確立
Y
6. 障害解析
障害原因
特定?
N
Y
回避策を適用
7. 回避策の検討、実施
本対策を適用(稼働環境のタイミングによる)
図 1.1-1
8. 本対策の検討、実施
障害解析概要フロー
システム管理者は、障害発生時の情報収集に必要な準備(図中の 1)を行ってからシステ
ムを稼働(2)する。障害発生時は、速やかに障害情報を収集(3)し、稼働を再開(2')す
る。
障害解析者は収集された障害情報から、まず初期切り分け(4)により、ハード/OS/ミ
ドル/アプリの切り分けを行う。切り分け後は、障害情報からの解析が可能かどうかを判
断し、不可能な場合は障害の再現手段を確立(5)する。次に、障害原因が特定できるまで
解析(6)を行う。
対策に関しては、エンタープライズシステムに於いては、システムを更新できるタイミ
- 1-3 -
ングが限られているため、本対策(8)の前に回避策(7)を実施することが多い。
本報告書では、主に太枠の部分に関して報告する。特に障害解析(6)については、障害
解析事例を用いて詳細に報告する。
1.2 準備
障害解析にあたり、万が一、障害が発生したとき十分な情報が取得できるようにいくつ
かの準備を行うべきである。あらかじめ障害に対する準備をしておくと、障害対応の時間
の節約が期待できる。
(1) カーネルクラッシュダンプ取得準備
以下の点に注意する。
・ ダンプデータ保存用パーティションのサイズは大丈夫か?
物理メモリサイズと同サイズではなく、余裕を持ったサイズ(約 1.5 倍を推奨)を用意
する必要がある。通常は OS インストール時にダンプ保存用パーティションを作成する。
運用時でパーティション作成が難しい場合は、ディスク増設などを検討する。
・ ダンプ取得用ディレクトリは十分なサイズを持つか?
diskdump の場合、/var/crash に取得したダンプを格納するので、そのディレクトリが
十分な空きディスク容量を持つか確認する。/var はログファイルが格納される場所なの
で十分な空きディスク容量がない場合があるので注意が必要である。可能であれば
/var/crash も十分な容量を持つ別パーティションにしておくのがよい。
・ カーネルパニック時にダンプ採取する設定になっているか?
cat /proc/sys/kernel/panic_on_oops を実行して 0 だった場合は、以下を実行しダンプを
取得できるようにする。恒久的に設定するには、/etc/sysctl.conf 中に
kernel.panic_on_oops = 1 の行を追加する。
# echo 1 > /proc/sys/kernel/panic_on_oops
・ パニックを起こしてみて、ダンプが取れることを確認する。
# echo c > /proc/sysrq-trigger
ないしは
Alt-SysRq-C
でダンプが取れることを確認する。
(2) カーネル設定
・
CONFIG_MAGIC_SYSRQ=y になっているか?
‘y’になっていない場合、SysRq キーによるクラッシュダンプの取得やメモリ情報の取得
ができないので注意する。/boot/config-`uname -r` が当該 OS の設定ファイルなのでそ
- 1-4 -
れを確認する。SysRq キーの機能については/usr/src/linux/Docuemtation/sysrq.txt を
参照のこと。
実行時に SysRq キーを有効にするには下記を行う。
# echo "1" > /proc/sys/kernel/sysrq
(3) アプリケーションクラッシュ取得準備
・コアファイルのサイズ制限がかかっていないことを ulimit -c コマンドで確認する。もし
もサイズが不足している場合は、ulimit -c unlimited を行う。恒久的に設定するには、
/etc/security/limits.conf 中に* soft core unlimited の行を追加し再ログインする。恒久的
に設定していない場合、ulimit コマンドで unlimited を設定したシェル以外でアプリケー
ションを実行しても、その設定は反映されないことに注意する必要がある。
・可能な限り gcc オプション-g を付けてコンパイルする。デバッグの時だけでなく、コア
ファイル解析の際にもシンボルありで表示されるため、追跡が容易になる。
(4)
oprofile を利用する場合は、kernel-debuginfo のインストール
# rpm –qa| grep debuginfo
で kernel-debuginfo がインストールされているか確認できる。
(5)
アプリケーションのログの設定と監視
・ アプリケーションによっては障害事項に関して独自のログを発行するものがある。障害
で停止する前に警告を発行する場合があるので、運用時に監視することによってあらか
じめ障害にそなえることができる。
・ 万が一障害が発生したとしても、アプリケーションログを取得するようにしておけば、
障害原因究明のヒントが得られるかもしれない。
1.3 障害情報収集および初期切り分け
障害が発生した直後の障害情報収集は重要であり、発生時の手順、更新された内容・環境
など調査し情報を残すと共に、可能な限り広範囲な障害情報を収集することが望ましい。
障害発生時のシステム状態を確認する為に mcinfo(MIRACLE LINUX)や、sysreport(Red
Hat)、getinfo(Turbolinux)を利用して収集することも有効である。収集の後は、状態回復/
復旧を行なうこと。
初期切り分けの判断材料として、/var/log/messages, /proc, dmesg 等の情報を確認するこ
とが重要である。必要なログの取得が終了したなら、速やかに状態回復/復旧を目指すこと。
- 1-5 -
1.4 再現および障害解析
まず、障害発生時の状況として、障害解析可能な情報(例えば、コアダンプファイルや
メモリダンプファイル)が保存されているかを確認する。
障害解析可能な情報が存在しない場合は、障害解析環境において障害を再現させる必要
がある。しかし実際には障害の再現は難しく、長時間掛かる場合も多い。更に再現しない
場合もあり、そのような場合には、稼働環境で追加情報収集の準備を行い、再現待ちをす
る。
障害解析可能な情報が存在する場合および、障害の再現が可能な場合は、障害解析を行
う。障害解析作業としては、解析に必要な情報収集を行いながら切り分け作業を行い、障
害原因を追求して行く。障害事象によって使用する解析ツールが異なるため、どのような
障害事象の場合にどのようなツールを使うのが有効であるかなど、具体的な手法に関して
は 2 章を参照のこと。
- 1-6 -
1.5 使用可能なツールとその分類
障害解析に有効なツールおよび関連ファイルを障害解析フェーズ毎に分類したものを 表 1.5-1 に示す。
表 1.5-1
項
機能分類
名称
障害解析に有効なツール/関連ファイルの分類
概要
番
1
ダンプ取得
diskdump
障害時にクラッシュダンプを
使用する解析フェーズ
備考
準備
(章番号)
情報
障害
収集
解析
○
3.6.1.1
○
3.6.1.2
○
3.6.1.3
○
3.6.1.4
ディスク上に採取する仕組
みである
2
netdump
障害時にクラッシュダンプを
ネットワーク経由で採取する
為の仕組みである。
3
LKCD
障害時のメモリダンプ採取
機能およびメモリダンプ解析
ツールの提供する。
4
kdump
障害時に、セカンドカーネル
を使用してダンプを採取する
仕組みである。
- 1-7 -
項
機能分類
名称
概要
番
5
mkdump
障害時に、ミニカーネルを使
使用する解析フェーズ
備考
準備
(章番号)
情報
障害
収集
解析
3.6.1.5
○
用してダンプを採取する仕組
みである。(kexec/kdump の
改良版)
6
システム情報取得
/var/log/messages
一般的なシステム情報を記
2.4
○
録したログファイル。
(システム全体)
7
/usr/include/asm/errno.h
エラー番号の定義ファイル。
8
dmesg
カーネルのログ用リングバッ
○
2.3.1
○
ファの表示および設定を行
なう。
9
lsmod
ロードされているモジュール
○
の情報を一覧表示する。
10
lspci
全ての PCI バスとそこに接
○
続されている全デバイスの
情報を表示する。
11
top
CPU およびメモリの使用量
○
をプロセス単位で表示する。
12
ipcs
IPC リソース情報を表示す
○
る。
13
sysctl
/proc/sys/以下にリストされ
ているカーネルパラメータを
設定する。
- 1-8 -
○
2.5.2
項
機能分類
名称
概要
番
14
mpstat
使用する解析フェーズ
備考
準備
(章番号)
/proc ファイルシステムが提
情報
障害
収集
解析
○
3.1
○
MIRACLE
供する統計データのうち
CPU 関連の情報を収集す
る。
15
mcinfo
各種ログやハードウェア情
LINUX
報、インストールされている
パッケージなどの情報を収
集する。
16
/proc/cpuinfo
CPU に関する情報を表示。
17
/proc/stat
カーネル/システムの統計情
○
○
○
報。
18
/proc/version
カーネルのバージョン識別
○
○
子文字列。
19
sysreport
システムのハードウェアと構
○
Red Hat Linux
Fedora Core
成に関する情報を収集す
る。
20
getinfo
システムのハードウェアと構
○
Turbolinux
○
2.5.1、 2.5.2、
成に関する情報を収集す
る。
21
sar
/proc ファイルシステムが提
供するシステムに関する統
計データを収集する。
- 1-9 -
3.1
項
機能分類
名称
概要
番
22
システム情報取得
/proc/プロセス ID/stat
備考
準備
(章番号)
プロセスの状態についての
情報
障害
収集
解析
○
情報。 ps で使われる。
(プロセス関連)
23
使用する解析フェーズ
ps
実行されているプロセスの
○
2.5.1
一覧を表示する。
24
pstree
実行中のプロセスをツリー形
○
式で表示する。
25
システム情報取得
free
メモリの使用量と空き容量を
表示する。
(メモリ関連)
26
○
vmstat
仮想メモリの統計情報を表
○
示する。
27
pmap
29
/proc/meminfo
○
未使用および使用中のメモ
○
○
○
○
2.4.1
○
2.5.1、 3.1
リ量などメモリ情報を表示。
free で使われる。
30
/proc/sys/vm/overcommit_memory
カーネル仮想メモリのアカウ
ントモードを表示。
31
システム情報取得
iostat
/proc ファイルシステムが提
供する統計データのうち I/O
(I/O 関連)
処理に関する情報を収集す
る。
32
fdisk
パーティションテーブルの操
作をおこなう。
- 1-10 -
○
項
機能分類
名称
概要
番
33
df
ファイルシステムのディスク
使用する解析フェーズ
備考
準備
(章番号)
情報
障害
収集
解析
○
3.5.1
○
3.5.1
○
3.5.1
○
3.5.1
使用量と空き容量を表示す
る。
34
lvm
複数のドライブをまとめて
「論理ボリューム」とし、 各
パーティションに割り振れ
る。さらにこのユニットは、空
きの調整が必要となった時
に、パーティションに対して
追加や削除が行える。
35
raidtools
S/W RAID 設定・管理が出
来るツールである。
36
mdadm
複数のディスクドライブやパ
ーティションをまとめて 1 つ
のファイルシステムとして利
用することができる。
37
DAVL
ディスクのフラグメンテーショ
○
ン状態を可視化する。
38
システム情報取得
(ネットワーク
ifconfig
ネットワークインタフェイスの
表示と設定を行なう。
- 1-11 -
○
3.4.1
項
機能分類
名称
概要
番
39
関連)
ping
ICMP パケットをネットワー
使用する解析フェーズ
備考
準備
(章番号)
情報
障害
収集
解析
○
3.4.1
○
3.4.1
ク上のホストに送り応答結果
を表示する。
40
netstat
ネットワーク接続および経路
に関する情報を表示する。
41
host
DNS を使いホスト名の検索
○
をおこなう。
42
route
IP 経路テーブルの表示およ
○
び設定をおこなう。
43
traceroute
あるホストから別のホストま
○
3.4.1
○
3.4.1
でのネットワーク経路を表示
する。
44
ethtool
ネットワークインタフェースの
状況を調査する。
45
46
トレーサ
strace
ユーザ空間のプラグラムが
(システムコール/
発行したシステムコールとシ
ライブラリ)
グナルをとらえて記録する。
ltrace
プログラムから共有ライブラ
リへの関数呼び出しを記録
する。
- 1-12 -
○
○
2.3.1、 2.5.2
○
○
2.3.1、 2.4.1、
2.4.2
項
機能分類
名称
概要
番
47
トレーサ
LKST
Linux カーネルの処理をトレ
(カーネル内
ースするツール。カスタマイ
イベント)
ズ機能をもつ。
48
LTT
組み込み系向けの Linux カ
使用する解析フェーズ
備考
準備
(章番号)
情報
障害
収集
解析
○
○
○
○
2.5.1、 2.5.2
ーネルの処理をトレースする
ツール。
49
プロファイラ
OProfile
カーネルおよびユーザプロ
○
3.2.1
グラムのハードウェアイベン
トのプロファイリングを行う。
コールグラフ機能、ソースコ
ードとの対比などを行う高機
能なプロファイラ。
50
51
デバッガ
readprofile
カーネルプロファイラ
○
3.2.6
gdb
プログラムが実行中もしくは
○
2.5.2
クラッシュした時にその プロ
(アプリケーション)
グラムの内部で何が行われ
ていたかを調べるツール。
52
デバッガ
(カーネル)
kdb
カーネル の 実行を トレ ース
し、メモリやデータ構造を調
査するツール。
- 1-13 -
○
項
機能分類
名称
概要
番
53
kgdb
使用する解析フェーズ
備考
準備
(章番号)
情報
障害
収集
解析
他のホストの gdb から
○
リモート操作できるカーネル
デバッガ
54
ダンプ解析
crash
UNIX の crash ツールのイ
○
3.6.2.1
○
3.6.2.1
○
3.6.2.1
ンターフェースをベースに作
成されたツール
55
lcrash
LKCD で採取されたダンプ
を編集するために作成され
たツール
56
Alicia
Linux カーネルダンプ解析
ツールである crash/lcrash
をラッピングしたダンプ解析
ツール
57
ロガー
MRTG
SNMP によりネットワークや
○
システムを監視しグラフ表示
する。
58
Nagios
システムとネットワークの監
視アプリケーション。ホストや
サービスを監視し、障害発生
に対し警告。
- 1-14 -
○
1.5.1 3 章で評価するツールについて
(1) パフォーマンス監視ツール:sar、 iostat、 mpstat
sysstat パッケージに含まれるこれらのツールは、CPU 利用率や I/O 負荷の計測に良
く利用されるものであるが、システムの負荷が高い状況下ではうまくデータを取得でき
ない場合があり、監視ツールとして利用上の注意が必要である。どのような負荷タイプ
で注意が必要か、回避策としてどのような方法が可能かについて評価を行い、より安定
して必要なデータを取得できる利用技術を提供する。
(2) プロファイラ:OProfile、 readprofile
OProfile はカーネルモードおよびユーザモードでのハードウェアイベントのプロファ
イリングを行う。コールグラフ機能、ソースコードとの対比の機能などがあり高機能で
ある。readprofile はカーネルプロファイリングの機能を提供する。
(3) システムコールトレーサ:strace、 ltrace
これらのツールは、主にアプリケーション障害の解析用として広く使われており、非
常に有効なツールである。使用される場面も多岐にわたると考えられるが、どの程度ま
での負荷ならば問題なく使用できるか評価を行い、実際に障害解析で使用する際のガイ
ドラインを提供する。
(4) ネットワーク情報収集ツール:ethtool、 ifconfig、 netstat、 ping、 traceroute、
Bonding
ネットワーク設定、監視、解析用として標準的に取り込まれている機能であり、様々
な状況下において有効なツールであると考えられるが、実際の使用方法について情報を
提供する。
(5) ディスク情報収集ツール:df、 raidtools、 mdadm、 smartmontool、 LVM2
ディスク環境設定、監視、解析用として一般的に使われており、様々な状況下におい
て有効なツールであると考えられるが、実際の使用方法について情報を提供する。
(6) ダンプツール:
(採取ツール)diskdump、 netdump、 LKCD、 kdump、 mkdump
(解析ツール)crash、 lcrash、 Alicia、 mdb
ダンプツールは、大きく分けてダンプをディスクに吐き出すためのダンプ採取ツール
と、ダンプをディスクから読み込み解析を容易にするためのダンプ解析ツールの二つに
分類できる。それぞれ複数のツールが利用可能であるが、ダンプツールに関しては整理
された情報が公開されていないため、各ツールの使用方法やツール間の機能比較等につ
いて情報を提供する。
- 1-15 -
2 障害解析手法と考察
2.1 障害事例の最近の傾向
国内SI/OSベンダ数社のサポートセンタにて、この一年間最近の問合せの件数を合計(約
200 件)し、事象分類した結果を 図 2.1-1 に示す。
事象分類
3% 2% 1%
5%
6%
31%
10%
10%
エラーメッセージ関連
ディスク障害
アプリ異常終了
フリーズ
パニック
ネットワーク障害
起動障害
スローダウン
インストール障害
リブート
17%
15%
図 2.1-1 障害(事象分類)
このグラフからはエラーメッセージ関連の問い合わせが多いことがわかる。これは、シス
テムから表示されるメッセージが、ユーザには障害(問題)であるかが判断出来ないためと考
えられる。今後は、表示されるメッセージの情報に関しても整備が必要なのでは、と考え
させられる結果である。
- 2-1 -
2.2 一般的な障害解析手法
以下、代表的な障害事象に関して、事象毎にそれぞれ代表的な障害解析手法を示す。
2.2.1 エラーメッセージ関連
エラーメッセージの場合、障害情報収集の一部として下記を行う。
(1) エラーメッセージの確認
異常終了時にエラーメッセージが出力されていないか確認し、出力されていればメモ
する等して保存しておく。
(2) アプリケーションログファイルの確認
アプリケーションログがあれば参照し、エラーが出力されていないかどうか確認する。
エラーが出力されていればメモする等して保存しておく。
(3) コアダンプファイルの確認
異常終了時にコアダンプファイルが出力されていないか確認し、出力されていれば別
ディスク上に書き出す等して保存しておく。
(4) システムログファイルの確認
異常終了時のシステムログ(/var/log/messages 等)を確認し、同アプリケーションの
エラーが出力されていないかを確認し、出力されていればメモする等して保存してお
く。
障害解析手法としては、主に表 2.2-1 に示すやり方がある。
表 2.2-1
エラーメッセージの障害解析手法
#
手法名称
手法概要
1
類似障害検
Red Hat 社の Bugzilla(https://bugzilla.redhat.com/bugzilla/)
索
を代表とするインターネット上のサイトや社内の障害事例等を
検索し、類似障害が報告されていないかを確認する。
2
アプリケー
アプリケーションのマニュアル等でログないしメッセージを確
ションログ
認する。
ファイルの
解析
3
環境情報の
どのような環境でエラーメッセージないしはログ情報が取得さ
取得
れたかを確認する。
表 2.2-2 の代表的な障害解析手法を用いた、エラーメッセージからの障害解析フローを
図 2.2-2 に示す。
- 2-2 -
解析開始
1. 類似障害検索
N
解決
エラーメッセ
ージあり?
Y
2. エラー解析
解決
再現手段確立
N
再現可?
Y
3. 最新版試行
解決
再準備
再現待ち
図 2.2-1
解析終了
エラーメッセージの障害解析フロー
- 2-3 -
2.2.2 アプリケーション異常終了
アプリケーション異常終了の場合、まず障害情報収集の一部として下記を行う。
(1) エラーメッセージの確認
異常終了時にエラーメッセージが出力されていないか確認し、出力されていればメモ
する等して保存しておく。
(2) アプリケーションログファイルの確認
アプリケーションログがあれば参照し、エラーが出力されていないかどうか確認する。
エラーが出力されていればメモする等して保存しておく。
(3) コアダンプファイルの確認
異常終了時にコアダンプファイルが出力されていないか確認し、出力されていれば別
ディスク上に書き出す等して保存しておく。
(4) システムログファイルの確認
異常終了時のシステムログ(/var/log/messages 等)を確認し、同アプリケーションの
エラーが出力されていないかを確認し、出力されていればメモする等して保存してお
く。
障害解析手法としては、主に 表 2.2-2 に示す 5 通りのやり方がある。
表 2.2-2
アプリケーション異常終了の障害解析手法
#
手法名称
手法概要
1
類似障害検索
Red Hat 社の Bugzilla
(https://bugzilla.redhat.com/bugzilla/)
を代表とするインターネット上のサイトや社内の障害事例等
を検索し、類似障害が報告されていないかを確認する。
2
コアダンプ解析
異常終了時のコアダンプが取れていた場合、デバッガを用いて
コアダンプを解析することで障害箇所を特定する
3
環境変更試行
アプリケーションの版を変えたり、CPU/ディスク/メモリ
等の条件を変えたりして、同様の現象が起こるか確認する
4
トレーサ解析
ライブラリ/システムコールトレーサを用いて障害原因を特
定する
5
デバッガ解析
デバッガを用いて更に詳細な障害原因の追跡を行う
表 2.2-2 の代表的な障害解析手法を用いた、アプリケーション異常終了の障害解析フロ
ーを 図 2.2-2 に示す。
- 2-4 -
解析開始
1. 類似障害検索
N
解決
コアダンプ
出力あり?
Y
2. コアダンプ解析
解決
再現手段確立
N
N
N
ソース入手
可能?
再現可?
Y
3. 最新版試行
解決
4. トレーサ解析
解決
-g 付きでコ
ンパイル済
み?
Y
Y
-g 付けてリビルド※
※ configure ス ク リ プ ト や
Makefile の修正が必要な
場合が多い。
5. デバッガ解析
解決
再準備
再現待ち
図 2.2-2
解析終了
アプリケーション異常終了の障害解析フロー
- 2-5 -
2.2.3 スローダウン
スローダウンの場合、まず障害情報収集の一部として下記を行う。
(1) スローダウン障害発生状況時の確認
いつから、どのようなクライアント側アプリケーション操作によりスローダウンに気
がついたかを確認し、必要に応じてスクリーンショット等を保存しておく。単一のク
ライアントのみで発生した障害か複数のクライアントで広範囲に発生しているかにつ
いても、原因の特定に有効な情報である。
(2) ネットワーク接続の確認
複数のクライアントで障害が発生しているが、一部のネットワークで障害が集中的に
発生している疑いがある場合には、サーバやルータへの応答テストやネットワーク負
荷履歴の確認、ネットワーク機器のログの確認をおこない、異常が出力されていれば
メモする等して保存しておく。
(3) アプリケーションのログファイルの確認
複数のクライアントで障害が発生しておりサーバ側アプリケーションで障害発生の疑
いがある場合には、アプリケーションのログファイルに警告やエラーが出力されてい
ないか確認し、出力されていればメモする等して保存しておく。
(4) サーバの負荷状況の確認
サーバのプロセス状況や負荷状況を確認し、通常と異なる場合にはメモする等して保
存しておく。
(5) システムログファイルの確認
サーバのシステムログ(/var/log/messages 等)を確認し、アプリケーションのエラー
が出力されていないかを確認し、出力されていればメモする等して保存しておく。
障害解析手法としては、主に 表 2.2-3 に示す 6 通りの方法がある。
表 2.2-3 スローダウンの障害解析手法
#
手法名称
手法概要
1
類似障害検索
Red Hat 社の Bugzilla
(https://bugzilla.redhat.com/bugzilla/)を代表とするイ
ンターネット上のサイトや社内の障害事例データベース等を
検索し、同様な障害が報告されていないかを確認する。
2
ログ解析
障害時のアプリケーションログやシステムログに詳細な記録
が取れていた場合、それぞれのケースで固有の方法により解析
することで障害箇所を特定する。
3
環境変更試行
アプリケーションの版を変えたり、CPU/ディスク/メモリ等
の条件を変えてみて、同様の現象が起こるか確認する
4
トレーサ解析
ライブラリ/システムコールトレーサを用いて障害原因を特
- 2-6 -
定する
5
6
プロファイル
プロファイラを用いて関数の呼び出し頻度や処理時間等を分
解析
析し障害原因を特定する
デバッガ解析
デバッガを用いて更に詳細な障害原因の追跡を行う
- 2-7 -
表 2.2-3 の代表的な障害解析手法を用いた、スローダウンの障害解析フローを 図 2.2-3
に示す。
解析開始
N
複数クライアン
トで異常あり?
単体問題として
障害解析
Y
ネットワーク
に異常あり?
Y
ネットワーク
障害解析手順へ
N
疑わしい要因
の選定
1. 類似障害検索
N
解決
アプリログに
異常あり?
Y
2. ログ解析
解決
再現手段確立
N
N
N
ソース入手
可能?
再現可?
Y
3. 環境変更試行
解決
4. トレーサ解析
解決
-g 付きで
コンパイル済み?
Y
Y
-g 付けてリビルド※
※ configure ス ク リ プ ト や
Makefile の修正が必要な
場合が多い。
5. プロファイル解析
6. デバッガ解析
解決
解決
再準備
再現待ち
図 2.2-3 スローダウンの障害解析フロー
- 2-8 -
解析終了
2.2.4 フリーズ
システムがフリーズした場合、次のような手順で解析を行う。
(1) コンソールからのコマンド入力が可能であるかを調べる。
コマンドにより、システム状態を解析し、対応を行う。→ 「スローダウン」対応
(2) コマンドの応答がない場合、または、異常が解消されない場合、
SysRqキーか、NMIインターフェースより、ダンプ採取を行う。
(3) 採取したダンプより、ダンプ解析ツールを使用して解析を行う。
次のような観点でダンプ解析を行う。
(a)CPU使用率の高いプロセスがあるかを調べる。ある場合は、そのプロセスがどのよう
な処理を行っているかを調べる。
(b)システムの資源(メモリ、スレッド等)が枯渇していないかを調べる。枯渇している
場合は、どのプロセスが浪費しているか、そのプロセスが異常な処理を行っていない
かを調べる。
(c)Run queueにキューされているプロセスが異常に多くないかを調べる。
(d)I/O Request queue に異常に多くの I/O 要求がキューされていないかを調べる。
(e)ロックをかけたままのプロセスの処理に誤りはないか、ロック開放待ちのプロセスが
異常な処理を行っていないかを調べる。
(f)停止しているプロセスの処理が正しいか、フラグのクリアミスでクリア待ちのままと
なっていないかを調べる。
(g)ハードウェアに異常があるようなメッセージがログされていないかを調べる。
(h)カーネルプロセスの処理が異常に多くないかを調べる。
表 2.2-4
(スワップ処理等)
フリーズの障害解析手法
#
手法名称
手法概要
1
類似障害検索
Red Hat 社の Bugzilla
(https://bugzilla.redhat.com/bugzilla/)
を代表とするインターネット上のサイトや社内の障害事例デ
ータベース等を検索し、同様な障害が報告されていないかを確
認する。
2
ダンプ解析
障害時に採取したダンプの解析を行うことで、障害箇所を特定
する。
3
ログ解析
障害時のアプリケーションログやシステムログに詳細な記録
が取れていた場合、それぞれのケースで固有の方法により解析
することで障害箇所を特定する。
4
環境変更試行
アプリケーションの版を変えたり、CPU/ディスク/メモリ
等の条件を変えてみて、同様の現象が起こるか確認する
- 2-9 -
解析開始
解決
1. 類似障害検索
コンソール
入力に応答
があるか?
Y
スローダウン
障害解析手順へ
N
N
SysRq キー
入力可?
Y
2. ダンプ解析
解決
3. ログ解析
解決
4 最新版試行
解決
再準備
再現待ち
図 2.2-4
フリーズの障害解析フロー
- 2-10 -
解析終了
2.2.5 カーネルパニック
カーネルパニックの場合、次のような手順で解析を行う。
(1) カーネルパニックのダンプが採取されているかを調べる。
カーネルパニックのダンプが採取されていない場合、コンソールに出力されたパニック
メッセージ、ログファイルから解析を行う。
(2) 採取されたダンプから、ダンプ解析ツールを使用して解析を行う。
(3) カーネルが停止したエラーの種類が何であるかを調べる。
(4) カーネルが停止したアドレスがどこであるかを調べる。
(5) カーネルソースコードより、停止したアドレスでどのような処理を行っていたかを解析
する。ソースコードとダンプのデータを照合しながら、ロジック追求を行う。
表 2.2-5
カーネルパニックの障害解析手法
#
手法名称
手法概要
1
類似障害検索
Red Hat 社の Bugzilla
(https://bugzilla.redhat.com/bugzilla/)
を代表とするインターネット上のサイトや社内の障害事例デ
ータベース等を検索し、同様な障害が報告されていないかを確
認する。
2
ダンプ解析
採取したダンプの解析を行う。
3
ログ解析
障害時のアプリケーションログやシステムログに詳細な記録
が取れていた場合、それぞれのケースで固有の方法により解析
することで障害箇所を特定する。
4
環境変更試行
アプリケーションの版を変えたり、CPU/ディスク/メモリ
等の条件を変えてみて、同様の現象が起こるか確認する
- 2-11 -
解析開始
1. 類似障害検索
N
解決
ダンプ採取
されたか?
Y
2. ダンプ解析
解決
3. ログ解析
解決
4 最新版試行
解決
再準備
再現待ち
図 2.2-5
解析終了
カーネルパニックの障害解析フロー
- 2-12 -
2.2.6 ネットワーク障害
ネットワーク障害発生時の対処法のフローとして以下のような手順を提案する。
NIC カード毎に IP アドレスが割り振られている環境、もしくはネットワーク冗長化され
た環境において、ネットワーク障害発生時の対処法のフローとして以下のような手順を奨
める。
開始
障害発生通知
1
1. pingテスト
(IPアドレス)
N
Y
2
2.pingテスト
(FQDN)
8.ifconfigにて
設定確認
N
Y
N
Y
6.参照DNSの
設定確認
4. netstat,
traceroute等
による確認
9.ethtoolにて
稼動確認
N
Y
12.ネットワーク
設定変更
N
Y
N
Y
7. 管理者
へ再問合せ
10.管理者へ
再問合せ
N
Y
Y
7.参照DNSの
設定変更
5.管理者へ問合せ
終了
2
N
2
2
11.物理的構成確認
1
図 2.2-6 ネットワーク解析フローチャート
- 2-13 -
1
1
1. 疎通テスト-ping-(ip アドレス)
この段階では、ping による ip アドレスを使用した疎通検証のみを行う。しかし、対 PC
だけではなくて、必要に応じて、ネットワークルータ等に対して疎通検証を行なう。
2. 疎通テスト-ping-(FQDN)
この段階では、IP アドレスを使用した疎通テストは終了している為、DNS サーバを介し
た名前解決が出来ることを確認する為に、ping を使用して疎通検証を行なう。必要に応じ
て、ネットワークルータ等に対して疎通検証を行なう。
3. netstat,traceroute による確認
netstat,traceroute によるネットワーク状態や、ルートの確認を行なう。
4. 管理者への問合せ
netstat,traceroute 等による確認を行なったが反応がない場合、ネットワーク管理者へ問
合せをする。
5. 参照 DNS の設定確認
/etc/resolv.conf,nslookup による参照 DNS サーバの確認を行なう。
6. 参照 DNS が正しいか管理者へ確認
通知された設定内容が正しいものかを確認するために、ネットワーク管理者へ問合せを
行なう。
7. 参照 DNS の設定変更
参照 DNS サーバの設定/変更を行なう。変更した後、再度、名前解決したことを確認す
る。
8. ネットワーク設定確認
ifconfig コマンドを使用したネットワークインターフェースの稼動状態確認を行なう。
9. インターフェース稼動確認
Ethtool を使用したネットワークインターフェースの稼動状態確認を行なう。確認項目は、
*Link detected:”(最終行)が”Yes”であれば、管理者への問合せを行い、”No”であれば、、
物理構成確認を行なう。
10. 管理者への構築環境の再問合せ
何が違っているのか判断できないので、再度、ネットワーク管理者へ問合せし、ip アド
レス、サブネットマスクなどの情報を確認する
11. 物理構成確認
物理的な障害が発生していると判断される。設定の問題ではなく、物理的に接続できて
いないと判断されるため、使用しているネットワーク構成を物理的な見解で見直す必要が
ある。もしくは、敷設されているネットワークが使用可能状態であるかも管理者に対して
確認する。
12. ネットワーク設定変更
入力ミスなどの問題による設定不良と思われる為、設定の変更、追加を行なう。
- 2-14 -
2.2.7 ディスク障害
ディスク障害時の対処方法切り分けについて述べる。以下の図は、ディスク障害が発生
した時の対処フローチャートである。
開始
障害発生通知
1.状況確認
(ログの確認)
N
Y
2.状況確認
3.shutdown
N
8.強制
Power Off
Y
Y
N
10. ディスク検出
確認
N
9.電源ON
Y
4.復旧の実施
N
11.復旧の実施
N
Y
Y
5.復旧確認
N
12.復旧確認
N
Y
Y
6.復旧
6.復旧
7.ディスク交換
終了
図 2.2-7 解析フローチャート
- 2-15 -
7.ディスク交換
1. syslog の確認が出来る状況にあるか確認する。
2. syslog に記録されている内容を確認し、どのようなディスク障害が発生しているか確認
する。
3. システムを停止し、fsck が行なえる状態にする。
4. fsck によるディスク復旧を行なう。
5. 復旧確認を行なう。この場合、システムを reboot させ障害発生したボリュームがマウ
ントできるか等を行なう。
6. 障害が発生したボリュームがマウントできていれば、復旧したものとする。
7. fsck による復旧の失敗、fsck の検証はパスしたがマウントできなかったことから、ディ
スク故障と判断し新品ディスクに交換する。
8. システムがハングアップしている状態であり、全ての操作が出来ないことから、強制的
に電源 OFF する。
9. 電源 ON し、fsck が出来る状態にする。
10. BIOS もしくは、dmesg によるディスクの検出ができているか確認する。
11. Rescue モードによる復旧(fsck)を実施する。
12. 復旧確認を行なう。この場合、システムをリブートさせ障害発生したボリュームがマウ
ントできるか等を行なう。
- 2-16 -
2.3 エラーメッセージ関連
2.3.1 スレッド生成不可(man ページにないエラー)が発生する障害の解析
アプリケーションのパラメータ設定によりスレッド生成数を増やすと、man ページに記
述のないスレッド生成エラーが表示される障害に関して、解析と対策を以下に報告する。
2.3.1.1 概要
本障害とその対策の概要を 表 2.3-1 に示す。
表 2.3-1
高負荷時アプリケーション異常終了の概要
番号
2.3.1
現象
パラメータ設定によりスレッド生成数を増やすと man ページにないス
発生日
2005/xx/xx
解決日
2005/xx/xx
レッド生成エラーが表示される
分類
エラーメッセージ関連
発生環境
OS
Fedora Core 3
CPU
Xeon 2.4GHz×1
メモリ
2GByte
ハードディスク
IDE 120GByte
ネットワーク
Intel 82545EM Gigabit Ethernet
原因
メモリ不足によるスレッド生成の失敗
対策
スレッドが使用するスタック領域の縮小(縮小して問題ないかどうか
は、アプリに依存する)
解析手法
ltrace による解析~man 確認、ヘッダファイル解析によるエラーコー
ドの確認~strace による解析
2.3.1.2 障害情報収集と初期切り分け
エラーメッセージ関連の障害発生時はまず、エラーメッセージをメモする等して記録し
ておく。また、どのような操作を行った場合にその障害が発生したかを記録しておく。
初期切り分けでは、エラーメッセージから障害原因が特定できないかを判断する。また
Web 上でエラーメッセージを検索する等して同様な障害報告がないかを確認する。
本事例では、エラーメッセージから障害の内容は確認できるのだが、何故その障害が発
生するのか、どう対策すれば良いかが分からなかった。このため、障害解析環境で再現さ
せて解析を行う。
2.3.1.3 再現手段の確立
まず、現象が再現するかどうかを確認する。再現手順は、以下の通り。
- 2-17 -
a. アプリケーションをスレッドパラメータ付きで起動する。この場合のパラメータ値は、
障害情報収集で取得した操作内容と同じものを使用する。本事例では 400 スレッドでエ
ラーメッセージ「pthread_create failed (id: 380)」が出力されるとのことだった。
$ thread_app
--thread=400
b. エラーメッセージが出力されることを確認する。
c. エラーメッセージが出力されたら、Ctrl+C 等によってアプリケーションを終了する。
上記手順により、障害が再現することを確認する。
2.3.1.4 解析
(1) ltrace による解析
障害が再現できたので、次のステップとして障害箇所の切り分けを行うため、システム
コール/ライブラリコールをトレースする。まずライブラリコールトレーサを用い、更に
システムコールレベルの詳細な情報が必要な場合にシステムコールトレーサを使う。ライ
ブラリコールトレーサ ltrace 経由でアプリケーションを起動して障害を再現する手順は、
以下の通り。
a. ltrace 経由でアプリケーション起動し、エラーメッセージが出力されるのを待つ
$ ltrace -f -o ltrace.log
thread_app
--thread=400
b. エラーメッセージが出力されたら、Ctrl+C 等によって ltrace を終了する。
トレース結果を確認する際には、まずエラーを返しているシステム/ライブラリコール
に着目して、当たりをつける。また障害箇所が特定できる場合は、そこから遡って見て行
き、障害の原因となるシステム/ライブラリコールを特定できるかどうかを確認する。
本事例では、エラーメッセージが出力されているため、そのメッセージを検索すれば良い。
ltraceのトレース結果を、図 2.3-1 に示す。
$ ltrace -f -o ltrace.log
thread_app
--thread=400
1. 出力エラーメッセージを検索
:(省略)
23865 pthread_create(0x804a5ec, 0, 0x8048520, 377, 0x6f9378) = 0
23865 pthread_create(0x804a5f0, 0, 0x8048520, 378, 0x6f9378) = 0
2. 直前の pthread_create
コールが失敗し 12 が返
っている
23865 pthread_create(0x804a5f4, 0, 0x8048520, 379, 0x6f9378) = 0
23865 pthread_create(0x804a5f8, 0, 0x8048520, 380, 0x6f9378) = 12
23865 printf("pthread_create failed (id: %d)\n", 380) = 32
3.
そ
の
前
の
pthread_create コ ー ル
は成功している
23865 pthread_join(0xb7fefbb0, 0, 0x8048520, 380, 0x6f9378 <unfinished ...>
23865 --- SIGINT (Interrupt) ---
図 2.3-1
エラーメッセージ出力付近の ltrace 結果
- 2-18 -
エラーメッセージ出力前の pthread_create 関数が 12 を返しており、その前までの
pthread_create は 0 を返している。
(2) man 確認、ヘッダファイル解析によるエラーコードの確認
man で確認すると、pthread_create は正常時は 0 を返すことが分かるので、12 を返して
いる pthread_create は何らかの要因で失敗したことが分かる。
次にエラーコード 12 の意味を調べる。man ページには pthread_create の返すエラーコ
ードが EXXX の形式で記述されているが、数値は記述されていないため、標準ヘッダファ
イル(/usr/include/asm/errno.h)を参照する。
$ cat /usr/include/asm/errno.h
:(省略)
#define ECHILD
10
/* No child processes */
#define EAGAIN
11
/* Try again */
#define ENOMEM
12
/* Out of memory */
#define EACCES
13
/* Permission denied */
:(省略)
図 2.3-2
エラーコード番号 12 の定義(定義ファイルの抜粋)
図 2.3-2 より、エラーの意味は「メモリ不足」だったことが分かるが、pthread_createの
manページにはENOMEMに関する記述はなく、どのような場合にメモリ不足エラーになる
のかが不明である。
(3) strace による解析
より詳細な解析を行うため、strace で再度トレースを行う。システムコールトレーサ
strace 経由でアプリケーションを起動して障害を再現する手順は、以下の通り。
a. strace 経由でアプリケーション起動し、エラーメッセージが出力されるのを待つ
$ strace -f -o strace.log
thread_app
--thread=400
b. エラーメッセージが出力されたら、Ctrl+C 等によって strace を終了する。
straceのトレース結果を 図 2.3-3 に示す。
- 2-19 -
$ strace -f -o strace.log
thread_app
--thread=400
1. 出力エラーメッセージを検索
:(省略)
24252 mmap2(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0
<unfinished ...>
24630 futex(0x6f97ac, FUTEX_WAIT, 2, NULL <unfinished ...>
24252 <... mmap2 resumed> )
= 0xbe7ff000
24252 mprotect(0xbe7ff000, 4096, PROT_NONE) = 0
2. エ ラ ー メ ッ セ ー ジ 出 力 直 前 の
mmap2 コールが ENOMEM を返し
ている
24252 clone(child_stack=0xbefff4c8, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND
3. エラーを返す mmap2 コールの前
は、mmap2, futex, mprotect, clone
NE_DETACHED,
parent_tidptr=0xbefffbf8,
{entry_number:6, コールが繰り返されており、この4
base_addr:0xbefffbb0,
つ の シ ス テ ム コ ー ル が
limit:1048575,
seg_32bit:1,
contents:0,
read_exec_only:0,
limit_in_pages:1,
pthread_create
に対応すると考えら
れる
seg_not_present:0, useable:1}, child_tidptr=0xbefffbf8) = 24631
|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID|CLO
24252 mmap2(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0
<unfinished ...>
4. ENOMEM になる前の mmap2 コ
ー ル で は 、 毎 回 8,392,704 ( 約
24252 <... mmap2 resumed> )
= 0xbf000000
8MByte)のメモリを確保しており、
最後に成功した mmap2 コールでは
24252 mprotect(0xbf000000, 4096, PROT_NONE) = 0
0xbf000000 のポインタ値が返って
24252 clone(child_stack=0xbf8004c8, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND
いる
24631 futex(0x6f97ac, FUTEX_WAIT, 2, NULL <unfinished ...>
|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID|CLO
NE_DETACHED,
parent_tidptr=0xbf800bf8,
limit:1048575,
seg_32bit:1,
contents:0,
{entry_number:6,
base_addr:0xbf800bb0,
read_exec_only:0,
limit_in_pages:1,
seg_not_present:0, useable:1}, child_tidptr=0xbf800bf8) = 24632
24252 mmap2(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0
<unfinished ...>
24632 futex(0x6f97ac, FUTEX_WAIT, 2, NULL <unfinished ...>
24252 <... mmap2 resumed> )
= -1 ENOMEM (Cannot allocate memory)
24252 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
24252 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0x868f000
24252 write(1, "pthread_create failed (id: 380)\n", 32) = 32
24252 futex(0xb7fefbf8, FUTEX_WAIT, 24253, NULL) = -1 EINTR (Interrupted system call)
24252 --- SIGINT (Interrupt) @ 0 (0) ---
図 2.3-3
エラーメッセージ出力付近の strace 結果
Linux では、各スレッドのメモリ領域は親プロセスの空間を共有する。また、IA-32 アー
キテクチャの場合、各プロセスで使用できるメモリ空間は 3GByte であり、その後ろの
1GByte はカーネル空間となっている(カーネル空間の先頭は 0xC0000000)。
注)ただし、Red Hat 系のカーネル(Fedora Core 3 も含む)で、カーネルオプション
CONFIG_X86_4G が有効になっている場合は、
プロセス空間が 4GByte までに拡張される。
- 2-20 -
図 2.3-3 から、スレッド生成に伴うメモリ確保であるmmapの返り値が約 8MByte毎に増
えてゆき、カーネル空間付近のポインタ値 0xbf000000 を返していることから、プロセス空
間を使い切ってしまったことが分かる。また、表示されたエラーメッセージ「pthread_create
failed (id: 380)」からスレッド数を 380 と仮定しメモリ使用量を算出すると、380×
8,392,704≒3GByteとなり、プロセス空間を使い切るだけのメモリを確保していることが推
測できる。
また、各スレッドのスタックサイズは ulimit で制限されるプロセススタックサイズと同
じである(ただし、これは使用している pthread ライブラリおよびそのコンパイル条件に
依存する)ため、ulimit コマンドでスタックサイズ値を確認する。
$ ulimit -s
8192(8MByte)であり、メモリ確保値と
合致する
8192
この結果、スレッド毎のメモリ確保容量≒スタックサイズであることも確認できる。
2.3.1.5 対策
対策案としては、スレッド毎のメモリ確保容量を少なくすることが考えられる。このた
めには、各スレッドが使用するスタック領域を縮小すれば良い。ただし、以下の点に注意
する必要がある。
(1) どの程度のスタック領域でアプリケーションが正常に動くのかは、アプリケーションに
依存する
(2) 使用している pthread ライブラリおよびそのコンパイル条件により、スレッドのスタッ
ク領域を変更できない場合がある
このような場合は、対策が可能であることを確認し、その対策によって障害が解消され
ることを確認した後で、更に評価環境で運用評価を行う必要がある。
スレッドのスタック領域を変更する手順は、以下の通り。
a. ulimit コマンドでスタック領域を変更する(下記では、2MByte に縮小)
$ ulimit -s 2048
b. ulimit コマンドを実行したシェル上でアプリケーションを起動する
$ thread_app
--thread=400
上記対策によってエラーメッセージが出力されなくなることを確認し、運用評価を行っ
た後に本対策とした。
- 2-21 -
2.3.1.6 付録~再現用アプリケーションのソースコード
本事例を再現させるためのアプリケーション(thread_app)のソースコードは、下記の
通り。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *loop(void *tindex)
{
int
i, timer = 3;
for (;;) fgetc(stdin);
}
int main(int argc, char *argv[])
{
int
tnum, i;
pthread_t *t;
char
*opt_head = "--thread=";
if (argc != 2 ||
strstr(argv[1], opt_head) == NULL ||
strlen(argv[1]) <= strlen(opt_head)) {
printf("app %sN\n", opt_head);
exit(1);
}
tnum = atoi(argv[1] + strlen(opt_head));
t = calloc(tnum, sizeof(pthread_t));
/* create tnum threads */
for (i = 0; i < tnum; i++) {
if (pthread_create(&t[i], NULL, loop, (void*)i)) {
printf("pthread_create failed (id: %d)\n", i);
tnum = i - 1;
break;
}
}
- 2-22 -
/* wait terminate tnum threads */
for (i = 0; i < tnum; i++) {
pthread_join(t[i], NULL);
}
exit(0);
}
- 2-23 -
2.4 アプリケーション異常終了
2.4.1 高負荷時にアプリケーションが異常終了する障害の解析(コアダンプな
し)
通常の負荷だと問題なく動作するアプリケーションが、メモリ高負荷な状況下では異常
終了する障害に関して、解析と対策を以下に報告する。
2.4.1.1 概要
本障害とその対策の概要を 表 2.4-1 に示す。
表 2.4-1
高負荷時アプリケーション異常終了の概要
番号
2.4.1
現象
通常負荷時は問題なく動作するアプリケーションが、メモリ負荷が高く
発生日
2005/xx/xx
解決日
2005/xx/xx
なると異常終了してしまう
分類
アプリケーション異常終了
発生環境
OS
Fedora Core 3
CPU
Xeon 2.4GHz×1
メモリ
2GByte
ハードディスク
IDE 120GByte
ネットワーク
Intel 82545EM Gigabit Ethernet
原因
メモリ確保後のポインタ値確認処理抜け(アプリケーションのバグ)
対策
メモリ確保後のポインタ値確認処理を追加
解析手法
ltrace による解析~ソースコードの解析
2.4.1.2 障害情報収集と初期切り分け
アプリケーション異常終了の障害発生時はまず、エラーメッセージが出ているか確認し、
出ていればメモする等して記録しておく。また、どのような操作を行った場合に、その障
害が発生したかを記録しておく。
設定によってはコアダンプファイルが出力される場合があるので、出力されていれば別デ
ィスクに保存しておく。
エラーメッセージが出力されている場合、その文字列の意味から障害原因が特定できな
いかを判断する。また Web 上でエラーメッセージを検索する等して同様な障害報告がない
かを確認する。
本事例では、エラーメッセージ、コアダンプファイル共に出力されていなかったため、
両者からの解析を行うことができなかった。このため、障害解析環境で再現させて解析を
行う。
- 2-24 -
2.4.1.3 再現手段の確立
まず、現象が再現するかどうかを確認する。再現手順は、以下の通り。
a. 高負荷状況作成ツール stress によりメモリ高負荷状況を再現する際に、stress 自身が kill
されないようにするため、メモリのオーバーコミットを禁止する設定を行う(スーパー
ユーザで行う必要あり)
# echo 2 > /proc/sys/vm/overcommit_memory
b. stress によって、メモリ負荷が高い状況を再現する
メモリ負荷の設定は再現環境マシンのメモリ/スワップ容量および、そこで稼働中のプ
ロセスでのメモリ使用状況に依存する。障害発生時のメモリ負荷情報が記録されている
場合はその負荷となるように stress のパラメータを設定し、記録されていない場合は
80%程度の適当な数値から始めて、再現するまで負荷を高くして行く。
本事例では、再現環境マシンのメモリが 2GByte、スワップが 14GByte で計 16GByte
であり、再現せるために約 92%程度のメモリ負荷(16GByte×92%≒23×640MByte)
が必要だった。
$ stress -m 23 --vm-bytes 640M --vm-hang --timeout 180s
※--vm-hang は、一度確保したメモリを stress 終了まで解放しない指定
c. /proc/meminfo や top 等により、メモリ使用状況を確認し、負荷が上がるのを待つ
d. アプリケーションを起動し、異常終了するのを待つ
上記手順により、障害が再現することを確認する。
2.4.1.4 解析
(1) ltrace による解析
障害が再現できたので、次のステップとして障害箇所の切り分けを行うため、システム
コール/ライブラリコールをトレースする。まずライブラリコールトレーサを用い、更に
システムコールレベルの詳細な情報が必要な場合にシステムコールトレーサを使う。ライ
ブラリコールトレーサ ltrace 経由でアプリケーションを起動して障害を再現する手順は、
以下の通り。
a.~c. 前述の手順と同様
d. ltrace 経由でアプリケーション起動し、異常終了するのを待つ
$ ltrace -f -o ltrace.log アプリケーション名
トレース結果を確認する際には、まずエラーを返しているシステム/ライブラリコール
に着目して、当たりをつける。また障害箇所が特定できる場合は、そこから遡って見て行
き、障害の原因となるシステム/ライブラリコールを特定できるかどうかを確認する。
- 2-25 -
ltraceのトレース結果を、図 2.4-1 に示す。
$ ltrace -f -o ltrace.log mem_app
1. セグメンテーションフォールトで異常終了したことが分かる
:(省略)
5421 sleep(1)
= 0
5421 malloc(10485760)
= 0x927b3008
5421 printf("%u\tmsg-out: %d\n", 59, 10485760)
2. 直前の malloc コールが失敗
し NULL が返っている
= 22
5421 sleep(1)
= 0
5421 malloc(10485760)
= NULL
3. その前の malloc コールは成
功している
5421 --- SIGSEGV (Segmentation fault) --5421 +++ killed by SIGSEGV +++
図 2.4-1
アプリケーション異常終了時の ltrace 結果
トレース結果の最後にはセグメンテーションフォールトで異常終了したことが出力され
ており、その直前に malloc が NULL を返し失敗したことが分かる。しかし、その前の malloc
は成功しているため、最後の malloc 付近で障害が発生したことが分かる。
(2) ソースコードの解析
次にアプリケーションのソースコードを入手し、mallocを実行しているコードを確認し
た所、図 2.4-2 のように2箇所でmallocを行っている部分が見つかった。
:(省略)
1. malloc 実行箇所その1
p = malloc(SIZE);
for (i = 0; i < SIZE; i++)
p[i] = 'a';
2. malloc 実行箇所その2
:(省略)
p = malloc(MAX_BUF_SIZE);
for (writes = 0; writes < MAX_BUF_SIZE; writes += cnt) {
cnt = read(f, buf, size);
if (cnt == 0)
return 1;
else if (cnt < 0)
return 0;
memcpy(p + writes, buf, cnt);
}
:(省略)
図 2.4-2
アプリケーションソース(malloc 実行箇所)
- 2-26 -
どちらの malloc が問題になっているのかを明らかにするため、ライブラリコールの引き数
値や前後のライブラリコールの流れをトレース結果と比較することで、切り分けを行う。
本事例では、引き数が異なっており、SIZE と MAX_BUF_SIZE を確認した所、問題とな
っている malloc は前者の方だということが分かった。
前者の malloc 周辺をよく見ると、メモリ確保が失敗した場合でもそのまま NULL ポイン
タに書き込みを行ってしまうことが分かる。よって、通常メモリが確保できる状況下では
問題なく動作するが、メモリ高負荷状況ではメモリ確保に失敗し、NULL ポインタ書き込
みによりセグメンテーションフォールトが発生することが分かる。
メモリ確保関数で NULL が返るようなメモリ高負荷状況下では、OOM killer が動作し、
カーネルの算出式によって決定される任意のプロセスが kill されてしまう可能性がある。
そこで稼働環境を確認した所、/proc/sys/vm/overcommit_memory の値は既に 2 に設定され
ており、オーバーコミットは禁止されていた(OOM killer は動作しない)ことが分かった。
2.4.1.5 対策
障害原因が処理抜けの場合、他にも同様に処理が抜けている箇所があることが予想され
る。よって、ソース全体を検索し同様の箇所がないか全て確認する必要がある。このため、
ソースを検索しメモリ確保(malloc, calloc)を使用している箇所で、返り値チェックが抜
けているものを洗い出し、返り値チェックを追加した。その後、再現させて異常終了しな
いことを確認した。
2.4.1.6 付録~再現用アプリケーションのソースコード
本事例を再現させるためのアプリケーション(mem_app)のソースコードは、下記の通
り。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define
SIZE
(10 * 1024 * 1024)
char *write_buf(void)
- 2-27 -
{
int
i;
char
*p;
p = malloc(SIZE);
for (i = 0; i < SIZE; i++)
p[i] = 'a';
return p;
}
int proc_open()
{
int
f;
f = open("/proc/kcore", O_CREAT|O_RDONLY);
return f;
}
int proc_read(int f)
{
int
cnt, writes, size = 128;
char
*p, buf[size];
if (f < 0)
return 0;
if (lseek(f, SIZE, SEEK_CUR) < 0)
return 0;
p = malloc(SIZE);
for (writes = 0; writes < SIZE; writes += cnt) {
cnt = read(f, buf, size);
if (cnt == 0)
return 1;
else if (cnt < 0)
return 0;
memcpy(p + writes, buf, cnt);
}
return 1;
}
- 2-28 -
int main_loop(void)
{
unsigned int
n;
char
*p;
int
f = -1;
for (n = 0;; n++) {
if (n < 4096)
p = write_buf();
else if (n == 4096)
f = proc_open();
else if (n == 4097)
proc_read(f);
else if (n == 4098) {
if (f >= 0)
close(f);
}
printf("%u\tmalloced: %d\n", n, SIZE);
sleep(1);
}
return 1;
}
int main(int argc, char *argv[])
{
main_loop();
exit(0);
}
- 2-29 -
2.4.2 高負荷時にアプリケーションが異常終了する障害の解析(コアダンプあ
り)
前節(2.4.1)と同じ障害(高負荷時にアプリケーションが異常終了)が発生した際にコ
アダンプが取れていた場合、障害解析がどのように異なるかを、以下に報告する。
2.4.2.1 概要
表 2.4-1 を参照のこと。
2.4.2.2 障害情報収集と初期切り分け
本事例ではコアダンプが取れていたため、再現手段の確立を飛ばして、コアダンプ情報
を元にした障害解析作業を行う。
2.4.2.3 解析
(1) gdb による解析
コアダンプが取れていた場合、デバッガ gdb を用いることで、どういった関数呼び出し
順の中のどの関数で障害が発生したか、即座に解析可能である。アプリケーションのコン
パイル時に-g オプション付きで gcc でコンパイル済みであれば、更にその関数内のどのス
テップで障害が発生したか、関数の引き数値は何だったかまで、解析可能である。
本事例では、アプリケーションは-g オプション付きで gcc でコンパイル済みであった。
gdb での障害箇所特定の手順を以下に示す。
a. gdb を起動し、障害発生関数を確認する
$ gdb mem_app core.5421
:(省略)
1. アプリケーション名とコア
ファイル名を指定して、gdb
を起動
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0
0x08048537 in write_buf () at mem_app.c:18
18
p[i] = 'a';
2. write_buf 関数内で障害発生
したことが分かる
3. -g 付きでコンパイルしていれ
ば、更にソースファイル名や
行番号、引き数の値も分かる
(これ以降の斜め文字部分)
(gdb)
b. gdb の where コマンドで、どういった関数呼び出し順の中で障害が発生したかを確認す
る
(gdb) where
#0
0x08048537 in write_buf () at mem_app.c:18
#1
0x08048683 in main_loop () at mem_app.c:60
#2
0x08048721 in main (argc=3, argv=0xbffffa64) at mem_app.c:77
- 2-30 -
main → main_loop → write_buf
の順で呼び出した際に、
write_buf 関数中で障害発生し
たことが分かる
c. gdb の l コマンドで、障害発生付近のソースを確認する(-g オプション付き時のみ有効)
(gdb) l
13
int
i;
14
char
*p;
gdb 起動時に表示された行番号
の部分に着目する。障害はこの
行で発生している
15
16
p = malloc(SIZE);
17
for (i = 0; i < SIZE; i++)
18
p[i] = 'a';
19
20
return p;
21
}
22
(gdb)
以上により、gdbによる解析だけで障害発生箇所が特定でき、更にソースまで確認できる。
コアダンプが残っていない前節(2.4.1)での障害解析と比較すると、再現手段の確立~障
害箇所の特定までのステップが、たったこれだけの作業で置換できることが分かる(表
2.4-2 参照)。障害によっては再現が難しい場合も多々あることも考慮すると、障害解析作
業の簡略化のためには、アプリケーションコンパイル時の-gオプションとコアダンプの設定
が重要である。
表 2.4-2
項
事前準備の違いによる障害解析ステップの違い
障害解析ステップ
番
解析難易度
コアダンプ設
コアダンプ設定
コアダンプ設定
定なし時
あり時
と-g オプション
あり時
1
再現手段の確立
高
低
低
2
障害箇所の特定
高
中
低
3
障害原因の究明
中
中
中
2.4.2.4 対策
2.4.1.5 を参照のこと。
- 2-31 -
2.4.3 高負荷時にアプリケーションが Out of Memory で強制終了された障害の
解析(コアダンプなし)
通常の負荷だと問題なく動作するアプリケーションが、メモリ高負荷な状況下では強制
終了する障害に関して、解析と対策を以下に報告する。
2.4.3.1 概要
本障害とその対策の概要を 表 2.4-3 に示す。
表 2.4-3
高負荷時アプリケーション異常終了の概要
番号
2.4.3
現象
通常負荷時は問題なく動作するアプリケーションが、Out of Memory
発生日
2005/xx/xx
解決日
2005/xx/xx
で強制終了してしまう
分類
アプリケーション強制終了
発生環境
OS
MIRACLE LINUX V4.0 beta
CPU
Xeon 2.0 * 2
メモリ
6GByte
ハードディスク
SCSI 72GByte
ネットワーク
Intel 82545EM Gigabit Ethernet
原因
i2o ドライバの不具合
対策
カーネルバージョンアップ
2.4.3.2 障害情報収集と初期切り分け
Iozone で高負荷をかけると、Out of memory (OOM) killer が走りアプリケーションが強制
終了されてしまう。
/var/log/messages 等には OOM killer によって強制終了されたプロセスの情報等がある。
エラーメッセージが出力されている場合、その文字列の意味から障害原因が特定できな
いかを判断する。また Web 上でエラーメッセージを検索する等して同様な障害報告がない
かを確認する。
2.4.3.3 再現手段の確立
まず、現象が再現するかどうかを確認する。再現手順は、以下の通り。
a. Iozone を流し高負荷状態にする。
上記手順により、障害が再現することを確認する。
2.4.3.4 解析
今回の場合は常に再現した。環境を確認してみると i2o ドライバを必要とする場合、当該障
害が発生することがわかった。
- 2-32 -
インターネット等(Red Hat の bugzilla および Linux Kernel Mailing List(LKML))で検索
してみると i2o ドライバが 2.6 カーネルで大幅に変更されていることが分かった。LKML
で質問したところ、最新版にバージョンアップして再現をすることを薦められた。
そこで、最新版のカーネルで再現実験をおこなったところ、OOM killer による強制終了は
発生しなかった。
2.4.3.5 対策
カーネルのバージョンアップ。
- 2-33 -
2.5 スローダウン
2.5.1 パフォーマンス監視ツールの障害解析
本節では、パフォーマンス監視ツールのスローダウン現象を取り上げ、その概要と再現
手順、主に LKST を用いた障害解析手順を示す。また、最後に本障害解析手法に対する留
意点を述べる。
2.5.1.1 障害の概要
事例として取り上げる障害の概要を以下の 表 2.5-1 に示す。
表 2.5-1 パフォーマンス監視ツール障害の概要
番号
現象
2.5.1
2005/xx/xx
発生日
解決日
2005/xx/xx
高負荷時、sar/iostat/mpstat コマンドによる統計情報取得の時間間隔
が指定した値にならない
分類
スローダウン
発生環境
OS
MIRACLE LINUX V4.0 beta
CPU
Intel Pentium Ⅲ 1.26GHz ×1
メモリ
1GB
ハードディスク
Ultra3 SCSI
ネットワーク
Intel Corp. 82544EI Gigabit Ethernet
36GB ×1
Controller
原因
ファイルシステムのコミット待ち
プロセス数増加に伴う実行権待ち
対策
出力データを tmpfs 上のファイルに保存する
nice コマンドによる優先度の変更
ファイルリダイレクトの利用(sar のみ)
解析手法
カーネル内部トレースによる遅延要因の特定
Linuxシステムにはsar、iostatおよびmpstatという、一定間隔ごとにシステムの統計情
報(CPU利用率、ディスク読込み/書込み量など)を取得するコマンドがある。ただし、高い
負荷を掛けた状態においては、以下の 図 2.5-1 ように統計情報が指定した時間間隔で採取
できないという問題が発生する場合がある。
# sar -A -o sar.dat 5 600
5 秒間隔でデータを取得する
# sar -u -f sar.dat
Linux 2.6.9-5.25AX (TAMA09)
21:29:47
CPU
%user
08/10/05
%nice
%system
- 2-34 -
%iowait
%idle
21:29:52
all
0.00
0.00
0.20
0.40
99.40
21:29:57
all
0.00
0.00
0.00
0.60
99.40
21:30:02
all
12.25
0.00
83.73
4.02
0.00
時間間隔が
21:30:16
all
1.00
0.00
40.03
58.97
0.00
指定した 5 秒
21:30:50
all
0.83
0.00
34.29
64.88
0.00
ではない
21:31:08
all
1.12
0.00
46.76
52.12
0.00
21:31:30
all
0.59
0.00
25.23
74.18
0.00
21:31:58
all
1.15
0.00
46.31
52.54
0.00
21:32:17
all
0.61
0.00
49.04
50.35
0.00
21:32:22
all
0.80
0.00
99.20
0.00
0.00
21:32:27
all
1.00
0.00
99.00
0.00
0.00
21:32:32
all
0.60
0.00
99.40
0.00
0.00
21:32:37
all
0.60
0.00
99.40
0.00
0.00
図 2.5-1 パフォーマンス監視ツールの障害発生の様子
2.5.1.2 障害の再現
障害を解析するにあたり、まず同様の障害を再現させる。障害の再現を検証した環境を 表
2.5-2 に示す。
表 2.5-2 障害再現・解析環境
ハードウェア
CPU
Intel Pentium III 1.26GHz ×1
メモリ 1GB
ソフトウェア
HDD
Ultra3 SCSI
OS
MIRACLE LINUX V4.0 beta
LKST
2.3-3AX (rpm からインストール)
sysstat
36GB ×1
5.0.5-1.1AX(ディストリビューションに付属して
いる rpm からインストール)
IOzone 3.239(ソースからインストール)
Stress 0.18.2-1.rf(ソース RPM からインストール)
障害を再現する際、一般的には障害が発生したときと同じシステム構成/負荷状況で再
現させることが理想的だが、この障害は発覚時のシステム構成が不明であること、および
各種のアプリケーションで高負荷状態が発生したときに発生していることから、典型的な
高負荷状況を擬似的に生成し、障害再現を確認する。
本節で想定した負荷状況と使用した負荷生成ツールを以下の 表 2.5-3 に示す。
- 2-35 -
表 2.5-3 想定した負荷状況と負荷生成ツール
負荷状況
負荷生成ツール
詳細
“-c (プロセス数)”オプションで実行
CPU 負荷
(平方根の計算を繰り返す)
Stress
“-m 1 –vm-bytes (malloc メモリサイズ)”オプ
メモリ負荷
ションで実行
(malloc/free の実行を繰り返す)
“-CMR -i0 -+n -+u -s 500M
ディスク I/O 負荷
IOzone
-t 1 -f io1”オプシ
ョンで実行
(ディスクへの書込み/読み込み)
障害解析をおこなうスローダウン事例としては以下の 表 2.5-4 の 2 つのケースを取り上
げる。
表 2.5-4 障害現象の再現確認
測定ツール
負荷状況
ケース 1
sar
ディスク I/O 負荷
ケース 2
iostat
CPU 負荷
具体的な障害の再現確認手順を以下に述べる。上の 表 2.5-4 の各ケースに対して、以下
の手順でシステム統計情報を取得し、障害の再現確認を行う。
(1) パフォーマンス監視ツールによるモニタリング開始
(2) (1)から 10 秒後に負荷生成の開始
(3) (2)の負荷生成の終了から 10 秒後にモニタリング終了
(4) (1)から (3)の間に取得したモニタリングデータの確認
今回の測定では以上の (1)から (3)の手順を自動化したスクリプトを用いた。このスクリプ
トを 図 2.5-2 に示す。
#!/bin/bash
if [ $# != 3 ]; then
echo "Usage: ./load.sh <load_type> <nr of worker> <mon_type>" >& 2
exit 1
fi
load_type=$1
worker=$2
mon_type=$3
- 2-36 -
export LANG=C
DATE_ID=`date +%y%m%d_%H%M%S`
SAVE_DIR=${load_type}_${worker}_${mon_type}_${DATE_ID}
INTERVAL=5
COUNT=600
TIMEOUT=240
LOG_FILE=load.log
mkdir ${SAVE_DIR}
echo "Make Directory ${SAVE_DIR}" | tee -a ${LOG_FILE}
# Start Monitoring
(1)
echo "Monitoring Start at `date`" | tee -a ${LOG_FILE}
モニタリングの
if [ ${mon_type} = sar ]; then
開始
sar -A -o ${SAVE_DIR}/sar.dat ${INTERVAL} ${COUNT} &
elif [ ${mon_type} = iostat ]; then
iostat –t -x ${INTERVAL} ${COUNT} > ${SAVE_DIR}/iostat.dat &
else
mpstat -P ALL ${INTERVAL} ${COUNT} > ${SAVE_DIR}/mpstat.dat &
fi
sleep 10
# Start Load
echo "Load Start at `date`" | tee -a ${LOG_FILE}
(2)
if [ ${load_type} = cpu ]; then
負荷生成
stress -c ${worker} -t ${TIMEOUT}
elif [ ${load_type} = mem ]; then
stress -m ${worker} -t ${TIMEOUT}
else
iozone_wrap ${worker} 500
fi
echo "Load Finish at `date`" | tee -a ${LOG_FILE}
sleep 10
(3)
# Stop Monitoring
モニタリングの
if [ ${mon_type} = sar ]; then
終了
killall sar
- 2-37 -
killall sadc
elif [ ${mon_type} = iostat ]; then
killall iostat
else
killall mpstat
fi
echo "Monitoring Finish at `date`" | tee -a ${LOG_FILE}
図 2.5-2 障害再現に利用したスクリプト(load.sh)
また、load.shの中で使用している、IOzoneを呼出すスクリプトiozone_wrapを以下の 図
2.5-3 に示す。
#!/bin/bash
if [ $# != 2 ]; then
echo "Usage: ./iozone_wrap <worker> <file_size>" >&2
exit 1
fi
worker=$1
file_size=$2
TMP_DIR=~/tmp
num=0
while [ $num -lt ${worker} ]
do
iozone -CMR -i0 -+n -+u -s ${file_size}M
-t 1 \
-f ${TMP_DIR}/io${num} > /dev/null &
num=`expr ${num} + 1`
done
wait
図 2.5-3 iozone を呼出すスクリプト iozone_wrap
以下に、load.shスクリプトの内部処理の流れを 図 2.5-4 に示す。
- 2-38 -
(1)モニタリング開始
第3引数で与えられたコマンドを利用
(5秒間隔で600回データを取得)
10秒後
(2)負荷生成
第1引数で与えられた負荷タイプを
第2引数で与えられた負荷量で実行
・第1引数がcpuの場合は第2引数の数だけ平方根計算プロセスを起動
・第1引数がmemの場合は(第2引数)MBのメモリのmalloc/freeを繰返す
・第1引数がioの場合(第2引数)個のプロセスが500MBのファイルを書込む
10秒後
(3)モニタリング終了
(1)で開始したモニタリングを終了
図 2.5-4 load.sh の内部処理
以下の 表 2.5-5 にload.shが受け取る引数の仕様を示す。
表 2.5-5 load.sh の引数
引数
第1引数
説明
cpu/mem/io のいずれかを指定する
cpu : stress -c による CPU 負荷を発生させる
mem : stress -m によるメモリ負荷を発生させる
io : iozone によるディスク I/O 負荷を発生させる
第2引数
負荷を発生させるプロセスの数を指定する
第3引数
sar/iostat/mpstat を指定する
sar : sar でモニタリングする
iostat : iostat でモニタリングする
Mpstat : mpstat でモニタリングする
以下の 表 2.5-6 にload.shが生成する出力ファイルについて説明する(これらのファイル
は、load.shの実行ディレクトリに作成される)。
表 2.5-6 load.sh の出力ファイル
出力ファイル名
概要
(第 1 引数)_(第 2 引数)_(第 3 引数)_(実行時刻)/ パフォーマンス監視ツール(第 3 引数で指
(第 3 引数).dat
定)が取得したデータが保存される。
- 2-39 -
モニタリングツールのデータ保存ディレク
トリ、モニタリングツールの開始/終了時
刻、および負荷生成の開始/終了時刻が
このファイルに追記される
load.log
((実行時刻)には load.sh スクリプトを実行開始した時刻が(西暦2桁)(月2桁)(日2桁)_(時2
桁)(分2桁)(秒2桁)の形式で入る)
以上に示したスクリプトを用いて、再現確認を行う。
■ケース 1:ディスク I/O 高負荷時における sar のスローダウン事例の再現確認
まず、ディスク I/O 高負荷状態で sar の障害を再現させるために以下のコマンドで実行し、
統計情報を取得する。
# load.sh io 2 sar
モニタリング開始時刻
Make Directory io_2_sar_050913_103530
負荷生成開始時刻
Monitoring Start at Tue Sep 13 10:35:30 JST 2005
Load Start at Tue Sep 13 10:35:40 JST 2005
負荷生成終了時刻
Load Finish at Tue Sep 13 10:36:11 JST 2005
/root/bin/load.sh: line 57:
7007 Terminated
sar -A -o ${SAVE_DIR}/sar.dat
${INTERVAL} ${COUNT}
モニタリング終了時刻
Monitoring Finish at Tue Sep 13 10:36:21 JST 2005
図 2.5-5 ケース1の再現確認
上述の手順で取得したデータを以下の手順で確認する。
# cd io_2_sar_050913_103530/
# sar -u -f sar.dat
Linux 2.6.9-5.25AX (TAMA09)
09/13/05
10:35:30
CPU
%user
%nice
%system
%iowait
%idle
10:35:35
all
0.20
0.00
0.00
0.60
99.20
10:35:40
all
0.20
0.00
0.00
0.40
99.40
10:35:45
all
2.40
0.00
97.41
0.20
0.00
10:36:08
all
0.47
0.00
16.39
65.89
17.25
10:36:13
all
0.00
0.00
6.20
3.60
90.20
10:36:18
all
0.20
0.00
0.00
0.40
99.40
Average:
all
0.54
0.00
18.66
32.25
48.56
23 秒開いて
いる
図 2.5-6 ディスク I/O 高負荷時の sar の取得データ
ディスクに負荷をかけている間(10:35:40 から 10:36:11)の期間にデータ取得タイミング
が 23 秒と大きく遅延する様子が再現できている。よって、ディスク I/O 高負荷の環境で障
- 2-40 -
害が再現できた。
■ケース 2:CPU 高負荷時における iostat のスローダウン事例の再現確認
次に、CPU 高負荷状態において iostat の障害を再現させるために、以下のコマンドを実
行し、統計情報を取得する。
# load.sh cpu 1000 iostat
Make Directory cpu_1000_iostat_050917_142852
Monitoring Start at Sat Sep 17 14:28:52 JST 2005
Load Start at Sat Sep 17 14:29:02 JST 2005
stress: info: [4100] dispatching hogs: 1000 cpu, 0 io, 0 vm, 0 hdd
stress: info: [4100] successful run completed in 240s
Load Finish at Sat Sep 17 14:33:02 JST 2005
/root/bin/load.sh: line 57:
4095 Terminated
iostat –t -x ${INTERVAL}
${COUNT} >${SAVE_DIR}/iostat.dat
Monitoring Finish at Sat Sep 17 14:33:12 JST 2005
図 2.5-7 ケース2の再現確認
上述の手順で取得したデータを以下の手順で確認する。
# cd cpu_1000_iostat_050917_142852
# grep Time iostat.dat
Time: 14:28:52
時刻情報だけを抽出
Time: 14:28:57
Time: 14:29:02
11 秒または 6 秒の開きが発生
Time: 14:29:13
Time: 14:29:19
Time: 14:29:25
Time: 14:29:31
Time: 14:29:36
Time: 14:29:41
Time: 14:29:46
Time: 14:29:51
Time: 14:29:56
Time: 14:30:01
Time: 14:30:06
Time: 14:33:07
Time: 14:33:12
図 2.5-8 CPU 高負荷時の iostat のデータ取得タイミング
以上から、14:29:02 から 14:29:31 までの期間でデータ取得タイミングが指定した 5 秒に
- 2-41 -
ならない様子が再現できている。よって、CPU 高負荷の環境で障害が再現できた。
2.5.1.3 障害原因候補の洗い出し
障害の原因を解析するために、原因として考えられる現象およびそれらを洗い出す手順
を以下に示す。
本節で対象とする監視ツールはいずれも、一定時間間隔ごとに起動し処理(統計情報の取
得、ファイルへの書き出しなど)を行う「タイマ駆動型アプリケーション」である。タイマ
駆動型アプリケーションの Linux 内部での動きは以下のようになる。
(1) CPU 毎に定期的に発生するローカルタイマ割り込みがハードウェア割り込み
ハンドラを起動し、更にハードウェア割り込みハンドラがソフト割り込み要求
を発生させる
(2) ソフトウェア割り込みハンドラの中でタイマリスト処理を実行し起動時刻に達
したタイマのハンドラを呼び出す。ここで、Linux にはいくつかのタイマリス
トが存在するが、ある実時間が経過した際にプロセスを起床させるためには、
it_real_fn というタイマリストが利用される。it_real_fn は指定した時刻になる
と起床すべきプロセスに対して通知のシグナル(SIGALRM)を生成する
(3) タイマをセットしたプロセスはシグナル SIGALRM を受け取ると実行可能状
態(TASK_RUNNING)となりランキューに接続される
(4) スケジューラがそのプロセスに実行権を与えると、そのプロセスのシグナルハ
ンドラが起動される
上記の流れおよび処理内容(ファイルI/Oが発生すること)に基づいて、障害の原因として
考えられる箇所および原因内容を 表 2.5-7 に示す。
表 2.5-7 原因箇所の候補と原因内容
項番
1
原因箇所
ハードウェア割込み
原因内容
ローカルタイマのハードウェア割込みの発生に対
して、H/W 割込みハンドラの実行が遅延する
H/W 割込みハンドラによるソフトウェア割込み要
2
ソフトウェア割込み
求に対して、ソフトウェア割込みハンドラ実行が遅
延する
指定時刻になると実行されるプロセスはタイマリ
3
タイマリスト処理の起動
ストで管理され、指定時刻になるとプロセスに起床
するようにシグナルを送るが、指定時刻と比較し、
この処理が遅延する
タイマリスト処理中にプロセスへのシグナル
4
タイマリスト処理
SIGALRM の送信が遅延する
- 2-42 -
シグナルの送信に対して、プロセスの起床(実行
5
シグナル処理の遅延
可能状態への遷移)が遅延する
プロセスが実行可能状態になってから、実行権を取
6
CPU 待ちの遅延
得するまでに他のプロセスが優先されるなどの理
由で、プロセスの実行が遅延する
大量の計算を行うなどのためにプロセスの処理が
7
実行時間の遅延
8
入出力処理による遅延
予定時間内に終了せず遅延する
統計情報の読み込みおよびファイルへの出力処理
が長くかかり遅延する
以上の遅延とイベントの関連を 図 2.5-9 に示す。
イベント
時間軸
ローカルタイマ
H/W 割込み発生
ローカルタイマ
ハンドラ実行
タイマリスト処理実行
タイマリスト
ハンドラ
起動指定時刻
S/W 割込み発生
S/W 割込み
1
H/W 割込み
2
S/W 割込み
3
ハンドラ
4
SIGALRM 送信
繰返し
5
SIGALRM 受信
実行可能状態へ遷移
6
対象
プロセス
実行状態へ遷移
7
入出力開始
8
入出力終了
図 2.5-9 遅延とイベントの関連
上で洗い出した原因候補に対して効率的に解析を進めるために、原因の可能性を考慮し
- 2-43 -
解析の解析順位をつける。
■ケース 1(ディスク I/O 高負荷時における sar のスローダウン事例)の場合
sarの挙動がスローダウンする現象は、ディスクI/O高負荷状況で発生しているので 表
2.5-7 の項番 8 の入出力処理に関する遅延が最も疑わしく、これを解析順位1番とする。つ
づいて、iozoneプロセスが優先されて実行される可能性を考え項番 6 のCPU待ちの遅延、
その他は必要に応じて処理の流れをさかのぼって解析を進めることとする。
■ケース 2(CPU 高負荷時における iostat のスローダウン事例)の場合
iostatの挙動がスローダウンする現象は、CPU高負荷時に発生しているため、表 2.5-7 の
項番 6 のCPU待ちの遅延が一番原因の可能性が高いと考えられ、これを解析順位 1 番とす
る。
2.5.1.4 LKST による障害解析手順
2.5.1.3 節で洗い出した障害の原因候補について調査するためには、図 2.5-9 に示したカー
ネル内部の 1 から 8 に関する各イベントを取得/解析できる必要がある。今回の障害解析に
おいてはその要求を満たすツールとしてカーネルトレースツールLKST(Linux Kernel
State Tracer)を使用する。以下にLKSTを使用して解析するための手順を示す。
(1) LKST モジュールロード
LKST を起動するにはカーネルモジュール lkst をロードする必要がある。また、プロセ
ス の 状 態 遷 移 や ウ ェ イ ト キ ュ ー の 詳 細 な 状 況 を 取 得 す る た め に lksteh_procstat や
lksteh_wqcounter などの LKST 拡張モジュールもロードする。
本障害解析では、測定前に LKST を初期化するために、始めにモジュールのアンロード
/ロードを行っている。
# modprobe -r lksteh_wqcounter
# modprobe -r lksteh_vminfo
# modprobe -r lksteh_sysinfo
# modprobe -r lksteh_procstat
# modprobe -r lksteh_fsinfo
# modprobe -r lkst
# modprobe lkst
# modprobe lksteh_fsinfo
# modprobe lksteh_procstat
# modprobe lksteh_sysinfo
# modprobe lksteh_vminfo
# modprobe lksteh_wqcounter
図 2.5-10 LKST モジュールのロード
(2) マスクセットファイルの作成
- 2-44 -
LKST では記録するカーネルイベントを選択するためにマスクセットを利用するが、マス
クセットの内容はファイルに保存して必要なときに再設定できる。マスクセットファイル
はシステムコールやソフトウェア割込みなどの解析対象(アナライザ)に応じて用意する必
要があり、エディタで編集することも可能だが、lkst_make_mask コマンドを利用して簡
単に作成することができる。以下に、lkst_make_mask コマンドの利用方法を示す。
# lkst_make_mask (マスクセット名) (アナライザ1) (アナライザ2) …
# lkstm read –n (マスクセット名) > (マスクセットファイル)
図 2.5-11 マスクセットファイルの作成方法
本障害解析で作成したマスクセットとアナライザの対応関係を以下の 表 2.5-8 に示す。
表 2.5-8 マスクセットファイルと対応アナライザ
マスクセット
ファイル名
対応アナライザ
maskset_irq
timer syscall procstat softirq runqueue schedrun waitcpu
maskset_wq
schedule schedrun syscall waitqueue waittime
(3) マスクセットの設定
LKSTでは複数のマスクセットを登録しておき、それらのマスクセットを切り替えること
で、取得するカーネルイベントを変更することができる。以下に (2)で作成したマスクセッ
トファイルを設定する方法を示す。
# lkstm write -m 4 -n test_mask write -f maskset_file
マスクセットファイル(maskset_file)を元に
マスクセット ID=4、マスクセット名=test_mask というマスクセットを登録する
(マスクセット ID は 3 から 254 までの値が使える)
# lkstm set -n test_mask
上で登録したマスクセット”test_mask”を有効にする(この時点で test_mask に
設定されたイベントが記録され始める)
図 2.5-12 マスクセットの設定
(4) バッファの準備
LKST は取得したイベントをまずメモリ上のバッファに記録しておき、LKST による記録
が終了した後にデータをファイルに保存し、解析に利用することを前提としている。デフ
ォルトでは利用可能なバッファが 64KB 用意されるが、取得するイベントの量が多くて
64KB では足らない場合、さらに大きなサイズ(最大 64MB)のバッファを用意し、利用する
ことができる。それでも不足する場合は複数のバッファを切り替えて利用することができ
る。本節では IOzone が大量のブロック I/O リクエストを発行するため、以下の手順により
- 2-45 -
IA-32 プラットフォームにおいて LKST で使用できるバッファの最大サイズである 100MB
のバッファを確保する。
# lkstbuf create -s 1M -b 254
# lkstbuf jump -b 254
# lkstbuf delete -b 0
# lkstbuf create -s 64M -b 1 -n 2
# lkstbuf create -s 35M -b 2 -n 1
# lkstbuf jump -b 1
# lkstbuf delete -b 254
図 2.5-13 バッファの準備
(5) モニタリング開始
パフォーマンス監視ツールを起動して、5 秒間隔でシステム統計情報を取得する。以下の
手順により output_file というファイルにデータを保存する。
# sar –A –o output_file 5 600
ケース1の場合
# iostat –t -x 5 600 > output_file
ケース2の場合
図 2.5-14 パフォーマンス監視ツール起動
(6) 負荷の生成
ディスク I/O 負荷を発生させる場合は IOzone を用いて 2 つのプロセスがそれぞれ
500MB のファイルを書き込む負荷を生成させる。CPU 負荷を発生させる場合は stress を
用いて、1000 個のプロセスが平方根を 50 秒間計算する負荷を発生させる。
# iozone_wrap 2 500
ケース1の場合
# stress –c 1000 –t 50
ケース2の場合
図 2.5-15 負荷の生成
(7) LKST によるイベント取得の停止
以下の手順で LKST によるイベント取得を停止する。
# lkst stop
図 2.5-16 LKST によるイベント取得の停止
(8) モニタリング終了
以下の手順でパフォーマンス監視ツールを停止する。
# killall sar
ケース1の場合
# killall sadc
- 2-46 -
ケース2の場合
# killall iostat
図 2.5-17 パフォーマンス監視ツールの停止
(9) LKST が記録したデータのファイルへの保存
LKST によるイベント取得を停止した時点ではイベントはメモリ上に記録されたままな
ので、lkstbuf コマンドを用いてファイルに保存する。また、CPU が複数存在するマシン上
でデータを取得した際は lkstlogdiv コマンドを利用してログを分割する必要がある(CPU が
1基の場合は必須ではないが、手順の汎用性を考えこの処理を行う)。
このあとは、生成された lkstlog-0 から必要な情報を引き出して障害解析を行うことにな
る。
# lkst stop
lkstlog-0, lkstlog-1 とログファイルが CPU の数だけ
# lkstbuf read –f lkstlog
できる(今回は CPU は 1 基なので 1 つのファイル
# lkstlogdiv lkstlog
lkstlog-0 が生成される)
図 2.5-18 イベント取得の停止と取得イベントのファイルへの保存
本節の解析では以上の手順を自動化した 図 2.5-19、図 2.5-20 のスクリプトを用い、障
害解析を行った(ただし、(2)の マスクセットファイルの作成はスクリプト実行前に行ってお
くものとする)。
#!/bin/bash
# Arguments check
if [ $# != 1 ]; then
echo "Usage: start_i.sh <maskset_file>" >& 2
exit 1
fi
MASKSET_NAME=test_mask
MASKSET_FILE=$1
LKST_LOG_FILE=lkstlog
LOG_FILE=lkst.log
INTERVAL=5
COUNT=600
SAVE_DIR=lkst-`date +%Y%m%d_%H%M%S`
echo "Make Directory ${SAVE_DIR}" | tee -a ${LOG_FILE}
mkdir ${SAVE_DIR}
- 2-47 -
# lkst restart
modprobe -r lksteh_wqcounter
modprobe -r lksteh_vminfo
(1)
modprobe -r lksteh_sysinfo
LKST モジュールロード
modprobe -r lksteh_procstat
modprobe -r lksteh_fsinfo
modprobe -r lkst
modprobe lkst
modprobe lksteh_fsinfo
modprobe lksteh_procstat
modprobe lksteh_sysinfo
modprobe lksteh_vminfo
modprobe lksteh_wqcounter
(3)
#/etc/init.d/lkst start
マスクセットの設定
# Write maskset id = 4
lkstm write -m 4 -n ${MASKSET_NAME} write -f ${MASKSET_FILE}
# Change mask
lkstm set -n ${MASKSET_NAME}
# Minimum lkst buffer size
lkstbuf create -s 1M -b 254
lkstbuf jump -b 254
lkstbuf delete -b 0
(4)
バッファの準備
# Get memory for recording
lkstbuf create -s 64M -b 1 -n 2
lkstbuf create -s 35M -b 2 -n 1
lkstbuf jump -b 1
(5)
lkstbuf delete -b 254
モニタリングの開始
# Start sysstat
#mon_sar 5 100 &
echo "Monitoring Start at `date`" | tee -a ${LOG_FILE}
sar -A -o ${SAVE_DIR}/sar.dat ${INTERVAL} ${COUNT} &
sleep 30
# Generate Load
- 2-48 -
echo "Load Start at `date`" | tee -a ${LOG_FILE}
(6)
iozone_wrap 2 500
負荷の生成
echo "Load Finish at `date`" | tee -a ${LOG_FILE}
sleep 10
(7)
# Stop event recording
LKST によるトレースの終了
lkst stop
# Stop sar
(8)
killall sar
モニタリングの終了
killall sadc
echo "Monitoring Finish at `date`" | tee -a ${LOG_FILE}
lkstbuf read -f ${SAVE_DIR}/${LKST_LOG_FILE}
cd ${SAVE_DIR}
lkstlogdiv ${LKST_LOG_FILE}
図 2.5-19 ケース 1 の測定スクリプト start_i.sh
#!/bin/bash
# Arguments check
if [ $# != 1 ]; then
echo "Usage: start_m.sh <maskset_file>" >& 2
exit 1
fi
MASKSET_NAME=test_mask
MASKSET_FILE=$1
LKST_LOG_FILE=lkstlog
LOG_FILE=lkst.log
INTERVAL=5
COUNT=600
SAVE_DIR=lkst-`date +%Y%m%d_%H%M%S`
echo "Make Directory ${SAVE_DIR}" | tee -a ${LOG_FILE}
mkdir ${SAVE_DIR}
- 2-49 -
# lkst restart
modprobe -r lksteh_wqcounter
(1)
modprobe -r lksteh_vminfo
LKST モジュールロード
modprobe -r lksteh_sysinfo
modprobe -r lksteh_procstat
modprobe -r lksteh_fsinfo
modprobe -r lkst
modprobe lkst
modprobe lksteh_fsinfo
modprobe lksteh_procstat
modprobe lksteh_sysinfo
modprobe lksteh_vminfo
modprobe lksteh_wqcounter
(3)
#/etc/init.d/lkst start
マスクセットの設定
# Write maskset id = 4
lkstm write -m 4 -n ${MASKSET_NAME} write -f ${MASKSET_FILE}
# Change mask
lkstm set -n ${MASKSET_NAME}
# Minimum lkst buffer size
lkstbuf create -s 1M -b 254
lkstbuf jump -b 254
(4)
lkstbuf delete -b 0
バッファの準備
# Get memory for recording
lkstbuf create -s 64M -b 1 -n 2
lkstbuf create -s 35M -b 2 -n 1
lkstbuf jump -b 1
lkstbuf delete -b 254
(5)
# Start sysstat
モニタリングの開始
#mon_sar 5 100 &
echo "Monitoring Start at `date`" | tee -a ${LOG_FILE}
iostat –t -x ${INTERVAL} ${COUNT} > ${SAVE_DIR}/iostat &
sleep 30
# Generate Load
echo "Load Start at `date`" | tee -a ${LOG_FILE}
- 2-50 -
stress -c 1000 -t 50
(6)
echo "Load Finish at `date`" | tee -a ${LOG_FILE}
負荷の生成
sleep 10
# Stop event recording
(7)
lkst stop
LKST によるトレースの終了
# Stop sar
(8)
killall iostat
echo "Monitoring Finish at `date`" | tee -a ${LOG_FILE}
モニタリングの終了
lkstbuf read -f ${SAVE_DIR}/${LKST_LOG_FILE}
cd ${SAVE_DIR}
lkstlogdiv ${LKST_LOG_FILE}
図 2.5-20 ケース 2 の測定スクリプト start_c.sh
図 2.5-21 にstart_i.shスクリプトの内部処理の流れを示す。
- 2-51 -
(1)LKTモジュールロード
一旦すべてのモジュールをアンロードした後にロードする
(3)マスクセットファイルの設定
第1引数として指定されたファイルを
マスクセットファイルとして設定する
(4)バッファの準備
100MBのサイズの保存用バッファを用意する
(5)モニタリング開始
sar を用い5秒間隔で100回データを取得する
30秒後
(6)負荷生成
iozone2プロセスで500MBのファイル書込みを行う
10秒後
(7)LKSTによるトレース停止
(8)モニタリング終了
(9)LKSTトレースのファイルへの保存
図 2.5-21 start_i.sh の内部処理
以下の 表 2.5-9 に、start_i.shが受け取る引数の仕様を示す。
表 2.5-9 start_i.sh の引数
引数
第1引数
説明
LKST イベント取得に利用するマスクセットファイルを指定する
以下の 表 2.5-10 にstart_i.shスクリプトが出力するファイルを示す(これらのファイルは
start_i.shの実行ディレクトリに作成される)。
表 2.5-10 start_i.sh の出力ファイル
出力ファイル名
概要
lkst-(実行時刻)/sar.dat
トレース中に取得した sar のデータが保存される
lkst-(実行時刻)lkstlog-0
LKST で取得したイベントがバイナリ形式で保存される
- 2-52 -
データ保存ディレクトリと
モニタリングの開始/終了時刻、
負荷生成の開始/終了時刻が保存される
lkst.log
((実行時刻)に start_ish スクリプトを実行開始した時刻が(西暦2桁)(月2桁)(日2桁)_(時2
桁)(分2桁)(秒2桁)の形式で入る)
以下に start_i.sh の利用手順を示す。
# ./start_i.sh maskset_wq
Make Directory lkst-20050915_120817
New maskset id=4 was written. (Name:test_mask)
Currently selected maskset was changed to id=4
New buffer was created, cpu=0, id=254 size=1048576 + 4032(margin)
Currently selected buffer changed to 254 on CPU 0
Buffer id=0 was deleted.
New buffer was created, cpu=0, id=1 size=67108864 + 4032(margin)
New buffer was created, cpu=0, id=2 size=36700160 + 4032(margin)
Currently selected buffer changed to 1 on CPU 0
Buffer id=254 was deleted.
Monitoring Start at Thu Sep 15 12:08:18 JST 2005
Load Start at Thu Sep 15 12:08:48 JST 2005
Load Finish at Thu Sep 15 12:09:18 JST 2005
Stop LKST event tracing.
./start_i.sh: line 70:
9124 Terminated
sar -A -o ${SAVE_DIR}/sar.dat
${INTERVAL} ${COUNT}
Monitoring Finish at Thu Sep 15 12:09:28 JST 2005
# cd lkst-20050915_120817/
# ls
lkstlog
lkstlog-0
sar.dat
図 2.5-22 start_i.sh の利用手順
start_c.sh については、start_i.sh で IOzone によるディスク I/O 負荷の代わりに 1000
プロセスによる 50 秒間の CPU 負荷を発生させ、sar でモニタリングする代わりに iostat
でモニタリングを行い、その結果を lkst-(実行時刻)/iostat.dat に保存している。それ以外は、
start_c.sh と start_i.sh の挙動に違いはないので、start_c.sh の仕様記述は省略する。
2.5.1.5 障害解析(ケース 1)
本節ではケース 1 の障害解析手順および結果について説明する。
■ケース 1:ディスク I/O 高負荷時における sar スローダウン事例の障害解析
- 2-53 -
まず、2.5.1.3 節で洗い出した障害の原因候補について、優先順位の高い順から解析を行
う。
(1) 入出力処理の挙動に関する確認
まず、入出力処理に関する挙動を調べるために、LKST で入出力システムコールの情報や
ウェイトキュー、プロセスの状態に関する情報を取得する必要がある(ウェイトキューはプ
ロセスの待機理由を詳細に調べるために必要)。そのため、以下の手順でマスクセットファ
イルを作成し、それを用いてイベントを取得する。
# lkst_make_mask maskset_3 procstat schedule schedrun syscall waitqueue waittime
# lkstm read -n maskset_3 > maskset_wq
# ./start_i.sh maskset_wq
Make Directory lkst-20050917_160707
New maskset id=4 was written. (Name:test_mask)
Currently selected maskset was changed to id=4
New buffer was created, cpu=0, id=254 size=1048576 + 4032(margin)
Currently selected buffer changed to 254 on CPU 0
Buffer id=0 was deleted.
New buffer was created, cpu=0, id=1 size=67108864 + 4032(margin)
New buffer was created, cpu=0, id=2 size=36700160 + 4032(margin)
Currently selected buffer changed to 1 on CPU 0
Buffer id=254 was deleted.
Monitoring Start at Sat Sep 17 16:07:08 JST 2005
Load Start at Sat Sep 17 16:07:38 JST 2005
Load Finish at Sat Sep 17 16:08:09 JST 2005
Stop LKST event tracing.
./start_i.sh: line 70:
6111 Terminated
sar -A -o ${SAVE_DIR}/sar.dat
${INTERVAL} ${COUNT}
Monitoring Finish at Sat Sep 17 16:08:19 JST 2005
図 2.5-23 マスクセットファイルの作成と LKST トレースの実行
測定後、まずこの測定で障害が発生していることを確認する。
# cd lkst-20050917_160707/
# sar -u -f sar.dat
Linux 2.6.9-5.25AX (TAMA09)
09/17/05
16:07:08
CPU
%user
%nice
%system
%iowait
%idle
16:07:13
all
1.20
0.00
1.59
0.60
96.61
16:07:18
all
0.40
0.00
0.20
0.40
99.00
16:07:23
all
0.00
0.00
0.00
0.20
99.80
16:07:28
all
0.20
0.00
0.00
0.60
99.20
- 2-54 -
16:07:33
all
0.20
0.00
0.00
0.40
99.40
16:07:38
all
0.20
0.00
0.40
0.60
98.80
16:07:43
all
2.20
0.00
97.80
0.00
0.00
16:08:06
all
0.54
0.00
35.20
48.02
16.24
16:08:11
all
0.20
0.00
8.02
5.01
86.77
16:08:16
all
0.20
0.00
0.00
0.40
99.40
Average:
all
0.54
0.00
20.06
17.27
62.14
23 秒開く
図 2.5-24 sar スローダウンの確認
この結果から、16:07:43 から 16:08:06 の間でデータ取得タイミングが 23 秒開く様子が
観察でき、障害が再現できていることが確認できる。
a. 入出力システムコールとプロセスの状態の解析
まず、sadc プロセス(sar のバックエンドプロセスで実際に統計情報の取得やファイルへ
の保存を行う)が発行する入出力に関するシステムコール(read, write, fsync, fdatasync な
ど)の実行で遅延が発生していないかを以下の手順で確認する。
# lkstla procstat -s lkstlog-0 | grep sadc
6113
3213.000000000
sadc
480
6.693750000
8.000000000
5.000000000
2.675
sadc の PID6113 であることが分かる
# lkstla syscall -s –p6113 lkstlog-0 > syscall_sadc.stat
図 2.5-25 システムコール統計情報の取得
上のコマンドで得られた結果を以下のコマンドでグラフ化する。
# lkst_plot_stat syscall_sadc.stat
図 2.5-26 システムコール統計情報のグラフ化
すると、図 2.5-27 が得られ、fdatasync(ディスクI/Oにおいてメモリ上のデータをディス
ク上のデータと同期させるシステムコール)の列のmaxの値を確認すると、約 19 秒という非
常に長い遅延が発生していることが確認できる。
- 2-55 -
約 19 秒近く
遅延している
図 2.5-27 sadc プロセスのシステムコールの回数と処理時間の統計
次に、システムコール fdatasync がどのタイミングで遅延しているかを調べるために、シ
ステムコール呼出しと処理時間の時系列データを確認する。この情報を得るために以下の
コマンドを実行する
# grep fdatasync syscall_sadc.stat
148
19.843863369
fdatasync
28.781
11
1.803987579
18.924932028
0.019923120
fdatasync のシステムコール番号が 148 であることが分かる
# lkstla syscall -l -p6113 -k148 lkstlog-0
System call analyzer
sysno
syscall_name
6113 は sadc の PID、148 は fdatasync のシステムコール番号
start[sec] processing-time
148
fdatasync 1126940828.017242039
0.030491725
148
fdatasync 1126940833.022834720
0.034036871
148
fdatasync 1126940838.021166238
0.019923120
148
fdatasync 1126940843.020340621
0.022785987
148
fdatasync 1126940848.019599594
0.025715150
148
fdatasync 1126940853.018784141
0.028568158
148
fdatasync 1126940858.024250161
0.684125676
148
fdatasync 1126940863.023344847
18.924932028
148
fdatasync 1126940886.948701006
0.022870817
- 2-56 -
148
fdatasync 1126940891.947976012
0.029745859
148
fdatasync 1126940896.947143087
0.020667978
図 2.5-28 fdatasync 処理状況の時系列データの取得
上の 図 2.5-28 からfdatasyncの処理が遅延している時刻が分かるが、その前後のsadcプ
ロセスの状態(実行中または待機中など)を知るために以下のコマンドを実行する。
# lkstla procstat -l –p6113 lkstlog-0
Process status analyzer
pid
task_name
start[sec]
process-stat
6113
sadc 1126940863.052936460
8.000000000
6113
sadc 1126940863.052943369
5.000000000
6113
sadc 1126940868.021156294
7.000000000
6113
sadc 1126940881.829223874
7.000000000
6113
sadc 1126940881.948244364
8.000000000
(略)
16:07:43
16:08:01
(略)
図 2.5-29 sadc プロセスの状態遷移情報の取得
この結果、図 2.5-29 のデータが得られ、これと 図 2.5-28 を比較すると、fdatasyncが呼
び出された直後に状態 5(TASK_UNINTERRUPTIBLE:割込み不可状態で待機する状態)に
遷移し、途中で状態 7(TASK_RUNNING:実行可能状態)に遷移していることが分かる。
b. ウェイトキュー関連の解析
次に、なぜシステムコール fdatasync の処理で遅延するかを調べるために、sadc プロセ
スがどこで、ウェイトキューにつながれているかを以下の手順で確認する。
Linux においてはディスクへの書込み完了やタイムアウト待ちなどのようにプロセスが
ある事象を待つ場合、カーネルがそのプロセスをウェイトキューに登録して管理する。よ
って、ウェイトキューを調べることでどのような事象でプロセスが待機しているかを明ら
かにすることができる。
以下のコマンドで、ウェイトキューにプロセスを登録するイベントを取得し、その中か
ら時刻 16:07:43.052943369 付近で sadc をウェイトキューにつないでいるイベント
(pid=00006113 になっているイベント)を探す。
# lkstbuf print -r -E lkst_etypes -e "waitqueue counting" -f lkstlog-0
(略)
event_type=waitqueue counting
cpu=00, pid=00006113
time=Sat Sep 17 16:07:43.052942274 2005
arg1=0xc18edaa4 00000000 : pointer to wait_queue_head
arg2=0xf6a7a700 00000000 : pointer to added process
- 2-57 -
arg3=0xf8863799 00000000 : pointer to call address
arg4=0x00000000 00000000 : waitqueue length
(略)
図 2.5-30 ウェイトキューにプロセスをつなぐイベントの確認
取得したイベントの arg3 の値は sadc プロセスをウェイトキューにつないだ関数のアド
レスを表す。その具体的な関数名は、以下のコマンドで確認することができる。
# lkstla waitqueue –s –k 0xf8863799 lkstlog-0
waitqueue length analyzer
address
min
calling_point
count
average
max
log_wait_commit+138
27
0.037037037
1.000000000
total percent
f8863799
0.000000000
1.000000000 100.00
図 2.5-31 sadc プロセスをウェイトキューにつないでいる関数の確認
上の結果において calling_point の列を見ることにより、log_wait_commit という関数の
内部で sadc プロセスをウェイトキューにつないでいることが分かる。この関数はファイル
システムにおけるジャーナリング処理のコミットの完了を待つ関数なので、sadc プロセス
はコミットの完了を待つために状態 5 に遷移したことが分かる。
次に sadc プロセスが状態 7 に遷移しているタイミングで、どのプロセスが sadc プロセ
スを起床させているかを確認する。以下のコマンドで、プロセスを起床しているイベント
を抽出し、sadc プロセスが状態 7 に遷移しているタイミング(16:08:01.829223874)付近を
調べる(起床したプロセスは arg1 から判断できる)。
# lkstbuf print -r -E lkst_etypes -e "wakeup_pid" -f lkstlog-0
(略)
event_type=wakeup_pid
cpu=00, pid=00000706
time=Sat Sep 17 16:08:01.829223874 2005
arg1=0x000017e1 00000000 : wakeup pid
arg2=0x00000003 00000000 : process state
0x17e1 は sadc の PID の
arg3=0x00000000 00000000 : synchronus
16 進表示
(略)
図 2.5-32 プロセスの起床イベントの確認
該当イベントの pid の項目を見ると、PID が 706 のプロセスが sadc プロセスを起床させ
ていることが分かる。このプロセスの名前は以下のコマンドで確認できる。
:# lkstla procstat -s -p706 lkstlog-0
Process status analyzer
pid
task_name
count
average
- 2-58 -
max
min
total percent
706
kjournald
220
6.804545455
8.000000000
5.000000000
1497.000000000 100.000
図 2.5-33 sadc プロセスを起床させているプロセスの確認
以上より kjournald プロセスが sadc プロセスを起床させていることが分かる。よって、
fdatasync システムコールの処理が遅延している理由は、kjournald プロセスが行うジャー
ナル処理におけるコミットの完了を sadc プロセスが待っているためと考えられる。
(2) CPU 待ち遅延の確認
入出力処理の次に考えられる遅延の要因として、CPU 待ちの有無を調査する。sadc プロ
セスの状態遷移に関する情報を取得して CPU 待ちが発生していないかを確認する。
# lkstla procstat -l lkstlog-0 > procstat.log
# lkst_plot_log procstat.log 6113
図 2.5-34 sadc プロセスの状態遷移に関する情報の取得
実行状態
ディスク I/O 負荷発生中
実行可能状態
シグナル受付可能待機状態
シグナル受付不可待機状態
図 2.5-35 sadc の状態遷移
- 2-59 -
上図でプロセスがどの状態で待機しているかは分かるが、プロセスの状態遷移の細かい
挙動が分かりづらいので、テキストデータを確認する(図 2.5-35 の 35 秒から 55 秒付近を
抽出している)。
# cat procstat_sadc.log
(略)
6113
sadc 1126940863.052833438
8.000000000
6113
sadc 1126940863.052838322
5.000000000
6113
sadc 1126940863.052928263
7.000000000
6113
sadc 1126940863.052936460
8.000000000
6113
sadc 1126940863.052943369
5.000000000
6113
sadc 1126940868.021156294
7.000000000
6113
sadc 1126940881.829223874
7.000000000
6113
sadc 1126940881.948244364
8.000000000
5 秒状態 5 で待機
14 秒状態 7 で待機
(略)
図 2.5-36 sadc プロセスの詳細な状態遷移
この結果、sadcプロセスは状態 5 と状態 7 で長い間待機していることが分かる。状態7
での長時間の待ちについては、2.5.1.7 節で考察する。
(3) タイマ処理の挙動の確認
まず以下の手順でソフトウェア割込み、タイマリスト、スケジューリングおよびプロセ
ス状態遷移などのイベントを取得するマスクセットを作成し(入出力に関する調査をした際
にこれらのイベントも同時に取得すると LKST バッファがあふれるため 2 回に分けて測定
している)、作成したマスクセットを利用して、LKST で前述したイベントをトレースする。
# lkst_make_mask maskset_1 timer syscall procstat softirq runqueue schedrun waitcpu
# lkstm read -n maskset_1 > maskset_irq
# ./start_i.sh maskset_irq
Make Directory lkst-20050917_164451
New maskset id=4 was written. (Name:test_mask)
Currently selected maskset was changed to id=4
New buffer was created, cpu=0, id=254 size=1048576 + 4032(margin)
Currently selected buffer changed to 254 on CPU 0
Buffer id=0 was deleted.
New buffer was created, cpu=0, id=1 size=67108864 + 4032(margin)
New buffer was created, cpu=0, id=2 size=36700160 + 4032(margin)
Currently selected buffer changed to 1 on CPU 0
Buffer id=254 was deleted.
Monitoring Start at Sat Sep 17 16:44:52 JST 2005
Load Start at Sat Sep 17 16:45:22 JST 2005
- 2-60 -
Load Finish at Sat Sep 17 16:45:56 JST 2005
Stop LKST event tracing.
./start_i.sh: line 70:
7940 Terminated
sar -A -o ${SAVE_DIR}/sar.dat
${INTERVAL} ${COUNT}
Monitoring Finish at Sat Sep 17 16:46:06 JST 2005
図 2.5-37 マスクセットファイルの作成とトレースの実行
今回の測定においても sar がスローダウンしているかどうかを以下の手順で確認する。
# cd lkst-20050917_164451
# sar -u -f sar.dat
Linux 2.6.9-5.25AX (TAMA09)
09/17/05
16:44:52
CPU
%user
%nice
%system
%iowait
%idle
16:44:57
all
1.40
0.00
1.40
0.60
96.61
16:45:02
all
9.98
0.00
1.00
1.00
88.02
16:45:07
all
0.20
0.00
0.00
0.40
99.40
16:45:12
all
0.00
0.00
0.00
0.60
99.40
16:45:17
all
0.20
0.00
0.00
0.40
99.40
16:45:22
all
0.20
0.00
0.40
0.40
99.00
16:45:27
all
1.80
0.00
98.20
0.00
0.00
16:45:32
all
1.00
0.00
99.00
0.00
0.00
16:45:42
all
0.99
0.00
99.01
0.00
0.00
16:45:53
all
0.29
0.00
25.36
41.01
33.33
16:45:58
all
0.20
0.00
6.00
4.60
89.20
16:46:03
all
0.00
0.00
0.00
0.80
99.20
Average:
all
1.25
0.00
32.50
6.62
59.63
11 秒開いている
図 2.5-38 sar スローダウンの確認
図 2.5-38 よりsarがスローダウンしていることが確認できる。以降はこのトレースで得ら
れたLKSTデータに対して解析を行う。
まず以下の手順でタイマリスト処理の起動遅延に関する統計データを取得する。
# lkstla timer –s lkstlog-0 > timer.stat
図 2.5-39 タイマリスト処理に関するデータの取得
以上の手順で得られた結果を以下の手順でグラフ化すると 図 2.5-41 のようになる。
# lkst_plot_stat timer.stat
1
timerdelayanalyzer.pdf
- 2-61 -
図 2.5-40 タイマリスト処理に関するデータのグラフ化
最大遅延は
0.2ms 以下
図 2.5-41 タイマリスト処理の回数とタイマリスト起動遅延時間
2.5.1.3 節の (2)で述べたように、sadcプロセスは指定した時刻に起床するためにit_real_fn
というタイマリストを用いている。そのため、ここではit_real_fnを重点的にチェックする。
図 2.5-41 においてit_real_fnタイマリストのmaxの値を確認すると 1 回のタイマリストの
起動遅延は最大でも 0.2ms以下であることから、タイマリスト処理の遅延もsarスローダウ
ンの原因でないことが分かる。
(4) タイマソフトウェア割込みの挙動の確認
まず、以下の手順でソフトウェア割込みの発生から割込みハンドラ実行までの遅延の統
計データを取得する。
# lkstla softirq –s lkstlog-0 > softirq.stat
図 2.5-42 ソフトウェア割込みに関するデータの取得
以上の手順で得られた結果を以下の手順でグラフ化すると 図 2.5-44 のようになる。
# lkst_plot_stat softirq.stat
1
software-irqdelayedtimeanalyzer.pdf
- 2-62 -
図 2.5-43 ソフトウェア割込みに関するデータのグラフ化
最大遅延が
0.4ms 以下
図 2.5-44 ソフトウェア割込みの回数と遅延時間
図 2.5-44 においてtimerのmaxの値を調べると、定期的(MIRACLE LINUX V4.0 betaでは
1ms毎)に発生するtimerソフトウェア割込みは、1回の処理で 0.4ms以上遅れていない。よ
って、timerソフトウェア割込みの遅延がsarスローダウンの原因ではないと考えられる。
(5) スケジューリング処理に関する確認
次に、ランキューの長さとスケジューリング処理の遅延の関係を以下のコマンドで取得
する。
- 2-63 -
# lkstla schedrun -s lkstlog-0
1 回のスケジューリング
scheduler overhead per runqueue-len analyzer
処理の最大遅延
len runqueue
count
average
max
min
total percent
1
rq-1
0.000949479
2
1876
0.000000506
0.000003607
0.000000274
0.000001290
0.000009732
0.000000292
0.000001447
0.000006825
0.000000284
878
0.000001241
0.000005424
0.000000300
241
0.000000867
0.000003632
0.000000330
32
0.000001217
0.000003314
0.000000336
31
0.000001524
0.000003160
0.000000370
29
0.000001172
0.000003073
0.000000303
23
0.000001176
0.000002498
0.000000373
17
0.000001423
0.000002795
0.000000376
9
0.000001675
0.000002723
0.000000508
2
0.000001585
0.000002443
0.000000727
10.931
rq-2
1010
スケジューリング
0.001302848 14.999
処理の遅延合計
3
rq-3
3419
0.004945749
4
rq-4
0.001089553
5
6
7
0.448
rq-7
0.000047244
8
0.544
rq-8
0.000033982
9
0.391
rq-9
0.000027039
0.311
rq-10
0.000024194
0.279
rq-11
0.000015071
12
2.407
rq-6
0.000038944
11
12.543
rq-5
0.000209055
10
56.937
0.174
rq-12
0.000003170
0.036
図 2.5-45 ランキューの長さとスケジューリング処理の遅延の確認
得られた結果の max の値から1回のスケジューリング処理では 0.1ms 以上の遅延は認め
らない。また、トレース中におけるスケジューリングの合計処理時間も total の値を合計し
て求めると、0.008686328 秒となり、sar による遅延(11 秒)に比べるとはるかに小さい。よ
ってスケジューリング処理による遅延が原因とは考えがたい。
■ケース 1 のまとめ
以上、LKST を用いた障害の原因追究を行い、ジャーナリング処理におけるコミットの完
- 2-64 -
了待ちという結果を得ることができた。この障害を回避する方法としては、sar の出力先に
tmpfs を使用するなどが考えられる。具体的な回避策とのその効果については 3.1.5.4 節を
参照のこと。
以下の 表 2.5-11 に、ケース 1 における障害解析結果の概要をまとめる。
表 2.5-11 ディスク I/O 高負荷時の sar のスローダウンに関する解析結果
原因候補
遅延
遅延の詳細
(8) 入出力処理
あり
fdatasync システムコールが 20s 遅延している箇所あり
(6) CPU 待ちの遅延
注意
(4) タイマリスト処理
なし
最大遅延は 0.2ms 以下
(2) ソフトウェア割込み
なし
最大遅延は 0.4ms 以下
(6) スケジューリング処理
なし
合計でも 9ms 程度
状態 5(割込み不可状態で待機)と状態 7(実行可能状態)で
合計して 15s 待機している箇所あり。内容吟味必要。
2.5.1.6 障害解析(ケース 2)
本節ではケース 2 の障害解析手順・結果について説明する。
■ケース 2:CPU 高負荷時における iostat スローダウン事例の障害解析
まず、2.5.1.3 節で洗い出した障害の原因候補について、原因の可能性が一番高いと思わ
れるCPU待ちについて調べるためにプロセスの状態遷移を測定する。
最初にマスクセットを以下の手順で作成し、それを用いて測定を行う。
# lkst_make_mask maskset_5 procstat schedule schedrun syscall
# lkstm read –n maskset_5 > maskset_cpu
# ./start_c.sh maskset_cpu
Make Directory lkst-20050917_085746
New maskset id=4 was written. (Name:test_mask)
Currently selected maskset was changed to id=4
New buffer was created, cpu=0, id=254 size=1048576 + 4032(margin)
Currently selected buffer changed to 254 on CPU 0
Buffer id=0 was deleted.
New buffer was created, cpu=0, id=1 size=67108864 + 4032(margin)
New buffer was created, cpu=0, id=2 size=36700160 + 4032(margin)
Currently selected buffer changed to 1 on CPU 0
Buffer id=254 was deleted.
Monitoring Start at Sat Sep 17 08:57:47 JST 2005
Load Start at Sat Sep 17 08:58:17 JST 2005
- 2-65 -
stress: info: [16251] dispatching hogs: 1000 cpu, 0 io, 0 vm, 0 hdd
stress: info: [16251] successful run completed in 50s
Load Finish at Sat Sep 17 08:59:07 JST 2005
stress による負荷生成
Stop LKST event tracing.
プロセス数は 1000
Monitoring Finish at Sat Sep 17 08:59:17 JST 2005
./start_c.sh: line 73: 16190 Terminated
iostat –t -x ${INTERVAL} ${COUNT}
>${SAVE_DIR}/iostat
図 2.5-46 マスクセットファイルの作成と LKST トレースの実行
本測定でも障害が発生していることを確認する。
# cd lkst-20050917_085746:
# grep Time iostat.dat
Time: 08:57:47
Time: 08:57:52
Time: 08:57:57
Time: 08:58:02
Time: 08:58:07
Time: 08:58:12
スローダウン発生
Time: 08:58:17
(5 秒間隔ではない)
Time: 08:58:28
Time: 08:58:34
Time: 08:58:40
Time: 08:58:46
Time: 08:58:51
Time: 08:58:56
Time: 08:59:01
Time: 08:59:06
Time: 08:59:11
Time: 08:59:16
図 2.5-47 iostat のデータ取得タイミングの確認
図 2.5-47 から 08:58:17 から 08:58:46 の期間で 11 秒から 6 秒のiostatのスローダウンが発
生していることがわかる。
(1) CPU 待ち遅延の確認
次に、iostat プロセスの状態遷移を得るために以下のコマンドを実行する。
# lkstla procstat -s lkstlog-0 | grep iostat
16190
377.000000000
iostat
54
6.981481481
0.156
8.000000000
5.000000000
iostat の PID が 16190 と分かる
- 2-66 -
# lkstla procstat -l lkstlog-0 > procstat.log
# lkst_plot_log procstat.log 16190
図 2.5-48 iostat の状態遷移の取得とグラフ化
図 2.5-48 の操作により以下のグラフが得られる。
実行状態
CPU 負荷発生中
実行可能状態
シグナル受付可能待ち
シグナル受付不可待ち
図 2.5-49 iostat の状態遷移(負荷プロセス数 1000)
図 2.5-49 からCPU負荷が発生している期間において、タイマのシグナルにより状態 6(シ
グナル受付可能状態で待機)から状態 7(実行可能状態)に移り、次の状態 8(実行状態)に移る
までに状態 7(実行可能状態)で秒単位の遅延が発生していることがわかる。よって、iostat
プロセスはCPU待ち状態でスローダウンしていることが分かる。
(2) 負荷量と遅延の関係
図 2.5-50、図 2.5-51 にCPU負荷を発生しているプロセス数をそれぞれ 500 及び 100 に減
らした場合の状態遷移図を示す(グラフの作成方法は 図 2.5-48 と同じ)。負荷プロセス数が
減ると状態 7 での遅延が軽減されている(start_c.shの”stress –c 1000 –t 50”の行をそれぞ
れ”stress –c 500 –t 50”、”stress –c 100 –t 50”に書き換えたスクリプトを使用して測定を行
った)。
- 2-67 -
CPU 負荷発生中
実行可能状態
シグナル受付可能待ち
図 2.5-50 iostat の状態遷移(負荷プロセス数 500)
実行可能状態
CPU 負荷発生中
シグナル受付可能待ち
図 2.5-51 iostat の状態遷移(負荷プロセス数 100)
- 2-68 -
(3) ランキューの長さと優先度の変化
負荷プロセスとiostatプロセスの実行スケジューリングがiostatの遅延に関係しているた
め、LKSTによりランキューの長さの変化を確認する(操作コマンドは 図 2.5-53 参照)。図
2.5-52 で示されるように負荷発生中は、1000 個の負荷プロセスは全てランキューにつなが
れており、実行スケジューリングに対し長い順番待ちが発生している。
CPU 負荷発生中
図 2.5-52 ランキューの長さの時間変化(負荷プロセス数 1000)
# lkstla runqueue -l lkstlog-0 > runqueue.log
# lkst_plot_log runqueue.log 0
図 2.5-53 LKST によるランキューの長さ計測
CPU負荷発生中における優先度別のプロセス数の時間変化を以下の 図 2.5-55 に示すス
クリプトで計測すると、図 2.5-54 のようになる。カーネルでは起動直後のプロセスには比
較的高い優先度が割当てられるため、本測定の負荷プロセスでは起動直後は優先度として
- 2-69 -
76 が割当てられ、後半では 77 に優先度が下がっている。これは状態遷移図(図 2.5-49)
において負荷生成直後に状態 7 での遅延が特に大きく、負荷発生期間の前半で遅延が観測
されることと対応している。
1200
合計 : 4
CPU 負荷発生中
1000
プ
ロ
優先度
800
600
77
セ
ス
78
85
84
83
82
81
80
79
78
77
76
75
400
76
数
200
9:31:41
9:31:42
9:31:44
9:31:45
9:31:46
9:31:47
9:31:48
9:31:50
9:31:51
9:31:52
9:31:53
9:31:54
9:31:56
9:31:57
9:31:58
9:31:59
9:32:00
9:32:01
9:32:03
9:32:04
9:32:05
9:32:06
9:32:07
9:32:09
9:32:10
9:32:11
9:32:12
9:32:13
9:32:15
9:32:16
9:32:17
9:32:18
9:32:19
9:32:20
9:32:22
9:32:23
9:32:24
9:32:25
9:32:26
9:32:28
9:32:29
9:32:30
9:32:31
9:32:32
9:32:34
9:32:35
9:32:36
9:32:37
9:32:38
9:32:40
9:32:41
0
9:31:41
時刻
図 2.5-54 優先度別プロセス数の変化(負荷プロセス数 1000)
#!/bin/bash
SAVE_DIR=ps-`date +%Y%m%d_%H%M%S`
注意:ディスク I/O の影響を
mkdir ${SAVE_DIR}
受けないように tmpfs 上に
出力する
while [ 1 ]
do
ps -elf > ${SAVE_DIR}/`date +%H_%M_%S`
sleep 1
done
図 2.5-55 優先度の計測スクリプト
■ケース 2 のまとめ
以上の結果より、CPU 高負荷状態における iostat の遅延は、CPU の実行スケジューリ
ング待ちにより発生している。このような CPU 待ちによる遅延を回避するには nice コマ
ンドを用いた優先度(NICE 値)の変更などが考えられる。実際に NICE 値を変更した際の挙
動については 3.1.5.4 節を参照されたい。
- 2-70 -
低
高
2.5.1.7 障害解析手順についての留意点
本節では、sar と iostat を例にとりタイマ駆動型アプリケーションの遅延障害の解析手法
を紹介した。同様の解析をおこなう上での留意点を以下に述べる。
■主要因の絞込み
タイマ駆動型アプリケーションでは、表 2.5-7 に示す複数の遅れ要因があるが、遅れ時
間の大きさにより、疑わしい要因がある程度絞り込まれる。本節の例では 10 秒以上の遅れ
が発生しているため、最も応答時間の遅いディスク入出力にかかわる周辺から調査を進め
た。しかし、これが 1msオーダーの遅れを問題とする解析では、最初に調査すべき要因も
変わってくることに留意されたい。
■長時間の状態7での待ち
ケース 1 のsarの遅延解析では、ジャーナル処理のコミット待ちが遅延原因であった。図
2.5-35、図 2.5-36 では一度状態 5(シグナル受付不可待機状態)で 5 秒待った後、状態7(実
行可能状態)に遷移しここでも 14 秒待ちに入っている。状態7になっているためプロセス
はランキューに接続されているが、状態 8(実行状態)になる前なのでウェイトキューにも
接続されている状態で待ちになっている。待ちの解除は、kjournaldプロセスがジャーナル
処理のコミットを完了したこと(図 2.5-32)により、もう一度状態 7 に遷移し直ちに状態
8 となってウェイトキューから外されるという順序(図 2.5-36)なので、状態7の長時間
の待ちも、実態はジャーナル処理のコミット待ちであり、ケース 2 のようなプロセスの実
行スケジューリングを待っているわけではない。LKSTにより状態 7 から状態 7 への遷移が
観測された場合には、このような待ち原因の吟味が必要である。
■LKST による解析
LKST の利用は、ソフト割込みやタイマリスト、システムコールの解析手順のよう
に、”lkstla (アナライザ名) -s (logfile)”というコマンドで、簡単にさまざまなイベントの遅
延に関する統計情報が取得・グラフ化が容易であり、障害の要因を絞り込むのに非常に有
用である。
ただし、統計情報により要因概要(本節では fdatasync システムコールの処理が遅延して
いる)が判明しても、さらに深い原因追求を行う場合は、LKST で取得したイベントから関
連しそうなものを抽出し、そこから付随する情報を引き出す必要がある(本節ではウェイト
キューにつなぐイベントやプロセスを起床させるイベントを抽出し、プロセスをウェイト
キューにつなぐ関数やプロセスを起床させるプロセスを調べた)。LKST をより効果的に利
用するためには、これらの手順の再利用/自動化などの機能拡張がなされると、更に利用し
やすいツールとなる。
- 2-71 -
■LKST の記録時間
LKST がイベントを記録するバッファサイズの上限が 100MB に限られる点は、記録時間
に関する注意が必要である。計測中 LKST がイベント記録用のバッファを使い切っていな
いことを確認するために、以下のコマンドでバッファの利用状況を監視する方法が有効で
ある。
# lkstbuf ls
id
cpu
255
0
size
prev_id next_id
readp
writep
wrap
32768
NUL
NUL
0
0
0
1
0* 67112896
2
2
55717440
55717504
0
2
0
1
1
4032
4032
0
36704192
図 2.5-56 バッファの利用状況の確認
LKST のイベントを取得していくと writep の数値が増えていく。この値がバッファのサ
イズを超えないことを確認する必要がある。もし超えてしまう場合は、取得するイベント
の種類を減らしたり、負荷量(発生するイベントの量)を調整したりする必要がある。
取得すべきイベントを減らせない場合には、測定を複数回に分けて行うなどの工夫が必
要となる。また、再現性が低い障害や測定しなければいけない期間が非常に長い障害など
の場合も、バッファを使い切ってしまうことがないように工夫する、または計測したい事
象が記録されたらバッファがその後のイベントにより上書きされる前に計測を停止するな
どの工夫が必要である。
- 2-72 -
2.5.2 システムコールトレーサがトレース対象プロセスを遅延させる障害の解
析
高負荷な状況下で sar を実行すると、取得しているデータが欠落するという問題が報告さ
れている。この障害をシステムコールトレーサである strace および lkst を用いて解析した
所、strace が sar プロセスを遅延させてしまう別な問題があることが分かった。この障害
に関して、解析と対策を以下に報告する。
2.5.2.1 概要
本障害とその対策の概要を 表 2.5-12 に示す。
表 2.5-12 高負荷時 strace 問題の概要
番号
2.5.2
現象
高負荷時、strace がトレース対象プロセスの処理を遅延させてしまう
分類
スローダウン
発生環境
OS
Fedora Core 3
CPU
Xeon 2.4GHz×1
メモリ
2GByte
ハードディスク
IDE 120GByte
ネットワーク
Intel 82545EM Gigabit Ethernet Controller
発生日
2005/xx/xx
解決日
2005/xx/xx
原因
strace ログ出力が他のファイル I/O 待ちにより遅延する
対策
strace ログ出力を ramfs 上のファイルに対して出力する(改善策)
解析手法
lkst による解析(所要時間が長いシステムコールを確認~事象待ち要
因の解析~事象待ち根本原因の追跡~I/O キュー、WAIT キューからの
解析結果裏付け)
2.5.2.2 障害発生の経緯
sar の高負荷時データ欠落問題を解析するため、まず障害解析環境で再現することを確認
する。その際の手順を以下に示す。
a. sar を1秒間隔で実行
$ sar 1 0
b. 高負荷状況作成ツール stress によって、メモリ負荷が高い状況を再現する
$ stress -m 100 --vm-bytes 32M --vm-hang --timeout 180s
※stress の設定は環境により異なる。ここでは、物理メモリ(2GByte)の約 1.5 倍(1.5
×2GByte≒100×32MByte)を設定。
c. sar の出力が欠落することを確認して、関連プロセス(stress と sar)を kill する
- 2-73 -
この手順により、stress 実行直後に sar の出力間隔が不安定になり、データが欠落すること
を確認した。
スローダウン障害の場合、悪影響を及ぼしているプロセスが存在する可能性がある。こ
れを切り分けるため、top コマンドで負荷が高くなっているプロセスがないかを確認する。
本事例では、top で確認したが stress が表示されるだけで、他に CPU/メモリ使用率が問
題になるようなプロセスは存在しなかった。
次に sar で処理時間の長いシステムコールは何かを切り分けるため、システムコールトレ
ーサ strace によってトレースを行う。この場合、時間関係のトレース情報が必要であるた
め、システムコール処理時間とタイムスタンプを出力するオプション(-ttt と-T)を指定す
る。この際の手順を以下に示す。
a. strace 経由で sar を1秒間隔で実行。システムコールのトレースを行う
$ strace -f -F -ttt -T -o strace.log sar 1 0
b.~c. 前述の手順と同様
スローダウン障害時のシステムコールログを確認する場合は、処理時間の長いシステム
コールに着目する。また、周期的な処理の実装の一つでは、タイマ(alarm システムコー
ルによるシグナル SIGALRM の通知)を使用している。本事例のように時刻周期が遅れる
ような場合には、alarm システムコール周りにも着目する。
alarmコールを検索しながらタイムスタンプを確認し、1秒毎になっていない箇所を確認
した(図 2.5-57 参照)。
6732
1120049624.827897 alarm(1)
= 0 <0.000011>
シグナル通知(1秒後)を
設定してから...
:(省略)
6730
1120049624.834089 read(0,
<unfinished ...>
6732
1120049626.535412 <... pause resumed> ) = ? ERESTARTNOHAND (To be restarted)
シグナル受信まで、設定した
1秒ではなく、約2秒かかっ
1120049626.535487 --- SIGALRM (Alarm clock) @ 0 (0) --- ている
<1.702452>
6732
図 2.5-57
sar データ欠落時の strace 結果
図 2.5-57 からは、確かに周期が遅れていることが分かるが、
それ以上のことは分からない。
同様に処理時間の長いシステムコールも確認したが、障害箇所を特定することはできなか
った。
システムコールトレース結果を確認しても障害箇所が特定できない場合、カーネル状態
トレーサ lkst を用いて、他プロセスの処理を含むカーネル内部動作をトレースし、障害箇
所を特定する。lkst を用いた解析手順を以下に示す。
- 2-74 -
a. lkst のモジュールをロードする(以下、スーパーユーザで行う必要あり)
# modprobe lksteh_procstat
# modprobe lksteh_wqcounter
b. lkst のマスクセットを設定する
スローダウンの場合、スケジューリング、I/O 待ち等が疑わしいため、これらに該当す
るアナライザと、システムコール用のアナライザを設定する
# lkst_make_mask debug_mask blkqueue biotime busywait procstat schedule schedrun \
syscall waitqueue waittime
# lkstm set -n debug_mask
c. lkst のバッファを確保/設定し、一旦バッファを空読みし、クリアする
# lkstbuf create -s 63M
# lkstbuf jump -b 1
# lkstbuf read -f /dev/null
d. 前述の手順により、strace で sar データ欠落をトレースする
e. lkst のバッファをファイルに出力する
# lkstbuf read -f lkst.log
f. lkst ログ解析に使用する lkst イベントタイプをファイルに保存する
# cp /proc/lkst_etypes lkst_etypes
lkstログの解析を行うため、最初に関連プロセスであるstrace、 sar、 sadcのプロセス
番号を確認する。プロセス番号の確認手順を 図 2.5-58 に示す。
$ lkstla procstat -s lkst.log | grep
8591
strace
1. プロセス一覧から strace
をフィルタし...
strace
26996
7.195510446
8.00000000
194250.00000000
5.00000000
2. pid を確認
図 2.5-58
lkst ログからの pid 確認(strace の例)
同様にsar、 sadcのプロセス番号も確認した所、各プロセスの関係とpid値は、図 2.5-59
のようになっていた。
親
strace
pid: 8591
図 2.5-59
子
sar
pid: 8592
sadc
pid: 8594
sadc は、/proc 下か
ら情報を取得する
プロセス
sar データ欠落障害時のプロセス関係と pid
- 2-75 -
次にsarのalarmシステムコール周期が遅れている部分を確認する(図 2.5-60 参照)。
$ lkstla syscall -l -p
8594
System call analyzer
sysno
syscall_name
:(省略)
-k
27
lkst.log
1. sadc プロセス(pid: 8594)が発行
したシステムコールからシステム
コール番号 27(alarm)をフィル
タして時刻順に表示する
※alarm システムコール番号が分か
start[sec] processing-time
らない場合は、以下のコマンドで
システムコール一覧を表示する
$ lkstla syscall -s lkst.log
27
alarm 1122005643.014185632
0.000030569
27
alarm 1122005644.014663423
0.000029989
27
alarm 1122005645.401448302
0.000029725
27
alarm 1122005650.286725212
0.000029849
27
alarm 1122005651.286560847
0.000029863 2. 発行周期が 1 秒でない部分を確認
27
alarm 1122005652.287015489
0.000030419
図 2.5-60
sar データ欠落時障害時の alarm コール発行状況(lkst ログの抜粋)
図 2.5-60 より、障害は時刻 1122005645~1122005650 の周辺で発生していることが分か
る。
次に、sarの問題かどうかを切り分けるため、障害発生時刻付近のプロセス状態を確認す
る(図 2.5-61 参照)。この結果、sadcがalarmコールから約1秒後にスケジューリングされ
た直後にstraceに制御が移り、そのままstraceが割り込み不可状態で事象待ちとなり、約3
秒が経過していることが分かった。よって問題はsarではなく、straceの処理が遅延してい
ることにあると考えられる。
$ lkstla procstat -lP -p8591,8592,8594 lkst.log
strace, sar, sadc プロセスの状態の変化を時刻順に表示
Process status analyzer
pid
task_name
pid
start[sec]
:(省略)
process-stat
alarm コールから約1秒経過
8594
sadc
8594 1122005646.402007570
7.000000000
8594
sadc
8594 1122005646.402011642
8.000000000
8591
strace
8591 1122005646.402017460
7.000000000
8594
sadc
8594 1122005646.402018826
3.000000000
8591
strace
8591 1122005646.402018919
8.000000000
8591
strace
8591 1122005646.402072318
5.000000000
8591
strace
8591 1122005649.268903292
7.000000000
8591
strace
8591 1122005649.927424669
8.000000000
8591
strace
8591 1122005649.928668505
5.000000000
8591
strace
8591 1122005649.928681947
7.000000000
- 2-76 -
sadc はスケジューリン
グ直後にトレース状態
(状態 3)で待ちになっ
ている
その直後、strace に制御
が移り、割り込み不可状
態で事象待ち(状態 5)
になったまま、3秒近く
経過している
8591
strace
8591 1122005650.286440488
8.000000000
8594
sadc
8594 1122005650.286468765
7.000000000
図 2.5-61
sar データ欠落障害時のプロセス状態(lkst ログの抜粋)
更にlkstログより、この時刻付近のシステムコールを解析した所、straceのwriteシステム
コールで遅延していることが分かった(図 2.5-62 参照)。
$ lkstla syscall -lP -p8591,8592,8594 lkst.log
strace, sar, sadc プロセスの syscall 発行を時刻順に表示
System call analyzer
sysno
syscall_name
pid
start[sec] processing-time
:(省略)
29
pause
8594 1122005645.966796426
0.435217434
114
wait4
8591 1122005645.968398497
0.433625642
78
gettimeofday
8591 1122005646.402032753
0.000003976
26
ptrace
8591 1122005646.402037847
0.000002775
26
ptrace
8591 1122005646.402041041
0.000000756
78
gettimeofday
8591 1122005646.402051381
0.000003075
write 8591 1122005646.402062455
3.884396753
4
26
ptrace
8591 1122005650.286464671
0.000004680
114
wait4
8591 1122005650.286470737
0.000069908
78
gettimeofday
8591 1122005650.286548666
0.000004072
図 2.5-62
alarm コールから
約1秒経過
strace の write システム
コ ー ル が 約 4秒 か か っ
ていることが分かる
sar データ欠落障害時のシステムコール(lkst ログの抜粋)
当初は sar データ欠落障害を追跡していたのだが、その途中で strace にも高負荷状況下
での使用に関しては問題があることが判明した(当初追跡していた、sar データ欠落障害の
解析と対策に関しては、2.5.1 節を参照)。
2.5.2.3 解析
(1) lkst による解析(所要時間が長いシステムコールを確認)
straceのシステムコールで他にも長時間(10msec以上)掛かっているものが存在するか
。
どうかを確認する(図 2.5-63 参照)
$ lkstla syscall -lP -p8591 -m0.01:100 lkst.log | grep -v wait4
strace システムコールを処理時間でフィルタ
する。また、wait4 はトレース対象プロセスの
イベント待ちなので、それも除く
System call analyzer
sysno
syscall_name
4
write
pid
start[sec] processing-time
8591 1122005618.357494243
- 2-77 -
0.015721569
4
write
8591 1122005628.987744834
0.361722669
26
ptrace
8591 1122005629.350419772
0.412785495
26
ptrace
8591 1122005645.402513623
0.558999814
write 8591 1122005646.402062455
3.884396753
4
3
read
8591 1122005653.287346371
0.012485473
3
read
8591 1122005654.302765216
0.013471801
図 2.5-63
strace で 10msec 以上掛かったシステムコールの一覧
これらのシステムコールの内、一番長時間掛かっているwrite(時刻 1122005646 秒の時
のもの)に関して解析を行った。このwriteコールは前述の 図 2.5-62 と同じ箇所であり、
割り込み不可状態での事象待ちに長時間掛かっていることまでは 図 2.5-61 で解析済みで
ある。
(2) lkst による解析(事象待ち要因の解析)
次のステップとして、何の事象を待っているのかを確認することで、障害要因箇所を追
跡する。カーネル 2.6 では、事象待ちとなる際に、事象毎に WAIT キューにつなぐ処理を
行う。
lkstではこのイベント(waitqueue counting)をトレースでき、そのイベント引き数を確
認することで、どの関数内からWAITキューにつないだかを確認することができる。lkstロ
グ解析による事象待ち関数の特定を 図 2.5-64 に示す。
$ lkstbuf print -r -E lkst_etypes -e "waitqueue counting" -f lkst.log
:(省略)
1. WAIT キューにつなぐイベントのみ表示
event_type=waitqueue counting
2. 時刻からイベントを特定
strace の pid と時刻からイベントを
特定
cpu=00, pid=00008591
time=Fri Jul 22 13:14:06.402071375 2005
arg1=0xf7f82464 00000000 : pointer to wait_queue_head
arg2=0xf7c1c230 00000000 : pointer to added process
arg3=0xc01f8d1f 00000000 : pointer to call address
3. WAIT キューにつなぐアドレスを
チェック
arg4=0x00000001 00000000 : waitqueue length
$ lkstla waitqueue -s
-k 0xc01f8d1f
4. waitqueue イベントの一覧からチェック
したアドレスをフィルタ
lkst.log
waitqueue length analyzer
address
min
c01f8d1f
0.000000000
calling_point
count
average
max
start_this_handle+593
2
0.500000000
1.000000000
total
5. この関数内から WAIT キューにつな
ぐ処理を行っていることが判明
1.000000000
図 2.5-64
lkst ログ解析による strace 事象待ち関数の特定
- 2-78 -
この結果、start_this_handle 関数内で WAIT キューにつながれていることが分かる。
次に該当関数ソース内のどのステップでWAITキューにつないでいるかを特定する。
objdumpコマンドによりカーネルを逆アセンブラし、周辺の関数コールなどから判断する
ことにより特定する(図 2.5-65、図 2.5-66 参照)。
$ objdump -d
--start-address=0xc01f8d1f
vmlinux
WAIT キューにつなぐアドレスを指定
Disassembly of section .text:
c01f8d1f <start_this_handle+0x593>:
付近に printk, schedule コールが
c01f8d1f:
81 7e 14 3c 4b 24 1d
cmpl
あることを確認
$0x1d244b3c,0x14(%esi)
c01f8d26:
74 23
je
c01f8d4b <start_this_handle+0x5bf>
c01f8d3f:
c7 04 24 c8 ac 39 c0
movl
$0xc039acc8,(%esp)
c01f8d46:
e8 27 30 f3 ff
call
c012bd72 <printk>
c01f8d4b:
8b 46 18
mov
0x18(%esi),%eax
c01f8d74:
0f 85 b0 03 00 00
jne
c01f912a <start_this_handle+0x99e>
c01f8d7a:
e8 01 31 19 00
call
c038be80 <schedule>
c01f8d7f:
89 da
mov
%ebx,%edx
:(省略)
:(省略)
図 2.5-65 WAIT キュー接続位置のカーネル逆アセンブラ
static int start_this_handle(journal_t *journal, handle_t *handle)
{
transaction_t *transaction;
:(省略)
/*
* If the current transaction is locked down for commit, wait for the
* lock to be released.
*/
if (transaction->t_state == T_LOCKED) {
DEFINE_WAIT(wait);
start_this_handle 関数内で schedule
をコールしているのは2箇所(そのう
ちの1箇所目)
prepare_to_wait(&journal->j_wait_transaction_locked,
&wait, TASK_UNINTERRUPTIBLE);
spin_unlock(&journal->j_state_lock);
schedule();
- 2-79 -
このステップで WAIT キューにつなぐ
と思われる
finish_wait(&journal->j_wait_transaction_locked, &wait);
goto repeat;
}
/*
* If there is not enough space left in the log to write all potential
* buffers requested by this operation, we need to stall pending a log
* checkpoint to free some more log space.
*/
spin_lock(&transaction->t_handle_lock);
needed = transaction->t_outstanding_credits + nblocks;
if (needed > journal->j_max_transaction_buffers) {
/*
* If the current transaction is already too large, then start
* to commit it: we can then go back and attach this handle to
* a new transaction.
*/
DEFINE_WAIT(wait);
jbd_debug(2, "Handle %p starting new commit...\n", handle);
spin_unlock(&transaction->t_handle_lock);
同2箇所目
prepare_to_wait(&journal->j_wait_transaction_locked,
&wait,
TASK_UNINTERRUPTIBLE);
__log_start_commit(journal, transaction->t_tid);
spin_unlock(&journal->j_state_lock);
schedule();
このステップで WAIT キューにつなぐ
と思われる
finish_wait(&journal->j_wait_transaction_locked, &wait);
goto repeat;
}
図 2.5-66 WAIT キュー接続位置のカーネルソース(fs/jbd/transaction.c)
カーネルソースのコメント(図 2.5-66 の斜め文字部分)よりstart_this_handle内からは、
以下の2つの要因によって事象待ちとなることが分かる。
・要因-1 現在のトランザクションがコミットのためロック中の場合、ロック解除を待つ
・要因-2 要求された処理のためのログ(変更記録)バッファが確保できない場合、他の処
理がチェックポイントに到達(ファイルデータの書き込みまでの一連の処理が終
了)し、ログスペースが解放されるのを待つ
- 2-80 -
逆アセンブラを詳細に解析すれば、どちらの要因によって待ちとなっているかが分かる
が、コンパイラによって最適化されたコードとなっているため、逆アセンブラ解析に慣れ
ていない場合は時間がかかる。解析時間を短縮するため、どの事象が発生したことで strace
プロセスが起床しているかを、先に確認する。
カーネル 2.6 では事象が起こると、その事象を待っているプロセスを起床させるために
wake_up 関数がコールされる。wake_up 関数ではプロセスを RUN キューにつなぐ処理を
行い、その後 RUN キューにつながれたプロセスの中でスケジューリングが行われる。
lkstではこのイベント(wakeup_pid)をトレースでき、そのイベント引き数を確認するこ
とで、どのプロセスがwake_up関数をコールしたかを確認することができる(straceを起床
させた事象は、そのプロセス実行中に発生)。lkstログ解析による起床プロセスの特定を 図
2.5-67 に示す。
$ lkstbuf print -r -E lkst_etypes -e "wakeup_pid" -f lkst.log
:(省略)
1. プロセスを起床させるイベントのみ表示
event_type=wakeup_pid
cpu=00, pid=00000214
time=Fri Jul 22 13:14:09.268903292 2005
2. 時刻および起床対象プロセス
時刻からイベントを特定
pid(strace の
pid は 8591、16 進数では 218f)によって、イ
ベントを特定
arg1=0x0000218f 00000000 : wakeup pid
arg2=0x00000003 00000000 : process state
arg3=0x00000000 00000000 : synchronus
$ lkstla procstat -s
-p 214
3. strace を起床させるプロセスの pid(214)
をチェック
lkst.log
4. プロセス状態変化イベントの一覧からチェ
ックした pid をフィルタ
Process status analyzer
pid
task_name
count
average
max
min
8.000000000
5.000000000
total
214
kjournald
450
6.931111111
3119.000000000
図 2.5-67
5. kjournald プロセスで事象が発生し、strace
を起床していることが判明
lkst ログ解析による strace 起床プロセスの特定
この結果、トランザクションのコミットを行うkjournaldによってstraceが起床されたこと
が 分 か る 。 す な わ ち 、 strace は ト ラ ン ザ ク シ ョ ン の コ ミ ッ ト の 終 了 を 待 っ て お り
(start_this_handle中の事象待ち要因-1)、コミット終了によって起床されたのだと想定さ
れる。また、図 2.5-64 と 図 2.5-67 より、事象待ちから事象発生までの時間は約3秒かか
っており、事象(この場合はトランザクションコミット終了)の発生が遅れたことに障害
原因を限定できたことになる。
- 2-81 -
(3) lkst による解析(事象待ち根本原因の追跡)
更に、トランザクションコミットの終了が遅れた原因は何かを追跡する。事象が発生し
ているkjournaldプロセスの状態について、障害が発生している時刻付近を確認する(図
2.5-68 参照)
。
$ lkstla procstat -lP
-p 214
lkst.log
:(省略)
kjournald(pid: 214)のプロセス状態の変化を
時刻順に表示
214
kjournald
214 1122005646.011219675
7.000000000
214
kjournald
214 1122005646.011227864
8.000000000
214
kjournald
214 1122005646.011233507
5.000000000
214
kjournald
214 1122005649.268884395
7.000000000
214
kjournald
214 1122005649.268887083
8.000000000
214
kjournald
214 1122005649.927378826
7.000000000
214
kjournald
214 1122005650.278798181
8.000000000
図 2.5-68
kjournald も約 3 秒事象待
ちになっている
kjournald プロセス状態の確認(lkst ログの抜粋)
図 2.5-68 より、kjournaldもstraceと同様に事象待ちとなっており、事象待ちの連鎖となっ
ていることが分かる。straceの場合と同様に、kjournaldについても、何の事象を待ってい
るのか、どのプロセスによって起床されているのかを確認する。
同様の手順で確認した所、journal_commit_transaction 関数で WAIT キューにつながれ
ており、lkstbuf プロセスによって起床されていることが分かった(詳細は省略)。
journal_commit_transaction 関数のソースコードのコメントより、kjournald プロセスが
待っている事象は、実行中の全 I/O 更新処理の終了待ちであり、lkstbuf の I/O 処理の延長
で起床されたことが分かる。
事象待ちの連鎖が終了するまで、更に遡って解析を行う。事象が発生していたlkstbufプロ
セスの状態について、障害が発生している時刻付近を確認する(図 2.5-69 参照)
。
$ lkstla procstat -lP
-p 8739
lkst.log
:(省略)
lkstbuf(pid: 8739)のプロセス状態の変化を
時刻順に表示
8739
lkstbuf
8739 1122005642.857962129
8.000000000
8739
lkstbuf
8739 1122005642.877961711
7.000000000
8739
lkstbuf
8739 1122005644.864863612
8.000000000
8739
lkstbuf
8739 1122005644.872919190
7.000000000
8739
lkstbuf
8739 1122005644.875835215
8.000000000
8739
lkstbuf
8739 1122005644.875851996
7.000000000
8739
lkstbuf
8739 1122005644.886705338
8.000000000
8739
lkstbuf
8739 1122005644.886707569
5.000000000
8739
lkstbuf
8739 1122005644.938930116
7.000000000
- 2-82 -
2箇所で事象待ち(5)に
なっているが、どちらも
それほど経たないうちに
スケジューリング待ち
(7)になっている
(1箇所目)
8739
lkstbuf
8739 1122005645.399773740
7.000000000
8739
lkstbuf
8739 1122005647.571356244
8.000000000
8739
lkstbuf
8739 1122005647.573401067
5.000000000
8739
lkstbuf
8739 1122005647.579012640
7.000000000
8739
lkstbuf
8739 1122005647.673300200
7.000000000
8739
lkstbuf
8739 1122005649.268427834
8.000000000
8739
lkstbuf
8739 1122005649.268886989
7.000000000
8739
lkstbuf
8739 1122005650.297033818
8.000000000
図 2.5-69
同2箇所目
lkstbuf プロセス状態の確認(lkst ログの抜粋)
図 2.5-69 から、lkstbufプロセスでは事象待ちになった場合でも、秒オーダーでの待ちには
なっていないこと、すなわち事象待ちによる連鎖がここで終了したことが分かる。
ここまでで解析できた、プロセスと事象待ちの連鎖状態は、図 2.5-70 の通り。
lkstbuf(pid: 8739)
kjournald(pid: 214)
strace(pid: 8591)
(journal_commit_transaction)
実行中の全 I/O 更新処理が
未終了
→終了待ち
write コール発行
約 3.26 秒
(start_this_handle)
I/O 更新処理終了
約 2.87 秒
現在のトランザクションが
ロック中
→コミット終了待ち
コミット終了
write コール終了
凡例
: 処理
: プロセス処理中
: CPU および事象待ち
図 2.5-70 プロセスと事象待ちの連鎖状態
- 2-83 -
事象待ちの連鎖状態から、lkstbuf の I/O 更新処理がジャーナルのトランザクションコミッ
ト処理を遅延させ、それによって strace の write が遅れたことが分かる。
ここまでの解析により、lkstbuf による大きなファイルの書き込み(63MByte をフォーマ
ット変換して書き出すため、容量が増加する)の I/O 処理がジャーナル処理を輻輳/遅延さ
せてしまい、それに伴い障害(write システムコールの遅延)が発生したと考えられる。
(4) lkst による解析(I/O キュー、WAIT キューからの解析結果裏付け)
この仮説を実証するため、ブロックI/O関連に着目し、lkstログ解析を行う。まず、ブロ
ックI/Oキューにたまっている数が多くなっていないか確認するため、ブロックI/Oキューを
確認する。確認は、図 2.5-71 の通り。
- 2-84 -
$ lkstla
blkqueue
-s lkst.log
1. ブロック I/O キュー状態を表示する
Block-IO request queue analyzer
rq-addr requestqueue
count
average
max
min
total percent
f7ce4028 0xf7ce4028RD
4.000000000
4
1.000000000
2.000000000
0.000000000
802
1.110972569
5.000000000
0.000000000
8
0.500000000
1.000000000
0.000000000
333
3.381381381
0.198
f7ce4029 0xf7ce4028WR
891.000000000
44.000
f7ce48c8 0xf7ce48c8RD
4.000000000
0.198
f7ce48c9 0xf7ce48c8WR
1126.000000000
ブロック
2.
write I/O
システムコールが問題となっ
キュー状態を表示
26.000000000
0.000000000
ていたので、書き込みのキューを確認
55.605
3. blkqueue の経過時間での変化をグラフ表示する。コマン
ドは、下記の通り
$ lkstla blkqueue -l lkst.log > blkqueue.log
$ lkst_plot_log -k f7ce4029,f7ce48c9 blkqueue.log
4. 障害発生箇所はこの付近(時刻
1122005646~1122005650 秒)。
1122005645 秒くらいにある山(最大
キュー長4)が疑わしい
図 2.5-71 ブロック I/O キュー長の解析
- 2-85 -
図 2.5-71 から、時刻 1122005646 付近にブロックI/Oキュー長が長くなり山になってい
る部分(キュー長は最大 4)が確認でき、この部分が疑わしいことが分かる。
キュー関係を洗う意味で、今度はWAITキュー長を確認する(図 2.5-72、図 2.5-73 参照)。
$ lkstla
waitqueue
-s lkst.log
1. WAIT キュー状態を表示する
waitqueue length analyzer
address
calling_point
min
count
average
max
2
0.500000000
1.000000000
175
2.097142857
6.000000000
85
2.282352941
5.000000000
total percent
c01f8d1f
start_this_handle+593
0.000000000
c02c7558
1.000000000
0.178
blk_congestion_wait+70
0.000000000
c0384bf4
367.000000000
65.302
unix_wait_for_peer+6d
0.000000000
194.000000000
34.520
2. キュー最大長が長いものに着目し...
(ここでは最大長 0 の項目は省略し、表示して
いない)
3. 関連しそうなキューを確認する
関数名から、関連しそうなキューを
確認する
4. waitqueue の経過時間での変化をグラフ表示する。コマ
ンドは、下記の通り
$ lkstla waitqueue -l lkst.log > waitqueue.log
$ lkst_plot_log -k c01f8d1f,c02c7558 waitqueue.log
5. 障害発生箇所はこの付近(時刻
1122005646~1122005650 秒)
図 2.5-72 WAIT キュー長の解析(その1)
- 2-86 -
6. キュー表示の場合、値 0 は X 軸に隠れて表示されないため、
ラインスタイルを変更して表示する。コマンドは、下記の通り
$ lkst_plot_log -k c01f8d1f,c02c7558 -l points waitqueue.log
7. ファイル書き出し後 1122005645 秒くらいからブロック I/O
が詰まり出し(blk_congestion_wait:ブロック I/O キュー空き
待 ち : × 点 )、 そ の 後 で ト ラ ン ザ ク シ ョ ン コ ミ ッ ト
(start_this_handle:トランザクションコミット待ち:+点)も
詰まってしまったと考えられる
図 2.5-73 WAIT キュー長の解析(その2)
図 2.5-72、図 2.5-73 から、ブロックI/Oキューが詰まり出し、その後でトランザクション
コミット処理が詰まってしまったことが分かり、先の仮説が正しかったことが確認できる。
write コール実行遅延の原因は、下記の2つの複合要因によるものだった。
・要因-1 lkst でトレース実行中にバッファ書き出しを行ってしまっていた
・要因-2 strace のログ書き出しが、大きなファイルの I/O 処理(本事例では lkst バッファ
の書き出し)がある場合、それに引っ張られて遅延する
要因-1 に関しては、トレース実行中にバッファ書き出しを行っても、lkst 自身のバッファ
書き出しはトレースされないだろう、という思い込みがあった。実際にはバッファ書き出
しの最中に発生したイベントを更に記録しようとするループ状態に陥ってしまい、なかな
かファイル書き出しが終了しない、という状態になってしまう。
要因-2 に関しては、本事例の障害は lkst のバッファ書き出しによる I/O 高負荷状態で発生
したが、lkst トレース中にバッファ書き出しを行わないようにした場合であっても、大き
なファイルを書き出すようなアプリケーションのトレース時には、同じ障害が発生すると
考えられる。
- 2-87 -
次に、処理時間が長い他のシステムコールについても障害要因が同じかどうか解析するた
め、図 2.5-63 中の他のシステムコールについても解析を行う(表 2.5-13 参照)。
表 2.5-13
strace で 100msec 以上掛かったシステムコール中のプロセス状態
項
システム
開始時刻※1
処理時間
プロセス状態
遅延タ
番
コール
※2
イプ
1
write
18.357494243
0.015721569
7、8
C
2
write
28.987744834
0.361722669
7、8
B
3
ptrace
29.350419772
0.412785495
7、8
B
4
ptrace
45.402513623
0.558999814
7、8
C
5
write
46.402062455
3.884396753
5、7、8
A
6
read
53.287346371
0.012485473
7、8
B
7
read
54.302765216
0.013471801
7、8
B
※1:開始時刻の秒数は下2桁以降のみ表示
※2:プロセス状態の意味は次の通り
5:割り込み不可状態で事象待ち、7:スケジューリング待ち、8:実行中
この表で、項番 5 が既に解析済みの、トランザクションコミットの待ち合わせを行ってい
た write である(タイプ A)。
その他のシステムコール中の lkst プロセス状態は、事象待ちになっておらず、単純にスケ
ジューリング待ちとなっていることが分かる。これらのスケジューリング待ち中に実行状
態となっているプロセスを調べた所、以下の2パターンがあることが分かった。
・多数のプロセス(stress 等)が実行 --- タイプ B
・ほとんどの時間を特定プロセスが CPU を占有 --- タイプ C
※特定プロセスは、kblockd/0、kjournald といった重い I/O 処理を行うプロセス
これまでの解析によって、strace がトレース対象プロセスを遅延させる障害の原因は、
下記によるものだということが分かる。
・原因-1 strace のログ書き出しが、大きなファイルの I/O 処理がある場合、それに引っ張
られて遅延する(タイプ A)
・原因-2 多数のプロセス実行によるスケジューリングでの遅延(タイプ B)
・原因-3 I/O 処理プロセスの CPU 占有による遅延(タイプ C)
2.5.2.4 対策
まず、lkst でトレースを行う場合は、バッファ書き出しをトレース中に行うのではなく、
トレース停止後に行うよう変更する必要がある。前述の手順中、バッファの書き出しを行
う以下の部分を変更することで、トレース停止後にバッファ書き出しを行うようにする。
- 2-88 -
<<< 変更前 >>>
e. lkst のバッファをファイルに出力する
# lkstbuf read -f lkst.log
<<< 変更後 >>>
e. lkst トレースを停止した後で lkst のバッファをファイルに出力する
# lkst stop
# lkstbuf read -f lkst.log
原因-1 strace のログ出力遅延に関しては、ログ出力先を ramfs/tmpfs 上のファイルにす
ることによって改善できる。strace ログ出力先を ramfs にする際の手順は、下記の通り。
a. ramfs をマウントする(スーパーユーザで行う必要あり)
# mount -t ramfs ramfs /mnt/ramfs
b. strace を実行(前述の手順中で、ログ出力先を変更した場合のもの)
$ strace -f -F -ttt -T -o /mnt/ramfs/strace.log sar 1 0
原因-2、3 に関しては、カーネル内のスケジューリングや I/O 処理に依存しており、対策
を施すことは難しい。nice 値変更等のチューニングを行うことも考えられるが、トレース
対象プロセスの本来の挙動を変えてしまう可能性があるため、問題がある。
以上により、完全な対策は不可能であるため、改善策として strace ログ出力先を ramfs 上
のファイルとすることとした。本事例の再現手順において、strace のログ出力先を ramfs
として障害を再現させた所、strace の write で長時間かかっていた部分(タイプ A)は解消
されていることが確認できた。
- 2-89 -
2.5.3 性能障害
性能障害の場合、oprofile などを利用してボトルネックを発見する。
表 2.5-14 I/O 負荷の高いベンチマークの性能障害の概要
番号
現象
2.5.3
解決日
2005/xx/xx
I/O 負荷の高いベンチマークにおいて性能上の問題が発見された。
分類
発生環境
2005/xx/xx
発生日
性能障害
OS
MIRACLE LINUX V4.0 beta
CPU
Xeon MP
メモリ
6GB
ハードディスク
SCSI
ネットワーク
原因
CPU キャッシュミスが多発していた。
対策
カーネルパッチを作成した。
解析手法
oprofile を利用した。
2.5.3.1 分析
oprofile でキャッシュミスを測定する。
例:
# opcontrol -e=BSQ_CACHE_REFERENCE:3000:0x200:1:1
ここで BSQ_CACHE_REFERENCE が測定すべきイベントである。3000 は当該イベン
トが 3000 回発生したらサンプリングする。0x200 はイベントマスクで L3 キャッシュミス
を測定する。次の 1 はカーネルモードをサンプリングすることを示し、最後の 1 はユーザ
ーモードをサンプリングする事を示す。したがって上記例はカーネル、ユーザー両方とも
プロファイリングする。
例:oprofile の詳細レポート。opreport -d の出力例
Counted BSQ_CACHE_REFERENCE events (cache references seen by the bus unit) with a unit mask
of 0x300 (multiple flags) count 3000
vma
samples %
image name
app name symbol name
c01bf3c0 57131
58.6964 vmlinux
vmlinux
__copy_from_user_ll
c01bf3e7 2
0.0035
c01bf3f0 53761
94.1013
c01bf3f2 1786
3.1261
c01bf3f4 13
0.0228
c01bf3f6 1157
2.0252
c01bf401 3
0.0053
c01bf402 369
0.6459
c01bf404 17
0.0298
c01bf405 23
0.0403
pattern1-0-cpu4-08112022/detail.out
ここで、c01bf3f0 でキャッシュミスを多発している事がわかる。vmlinux を逆アセンブ
- 2-90 -
ルすることによって当該アドレスが何をしているのかがわかる。
# objdump -S vmlinux-2.6.9-11.11AX
当該ソースコードは下記の通り。
c01bf3c0 <__copy_from_user_ll>:
c01bf3c0:
57
c01bf3c1:
83 f9 3f
c01bf3c4:
89 c7
c01bf3c6:
56
c01bf3c7:
89 d6
c01bf3c9:
76 0a
c01bf3cb:
31 d0
c01bf3cd:
85 05 00 a9 43 c0
c01bf3d3:
75 23
c01bf3d5:
89 c8
c01bf3d7:
83 f9 07
c01bf3da:
76 18
c01bf3dc:
89 f9
c01bf3de:
f7 d9
c01bf3e0:
83 e1 07
c01bf3e3:
29 c8
c01bf3e5:
f3 a4
c01bf3e7:
89 c1
c01bf3e9:
c1 e9 02
c01bf3ec:
83 e0 03
c01bf3ef:
90
c01bf3f0:
f3 a5
c01bf3f2:
89 c1
c01bf3f4:
f3 a4
c01bf3f6:
eb 09
c01bf3f8:
89 f8
c01bf3fa:
e8 e7 fe ff ff
c01bf3ff:
89 c1
c01bf401:
5e
c01bf402:
89 c8
c01bf404:
5f
c01bf405:
c3
c01bf406:
90
c01bf407:
90
push
%edi
cmp
$0x3f,%ecx
mov
%eax,%edi
push
%esi
mov
%edx,%esi
jbe
c01bf3d5 <__copy_from_user_ll+0x15>
xor
%edx,%eax
test
%eax,0xc043a900
jne
c01bf3f8 <__copy_from_user_ll+0x38>
mov
%ecx,%eax
cmp
$0x7,%ecx
jbe
c01bf3f4 <__copy_from_user_ll+0x34>
mov
%edi,%ecx
neg
%ecx
and
$0x7,%ecx
sub
%ecx,%eax
repz movsb %ds:(%esi),%es:(%edi)
mov
%eax,%ecx
shr
$0x2,%ecx
and
$0x3,%eax
nop
repz movsl %ds:(%esi),%es:(%edi) **この部分
mov
%eax,%ecx
repz movsb %ds:(%esi),%es:(%edi)
jmp
c01bf401 <__copy_from_user_ll+0x41>
mov
%edi,%eax
call
c01bf2e6 <__copy_user_zeroing_intel>
mov
%eax,%ecx
pop
%esi
mov
%ecx,%eax
pop
%edi
ret
nop
nop
上記ソースコードの repz movsl %ds:(%esi),%es:(%edi) がキャッシュミスを多発してい
る事がわかる。
I/O 負荷の高いベンチマークで write(2)を多発するようなアプリケーションの場合、
filemap_copy_from_user()で__copy_from_user()が呼ばれている。ある関数がどこから呼ば
れているかは OProfile のコールグラフ機能によって容易に発見できるので、それを利用し
てどこから copy_from_user が呼ばれているか調査した。
# opcontrol --callgraph=#depth
図 2.5-74 call graph の設定例
opcontrol で#depth に測定すべき深さを指定する。コールグラフの計測はオーバヘッド
がかかるので注意が必要である。
計測後 opstack でコールグラフのレポートを作成し分析する。
- 2-91 -
#
opstack -f -p /lib/modules/$(uname -r) > ${saveDir}/callgraph.out 2>&1
図 2.5-75 call graph のレポート作成
さて__copy_from_user_ll()の実行例は下記のとおりである。
0
0
6
8.8e-04
vmlinux copy_from_user
4157
21.8433
325670 47.5335
vmlinux __generic_file_aio_write_nolock
14874
78.1567
359462 52.4656
vmlinux generic_file_buffered_write
241263
1
13.7168
1
100.000
5.7e-05
0
vmlinux __copy_from_user_ll
0
vmlinux __copy_user_zeroing_intel
図 2.5-76 コールグラフ(__copy_from_user_ll)
copy_from_user()/__generic_file_aio_write_nolock()/generic_file_buffered_write() と い
う関数から呼ばれていることが分かる。
filemap_copy_from_user(struct page *page, unsigned long offset,
const char __user *buf, unsigned bytes)
{
char *kaddr;
int left;
kaddr = kmap_atomic(page, KM_USER0);
left = __copy_from_user(kaddr + offset, buf, bytes);
kunmap_atomic(kaddr, KM_USER0);
if (left != 0) {
/* Do it the slow way */
kaddr = kmap(page);
left = __copy_from_user(kaddr + offset, buf, bytes);
kunmap(page);
}
return bytes - left;
}
通常、write(2)の場合、ユーザー空間からカーネル空間へデータをコピーした後、すぐに
ディスクに書き出されるのではなく、非同期にディスクに書き出される。従ってユーザー
空間からカーネル空間へコピーされたデータがすぐアクセスされる可能性は低い。
表 2.5-15 Pentium4/Xeon におけるキャッシュのサイズ
キャッシュ
キャッシュサイズ
L1(一次)キャッシュ
8KB
L2(二次)キャッシュ
512KB
L3(三次)キャッシュ
1 ないし 2MB
- 2-92 -
十分大きなファイルを書き出す場合、データはキャッシュにはのりきらないので当然キ
ャッシュミスを起こす。特にメモリへの書き込みの場合、すぐにアクセスされないのであ
るから、キャッシュにのせる意味はない。キャッシュにのせる必要のないデータをキャッ
シュにのせる事によってすぐに必要になるであろうデータを追い出してしまう事を cache
pollution と呼ぶ。上記の例は典型的な cache pollution が発生している。
作成したパッチの部分
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
略
__asm__ __volatile__(
"
"0:
"
"
"1:
"
"2:
"21:
"
"
"3:
"31:
"
"
.align 2,0x90\n"
movl 32(%4), %%eax\n"
cmpl $67, %0\n"
jbe 2f\n"
movl 64(%4), %%eax\n"
.align 2,0x90\n"
movl 0(%4), %%eax\n"
movl 4(%4), %%edx\n"
movnti %%eax, 0(%3)\n"
movnti %%edx, 4(%3)\n"
movl 8(%4), %%eax\n"
movl 12(%4),%%edx\n"
movnti %%eax, 8(%3)\n"
movnti %%edx, 12(%3)\n"
そこで、cache pollution を発生させないため、レジスタからメモリへ転送する時、キャ
ッシュをバイパスする命令(MOVNTI 命令)を利用した API(__copy_from_user_ll_nocache)
を作成し、filemap_copy_from_user()でそれを利用するようにした。
その結果、
zキャッシュミス(BSQ_CACHE_REFERENCE,0x200)
改良版/オリジナル版
16153/55033=29.35% (約 70%減)
zクロック数(GLOBAL_POWER_EVENTS)
改良版/オリジナル版
1234232/1705473=72.37%(約 30%減)
z__copy_from_user_ll_nocache(改良版)と__copy_from_user_ll のキャッシュミス
1/37117=0
改良版
pattern9-0-cpu4-0-09031504/summary.out 200/nocache 16153
pattern9-0-cpu4-0-09031508/summary.out 3f/nocache 1234232
pattern9-0-cpu4-0-09031512/summary.out GLOBAL_POWER_EVENTS 1513271
オリジナル版
pattern9-0-cpu4-0-09031546/summary.out 200/orig 55033
pattern9-0-cpu4-0-09031549/summary.out 3f/orig 1304147
pattern9-0-cpu4-0-09031553/summary.out GLOBAL_POWER_EVENTS 1705473
cache pollution の場合は、MOVNTI 命令のようなキャッシュをバイパスする命令を利用
すると効果がある事が確認できた。
- 2-93 -
2.6 フリーズ
2.6.1 フリーズ障害の解析
実際にフリーズを起こした障害を例にあげ、採取されたダンプからの解析と対策を
以下に報告する。
2.6.1.1 概要
本障害とその対策の概要を表 2.6-2 に示す。
表 2.6-1 高優先度プロセスの異常稼動による現象の概要
番号
2.6.1
現象
性能情報採取コマンド(優先度:高)を実行中にフリーズが発生した
分類
フリーズ
発生環境
OS
Redhat AS4.0 update1
CPU
Xeon MP 3.0G × 1
メモリ
4GBytes
ハードディスク
72Gbytes
ネットワーク
IntelPro1000
原因
発生日
2005/xx/xx
解決日
2005/xx/xx
情報採取パッケージ(sysstat)が未導入であったため、情報採取コマンド
を実行する高優先度の性能情報採取シェルスクリプト(status.sh)の
子プロセスが、wait なしでループしたため
対策
情報採取パッケージ(sysstat)コマンドの導入
解析手法
(1) 解析資料採取
(2) 現象発生時プロセス特定
(3) 現象発生時のプロセス詳細確認
(4) ログファイル確認
(5) 原因特定
2.6.1.2 障害情報収集と初期切り分け
性能情報採取ツール(status.sh)を実行したところ、実行した端末、コンソールへの
応答がなくなった。
コンソールからのコマンド入力に対して応答がないフリーズの場合、SysRq キー/
NMI イ ン タ ー フ ェ ー ス に よ り ダ ン プ 採 取 を 行 う 。 シ ス ロ グ フ ァ イ ル
(/var/log/messages)及び、その時稼動していたアプリケーションのログファイルを採
取しておく。
- 2-94 -
2.6.1.3 解析
以下の手順で解析を行った。
(1)
解析資料採取
次の資料の採取を行う。
・ダンプ(SysRq キーにより、diskdump で採取:diskdump 導入/設定方法は、
3.6.1.1 を参照のこと)
・性能情報採取ツールのログファイル
(2)
現象発生時のプロセス特定
ダンプ解析ツール Alicia でダンプ解析を開始する。
# alicia
-crash
map-file
vmlinux
dump-file
KERNEL: /usr/src/linux-2.6.9-11ELsmp-devmem/vmlinux
DUMPFILE: ./vmcore
CPUS: 1
←②
DATE: Sun Sep 11 04:45:11 2005
UPTIME: 49 days, 17:01:52
←①
←①
LOAD AVERAGE: 3.39, 0.96, 0.34
TASKS: 74
NODENAME: redhatas4u1
RELEASE: 2.6.9-11ELsmp-devmem
←②
VERSION: #1 SMP Sun Sep 11 03:06:25 JST 2005
MACHINE: i686
←②
MEMORY: 2 GB
(2393 Mhz)
←②
PANIC: "Oops: 0002 [#1]" (check log for details)
PID: 21191
←③
COMMAND: "echo"
←③
TASK: dca7d230
←③
[THREAD_INFO: de469000]
←③
CPU: 0
STATE: TASK_RUNNING (PANIC)
alicia>
図 2.6-1 Alicia 起動時の出力メッセージ
Aliciaの最初の出力 (図 2.6-1)より、
① ダンプ採取された時間、稼動時間
② システム情報(カーネルのリリース、バーション、CPU 数、メモリ量等)
③ パニック情報(Oops タイプ、PID、コマンド、タスク等)
が得られる。詳細なパニック情報を得るために、log コマンドを入力する。
- 2-95 -
alicia> log
(途中 略)
SysRq : Crashing the kernel by request
Unable to handle kernel NULL pointer dereference at virtual address 00000000
printing eip:
c0201580
*pde = 20688001
Oops: 0002 [#1]
SMP
Modules linked in: md5(U) ipv6(U) parport_pc(U) lp(U) parport(U) autofs4(U) i2c_
dev(U) i2c_core(U) sunrpc(U) scsi_dump(U) diskdump(U) dm_mod(U) button(U) batter
y(U) ac(U) uhci_hcd(U) hw_random(U) e1000(U) floppy(U) sg(U) ext3(U) jbd(U) mpts
csih(U) mptbase(U) sd_mod(U) scsi_mod(U)
CPU:
0
EIP:
0060:[<c0201580>]
EFLAGS: 00010046
Not tainted VLI
(2.6.9-11ELsmp-devmem)
EIP is at sysrq_handle_crash+0x0/0x8
eax: 00000063
ebx: c032fa94
ecx: f691f000
edx: de469e44
esi: 00000063
edi: f691f000
ebp: de469e44
esp: de469d40
ds: 007b
es: 007b
ss: 0068
Process echo (pid: 21191, threadinfo=de469000 task=dca7d230)
Stack: c02016c2 c02e782b c02e8c3c 00000006 00000001 f7d2d180 00000001 0000002e
c01fc4a8 de469e44 c032de20 f7d24064 f7d2d180 0000002e c025c231 00000001
00000001 0000002e f7d24064 00000001 00000000 c025eeef 00000001 0000002e
図 2.6-2 log コマンドの出力メッセージ
図 2.6-2 のlogコマンドの応答より、このダンプは、SysRqキーの入力により採取され
たことが確認できる。
フリーズは、現象発生時に実行中のプロセスが起因して発生している可能性が高い
ので、原因特定の第一歩として、ps コマンドを実行し、現象発生時に実行中だったプ
ロセスを確認する。
- 2-96 -
alicia> ps
PID
PPID
CPU
TASK
ST
%MEM
VSZ
RSS
0
0
0
c0314a60
RU
0.0
0
0
1
0
0
f7f21630
RU
0.0
2004
552
(途中
COMM
[swapper]
init
現象発生時に稼動してい
略)
たプロセスの親プロセス
の親プロセス
3619
3587
0
dc4da030
RU
0.0
2724
924
top
3620
2708
0
dc4db630
IN
0.1
7676
2168
sshd
3622
3620
0
dc4db0b0
IN
0.1
5300
1164
sftp-server
3641
3549
0
dc4dab30
IN
0.1
6768
1124
status.sh
3699
3641
0
dc4da5b0
IN
0.0
2388
860
sh
3705
3699
0
dc42abb0
IN
0.0
2640
464
sleep
3716
3641
0
dc42b130
IN
0.0
4124
860
sh
3720
3716
0
dc42b6b0
IN
0.0
2884
464
sleep
3734
3641
0
dc42a630
IN
0.0
3724
848
sh
3742
3734
0
dc42a0b0
IN
0.0
3728
464
sleep
3752
3641
0
dcaa5730
IN
0.0
3708
852
sh
3756
3752
0
dcaa51b0
IN
0.0
3164
460
sleep
3770
3641
0
dcaa4c30
IN
0.0
3292
848
sh
現象発生時に稼動
3774
3770
0
dcaa46b0
IN
0.0
3108
464
sleep
していたプロセス
3788
3641
0
dcaa4130
IN
0.0
2924
852
sh
の親プロセス
3797
3788
0
dca7d7b0
IN
0.0
3660
464
sleep
3815
3641
0
dca7ccb0
IN
0.0
4120
856
sh
3865
3641
0
dca7c730
IN
0.0
2136
860
sh
3870
3865
0
dca7c1b0
IN
0.0
2320
464
sleep
“>”の付いたプロセス
4056
3641
0
dca77830
IN
0.0
2472
856
sh
が現象発生時に稼動
4060
4056
0
dca772b0
IN
0.0
2040
508
vmstat
していたプロセス
5054
3641
0
dca76d30
IN
0.0
2604
460
sleep
> 21191
3815
0
dca7d230
RU
0.0
1368
180
echo
(性能情報採取ツールの
メインプロセス)
alicia>
図 2.6-3 ps コマンドの出力メッセージ
図 2.6-3 より、システムがフリーズしてダンプを採取した時点で、
・ 稼動していたプロセス(PID:21191)は、“echo”コマンド実行
・ その親プロセス(PID:3815)は、シェルスクリプトを実行中
・ その親プロセス(PID:3641)は、フリーズが発生する直前に投入した性能情
報採取ツール(status.sh)
- 2-97 -
であることがわかる。
(3) 現象発生時のプロセス詳細確認
次に各プロセスの Cputime を計算して、使用量の大きい順番にソートして表示する
LDAS(Alicia の拡張コマンド)を使用して、Cputime をどのプロセスが多く消費し
ているかを調べる。
alicia> ps_cpu | more
PID
PPID CPU
TASK
ST %MEM
VSZ
RSS Cputime COMM
0
0
0 c0314a60 RU
0.0
0
0
3815
3641
0 dca7ccb0 IN
0.0
4120
856
1
0
0 f7f21630 RU
0.0
2004
552
2853
1
0 c2386230 IN
0.8
58
1
0 f7cd7730 IN
0.0
0
0
2989
1
0 f69523b0 RU
0.3
9116
5872
515 hald
2660
1
0 f6997630 RU
0.2
11456
3772
258 cupsd
223
1
0 f7cd66b0 RU
0.0
0
0
162 [kjournald]
2964
1
0 c239a830 IN
0.1
2948
1208
128 dbus-daemon
3641
3549
0 dc4dab30 IN
0.1
6768
1124
106 status.sh
2935
1
0 f6a965b0 IN
0.2
5992
3336
68 xfs
3619
3587
0 dc4da030 RU
0.0
2724
924
68 top
57
4
0 f7c700b0 IN
0.0
0
0
2708
1
0 f6952930 IN
0.1
5640
1652
57 sshd
3547
2708
0 df536630 IN
0.1
7744
2196
41 sshd
19064 17632
187081 [swapper]
3994 sh
708 init
690 cannaserver
609 [kswapd0]
-1
59 [pdflush]
図 2.6-4 ps_cpu(Alicia の LDAS)コマンドの出力メッセージ
最も多く Cputime を使用しているのは、swapper である。swapper は、仮想記憶
を司るカーネルプロセスで、PID:0 で起動している。このプロセスは、アイドル状
態でも他のプロセスより、Cputime を使用しているのが経験的にわかっている。今回
は、フリーズ直前に入力した性能情報採取ツール status.sh に関連するプロセスが 2
番目に Cputime を多く使用しているので、そのプロセス(PID:3815)から調べて、
それに関連するプロセスも念のため、調べてみる。
性能情報採取ツール(status.sh)に関連するプロセス3つについて、ps –t コマン
ドで、それぞれの Cputime を調べてみる。LDAS ps_cpu では、このコマンドで応答
される USER TIME と SYSTEM TIME の合計が Cputime として表示される。
alicia> ps -t 3815
- 2-98 -
PID: 3815
TASK: dca7ccb0
CPU: 0
COMMAND: "sh"
RUN TIME: 183930010746 days, 10:02:11
START TIME: 2555191149513933013
PID:3815 が 使 用 し て い る
USER TIME: 929
USER/SYSTEM TIME
SYSTEM TIME: 3065
alicia> ps -t 21191
PID: 21191
TASK: dca7d230
CPU: 0
COMMAND: "echo"
RUN TIME: 164461182487 days, 01:15:15
PID:21191 が 使 用 し て い る
START TIME: 4237297911123149033
USER/SYSTEM TIME
USER TIME: 0
SYSTEM TIME: 1
alicia> ps -t 3641
PID: 3641
TASK: dc4dab30
CPU: 0
COMMAND: "status.sh"
RUN TIME: 179188446388 days, 01:34:27
START TIME: 2964862310075597009
PID:3641 が 使 用 し て い る
USER TIME: 34
USER/SYSTEM TIME
SYSTEM TIME: 72
alicia>
図 2.6-5 ps –t コマンドの出力メッセージ
図 2.6-4/図 2.6-5 より、プロセス(PID:3815) が実行しているシェルスクリプトが異
常に Cputime(USER / SYSTEM TIME) を使用していることが確認できる。
まず、プロセス(PID:3815)のシェルスクリプトでは、どのようなファイルをオープ
ンしているかを調べてする。これには、files コマンドを使用する。
alicia> files 3815
PID: 3815
ROOT: /
TASK: dca7ccb0
CPU: 0
COMMAND: "sh"
CWD: /opt/status
PID:3815 がオープンし
ているファイル(iostat
FD
FILE
DENTRY
INODE
TYPE
PATH
0
ebebe580
f7d9d804
f7d9b93c
CHR
/dev/null
1
f2299280
ebebf5a4
f6a68cc8
CHR
/dev/pts/0
2
ebebec80
f7d9d804
f7d9b93c
CHR
/dev/null
255
ebebe380
f228689c
df53c770
REG
/var/tmp/statdir_3641/iostatxdcmd
を定期的に起動している
シェルスクリプト)
alicia>
図 2.6-6 files コマンドの出力メッセージ
オープンしているファイルの中にiostatを定期的に起動しているシェルスクリプト
があることがわかる。(図 2.6-6)
- 2-99 -
/var/tmp/statdir_3641/iostatxdcmd
次に、プロセス(PID:3815)の情報を得るために、task_struct 構造体を、struct
コマンドを使用して調べてみる。task_struct 構造体は、プロセス毎に生成され、プ
ロセスを管理するために使用される。
alicia> ps 3815
PID
PPID
CPU
TASK
ST
%MEM
VSZ
RSS
COMM
3815
3641
0
dca7ccb0
IN
0.0
4120
856
sh
alicia>
alicia> struct task_struct dca7ccb0 | more
struct task_struct {
state = 1,
thread_info = 0xdeb17000,
usage = {
counter = 10
},
flags = 4194560,
ptrace = 0,
lock_depth = -1,
prio = 0,
static_prio = 120,
run_list = {
next = 0x100100,
prev = 0x200200
},
静的優先度が 99(高優先度)に
(途中 略)
設定されている。
rt_priority = 99,
(途中 略)
図 2.6-7 PID:3815 に対する ps コマンドの出力メッセージ
図 2.6-7 より、このプロセスの優先度(rt_priority)が 99 に設定されていることがわか
る。この優先度は、通常のプロセスでは、静的優先度 0 が設定されているが、このプ
ロセスは、処理の優先度を上げるために、静的優先度が 99 に設定されている。
ここまでの解析で、プロセス(PID:3815)が優先度を上げたシェルスクリプトを実
行していて、Cputime を異常に多く使用していることが判った。そこで、このプロセ
スがどのような処理を実際に行っているかをシェルスクリプトや、その実行結果のロ
- 2-100 -
グファイルから解析する。
(4)
ログファイル確認
プロセス(PID:3815)がどのような処理を行っていたかを確認するために、その親
プロセスである性能情報採取ツールのメインプロセス(status.sh)のシェルスクリプ
トの内容を確認してみる。その結果、次のような採取コマンドを高優先度(静的優先
度値を上げている)で実行していることがわかった。
・sar
・mpstat
・iostat
そこで、上記採取コマンドが出力している実行時のログファイルを確認したところ、
以下のことがわかった。
上記採取コマンドの起動方法およびログファイルは次のとおり。ログ採取のディレ
クトリィ(/var/tmp/statdir_3641/)は、メインプロセス(status.sh)が作成し、各
コマンド実行時に指定している。sar、mpstat コマンドは、INTERVAL の間隔で、
COUNT 回数まで実行するのに対して、iostat コマンドは、採取データを編集するツ
ールで編集しやすいようにしているため、INTERVAL の間隔指定をし、while 文で外
側のループで複数回実行させている。
● sar の起動方法
# /usr/bin/sar
-o
/var/tmp/statdir_3641/sar.log
INTERVAL COUNT >/dev/null 2>&1 &
● mpstat の起動方法
# /usr/bin/mpstat -P ALL INTERVAL COUNT >>/var/tmp/statdir_3641/mpstat.log 2>/dev/null &
● iostat の起動方法
# sh
/var/tmp/statdir_3641/iostatxdcmd
2>/dev/null
&
# シェルスクリプト(/var/tmp/statdir_3641/iostatxdcmd)
while
[ 1 ]
do
/bin/echo
iostat
/bin/echo
INTV
/bin/date
>>/var/tmp/statdir_3641/iostat_xd.log
/usr/bin/iostat
>>/var/tmp/statdir_3641/iostat_xd.log
INTERVAL >>/var/tmp/statdir_3641/iostat_xd.log
-x
-d
INTERVAL 2 >>/var/tmp/statdir_3641/iostat_xd.log
done
/var/tmp/statdir_3641/以下に採取されるはずの各種ログファイルを確認した結果、採
取 コ マ ン ド ( sar 、 mpstat ) の ロ グ フ ァ イ ル ( /var/tmp/statdir_3641/sar.log 、
- 2-101 -
mpstat.log)がないことおよび採取コマンド(iostat)が正常結果を出力していない
ことが確認できた。
(5)
原因特定
iostat コマンドがエラーになった原因を調べるために、iostat コマンドに関する情
報採取を行う。そのために、まず、iostat コマンドをコマンドラインから入力してみ
ると、“iostat:command not found”と表示され、iostat コマンドが導入されていな
いことが判明した。メインプロセスから起動される各コマンドのうち、sar、mpstat
コマンドは 1 回の実行でエラーになればそこで終了してしまうが、iostat コマンドの
場合、コマンド実行がエラーになっても、その外側の while 文のループが wait なし
で繰り返し続けることになる。しかもその実行は、高優先度に設定されているため、
他のプロセスが処理されなくなり、フリーズ状態に陥ったと考えられる。本システム
には iostat が含まれる sysstat パッケージが導入されていないと仮定し、rpm コマン
ドで sysstat パッケージの導入確認を実施した結果、該パッケージが導入されていな
いことが明らかになった。
2.6.1.4 対策
sysstat パッケージを rpm コマンドで導入し、性能情報採取ツール(status.sh)
でシステムがフリーズすることなく、性能情報を採取することを確認した。
また、性能情報採取ツールのシェルスクリプトを変更し、実行に必要な各コマン
ドが導入されているかを判断するように改良した。
- 2-102 -
2.7 カーネルパニック
2.7.1 カーネルパニック障害の解析
実際にカーネルパニックを起こした障害を例にあげ、採取されたダンプファイルから
の解析と対策を以下に報告する。
2.7.1.1 概要
本障害とその対策の概要を 表 2.7-1 に示す。
表 2.7-1
メモリ破壊によるカーネルパニックの概要
番号
2.7.1
現象
突然、カーネルパニックが発生した
分類
カーネルパニック
発生環境
OS
Red Hat AS4.0 update1
CPU
Xeon 2.4GHz×2
メモリ
2Gbyte
ハードディスク
72Gbyte
ネットワーク
IntelPro1000
発生日
2005/xx/xx
原因
ハードウェア障害でメモリ破壊
対策
メモリ交換
解析手法
(1)
解析資料の採取
(2)
現象確認
(3)
障害発生時の命令確認
(4)
逆アセンブルリスト
(5)
原因特定
解決日
2005/xx/xx
2.7.1.2 障害情報収集と初期切り分け
カーネルパニックの場合は、まず、ダンプファイルが採取されているかを確認する。
システムはカーネルパニック時にダンプが採取されるように設定されていなければ
ならないが、各ダンプ採取ツールには、以下のようにダンプが採取される方法に違い
がある。
(1) diskdump/netdump は、カーネルパニック後のリブート後に、/var/crash ディレクトリ
にダンプが採取される。
(2) LKCD は、カーネルパニック後のリブート後に、/var/log/dump ディレクトリにダンプ
が採取される。
(3) kdump は、カーネルパニック時に、ダンプ採取専用のカーネルが起動される。
/proc/vmcore にダンプ・イメージがアクセスできるようになっているので、手動で保存
- 2-103 -
する。
(4) mkdump は、カーネルパニック時に、ダンプ採取専用カーネルが起動される。ダンプ
採取後に、通常のカーネルが起動され、ダンプパーティションにダンプが採取される。
2.7.1.3 解析
以下の手順で解析を行った。
(1) 解析資料の採取
次の資料が採取されているか確認する。
・ダンプ(diskdump で採取:diskdump の導入/設定方法は、3.6.1.1 を参照)
(2) 現象確認
ダンプ解析ツール Alicia でダンプ解析を開始する。
# alicia –crash map vmlinux dump-file
KERNEL: /usr/src/linux-2.6.9-11ELsmp-devmem/vmlinux
DUMPFILE: /var/crash/127.0.0.1-2005-09-11-03:29/vmcore
CPUS: 2
←②
DATE: Sun Sep 11 03:29:59 2005
UPTIME: 00:09:08
←①
←①
LOAD AVERAGE: 0.01, 0.13, 0.16
TASKS: 61
NODENAME: redhatas4u1
RELEASE: 2.6.9-11ELsmp-devmem
←②
VERSION: #1 SMP Sun Sep 11 03:06:25 JST 2005
MACHINE: i686
←②
MEMORY: 2 GB
(2392 Mhz)
←②
PANIC: "Oops: 0002 [#1]" (check log for details)
PID: 3297
←③
←③
COMMAND: "perl"
TASK: f7451930
←③
[THREAD_INFO: e87de000]
←③
CPU: 0
STATE: TASK_RUNNING (PANIC)
alicia>
図 2.7-1 Alicia 起動時の出力メッセージ
Aliciaの最初の出力(図 2.7-1)より、
① ダンプ採取された時間、稼動時間
- 2-104 -
② システム情報(カーネルのリリース、バーション、CPU 数、メモリ量等)
③ パニック情報(Oops タイプ、PID、コマンド、タスク等)
が得られる。これにより、perl コマンドを実行中にダンプが採取されていたことが判
る。次に、詳細なパニック情報を得るために、log コマンドを入力する。
log コマンドより、障害発生時の”Oops”の情報を確認することができる。log コマン
ドは、パニック発生時にメモリ上に残されたシステムログのバッファの内容を表示す
るコマンドである。Linux
カーネルはシステム障害を検知し、パニックによってシス
テム停止を行う場合、どのような障害を検知したかをシステムログに出力している。
alicia> log
参照しようとしたアドレス
(途中 略)
Unable to handle kernel NULL pointer dereference at virtual address 0000008f
printing eip:
障害が発生したアドレス
c0168a18
*pde = 27f93001
Oops: 0002 [#1]
SMP
Modules linked in: scsi_dump(U) diskdump(U) md5(U) ipv6(U) parport_pc(U) lp(U) p
arport(U) autofs4(U) i2c_dev(U) i2c_core(U) sunrpc(U) dm_mod(U) button(U) batter
y(U) ac(U) uhci_hcd(U) hw_random(U) e1000(U) floppy(U) sg(U) ext3(U) jbd(U) mpts
csih(U) mptbase(U) sd_mod(U) scsi_mod(U)
CPU:
0
EIP:
0060:[<c0168a18>]
EFLAGS: 00010287
Not tainted VLI
(2.6.9-11ELsmp-devmem)
EIP is at sys_flock+0x0/0x119
eax: 0000008f
ebx: 00000003
ecx: 00000002
edx: 0000007b
esi: 00000002
edi: 093902f8
ebp: e87de000
esp: e87defc0
ds: 007b
es: 007b
ss: 0068
Process perl (pid: 3297, threadinfo=e87de000 task=f7451930)
Stack: c02c736b 00000003 00000002 04598c0c 00000002 093902f8 bffe2d28 0000008f
0000007b 0000007b 0000008f 004737a2 00000073 00000282 bffe2cf8 0000007b
Call Trace:
[<c02c736b>] syscall_call+0x7/0xb
Code: 00 fe ff ff 8d 54 24 20 8d 43 1c e8 95 6c fb ff 85 f6 89 f7 0f 84 56 ff ff
ff 89 d8 e8 0f ea ff ff 83 c4 40 89 f8 5b 5e 5f 5d c3 <00> 00 f7 ff ff ff 57 56
53 57 8b 44 24 18 8b 5c 24 1c e8 1e e3
alicia>
図 2.7-2 log コマンドの出力メッセージ
- 2-105 -
図 2.7-2 より、以下のことが確認できる。
・障害が発生したアドレスは、0xc0168a18
・参照しようとしたアドレスは、0x8f
(3) 障害発生時の命令確認
障害発生時にどの命令が処理されていたかを確認するため、停止したアドレス付近の
メモリ内容をアセンブリコードで表示させる逆アセンブラ dis コマンドを入力する。
alicia> dis 0xc0168a18 10
0xc0168a18 <sys_flock>: add
%al,(%eax)
0xc0168a1a <sys_flock+2>:
idiv
%edi
0xc0168a1c <sys_flock+4>:
(bad)
0xc0168a1d <sys_flock+5>:
call
*0x56(%edi)
0xc0168a20 <sys_flock+8>:
push
%ebx
0xc0168a21 <sys_flock+9>:
push
%edi
0xc0168a22 <sys_flock+10>:
mov
0x18(%esp),%eax
0xc0168a26 <sys_flock+14>:
mov
0x1c(%esp),%ebx
0xc0168a2a <sys_flock+18>:
call
0xc0156d4d <fget>
0xc0168a2f <sys_flock+23>:
test
%eax,%eax
図 2.7-3 dis コマンドの出力メッセージ
図 2.7-3 より、障害が発生したアドレスでは、sys_flockルーチンの最初の命令addを実
行していることが確認できる。実行の内容は、
al + (eax) ⇒ al
である。次に、AL レジスタ、EAX レジスタの内容がどのような値であったかを調べる
ために、バックトレースを表示する bt コマンドを入力する。
btコマンドでは、図 2.7-4 のようにスタック情報を表示することができる。
alicia> bt
PID: 3297
TASK: f7451930
CPU: 0
COMMAND: "perl"
#0 [e87dee34] disk_dump at f89619f6
#1 [e87dee38] printk at c01219d3
#2 [e87dee44] freeze_other_cpus at f8961827
#3 [e87dee54] start_disk_dump at f89618d2
#4 [e87dee64] try_crashdump at c0133479
#5 [e87dee6c] die at c0106009
#6 [e87deea0] do_page_fault at c011a88c
#7 [e87def80] error_code (via page_fault) at c02c7e45
EAX: 0000008f
EBX: 00000003
ECX: 00000002
EDX: 0000007b
- 2-106 -
EBP: e87de000
DS:
007b
ESI: 00000002
ES:
007b
CS:
0060
EIP: c0168a18
ERR: ffffffff
EDI: 093902f8
EFLAGS: 00010287
#8 [e87defbc] sys_flock at c0168a18
#9 [e87defc0] system_call at c02c7364
EAX: 0000008f
EBX: 00000003
ECX: 00000002
EDX: 04598c0c
DS:
007b
ESI: 00000002
ES:
EDI: 093902f8
SS:
007b
ESP: bffe2cf8
EBP: bffe2d28
CS:
0073
EIP: 004737a2
ERR: 0000008f
007b
EFLAGS: 00000282
alicia>
図 2.7-4 bt コマンドの出力メッセージ
バックトレースから、EAX レジスタの値が 0x8f であることが判る。また、この 0x8f
をアドレス情報としてそのメモリ内容を参照しようとしたところで、ページフォルト
の障害が発生したことが判る。ページフォルトとは、CPU で実行中の命令によって
メモリ上に存在しないページアドレスを参照することにより発生する障害で、ユーザ
プロセス処理、カーネル処理のいずれでも発生しうる。ページフォルトそのものは異
常処理ではなく、正常な処理中にも発生するが、カーネルの処理中には発生しないよ
うに設計されている。にもかかわらずカーネル処理中にページフォルトが発生した場
合には、不正なカーネル処理が行われたと判断し、カーネルは自身を停止させる。
次にEAXレジスタの値を元に、一連の処理が正しく実行されたと仮定して、カーネ
ル処理を追っていく。sys_flockをコールしているのは、バックトレース#9 エントリ
より、system_callであることが判る。system_callルーチンの逆アセンブラを表示さ
せるため、disコマンドを入力する。(図 2.7-5)
alicia> dis c02c7343 10
0xc02c7343 <system_call+11>:
mov
$0x7b,%edx
0xc02c7348 <system_call+16>:
mov
%edx,%ds
0xc02c734a <system_call+18>:
mov
%edx,%es
0xc02c734c <system_call+20>:
mov
$0xfffff000,%ebp
0xc02c7351 <system_call+25>:
and
%esp,%ebp
0xc02c7353 <system_call+27>:
testb
$0x81,0x8(%ebp)
0xc02c7357 <system_call+31>:
jne
0xc02c73cc <syscall_trace_entry>
0xc02c7359 <system_call+33>:
cmp
$0x11d,%eax
0xc02c735e <system_call+38>:
jae
0xc02c7408 <syscall_badsys>
0xc02c7364 <syscall_call>:
call
*0xc03159bc(,%eax,4)
0xc02c736b <syscall_call+7>:
mov
%eax,0x18(%esp,1)
図 2.7-5 dis コマンドの出力メッセージ
- 2-107 -
sys_flock をコールする部分のコードは、
call (0xc03159bc+EAX×4)
となっている。ベースとなっている 0xc03159bcの内容を、rdコマンドを使って表示させ
てみると、図 2.7-6 のように 4 バイトずつのアドレス情報が得られる。
alicia> rd c03159bc 152
c03159bc:
c012bb41 c0123a5f c0104928 c01561dc
A..._:..(I...a..
c03159cc:
c015623e c01557fd c01558ef c0124d15
>b...W...X...M..
(途中 略)
c0315bcc:
c012e0e4 c01550ec c0159fd1 c016d8af
.....P..........
c0315bdc:
c0121156 c012cc15 c0134708 c013471f
V........G...G..
c0315bec:
c0155dc7 c0165e05 c0166504 c0168a18
.]...^...e......
c0315bfc:
c014d655 c015661f c0156681 c012e15d
U....f...f..]...
c0315c0c:
c0157567 c0126654 c014a01d c014a113
gu..Tf..........
alicia>
図 2.7-6 rd コマンドの出力メッセージ
EAX レジスタの値が 0x8f の場合のアドレス
0xc03159bc + 0x8f × 4 = 0xc0315bf8
を調べてみると、sys_flock ルーチンのアドレス(0xc0168a18)を示している。このこ
とから、このアドレス領域は、各システムコールの処理ルーチンのアドレステーブル
であると仮定することができる。
カーネルのソースコードを調べてみると、0x8fはsys_flockのシステムコールIDであり、
このルーチン(sys_flock)では、EAXレジスタが、システムコールIDで使用されている
ことが判る。次にシステムコールIDを定義している /usr/include/asm/unistd.hを 図
2.7-7 に示す。0x8fは、10 進で 143 である。
#define _ASM_I386_UNISTD_H_
/*
* This file contains the system call numbers.
*/
#define __NR_restart_syscall
0
#define __NR_exit
1
#define __NR_fork
2
#define __NR_read
3
- 2-108 -
(途中 略)
#define __NR__llseek
140
#define __NR_getdents
141
#define __NR__newselect
142
#define __NR_flock
143
#define __NR_msync
144
#define __NR_readv
145
#define __NR_writev
146
#define __NR_getsid
147
#define __NR_fdatasync
148
(途中
略)
図 2.7-7 /usr/include/asm/unistd.h の内容
ここまでの解析で、sys_flockがコールされるまでの処理で、EAXレジスタの使われ
方に特に異常がないことが判った。sys_flockルーチンでadd命令が実行されて障害が
発生したのかを、レジスタの値以外の観点から調べることにし、add命令が実行され
た過程を調査していく。まずは、ダンプ上のコードを表示させるために、rdコマンド
で使用する。
(図 2.7-8)
alicia> rd sys_flock 10
c0168a18:
fff70000 5657ffff 448b5753 5c8b1824
......WVSW.D$..\
c0168a28:
1ee81c24 85fffee3 0fc789c0 0000f084
$...............
c0168a38:
c1de8900 e38302ee
........
alicia>
図 2.7-8 sys_flock ルーチンのダンプ上のコード
(4) 逆アセンブルリスト
追求を進めていく上でまず確認することは、ダンプ上の該当アドレスのメモリ内容と
カーネルコードが一致していることを確認することである。これは、デバック情報付き
でコンパイルしたカーネルの逆アセンブルリスト(図 2.7-9)と、ダンプのメモリ内容
を比較することで確認できる。
# objdump -S /usr/src/linux-2.6.9-11ELsmp-devmem/vmlinux | grep -A 5 "c0168a18 "
c0168a18 <sys_flock>:
c0168a18:
55
push
%ebp
c0168a19:
bd f7 ff ff ff
mov
$0xfffffff7,%ebp
c0168a1e:
57
push
%edi
- 2-109 -
c0168a1f:
56
push
%esi
c0168a20:
53
push
%ebx
# objdump -s /usr/src/linux-2.6.9-11ELsmp-devmem/vmlinux | grep -A 5 c0168a10
c0168a10 4089f85b 5e5f5dc3 55bdf7ff ffff5756
@..[^_].U.....WV
c0168a20 53578b44 24188b5c 241ce81e e3feff85
SW.D$..\$.......
c0168a30 c089c70f 84f00000 0089dec1 ee0283e3
................
c0168a40 fb83f601 83e60183 fb08740f f6c32075
..........t... u
c0168a50 0af6401c 030f84c7 00000089 d989e289
..@.............
c0168a60 f8e8e7e5 ffff85c0 89c50f85 b2000000
................
図 2.7-9 カーネルの逆アセンブルリスト
ここで、大きな異変に気付く。ダンプ上のアドレス 0xc0168a18 の内容がカーネルを
アセンブルした時に得られる内容と食い違っていることである。これは、図 2.7-3/図
2.7-8/図 2.7-9 を比較することで確認できる。
図 2.7-10 にアドレス 0xc0168a18 の内容を比較して表示してみた。ダンプ上(Aliciaに
よる表示)では、下位 16 ビットが 0 に変更されていることが判る。本来は、0xfff7bd55
であったはずである。図 2.7-10 の矢印で示したように、Aliciaの表示とobjdumpの表示
では、byte単位での表示(方向)が異なることに注意する必要がある。
alicia> rd sys_flock
c0168a18:
fff70000 5657ffff 448b5753 5c8b1824
......WVSW.D$..\
# objdump -s
c0168a10
55bdf7ff ffff5756
U.....WV
図 2.7-10 Alicia と objdump の表示方向の違い
(5)
原因特定
ここまでの解析から、何らかの理由により、アドレス 0xc0158a18 の内容が 2 バイ
ト分変更され、sys_flock ルーチンで誤ったコードが実行されてしまい、その結果、
ページフォルト障害が発生したものと判断できる。
メモリ内容が書き換えられた理由としては、
・ メモリハードウェア障害
・ カーネルのバグにより、意図しないアドレスに書き込みを行っている
などが考えられる。
最終的な原因判明は、本障害がハードウェア障害によるものなのか、カーネルのバグ
- 2-110 -
によるものなのかを明らかにすることである。そのためには、メモリ障害の痕跡を各種
ログで調査し、あるいは、カーネルロジックとつきあわせながら更に詳細なダンプ追求
を実施する。一般的には、ハードウェアによる問題かソフトウェアによる問題かの切り
分けは、何らかの痕跡(状況証拠)を元に追求の初期段階で判断をくだす必要がある。
追求に長時間を要す場合には、トラブルに関連するハードウェア部位に対してひとまず
部品を交換し、再発に備えるといったケースも少なくない。
2.7.1.4 対策
メモリハードウェア障害が疑わしい場合、または、メモリハードウェア障害と判断
できた場合には、メモリチェックユーティリティにより、メモリに障害がないかを調
べ、メモリのハードウェア交換を行う。
- 2-111 -
2.8 ネットワーク障害
2.8.1 障害概要
事例として取り上げる障害の内容について以下に述べる。
表 2.8-1 ネットワーク障害概要
番号
2.8.1
発生日
2005/xx/xx
解決日
2005/xx/xx
現象
Bonding 構成が組まれた環境において、ネットワークインターフェースのリンクダ
ウンが発生する。
分類
ネットワーク障害
発生環境
OS
Turbolinux 10 Server
CPU
Pentium 4 3.20GHz x 1
メモリ
256Mbyte
ハードディスク
IDE 120Gbyte
ネットワーク
Intel Corp. 82557/8/9 Ethernet Pro 100 x 2
原因
ケーブルの断線によるリンクダウンが発生
対策
ネットワークケーブルの交換
解析手法
Swatch による silo 監視から、障害内容を確認
2.8.2 障害検知
通常運用中に、swatch 監視より、”Messages from Swatch”という件名のメールが送信さ
れる。送信された内容を確認する。
Sep 1 14:33:44 enfuzion01 kernel: bonding: bond0: link status definitely down for
interface eth1, disabling it
Sep 1 14:33:44 enfuzion01 kernel: bcm5700: eth1 NIC Link is Down
図 2.8-1 Message from Swatch
メッセージの内容は、”eth1 のリンクがダウンした”、というものである。これを踏まえて、
ksysguardにて、ネットワークの転送状態を確認することにする。図 2.8-2 障害発生中の
ksysguardを見てわかるとおり、パケットの送受信数が”0”であることを示していることが
わかる。推測できることは、パケットが送受信できていない = ネットワークインターフェ
ースに何らかの問題が発生したことがわかる。
- 2-112 -
送受信の転送パケット数が、”0”という事は eth1 で、
障害が発生したと判断して良い。
図 2.8-2 障害発生中の ksysguard
表 2.8-2 ksysguard の図内構成
パケット
データ
エラー
ドロップされた
パケット
Local Host
Remote Host
bond0 受信
bond0 受信
bond0 受信
bond0 受信
bond0 送信
bond0 送信
bond0 送信
bond0 送信
eth0 受信
eth0 受信
eth0 受信
eth0 受信
eth0 送信
eth0 送信
eth0 送信
eth0 送信
eth1 受信
eth1 受信
eth1 受信
eth1 受信
eth1 送信
eth1 送信
eth1 送信
eth1 送信
bond0 受信
bond0 受信
bond0 受信
bond0 受信
bond0 送信
bond0 送信
bond0 送信
bond0 送信
eth0 受信
eth0 受信
eth0 受信
eth0 受信
eth0 送信
eth0 送信
eth0 送信
eth0 送信
eth1 受信
eth1 受信
eth1 受信
eth1 受信
eth1 送信
eth1 送信
eth1 送信
eth1 送信
2.8.3 障害切り分け
NIC のドライバが稼動しているか確認を行なう。これは、ifconfig コマンドを使用するこ
- 2-113 -
とで判明する。判断する内容として、下線が引かれている、UP, RUNNING というキーワ
ードが出ている事を確認する。
「UP」は現在正常に稼働していることを示し、
「RUNNING」
はドライバが正常にロードされている状態を示す。
bond0
Link encap:Ethernet
HWaddr 00:12:3F:6E:75:9E
inet addr:172.16.37.141
Bcast:172.16.39.255
UP BROADCAST RUNNING MASTER MULTICAST
Mask:255.255.252.0
MTU:1500
Metric:1
RX packets:2773525 errors:0 dropped:0 overruns:0 frame:0
TX packets:1101416 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1979358842 (1887.6 Mb)
eth0
Link encap:Ethernet
TX bytes:72928144 (69.5 Mb)
HWaddr 00:12:3F:6E:75:9E
UP BROADCAST RUNNING SLAVE MULTICAST
MTU:1500
Metric:1
RX packets:582716 errors:0 dropped:0 overruns:0 frame:0
TX packets:550715 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:282233562 (269.1 Mb)
TX bytes:38724565 (36.9 Mb)
Interrupt:18 Memory:dfcf0000-dfd00000
eth1
Link encap:Ethernet
HWaddr 00:12:3F:6E:75:9E
UP BROADCAST RUNNING SLAVE MULTICAST
MTU:1500
Metric:1
RX packets:2190809 errors:0 dropped:0 overruns:0 frame:0
TX packets:550701 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1697125280 (1618.5 Mb)
lo
TX bytes:34203579 (32.6 Mb)
Link encap:Local Loopback
inet addr:127.0.0.1
Mask:255.0.0.0
UP LOOPBACK RUNNING
MTU:16436
Metric:1
RX packets:4431 errors:0 dropped:0 overruns:0 frame:0
TX packets:4431 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:382582 (373.6 Kb)
TX bytes:382582 (373.6 Kb)
図 2.8-3 障害発生時の ifconfig 結果
この結果から、インターフェースは稼動していると判断できるが、ifconfig コマンドの結果
からは、ネットワークデバイスドライバは、正常に稼動している、という事しかわからな
い。ハードウェア障害なのか、ソフトウェア障害なのかを切り分ける為に、H/W の状態を
ethtool にて取得する。
- 2-114 -
表 2.8-3 障害発生後の ethtool による H/W 状況の収集
# ethtool eth0
# ethtool eth1
Settings for eth0:
Settings for eth1:
Supported ports: [ TP MII ]
Supported ports: [ TP MII ]
Supported link modes:
Supported link modes:
10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Supports auto-negotiation: Yes
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
100baseT/Half 100baseT/Full
Advertised auto-negotiation: Yes
Advertised auto-negotiation: Yes
Speed: 10Mb/s
Speed: 10Mb/s
Duplex: Half
Duplex: Half
Port: MII
Port: MII
PHYAD: 1
PHYAD: 1
Transceiver: internal
Transceiver: internal
Auto-negotiation: on
Auto-negotiation: on
Supports Wake-on: g
Supports Wake-on: g
Wake-on: d
Wake-on: d
Current message level: 0x00000007 (7)
Current message level: 0x00000007 (7)
Link detected: yes
Link detected: no
実行結果から、eth1 の Link detected が”No”になっていることがわかった。これは物理的
に電気信号が切断された場合に発生する状態である。”Message from Swatch”の内容と併せ
ると、ハードウェア的に接続がダウンしたと判断できる。このことから、物理的な結線に
問題があると考えられ、ネットワークハブの FC/COL ランプを確認したら、動作ランプが
消えていることが確認できた。
2.8.4 障害回復手順
ケーブルには、外傷は見つからないので、内部断線していると思われる為、ケーブルチ
ェッカーによる診断を行なう。(無い場合は、直接、新品ケーブルへ交換してみる)確認した
ところ、内部断線を起こしている事が判明したので、新品のケーブルに入替え、Link ラン
プが点灯し、ksysguard にてパケットの転送が再開されていることの確認を行なう。問題
発生時、”0”と表示されていた項目も”0”以外の数値が表示されており、通信が再開されてい
ることがわかる。本当に回復したのか確認するために、syslog の内容を確認し、eth1 が
Linkup していることを確認する。
# tail –f /var/log/messages | grep up
Aug 19 12:41:13 enfuzion01 kernel: e100: eth1: e100_watchdog: link up, 100Mbps,
full-duplex
図 2.8-4 回復後の syslog 内容(抜粋)
- 2-115 -
ログ上、インターフェースが up しているという事から、H/W 監視を行う事ができる ethtool
にて、Link detected が yes になっていることを確認する。
表 2.8-4 回復後の ethtool の結果
# ethtool eth0
# ethtool eth1
Settings for eth0:
Settings for eth1:
Supported ports: [ TP MII ]
Supported ports: [ TP MII ]
Supported link modes:
Supported link modes:
10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Supports auto-negotiation: Yes
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half
100baseT/Half
100baseT/Full
100baseT/Full
Advertised auto-negotiation: Yes
Advertised auto-negotiation: Yes
Speed: 10Mb/s
Speed: 10Mb/s
Duplex: Half
Duplex: Half
Port: MII
Port: MII
PHYAD: 1
PHYAD: 1
Transceiver: internal
Transceiver: internal
Auto-negotiation: on
Auto-negotiation: on
Supports Wake-on: g
Supports Wake-on: g
Wake-on: d
Wake-on: d
Current message level: 0x00000007 (7)
Current message level: 0x00000007 (7)
Link detected: yes
Link detected: yes
問題を回避できたと判断し、tcpdump、ping による疎通確認を行なう。
tcpdump による通信確認を行なう。tcpdump とはネットワーク通信の状態を見ることがで
きるツールである。tcpdump で表示される内容をログファイルに書き込み、別コンソール
から結果内容を抽出する方法で結果を見る事にする。tcpdump の内容は非常に膨大な量の
データが流れる為、ファイルに吐き出し、必要な情報だけを抽出することができる。
# tcpdump > tcpdump.log
図 2.8-5 tcpdump の開始
tcpdump 開始の後、別コンソールにて、対向 PC(dhcp-148)に対して ping 実行する。書き
出されているログに対して、grep 検索を行い、ログの抽出を行なう。
# ping –c 3 dhcp-148
図 2.8-6 ping の実行
ping を実行することで、通信した結果が、tcpdump のログに残る。
# tail –f tcpdump.log | grep dhcp-148
- 2-116 -
11:24:58.366899 arp reply dhcp-148 is-at 00:90:99:16:5f:9a
11:24:58.366912 IP enfuzion01 > dhcp-148: icmp 64: echo request seq 1
11:24:58.367047 IP dhcp-148 > enfuzion01: icmp 64: echo reply seq 1
11:24:59.367494 IP enfuzion01 > dhcp-148: icmp 64: echo request seq 2
11:24:59.367605 IP dhcp-148 > enfuzion01: icmp 64: echo reply seq 2
11:25:00.368141 IP enfuzion01 > dhcp-148: icmp 64: echo request seq 3
11:25:00.368279 IP dhcp-148 > enfuzion01: icmp 64: echo reply seq 3
図 2.8-7 tcpdump 結果
疎通できている場合、対向 PC より reply が送信されていることがわかる。この結果から、
TCP/IP による疎通ができていることがわかる。
traceroute コマンドにて、障害発生前と同じ経路で通信が行なえているか確認を行なう。
障害前と同じ経路であれば、障害前の状態に戻せたと判断できる。
続いて、traceroute による経路確認を行なう。
# traceroute www.ipa.go.jp
traceroute to www.ipa.go.jp (xxx.xxx.xxx.xxx), 30 hops max, 38 byte packets
1
ns (172.xx.xxx.xxx)
2
gw18-2.hoge-hoge.net (xxx.xxx.xxx.xxx)
3
x20-1.hoge-hoge.net (xxx.xxx.xxx.xxx)
4
gw148.hogehog.hoge.net (xxx.xxx.xxx.xxx)
11.833 ms
5
gw254.hogehog.hoge.net (xxx.xxx.xxx.xxx)
8.905 ms
6
hoge.hoge.net (xxx.xxx.xxx.xxx)
7
xxx.hogehoge.net (xxx.xxx.xxx.xxx)
8
xxx.hogehoge.hogehoge.net (xxx.xxx.xxx.xxx)
9
hoge.hoge.hoge.hoge.hogehoge.net (xxx.xxx.xxx.xxx)
10
0.225 ms
0.152 ms
0.276 ms
11.129 ms
0.770 ms
20.743 ms
xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)
0.723 ms
0.704 ms
8.910 ms
1.063 ms
8.921 ms
10.330 ms
10.361 ms
10.403 ms
20.694 ms
66.105 ms
0.687 ms
0.993 ms
10.175 ms
10.422 ms
0.658 ms
20.833 ms
10.735 ms
46.977 ms
20.748 ms
10.856 ms 10.770 ms
48.357 ms
図 2.8-8 回復後の traceroute 情報
復旧後の確認として ksysguard にてパケットの転送状態を確認する。結果、eth1 の送受信
が、”0”という表示ではない事が確認できる。
- 2-117 -
表示が、”0”ではないので、通信が行なわれていると
判断して良い。
図 2.8-9 復旧後の ksysguard
- 2-118 -
2.9 ディスク障害
2.9.1 H/W RAID 5/1
障害発生時、警告音が鳴り、監視ツールより、指定したユーザ宛てに通知され、その結
果から、障害問題の切り分けをし、障害発生後の回復手順についても検証する。RAID5,1
とも同じ手順である。
2.9.1.1 障害概要
事例として取り上げる障害の内容について以下に述べる。
表 2.9-1 ハードウェア RAID 障害概要
番号
2.9.1
現象
H/W RAID 環境にて Channel ID2 への I/O が行なえない。
分類
ディスク障害/ ディスク不良
発生環境
OS
Turbolinux 10 Server
CPU
Athlon64 3500+
メモリ
1Gbyte
ハードディスク
SCSI 36GB x 2 ~ 3
ネットワーク
TL-8139/8139C/8139C+
発生日
2005/xx/xx
解決日
原因
Channel ID2 にて、I/O 障害が発生
対策
不良ディスクの交換
解析手法
Storage Manager*からの警告および syslog の内容を確認
2005/xx/xx
*Storage Manager は、Adaptec 社製 HostRAID,SCSI デバイスを監視できる GUI ツール
である。
2.9.1.2 障害検知
障害時、RAID カードよりアラート音が発せられ、監視ツールからルートユーザ宛てにメ
ールで障害発生通知(Event notification – Event Type: Error)が送信される。RAID カード
から発せられるアラート音は、問題が解決されるまで鳴り続ける。(オプションでアラート
OFF もある)。
# tail –f /var/log/messages
Sep 23 12:19:19 rouge login(pam_unix)[1400]: session opened for user root by (uid=0)
Sep 23 12:19:47 rouge kernel: SCSI device sda: 143237120 512-byte hdwr sectors (73337 MB)
Sep 23 12:19:47 rouge kernel: sda: Write Protect is off
Sep 23 12:19:47 rouge kernel: SCSI device sda: drive cache: write through
- 2-119 -
図 2.9-1 障害発生直後の syslog 情報
This message was generated by the Adaptec Storage Manager Agent.
Please do not reply to this message.
Event Description: Verify failed: controller 1, logical device 1 ("array01raid5") [0x00]
Event Type: Error
Event Source: rouge
Date: 09/21/2005
Time: 21:23:20 PM JST
図 2.9-2 Storage Manager からのメール(抜粋)
2.9.1.3 障害切り分け
この情報により、RAID 構成の”device1”にて障害が発生したことがわかり、Storage
Manager にて、状態を確認したところ、Channel ID2 が消えていることが判る。
この場合、
Channel ID2 が表示されているのが、正常動作で
あるが、障害発生時には表示されていない。
図 2.9-3 障害発生の Storage Manager
- 2-120 -
2.9.1.4 障害解析
Storage Manager から送信されたメッセージ中(図 2.9-2)に、”Veryfiy faild: Controller
1 ~”と書かれていた。内容を確認すると、logicaldevice(アレイ構成)に障害が発生したこと
を意味するメッセージであり、Storage Manager 上で、状態を確認すると、3 つあるディ
スクイメージが、2 つになっていることが分かる。これに合わせて、図 2.9-2” Storage
Manager からのメール(抜粋)”のメールと同時刻に、図 2.9-4”Event Notification - Event
Type: Informational”という件名のメールが送られてくる。このメールには、障害が発生
している device が書かれている。
This message was generated by the Adaptec Storage Manager Agent.
Please do not reply to this message.
Event Description: Physical drive removed: controller 1, channel 0, SCSI device ID 2
Event Type: Informational
Event Source: dhcp-148
Date: 08/25/2005
Time: 07:19:59 PM JST
図 2.9-4 Event Notification - Event Type: Informational
この 2 つの情報から、logicaldevice1の SCSI Channel ID2 で物理的な障害が発生したこ
とがわかる。これによりディスク交換が必要と判断できる。
2.9.1.5 障害回復手順
SCSI RAID カードには、自動再構成の機能が含まれているため、新品ディスクに換える
事で再構成が自動で開始される。この際、fdisk は行なわなくて良い。図 2.9-5“再構成中の
Storage Manager”は再構成中の画面情報である。ChannelID 2 に障害が発生し、障害復旧
に伴う再構成が行われている事が視覚的にわかるようになっている。
- 2-121 -
図 2.9-5 再構成中の Storage Manager
最後に、df コマンドにて、全てのファイルシステムを表示し、回復したことを確認する。
# df -a
Filesystem
1K-blocks
/dev/sda1
10317828
5043352
4750360
none
0
0
0
-
/proc
usbfs
0
0
0
-
/proc/bus/usb
sysfs
0
0
0
-
/sys
10317860
32936
9760804
0
0
0
/dev/sda3
none
Used Available Use% Mounted on
- 2-122 -
52% /
1% /home
-
/dev/pts
2.9.2 S/W RAID5/1
障害発生時、監視ツールより、指定したユーザ宛てにメールにて通知され、その結果か
ら、障害問題の切り分けをし、障害発生後の回復手順についても検証する。RAID5,1 とも
同じ手順である。
2.9.2.1 障害概要
事例として取り上げる障害の内容について以下に述べる。
表 2.9-2 ソフトウェア RAID 障害概要
番号
2.9.2
現象
S/W RAID 環境にて、/dev/hdb への I/O が行なえない。
分類
ディスク障害/ ディスク不良
発生環境
OS
Turbolinux 10 Server
CPU
Athlon64 3500+
メモリ
1Gbyte
ハードディスク
IDE 80Gbyte x 2 ~ 3
ネットワーク
TL-8139/8139C/8139C+
発生日
2005/xx/xx
原因
/dev/hdb にて、I/O 障害が発生
対策
不良ディスクの交換
解析手法
swatch による syslog 監視から、障害内容を確認
解決日
2005/xx/xx
2.9.2.2 障害検知
障害発生時、swatch 監視より設定したユーザ宛てにメールで障害発生通知が行われる。
送付内容は以下の通り。
Sep
2 04:02:16 dhcp-148 kernel: end_request: I/O error, dev hdb, sector 41929433
Sep
2 04:02:16 dhcp-148 kernel: md: write_disk_sb failed for device hdb2
図 2.9-6 Message from Swatch
このメッセージから読み取れることは、/dev/hdb のディスクに問題が発生した、というこ
とである。
2.9.2.3 障害切り分け
システムよりディスク障害の警告メールが送られてきたので、状態確認のため、mdadm
にて状況確認を行なうことにする。
- 2-123 -
# mdadm -Q --detail /dev/md1
/dev/md1:
Version : 00.90.01
Creation Time : Tue Aug 30 15:25:29 2005
Raid Level : raid5
Array Size : 20964608 (19.99 GiB 21.47 GB)
Device Size : 10482304 (10.00 GiB 10.73 GB)
Raid Devices : 3
Total Devices : 3
Preferred Minor : 1
Persistence : Superblock is persistent
Update Time : Wed Aug 31 12:11:32 2005
State : clean, degraded
Active Devices : 2
Working Devices : 2
Failed Devices : 1
Spare Devices : 0
Layout : left-asymmetric
Chunk Size : 64K
UUID : 763b126d:630c5e2e:61149fcb:fad9c28e
Events : 0.153
Number
Major
Minor
RaidDevice State
0
3
3
0
active sync
1
0
0
-
removed
2
22
66
2
active sync
3
3
66
-
faulty
/dev/hda3
/dev/hdd2
/dev/hdb2
図 2.9-7 S/W RAID 状況確認
2.9.2.4 障害解析
図 2.9-7 より、md1 の/dev/hdbがRAID構成から外れている事がわかる。このことを踏ま
えて、syslogを確認(図 2.9-8)し、/dev/hdbにて何が発生していたかを確認する。I/Oエラ
ーが発生しているが、fsckによるディスクの復旧を行い、改善されない場合、ディスクへの
書き込みが出来なくなっているので、ディスク不良と判断しディスク交換することになる。
# less /var/log/messages
- 2-124 -
Jul
5 21:40:51 usen4 kernel: end_request: I/O error, dev 16:41 (hdb),sector 34425168
Jul
5 21:40:56 usen4 kernel: hdb: dma_intr: status=0x51 { DriveReady
SeekComplete
Error }
Jul
5 21:40:56 usen4 kernel: hdb: dma_intr: error=0x40 {UncorrectableError },
LBAsect=33262669, ector=33262544
図 2.9-8 syslog
2.9.2.5 障害回復手順
シングルユーザモードに移行した後、fsck による復旧を試みる。
# shutdown –F now
図 2.9-9 シングルユーザモードへの移行
移行終了の後、fsck によるディスク修復を試みる。
# fsck –c –y /dev/md1
図 2.9-10 fsck の実行
結果として、fsck を実行したが障害を取り除くことができなかった。新品ディスクに交換
する以外に術が無いことが判明した。S/W RAID 構成の回復方法は、raidhotadd コマンド
による再構成にて RAID 構成を元に戻すことができる。ただし、S/W RAID 構成が解除さ
れた場合、システムを一時停止することが必要となる点に注意が必要である。これは、稼
動中にディスクを入れ換えてもシステムは認識できないためである。新品のディスクをそ
のままマウントしただけでは、S/W RAID の再構成は行なえない。再構成を行う為に fdisk
によるパーティションの再設定が必要であり、前準備として図 2.9-11 の再構成コマンドを
実行する必要がある。
# raidhotadd /dev/md0 /dev/hdb2
# raidhotadd /dev/md1 /dev/hdb2
図 2.9-11 raidhotadd による再構成コマンド
再構成中の進捗状況は、/proc/mdstat を見ることで、確認できる。下線が引いてある情報
が進行状況を知らせるものになる。
# cat /proc/mdstat
Personalities : [raid5]
md1 : active raid5 hda3[0] hdd2[2]
20964608 blocks level 5, 64k chunk, algorithm 0 [3/2] [U_U]
- 2-125 -
md0 : active raid5 hdb1[3] hda2[0] hdd1[2]
20964608 blocks level 5, 64k chunk, algorithm 0 [3/2] [U_U]
[>....................]
recovery =
1.0% (113280/10482304) finish=12.2min
speed=14160K/sec
unused devices: <none>
図 2.9-12 S/W RAID 再構成進行状態
S/W RAID の再構成(raidhotadd コマンド)の複数同時実行はできないが、投下されたコマ
ンドは、前者の再構成が終了した後、すぐに後者の再構成が開始される。/proc/mdstat に
て、構成が完了した事が確認できたら、mdstat にて、構成が復元できたかを確認する。
# less /proc/mdstat
Personalities : [raid5]
md1 : active raid5 hdb2[1] hda3[0] hdd2[2]
20964608 blocks level 5, 64k chunk, algorithm 0 [3/3] [UUU]
md0 : active raid5 hdb1[1] hda2[0] hdd1[2]
20964608 blocks level 5, 64k chunk, algorithm 0 [3/3] [UUU]
図 2.9-13 mdstat 結果
- 2-126 -
2.9.3 LVM
LVM はカーネル 2.4 からサポートされたディスク管理機能である。カーネル 2.6 にて根
本的な見直しが行なわれ LVM2 へとバージョンアップされている。この LVM を利用する
と複数のハードディスクをグループ化し 1 つの論理ディスクとして運用することも出来る。
スナップショット、構成変更を利用し、障害回避する手段を検証する。
2.9.3.1 障害概要
事例として取り上げる障害の内容について以下に述べる。
表 2.9-3 LVM 障害事例
番号
2.9.3
発生日
2005/xx/xx
現象
/dev/hdb への I/O が行えない。
分類
ディスク障害/ ディスク不良
発生環境
OS
Turbolinux 10 Server
CPU
Athlon64 3500+
メモリ
1Gbyte
ハードディスク
IDE 80Gbyte x 2
ネットワーク
TL-8139/8139C/8139C+
原因
/dev/hdb にて、I/O 障害が発生
対策
不良ディスクの交換
解析手法
Swatch による syslog 監視から、障害内容を確認
解決日
2005/xx/xx
2.9.3.2 障害検知
障害発生時、swatch 監視より設定したユーザ宛てにメールで障害発生通知が行われる。
送付内容は以下の通り。
Sep 3 04:03:15 dhcp-148 kernel: end_request: I/O error, dev hdb, sector 41929433
Sep 3 04:03:15 dhcp-148 kernel: md: write_disk_sb failed for device hdb2
図 2.9-14 Message from Swatch
2.9.3.3 障害切り分け
このメッセージから読み取れることは、hdb のディスクに問題が発生した、ということ
である。同時刻に syslog にて、どのようなメッセージが出ているかも確認する必要がある。
Sep
8 11:49:56 dhcp-148 kernel: ide0: reset timed-out, status=0x80
Sep
8 11:49:56 dhcp-148 kernel: end_request: I/O error, dev hdb, sector 4575
Sep
8 11:49:56 dhcp-148 kernel: EXT3-fs error (device dm-0): ext3_readdir: directory #2
contains a hole at offset 0
Sep
8 11:49:56 dhcp-148 kernel: Aborting journal on device dm-0.
- 2-127 -
Sep
8 11:49:56 dhcp-148 kernel: end_request: I/O error, dev hdb, sector 447
Sep
8 11:49:56 dhcp-148 kernel: Buffer I/O error on device dm-0, logical block 0
Sep
8 11:49:56 dhcp-148 kernel: lost page write due to I/O error on dm-0
Sep
8 11:49:56 dhcp-148 kernel: ext3_abort called.
Sep
8 11:49:56 dhcp-148 kernel: EXT3-fs error (device dm-0): ext3_journal_start:
Detected aborted journal
図 2.9-15 syslog
syslog を確認したところ、I/O エラーを表示していることから、ディスク不良が発生してい
るようである。
2.9.3.4 障害解析
マウントされている LVM の領域へ移動し、アクセスできるかを確認したところ、アクセ
スできない状態になっていた。この状態では何もできないため、シングルユーザモードに
移行し、fsck による回復処置を試みる。
# shutdown –F now
図 2.9-16 シングルユーザモードへ移行
シングルユーザモードに移行終了の後、fsck を実行し回復を試みる。
# fsck –c –y /dev/hdb2
図 2.9-17 fsck の実行
fsck を実行しディスクの復旧後、システムを再起動し、LVM の領域をマウントしようとし
ても、マウントは出来なかった。これにより、新品ディスクへ交換する以外、術がないこ
とが判明した。
2.9.3.5 障害回復手順
新品ディスクに入換えても、システム上、LVM の構成情報は/etc/lvm ディレクトリに存
在している。再構成を行おうとしても、旧構成情報が残っている為、pvcreate、lvcreate
などの LVM 環境の再構成を行うコマンドを実行しても再構築が行なえない点に注意する。
ディスクを入れ換えた直後に、LVM の構成が行えない状況であっても lvdisplay、pvdisplay
などの構成情報参照コマンドは、障害発生前の情報を返してしまう。これは構成情報が残
っているからである。しかし、この状況においても、lvremove,vgremove 等のコマンドは
使用できるので、以前作成した LVM 構成を削除した後に、環境を作り直すことになる。 (構
成手順は 3 章を参照)
- 2-128 -
2.9.3.6 スナップショットを利用した障害回避法について
LVM には、RAID のような補完機能は実装されていない為、ディスク障害が発生した場
合、自己修復によるデータの復旧が出来ない点が問題となる。この問題を補う為には日常
的なバックアップを行う必要がある。LVM は、システムの運用中にボリューム単位で別の
空き領域に対してバックアップを行うことができるスナップショット機能を実装している。
スナップショットは、ある時点のイメージを別領域へコピーする機能である。コピーされ
た情報を、共有ディスク(例:NFS サーバなど) へ移すことにより、システム/サービスを停
めずバックアップを行う事が出来る。これは大きなメリットである。この処理を、定期的
に実施し続けることで、障害発生時の復旧に有効な手法となる。LVM 環境、スナップショ
ットの作成方法については、3 章に記す。
スナップショットで収集されたデータは、名が示すとおり断片的なデータでしかないた
め、スナップショットで採られたデータは、マウントし別の領域へコピーする必要がある。
コピー終了後は、マウントを解除し、スナップショットも削除する。これは、次回のスナ
ップショットを行う為の準備でもある。以下にサンプルスクリプトを添付する。サンプル
スクリプトでは、NFS サーバに対してバックアップを行うようにしている。
#!/bin/sh
#
PARTITION=(lv01)
PREFIX=/dev/vg_01
SNAP_SIZE=4098M
SNAP_NAME=snap0
BACKUP_DIR=backup.exsample.com:/export
MOUNT_POINT=/mnt/backup
MOUNT_SNAP=/mnt/snap
echo nfs mount start.
mount $BACKUP_DIR $MOUNT_POINT || exit
echo nfs mount end.for i in ${PARTITION[*]}
do
lvremove -f ${PREFIX}/${SNAP_NAME}
lvcreate --snapshot --size $SNAP_SIZE --name $SNAP_NAME ${PREFIX}/$i
mount ${PREFIX}/$i ${MOUNT_SNAP}
cp ${MOUNT_SNAP}/* ${MOUNT_POINT}
umount ${PREFIX}/$i ${MOUNT_SNAP}
lvremove -f ${PREFIX}/${SNAP_NAME}
done
umount $MOUNT_POINT
図 2.9-18 スナップショットを使用するサンプルスクリプト
- 2-129 -
2.9.3.7 ディスク使用量増大に対する対処について
LVM でボリュームを管理する最大のメリットは、ディスクの空き容量が少なくなったとき、
新しいハードディスクを追加し、容易にロジカルボリュームのサイズを拡張できるところ
にある。構築手順については、3 章に記す。
- 2-130 -
3 ツール評価
3.1 パフォーマンス監視ツールの信頼性評価
本節では、パフォーマンス監視ツールとして sar、iostat、mpstat という 3 つのコマンド
の信頼性評価を行う。特に高負荷時におけるこれらのツールの挙動を調べ、データが指定
した間隔で取得できないという既知の問題に対していくつかの回避策を提示する。
3.1.1 ツールの概要
sar、iostat、mpstat は一定ごとにカーネルが提供する様々なシステム統計情報を取得す
ることにより、システムの負荷状況をモニタリングすることができるコマンドである。こ
れらのコマンドは Linux システムでは sysstat というパッケージに含まれ、多くの Linux
ディストリビューションでは標準で提供されている一般的なツールである。
3.1.1.1 sar
sar は CPU 利用率、ネットワーク、ディスク I/O およびページングなどの多岐にわたる
システム統計情報を一定間隔ごとに取得するコマンドである。取得した統計情報は標準出
力に出力されるが、”-o”オプションを使用することにより指定したファイルにバイナリ形式
で保存することもできる。バイナリ形式で保存した場合、統計情報を確認するには同コマ
ンドを使用してテキスト形式に変換・出力する必要があるが、必要な情報を柔軟に取得す
ることができる。
以下の 図 3.1-1 にsarコマンドでデータを取得し、結果をバイナリファイルとして保存す
る方法を示す。
$ sar -A -o output_file 5 600 &
モニタリングの開始
シ ス テ ム 統 計 情 報 を 5 秒 間 隔 で 600 回 取 得 し 、
output_file にバイナリデータとして保存
-A:取得可能な統計情報をすべて取得
-o:バイナリ形式として保存するファイル名を指定
$ killall sar
モニタリングの終了
$ killall sadc
図 3.1-1 sar コマンドによるデータ取得手順例
図 3.1-1 で取得したファイルはバイナリ形式なので取得したデータを参照するにはsarコマ
ンドでテキスト形式に変換する必要がある。図 3.1-2 に例としてCPU利用率のデータを取
得する方法を示す。
$ sar -u -f output_file
図 3.1-1 の sar コマンドで保存された統計情報
をテキストフォーマットに整形して出力する
Linux 2.6.9-5.25AX (TAMA09)
09/06/05
-u:CPU 利用率を表示
-f:保存ファイル名を指定
- 3-1 -
22:50:07
CPU
%user
%nice
%system
%iowait
%idle
22:50:12
all
32.26
0.00
0.00
1.00
66.73
22:50:17
all
99.80
0.00
0.20
0.00
0.00
22:50:22
all
100.00
0.00
0.00
0.00
0.00
22:50:27
all
100.00
0.00
0.00
0.00
0.00
22:50:32
all
100.00
0.00
0.00
0.00
0.00
22:50:37
all
99.80
0.00
0.20
0.00
0.00
(以下略)
図 3.1-2 sar による取得データの表示例
図 3.1-2 では-uオプションでCPU利用率を取得しているが、他にも-bオプションでディ
スクI/Oに関する統計情報、-nオプションでネットワークに関する統計情報が取得できる。
その他のデータ取得に関してはsarのmanページを参照のこと。
3.1.1.2 iostat
iostatは一定期間毎のディスクの転送回数や転送量、入出力リクエストキューの長さなど、
デバイスやパーティションごとの入出力の情報を取得するコマンドである(sarでも入出力
の情報は得られるが、システム全体の情報しか得られない)。取得された統計情報は標準出
力にテキスト形式で出力され、データをファイルに保存するためにはファイルリダイレク
トを使用する必要がある。図 3.1-3 にiostatでデータを取得する方法を示す。
$ iostat –t -x 5 100 >
output_file
&
モニタリングの開始
システム統計情報を 5 秒間隔で 600 回取得し、output_file
にテキストデータとして保存
-t:データを取得した時刻を出力
-x:デバイスごとの統計情報を出力
モニタリングの終了
$ killall iostat
図 3.1-3 iostat によるデータ取得手順例
図 3.1-3 で取得したデータはテキスト形式で保存されているので 図 3.1-4 のようにcatコマ
ンドなどで確認することができる。
$ cat output_file
Linux 2.6.9-5.25AX (TAMA09)
09/07/05
Time: 12:38:51
avg-cpu:
%user
%nice
0.49
0.00
%sys %iowait
%idle
0.08
99.29
0.14
- 3-2 -
Device:
avgqu-sz
rrqm/s wrqm/s
await
sda
0.17
svctm
w/s
rsec/s
wsec/s
rkB/s
0.38
3.23
48.17
1.61
%sys %iowait
%idle
0.00
0.20
99.60
w/s
rsec/s
wsec/s
rkB/s
0.20
0.00
22.36
0.00
%sys %iowait
%idle
0.00
0.20
99.80
w/s
rsec/s
wsec/s
rkB/s
0.40
0.00
3.21
0.00
wkB/s avgrq-sz
%util
0.01
5.64
6.01
0.29
350.55
r/s
0.09
24.09
107.40
Time: 12:38:56
avg-cpu:
%user
%nice
0.20
0.00
Device:
avgqu-sz
rrqm/s wrqm/s
await
sda
0.00
svctm
wkB/s avgrq-sz
%util
0.00
2.40
12.00
0.24
8.00
r/s
0.00
11.18
112.00
Time: 12:39:01
avg-cpu:
%user
%nice
0.00
0.00
Device:
avgqu-sz
rrqm/s wrqm/s
await
sda
0.00
5.50
svctm
r/s
wkB/s avgrq-sz
%util
0.00
0.00
4.00
0.16
0.00
1.60
8.00
(以下略)
図 3.1-4 iostat による取得データの表示例
-t や-x 以外のオプションに関しては、iostat の man ページを参照のこと。
3.1.1.3 mpstat
一定期間毎にCPUに関する統計情報(CPU利用率、割込み発生回数など)を取得するコマ
ンドである。iostatコマンドと同様、取得された結果は標準出力にテキスト形式で出力され、
データをファイルに保存するためにはファイルリダイレクトを使用する必要がある。図
3.1-5 にmpstatによるデータ取得方法を示す。
モニタリングの開始
$ mpstat 5 100 > output_file
5 秒間隔で 100 回システム統計情報を取得し
&
output_file にテキストデータとして保存する
モニタリングの終了
$ killall mpstat
図 3.1-5 mpstat によるデータ取得手順例
- 3-3 -
図 3.1-5 で取得したデータはiostatと同じくテキスト形式で保存されているので、図 3.1-6
のようにcatなどでデータを確認できる。
$ cat output_file
Linux 2.6.9-5.25AX (TAMA09)
09/07/05
12:41:13
CPU
%user
%nice %system %iowait
%irq
%soft
%idle
intr/s
12:41:18
all
0.00
0.00
0.00
0.00
0.00
0.00
100.00
1012.65
12:41:23
all
0.20
0.00
0.00
0.20
0.00
0.00
99.60
1009.58
12:41:28
all
0.20
0.00
0.00
0.40
0.00
0.00
99.40
1006.79
12:41:33
all
0.00
0.00
0.00
0.20
0.00
0.00
99.80
1016.06
(以下略)
図 3.1-6 mpstat による取得データの表示例
mpstat にもオプションが存在するが、それらに関しては mpstat の man ページを参照の
こと。
3.1.2 評価環境
3.1.2.1 ハードウェア構成
今回の評価で使用したハードウェアの構成を以下の 表 3.1-1 に示す。
表 3.1-1 ハードウェア構成
項番
項目
評価環境
1
機種名
DELL PowerEdge 1650
2
CPU
Intel PentiumIII 1.26GHz × 1
3
メモリ
1GB
4
ディスクドライブ
Ultra3 SCSI 36GB × 1
5
ネットワーク
Intel Corp. 82544EI Gigabit Ethernet
Controller
3.1.2.2 ソフトウェア構成
今回はLinuxカーネル 2.4 ベースと 2.6 ベースのディストリビューションの環境で評価を
行った。使用したソフトウェアの構成を以下の 表 3.1-2 に示す。
表 3.1-2 ソフトウェア構成
項番
項目
カーネル 2.6 環境
1
ディストリビューション MIRACLE LINUX V4.0 beta MIRACLE LINUX V3.0
2
kernel
2.6.9-5.25AX
- 3-4 -
カーネル 2.4 環境
2.4.21-9.30AX
3
sysstat
5.0.5-1.1AX(RPM)
4.0.7-4.2AX(RPM)
4
stress
0.18.2-1.rf(ソース RPM からインストール)
5
IOzone
3.239(ソースからインストール)
3.1.2.3 環境準備
まず、ハードウェア環境を以下の手順で確認する。
(1) CPU の確認
以下の手順で CPU を確認する。
# cat /proc/cpuinfo
processor
: 0
vendor_id
: GenuineIntel
cpu family
: 6
model
: 11
model name
: Intel(R) Pentium(R) III CPU family
stepping
: 1
cpu MHz
: 1263.699
cache size
: 512 KB
1266MHz
(以下略)
図 3.1-7 CPU の確認
図 3.1-7 でprocessorが”0”のものだけがあること(CPUが 1 基であること)とmodel name
が”Intel(R) Pentium(R) III CPU family
1266MHz”であることを確認する。
(2) メモリの確認
以下のコマンドでメモリ量を確認する。
# cat /proc/meminfo
MemTotal:
1032380 kB
MemFree:
878244 kB
Buffers:
9240 kB
Cached:
15820 kB
SwapCached:
Active:
Inactive:
4456 kB
21900 kB
8656 kB
(以下略)
図 3.1-8 メモリの確認
図 3.1-8 でMemTotalの項目が”1032380 kB”になっていることを確認する。
- 3-5 -
(3) ディスクの確認
ファイルシステムの空き容量および種類を確認するために、以下のコマンドを実行する。
# df -k
Filesystem
1K-blocks
Used Available Use% Mounted on
/dev/sda2
15480832
9994688
4699764
/dev/sda1
505604
14200
465300
3% /boot
none
516188
1692
514496
1% /dev/shm
16943148
13131056
2951412
/dev/sda5
69% /
82% /work
# mount
/dev/sda2 on / type ext3 (rw)
none on /proc type proc (rw)
none on /sys type sysfs (rw)
none on /dev/pts type devpts (rw,gid=5,mode=620)
usbfs on /proc/bus/usb type usbfs (rw)
/dev/sda1 on /boot type ext3 (rw)
none on /dev/shm type tmpfs (rw)
/dev/sda5 on /work type ext3 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
図 3.1-9 ディスクの確認
df –k コマンドの実行結果から、/(ルート)パーティションと/work パーティションが存在
すること(Mounted on 列)と、mount コマンドの実行結果から tmpfs の存在(“none on
/dev/shm type tmpfs (rw)”の行)を確認する。
次にソフトウェア環境を確認する。
(1) sysstat の確認
今回評価するコマンドが含まれているパッケージ sysstat がインストールされているか
どうかを以下のコマンドで確認する。
$ rpm –qa | grep sysstat
sysstat-5.0.5-1.1AX
図 3.1-10 sysstat のインストール確認
インストールされていない場合は、RPM パッケージをインストール CD から入手して以
下の手順でインストールする。
# rpm –ivh sysstat-5.0.5-1.1.AX.i386.rpm
# rpm –ivh sysstat-4.0.7-4.2AX.i386.rpm
MIRACLE LINUX V4.0 β版の場合
MIRACLE LINUX V3.0 の場合
図 3.1-11 sysstat のインストール方法
- 3-6 -
(2) 負荷生成ツールの確認
擬似的に高負荷状態を発生させる負荷生成ツール(stress、 IOzone)がインストールされ
ているかを以下のコマンドで確認する。
$ rpm –qa | grep stress
stress-0.18.2-1.rf
$ which iozone
/usr/local/bin/iozone
図 3.1-12 stress と IOzone のインストール確認
stress がインストールされていない場合は、http://weather.ou.edu/~apw/projects/stress/
からソース RPM をダウンロードして、以下の手順でソース RPM からインストールする。
# rpmbuild --rebuild stress-0.18.2-1.rf.src.rpm
# rpm -ivh /usr/src/asianux/RPMS/i386/stress-0.18.2-1.rf.i386.rpm
図 3.1-13 ソース RPM を用いた stress のインストール方法
IOzone がインストールされていない場合は、http://www.iozone.org/からソースコードを
ダウンロードして、以下の手順でコンパイル/インストールする。
# tar xf iozone3_239.tar
# cd iozone3_239
# make linux
# cp –p iozone /usr/local/bin
図 3.1-14 IOzone のソースコードからのインストール方法
3.1.3 評価項目
パフォーマンス監視ツールの評価として、3 種類の代表的な負荷タイプ(ディスク I/O、
CPU、メモリ)に対して指定した時間間隔でシステムの統計情報をどの程度取得できるか
を評価する。
3.1.4 評価手順
本節のパフォーマンスツール評価の手順を以下に示す。
(1) パフォーマンス監視ツールを起動
(2) (1)の 10 秒後に負荷生成を開始
(3) (2)の負荷生成終了の 10 秒後にパフォーマンス監視ツールを終了
測定では以上の手順を自動化したスクリプト load.sh を使用した。load.sh のソースコー
ド、仕様、使用方法などは 2.5.1.2 節を参照のこと。
また、実際の測定においては 1 条件(同じ負荷量、モニタリングツール)に対して 3 回測定
を行っている。データ取得間隔の分布をグラフ化しているところでは、その3回の測定に
おいて負荷が発生している期間におけるデータ取得間隔を集計している。
- 3-7 -
3.1.5 評価結果
まず、負荷が比較的高くない状況で sar、iostat、mpstat でモニタリングを実施し、各ツ
ールが指定した時間間隔でデータが取得できるか、負荷情報を正しく取得できるかを確認
する。
stress 1 プロセスで CPU 負荷をかけた際の sar の挙動について、指定した間隔でデータ
が取得できるか、負荷状況を正しく取得できるかを以下の手順で確認する。
# load.sh cpu 1 sar
モニタリング開始時刻
Make Directory cpu_1_sar_050916_150411
Monitoring Start at Fri Sep 16 15:04:11 JST 2005
CPU 負荷生成開始時刻
Load Start at Fri Sep 16 15:04:21 JST 2005
stress: info: [3507] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
stress: info: [3507] successful run completed in 240s
CPU 負荷生成終了時刻
Load Finish at Fri Sep 16 15:08:21 JST 2005
モニタリング終了時刻
Monitoring Finish at Fri Sep 16 15:08:31 JST 2005
/root/bin/load.sh: line 58:
3501 Terminated
sar -A -o ${SAVE_DIR}/sar.dat
${INTERVAL} ${COUNT}
# cd cpu_1_sar_050916_150411/
# sar -u -f sar.dat
Linux 2.4.21-9.30AX (tama08)
2005年09月16日
15時04分11秒
CPU
%user
%nice
%system
%idle
15時04分16秒
all
0.00
0.00
2.01
97.99
15時04分21秒
all
0.00
0.00
2.00
98.00
15時04分26秒
all
98.00
0.00
1.60
0.40
15時04分31秒
all
98.00
0.00
2.00
0.00
15時04分36秒
all
98.00
0.00
2.00
0.00
15時04分41秒
all
98.00
0.00
2.00
0.00
15時04分46秒
all
98.00
0.00
2.00
0.00
15時04分51秒
all
98.00
0.00
2.00
0.00
15時04分56秒
all
98.20
0.00
1.80
0.00
15時05分01秒
all
98.40
0.00
1.60
0.00
15時07分56秒
all
98.00
0.00
2.00
0.00
15時08分01秒
all
98.00
0.00
2.00
0.00
15時08分06秒
all
98.00
0.00
2.00
0.00
15時08分11秒
all
98.00
0.00
2.00
0.00
15時08分16秒
all
98.00
0.00
2.00
0.00
15時08分21秒
all
98.00
0.00
2.00
0.00
負荷生成開始
(中略)
- 3-8 -
負荷生成終了
15時08分26秒
all
0.20
0.00
1.61
98.19
15時08分31秒
all
0.00
0.00
2.00
98.00
Average:
all
90.55
0.00
1.92
7.53
図 3.1-15 CPU 負荷時の sar の挙動
図 3.1-15 の%user(CPUがユーザ時間で使用された割合)の列を見ると負荷を掛け始めた
15:04:21 から 15:08:21 の期間で 100%に近い値になっていて、CPU負荷が発生していると
いう事実が分かる。一方、それ以外の期間では%idle(CPUのアイドル率)が 100%に近い値
になっており、負荷が発生していない事実が分かる。また、一番左の列を見るとデータ取
得タイミングも指定した 5 秒通りになっていることが分かる。
次に iozone1プロセスでディスク I/O 負荷を掛けた際の iostat の挙動について、指定した
間隔でデータが取得できるか、負荷状況を正しく取得できるか確認する。
# load.sh io 1 iostat
モニタリング開始時刻
Make Directory io_1_iostat_050916_151418
Monitoring Start at Fri Sep 16 15:14:18 JST 2005
Load Start at Fri Sep 16 15:14:28 JST 2005
ディスク I/O 負荷生成開始時刻
Load Finish at Fri Sep 16 15:14:49 JST 2005
ディスク I/O 負荷生成終了時刻
Monitoring Finish at Fri Sep 16 15:14:59 JST 2005
# cd io_1_iostat_050916_151418
モニタリング終了時刻
# cat iostat.dat
Linux 2.4.21-9.30AX (tama08)
09/16/05
Time: 15:14:18
avg-cpu:
%user
%nice
%sys
%idle
0.70
0.00
2.47
96.83
Device:
rrqm/s wrqm/s
avgqu-sz
await
/dev/sda
1.88
6.81
0.00
0.45 1599.78 1022.47
/dev/sda2
1.12
/dev/sda3
0.31
7.18
0.08
104.90
7.48
rsec/s
wsec/s
rkB/s
wkB/s avgrq-sz
9.08 2678.00
4.54
1339.00
517.32
0.10
0.01
0.05
3.84
0.46
4.74
0.00
0.03
0.37
4.50
7.80 2557.56
3.90
1278.78
526.39
0.08
0.21
1.27
0.63
60.17
415.94
3.54
0.02
0.01
2.90
0.60 315.14
96.73
w/s
%util
0.68 330.00
105.40
/dev/sda1
svctm
r/s
3.50
14.83
0.22
Time: 15:14:23
- 3-9 -
120.34
avg-cpu:
%user
%nice
%sys
%idle
0.00
0.00
1.81
98.19
Device:
rrqm/s wrqm/s
avgqu-sz
await
/dev/sda
svctm
0.04
0.00
5.00
/dev/sda1
0.00
0.04
5.62
5.00
rkB/s
0.00
0.80
0.00
51.41
0.00
25.70
64.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.80
0.00
51.41
0.00
25.70
64.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
rsec/s
wsec/s
rkB/s
wkB/s avgrq-sz
0.00
負荷生成開始
Time: 15:14:28
avg-cpu:
%user
%nice
%sys
%idle
0.00
0.00
2.00
98.00
Device:
rrqm/s wrqm/s
avgqu-sz
await
/dev/sda
svctm
0.00
0.02
3.33
/dev/sda1
0.00
3.33
0.00
0.02
0.00
0.00
0.60
0.00
8.02
0.00
4.01
13.33
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.60
0.00
8.02
0.00
4.01
13.33
0.00
0.00
0.00
0.00
0.00
0.00
0.00
rsec/s
wsec/s
rkB/s
wkB/s avgrq-sz
0.00
0.40
3.33
0.20
0.00
0.00
%util
0.00
0.00
/dev/sda3
w/s
0.20
0.00
3.33
r/s
0.40
0.00
/dev/sda2
wkB/s avgrq-sz
0.40
0.00
0.00
wsec/s
0.00
0.00
/dev/sda3
0.00
0.00
0.00
5.00
rsec/s
0.40
0.00
/dev/sda2
w/s
%util
5.62
5.00
0.00
r/s
0.00
0.00
0.00
Time: 15:14:33
avg-cpu:
%user
%nice
%sys
%idle
3.31
0.00
95.87
0.83
Device:
rrqm/s wrqm/s
avgqu-sz
await
/dev/sda
/dev/sda1
0.00
/dev/sda2
8.66
0.00
0.00
w/s
%util
0.00 21687.05
3180.99 1066.73
0.00
svctm
r/s
0.00 98.62
0.00 175435.81
0.00 87717.91
1778.86
85.40
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00 21687.05
0.00 98.62
0.00 175435.81
- 3-10 -
0.00 87717.91
1778.86
3180.99 1066.73
/dev/sda3
0.00
8.66
0.00
0.00
85.40
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
rsec/s
wsec/s
rkB/s
wkB/s avgrq-sz
0.00
Time: 15:14:38
avg-cpu:
%user
%nice
%sys
%idle
0.00
0.00
100.00
0.00
Device:
rrqm/s wrqm/s
avgqu-sz
await
/dev/sda
svctm
r/s
%util
0.00 95812.00
52577.40 3836.56
/dev/sda1
0.00
/dev/sda2
0.00
0.00
0.00
0.00 95812.00
/dev/sda3
0.00 387408.00
679.66
0.00
0.00
0.00
0.00
0.00
0.00
0.00 1140.00
0.00 774816.00
0.00 387408.00
679.66
8.77 1000.00
0.00
0.00
0.00 774816.00
0.00
52577.40 3836.56
0.00
0.00 1140.00
8.77 1000.00
0.00
0.00
w/s
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
rsec/s
wsec/s
rkB/s
wkB/s avgrq-sz
0.00 3470.27
0.00
1735.14
4.12
0.00
0.00
0.00
0.00
0.00 3470.27
0.00
1735.14
4.12
0.00
0.00
Time: 15:14:43
avg-cpu:
%user
%nice
%sys
%idle
0.00
0.00
59.46
40.54
Device:
rrqm/s wrqm/s
avgqu-sz
await
/dev/sda
svctm
r/s
%util
0.00 227.03
13559.46 3554.87
/dev/sda1
0.00
/dev/sda2
0.00
0.00
0.00
0.00 227.03
/dev/sda3
0.00
0.00 843.24
7.44 627.03
0.00
0.00
0.00
0.00
13559.46 3554.87
0.00
0.00 843.24
7.44 627.03
0.00
0.00
w/s
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
rsec/s
wsec/s
rkB/s
wkB/s avgrq-sz
0.00
負荷生成終了
Time: 15:14:48
avg-cpu:
Device:
avgqu-sz
%user
%nice
%sys
%idle
0.00
0.00
7.82
92.18
rrqm/s wrqm/s
await
svctm
r/s
w/s
%util
- 3-11 -
/dev/sda
0.02
0.00
0.59
/dev/sda1
0.00
0.59
/dev/sda2
3.21
0.59
0.00
52.91
0.00
26.45
15.53
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
3.41
0.00
52.91
0.00
26.45
15.53
0.00
0.00
0.00
0.00
0.00
0.00
0.00
w/s
rsec/s
wsec/s
rkB/s
wkB/s avgrq-sz
0.00
2.21
0.00
44.98
0.00
22.49
20.36
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
2.21
0.00
44.98
0.00
22.49
20.36
0.00
0.00
0.00
0.00
0.00
0.00
0.00
rsec/s
wsec/s
rkB/s
wkB/s avgrq-sz
0.20
0.00
0.00
3.41
0.00
0.00
/dev/sda3
0.00
0.00
0.00
0.59
0.00
0.20
0.00
0.00
0.02
3.21
0.00
0.00
0.00
Time: 15:14:53
avg-cpu:
%user
%nice
%sys
%idle
0.00
0.00
2.21
97.79
Device:
rrqm/s wrqm/s
avgqu-sz
await
/dev/sda
svctm
0.04
0.00
1.82
/dev/sda1
0.00
/dev/sda2
0.04
0.00
0.00
0.00
0.00
1.82
/dev/sda3
0.00
0.40
0.00
0.00
3.41
1.82
0.40
0.00
0.00
%util
3.41
1.82
r/s
0.00
0.00
0.00
Time: 15:14:58
avg-cpu:
%user
%nice
%sys
%idle
0.00
0.00
2.00
98.00
Device:
rrqm/s wrqm/s
avgqu-sz
await
/dev/sda
0.00
0.00
0.00
/dev/sda1
0.00
0.00
/dev/sda2
0.00
0.00
/dev/sda3
0.00
svctm
0.00
0.00
0.00
0.00
0.00
8.00
0.00
4.00
13.33
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.60
0.00
8.00
0.00
4.00
13.33
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.60
0.00
0.40
0.00
0.00
0.00
0.00
0.00
w/s
%util
0.40
0.00
r/s
0.00
図 3.1-16 ディスク I/O 高負荷時の iostat の挙動
- 3-12 -
図 3.1-16 から負荷のかかっている期間(15:14:28 から 15:14:49)内でwrqm/s(1 秒あたりの
マージされた書込みリクエスト数)やw/s(1 秒あたりの書込みリクエスト数)、wsec/s(1秒当
たりの書込みセクタ数)、wkB/s(1秒あたりの書込み量(KB))の値が高くなっており、ディ
スクへの書込みが発生していることがわかる。また、Timeの項目を見ると表示されている
時刻が 5 秒間隔になっており、データ取得間隔が指定通りになっていることが分かる。
次に、stress1プロセスでメモリ負荷を掛けた際の mpstat の挙動について、指定した時
間間隔でデータを取得できるか、正しい負荷状況を取得できるか確認する。
# load.sh mem 512 mpstat
Make Directory mem_512_mpstat_050916_162042
モニタリング開始時刻
Monitoring Start at Fri Sep 16 16:20:42 JST 2005
メモリ負荷生成開始時刻
Load Start at Fri Sep 16 16:20:52 JST 2005
stress: info: [699] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: info: [699] successful run completed in 240s
メモリ負荷生成終了時刻
Load Finish at Fri Sep 16 16:24:52 JST 2005
/root/bin/load.sh: line 57:
694 Terminated
mpstat -P ALL ${INTERVAL}
${COUNT} >${SAVE_DIR}/mpstat.dat
Monitoring Finish at Fri Sep 16 16:25:02 JST 2005
モニタリング終了時刻
# cd mem_512_mpstat_050916_162042/
# cat mpstat.dat
Linux 2.4.21-9.30AX (tama08)
09/16/05
16:20:42
CPU
%user
%nice %system
%idle
intr/s
16:20:47
all
0.00
0.00
0.00
100.00
101.40
16:20:47
0
0.00
0.00
0.00
100.00
101.40
16:20:52
all
0.00
0.00
0.00
100.00
101.40
16:20:52
0
0.00
0.00
0.00
100.00
101.40
16:20:57
all
82.16
0.00
17.43
0.40
102.61
16:20:57
0
82.16
0.00
17.43
0.40
102.61
16:21:02
all
79.40
0.00
20.60
0.00
106.00
16:21:02
0
79.40
0.00
20.60
0.00
106.00
16:21:07
all
87.80
0.00
12.20
0.00
101.00
16:21:07
0
87.80
0.00
12.20
0.00
101.00
16:21:12
all
84.00
0.00
16.00
0.00
101.20
16:21:12
0
84.00
0.00
16.00
0.00
101.20
16:24:27
all
85.60
0.00
14.40
0.00
101.00
16:24:27
0
85.60
0.00
14.40
0.00
101.00
16:24:32
all
84.20
0.00
15.80
0.00
105.20
16:24:32
0
84.20
0.00
15.80
0.00
105.20
(中略)
- 3-13 -
負荷生成開始
16:24:37
all
84.40
0.00
15.60
0.00
106.00
16:24:37
0
84.40
0.00
15.60
0.00
106.00
16:24:42
all
87.60
0.00
12.40
0.00
101.40
16:24:42
0
87.60
0.00
12.40
0.00
101.40
16:24:47
all
88.40
0.00
11.60
0.00
102.00
16:24:47
0
88.40
0.00
11.60
0.00
102.00
16:24:52
all
83.00
0.00
16.60
0.40
102.20
16:24:52
0
83.00
0.00
16.60
0.40
102.20
16:24:57
all
0.00
0.00
0.00
100.00
101.61
16:24:57
0
0.00
0.00
0.00
100.00
101.61
16:25:02
all
0.00
0.00
0.00
100.00
101.61
16:25:02
0
0.00
0.00
0.00
100.00
101.61
負荷生成終了
図 3.1-17 メモリ負荷時の mpstat の挙動
図 3.1-17 において負荷が掛かっている期間(16:20:52 から 16:24:52)の間で%sys(システム
レベルでのCPU利用率)の値が約 10 から 20 程度に上昇しており、CPUがシステム時間とし
て利用されていることがわかる。また、一番左の列を見ると5秒後毎の時刻が表示されて
いて、データ取得タイミングが指定通りになっていることがわかる(上の例ではCPU毎のデ
ータとCPU全体のデータの 2 種類が繰り返し出力されているので、同じ時刻が2回続いて
いる)。
3.1.5.1 CPU 高負荷環境における障害状況
本節では、CPU 高負荷時における sar/iostat/mpstat が指定した時間間隔(5 秒)でデータ
を取得できるかどうかを確認する。
以下に load.sh スクリプトを用いて stress の実行プロセス数を 100、500、1000 と変え
ながら CPU 負荷を発生させた状態での、データ取得間隔の分布を示す。
(1) sar について
CPUに高い負荷を掛けたときの、sarのデータ取得間隔の分布を以下の 図 3.1-18(カーネ
ル 2.6 環境)および 図 3.1-19(カーネル 2.4 環境)に示す。
- 3-14 -
100
90
100 プロセスでは
80
遅延なし
70
比率(%)
60
100プロセス
500プロセス
1000プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-18 CPU 高負荷時における sar のデータ取得間隔の分布(カーネル 2.6 環境)
100
90
80
70
比率(%)
60
50プロセス
100プロセス
500プロセス
1000プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-19 CPU 高負荷時における sar のデータ取得間隔の分布(カーネル 2.4 環境)
カーネル 2.6 環境においては CPU 負荷が 100 プロセスの場合は遅延が発生していない(=
時間間隔が 5 秒の比率が 100%になっている)。ただし 500 プロセス、1000 プロセスと負荷
を上げていくに従い遅延が発生する。一方カーネル 2.4 環境においては、50 プロセスの負
- 3-15 -
荷でもわずかながら遅延が発生し、100 プロセス、500 プロセス、1000 プロセスと負荷が
高くなるに従いより遅延が大きくなる傾向が分かる。よって、CPU 高負荷時にはカーネル
2.4 環境に比べカーネル 2.6 環境の方が sar の遅延が発生しにくいといえる。
(2) iostat について
CPUに高い負荷を掛けたときの、iostatのデータ取得間隔の分布を以下の 図 3.1-20 (カ
ーネル 2.6 環境)および 図 3.1-21 (カーネル 2.4 環境)に示す。
100
90
80
70
100プロセス
500プロセス
1000プロセス
50
40
負荷が高くなると
30
遅れが発生
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
0
1
比率(%)
60
時間間隔(s)
図 3.1-20 CPU 高負荷時における iostat のデータ取得間隔の分布(カーネル 2.6 環境)
- 3-16 -
100
90
80
70
比率(%)
60
50プロセス
100プロセス
500プロセス
1000プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-21 CPU 高負荷時における iostat のデータ取得間隔の分布(カーネル 2.4 環境)
カーネル 2.6 環境、2.4 環境共に 100 プロセスまでは遅延が発生していないが、負荷量を
増やした場合に、カーネル 2.6 環境では遅延する回数が増えている一方で、カーネル 2.4 環
境では大きな変化は見られない。よって CPU 高負荷時の iostat はカーネル 2.4 環境の方が、
指定した通りの挙動を示す傾向がある。
(3) mpstat について
CPUに高い負荷を掛けたときの、mpstatのデータ取得間隔の分布を以下の 図 3.1-22 (カ
ーネル 2.6 環境)および 図 3.1-23 (カーネル 2.4 環境)に示す。
- 3-17 -
100
90
80
70
比率(%)
60
100プロセス
500プロセス
1000プロセス
50
40
負荷が高くなると
30
遅れが発生
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-22 CPU 高負荷時における mpstat のデータ取得間隔の分布(カーネル 2.6 環境)
100
90
80
70
比率(%)
60
50プロセス
100プロセス
500プロセス
1000プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-23 CPU 高負荷時における mpstat のデータ取得間隔の分布(カーネル 2.4 環境)
mpstat の場合も iostat と同じく、カーネル 2.6 環境、2.4 環境共に 100 プロセスまでは
遅延が発生していないが、負荷を増やした場合に、カーネル 2.6 環境では遅延する回数が増
えている一方、カーネル 2.4 環境では大きな変化は見られない。
以上の (1)、(2)、(3)から、CPU高負荷時にsarはカーネル 2.6/2.4 環境共に遅延が発生す
- 3-18 -
るが、iostat/mpstatに関してはカーネル 2.6 環境の方がカーネル 2.4 環境より遅延が発生し
やすいといえる。
3.1.5.2 メモリ高負荷環境における障害状況
本節では、メモリ高負荷時における sar/iostat/mpstat が指定した時間間隔(5 秒)でデータ
を取得できるかどうかを確認する。
以下に load.sh スクリプトを用いて stress 1 プロセスで 512MB、1024MB、2048MB の
メモリ領域の malloc/free を繰り返すことによりメモリ負荷を発生させた状態での、データ
取得間隔の分布を示す(今回検証で用いた環境はメモリを 1GB 搭載しているため、512MB
の負荷ではスワップは発生しないが、2048MB の負荷では確実にスワップが発生する)。
(1) sar について
メモリに高い負荷を掛けたときの、sarのデータ取得間隔の分布を以下の 図 3.1-24 (カー
ネル 2.6 環境)および 図 3.1-25 (カーネル 2.4 環境)に示す。
100
90
80
70
512MB
1024MB
2048MB
50
40
30
20
6 秒が最大
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
0
1
比率(%)
60
時間間隔(s)
図 3.1-24 メモリ高負荷時における sar のデータ取得間隔の分布(カーネル 2.6 環境)
- 3-19 -
100
90
80
70
比率(%)
60
512MB
1024MB
2048MB
50
40
30
20
9 秒が最大
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-25 メモリ高負荷時における sar のデータ取得間隔の分布(カーネル 2.4 環境)
sarの挙動に関して、図 3.1-24 と 図 3.1-25 を確認すると、カーネル 2.6 環境、2.4 環境
共に 512MBの負荷において遅れは発生していないが、2048MBの負荷の際に、発生頻度は
低いが遅れが発生していることがわかる。また、最大のデータ取得間隔を見ると、カーネ
ル 2.6 環境では 6 秒にとどまっている一方、カーネル 2.4 環境では 9 秒まで遅れていること
が分かる。よって、メモリ高負荷時のsarの遅延はカーネル 2.6 環境で改善されているとい
える。
(2) iostat について
メモリに高い負荷を掛けたときの、iostatのデータ取得間隔の分布を以下の 図 3.1-26 (カ
ーネル 2.6 環境)および 図 3.1-27 (カーネル 2.4 環境)に示す。
- 3-20 -
100
90
80
70
比率(%)
60
512MB
1024MB
2048MB
50
40
30
20
6 秒が最大
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-26 メモリ高負荷時における iostat のデータ取得間隔の分布(カーネル 2.6 環境)
100
90
80
70
比率(%)
60
512MB
1024MB
2048MB
50
40
30
20
10 秒が最大
10
61~
51~60
41~50
31~40
21~30
11~20
10
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-27 メモリ高負荷時における iostat のデータ取得間隔の分布(カーネル 2.4 環境)
iostatの挙動に関して 図 3.1-26 と 図 3.1-27 を確認すると、sarと同じく 512MBの負荷
では遅れが発生していないが、2048MBの負荷では遅れが発生している。また、データ取得
間隔の開きもカーネル 2.4 環境の方がカーネル 2.6 環境より長い。よってsarと同じく、カ
ーネル 2.6 環境においてメモリ高負荷時のiostatの遅延も改善されているといえる。
(3) mpstat について
メ モ リ に 高 い 負 荷 を 掛 け た と き の 、 mpstat の デ ー タ 取 得 間 隔 の 分 布 を 以 下 の 図
- 3-21 -
3.1-28(カーネル 2.6 環境)および 図 3.1-29(カーネル 2.4 環境)に示す。
100
90
80
70
比率(%)
60
512MB
1024MB
2048MB
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-28 メモリ高負荷時における mpstat のデータ取得間隔の分布(カーネル 2.6 環境)
100
90
80
70
比率(%)
60
512MB
1024MB
2048MB
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-29 メモリ高負荷時における mpstat のデータ取得間隔の分布(カーネル 2.4 環境)
mpstatの挙動に関して、図 3.1-28 と 図 3.1-29 を確認すると、sar/iostatと同じように
512MBの負荷の場合は遅れが発生していないが、負荷量を増やすと遅れが発生する。ただ
し、カーネルの違いによる差は顕著には見られない。
以上から、スワップの発生しない負荷(512MB 負荷)では遅れが発生しないが、2048MB
の負荷のようなスワップが発生するメモリ負荷においては sar/iostat/mpstat それぞれ遅れ
- 3-22 -
が発生することがわかる。また、sar と iostat についてはカーネル 2.6 環境の方がカーネル
2.4 環境に比べ遅延しない傾向にあるといえる。
3.1.5.3 ディスク I/O 高負荷環境における障害状況
本節では、ディスク I/O 高負荷時における sar/iostat/mpstat が指定した時間間隔(5 秒)
でデータを取得できるかどうかを確認する。
以下では load.sh スクリプトを用いて IOzone でディクス I/O 負荷を発生させた状態での、
sar/iostat/mpstat のデータ取得間隔の分布を示す。実際には IOzone の実行プロセスを 2
プロセス、5 プロセス、10 プロセスと変化させながら測定した(1 プロセスは 500MB のフ
ァイル書込みを行う)。
(1) sar について
ディスクに高い負荷を掛けたときの、sarのデータ取得間隔の分布を以下の 図 3.1-30(カ
ーネル 2.6 環境)および 図 3.1-31(カーネル 2.4 環境)に示す。
100
90
80
70
比率(%)
60
2プロセス
5プロセス
10プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-30 ディスク I/O 高負荷時における sar のデータ取得間隔の分布(カーネル 2.6 環境)
- 3-23 -
100
90
80
70
比率(%)
60
2プロセス
5プロセス
10プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-31 ディクス高負荷時における sar のデータ取得間隔の分布(カーネル 2.4 環境)
図 3.1-30 と 図 3.1-31 の結果の結果を比較するとカーネル 2.4/2.6 環境を問わずsarは大き
く遅れることがわかる。
(2) iostat について
ディスクに高い負荷を掛けたときの、iostatのデータ取得間隔の分布を以下の 図 3.1-32
(カーネル 2.6 環境)および 図 3.1-33 (カーネル 2.4 環境)に示す。
100
90
80
70
比率(%)
60
2プロセス
5プロセス
10プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-32 ディスク I/O 高負荷時における iostat のデータ取得間隔の分布(カーネル 2.6 環境)
- 3-24 -
100
90
80
70
比率(%)
60
2プロセス
5プロセス
10プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-33 ディスク I/O 高負荷時における iostat のデータ取得間隔の分布(カーネル 2.4 環境)
一方、iostatに関しては 図 3.1-32 と 図 3.1-33 で示すようにカーネル 2.6 環境とカーネ
ル
2.4 環境で結果が異なり、カーネル 2.4 環境では iozone2 プロセスでも遅れが発生してい
るが、カーネル 2.6 環境では 10 プロセスでも遅れが発生していない。よって、ディスク I/O
高負荷時の iostat の挙動がカーネル 2.6 環境では改善されているといえる。
(3) mpstat について
デ ィス クに高 い負 荷を掛 けた ときの 、 iostatの デー タ取得 間隔 の分布 を以 下の 図
3.1-34(カーネル 2.6 環境)および 図 3.1-35 (カーネル 2.4 環境)に示す。
- 3-25 -
100
90
80
70
比率(%)
60
2プロセス
5プロセス
10プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-34 ディスク I/O 高負荷時における mpstat のデータ取得間隔の分布(カーネル 2.6 環境)
100
90
80
70
比率(%)
60
2プロセス
5プロセス
10プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-35 ディスク I/O 高負荷時における mpstat のデータ取得間隔の分布(カーネル 2.4 環境)
カーネル 2.4 環境とカーネル 2.6 環境の差異に関して iostat と同様の傾向である。
(4) I/O スケジューラの選択による挙動の違い
Linux カーネル 2.6 ではブロックデバイスへの I/O リクエストを効率よく処理するため
に新たな I/O スケジューリング機構が複数導入され、用途に応じて選択することができる
(なお、これまでに示したでデータは MIRACLE LINUX V4.0 beta でのデフォルトである
CFQ I/O スケジューラを使用した環境で取得している)。
- 3-26 -
現在利用できる I/O スケジューラは以下の 4 種類である
1.
CFQ(Completed Fair Queuing): デバイス入出力を細かい単位でおこないプロ
セス間で I/O を等しく分配することにより、システムの応答時間を改善する。
2.
deadline: 長時間待たされている I/O 処理を優先的に処理することにより I/O リ
クエスト処理時間を一定以内に保つ。一般にデータベースシステム向けとされ
ている。
3.
as(anticipatory): deadline タイプの改良型。同じプロセスがファイルに対して
連続した I/O を発行する一般的な傾向を利用し、プロセスごとの統計情報に基づ
いて連続した領域の I/O リクエストを発行することにより I/O 処理性能の向上を
図る。
4.
noop: 単純なセクタ順での I/O リクエストの並び替えと併合処理を行うのみ。
以上のI/Oスケジューラを使用した際のディスクI/O高負荷時(iozone10 プロセスで
500MBのファイル書込み)のsarのデータ取得間隔の分布を以下の 図 3.1-36 に示す。
100
90
80
70
比率(%)
60
cfq
as
50
deadline
noop
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-36 I/O スケジューラによる sar のデータ取得間隔の変化
図 3.1-36 からI/Oスケジューラの変更を変更しても 10 秒以上の遅延が解消される事はなく、
根本的な解決にはならない。
以上 (1)、(2)、(3)からディスクI/O高負荷環境においてはsarはカーネル 2.6/2.4 環境を問
わず遅延が発生するが、iostat/mpstatはカーネル 2.4 環境でしか遅延が発生しない。また、
(4)ディスクI/O高負荷時のsarの遅延はI/Oスケジューラーを変更しても解消されない。
3.1.5.4 評価結果のまとめ
3.1.5.1 節、3.1.5.2 節および 3.1.5.3 節で得られた評価結果の概要を 表 3.1-3 にまとめる。
- 3-27 -
表 3.1-3 高負荷環境における障害状況
負荷タイプ
カーネル
sar
iostat
mpstat
sar と同程度の遅延。
sar と同程度の遅延。
2.4
負荷 100 プロセスでは
遅延なし。500 と 1000
では遅延発生。
カーネル 2.6 より遅延大
2.6
軽度の遅延(最大 6 秒)
カーネル 2.6 よりも軽度の
遅延。
sar と同程度の遅延。
カーネル 2.6 よりも軽度の
遅延。
sar と同程度の遅延。
2.4
軽度の遅延(最大 9 秒)
軽度の遅延(最大 10 秒)
軽度の遅延(最大7秒)
2.6
大きな遅延発生
遅延発生なし
遅延発生なし
2.4
カーネル 2.6 と同程度
の大きな遅延発生
大きな遅延発生
遅延発生
(iostat より軽度)
2.6
CPU 負荷
メモリ負荷
I/O 負荷
3.1.5.5 考察および回避策
本節では 2.5.1.5 節および 2.5.1.6 節で述べた障害の回避するための方法およびをその効
果について述べる。
3.1.5.1 節、3.1.5.2 節および 3.1.5.3 節で確認したsar/iostat/mpstatの遅延の原因として以
下があげられる。
z
ジャーナリング処理のコミット待ちによる fdatasync の遅延
z
CPU 高負荷による実行権待ち
(これらの原因を特定する手順は 2.5.1 節を参照のこと)
1 番目の fdatasync の遅延を回避するためには、書込み速度の速い tmpfs の利用や、負荷
の小さいファイルシステムへの出力(ジャーナリング処理の回避)などが考えられる。
また、2 番目の CPU 高負荷による実行権待ちには、プロセス優先度を変更して実行権を
得やすくするなどの回避策が考えられる。
また、ディスクI/O高負荷時にsarは遅延するが、ファイルリダイレクトを利用している
iostat/mpstatは遅延しない(図 3.1-32、図 3.1-34 参照)ことから、sarにおいてもファイル
リダイレクトの利用も効果があると考えられる。
以上の各方法について、どの程度障害回避の効果があるか検証した。その結果概要を 表
(4)で述べる (以下の測定においても 3.1.5.1
3.1-4 に、詳細な手順と結果を以下の (1)、(2)、(3)、
節、3.1.5.2 節および 3.1.5.3 節で実施した手順と同じく同一条件に対して 3 回測定を行い、
その結果を集計している)。
表 3.1-4 障害回避方法とその効果
項番 方法
1
tmpfs
の利用
効果が確認
された負荷 考慮点
タイプ
メモリ上にデータを保存する
計測結果の出力先としてディスクより
ため、監視中にマシン停止など発生すると
書込み速度の速いメモリファイルシス
ディスク I/O
データが消失する
テムを利用する
CPU 高負荷状態では効果はない
方法として挙げられた背景
- 3-28 -
2
3
4
sar が遅延する環境においてもファイ
ファイルリ
ル リ ダ イ レ ク ト を 利 用 す る
ディスク I/O
ダイレクト
iostat/mpstat は遅延しないばあいが
の利用
る
プロセス優
プロセスの実行優先度を上昇させ、
先度
実行可能状態になった際にすぐに実
CPU
(NICE 値)
行権を得られるようにする
の変更
負荷の小
遅延発生に影響を与えているジャー
さいファイ
ナリング処理はファイルシステムごと ディスク I/O
ルシステ
に行われる
ムへ出力
sar のみ適用可能
NICE 値を変更してプロセスの優先度を上昇
させるには root 権限が必要
ディスク I/O 高負荷状態では効果がない
ディスクへの負荷が非常に高い場合、効果
は小さい
(1) tmpfs の利用
tmpfs はメモリ上に構築されたファイルシステムであり、通常の(ディスク上に構築され
たファイルシステムと同様な)ファイルアクセスを行うことができる。OS を停止する等によ
ってマウントを解除すると内容は全て破棄されるが、高速なファイルアクセスが可能なた
め、一時ファイルの格納先として適している。
以下にカーネル 2.6 環境で IOzone によるディスク I/O 高負荷状況で tmpfs をデータ出力
先として用いる手順と、sar/iostat/mpstat のデータ取得間隔の分布を表す。
[root@TAMA09 shm]# cd /dev/shm
tmpfs へ移動
[root@TAMA09 shm]# load.sh io 2 sar
Make Directory io_2_sar_050916_160340
Monitoring Start at Fri Sep 16 16:03:40 JST 2005
Load Start at Fri Sep 16 16:03:50 JST 2005
Load Finish at Fri Sep 16 16:04:22 JST 2005
/root/bin/load.sh: line 57:
1750 Terminated
${INTERVAL} ${COUNT}
Monitoring Finish at Fri Sep 16 16:04:32 JST 2005
図 3.1-37 tmpfs の利用手順
- 3-29 -
sar -A -o ${SAVE_DIR}/sar.dat
100
90
遅延なし
80
70
比率(%)
60
2プロセス
5プロセス
10プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-38 tmpfs 使用時のディスク I/O 高負荷時における sar のデータ取得間隔の分布
この結果から、ディスク I/O 高負荷環境における sar の遅延については tmpfs の利用で
障害が解決していることが分かる。
次に tmpfs を利用した上で、stress による CPU 負荷(1000 プロセス)環境時における iostat
の挙動を確認する。
100
90
80
70
比率(%)
60
100プロセス
500プロセス
1000プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-39 tmpfs 使用時の CPU 高負荷時における iostat のデータ取得間隔の分布
図 3.1-20(ディスク上のファイルシステムを利用)と 図 3.1-39(tmpfsを利用)を比較すると、
特に6秒、7 秒の遅延は解消されず、CPU高負荷状態でtmpfsを使用することによって障害
が解決されたとは言い難い。
- 3-30 -
また、tmpfs を利用する際の注意点として、マウントを解除すると出力されたデータが消
失するため、コマンド終了後はディスク(上のファイルシステム)にコピーするといったバッ
クアップが必要である。
(2) ファイルリダイレクトの利用
ディスク I/O 高負荷時にバイナリファイルにデータを直接保存する sar は遅延するが、フ
ァイルリダイレクトを利用する iostat/mpstat は遅延しないことから、sar でもファイルリ
ダイレクトを利用するとデータ取得の不具合は解消されるのではないかと予想される。
以下にファイルリダイレクトを利用するように load.sh を修正した load_f.sh を示す(sar
の出力にファイルリダイレクトを利用する以外は load.sh と内部動作や使用方法は同じ)。
#!/bin/bash
if [ $# != 3 ]; then
echo "Usage: ./load_f.sh <load_type> <nr of worker> <mon_type>" >& 2
exit 1
fi
load_type=$1
worker=$2
mon_type=$3
export LANG=C
DATE_ID=`date +%y%m%d_%H%M%S`
SAVE_DIR=${load_type}_${worker}_${mon_type}_${DATE_ID}
INTERVAL=5
COUNT=600
TIMEOUT=240
LOG_FILE=load.log
mkdir ${SAVE_DIR}
echo "Make Directory ${SAVE_DIR}" | tee -a ${LOG_FILE}
# Start Monitoring
echo "Monitoring Start at `date`" | tee -a ${LOG_FILE}
if [ ${mon_type} = sar ]; then
ファイルリダイレクトを
使用
sar -A ${INTERVAL} ${COUNT} > ${SAVE_DIR}/sar.dat &
elif [ ${mon_type} = iostat ]; then
iostat –t -x ${INTERVAL} ${COUNT} > ${SAVE_DIR}/iostat.dat &
- 3-31 -
else
mpstat -P ALL ${INTERVAL} ${COUNT} > ${SAVE_DIR}/mpstat.dat &
fi
sleep 10
# Start Load
echo "Load Start at `date`" | tee -a ${LOG_FILE}
if [ ${load_type} = cpu ]; then
stress -c ${worker} -t ${TIMEOUT}
elif [ ${load_type} = mem ]; then
stress -m 1 --vm-bytes ${worker}M -t ${TIMEOUT}
else
iozone_wrap ${worker} 500
fi
echo "Load Finish at `date`" | tee -a ${LOG_FILE}
sleep 10
# Stop Monitoring
if [ ${mon_type} = sar ]; then
killall sar
killall sadc
elif [ ${mon_type} = iostat ]; then
killall iostat
else
killall mpstat
fi
echo "Monitoring Finish at `date`" | tee -a ${LOG_FILE}
図 3.1-40 sar の出力にファイルリダイレクトを利用するスクリプト load_f..sh
以下にカーネル 2.6 環境で IOzone によるディスク I/O 高負荷状況でファイルリダイレク
トを利用した場合の、sar のデータ取得間隔の分布を示す。
- 3-32 -
100
90
遅延なし
80
70
比率(%)
60
2プロセス
5プロセス
10プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-41 ファイルリダイレクト使用時のディスク I/O 高負荷時における sar のデータ取得間隔
の分布
上の結果から、データ取得間隔は指定どおりの 5 秒になっている。よって、sar のスロー
ダウンに関してファイルリダイレクトの使用は有効であるといえる。
(3) プロセス優先度(NICE 値)の変更
負荷プロセスが多数存在すると、パフォーマンス監視ツールのプロセスが実行可能状態
になってから実際に実行権を得るまでに遅延が発生する場合がある。それを防ぐためにプ
ロセスの優先度(NICE 値)を nice コマンドで上昇させ、実行可能になると直ちに実行権を取
得できるようにすることで、遅延を回避することができると考えられる。
以下に、sar/iostat/mpstat の NICE 値を”-20”に設定するように load.sh を変更した
load_n.sh を示す。ちなみに、sar/iostat/mpstat の NICE 値を変更する以外は、load_n.sh
の内部処理や使用方法は load.sh と同じである。
#!/bin/bash
if [ $# != 3 ]; then
echo "Usage: ./load.sh <load_type> <nr of worker> <mon_type>" >& 2
exit 1
fi
load_type=$1
worker=$2
mon_type=$3
- 3-33 -
export LANG=C
DATE_ID=`date +%y%m%d_%H%M%S`
SAVE_DIR=${load_type}_${worker}_${mon_type}_${DATE_ID}
INTERVAL=5
COUNT=600
TIMEOUT=240
LOG_FILE=load.log
mkdir ${SAVE_DIR}
echo "Make Directory ${SAVE_DIR}" | tee -a ${LOG_FILE}
# Start Monitoring
echo "Monitoring Start at `date`" | tee -a ${LOG_FILE}
if [ ${mon_type} = sar ]; then
nice -n -20 sar -A -o ${SAVE_DIR}/sar.dat ${INTERVAL} ${COUNT} &
elif [ ${mon_type} = iostat ]; then
nice -n -20 iostat –t -x ${INTERVAL} ${COUNT} > ${SAVE_DIR}/iostat.dat &
else
nice -n -20 mpstat -P ALL ${INTERVAL} ${COUNT} > ${SAVE_DIR}/mpstat.dat &
fi
nice コマンドを用いて
sleep 10
優先度を変更する
# Start Load
echo "Load Start at `date`" | tee -a ${LOG_FILE}
if [ ${load_type} = cpu ]; then
stress -c ${worker} -t ${TIMEOUT}
elif [ ${load_type} = mem ]; then
stress -m 1 --vm-bytes ${worker}M -t ${TIMEOUT}
else
iozone_wrap ${worker} 500
fi
echo "Load Finish at `date`" | tee -a ${LOG_FILE}
sleep 10
# Stop Monitoring
if [ ${mon_type} = sar ]; then
- 3-34 -
killall sar
killall sadc
elif [ ${mon_type} = iostat ]; then
killall iostat
else
killall mpstat
fi
echo "Monitoring Finish at `date`" | tee -a ${LOG_FILE}
図 3.1-42 sar/iostat/mpstat の NICE 値を変更したスクリプト load_n.sh
以下にカーネル 2.6 環境で stress による CPU 高負荷状況で NICE 値をを利用した場合の、
sar/iostat/mpstat のデータ取得間隔の分布を示す。
100
90
80
70
100プロセス
500プロセス
1000プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
0
1
比率(%)
60
時間間隔(s)
図 3.1-43 NICE 値を変更した際の CPU 高負荷時における sar のデータ取得間隔の分布
- 3-35 -
100
90
80
70
比率(%)
60
100プロセス
500プロセス
1000プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-44 NICE 値を変更した際の CPU 高負荷時における iostat のデータ取得タイミング
100
90
80
70
比率(%)
60
100プロセス
500プロセス
1000プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-45 NICE 値を変更した際の CPU 高負荷時における mpstat のデータ取得タイミング
CPU高負荷環境においてNICE値を変更しない場合(図 3.1-18(sar)、図 3.1-20(iostat)、図
3.1-22(mpstat)) と NICE 値 を 変 更 し た 場 合 ( 図 3.1-43(sar) 、 図 3.1-44(iostat) 、 図
3.1-45(mpstat))を比較すると(共にカーネル 2.6 環境)、NICEを変更することで、すべての
データ取得間隔が 5 秒になるわけではないが、遅延している比率がかなり下がり、CPU負
荷に対しては一定の効果が得られている。
次に、NICE 値を変更した場合のディスク I/O 高負荷時の sar の挙動について確認する。
- 3-36 -
100
90
80
70
比率(%)
60
2プロセス
5プロセス
10プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-46 NICE 値を変更した場合のディスク I/O 高負荷時の sar の挙動
図 3.1-46 から遅延が解消していないことが分かり、ディスクI/O高負荷時のsarのスローダ
ウンにはNICE値の変更することによって障害は解決されないことが分かる。ディスクへの
書込み完了を待つ遅延では、プロセスのスケジューリングの順番を待っているわけではな
い(2.5.1.5 節参照)ため、優先度の変更の効果が現れないと考えられる。
また、NICE 値を利用してプロセスの優先順位を高くするためには root ユーザで nice コ
マンドを実行する必要があるので注意が必要である。
(4) 負荷の小さいファイルシステムへの出力
ディスク I/O 高負荷時において sar が遅延するのはジャーナリング処理によるコミット待
ちが原因である(2.5.1.5 節参照)。ただし、ジャーナリング処理はファイルシステムごとに行
われるため、ディスク I/O 負荷が高いパーティショとは別のパーティションを sar の出力結
果保存先とすればコミット待ちによる遅延は回避できるものと考えられる。
以下にカーネル 2.6 環境で IOzone によるディスク I/O 高負荷状況で sar の出力先を別パ
ーティションにした場合のデータ取得間隔の分布を示す。
- 3-37 -
100
90
80
70
比率(%)
60
2プロセス
5プロセス
10プロセス
50
40
30
20
10
61~
51~60
41~50
31~40
21~30
11~20
10
9
8
7
6
5
4
3
2
1
0
時間間隔(s)
図 3.1-47 別パーティションを使用した場合のディスク I/O 高負荷時の sar のデータ取得間隔
以上の結果から、2 プロセスのケースにおいては間隔がほぼ指定通りの 5 秒になっており
一定の効果はあるが、5 プロセス/10 プロセスの負荷においては、改善がみられるものの取
得間隔が広がる場合が数回あり、スローダウンが完全に解消されるとはいえない。
ただし、今回は負荷が高いパーティションと sar の出力先パーティションが同じデバイス
上にあるため、効果が限定的であったと考えられる。それらを別の物理デバイスにすれば
より高い効果が期待される。
■まとめ
以上の(1)から(4)の結果から、sar/iostat/mpstat について以下のような利用指針を得るこ
とができる。
sar、iostat、mpstat は高負荷時にデータ取得間隔が開くが、tmpfs やファイルリダイレ
クトの使用、nice コマンドによる優先度の操作、結果の出力先ファイルシステムの変更で
改善されるケースがある。ただし、負荷のタイプにより遅延を発生させる原因が異なり、
1つの回避策が常にすべての問題を解決するわけではない。よって、以下のような対策が
さらに必要である。
z
システム内で発生する負荷のタイプ、負荷の大きさをまず分析し、それぞれのタイ
プにあった適切な回避策を選択する
z
複数の回避策の組み合わせ(tmpfs の利用と NICE 値の利用の併用など)を検討する
- 3-38 -
3.2 プロファイラの機能評価
3.2.1 ツール概要
OProfile は、Linux 2.2/2.4/2.6 システムに対応したプロファイリングツールであり、モ
ジュールや割り込みハンドラも含んだカーネルから共有ライブラリや通常アプリケーショ
ンにいたる、システムのすべてをプロファイリングする能力を持っている。
プロファイリングは、様々なイベントの発生時点における PC (Program Counter) の値
をサンプリングすることによって、その瞬間にどのバイナリ中のどの箇所が CPU によって
実行中であったかという情報を記録する。この情報の蓄積を統計的に処理することによっ
て、システム全体の中で一体どこの処理に偏っているのか、どこの処理に集中しているの
かを把握し、例えばパフォーマンス向上を検討する材料となりえる。
サンプリングのトリガーとして設定できるイベントは CPU の種類によって異なるが、タ
イマイベントはどの CPU でも利用できる。PentiumIII 系では CPU_CLK_UNHALTED、
Pentium 4 系では GLOBAL_POWER_EVENTS と呼ばれている。
OProfileの公式ページ http://oprofile.sourceforge.net/ にはソースコードだけでなく、ド
キュメントやFAQが掲載されているので参考にされたい。
3.2.2 評価環境
評価に用いた評価環境を 表 3.3-1 に示す。以降の評価は、全てこの環境で行ったもので
ある。
表 3-5
項
OProfile 機能評価の評価環境
項目
評価環境
番
1
ハード
CPU
Intel Xeon 2GHz×4
2
ウェア
メモリ
5GByte
ハードディスク
34GByte(SCSI)×4
3
4
ソフト
ディストリビューション
MIRACLE LINUX V4.0 beta
5
ウェア
カーネル
2.6.9
ファイルシステム
ext3(ブロックサイズ:4KByte)
7
MIRACLE LINUX V4.0 の場合、OProfile はデフォルトでインストールされているが、
カーネルプロファイリングをする場合は kernel-debuginfo パッケージがインストールされ
ている必要がある。
- 3-39 -
3.2.3 評価項目
MIRACLE LINUX V4.0 において OProfile を利用するには、oprofile-0.8.2-1AX.i386.rpm
パッケージに含まれている各コマンドを実行する。今回の検証に使用した3つのコマンド
を 以 下 に 紹 介 す る 。 な お 、 OProfile が サ ン プ リ ン グ し た デ ー タ は デ ィ レ ク ト リ
/var/lib/oprofile/samples に格納される。
コマンド
説明
opcontrol [ options ]
各種設定をする。oprofile の起動停止。
opreport [ options ] [ profile specification ]
レポートを作成する
opstack [ options ] [ profile specification ]
コールグラフを作成する
opannotate [ options ] [ profile specification ]
ソースコードとプロファイルを出力する
oparchive [ options ] [ profile specification ]
oprofile データをアーカイブする
opgprof [ options ] [ profile specification ]
gprof 形式のプロファイルデータを出力
options:
session:sessionlist
セッションリストを指定。セッションリストの指定がない場合は、current セッションとみ
なす
session-exclude:sessionlist
取り除くセッションのリスト
image:imagelist
プロファイルするイメージのリスト
image-exclude:imagelist
取り除くイメージのリスト
lib-image:imagelist
イメージリストと同様
lib-image-exclude:imagelist
取り除く lib-image のリスト
event:eventname
イベント名
count:eventcount
カウント数。イベントがこの回数発生したらデータをサンプリングする
unit-mask:maskvalue
ユニットマスク
cpu:cpulist
プロファイルする CPU リスト(0から始まる)
tgid:pidlist
プロファイルするタスクグループを指定する
- 3-40 -
tid:tidlist
プロファイルするスレッドを指定する。最近のスレッドライブラリを利用すると、プロセ
スのすべてのスレッドは同じタスクグループ ID を共有するが異なるスレッド ID を持つ
/usr/bin/opcontrol
機能:
各種設定変更や起動・停止といった OProfile のコントロールを行う。
オプション:
--vmlinux=<kernel file>
デバッグ情報入りカーネルファイルを指定する
--no-vmlinux
カーネルファイルを持っていなく、カーネルプロ
ファイリングを取りたくない時指定する
--help
ヘルプを表示する
--version
バージョンを表示する
--init
oprofile のモジュールをロードする
--setup
プロファイリングオプションの設定をし、
/root/.oprofile/daemonrc に格納する
--start-daemon
oprofile デーモンを起動する。プロファイリング
そのものはまだ開始しない。2.2/2.4 カーネルでは
利用できない
--reset
サンプリングしたデータを削除する
--dump
プロファイリングしたデータをデーモンへフラッ
シュする
--start
プロファイリングを開始する
--stop
プロファイリングを終了する。デーモンは起動し
たままである。2.2/2.4 カーネルでは利用できない
--shutdown
プロファイリングを終了する。デーモンも kill す
る
--deinit
デーモンをシャットダウンし、oprofile モジュー
ルと oprofilefs をアンロードする
--buffer-size
サンプルを格納するカーネルバッファサイズ
--cpu-buffer-size
CPU ごとのカーネルバッファサイズ.(2.6 のみ)
--event=[event|”default”]
イベントないしは”default”を指定する
--separate=[none,lib,kernel,t
セパレータによりサンプリングを分離する
hread,cpu,all]
- 3-41 -
--callgraph=#depth
コールグラフのサンプリングを有効にする。
#depth が0の場合、コールグラフサンプリングを
行わない。x86 で 2.6 カーネル以降で利用可能で
ある
--image=[name,name...|"all"]
--verbose
デーモンのログに詳細を出力。オーバヘッドが大
きい
--kernel-range=start,end
16 進でカーネルの VMA アドレスを指定する
--save=<session name>
サンプリングしたデータを別名で保存する
使用例:
# opcontrol --vmlinux= /usr/lib/debug/lib/modules/`uname –r`/vmlinux
# opcontrol --reset
# opcontrol –start
/usr/bin/opreport
機能:
サンプリングしたデータから、実際に解析可能なデータを抽出する。
オプション:
--accumulated / -c
シンボルリストのサンプル数、パーセンテージを積算する
--debug-info / -g
各シンボルのソースファイルと行を表示する
--demangle=none|smar
t|normal
--details / -d
命令毎の情報を表示
--exclude-dependent / アプリケーション依存のライブラリ、モジュール、カーネ
-x
ル等イメージを含めない。--separate を利用したときに意
味がある
--exclude-symbols
/ シンボルを除外する
-e [symbols]
--global-percent
全体に対する比率を表示する
--help / -? / --usage ヘルプを表示する
--image-path
/
[paths]
--include-symbols
-p バイナリの追加検索パスを指定する。2.6 カーネル以降、モ
ジュールを見つけるために必要である
/ symbols だけを含める
-i [symbols]
--long-filenames / -l フルパスを出力する
- 3-42 -
--merge / -m [lib,
--separate セッションで分離したプロファイルデータをマ
cpu, tid, tgid,
ージする
unitmask, all]
--no-header
プロファイリングパラメータの詳細情報を含めない
--output-file / -o
stdout ではなく file へ出力する
[file]
--reverse-sort / -r
デフォルトとは逆順にソートする
--show-address / -w
各シンボルの VMA アドレスを表示する
--sort / -s [vma,
[vma, sample, symbol, debug, image]でソートする
sample, symbol,
debug, image]
--symbols / -l
シンボルごとにリストする
--threshold / -t
percentage 以上のデータのシンボルだけを出力する
[percentage]
--verbose / -V
詳細なデバッグ情報を与える
[options]
--version / -v
バージョンを示す
使用例
# opreport -l -p /lib/modules/$(uname -r)
> ${saveDir}/summary.out 2>&1
/usr/bin/opannotate
機能:
サンプリングデータが記載されたソースファイルを出力する。
オプション:
--assembly / -a
アセンブリを出力する。--source と一緒の場合、ソー
ス、アセンブリ混在で出力する
--output-dir <directory>
ソースファイルの出力ディレクトリを指定する
--demangle=none|smart|nor
mal
--exclude-dependent / -x
アプリケーション依存のライブラリ、モジュール、カ
ーネル等イメージを含めない。--separate を利用した
ときに意味がある
--exclude-symbols
/
-e シンボルを除外する
[symbols]
--help / -? / --usage
ヘルプを表示する
- 3-43 -
--image-path / -p [paths]
バイナリの追加検索パスを指定する。2.6 カーネル以
降、モジュールを見つけるために必要である
files だけを含める
--include-file [files]
--include-symbols
/
-i symbols だけを含める
[symbols]
--objdump-params [params]
objdump を呼ぶときの追加のパラメータ
--merge / -m [lib, cpu, tid, --separate セッションで分離したプロファイルデータ
tgid, unitmask, all]
をマージする
--output-dir / -o [dir]
出力ディレクトリ。opannotate 出力を各ソースファ
イルごとに行う
--search-dirs / -d [paths] ソースファイルを検索するパス。イメージに対するデ
バッグ情報が早退パスを含むとき、このオプションを
利用する必要がある
--base-dirs / -b [paths]
デバッグソースファイルから取り除くパス。
--search-dirs の base-dirs を探す前に行う
annotate ソースを出力する。これにはバイナリのデ
--source / -s
バッグ情報が必要である
--threshold
/
-t percentage 以上のデータのシンボルだけを出力する
[percentage]
--verbose / -V [options]
詳細なデバッグ情報を与える
--version / -v
バージョンを示す
使用例:
# opannotate -s -o ${saveDir}/src 2> ${saveDir}/opannotate.log
そのほか、opstack/opgprof/oparchive などのコマンドがある。
利用可能な性能イベント:
x86info の出力:
Family: 15 Model: 2 Stepping: 6 Type: 0 Brand: 12
CPU Model: Pentium 4 (Northwood) Original OEM
Processor name string: Intel(R) Xeon(TM) MP CPU 2.20GHz
Feature flags:
fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflsh dtes
acpi mmx fxsr sse sse2 selfsnoop ht acc pbe
Extended feature flags:
cntx-id
Instruction trace cache:
- 3-44 -
Size: 12K uOps 8-way associative.
L1 Data cache:
Size: 8KB
Sectored, 4-way associative.
line size=64 bytes.
L2 unified cache:
Size: 512KB
Sectored, 8-way associative.
line size=64 bytes.
L3 unified cache:
Size: 2MB
8-way associative.
line size=64 bytes.
Instruction TLB: 4K, 2MB or 4MB pages, fully associative, 128 entries.
Data TLB: 4KB or 4MB pages, fully associative, 64 entries.
The physical package supports 1 logical processors
このマシンの利用可能な性能評価イベントは、opcontrol –list-events で得られる。性能
評価イベントは CPU アーキテクチャに依存するので注意が必要である。例えば Pentium
III と Pentium 4/Intel Xeon 系では取得できるイベントはまったく異なる。
各イベントの詳細については、IA-32 Intel Architecture Software Developer’s Manual、
Volume 3: System Programming Guide、 Appendix A を参照のこと。
表 3-6Pentium4/Xeon の性能評価イベント
oprofile: available events for CPU type "P4 / Xeon"
See Intel Architecture Developer's Manual Volume 3, Appendix A and
Intel Architecture Optimization Reference Manual (730795-001)
イベント名およびユニットマスク
GLOBAL_POWER_EVENTS: (counter: 0, 4)
time during which processor is not stopped (min count: 3000)
Unit masks (default 0x1)
---------0x01: mandatory
BRANCH_RETIRED: (counter: 3, 7)
retired branches (min count: 3000)
Unit masks (default 0xc)
---------0x01: branch not-taken predicted
0x02: branch not-taken mispredicted
- 3-45 -
0x04: branch taken predicted
0x08: branch taken mispredicted
MISPRED_BRANCH_RETIRED: (counter: 3, 7)
retired mispredicted branches (min count: 3000)
Unit masks (default 0x1)
---------0x01: retired instruction is non-bogus
BPU_FETCH_REQUEST: (counter: 0, 4)
instruction fetch requests from the branch predict unit (min count: 3000)
Unit masks (default 0x1)
---------0x01: trace cache lookup miss
ITLB_REFERENCE: (counter: 0, 4)
translations using the instruction translation lookaside buffer (min count:
3000)
Unit masks (default 0x7)
---------0x01: ITLB hit
0x02: ITLB miss
0x04: uncacheable ITLB hit
MEMORY_CANCEL: (counter: 2, 6)
cancelled requesets in data cache address control unit (min count: 3000)
Unit masks (default 0x8)
---------0x04: replayed because no store request buffer available
0x08: conflicts due to 64k aliasing
MEMORY_COMPLETE: (counter: 2, 6)
completed split (min count: 3000)
Unit masks (default 0x3)
---------0x01: load split completed,
excluding UC/WC loads
0x02: any split stores completed
0x04: uncacheable load split completed
0x08: uncacheable store split complete
LOAD_PORT_REPLAY: (counter: 2, 6)
replayed events at the load port (min count: 3000)
Unit masks (default 0x2)
----------
- 3-46 -
0x02: split load
STORE_PORT_REPLAY: (counter: 2, 6)
replayed events at the store port (min count: 3000)
Unit masks (default 0x2)
---------0x02: split store
MOB_LOAD_REPLAY: (counter: 0, 4)
replayed loads from the memory order buffer (min count: 3000)
Unit masks (default 0x3a)
---------0x02: replay cause: unknown store address
0x08: replay cause: unknown store data
0x10: replay cause: partial overlap between load and store
0x20: replay cause: mismatched low 4 bits between load and store addr
BSQ_CACHE_REFERENCE: (counter: 0, 4)
cache references seen by the bus unit (min count: 3000)
Unit masks (default 0x73f)
---------0x01: read 2nd level cache hit shared
0x02: read 2nd level cache hit exclusive
0x04: read 2nd level cache hit modified
0x08: read 3rd level cache hit shared
0x10: read 3rd level cache hit exclusive
0x20: read 3rd level cache hit modified
0x100: read 2nd level cache miss
0x200: read 3rd level cache miss
0x400: writeback lookup from DAC misses 2nd level cache
IOQ_ALLOCATION: (counter: 0)
bus transactions (min count: 3000)
Unit masks (default 0xefe1)
---------0x01: bus request type bit 0
0x02: bus request type bit 1
0x04: bus request type bit 2
0x08: bus request type bit 3
0x10: bus request type bit 4
0x20: count read entries
0x40: count write entries
0x80: count UC memory access entries
- 3-47 -
0x100: count WC memory access entries
0x200: count write-through memory access entries
0x400: count write-protected memory access entries
0x800: count WB memory access entries
0x2000: count own store requests
0x4000: count other / DMA store requests
0x8000: count HW/SW prefetch requests
IOQ_ACTIVE_ENTRIES: (counter: 4)
number of entries in the IOQ which are active (min count: 3000)
Unit masks (default 0xefe1)
---------0x01: bus request type bit 0
0x02: bus request type bit 1
0x04: bus request type bit 2
0x08: bus request type bit 3
0x10: bus request type bit 4
0x20: count read entries
0x40: count write entries
0x80: count UC memory access entries
0x100: count WC memory access entries
0x200: count write-through memory access entries
0x400: count write-protected memory access entries
0x800: count WB memory access entries
0x2000: count own store requests
0x4000: count other / DMA store requests
0x8000: count HW/SW prefetch requests
BSQ_ALLOCATION: (counter: 0)
allocations in the bus sequence unit (min count: 3000)
Unit masks (default 0x21)
---------0x01: (r)eq (t)ype (e)ncoding, bit 0: see next bit
0x02: rte bit 1: 00=read, 01=read invalidate, 10=write, 11=writeback
0x04: req len bit 0
0x08: req len bit 1
0x20: request type is input (0=output)
0x40: request type is bus lock
0x80: request type is cacheable
0x100: request type is 8-byte chunk split across 8-byte boundary
0x200: request type is demand (0=prefetch)
- 3-48 -
0x400: request type is ordered
0x800: (m)emory (t)ype (e)ncoding, bit 0: see next bits
0x1000: mte bit 1: see next bits
0x2000: mte bit 2: 000=UC, 001=USWC, 100=WT, 101=WP, 110=WB
X87_ASSIST: (counter: 3, 7)
retired x87 instructions which required special handling (min count: 3000)
Unit masks (default 0x1f)
---------0x01: handle FP stack underflow
0x02: handle FP stack overflow
0x04: handle x87 output overflow
0x08: handle x87 output underflow
0x10: handle x87 input assist
MACHINE_CLEAR: (counter: 3, 7)
cycles with entire machine pipeline cleared (min count: 3000)
Unit masks (default 0x1)
---------0x01: count a portion of cycles the machine is cleared for any cause
0x04: count each time the machine is cleared due to memory ordering issues
0x40: count each time the machine is cleared due to self modifying code
TC_MS_XFER: (counter: 1, 5)
number of times uops deliver changed from TC to MS ROM (min count: 3000)
Unit masks (default 0x1)
---------0x01: count TC to MS transfers
UOP_QUEUE_WRITES: (counter: 1, 5)
number of valid uops written to the uop queue (min count: 3000)
Unit masks (default 0x7)
---------0x01: count uops written to queue from TC build mode
0x02: count uops written to queue from TC deliver mode
0x04: count uops written to queue from microcode ROM
INSTR_RETIRED: (counter: 3, 7)
retired instructions (min count: 3000)
Unit masks (default 0x1)
---------0x01: count non-bogus instructions which are not tagged
0x02: count non-bogus instructions which are tagged
0x04: count bogus instructions which are not tagged
- 3-49 -
0x08: count bogus instructions which are tagged
UOPS_RETIRED: (counter: 3, 7)
retired uops (min count: 3000)
Unit masks (default 0x1)
---------0x01: count marked uops which are non-bogus
0x02: count marked uops which are bogus
UOP_TYPE: (counter: 3, 7)
type of uop tagged by front-end tagging (min count: 3000)
Unit masks (default 0x2)
---------0x02: count uops which are load operations
0x04: count uops which are store operations
RETIRED_MISPRED_BRANCH_TYPE: (counter: 1, 5)
retired mispredicted branched, selected by type (min count: 3000)
Unit masks (default 0x1f)
---------0x01: count unconditional jumps
0x02: count conditional jumps
0x04: count call branches
0x08: count return branches
0x10: count indirect jumps
RETIRED_BRANCH_TYPE: (counter: 1, 5)
retired branches, selected by type (min count: 3000)
Unit masks (default 0x1f)
---------0x01: count unconditional jumps
0x02: count conditional jumps
0x04: count call branches
0x08: count return branches
0x10: count indirect jumps
TC_DELIVER_MODE: (counter: 1, 5)
duration (in clock cycles) in the trace cache and decode engine (min count:
3000)
Unit masks (default 0x4)
---------0x04: processor is in deliver mode
0x20: processor is in build mode
PAGE_WALK_TYPE: (counter: 0, 4)
- 3-50 -
page walks by the page miss handler (min count: 3000)
Unit masks (default 0x1)
---------0x01: page walk for data TLB miss
0x02: page walk for instruction TLB miss
FSB_DATA_ACTIVITY: (counter: 0, 4)
DRDY or DBSY events on the front side bus (min count: 3000)
Unit masks (default 0x3f)
---------0x01: count when this processor drives data onto bus
0x02: count when this processor reads data from bus
0x04: count when data is on bus but not sampled by this processor
0x08: count when this processor reserves bus for driving
0x10: count when other reserves bus and this processor will sample
0x20: count when other reserves bus and this processor will not sample
BSQ_ACTIVE_ENTRIES: (counter: 4)
number of entries in the bus sequence unit which are active (min count: 3000)
Unit masks (default 0x21)
---------0x01: (r)eq (t)ype (e)ncoding, bit 0: see next bit
0x02: rte bit 1: 00=read, 01=read invalidate, 10=write, 11=writeback
0x04: req len bit 0
0x08: req len bit 1
0x20: request type is input (0=output)
0x40: request type is bus lock
0x80: request type is cacheable
0x100: request type is 8-byte chunk split across 8-byte boundary
0x200: request type is demand (0=prefetch)
0x400: request type is ordered
0x800: (m)emory (t)ype (e)ncoding, bit 0: see next bits
0x1000: mte bit 1: see next bits
0x2000: mte bit 2: 000=UC, 001=USWC, 100=WT, 101=WP, 110=WB
SSE_INPUT_ASSIST: (counter: 2, 6)
input assists requested for SSE or SSE2 operands (min count: 3000)
Unit masks (default 0x8000)
---------0x8000: count all uops of this type
PACKED_SP_UOP: (counter: 2, 6)
packed single precision uops (min count: 3000)
- 3-51 -
Unit masks (default 0x8000)
---------0x8000: count all uops of this type
PACKED_DP_UOP: (counter: 2, 6)
packed double precision uops (min count: 3000)
Unit masks (default 0x8000)
---------0x8000: count all uops of this type
SCALAR_SP_UOP: (counter: 2, 6)
scalar single precision uops (min count: 3000)
Unit masks (default 0x8000)
---------0x8000: count all uops of this type
SCALAR_DP_UOP: (counter: 2, 6)
scalar double presision uops (min count: 3000)
Unit masks (default 0x8000)
---------0x8000: count all uops of this type
64BIT_MMX_UOP: (counter: 2, 6)
64 bit integer SIMD MMX uops (min count: 3000)
Unit masks (default 0x8000)
---------0x8000: count all uops of this type
128BIT_MMX_UOP: (counter: 2, 6)
128 bit integer SIMD SSE2 uops (min count: 3000)
Unit masks (default 0x8000)
---------0x8000: count all uops of this type
X87_FP_UOP: (counter: 2, 6)
x87 floating point uops (min count: 3000)
Unit masks (default 0x8000)
---------0x8000: count all uops of this type
X87_SIMD_MOVES_UOP: (counter: 2, 6)
x87 FPU, MMX, SSE, or SSE2 loads, stores and reg-to-reg moves (min count:
3000)
Unit masks (default 0x18)
---------0x08: count all x87 SIMD store/move uops
- 3-52 -
0x10: count all x87 SIMD load uops
3.2.4 評価手順
OProfile を利用して cache pollution が発生している場所を特定する。
準備:
# opcontrol --vmlinux= /usr/lib/debug/lib/modules/`uname –r`/vmlinux ${OPevent}
ここで${OPevent}に測定したいイベント名、サンプリング間隔、イベントマスク、カー
ネル、ユーザーでのプロファイリングをするかいなかを指定する。
イベント設定例:
-e=BSQ_CACHE_REFERENCE:3000:0x200:1:1
イベント名は先に示した 表 3-6Pentium4/Xeonの性能評価イベントを参照し、キャッシ
ュ関連のもの(BSQ_CACHE_REFERENCE)を選び、イベントマスクは 0x200(3rd level
cache miss)を設定している。
サンプリングデータのリセット:
# opcontrol –reset
開始(サンプリングの開始):
# opcontrol –start
サンプリングの開始から終了の間に、測定したい、ベンチマークなどを流す。
終了(サンプリングの終了):
# opcontrol –shutdown
データ処理(各種統計データの抽出と、元データの保存)
:
# opreport –l –p /lib/modules/$(uname -r) > ${saveDir}/summary.out 2>&1
# opreport –l –p /lib/modules/$(uname -r) > ${saveDir}/detail.out 2>&1
# opannotate -s -d /usr/src/linux-$(uname -r) ¥
-o ${saveDir}/src > ${saveDir}/opannotate.log 2>&1
# opcontrol -save=${session}
以上の手順によって、計測パターンごとに以下の 4 種類のデータが得られる。
表 3-3-7 OProfile のデータ
ファイル summary.out
カーネルの各シンボルごとのプロファイリン
グデータ
- 3-53 -
ファイル detail.out
シンボルを細分化した、命令単位のデータ
ディレクトリ ./src/ 下のファイル
プロファイリングデータを併記したソースコ
ード
ディレクトリ
OProfile サンプリング生データ保存先。これ
/var/lib/oprofile/samples/session/
をもとに別形式のデータを抽出可能。
summary.out のフォーマットは次の通り。占有率の高い順にシンボルがリストされ
る。
CPU: P4 / Xeon with 2 hyper-threads, speed 2993.03 MHz (estimated) CPU の種類とクロック
Counted GLOBAL_POWER_EVENTS events (time during which processor is not stopped) with a unit mask of 0x01
(mandatory) count 100000
samples
%
サンプル数
測定したイベントとサンプリング頻度
image name
占有率
イメージ名
app name
アプリケーション名
symbol name
シンボル名
215795
5.6329
vmlinux
vmlinux
__copy_user_zeroing_intel_nocache
104172
2.7192
jbd.ko
jbd
journal_stop
102359
2.6719
jbd.ko
jbd
journal_add_journal_head
93709
2.4461
jbd.ko
jbd
do_get_write_access
89073
2.3251
vmlinux
vmlinux
__might_sleep
74740
1.9509
jbd.ko
jbd
journal_put_journal_head
73707
1.9240
jbd.ko
jbd
journal_dirty_metadata
68674
1.7926
vmlinux
vmlinux
__find_get_block
63702
1.6628
jbd.ko
jbd
journal_cancel_revoke
63660
1.6617
vmlinux
vmlinux
__brelse
62624
1.6347
jbd.ko
jbd
journal_dirty_data
57284
1.4953
vmlinux
vmlinux
mark_offset_tsc
55985
1.4614
jbd.ko
jbd
start_this_handle
54099
1.4121
vmlinux
vmlinux
__cond_resched
47993
1.2528
vmlinux
vmlinux
__mark_inode_dirty
47878
1.2498
vmlinux
vmlinux
unlock_buffer
42326
1.1048
ext3.ko
ext3
ext3_new_block
39625
1.0343
vmlinux
vmlinux
__block_write_full_page
図 3.2-1 pattern9-0-cpu2-0-09081635/summary.out
detail.out のフォーマットは次の通り。シンボルごとに、その内訳がサンプル数や占
有率と共にリストされる。
- 3-54 -
CPU: P4 / Xeon with 2 hyper-threads, speed 2993.03 MHz (estimated)
CPU の種類とクロック
Counted GLOBAL_POWER_EVENTS events (time during which processor is not stopped) with a unit mask of
0x01 (mandatory) count 100000
vma
samples
%
c01c3be1 215795
5.6329
image name
app name
vmlinux
vmlinux
symbol name
__copy_user_zeroing_intel_nocache
仮想アドレス
全体に対する占有率
サンプル数
アプリケーション名
シンボル名
当該関数内での占有率
c01c3be1 86
0.0399
c01c3be2 74
0.0343
c01c3be4 35
0.0162
c01c3be5 40
0.0185
c01c3be7 10
0.0046
c01c3be8 30
0.0139
c01c3bea 117
0.0542
c01c3bed 3404
1.5774
c01c3bf0 157
0.0728
c01c3bf2 2231
1.0339
c01c3bf5 9581
4.4399
c01c3bf6 4308
1.9963
c01c3bf9 2554
1.1835
c01c3bfc 295
0.1367
c01c3c00 5485
2.5418
c01c3c04 4328
2.0056
c01c3c07 2171
1.0060
c01c3c0a 325
0.1506
c01c3c0e 4915
2.2776
図 3.2-2detail.out
3.2.5 評価結果
まず、クロック数を測定するために、GLOBAL_POWER_EVENTS を設定し、OProfile
で計測してみた。
下記は CPU ビジー型のベンチマークで CPU 数 16 個のマシンで計測したものである。
__copy_from_user_ll()という関数が実行時間の約 28%強を占めている。トップ 5 の関数
の実行時間が 65%を超えているのが分かる。ここで__copy_from_user_ll()という関数は、
ユーザー空間からカーネル空間へデータをコピーする関数である。write(2)では必ず実行さ
れる関数である。実装は非常に単純なデータの転送で、アルゴリズム的に工夫の余地はほ
とんどないと思われた。
- 3-55 -
表 3-8 プロファイリング全体結果/ pattern9-0-cpu16-08031605
順位
シンボル
サンプル数
占有率(%)
累積占有率(%)
1
__copy_from_user_ll
3201368
28.54
28.54
2
_spin_lock_irq
1870823
16.68
45.22
3
no symbols/jbd
1071441
9.55
54.77
4
_spin_lock
769409
6.86
61.63
5
no symbols/ext3
484137
4.32
65.95
__copy_from_user_ll() の 詳 細 は 表 3-9 プ ロ フ ァ イ リ ン グ __copy_from_user_ll 詳 細
/2.6.9-11.5AXのとおりである。c01c03d4 のアドレスのmovsl命令で当該関数中の約 92%を
占有している。
表 3-9 プロファイリング__copy_from_user_ll 詳細/2.6.9-11.5AX
アドレス
サンプル
__copy_from_us
数
er_ll に対する占
命令
有率(%)
c01c03d4
c01c03d6
repz
3036318
92.71
movsl %ds:(%esi),%es:(%edi)
96922
2.96
mov
c01c03d8
%eax,%ecx
repz
movsb %ds:(%esi),%es:(%edi
6999
0.21
)
c01c03da
110331
3.37
jmp
c01c03e5
c01c03e6
23495
0.71
mov
%ecx,%eax
repz movsl %ds:(%esi),%es:(%edi) は%ds:(%esi)から%es:(%edi)へ%ecx *4 バイト転送
する命令である。
mov 命令のコストが高いときはキャッシュミスを疑ってみる。
そこで、L3 キャッシュミスを測定してみる。
# opcontrol –e=BSQ_CACHE_REFERENCE:3000:0x200:1:1
下記のとおり、__copy_from_user_ll()でキャッシュミスが多発しているのが分かる。約
63%のキャッシュミスが、当該ルーチンで発生していて、2 位以下の寄与率は 2%以下であ
る。この関数は非常にたちの悪い L3 キャッシュミスを起こしているというのがよくわかる。
CPU: P4 / Xeon, speed 2201.02 MHz (estimated)
Counted BSQ_CACHE_REFERENCE events (cache references seen by the bus unit) with a
unit mask of 0x200 (read 3rd level cache miss) count 3000
samples
%
app name
symbol name
- 3-56 -
37260
63.1772
vmlinux
__copy_from_user_ll
1039
1.7617
vmlinux
_spin_lock_irqsave
935
1.5854
vmlinux
_spin_lock
925
1.5684
vmlinux
blk_rq_map_sg
910
1.5430
vmlinux
journal_add_journal_head
図 3.2-3pattern9-0-cpu4-0-08141508/summary.out
L2/L3 キ ャ ッ シ ュ ヒ ッ ト は 以 下 の と お り で あ る 。 メ モ リ ア ク セ ス に 比 べ て
__copy_from_user_ll()のキャッシュミスの多さが際立っている。
CPU: P4 / Xeon, speed 2201.02 MHz (estimated)
Counted BSQ_CACHE_REFERENCE events (cache references seen by the bus unit) with a
unit mask of 0x3f (multiple flags) count 3000
samples
%
app name
symbol name
118812
7.3122
vmlinux
__copy_from_user_ll
82947
5.1049
vmlinux
_spin_lock
65983
4.0609
vmlinux
journal_add_journal_head
61903
3.8098
vmlinux
__find_get_block
59457
3.6593
vmlinux
journal_dirty_metadata
図 3.2-4pattern9-0-cpu4-0-08141510/summary.out
CPU
レジスタ
L1 キャッシュ
SB
メインメモリ
L2キャッシュ
図 3.2-5CPU、キャッシュ、メモリ構成
- 3-57 -
メインメモリに CPU からアクセスするとき L1(一次)/L2(二次)キャッシュにデータがな
い場合、メインメモリにメモリバス経由でアクセスしにいく。そのコストは L1 キャッシュ
アクセスに比べ 100 倍以上コスト(時間)がかかる。CPU に他にするべき仕事がないと 200
~300 クロック遊んでしまうことになる。そのため、キャッシュミスを減らすことが性能向
上のために非常に重要になってくる。
表 3-10 キャッシュのアクセスコスト
デバイス
アクセスコスト
L1(一次)キャッシュ
2 クロック
L2(二次)キャッシュ
10 クロック
L3(三次)キャッシュ
50 クロック程度
メインメモリ
200~300 クロック前後
CPU がメインメモリからデータを読むとき、適当なキャッシュにデータを置く。これを
cache line fill とよぶ。次回データを読むとき、同じデータがキャッシュにあれば、CPU は
メインメモリからではなくキャッシュからデータを読むことができる。これをキャッシュ
ヒットと呼ぶ。
CPUがキャッシュ可能なメモリへ書き込む場合、最初キャッシュにそのメモリのキャッ
シュラインが存在するかチェックする。有効なキャッシュラインが存在した場合、CPUは
(書き込みポリシーに依存するのだが)、メインメモリではなくキャッシュに書き込む。こ
れをライトヒット(write hit)と呼ぶ。もしキャッシュをライトミスしたら(有効なキャッシ
ュライン存在しない)、CPUはcache line fill, write allocationを行う。データをキャッシュ
ラインに書き、そしてメインメモリへ書く。もしデータがメモリへ書かれるなら、それは
最初にストアバッファ(Store Buffer)へ書き込まれ、システムバスが利用できるようになっ
たら、ストアバッファ 1からメモリへ書き込まれる。
キャッシュラインフィルするとき CPU はそのラインを新しいデータに置き換えるが、置
き換えられたデータがすぐに必要になる場合もある。必要なデータを追い出して置き換え
てしまったとき cache conflict あるいは cache pollution が発生したという。
例えば書き出したデータをすぐにアクセスしないとしたら、そのデータをキャッシュに
のせる必要はない。データをキャッシュにのせなければ必要なデータを追い出すこともな
いので cache pollution が発生しない。
IA-32 には Non-temporal move 命令というのがある。これは、CPU レジスタからキャッ
シュ(L1/L2/L3)を経由せず直接メインメモリにデータを移動する。これらの命令はレジ
スタからメモリへ書き込むときキャッシュを経由しないので cache pollution を防止するの
に利用することができる。
一方で、どっちもすぐにアクセスするデータなのではあるがたまたま同じキャッシュラ
インに載るために cache conflict が発生している場合もある。
これを特に thrashing とよぶ。
キャッシュミスが多発しているとき、その原因がキャッシュコンフリクト(スラッシン
1
Pentium 4 および Intel Xeon プロセッサは 24 エントリのストアバッファを持つ。
- 3-58 -
グ)によるものか、cache pollution によるものか見極めるのは OProfile のデータだけでは
不十分で、ソースコードを確認し分析する必要がある。
キャッシュミスが発生した時点の各種レジスタの値がわかれば、どのメモリへアクセス
しているのがわかるので、そのめもりがどのキャッシュラインのセットへ割り当てられる
かは分かる。しかし現状の OProfile ではそのような情報を提供していない。
例えば Pentium 4 ないし Intel Xeon プロセッサの L2 キャッシュは 512KB、キャッシュ
ラインサイズは 64 バイト、8 way set associative なので 512KB/64=8192 個キャッシュラ
インがある。そのキャッシュラインを 8 個で共有するので、8129/8=1024 なので、アドレ
スを 1024 で割ったあまりのうち下の 64 バイト分を無視した部分が等しければ同じキャッ
シュラインのセットに割り当てられる。
例えば要素が 1024 バイトの配列があったとする。この配列をアクセスすると先頭アドレ
スが 1024 バイトで飛び飛びになっているので、常に同じキャッシュラインにのるので要素
を 8 個以上アクセスすると確実に cache conflict をすることになる。
同じキャッシュラインのセットということがわかれば cache conflict の可能性が高いとい
うことが推定できる。
今回はソースコードを分析して cache pollution の可能性を疑い、それを解決するパッチ
を作成し、評価してみた。
diff -ur linux-2.6.13/Makefile linux-2.6.13.nt/Makefile
--- linux-2.6.13/Makefile
2005-08-29 08:41:01.000000000 +0900
+++ linux-2.6.13.nt/Makefile
2005-09-03 14:11:27.000000000 +0900
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 13
-EXTRAVERSION =
+EXTRAVERSION = .nt
NAME=Woozy Numbat
# *DOCUMENTATION*
diff
-ur
linux-2.6.13/arch/i386/lib/usercopy.c
linux-2.6.13.nt/arch/i386/lib/usercopy.c
--- linux-2.6.13/arch/i386/lib/usercopy.c
2005-08-29
08:41:01.000000000
2005-09-03
14:09:18.000000000
+0900
+++ linux-2.6.13.nt/arch/i386/lib/usercopy.c
+0900
@@ -425,6 +425,107 @@
: "eax", "edx", "memory");
- 3-59 -
return size;
}
+
+/* Non Temporal Hint version of __copy_user_zeroing_intel */
+/* It is cache aware.
*/
+/* [email protected]
*/
+static unsigned long
+__copy_user_zeroing_intel_nocache(void *to, const void __user *from, unsigned long
size)
+{
+
int d0, d1;
+
+
__asm__ __volatile__(
+
"
.align 2,0x90\n"
+
"0:
movl 32(%4), %%eax\n"
+
"
cmpl $67, %0\n"
+
"
jbe 2f\n"
+
"1:
movl 64(%4), %%eax\n"
+
"
.align 2,0x90\n"
+
"2:
movl 0(%4), %%eax\n"
+
"21:
movl 4(%4), %%edx\n"
+
"
movnti %%eax, 0(%3)\n"
+
"
movnti %%edx, 4(%3)\n"
+
"3:
movl 8(%4), %%eax\n"
+
"31:
movl 12(%4),%%edx\n"
+
"
movnti %%eax, 8(%3)\n"
+
"
movnti %%edx, 12(%3)\n"
+
"4:
movl 16(%4), %%eax\n"
+
"41:
movl 20(%4), %%edx\n"
+
"
movnti %%eax, 16(%3)\n"
+
"
movnti %%edx, 20(%3)\n"
+
"10:
movl 24(%4), %%eax\n"
+
"51:
movl 28(%4), %%edx\n"
+
"
movnti %%eax, 24(%3)\n"
+
"
movnti %%edx, 28(%3)\n"
+
"11:
movl 32(%4), %%eax\n"
+
"61:
movl 36(%4), %%edx\n"
+
"
movnti %%eax, 32(%3)\n"
+
"
movnti %%edx, 36(%3)\n"
+
"12:
movl 40(%4), %%eax\n"
- 3-60 -
+
"71:
movl 44(%4), %%edx\n"
+
"
movnti %%eax, 40(%3)\n"
+
"
movnti %%edx, 44(%3)\n"
+
"13:
movl 48(%4), %%eax\n"
+
"81:
movl 52(%4), %%edx\n"
+
"
movnti %%eax, 48(%3)\n"
+
"
movnti %%edx, 52(%3)\n"
+
"14:
movl 56(%4), %%eax\n"
+
"91:
movl 60(%4), %%edx\n"
+
"
movnti %%eax, 56(%3)\n"
+
"
movnti %%edx, 60(%3)\n"
+
"
addl $-64, %0\n"
+
"
addl $64, %4\n"
+
"
addl $64, %3\n"
+
"
cmpl $63, %0\n"
+
"
ja
+
"
sfence \n"
+
"5:
movl %0, %%eax\n"
+
"
shrl $2, %0\n"
+
"
andl $3, %%eax\n"
+
"
cld\n"
+
"6:
rep; movsl\n"
+
"
movl %%eax,%0\n"
+
"7:
rep; movsb\n"
+
"8:\n"
+
".section .fixup,\"ax\"\n"
+
"9:
lea 0(%%eax,%0,4),%0\n"
+
"16:
pushl %0\n"
+
"
pushl %%eax\n"
+
"
xorl %%eax,%%eax\n"
+
"
rep; stosb\n"
+
"
popl %%eax\n"
+
"
popl %0\n"
+
"
jmp 8b\n"
+
".previous\n"
+
".section __ex_table,\"a\"\n"
+
"
.align 4\n"
+
"
.long 0b,16b\n"
+
"
.long 1b,16b\n"
+
"
.long 2b,16b\n"
0b\n"
- 3-61 -
+
"
.long 21b,16b\n"
+
"
.long 3b,16b\n"
+
"
.long 31b,16b\n"
+
"
.long 4b,16b\n"
+
"
.long 41b,16b\n"
+
"
.long 10b,16b\n"
+
"
.long 51b,16b\n"
+
"
.long 11b,16b\n"
+
"
.long 61b,16b\n"
+
"
.long 12b,16b\n"
+
"
.long 71b,16b\n"
+
"
.long 13b,16b\n"
+
"
.long 81b,16b\n"
+
"
.long 14b,16b\n"
+
"
.long 91b,16b\n"
+
"
.long 6b,9b\n"
+
"
.long 7b,16b\n"
+
".previous"
+
: "=&c"(size), "=&D" (d0), "=&S" (d1)
+
: "1"(to), "2"(from), "0"(size)
+
: "eax", "edx", "memory");
+
return size;
+}
+
#else
/*
* Leave these declared but undefined. They should not be any references to
@@ -434,6 +535,8 @@
__copy_user_zeroing_intel(void *to, const void __user *from, unsigned long size);
unsigned long
__copy_user_intel(void __user *to, const void *from, unsigned long size);
+unsigned long
+__copy_user_zeroing_intel_nocache(void *to, const void __user *from, unsigned long
size);
#endif /* CONFIG_X86_INTEL_USERCOPY */
/* Generic arbitrary sized copy. */
@@ -515,7 +618,6 @@
: "memory");
\
} while (0)
- 3-62 -
unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long
n)
{
BUG_ON((long) n < 0);
@@ -588,6 +690,21 @@
}
EXPORT_SYMBOL(__copy_from_user_ll);
+unsigned long
+__copy_from_user_ll_nocache(void *to, const void __user *from, unsigned long n)
+{
+
BUG_ON((long)n < 0);
+#ifdef CONFIG_X86_INTEL_USERCOPY
+
if ( n > 64 && cpu_has_xmm2)
+
n = __copy_user_zeroing_intel_nocache(to, from, n);
+
else
+
__copy_user_zeroing(to, from, n);
+#else
+
__copy_user_zeroing(to, from, n);
+#endif
+
return n;
+}
+
/**
* copy_to_user: - Copy a block of data into user space.
* @to:
Destination address, in user space.
diff
-ur
linux-2.6.13/include/asm-i386/uaccess.h
linux-2.6.13.nt/include/asm-i386/uaccess.h
--- linux-2.6.13/include/asm-i386/uaccess.h
2005-08-29
08:41:01.000000000
2005-09-03
14:09:18.000000000
+0900
+++ linux-2.6.13.nt/include/asm-i386/uaccess.h
+0900
@@ -413,6 +413,8 @@
const void *from, unsigned long n);
unsigned long __must_check __copy_from_user_ll(void *to,
const void __user *from, unsigned long n);
+unsigned long __must_check __copy_from_user_ll_nocache(void *to,
- 3-63 -
+
const void __user *from, unsigned long n);
/*
* Here we special-case 1, 2 and 4-byte copy_*_user invocations. On a fault
@@ -502,11 +504,40 @@
}
static inline unsigned long
+__copy_from_user_inatomic_nocache(void *to, const void __user *from, unsigned long
n)
+{
+
if (__builtin_constant_p(n)) {
+
unsigned long ret;
+
+
switch (n) {
+
case 1:
+
__get_user_size(*(u8 *)to, from, 1, ret, 1);
+
return ret;
+
case 2:
+
__get_user_size(*(u16 *)to, from, 2, ret, 2);
+
return ret;
+
case 4:
+
__get_user_size(*(u32 *)to, from, 4, ret, 4);
+
return ret;
+
}
+
}
+
return __copy_from_user_ll_nocache(to, from, n);
+}
+
+static inline unsigned long
__copy_from_user(void *to, const void __user *from, unsigned long n)
{
might_sleep();
return __copy_from_user_inatomic(to, from, n);
}
+
+static inline unsigned long
+__copy_from_user_nocache(void *to, const void __user *from, unsigned long n)
+{
+
might_sleep();
- 3-64 -
+
return __copy_from_user_inatomic_nocache(to, from, n);
+}
+
unsigned long __must_check copy_to_user(void __user *to,
const void *from, unsigned long n);
unsigned long __must_check copy_from_user(void *to,
diff -ur linux-2.6.13/mm/filemap.c linux-2.6.13.nt/mm/filemap.c
--- linux-2.6.13/mm/filemap.c
2005-08-29 08:41:01.000000000 +0900
+++ linux-2.6.13.nt/mm/filemap.c
2005-09-03 14:09:18.000000000 +0900
@@ -1726,7 +1726,7 @@
int copy = min(bytes, iov->iov_len - base);
base = 0;
-
left = __copy_from_user_inatomic(vaddr, buf, copy);
+
left = __copy_from_user_inatomic_nocache(vaddr, buf, copy);
copied += copy;
bytes -= copy;
vaddr += copy;
diff -ur linux-2.6.13/mm/filemap.h linux-2.6.13.nt/mm/filemap.h
--- linux-2.6.13/mm/filemap.h
2005-08-29 08:41:01.000000000 +0900
+++ linux-2.6.13.nt/mm/filemap.h
2005-09-03 16:47:39.000000000 +0900
@@ -34,13 +34,13 @@
int left;
kaddr = kmap_atomic(page, KM_USER0);
-
left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
+
left = __copy_from_user_inatomic_nocache(kaddr + offset, buf, bytes);
kunmap_atomic(kaddr, KM_USER0);
if (left != 0) {
/* Do it the slow way */
kaddr = kmap(page);
-
left = __copy_from_user(kaddr + offset, buf, bytes);
+
left = __copy_from_user_nocache(kaddr + offset, buf, bytes);
kunmap(page);
}
return bytes - left;
- 3-65 -
3.2.6 readprofile
readprofile [ options ]
readprofile コマンドは、/proc/profile の情報を標準出力に出力する。出力される情報は、
3 種類の情報から構成されている。最初の項目は、クロックチック(clock tick)である。 2 番
目は、たくさんの時間を消費しているカーネル内部の C の関数名である。 3 番目の項目
は、手続きの「負荷」を正規化したもので、関数の長さとクロック数の比率として計算さ
れる。これらの項は、読み取りやすいように空白を入れ、桁を揃えて出力される。
表 3-11readprofile のオプション
オプション
説明
-m mapfile
マ ッ プ フ ァ イ ル を 指 定 す る 。 デ フ ォ ル ト で は 、
/usr/src/linux/System.map
が使用される。現在のカーネルが最後にコ
ンパイルしたものでない場合、または System.map を他の場所に保存し
ている場合は 、コ マンドライン上でマップファイルを指定する必要が
ある。マップファイル名の最後が ‘.gz’ となっている場合は、実行時
に自動的に伸長される
-p profile
別 の プ ロ フ ァ イ リングバッファを指定する。デフォルトでは、
/proc/profile が使用される。別のプロファイリングバッファを使 用す
ると、カーネルプロファイリングを「凍結」した後でプロファイリング
情報を読む場合などに有用である。 /proc/profile は、‘cat’ や、‘cp’
コマンドを使ってコピーすることができる。プログラムがプロファイリ
ングバッファのサイズを前もって取得する必要があるため 、
readprofile-1.1
で行なわれていた、圧縮されたプロファイリングバッ
ファはサポートされなくなった
-i
カーネルプロファイリング情報の表示。このオプションを指定すると、
readprofile は、カーネルによって使用されているプロファイリングステ
ップのみを表示する。プロファイリングステップはプロファイリングバ
ッファの精度であり、(make config を使った)カーネルの設定、またはカ
ーネルのコマンドラインで指定される。-t(terse:簡 潔モード)スイッチが
-i と一緒に指定されると、単に 10 進数の数字のみが表示される
-a
マップファイル中のすべてのシンボルを表示する。デフォルトでは、使
用クロック数が 0 の手続きは出力されない
-b
各メモリ領域に対する出現数のカウントを表示する
-r
プロファイリングバッファの内容を初期化する。 /proc/profile は、スー
- 3-66 -
パーユーザーだけが書き込み可能で、一般ユーザーは読み込みしかでき
ないため、このオプションを使用するには、スーパーユーザーの権限が
必要となる。しかし、 readprofile を setuid 0 とすることで 、特権を
持たないユーザーでもプロファイリングバッファの内容を初期化するこ
とができる
-M
multiplier
カーネルがプロファイリング割り込みを各 CPU に送る周期を変更でき
るアーキテクチャもある。このオプションにより、周期をシステムクロ
ック周波数 HZ の倍数で設定できる。 i386-SMP (2.2 と 2.4 カーネル)
と sparc64-SMP (2.4 カーネル) でサポートされている。このオプショ
ンはプロファイリングバッファの初期化も行うので、スー パーユーザー
特権が必要である
詳細モード。出力は 4 つの項目から構成され、それぞれ空白により桁が
-v
揃えられる。最初の項目はカーネルの関数の RAM アドレス、2 番目の
項目は関数の名前、 3 番目の項目は使用したクロック数、最後の項目に
は正規化された負荷が表示される
バージョン情報の表示。 readprofile は、現在のバージョン番号を表示
-V
した後、終了する
例:
# readprofile |sort -nr +2 |head -10
7479250 default_idle
159132.9787
548 kunmap_atomic
49.8182
567 this_rq_lock
14.5385
7487519 total
3.9394
500 probe_irq_mask
3.8760
156 cpu_idle
2.6441
111 kpmd_ctor
1.9821
5 zlib_inflate_codes_free
1.2500
225 __add_to_swap_cache
1.2295
831 do_page_fault
1.0519
図 3.2-6 最もクロックを消費した関数上位 10 個の表示
readprofile を実行するためには、カーネル起動時にカーネルパラメタ profile=1 など与え
ておかなければならない。
title Asianux (2.6.9-11.11AXsmp)
root (hd0,0)
kernel /vmlinuz-2.6.9-11.11AXsmp ro root=LABEL=/ profile=1
initrd /initrd-2.6.9-11.11AXsmp.img
- 3-67 -
図 3.2-7grub.conf の設定
3.2.7 考察
カーネルプロファイラとして、OProfile と readprofile を比較検討する。
OProfile は CPU が提供する各種ハードウェアイベントをプロファイリングするが、
readprofile はタイマによるサンプリング機能だけである。
また取得可能なイメージも OProfile はカーネル、ユーザプログラムどちらもプロファイ
リングできるが、readprofile はカーネルプロファイリングだけである。
レポート機能も、OProfile はソースコードとの対比をとったり、様々な形式に対応して
いるが、readprofile はアドレスとシンボル名を対比させるだけである。
OProfile はそれ以外にもコールグラフの測定、
プロファイリングデータのアーカイブ化、
gprof 形式でのデータ出力など豊富な機能を持つ。
OProfile の起動、停止は opcontrol で行う。readprofile を利用するときは起動時にカー
ネルパラメータで設定しないとならない。一度起動した readprofile を停止する方法は再起
動以外ない。
OProfile はユーザランドのツールをインストールする必要がある。2.6 カーネルへは組み
込まれているので特に新たなカーネルを作成する必要はない。readprofile は既に組み込ま
れているのでインストールの作業等は必要ない。
かつては、カーネルのプロファイリングは readporfile がカーネルに標準に装備されてい
たのでよく利用されていたが、機能の充実度、使いやすさ、カーネルに既に組み込まれた
点などを考えると OProfile を利用を推奨する。
- 3-68 -
3.3 システムコールトレーサの評価
3.3.1 システムコールトレーサの概要
システムコールトレーサは、カーネル空間とユーザ空間のインタフェースである、シス
テムコールをトレースするツールである。システムコールを追跡することで、想定通りの
正しい順序でシステムコールが発行されているか、期待していない結果やエラーを返して
いるシステムコールがないか、などを確認することができる。
Linux で利用できるシステムコールトレーサとしては主に strace と ltrace が使われてい
る。strace はシステムコールを追跡するツールであり、追跡するプロセスの子プロセスが
発行するシステムコールも追跡可能である。ltrace は strace とほぼ同様の機能に加え、ダ
イナミックライブラリ内のライブラリ関数コールも追述できるようにしたツールである。
以下では両ツールを代表し、strace に関して、その機能および信頼性の評価を行った。
3.3.2 strace 評価環境
strace評価に用いた評価環境を 表 3.3-1 に示す。以降の評価は、全てこの環境で行った
ものである。
表 3.3-1
項
strace 機能評価の評価環境
項目
評価環境
番
1
ハード
CPU
Pentium III 800MHz×1
2
ウェア
メモリ
512MByte
ハードディスク
18GByte(SCSI)
3
4
ソフト
ディストリビューション
Fedora Core 3
5
ウェア
カーネル
2.6.9
6
ファイルシステム
ext3(ブロックサイズ:4KByte)
7
strace
4.5.8
3.3.3 strace 機能評価
ここでは、strace の全オプションについて、man ページ通り動くかどうかを評価した。
また、man ページ化されていないオプションが存在するかどうかも、合わせて評価した。
3.3.3.1 評価手順
strace 機能評価の際の評価手順を、以下に示す。
- 3-69 -
(1) ls コマンド等を strace 経由で実行。その際に、strace のオプションを変化させて確認す
る。
(2) オプション分(1)の手順を繰り返す。
(3) strace のソースを参照し、man ページ化されていないオプションの有無を確認する。
3.3.3.2 結果
strace機能評価の結果を 表 3.3-2 に示す。
表 3.3-2
#
1
2
3
オプション
-c
-d
-f
4
strace 機能評価結果
man ページ概要
評価結果
各システムコールの所要時間、呼出し回数、エ
man ページ通り
ラー発生回数を統計表示する
strace 自身のデバッグ情報を標準エラー出力
man ページ通り
に表示する
トレース対象プログラムから(v)fork で生成さ
man ページ通り
れたプロセスも strace のトレース対象とする
-o filename オプションが指定され、かつトレ
man ページ通り
ース対象プログラムから子プロセスを生成す
る場合、以下のようにトレース結果を別ファイ
-ff
ルに保存する。
トレース対象プログラムのトレース出力先:
filename
生成された子プロセスのトレース出力先:
filename.pid
5
-F
トレース対象プログラムから vfork で生成され
-f オ プ シ ョ ン の み で
たプロセスも strace のトレース対象とする
vfork トレースが可能
6
-h
strace のコマンドヘルプを表示する
man ページ通り
7
-i
システムコール時の命令ポインタを表示する
man ページ通り
アタッチやデタッチに関するメッセージを抑
man ページ通り
8
9
10
11
-q
-r
-t
-tt
12
止する
各システムコール間の相対時間を表示する
man ページ通り
各システムコールのトレース開始時刻
man ページ通り
hh:mm:ss をトレース結果の前に表示する
-t オプションで記録する時刻のフォーマット
にμ秒の単位を追加する(hh:mm:ss.μ)
-tt オプションのようにμ秒の単位まで表示す
-ttt
man ページ通り
るが、時分秒の部分は 1970 年 1 月 1 日 00:00:00
UTC からの秒数として表示する(秒数.μ)
- 3-70 -
man ページ通り
#
13
14
15
16
17
オプション
-T
-v
-V
-x
-xx
18
man ページ概要
評価結果
各システムコールの開始から終了までの時間
man ページ通り
を記録する
構造体の情報を表示する際に、省略しないよう
にする
strace のバージョン番号を表示する
man ページ通り
非 ASCII 文字列を表示する際に、16 進表記で表
man ページ通り
示する
全ての文字列を表示する際に、16 進表記で表示
man ページ通り
する
各システムコールの戻り値を表示する位置(行
-a column
man ページ通り
man ページ通り
の何文字目にするか)を変更する。
デフォルト値は 40
19
どのイベントをどのようにトレースするかを
qualifier に指定可能な値
変更する。expr の書式は以下の通り([]で囲ま
として以下が存在する。
れた部分は省略可能)。
t
:trace と同義
[qualifier=][!]value1[,value2]
a
:abbrev と同義
v
:verbose と同義
x
:raw と同義
qualifier の値は、項番 20~31 に後述する
-e expr
trace、abbrev、verbose、raw、signal、read、 signals:signal と同義
write が指定可能で、デフォルトは trace とな
s
:signal と同義
っている。
reads
:read と同義
例えば、-eopen を指定(-e trace=open と同義) r
:read と同義
した場合、open コールのみトレースする。また、 writes :write と同義
-e trace=!open を指定した場合、open 以外の
w
:write と同義
全システムコールをトレースする。
20
set で指定したシステムコールのみトレースす
-e trace=set
man ページ通り
る。all 及び none も指定可能であり、デフォル
トは all
21
22
-e trace=file
-e
trace=process
23
-e
trace=network
24
-e
ファイル関連のシステムコールのみトレース
man ページ通り
する
プロセス管理関連のシステムコールのみトレ
man ページ通り
ースする
ネットワーク関連のシステムコールのみトレ
man ページ通り
ースする
シグナル関連のシステムコールのみトレース
man ページ通り
trace=signal
する
25
-e trace=ipc
IPC 関連のシステムコールのみトレースする
man ページ通り
26
-e abbrev=set
set で指定したシステムコールに関して、大き
man ページ通り
- 3-71 -
#
オプション
man ページ概要
評価結果
な構造体の各メンバを省略して表示する。
all 及び none を指定可能であり、デフォルトは
all。abbrev=none は、-v オプションと同義
27
set で指定したシステムコールに関して、構造
-e verbose=set
man ページ通り
体の内容(メンバ名と値)を表示する。
all 及び none を指定可能であり、デフォルトは
all
28
set で指定したシステムコールの引数と戻り値
-e raw=set
man ページ通り
の値を、生データとして 16 進表記で表示する。
all 及び none を指定可能
29
set で指定したシグナルのみトレースする。
-e signal=set
30
-e read=set
all、none 以外のシグナル
all 及び none を指定可能で、
デフォルトは all。 名を指定すると、エラーが
例えば signal=!SIGIO(または signal=!io)を
発生する
指定した場合、SIGIO はトレースしない
(Ver 4.5.9 で修正済み)
read コールのファイルディスクリプタ値が、
man ページ通り
set で指定した値と一致した場合、読み出しデ
ータを 16 進表記でダンプ表示する
31
write コールのファイルディスクリプタ値が、
-e write=set
man ページ通り
set で指定した値と一致した場合、書き込みデ
ータを 16 進表記でダンプ表示する
32
-o filename
33
filename で指定したファイルに対し、strace
の結果を出力する
システムコールの所要時間を計算する際に考
-O overhead
man ページ通り
man ページ通り
慮される、strace のオーバヘッド(μ秒の単位)
を変更する
34
動作中のプロセスにアタッチし、トレースを行
-p pid
man ページ通り
う。デタッチするには Ctl-c を入力する。デタ
ッチによりトレースを終了する(トレース対象
は続行)。
35
-s strsize
36
ファイル名以外の文字列の表示を、指定文字数
man ページ通り
で切り詰める。デフォルトは 32
-c オプションで各システムコールの統計情報
man ページ通り
を表示する際、sortby で指定した項目でソート
-S sortby
する。
sortby に指定可能な値は、time、calls、name、
nothing で、デフォルトは time
37
-u username
トレース対象プログラムを、username のユーザ
権限で実行する
- 3-72 -
man ページ通り
#
38
オプション
-E var=val
39
-E var
man ページ概要
評価結果
トレース対象プログラムを実行する際に、環境
man ページ通り
変数の追加および変更(var=val)を行う
トレース対象プログラムを実行する際に、var
man ページ通り
で指定された環境変数を削除する
3.3.3.3 考察
当初の予想では、全オプション問題なく動作し、いくつか man ページにないオプション
を確認できるのでは、と考えていた。
評価の結果、確認できた項目は下記の通り。
(1) -f オプションだけで、vfork で生成された子プロセスのトレースが可能
(2) -e signal= オプションだけは正しく動作しない
(3) -e expr オプションに関しては、省略形式の別名の指定が可能
(1) に関して、man ページでは vfork で生成された子プロセスのトレースを行うには、-F
オプションが必要となっているが、実際には-f オプションだけでトレース可能であった。
(2) の-e signal= オプションに関しては、その後の調査によってバージョン 4.5.9 からは正
しく動作することを確認した。このオプションに関しては、使用頻度が低いために問題が
顕在化しなかったのだと考えられる。逆に考えると、使用頻度の高いオプションを使用す
るだけで大半の問題は解決できてきたと考えられ、strace の有用性を物語っていると思わ
れる。
3.3.4 strace 信頼性評価(前提条件)
strace の信頼性評価として、CPU 負荷、I/O 負荷、メモリ負荷のそれぞれについて、ど
の程度の負荷までならば問題なく動作するかを評価した。
strace 信頼性評価の前提条件を、以下に示す。
(1) システムのサービスによって測定誤差が生じるのを防ぐため、使用していないランレベ
ル(本評価環境の場合は4)を使い、不要なサービスを全て停止するように設定してお
く。今回の評価時に動作するように設定しているサービスは、autofs、syslog、haldaemon、
sysstat、kudzu、lm_sensors、cpuspeed のみ。
(2) 負荷設定直後に計測開始するのではなく、負荷が安定することを確認してから、計測を
開始する。
(3) 自作のマイクロベンチマーク(図 3.3-1)を使用し、1システムコールの所要時間を計
測する。これをstraceありとなしでそれぞれ計測し、その差分をもってstraceのオーバ
- 3-73 -
ーヘッドとする。
(4) 一般的な利用方法をモデリングするため、strace は ext3 ファイルシステム上にログフ
ァイル出力を行うものとする。
(5) システムコールについては、時前計測で異なる傾向が見られた、gettimeofday、getuid、
uname の3つについて、それぞれ計測する。
(6) 評価結果は、評価環境に依存している。環境が変わると、目安となる負荷も変わるので、
注意が必要。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main (int argc, char *argv[])
{
struct timeval tv, otv;
int sec=10;
unsigned long count;
if(argc == 2) sec = atoi(argv[1]);
gettimeofday(&otv,NULL);
count = 0;
getuid, uname 用に使用する
場合は、コメントを外してコ
ンパイルする
do {
//getuid();
//uname(NULL);
gettimeofday(&tv,NULL);
count ++;
} while ( count < 1000 );
tv.tv_sec -= otv.tv_sec;
tv.tv_usec -= otv.tv_usec;
printf("%d nsec per call\n", (tv.tv_sec*1000*1000 + tv.tv_usec)/(count/1000));
return 0;
}
図 3.3-1
gettimeofday 用マイクロベンチマークプログラム
- 3-74 -
不要なサービスを停止するための手順は、下記の通り。
a. ランレベルの変更
# vi /etc/inittab
:(略)
# Default runlevel. The runlevels used by RHS are:
#
0 - halt (Do NOT set initdefault to this)
#
1 - Single user mode
#
2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#
3 - Full multiuser mode
#
4 - unused
#
5 - X11
#
6 - reboot (Do NOT set initdefault to this)
#
この部分を 4(未使用レベル)
に変更する
id:3:initdefault:
:(略)
b. レベル4で on になっているサービスの確認
レベル4で on になっている
サーピスをチェックする
# chkconfig --list
rpcsvcgssd
0:off
1:off
2:off
3:on
4:on
5:on
6:off
crond
0:off
1:off
2:on
3:on
4:on
5:on
6:off
microcode_ctl
0:off
1:off
2:off
3:off
4:off
5:off
6:off
:(略)
c. 不要なサービス群を off に設定
チェックしたサービス群を
OFF にする
(図は rpcsvcgssd
の例)
# chkconfig --level 4 rpcsvcgssd off
d. リブート
# shutdown -r now
e. サービスが正しく設定されていることを確認
off に設定したサービスが、正
レベル4で on になっている
しく off になっていることを
サーピスをチェックする
確認する
# chkconfig --list
rpcsvcgssd
0:off
1:off
2:off
3:on
4:off
5:on
6:off
crond
0:off
1:off
2:on
3:on
4:off
5:on
6:off
microcode_ctl
0:off
1:off
2:off
3:off
4:off
5:off
6:off
:(略)
- 3-75 -
gettimeofday のマイクロベンチマークを strace ありとなしで計測する場合の実行例は、
下記の通り。
a. strace なしで実行
$ gtobench2_gettimeofday
2961 nsec per call
b. strace ありで実行
$ strace -o strace.log gtobench2_gettimeofday
33885 nsec per call
各システムコールの所要時間 T(syscall)の算出式は gettimeofday コールかどうかで異な
り、マイクロベンチマークで計測した時間を B(syscall)とした場合、下記の通り。
(1) T(gettimeofday)=B(gettimeofday)
(2) T(other)=B(other)-B(gettimeofday)
3.3.5 strace 信頼性評価(CPU 負荷時)
3.3.5.1 評価手順
strace 信頼性評価(CPU 負荷)の評価手順を、以下に示す。
(1) マイクロベンチマークプログラムを使い、3つのシステムコールについて、strace のオ
ーバーヘッドを 10 点分計測する。
(2) 負荷生成プログラム stress を用いて、CPU 負荷(プロセス数:200)を設定する。
$ stress -c 200
stress 実行後、各 stress プロセスのスケジューリング状態が均等になることを top コ
マンドのプライオリティ表示(PR)覧で確認する。
(3) (1)をもう一度行う。この手順によって、CPU 負荷設定時の strace オーバーヘッドを算
出する。
(4) stress の CPU 負荷をプロセス数:400、600、800、1000 と変えて(2)、(3)の手順を繰
り返す。
3.3.5.2 結果と考察
測定結果を 表 3.3-3、表 3.3-4、表 3.3-5 に示す。これらの表より、どのシステムコール
の場合でもstraceを介さずに実行した場合はCPU負荷の影響をほとんど受けていないこと
が分かる。これは、システムコール 1000 回分の実行が、全て1度のスケジューリング内で
実行されており、その間に他のプロセスがスケジューリングされないためと考えられる。
- 3-76 -
表 3.3-3
gettimeofday コールと strace のオーバーヘッド(CPU 負荷時)
項
CPU 負
システムコールのオーバ
strace のオーバーヘッド(usec/コー
番
荷(プロ
ーヘッド(usec/コール)
ル)
セス数)
最小値
最大値
平均値
最小値
最大値
平均値
1
0
0.47
0.50
0.49
99.56
101.57
100.15
2
200
0.47
0.50
0.48
99.82
14,991.35
2,411.68
3
400
0.47
0.50
0.48
99.54
24,713.76
3,067.10
4
600
0.47
0.50
0.49
99.53
56,882.43
8,218.78
5
800
0.47
0.51
0.49
99.70
68,333.59
13,391.28
6
1000
0.47
0.50
0.49
99.01
71,430.01
19,293.51
表 3.3-4
getuid コールと strace のオーバーヘッド(CPU 負荷時)
項
CPU 負
システムコールのオーバ
strace のオーバーヘッド(usec/コー
番
荷(プロ
ーヘッド(usec/コール)
ル)
セス数)
最小値
最大値
平均値
最小値
最大値
平均値
1
0
0.23
0.26
0.24
91.50
197.64
193.42
2
200
0.23
0.26
0.25
92.42
2,396.11
1,039.84
3
400
0.23
0.26
0.24
92.72
8,520.23
3,048.17
4
600
0.22
0.25
0.24
93.40
44,998.41
15,576.54
5
800
0.24
0.25
0.25
91.90
80,143.35
33,371.15
6
1000
0.22
0.33
0.25
91.69
114,876.04
44,434.96
表 3.3-5
uname コールと strace のオーバーヘッド(CPU 負荷時)
項
CPU 負
システムコールのオーバ
strace のオーバーヘッド(usec/コー
番
荷(プロ
ーヘッド(usec/コール)
ル)
セス数)
最小値
最大値
平均値
最小値
最大値
平均値
1
0
0.69
0.72
0.70
209.21
211.10
210.64
2
200
0.70
0.73
0.71
9,967.25
40,073.87
29,207.73
3
400
0.70
0.73
0.71
27,768.82
78,000.90
59,612.87
4
600
0.69
0.72
0.70
1,885.32
114,959.96
76,587.22
5
800
0.69
0.72
0.70
57,450.17
152,566.38
123,812.39
6
1000
0.69
0.70
0.69
205.38
228,837.63
155,514.37
システムコール毎に、CPU負荷とstraceオーバーヘッドの関係をグラフにしたものを 図
3.3-2、図 3.3-3、図 3.3-4 に示す。
- 3-77 -
オーバーヘッド(msec)
250
200
min
max
avg
150
100
50
0
0
200
オーバーヘッド(msec)
図 3.3-2
800
1000
gettimeofday の strace オーバーヘッド(CPU 負荷時)
250
200
min
max
avg
150
100
50
0
0
200
図 3.3-3
オーバーヘッド(msec)
400
600
プロセス数
400
600
プロセス数
800
1000
getuid の strace オーバーヘッド(CPU 負荷時)
250
200
min
max
avg
150
100
50
0
0
200
図 3.3-4
400
600
プロセス数
800
1000
uname の strace オーバーヘッド(CPU 負荷時)
- 3-78 -
以上のグラフより、プロセス数が増加するに伴い strace オーバーヘッドも増加する傾向
があることが分かる。
どの程度の CPU 負荷まで strace を問題なく使用できるかの判断としては、下記の理由
により「CPU フル稼働プロセス数が 400 より少なければ使用可能」が一つの目安であると
考えられる。
(1) gettimeofday、getuid の場合、プロセス数 400 を超えると急激にオーバーヘッドが増加。
(2) uname の場合プロセス数 400 でオーバーヘッドの平均が 50msec を超える。
注)ただし、この数値は評価環境に依存した値である。
3.3.6 strace 信頼性評価(I/O 負荷時)
3.3.6.1 評価手順
strace 信頼性評価(I/O 負荷)の評価手順を、以下に示す。
(1) 事前計測として、I/O 負荷が線形に近い形で変化する stress のパラメータを確認する
(I/O 負荷は、iostat を5秒間隔で実行することで計測する)
。今回の場合は、下記の負
荷設定~計測方法によって、線形 I/O 負荷が得られた。
・書き込みバイト数を 256KByte に固定
・プロセス数を 0~1000 まで 200 刻みに変えて行く
・--hdd-noclean を指定(負荷をかけている間は、生成したファイルを削除しない)
・上記パラメータで stress 実行後、iostat の書き込みスループット表示値の上下動
がある程度安定してから、2 分間計測する
この負荷を設定するための stress コマンド(プロセス数 200 の例)を下記に示す。
$ stress --hdd-bytes 256KB --hdd-noclean -hdd 200
(2) 上記と同じ負荷設定~計測方法の間に、マイクロベンチマークプログラムを実行し、3
つのシステムコールについて、strace のオーバーヘッドを計測する。
(3) (2)の計測を繰り返し、10 点分計測する。これをプロセス数 0~1000 まで 200 刻みで行
う。
3.3.6.2 結果と考察
事前に計測した、stressでI/O負荷を設定した際の、書き込みスループットを 表 3.3-6 に
示す。
- 3-79 -
表 3.3-6
stress I/O 負荷時のプロセス数とスループットの関係
項
stress プロセス
番
数
書き込みスループット(KByte/秒)
最小値
最大値
平均値
1
200
279.57
295.95
284.16
2
400
247.20
363.71
295.34
3
600
734.22
1,165.78
928.88
4
800
945.17
1,400.13
1,245.15
5
1000
1,253.02
1,604.74
1,438.19
スループット(MByte/sec)
表 3.3-6 をグラフにしたものを 図 3.3-5 に示す。
2
1.5
min
max
avg
1
0.5
0
0
図 3.3-5
200
400
600
プロセス数
800
1000
stress I/O 負荷時のプロセス数とスループットのグラフ
多少のばらつきはあるものの、事前計測の目的である、線形の I/O 負荷が得られているこ
とが確認できる。
本評価での strace のオーバーヘッドは、I/O 負荷を基準とした計測値を確認する必要が
あるが、実際には stress プロセス数を変えて計測している。このため、strace オーバーヘ
ッド計測時のプロセス数を、事前に計測したスループットの平均値に変換する。
変換後の計測結果を 表 3.3-7、表 3.3-8、表 3.3-9 に示す。
これらの表から、どのシステムコールの場合も strace を介さずに実行した場合は、I/O 負
荷の影響をほとんど受けていないことが分かる。これは、CPU 負荷の場合と同じ要因によ
ると考えられる。
- 3-80 -
表 3.3-7
gettimeofday コールと strace のオーバーヘッド(I/O 負荷時)
項
I/O 負荷(スル
システムコールのオーバ
strace のオーバーヘッド(usec
番
ープット:
ーヘッド(usec/コール)
/コール)
KByte/秒)
最小値
最大値
平均値
最小値
最大値
平均値
1
0
0.47
0.51
0.49
98.14
98.83
98.51
2
284.16
0.47
0.51
0.49
99.47
100.88
99.86
3
295.34
0.47
0.51
0.49
98.36
29,788.07
3,069.39
4
928.88
0.47
0.50
0.48
98.25
13,719.40
1,461.74
5
1,245.15
0.47
0.50
0.48
97.81
2,940.19
622.62
6
1,438.19
0.47
0.63
0.51
98.75
8,943.56
1,004.99
表 3.3-8
getuid コールと strace のオーバーヘッド(I/O 負荷時)
項
I/O 負荷(スル
システムコールのオーバ
strace のオーバーヘッド(usec
番
ープット:
ーヘッド(usec/コール)
/コール)
KByte/秒)
最小値
最大値
平均値
最小値
最大値
平均値
1
0
0.71
0.74
0.73
90.92
91.86
91.29
2
284.16
0.71
0.75
0.74
90.42
14,965.79
5,698.87
3
295.34
0.71
0.74
0.73
93.45
9,135.86
12,167.37
4
928.88
0.71
0.74
0.73
94.77
26,121.42
10,914.69
5
1,245.15
0.71
0.74
0.73
6,633.82
115,849.30
63,265.69
6
1,438.19
0.71
0.74
0.73
90.64
93,260.74
49,300.90
表 3.3-9
uname コールと strace のオーバーヘッド(I/O 負荷時)
項
I/O 負荷(スル
システムコールのオーバ
strace のオーバーヘッド(usec
番
ープット:
ーヘッド(usec/コール)
/コール)
KByte/秒)
最小値
最大値
平均値
最小値
最大値
平均値
1
0
1.18
1.21
1.19
207.14
208.86
207.61
2
284.16
1.18
1.21
1.19
1,258.61
52,662.20
28,635.51
3
295.34
1.18
1.26
1.20
11,777.31
86,316.45
62,966.00
4
928.88
1.18
1.19
1.19
209.05
82,891.10
42,701.96
5
1,245.15
1.18
1.22
1.19
228.78
349,989.48
115,917.87
6
1,438.19
1.18
1.29
1.20
208.78
156,542.47
97,228.24
システムコール毎に、I/O負荷とstraceオーバーヘッドの関係をグラフにしたものを 図
3.3-6、図 3.3-7、図 3.3-8 に示す。
- 3-81 -
オーバーヘッド(msec)
400
350
300
250
200
150
100
50
0
min
max
avg
0
0.25
オーバーヘッド(msec)
図 3.3-6
1.25
1.5
gettimeofday の strace オーバーヘッド(I/O 負荷時)
400
350
300
250
200
150
100
50
0
min
max
avg
0
0.25
図 3.3-7
オーバーヘッド(msec)
0.5
0.75
1
スループット(MByte/秒)
0.5
0.75
1
スループット(MByte/秒)
1.25
1.5
getuid の strace オーバーヘッド(I/O 負荷時)
400
350
300
250
200
150
100
50
0
min
max
avg
0
0.25
図 3.3-8
0.5
0.75
1
スループット(MByte/秒)
1.25
1.5
uname の strace オーバーヘッド(I/O 負荷時)
- 3-82 -
以上のグラフより、書き込みスループットが 1MByte/秒くらいから、strace オーバーヘ
ッドが急増しており、最小値と最大値のばらつきも大きくなっていることが分かる。
よって、どの程度の I/O 負荷まで strace を問題なく使用できるかの判断としては「書き込
みスループットが 1MByte/秒より少なければ使用可能」が一つの目安であると考えられる。
注)ただし、この数値は評価環境に依存した値である。
今回の事前評価では、書き込みデータバイト数を変えても I/O 負荷が線形にならなかった
ため、プロセス数を変える方法を採らざるを得なかった。今回の評価で得られた数値には、
プロセス数増加によるスケジューリングのオーバーヘッドも影響を与えている可能性が考
えられるが、このような可能性を排除するためにも、もっと少ないプロセス数で I/O 負荷を
線形に変えられるようなパラメータの設定方法を見つけ、そのパラメータでも評価するこ
とが今後の課題である。
3.3.7 strace 信頼性評価(メモリ負荷時)
3.3.7.1 評価手順
strace の使用メモリはそれ程多くないと予想され、スワップアウトする付近までメモリ
負荷を上げないと、strace のオーバーヘッドは変化しないと考えられる。このため、事前
計測を行い、スワップアウトする付近のメモリ負荷を大まかに確認してから、strace のオ
ーバーヘッドを測定する。
strace 信頼性評価(メモリ負荷)の評価手順を、以下に示す。
(1) 事前計測として、stress でメモリ負荷を設定(設定方法は後述)した上で、strace 経由
でマイクロベンチマークを実行する。メモリ負荷バイト数を増やしながらこの手順を繰
り返し、スワップアウトが発生する境界のメモリ負荷バイト数を確認する。今回の場合
は、484MByte だった。
※スワップアウトの発生は、free コマンドで確認する。
(2) stress でメモリ負荷を設定する。stress プロセス数は1とし、確保するメモリ容量は事
前計測で得られたスワップアウト直前の値(今回の場合は 482MByte)を設定する。
$ stress -m 1 --vm-hang --vm-bytes 482MB
(3) free コマンドにより、メモリ負荷が安定することを確認する。
(4) マイクロベンチマークを使い、3つのシステムコールについて strace オーバーヘッド
を 10 点分計測する。
(5) メモリ負荷を、1MByte ずつ上げながら、(2)~(4)の手順を繰り返す。メモリ負荷を上
げても strace オーバーヘッドにほとんど変化が見られないようならば計測を終了する。
3.3.7.2 結果と考察
測定結果を 表 3.3-10、表 3.3-11、表 3.3-12 に示す。
- 3-83 -
表 3.3-10
gettimeofday コールと strace のオーバーヘッド(メモリ負荷時)
項
メモリ負荷
システムコールのオーバ
strace のオーバーヘッド(usec/
番
(MByte)
ーヘッド(usec/コール)
コール)
最小値
最大値
平均値
最小値
最大値
平均値
1
482
0.47
0.50
0.49
97.61
133.29
101.74
2
483
0.47
0.51
0.49
97.61
98.26
97.94
3
484
0.47
0.51
0.48
97.61
100.21
98.99
4
485
0.47
0.51
0.48
97.70
99.04
98.28
5
486
0.47
0.51
0.48
97.83
100.08
98.85
表 3.3-11
getuid コールと strace のオーバーヘッド(メモリ負荷時)
項
メモリ負荷
システムコールのオーバ
strace のオーバーヘッド(usec/
番
(MByte)
ーヘッド(usec/コール)
コール)
最小値
最大値
平均値
最小値
最大値
平均値
1
482
0.23
0.26
0.25
90.58
76.97
89.51
2
483
0.22
0.25
0.24
90.71
120.86
93.80
3
484
0.23
0.26
0.25
92.26
5,150.03
597.60
4
485
0.24
0.26
0.25
91.11
91.98
91.36
5
486
0.23
0.27
0.25
89.95
89.40
89.65
表 3.3-12
uname コールと strace のオーバーヘッド(メモリ負荷時)
項
メモリ負荷
システムコールのオーバ
strace のオーバーヘッド(usec/
番
(MByte)
ーヘッド(usec/コール)
コール)
最小値
最大値
平均値
最小値
最大値
平均値
1
482
0.70
0.72
0.70
203.92
413.35
225.34
2
483
0.69
0.72
0.70
203.44
225.51
207.06
3
484
0.70
0.73
0.72
205.46
2,490.64
435.01
4
485
0.70
0.73
0.71
206.47
209.74
207.86
5
486
0.70
0.73
0.71
206.16
206.73
206.81
これらの表から、どのシステムコールの場合も strace を介さずに実行した場合は、メモ
リ負荷の影響をほとんど受けていないことが分かる。これは、CPU 負荷の場合と同じ要因
によると考えられる。
システムコール毎に、
メモリ負荷とstraceオーバーヘッドの関係をグラフにしたものを 図
3.3-9、図 3.3-10、図 3.3-11 に示す。
- 3-84 -
オーバーヘッド(msec)
6
5
4
min
max
avg
3
2
1
0
482
483
オーバーヘッド(msec)
図 3.3-9
485
486
gettimeofday の strace オーバーヘッド(メモリ負荷時)
6
5
4
min
max
avg
3
2
1
0
482
483
図 3.3-10
オーバーヘッド(msec)
484
メモリ負荷(MByte)
484
メモリ負荷(MByte)
485
486
getuid の strace オーバーヘッド(メモリ負荷時)
6
5
4
min
max
avg
3
2
1
0
482
483
図 3.3-11
484
メモリ負荷(MByte)
485
486
uname の strace オーバーヘッド(メモリ負荷時)
- 3-85 -
これらのグラフから、strace のオーバーヘッドはスワップアウト発生時のみ約 5msec と
多少大きくなるが、スワップアウトの前後ではほとんど一定(1msec 以下)のオーバーヘ
ッドしかかからないことが分かる。
メモリスワップアウト発生後のオーバーヘッドが少ないことについては、今回の評価は
メモリ負荷が安定してから計測する方法のため、スワップアウト後ではメモリに strace 使
用分程度の空きがあったためではないかと考えられる。
いずれにせよ、strace のオーバーヘッドは最大でも約 5msec、平均では 1msec 以下とな
っており、strace を使用する際には、メモリ負荷はほとんど考慮しなくても良いと考えら
れる。
注)ただし、この数値は評価環境に依存した値である。
- 3-86 -
3.4 ネットワーク情報収集ツールの評価
ネットワーク情報収集ツールとして ping, traceroute, netstat, ifconfig, ethtool の機能評
価を行なうことにする。
3.4.1 ツールの使用方法
H/W 監視ツールとして、ethtool の機能検証を、インターフェース監視ツールとして、
ifconfig, netstat の機能検証を、経路監視として、ping, traceroute,を、システムの監視と
して、swatch の機能検証 を行なうことにする。また、ネットワークの障害発生時のデータ
転送の影響を回避する方法として、ネットワークの冗長化機能の検証を行なう。
3.4.1.1 ethtool
ethtools は、ネットワーク機器の物理/電気リンクの状態を検出するコマンドである。実
行は ethtool を実行する。パラメータに、イーサネットデバイス名を指定することで状態を
監視するデバイスを指定する事ができる。以下に書式例は、eth1 の稼動情報を表示した結
果である。
ethtool ethX
ethtool -h
ethtool -a ethX
ethtool -A ethX [autoneg on|off] [rx on|off] [tx on|off]
ethtool -c ethX
ethtool -C ethX [adaptive-rx on|off] [adaptive-tx on|off] [rx-usecs N] [rx-frames N]
[rx-usecs-irq N] [rx-frames-irq N] [tx-usecs N] [tx-frames N] [tx-usecs-irq N]
[tx-frames-irq N] [stats-block-usecs N] [pkt-rate-low N] [rx-usecs-low N] [rx-frames-low
N] [tx-usecs-low N] [tx-frames-low N] [pkt-rate-high N] [rx-usecs-high N] [rx-frames-high
N] [tx-usecs-high N] [tx-frames-high N] [sample-interval N]
ethtool -g ethX
ethtool -G ethX [rx N] [rx-mini N] [rx-jumbo N] [tx N]
ethtool -i ethX
ethtool -d ethX
ethtool -e ethX [raw on|off] [offset N] [length N]
ethtool -E ethX [magic N] [offset N] [value N]
ethtool -k ethX
ethtool -K ethX [rx on|off] [tx on|off] [sg on|off] [tso on|off]
ethtool -p ethX [N]
ethtool -r ethX
ethtool -S ethX
- 3-87 -
ethtool -t ethX [offline|online]
ethtool -s ethX [speed 10|100|1000] [duplex half|full] [port tp|aui|bnc|mii] [autoneg
on|off]
[phyad
N]
[xcvr
internal|external]
[wol
p|u|m|b|a|g|s|d...]
[sopass
xx:yy:zz:aa:bb:cc] [msglvl N]
図 3.4-1 ethtool 書式
表 3.4-1 ethtool オプション
-a
queries the specified ethernet device for pause parameter information.
-A
change the pause parameters of the specified ethernet device.
autoneg on|off
Specify if pause autonegotiation is enabled.
rx on|off
Specify if RX pause is enabled. / Specify if RX checksumming is enabled.
tx on|off
Specify if TX pause is enabled. / Specify if TX checksumming is enabled.
-c
queries the specified ethernet device for coalescing information.
-C
change the coalescing settings of the specified ethernet device.
-g
queries the specified ethernet device for rx/tx ring parameter information.
-G
change the rx/tx ring parameters of the specified ethernet device.
rx N
Change number of ring entries for the Rx ring.
rx-mini N
Change number of ring entries for the Rx Mini ring.
rx-jumbo N
Change number of ring entries for the Rx Jumbo ring.
tx N
Change number of ring entries for the Tx ring.
-i
queries the specified ethernet device for associated driver information.
-d
retrieves and prints a register dump for the specified ethernet device.
-e
retrieves and prints an EEPROM dump for the specified ethernet device.
-E
Changes EEPROM byte for the specified ethernet device.
-k
queries the specified ethernet device for offload information.
sg on|off
Specify if scatter-gather is enabled.
tso on|off
Specify if tcp segmentation offload is enabled.
-p
initiates adapter-specific action intended to enable an operator to easily
identify the adapter by sight.
N
Length of time to perform phys-id, in seconds.
-r
restarts auto-negotiation on the specified ethernet device, if auto-negotiation is
enabled.
-S
queries the specified ethernet device for NIC- and driver-specific statistics.
speed 10|100|1000
Set speed in Mb/s.
duplex half|full
Set full or half duplex mode.
port tp|aui|bnc|mii
Select device port.
autoneg on|off
Specify if autonegotiation is enabled.
phyad N
PHY address.
- 3-88 -
xcvr
Select transceiver type.
internal|external
wol
p
Wake on phy activity
p|u|m|b|a|g|s|d...
u
Wake on unicast messages
m Wake on multicast messages
b
Wake on broadcast messages
a Wake on ARP
g
Wake on MagicPacket(tm)
s Enable SecureOn(tm) password for MagicPacket(tm)
d
sopass
Disable
(wake
on nothing).
This option clears all previous options.
Set the SecureOn(tm) password.
xx:yy:zz:aa:bb:cc
msglvl N
Set the driver message level. Meanings differ per driver.
# ethtool eth1
Settings for eth1:
Supported ports: [ TP MII ]
Supported link modes:
10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Supports auto-negotiation: Yes
Advertised link modes:
10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Full
Port: MII
PHYAD: 1
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: g
Wake-on: d
Current message level: 0x00000007 (7)
Link detected: yes
図 3.4-2 ethtool 実行例
3.4.1.2 ifconfig
インターフェースの状態確認/設定のためのコマンドであり、IP アドレス,サブネットマ
- 3-89 -
スクの確認や設定をすることができる。以下に、書式、オプション、実行例を記す。実行
例では、bonding を使用して、ネットワークの冗長化がなされている bonding を使用した
場合の ifconfig の実結果である。
ifconfig [interface]
ifconfig interface [aftype] options | address ...
表 3.4-2 ifconfig 書式
表 3.4-3 ifconfig 使用できるオプション
interface
ドライバの名前に装置の番号を付けたもの
up
インタフェースを活動状態にする
down
インタフェースのドライバを停止する
[-]arp
ARP プロトコルの使用を有効/無効にする
[-]promisc
無差別 (promiscuous) モードを有効/無効にする
[-]allmulti
全マルチキャストモードを有効/無効にする
metric N
インタフェースメトリックを設定する
mtu N
インタフェースの最大転送単位 (MTU) を設定する
dstaddr addr
ポイント間接続においてリモートの IP アドレスを設定する
netmask addr
ネットワークマスクを設定する
add addr/prefixlen
IPv6 アドレスをインタフェースに追加する
del addr/prefixlen
IPv6 アドレスをインタフェースから削除する
tunnel xx.xx.xx.xx
新規の SIT (IPv6-in-IPv4) デバイスを作成し、 与えられた対象アドレスにトンネ
ルする
irq addr
デバイスにより使用される割り込みを設定する
io_addr addr
デバイスの I/O 開始アドレスを設定する
mem_start addr
デバイスにより使用される共有メモリーの開始アドレスを設定する
media type
デバイスで使用される、物理ポートもしくは媒体タイプを設定する
[-]broadcast [addr]
アドレスを指定すると、このインタフェースに プロトコルブロードキャストアド
レスを設定する
[-]pointopoint [addr]
ポイント間接続モードを有効にする
hw class address
デバイスドライバーがこの操作をサポートしていれば、 インタフェースのハード
ウェアアドレスを設定する
multicast
インタフェースのマルチキャストフラグを設定する
txqueuelen length
デバイスの送信キューの長さをセットする
# ifconfig
bond0
Link encap:Ethernet
HWaddr 00:12:3F:6E:75:9E
inet addr:172.16.37.141
Bcast:172.16.39.255
- 3-90 -
Mask:255.255.252.0
UP BROADCAST RUNNING MASTER MULTICAST
MTU:1500
Metric:1
RX packets:2895740 errors:0 dropped:0 overruns:0 frame:0
TX packets:2440459 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:367358753 (350.3 Mb)
eth0
Link encap:Ethernet
TX bytes:408660326 (389.7 Mb)
HWaddr 00:12:3F:6E:75:9E
UP BROADCAST RUNNING SLAVE MULTICAST
MTU:1500
Metric:1
RX packets:1481442 errors:0 dropped:0 overruns:0 frame:0
TX packets:1221730 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:192590856 (183.6 Mb)
TX bytes:217084785 (207.0 Mb)
Interrupt:18 Memory:dfcf0000-dfd00000
eth1
Link encap:Ethernet
HWaddr 00:12:3F:6E:75:9E
UP BROADCAST RUNNING SLAVE MULTICAST
MTU:1500
Metric:1
RX packets:1414298 errors:0 dropped:0 overruns:0 frame:0
TX packets:1218729 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:174767897 (166.6 Mb)
lo
TX bytes:191575541 (182.7 Mb)
Link encap:Local Loopback
inet addr:127.0.0.1
Mask:255.0.0.0
UP LOOPBACK RUNNING
MTU:16436
Metric:1
RX packets:4347 errors:0 dropped:0 overruns:0 frame:0
TX packets:4347 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:376568 (367.7 Kb)
TX bytes:376568 (367.7 Kb)
図 3.4-3 ifconfig 実行例
3.4.1.3 netstat
netstat ネットワーク機器までのルーティング情報などを取得することができるコマンド
である。オプションによっては、インターフェイスごとのネットワーク統計などを確認す
ることができる。実行例は、オプションに -nr を指定し、出力を IP アドレスなど数値のみ
に抑制し、ルーティング・テーブルを表示している。
netstat
[address_family_options] [--tcp|-t] [--udp|-u] [--raw|-w] [--listening|-l]
- 3-91 -
[--all|-a] [--numeric|-n] [--numeric-hosts][--numeric-ports][--numeric-ports] [--symbolic|-N]
[--extend|-e[--extend|-e]]
[--timers|-o]
[--program|-p]
[--verbose|-v]
[--continuous|-c]
[delay]
netstat
{--route|-r}
[address_family_options]
[--extend|-e[--extend|-e]]
[--verbose|-v]
[--numeric|-n] [--numeric-hosts][--numeric-ports][--numeric-ports] [--continuous|-c] [delay]
netstat
{--interfaces|-i}
[--program|-p]
[iface]
[--all|-a]
[--numeric|-n]
[--extend|-e[--extend|-e]]
[--verbose|-v]
[--numeric-hosts][--numeric-ports][--numeric-ports]
[--continuous|-c] [delay]
netstat
{--groups|-g}
[--numeric|-n]
[--numeric-hosts][--numeric-ports][--numeric-ports]
[--continuous|-c] [delay]
netstat
{--masquerade|-M}
[--extend|-e]
[--numeric|-n]
[--numeric-hosts][--numeric-ports][--numeric-ports] [--continuous|-c] [delay]
netstat {--statistics|-s} [--tcp|-t] [--udp|-u] [--raw|-w] [delay]
address_family_options:
[--protocol={inet,unix,ipx,ax25,netrom,ddp}[,...]]
[--unix|-x]
[--inet|--ip]
[--ax25]
[--ipx]
[--netrom] [--ddp]
図 3.4-4 netstat 書式
表 3.4-4 netstat オプション
引数なし
オープンされているソケットの一覧を表示する
--route , -r
カーネルの経路テーブルを表示する
--groups , -g
マルチキャストグループメンバーシップ情報を表示する
--interface=iface , -i
ネットワークインターフェースの状態テーブルを表示する
--masquerade , -M
マスカレードされた接続を表示する
--statistics , -s
各プロトコルの統計情報の一覧を表示する
--verbose , -v
詳細表示モードになり、起こっていることをユーザーに知らせる
--numeric , -n
ホスト・ポート・ユーザーなどの名前を解決せずに、
数字のアドレスで表示する
--numeric-hosts
ホストアドレスを数値で表示する
--numeric-ports
ポート番号を数値で表示する
--numeric-users
ユーザー ID を数値で表示する
--protocol=family , -A
接続状態を表示するアドレスファミリーを指定する
- 3-92 -
-c, --continuous
指定された情報を 1 秒ごとに表示し続ける
-e, --extend
詳しい情報を表示する
-o, --timers
ネットワーキングタイマーに関する情報が追加される
-p, --program
各ソケットが属しているプログラムの PID と名前が表示される
-l, --listening
接続待ち (listen) 状態にあるソケットのみを表示する
-a, --all
接続待ち状態にあるソケットも、
接続待ち状態にないソケットも表示する
-F
FIB からの経路情報を表示する
-C
経路キャッシュからの経路情報を表示する
# netstat -nr
Kernel IP routing table
Destination
192.168.10.0
Gateway
0.0.0.0
127.0.0.0
0.0.0.0
0.0.0.0
192.168.10.1
Genmask
Flags
255.255.252.0
255.0.0.0
U
U
0.0.0.0
MSS Window
0 0
0 0
UG
0 0
irtt Iface
0 bond0
0 lo
0 bond0
図 3.4-5 netstat 実行例
3.4.1.4 ping
ping は ICMP の ECHO_REQUEST パケットをネットワーク上の任意のホストに送
信し、その応答(ICMP ECHO REPLAY)を受け取ることにより、リモートホストとの通
信が可能かどうかを確認するための手段として利用できるコマンドである。ping を実行す
る場合、パラメータとして、IP アドレスもしくは、ホスト名(FQDN)を指定する。
ping [ -LRUbdfnqrvVaAB] [ -c count] [ -i interval] [ -l preload] [-p pattern] [ -s packetsize] [ -t
ttl] [ -w deadline] [ -F flowlabel] [ -I interface] [ -M hint] [ -Q tos] [ -S sndbuf] [ -T timestamp
option] [ -W timeout] [ hop ...] destination
図 3.4-6 ping 書式
表 3.4-5 ping オプション
-c count
cont 個のパケットを送信した後、停止する
-d
使用するソケットに SO_DEBUG オプションを設定する
-i wait
個々のパケットの間に wait 秒待つ
-l preload
指定した preload の値だけ ECHO_REQUEST パケットを出来るだけ速く送信し、
通常の動作に戻る
-n
数値出力のみ
- 3-93 -
-p pattern
送出するパケットを埋めるための 16 個までの “pad”バイトを指定できる
-q
開始と終了時の要約以外は、何も表示しない
-r
経路を記録する
-s packetsize
何バイトのデータが送られるかを指定する
-v
ECHO_RESPONSE 以外の ICMP パケットを表示する
-w waittime
ping を waittime 秒後に終了させる
-I interface
与えられたインタフェースから、マルチキャストパケットを送る
-L
マルチキャストパケットのループバックを抑制する
-t ttl
マルチキャストパケットの IP 寿命時間 (Time To Live) を設定する
$ ping www.turbolinux.co.jp
PING www.turbolinux.co.jp (xxx. xx. xxx xxx) from xxx. xxx. xx. xxx : 56(84) bytes of data.
64 bytes from www.turbolinux.co.jp (xxx.xx.xxx.xxx): icmp_seq=0 ttl=246 time=344.910 msec
64 bytes from www.turbolinux.co.jp (xxx.xx.xxx.xxx): icmp_seq=1 ttl=246 time=441.273 msec
64 bytes from www.turbolinux.co.jp (xxx.xx.xxx.xxx): icmp_seq=2 ttl=246 time=350.848 msec
64 bytes from www.turbolinux.co.jp (xxx.xxxxxx.xxx): icmp_seq=3 ttl=246 time=177.361 msec
64 bytes from www.turbolinux.co.jp (xxx.xx.xxx.xxx): icmp_seq=4 ttl=246 time=335.683 msec
64 bytes from www.turbolinux.co.jp (xxx.xx.xxx.xxx): icmp_seq=5 ttl=246 time=338.347 msec
64 bytes from www.turbolinux.co.jp (xxx.xx.xxx.xxx): icmp_seq=6 ttl=246 time=312.197 msec
--- www.turbolinux.co.jp ping statistics --7 packets transmitted, 7 packets received, 0% packet loss
round-trip min/avg/max/mdev = 177.361/328.659/441.273/72.454 ms
図 3.4-7 ping 実行例
3.4.1.5 traceroute
traceroute は相手先の機器までのネットワークの経路を調査することができる。ゲート
ウェイ-ホスト間や経路上のルータのルーティング設定を確認するために用いられることが
多い。目的のホストまでの経路や疎通が何処までできているか、設置場所が不明なホスト
のおおまかな場所を推測する、といった用途にも使用できる。コンソールから traceroute
を実行する。パラメータとして、IP アドレスもしくはホスト名(FQDN)を指定する。
traceroute [ -dFInrvx ] [ -f first_ttl ] [ -g gateway ] [ -i iface ] [ -m max_ttl ] [ -p
port ] [ -q nqueries ] [ -s src_addr ] [ -t tos ] [ -w waittime ] [ -z pausemsecs ] host
[ packetlen ]
図 3.4-8 traceroute 書式
- 3-94 -
表 3.4-6 traceroute オプション
-f
使用する TTL の初期値を指定する
-F
IP パケットの分割を禁止する
-d
デバックモードで動作する
-g
経由すべきゲートウェイのアドレスを最大 8 個まで指定できる。
-i
指定されたインターフェイスを用いて実行する
-I
UDP パケットではなく、ICMP Echo Request を用いる
-m
使用する TTL の最大値を指定する
-n
出力を IP アドレスのみに抑制する
-p
使用する UDP パケットのポート番号を指定する
-r
直接パケットを指定したホストに転送するように指示する
-s
指定された IP アドレスから実行する
-t
パケットのサービスタイプを指定された値に設定する
-v
詳細モード
-w
タイムアウト時間を指定する
-x
ICMP の CheckSum の評価を行う
# traceroute www.ipa.go.jp
traceroute to www.ipa.go.jp (xxx.xx.xxx.xxx), 30 hops max, 38 byte packets
1
ns (xxx.xx.xxx.xxx)
0.204 ms
0.166 ms
0.345 ms
2
h18hohoge.net (xxx.xx.xxx.xxx)
3
203.hogehoge.net (xxx.xx.xxx.xxx)
3.074 ms
2.900 ms
2.828 ms
4
163hoge.hoge.net (xxx.xx.xxx.xxx)
3.702 ms
3.252 ms
10.599 ms
5
ae.hoge.net (xxx.xx.xxx.xxx)
6
xxx.xx.xxx.xxx (xxx.xx.xxx.xxx)
7
g2.hogehoge.net (xxx.xx.xxx.xxx)
4.146 ms
4.140 ms
8
g0.hogehoge.net (xxx.xx.xxx.xxx)
4.580 ms
14.806 ms
9
xxx.xx.xxx.xxx (xxx.xx.xxx.xxx)
62.259 ms
5.391 ms
1.528 ms
4.409 ms
0.645 ms
3.785 ms
4.076 ms
10.970 ms
3.669 ms
4.406 ms
10.604 ms
4.137 ms
14.330 ms
4.485 ms
図 3.4-9 traceroute 実行例
3.4.2 bonding 環境での機能評価
3.4.2.1 ハードウェア構成
Bonding 構成を作成するにあたり、2 枚以上のイーサネットカードが必要になる。今回使
用した検証環境を以下に示す。
- 3-95 -
表 3.4-7 ハードウェア環境
CPU
Pentium4 3.20GHz
メモリ
256MB
ハードディスク
160GB
ネットワーク
Intel Corp. 82557/8/9 [Ethernet Pro 100] x 2
3.4.2.2 ソフトウェア構成
Kernel2.6 を採用している Turbolinux 10 Server を使用して評価を行なった。使用した
ソフトウェア構成を示す。
表 3.4-8 ソフトウェア構成
ディストリビューション
Turbolinux 10 Server
kernel
2.6.8-5
ping(net-tools)
1.60-13
traceroute
1.4a12-3
netstat(net-tools)
1.60-13
ifconfig(net-tools)
1.60-13
ethtool
1.8.2
swatch
3.1.1-1
bonding ドライバ
2.6.0
e100 ドライバ
3.4.10
3.4.2.3 bonding 環境構築
bonding とは、ネットワークを冗長化する機能である。1 つのシステムに複数(2 つ以上)
のネットワークインターフェースカードを実装し、両インターフェースより送受信を行な
う。ネットワーク機器に障害が起きた場合、別の経路を利用することにより、通信の切断
を回避することができる。bonding 環境を構築する為の設定を以下に示す。
はじめに、modules.confの修正を行なう。図 3.4-10 の内容を追記する。
また、別表にある、オプションを指定する設定を行う。
alias bond0 bonding
options bonding mode=0 miimon=100
(mode=0 (ラウンドロビン) で、miimon (切断監視) を 100ms)
図 3.4-10 modules.conf(抜粋)
- 3-96 -
表 3.4-9 bonding で使用できるオプション
arp_interval
ARP モニタリング頻度をミリ秒単位で指定する
arp_ip_target
arp_interval が正数の場合の IP アドレスを指定する
downdelay
リンク失敗が検知されてからリンクを無効にするまでの遅延時間をミリ秒で指定する
lacp_rate
802.3ad モードでの LACPDU パケットを転送する為のリンクパートナーを問い合わ
せる際のレートを指定する。指定可能オプションは別表(lacp_rate で指定できるオプシ
ョン)を参照
max_bonds
結合ドライバの1実体用に作成する結合インターフェースの数を指定する
miimon
MII リンク監視を行う頻度をミリ秒単位で指定する
mode
結合ポリシーの1つを指定する。デフォルトはラウンドロビン
指定可能オプションは別表(mode で指定できるオプション)を参照
multicast
マルチキャストサポートの為の操作モードを指定する
primary
この値が入力され、デバイスがオンラインであれば、そのデバイスは出力メディアとし
て最初に使用できる
updelay
リンクアップ状態を検知した後にリンクが有効になるまでの遅延時間をミリ秒で指定す
る
use_carrier
リ ン ク 状 態 を 検 知 す る の に miimon が MII あ る い は ETHTOOL ioctl /
netif_carrier_ok() を使うか使わないかを指定する
表 3.4-10 lacp_rate で指定できるオプション
slow or 0
LACPDU を送るパートナーを 30 秒単位で要求する (デフォルト)
fast or 1
LACPDU を送るパートナーを 1 秒単位で要求する
- 3-97 -
表 3.4-11 mode で指定できるオプション
balance-rr or 0
ラウンドロビンポリシー
利用可能なスレーブを最初から
最後まで順番に使用して送信する
active-backup or 1
アクティブ
結合インターフェース中の1スレーブのみアクティ
バックアップポリシー
ブとなる。アクティブスレーブでの通信が失敗した時
に限り、他のスレーブがアクティブになる
balance-xor or 2
XOR ポリシー
(宛先 MAC アドレスで XOR された元 MAC アド
レス) モジューラスレーブカウント」を基にして送信
する
broadcast or 3
ブロードキャストポリシー
全スレーブインターフェースで全てのパケットを送
信する
802.3ad or 4
IEEE 802.3ad 動的リンク集合。スピードと全/半二
-
重設定が同じ集合グループを作成する
表 3.4-12 multicast で指定できるオプション
disabled or 0
無効 (マルチキャストサポートなし)
active or 1
アクティブバックアップモードに便利な、
アクティブなスレーブのみ有効とする
all or 2
全てのスレーブで有効とする
modules.conf の修正後、depmod コマンドにて、起動時に読み込まれるモジュール情報の
更新を行なう。
# depmod –a
図 3.4-11 depmod コマンド
bonding インターフェースを作成する為に、/etc/sysconfig/network-scripts に ifcfg-bond0
を作成する。以下に bond0 の設定例を提示する。
DEVICE=bond0
IPADDR=172.16.37.141(142)
NETMASK=255.255.252.0
NETWORK=172.16.36.0
BROADCAST=172.16.39.255
BOOTPROTO=none
ONBOOT=yes
USERCTL=yes
図 3.4-12 bond0 設定
- 3-98 -
bond0 インターフェースをマスタとするために、ifcfg-eth0,1 には、スレーブの設定を行う
必要がある為、設定を変更する。
表 3.4-13 インターフェース設定変更
eth0
eth1
# vi ifcfg-eth0
# vi ifcfg-eth1
DEVICE=eth0
DEVICE=eth1
BOOTPROTO=none
BOOTPROTO=none
MASTER=bond0
MASTER=bond0
SLAVE=yes
SLAVE=yes
ONBOOT=yes
ONBOOT=yes
USERCTL=yes
USERCTL=yes
設定終了の後、システムを再起動し、bonding環境が稼動することを確認する。再起動後に、
ifconfigコマンドにて、bonding環境が構成されているか確認する。bondingドライバが起動
時にkernelに読み込まれると、図 3.4-13 のような情報が表示される。
# ifconfig
bond0
Link encap:Ethernet
HWaddr 00:12:3F:6E:75:9E
inet addr:172.16.37.141
Bcast:172.16.39.255
UP BROADCAST RUNNING MASTER MULTICAST
Mask:255.255.252.0
MTU:1500
Metric:1
RX packets:4753870 errors:0 dropped:0 overruns:0 frame:0
TX packets:4946251 errors:3 dropped:0 overruns:0 carrier:3
collisions:0 txqueuelen:0
RX bytes:470374210 (448.5 Mb)
eth0
Link encap:Ethernet
TX bytes:868100041 (827.8 Mb)
HWaddr 00:12:3F:6E:75:9E
UP BROADCAST RUNNING SLAVE MULTICAST
MTU:1500
Metric:1
RX packets:1501071 errors:0 dropped:0 overruns:0 frame:0
TX packets:2473063 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:166320363 (158.6 Mb)
TX bytes:2593576762 (2473.4 Mb)
Interrupt:18 Memory:dfcf0000-dfd00000
eth1
Link encap:Ethernet
HWaddr 00:12:3F:6E:75:9E
UP BROADCAST RUNNING SLAVE MULTICAST
MTU:1500
Metric:1
RX packets:3252799 errors:0 dropped:0 overruns:0 frame:0
TX packets:2473189 errors:3 dropped:0 overruns:0 carrier:3
collisions:0 txqueuelen:1000
RX bytes:304053847 (289.9 Mb)
TX bytes:2569490729 (2450.4 Mb)
図 3.4-13 構成確認
- 3-99 -
詳細は、/usr/src/linux-2.6.8/Documentation/networking/bonding.txt を参照すること。
3.4.2.4 swatch
swatch は、ログを監視し、設定した文字列を検出すると、指定したユーザへメールにて
通知を行う。以下に、swatch のインストール方法を示す。 swatch を使用するには以下の
パッケージが必要となる。
perl-Carp-Clan,
perl-Bit-Vector,
perl-Date-Calc,
perl-File-Tail,
perl-TimeDate,
perl-Date-Manip, perl-Mail-Sendmail
上記パッケージのインストールが終了した後に、swatch のインストールを行なうことがで
きる。
# rpm –ivh swatch-3.1.1-1.noarch.rpm
図 3.4-14 swatch のインストール
swatch.conf にて、監視対象から検出する文字列の設定、検出時の動作を設定する。下図
“swatch.conf 設定例(抜粋)” は設定例である。
# less swatch.conf
watchfor /eth/
<- watchforの後に検出する文字列(パターン)を記述
mail=root
<- 指定されたアドレスにメールを送信
throttle use=message
<- 一度検出されたパターンが再度検出された場合、
検出を抑えることができる
watchfor /hda/
mail=root
throttle use=message
watchfor /sda/
mail=root
throttle use=message
図 3.4-15 swatch.conf 設定例(抜粋)
表 3.4-14 アクションで指定できるパラメータ
echo [modes]
ターミナルにメッセージを表示する
modes により表示形式(別表参照)を変更可能する
bell [N]
beep 音を N 回鳴らす
数字を指定しなければ 1 回鳴らす
- 3-100 -
exec command
指定したコマンドを実行する
mail [=address:address:…]
指定されたアドレスにメールを送信する
[,subject=your_text_here]
pipe command[,keep_open]
パイプでコマンドに結果を渡す
write [user:user:…]
swatch を実行しているサーバにログインしているユーザーに、
write コマンドを使用して結果を送信する
throttle hours:minutes:seconds
一度検出されたパターンが再度検出された場合、検出を抑える
,[use=message|regex]
continue
マッチするパターンが検出されると指定されたアクションが実行さ
れて終了するが、continue が指定されている場合はさらにマッチする
パターンの検出を行なう
マッチするパターンを検出すると swatch が終了する
quit
表 3.4-15 modes で使用できるオプション
normal
通常の表示
bold
太字で表示
underscore
下線で表示
blink
点滅で表示
inverse
反転して表示
[color]
black, red, green, yellow, blue, magenta,
cyan, white の色で表示
[color_h]
black_, red_h, green_h, yellow_h,
blue_h, magenta_h, cyan_h, white_h の色で反転
random
上記のものをランダムに使用
設定終了の後、swatch を実行する。
# swatch -c /etc/swatch.conf -t /var/log/messages
*** swatch version 3.1.1 (pid:26195) started at Mon Sep 19 02:17:27 JST 2005
図 3.4-16 swatch の実行
表 3.4-16 swatch 起動時に指定できるオプション
--config-file=filename
-c filename
設定ファイルを指定する
--input-record-separator
改行コードの指定する
=regular_expression
--restart-time
-r [+]hh:mm[am|pm]
swatch を再起動する時間を hh:mm で指定する
=[+]hh:mm[am|pm]
--script-dir
swatch を起動すると
- 3-101 -
=/path/to/directory
--tail-file
スクリプトファイルが作成される
-t filename
監視対象となるログのファイル名を指定する
-p command
コマンドの実行結果を swatch にパイプする
-f filename
設定ファイルに適合する内容をスキャンする
=filename
--read-pip
e=command
--examine
=filename
--dump-script[=filename]
デバッグ用のオプション
3.4.3 bonding 機能検証手順
bonding 環境下において、ネットワークケーブルが断絶した場合の OS の挙動を調べる事
とする。機能検証の手順として以下を行なう。
・scp コマンドにて、ファイル転送中に bonding 環境のうち、1 本のネットワークケーブ
ルを抜く
・scp のスループットの変化を確認
・抜いたネットワークケーブルを元に戻し、scp のスループットの変化を確認
3.4.4 bonding 機能検証結果と考察
ケーブルを抜いた直後、スループットが低下するがネットワークの冗長化環境で転送して
いる為に、ファイル転送自体が停止する事はない。同状態から、ネットワークケーブルを
戻すことにより、スループットがケーブルを抜く前と同等の値に戻る事も確認できた。
# scp bondtrancefarfile root@dhcp-148:/root
bondtrancefarfile
12%
562MB
2.4MB/s
26:44 ETA
bondtrancefarfile
12%
564MB
2.4MB/s
27:03 ETA
bondtrancefarfile
12%
567MB
2.3MB/s
27:20 ETA
bondtrancefarfile
12%
569MB
2.3MB/s
27:35 ETA
bondtrancefarfile
12%
571MB
2.3MB/s
27:22 ETA
bondtrancefarfile
13%
573MB
2.3MB/s
27:24 ETA
bondtrancefarfile
2.1MB/s から、1.9MB/s へ転送量が減る。
13%
573MB
2.1MB/s
30:27 ETA
bondtrancefarfile
と同時に、転送時間が増えていることもわかる。 13%
574MB
1.9MB/s
33:27 ETA
bondtrancefarfile
Î 障害が発生した事がわかる。
13%
575MB
1.8MB/s
35:06 ETA
bondtrancefarfile
以降、転送量が減り続ける。
13%
576MB
1.7MB/s
36:45 ETA
bondtrancefarfile
13%
576MB
1.6MB/s
39:14 ETA
bondtrancefarfile
13%
577MB
1.6MB/s
40:40 ETA
bondtrancefarfile
13%
578MB
1.5MB/s
42:25 ETA
bondtrancefarfile
13%
579MB
1.5MB/s
43:30 ETA
bondtrancefarfile
13%
580MB
1.4MB/s
44:57 ETA
bondtrancefarfile
13%
581MB
1.4MB/s
46:30 ETA
== 省略 ==
- 3-102 -
bondtrancefarfile
13%
590MB
1.1MB/s
56:17 ETA
bondtrancefarfile
13%
591MB
1.1MB/s
58:29 ETA
bondtrancefarfile
13%
592MB
1.1MB/s
59:54 ETA
bondtrancefarfile
13%
593MB
1.1MB/s 1:00:23 ETA
bondtrancefarfile
13%
594MB
1.0MB/s 1:01:33 ETA
bondtrancefarfile
13%
595MB
1.0MB/s 1:03:06 ETA
bondtrancefarfile
13%
595MB
1.0MB/s 1:04:58 ETA
bondtrancefarfile
13%
596MB 986.5KB/s 1:05:57 ETA
bondtrancefarfile
13%
597MB 958.7KB/s 1:07:51 ETA
bondtrancefarfile
13%
598MB 964.4KB/s 1:07:26 ETA
bondtrancefarfile
13%
599MB 954.8KB/s 1:08:05 ETA
14%
647MB 907.6KB/s 1:10:43 ETA
14%
648MB 903.6KB/s 1:11:01 ETA
14%
649MB 917.3KB/s 1:09:56 ETA
bondtrancefarfile
14%
650MB 908.7KB/s 1:10:35 ETA
bondtrancefarfile
14%
652MB 982.7KB/s 1:05:14 ETA
bondtrancefarfile
14%
654MB
1.2MB/s
54:24 ETA
bondtrancefarfile
14%
657MB
1.3MB/s
48:21 ETA
bondtrancefarfile
14%
660MB
1.5MB/s
42:04 ETA
bondtrancefarfile
15%
663MB
1.6MB/s
39:03 ETA
bondtrancefarfile
15%
681MB
2.0MB/s
31:23 ETA
bondtrancefarfile
15%
683MB
2.0MB/s
30:34 ETA
bondtrancefarfile
15%
686MB
2.1MB/s
29:40 ETA
bondtrancefarfile
15%
689MB
2.2MB/s
28:31 ETA
bondtrancefarfile
15%
691MB
2.2MB/s
27:57 ETA
bondtrancefarfile
15%
694MB
2.3MB/s
26:56 ETA
bondtrancefarfile
15%
697MB
2.3MB/s
26:36 ETA
bondtrancefarfile
状態が復旧したと思われる。
bondtrancefarfile
理由は、転送量が障害前と同等の転送量に戻っ
bondtrancefarfile
た。
15%
699MB
2.4MB/s
26:07 ETA
15%
702MB
2.4MB/s
25:46 ETA
15%
705MB
2.5MB/s
25:04 ETA
bondtrancefarfile
16%
708MB
2.5MB/s
24:57 ETA
bondtrancefarfile
16%
710MB
2.5MB/s
24:43 ETA
== 省略 ==
抜いたケーブルを戻した。
bondtrancefarfile
転送量が約 1MB/s から、1.2MB に
bondtrancefarfile
上がっていることがわかる。
bondtrancefarfile
== 省略 ==
図 3.4-17 scp による転送ログ
* bondtrancefarfile:転送テストのために作成したランダムなバイナリファイル 4.3Gb を
使用する。
- 3-103 -
bonding を利用する事によりネットワーク障害に対する耐久性を向上することが出来る。通
常予想される様な、ネットワークケーブルの断線、ネットワークの機器の故障などが、万
が一発生しても、別の経路を利用して通信が継続されるため、実際のアプリケーションに
対する障害の影響を最小限とすることができる。ネットワークには、様々なハードウェア
が使われている為に故障が起こる可能性を排除することはできない。今回検証したツール
を有効活用することにより障害発生からの復旧を行うとともに、bonding 環境を構築するこ
とで、アプリケーションへの影響を最小に抑えることは可能であると考える。今後の課題
として、bonding 環境で、ネットワークの経路変更にどれ位の時間がかかるか、計測を行う
ことなどが挙げられる。
- 3-104 -
3.5 ディスク情報収集ツールの評価
ディスク情報収集の評価として、以下の機能評価を行なう事とする。
Storage Manager, df, raidtools, mdadm, LVM2
3.5.1 ツールの使用方法
H/W RAID の監視ツールとして、StorageManager の評価を、S/W RAID の機能検証と
して、mdadm,raidtools,df の評価を、LVM の機能検証として、LVM2 の評価を行なう。
3.5.1.1 Storage Manager
H/W RAID監視できるStorage Mangerは、Adaptec社製のHostRAID/SCSIデバイスを監
視するツールである(詳細は、3.5.2.3 を参照)。要求環境として、aacraidの、1.1.5 以上が
必要である。aacraidのバージョン確認は、modinfoコマンドで確認することが出来る。
3.5.1.2 df
df は、ファイルシステムのディスク容量の使用状況を表示するコマンドである。パーテ
ィションごとに、総容量、使用量、空容量、使用率、マウントポイントをブロック(512byte)
単位で表示することができる。df の実行例を以下に示す。以降、書式、オプション、実行
例の順で記す。
df [options] [file...]
図 3.5-1 df 書式
表 3.5-1 df で使用できるオプション
POSIX オプション
-k
デフォルトの 512 バイト単位の代わりに 1024 バイト単位を用い
る。
-P
`Filesystem
N-blocks Used Available Capacity Mounted on' とい
うヘッダをつけて 6 列で出力する
GNU オプション
a, --all
サ イズが 0 ブロックのファイルシステムやタイプが `ignore' また
は`auto' のファイルシステムもリスト表示に含める
-i, --inodes
ブ ロック単位での使用容量のかわりに inode の使用状況をリスト
表示する
-k, --kilobytes
デフォルトのブロックサイズを無視し、 1024 バイトを 1 ブロック
- 3-105 -
としてサイズを表示する
-l, --local
ローカルファイルシステムのみをリスト表示する
-m, --megabytes
メガバイト (1,048,576 バイト) ブロック単位でサイズを表示する
-t fstype,
タイプが fstype のファイルシステムのみをリスト表示する
--type=fstype
タイプが fstype のファイルシステムを除外する。
-x fstype,
--exclude-type=fstype
それぞれのサイズについて、例えばメガバイトなら M といったサイ
-H, --si
ズ文字を付加する
-T, --print-type
各ファイルシステムのタイプを表示する
--block-size=SIZE
使用量データを得る前に sync を呼ばない
--sync
使用量データを得る前に sync を呼ぶ。システムによっては新しい結
果を得ることができる
# df
Filesystem
/dev/md0
1K-blocks
20635516
2942904
16644384
62193
11203
47779
19% /boot
20635516
32928
19554360
1% /home
/dev/hda1
/dev/md1
Used Available Use% Mounted on
16% /
図 3.5-2 df 実行例
3.5.1.3 smartmontools
smartmontools は、ハードディスクが持っている自己診断機能を利用してディスクを監
視するツールである。SMART から得られる情報を監視することによって、ハードディスク
の故障を未然に防げる可能性もある。
smartctl – SMART よるディスク監視ができる。
smartctl [options] device
図 3.5-3 smartctrl 書式
表 3.5-2 smartctl オプション
SHOW オプション
-i, --info
Prints the device model number, serial number, firmware version, and
ATA Standard version/revision
-a, --all
information.
Prints all SMART information about the disk, or TapeAlert
information about the tape drive or changer.
RUN-TIME オプション
-q TYPE, --quietmode=TYPE
Specifies that smartctl should run in one of the two quiet modes
described here.
- 3-106 -
-d TYPE, --device=TYPE
Specifies the type of the device. The valid arguments to this option
are ata, scsi, and 3ware,N.
-T TYPE, --tolerance=TYPE
Specifies how tolerant smartctl should be of ATA and SMART
command failures.
-b TYPE, --badsum=TYPE
Specifies the action smartctl should take if a checksum error is
detected in the: (1) Device Identity Structure, (2) SMART Self-Test
Log Structure, (3) SMART Attribute Value Structure, (4) SMART
Attribute Threshold Structure, or (5) ATA Error Log Structure.
-r TYPE, --report=TYPE
Intended primarily to help smartmontools developers understand the
behavior of smartmontools on non-conforming or poorly conforming
hardware.
コマンド
-s VALUE, --smart=VALUE
Enables
or
disables
SMART
on device.
-o VALUE, --offlineauto=VALUE
Enables or disables SMART automatic offline test, which scans the
drive every four hours for disk defects.
-S VALUE, --saveauto=VALUE
Enables or disables SMART autosave of device vendor-specific
Attributes.
DISPLAY オプション
-H, --health
SMART status is based on information that it has gathered from
online and offline tests, which were used to determine/update its
SMART vendor-specific Attribute values.
-c, --capabilities
Prints only the generic SMART capabilities.
-A, --attributes
Prints only the vendor specific SMART Attributes.
-l TYPE, --log=TYPE
Prints either the SMART Error Log, the SMART Self-Test Log, the
SMART Selective Self-Test Log [ATA only], or theLog
Directory [ATA
only].
-v N,OPTION, --vendorattribute=N,OPTION
Sets a vendor-specific display OPTION for Attribute N.
-F TYPE, --firmwarebug=TYPE
Modifies the behavior of smartctl to compensate for some known and
understood device firmware bug.
-P TYPE, --presets=TYPE
Specifies whether smartctl should use any preset options that are
available for this drive.
OFFLINE TEST AND SELF-TEST オプション
-t TEST, --test=TEST
Note that only one test type can be run at a time, so only one test type
should be specified per command line.
-C, --captive
Runs self-tests in captive mode.
3.5.1.4 raidtools
raidtools は、S/W RAID 構成向けのコマンドが用意されている。以下はコマンド一覧で
- 3-107 -
ある。実行例として、実行例として、raidhotadd の使い方を示す。raidhotadd は、障害発
生後、RAID 構成を戻すときに使用するコマンドである。
表 3.5-3 raidtools に含まれているコマンド一覧
detect_multipath – md デバイスを検出する。
detect_multipath [OPTION...]
図 3.5-4 detect_multipath 書式
表 3.5-4 detect_multipath オプション
-v, --verbose
Print out extra information
-s, --superblock
Print out only those devices that already have a valid multipath raid superblock
-n, --new
Print out only those devices that don't have a valid multipath superblock
--usage
Display brief usage message
lsraid - md デバイスの状態確認を表示する。
lsraid -A [-g|-s|-f] {-a <device> | -d <device>} ...
lsraid -A -p
lsraid -D [-l] {-a <device> | -d <device>} ...
lsraid -D -p
lsraid -R {-a <device> | -d <device>} ...
lsraid -R -p
lsraid -h
lsraid –V
図 3.5-5 lsraid 書式
表 3.5-5 lsraid オプション
-A
Selects array-based operation
-a <device>
Adds md device <device> to the list of devices to query.
-D
Selects disk-based operation.
-d <device>
Adds block device <device> to the list of devices to query.
-f
Displays only failed block devices in array-based mode (-A).
-g
Displays only good block devices in array-based mode (-A).
-l
Displays a long dump of block device superblocks in disk-based
mode(-D).
-p
Scans all block devices in /proc/partitions for RAID arrays.
-R
Selects raidtab operation.
-s
Displays only spare block devices in array-based mode
- 3-108 -
(-A).
mkraid – md デバイスを作成する。
mkraid [--configfile] [--version] [--force] [--upgrade] [-cvfu] </dev/md?>+
図 3.5-6 mkraid 書式
表 3.5-6 mkraid オプション
-c, --configfile filename
Use filename as the configuration file (/etc/raidtab is used by default).
-f, --force
Initialize
the
consituent devices, even if they appear to have data on them
already
-o, --upgrade
This option upgrades older arrays to the current kernel's RAID version,
without destroying data.
raid0run – raid0/LINEAR を起動させる。
raid0run [--configfile] [--version] [--force] [--upgrade] [-acvfuv] </dev/md?>+
図 3.5-7 raid0run 書式
表 3.5-7 raid0run オプション
-c, --configfile filename
Use filename as the configuration file (/etc/raidtab is used by default).
-a, --all
Starts up all nonpersistent RAID0 and LINEAR arrays defined in raidtab.
raidhotadd – md デバイスにディスクを追加する。
raidhotadd [--all] [--configfile] [--help] [--version] [-achv] </dev/md?>*
図 3.5-8 raidhotadd 書式
# raidhotadd /dev/md1 /dev/hdb2
図 3.5-9 raidhotadd 実行例
raidhotremove – md デバイスからディスクを外す。
raidhotremove [--all] [--configfile] [--help] [--version] [-achv] </dev/md?>
図 3.5-10 raidhotremove 書式
# raidhotremove /dev/md1 /dev/hdb2
図 3.5-11 raidhotremove 実行例
raidreconf – raid 構成を変更する。
- 3-109 -
raidreconf -o oldraidtab -n newraidtab -m /dev/md?
raidreconf -i /dev/sd? -n newraidtab -m /dev/md?
raidreconf -n newraidtab -m /dev/md? -e /dev/sd??
図 3.5-12 raidreconf 書式
表 3.5-8 raidreconf オプション
-o {--old} oldraidtab
Specifies the path name of the
old
(current)
{--new} newraidtab
Specifies the
-m {--mddev} /dev/md?
Specifies the name of the raid array to modify.
-i {--import} /dev/sd??
Specifies the name of the device to import from.
-e {--export} /dev/sd??
Specifies the name of the device to export to.
raidtab.
path name of the new raidtab.
raidsetfaulty – md デバイスの無効にする。
raidsetfaulty [--all] [--configfile] [--help] [--version] [-achv] </dev/md?>*
図 3.5-13 raidsetfaulty 書式
raidstart/ raidstop – md デバイスの開始、停止をする。
raidstart [options] <raiddevice>*
raidstop [options] <raiddevice>*
図 3.5-14 mdstart/mdstop 書式
3.5.1.5 mdadm
mdadm は md デバイスの作成,管理,監視するためのプログラムである。
Linux の S/W RAID は md (Multiple Devices) デバイスドライバとして実装されている。
現状 Linux ではリニア md デバイス,RAID 0 (ストライピング),RAID 1 (ミラーリング),
RAID 4,RAID 5,RAID 6 そしてマルチパス(MULTIPATH) がサポートされている。以
下に、S/W RAID を監視するツールをインストールする方法を示す。
rpm -ivh /var/src/rpm/RPMS/i586/mdadm-1.12.0-1.i586.rpm
図 3.5-15 mdadm インストール
表 3.5-9 mdadm 書式
Assemble モード
mdadm --assemble <RAID Device> <Options, ArrayDevices>...
mdadm --assemble --scan <RAID Device, Options>...
mdadm --assemble --scan options...
Build モード
mdadm --build <RAID Device> --chunk=X --level=Y --RAID Devices=<Array
- 3-110 -
Devices>
mdadm --create <RAID Device> --chunk=X --level=Y --RAID Devices=<Array
Create モード
devices>
mdadm <RAID Device> <Options>... <Array Devices>..
Manage モード
表 3.5-10 mdadm で指定できるオプション
モード
Assemble
作成されたアレイの構成情報を元に 1 つのアクティブアレイを編成する
Build
デバイスごとのスーパブロックをもたない古いタイプのレガシーアレイを作成する。
Create
デバイスごとのスーパブロックをもつアレイを作成する
Manage
スペアデバイスを追加することができ、欠陥のあるデバイスをアレイから外すなどの管
理を行う
Misc
個々のデバイスに対して様々な操作を行う
Follow
md デバイスをモニタし、状態変化を検出して指定したアクションを起こさせる
or Monitor
オプション
-A, --assemble
存在していたアレイを編成する。
-B, --build
スーパブロックをもたないアレイ(レガシーアレイ)を作る
-C, --create
アレイの新規作成を行う
-Q, --query
md デバイスや md アレイの構成デバイスについての情報を表示する
-D, --detail
1 つまたは複数の md デバイスの詳細な情報を表示する
-E, --examine
1 つまたは複数のデバイスの md スーパブロックの内容を表示する
-F, --follow,
モニタモードを選択する
--monitor
-b, --brief
概要表示。 これは --detail や --examine と共に用いられる
-c, --config=
コンフィグファイルの指定。 デフォルトは /etc/mdadm.conf
-s, --scan
不足情報を補うためにコンフィグファイルか /proc/mdstat をスキャンする
Create/ Build モードのオプション
-c, --chunk=
処理単位をキロバイトで指定する
--rounding=
リニアアレイにおける丸め係数を指定
-l, --level=
RAID のレベルを指定する
--create において指定できる値は次の通り。
linear, RAID0, 0, stripe, RAID1, 1, mirror, RAID4, 4, RAID5, 5, RAID6, 6, multipath,
mp
-p, --parity=
RAID 5 のパリティ生成アルゴリズムを指定する。 指定できる値は次の通り
left-asymmetric, left-symmetric, right-asymmetric, right-symmetric, la, ra, ls, rs
デフォルトは left-symmetric
- 3-111 -
-n, --raid-devices=
アレイ内のアクティブなデバイスの数
-x,
アレイに対するスペアデバイスの数
--spare-devices=
スペアは後から追加したり外したりできる
-z, --size=
RAID 1/4/5 における各ドライブの使用容量をキロバイトで指定
Assemble モード
-u, --uuid=
編成するアレイの uuid を指定する
-m, --super-minor=
作成されるアレイのマイナーデバイス番号を指定する
-f, --force
スーパブロックが古くてもアレイの作成を行う。
-R, --run
アレイを構成するドライブの数が必要数に満たなくてもアレイを起動させる
-U, --update=
アレイ編成時、各デバイスのスーパブロックを更新する
Manage モードのオプション
-a, --add
指定されたデバイス(群)を、アレイを止めずに追加
-r, --remove
指定されたデバイス(群)を削除する
-f, --fail
指定されたデバイス(群)に対し、不良であることを示すマークを付ける
Misc モードのオプション:
-R, --run
部分的に構成されたアレイを起動させる。
-S, --stop
アレイを非アクティブにし、すべてのリソースを開放する
-o, --readonly
アレイに読取り専用マークを付ける。
-w, --readwrite
アレイに読書き可マークを付ける。
--zero-superblock
デバイスが有効な md スーパブロックをもつ場合、その内容をゼロで上書きする
Monitor モードのオプション
-p,--program, -alert
イベントを検出した時に起動するプログラムを指定する
-d, --delay
md アレイの状態をポーリングする周期を秒で指定する
デフォルトは 60 秒
-f, --daemonise
mdadm がモニタ動作を行う場合、バックグラウンドデーモンとする
-1, --oneshot
アレイのチェックを 1 回だけ行う
mdadm コマンドにて、RAID 構成を確認する。
# mdadm -Q --detail /dev/md0
/dev/md0:
Version : 00.90.01
Creation Time : Tue Aug 30 15:25:24 2005
Raid Level : raid5
Array Size : 20964608 (19.99 GiB 21.47 GB)
Device Size : 10482304 (10.00 GiB 10.73 GB)
Raid Devices : 3
Total Devices : 2
Preferred Minor : 0
Persistence : Superblock is persistent
- 3-112 -
Update Time : Wed Sep
7 12:47:07 2005
State : clean, degraded
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Layout : left-asymmetric
Chunk Size : 64K
UUID : 863caab1:854a897f:3fc0053a:c5e50c4d
Events : 0.57253
Number
Major
Minor
RaidDevice State
0
3
2
0
active sync
1
0
0
-
removed
2
22
65
2
active sync
/dev/hda2
/dev/hdd1
図 3.5-16 mdadm 実行例
3.5.1.6 LVM2
LVM は、カーネル 2.4 からサポートされた強力なディスク管理機能であり、カーネル
2.6 では根本的な設計の見直しが行われ、LVM2(Logical Volume Manager Version2)へ
とバージョンアップしている。LVM を利用すると物理的に複数のハードディスクをグルー
プ化して 1 つの論理的なディスクに見せることができる。論理的なディスクには、SCSI、
IDE などのインターフェースに関係なく仮想的なディスクを作成することができる。
pvcreate – フィジカルボリュームの作成
pvcreate [-d|--debug] [-f[f]|--force [--force]] [-y|--yes] [-h|--help] [-t|--test]
[--labelsector] [-M|--metadatatypetype] [--metadatacopies#copies]
[--restorefilefile]
[--setphysicalvolumesizesize]
[--version]
[PhysicalVolume...]
図 3.5-17 pvcreate 書式
表 3.5-11 pvcreate オプション
オプション
- 3-113 -
[-v|--verbose]
[--metadatasizesize]
PhysicalVolume
-f, --force
Force the creation without any confirmation.
-u, --uuid uuid
Specify the uuid for the device.
-y, --yes
Answer yes to all questions.
METADATA オプション
--metadatasize
The approximate amount of space to be set aside
size
for each meta data area.
--metadatacopies
The number of metadata areas to set aside on each
copies
PV.
--restorefile file
By default the PV is labelled with an LVM2 identifier
--labelsector sector
in its second sector (sector 1).
Overrides the automatically-detected size of the PV.
--setphysicalvolumesize size
pvdisplay – フィジカルボリュームの表示
vdisplay
[-c/--colon]
[-d/--debug]
[-h/-?/--help]
[-s/--short]
[-v[v]/--verbose
[--verbose]]
PhysicalVolumePath [PhysicalVolumePath...]
図 3.5-18 pvdisplay 書式
表 3.5-12 pvdisplay オプション
-c, --colon
Generate colon separated output for easier parsing in scripts or programs.
-s, --short
Only display the size of the given physical volumes.
-m, --maps
Display the mapping of physical extents to logical volumes and logical extents.
vgcreate -ボリュームグループの作成
vgcreate
[--addtag
Tag]
[-l|--maxlogicalvolumes
[-A|--autobackup
{y|n}]
MaxLogicalVolumes]
[-p|--maxphysicalvolumes
MaxPhysicalVolumes]
[-d|--debug]
[-h|--help]
[-M|--meta-datatypetype]
[-s|--physicalextentsize
PhysicalExtentSize[kKmMgGtT]] [-t|--test] [-v|--verbose] [--version] VolumeGroupName
PhysicalVolumePath [PhysicalVolumePath...]
図 3.5-19 vgcreate 書式
表 3.5-13 vgcreate オプション
-A, --autobackup {y|n}
Controls automatic backup of VG metadata after the change.
-l, --maxlogicalvolumes
Sets the maximum possible logical volume count.
MaxLogicalVolumes
-p,--maxphysicalvolumes MaxPhysicalVolumes
Sets the maximum possible physical volume count.
-s,--physicalextentsize
Sets the physical extent size on physical volumes of this volume
- 3-114 -
group.
PhysicalExtentSize[kKmMgGtT]
vgdisplay – ボリュームグループの表示
vgdisplay
[-A|--activevolumegroups]
[-c|--colon]
[-d|--debug]
[-h|--help]
[--ignorelockingfailure] [-P|--partial] [-s|--short] [-v[v]|--verbose [--verbose]] [--version]
[VolumeGroupName...]
図 3.5-20 vgdisplay 書式
表 3.5-14 vgdisplay オプション
-A, --activevolumegroups
Only select the active volume groups.
-c, --colon
Generate colon separated output for easier parsing in scripts or
programs.
Give a short listing showing the existence of volume groups.
-s, --short
lvcreate -ロジカルボリュームの作成
lvcreate [--addtag Tag] [-A/--autobackup y/n] [-C/--contiguous y/n] [-d/--debug] [-h/-?/--help]
[-i/--stripes Stripes [-I/--stripesize StripeSize]] {-l/--extents LogicalExtentsNumber | -L/--size
LogicalVolumeSize[kKmMgGtT]}
[-M/--persistent
y/n]
[--minorminor]
[-n/--name
LogicalVolumeName] [-p/--permission r/rw] [-r/--readahead ReadAheadSectors] [-t/--test]
[-v/--verbose] [-Z/--zero y/n] VolumeGroupName [PhysicalVolumePath...]
lvcreate {-l/--extents LogicalExtentsNumber | -size LogicalVolumeSize[kKmMgGtT]}
[-c/--chunksize
ChunkSize]
-s/--snapshot
-n/--name
SnapshotLogicalVolumeName
OriginalLogicalVolumePath
図 3.5-21 lvcreate 書式
表 3.5-15 lvcreate オプション
-c, --chunksize ChunkSize
Power of 2 chunk size for the snapshot logical volume between
4k and 1024k.
-C, --contiguous y/n
Sets or resets the contiguous allocation policy for logical
volumes.
-i, --stripes Stripes
Gives the number of stripes. This is equal to the number of
physical volumes to scatter the logical volume.
-I, --stripesize StripeSize
Gives the number of kilobytes for the granularity of the stripes.
-l,
Gives the number of logical extents to allocate for the new
--extents LogicalExtentsNumber
logical volume.
-L,
Gives the size to allocate for the new logical
- 3-115 -
volume.
--size LogicalVolumeSize[kKmMgGtT]
--minor minor
Set the minor number.
-n, --name LogicalVolumeName
The name for the new logical volume.
-p, --permission r/w
Set access permissions to read only or read and write.
-r, --readahead ReadAheadSectors
Set read ahead sector count of this logical volume to a value
between 2 and 120.
Create a snapshot logical volume for an
-s, --snapshot
existing, so called
original logical volume.
Controls zeroing of the first KB of data in the new logical
-Z, --zero y/n
volume.
lvdisplay – ロジカルボリュームの表示
lvdisplay
[-c/--colon]
[-d/--debug]
[-h/-?/--help]
[--ignorelockingfailure]
[--maps]
[-P/--partial] [-v/--verbose] LogicalVolumePath [LogicalVolumePath...]
図 3.5-22 lvdisplay 書式
表 3.5-16 lvdisplay オプション
-c, --colon
Deprecated.
To be replaced with a more-powerful reporting tool.
-m, --maps
Display the mapping of logical extents to physical volumes and physical
extents.
vgextend -ボリュームグループにフィジカルボリュームの追加
vgextend
[-A/--autobackup
y/n]
[-d/--debug]
[-h/-?/--help]
[-t/--test]
[-v/--verbose]
VolumeGroupName PhysicalDevicePath [PhysicalDevicePath...]
図 3.5-23 vgxtend 書式
lvextend -ロジカルボリュームのサイズの拡大
lvextend [-A/--autobackup y/n] [-d/--debug] [-h/-?/--help] [-i/--stripes Stripes [-I/--stripesize
StripeSize]]
{-l/--extents
[+]LogicalExtentsNumber
[+]LogicalVolumeSize[kKmMgGtT]}
[-t/--test]
[-v/--verbose]
|
-L/--size
LogicalVolumePath
[PhysicalVolumePath...]
図 3.5-24 lvextend 書式
表 3.5-17 lvextend オプション
-l, --extents [+]LogicalExtentsNumber
Extend or set the logical volume size in units of logical
extents.
-L,
Extend or set the logical volume size in units in units of
- 3-116 -
--size [+]LogicalVolumeSize[kKmMgGtT]
megabytes.
-i, --stripes Stripes
Gives the number of stripes for the extension.
-I, --stripesize StripeSize
Gives the number of kilobytes for the
granularity of the
stripes.
3.5.2 H/W RAID 5/1 評価環境
H/W RAID 構成環境において、ディスク障害を発生させた時の OS の挙動を監視し、障
害状態から回復する手順を確認する。
3.5.2.1 ハードウェア構成
以下に H/W RAID5/1 の検証を行なった環境を示す。
表 3.5-18 H/W RAID5/1 検証環境
ハード
CPU
Athlon64 3500+
メモリ
1GB
RIAD カード
SCSI RAID2200S
HDD
UltraSCSI 320 36GB x 3
表 3.5-19 H/W RAID5/1 構成時のパーティション情報
パーティション(sda)
/
10GB
swap
1GB
/home
10GB
今回の環境では、H/W RAID 5/1 のディスクアサインは、/dev/sda となる。
3.5.2.2 ソフトウェア構成
Kernel2.6 を採用している Turbolinux 10 Server を使用して評価を行なった。使用した
ソフトウェア構成は以下の通り。
表 3.5-20 ソフトウェア構成
ディストリビューション
Turbolinux 10 Server
Kernel
2.6.8-5
StorageManager
2.10
Swatch
3.1.1-1
StorageManager、mdadm、は別途環インストールした為、以降に構築方法を示す。
swatch はネットワーク環境構築を参照。
3.5.2.3 Storage Manager のインストール/設定
Linux 版 Storage Manager は、OSS ツールではないが、RAID カードを購入すると添付
- 3-117 -
CD に収められている。モジュールは、RPM パッケージで提供されているので、インスト
ールは簡単にできる。添付 CD に収録されている Storage Manager をインストール、起動
までの手順を以下に記す。
CD に収録されているパッケージをインストールする。
#rpm –ivh StorMan-2.10.i386.rpm
図 3.5-25 Storage Manager のインストール
Storage Manager には、監視デーモンが必要であり、常時、store_agent を起動しておく必
要がある。
# /etc/init.d/store_agent start
もしくは、
#chkconfig store_agent on
図 3.5-26 監視デーモンの起動
Storage Manager は、日本語表示が出来ないため、監視ツールを立ち上げる前に、
“LANG=C”と設定する必要がある。
# export LANG=C
# /usr/StoreMan/StoreMan.sh
図 3.5-27 Storage Manager の起動
正常時稼動状態
正常稼動中の Storage Manager のイメージ(Storage Manager 画面)を添付する。
- 3-118 -
図 3.5-28 Storage Manager 画面
Storage Manager の設定
障害発生時、mail にて通知する為の設定を行なう。この設定を行なうことにより障害発
生通知が行えるようになる。(これ以外の設定は、とくにする必要はない。)
1.
通知設定
Local system をクリックし、Actions から、Agent actions を選び Configure 選択する。
下図“通知設定”の画面が表示されたら、Email Notifications タブを選択する。
- 3-119 -
図 3.5-29 通知設定
2.
Email Notifications の設定
同ウィンドより、Email Notificationsのタブを選択し、ツールバーにあるAdd email
recipientボタンを押し、下図 “送信先情報登録”が表示される。初期設定時、SMTPサーバ
設定が表示される。表示されたら、SMTPサーバのアドレスと、返信先のメールアドレスを
入力する。入力例としてSMTPには、”192.168.0.1”,”gateway.hoge.net”などを入力する。
Reply to email address には、”[email protected]”, “[email protected]” など入力す
る(任意により設定可能)。
入力例) localhost,
192.168.255.10 等と設定する
入力例) root, admin
などを設定する
図 3.5-30 SMTP サーバ設定
- 3-120 -
Recipient name には、任意の名前を入力し、Email address には、障害報告通知を出した
いアドレスを入力し、add ボタンを押すことにより、障害発生時に発信されるメールの送信
先の設定が終了する。
任意の名称を入力する
入力例) root, admin
障害報告通知を送信したいユ
ーザアカウントを入力する。
入力例) root, admin
図 3.5-31 送信先情報登録
Event type には、以下の 3 種類を選択することが出来る。
表 3.5-21Eventtype で選択できるオプション
Error
障害のみ
Error, Warning
障害、警告のみ
Error, Warning, Information
障害、警告、情報
登録後、メールの送信テストを行なう。Actions をクリックし Send test message を選択す
る。エラーが表示されなかったら、送信されているものとする。
3.5.2.4 H/W RAID 5/1 機能検証項目
H/W RAID 環境下において、I/F ケーブルを引き抜き、擬似的なディスク I/O 障害を発生
させ、OS の挙動を確認し、ディスクを入れ換えて、自動再構築されることを確認する。
3.5.2.5 H/W RAID 5/1 機能検証手順
稼動中にディスクの I/F ケーブルを抜き、擬似障害を発生させる。擬似障害発生時に
Storage Manager から通知される内容を確認した後、ディスクを交換して、再構成される
ことを確認する。その際、Storage Manager で表示される情報を変化も監視する。
3.5.2.6 H/W RAID 5/1 機能評価結果と考察
障害発生時には、ボードが持っている障害検知機能(アラーム音)により、障害が発生した
事がわかる。また、製品の添付 CD に収録されている Storage Manager の併用使用により
メールによる障害報告を受けることができるため、常時監視を行わなくても障害発生時に
- 3-121 -
は、メールによる通知によって、障害発生を知ることができた。また、ディスクを交換す
る事により自動で RAID の再構成が行なわれることも確認できた。H/W RAID は障害検知、
復旧までをインターフェースボードがサポートしている場合が多く、
後に述べる S/W RAID
の様にシステム管理者がコマンド操作で、それらの操作を行う必要は少ない。
3.5.3 S/W RAID 5/1 ディスク評価環境
S/W RAID 構成環境において、ディスク障害を発生させた時の OS の挙動を監視し、障害
状態から回復する手順を確認する。
3.5.3.1 ハードウェア構成
以下に S/W RAID5/1 の検証を行なった環境を示す。
表 3.5-22 S/W RAID5/1 検証環境
ハード
CPU
Athlon64 3500+
メモリ
1GB
HDD
IDE 80GB x 3~2
表 3.5-23 S/W RAID5 構成時のパーティション情報
パーティション(had)
パーティション(hdb)
パーティション(hdc)
/boot
64MB
/
10GB
/home
10GB
swap
1GB
/
10GB
/home
10GB
/
10GB
/home
10GB
表 3.5-24 S/W RAID1 構成時のパーティション情報
パーティション(had)
パーティション(hdb)
/
10GB
/home
10GB
swap
1GB
/
10GB
/home
10GB
S/W RAID 5/1 環境でのディスクアサインは、/dev/md0,/dev/md1 となる。
3.5.3.2 ソフトウェア構成
Kernel2.6 を採用している Turbolinux 10 Server を使用して評価を行なった。使用した
- 3-122 -
ソフトウェア構成を示す。
表 3.5-25 ソフトウェア構成
ディストリビューション
Turbolinux 10 Server
kernel
2.6.8-5
smartmontools
5.33-1
lvm2
2.00.20-6
raidtools
1.00.3-2
mdadm
1.12.0-1
df
5.2.1
swatch
3.1.1-1
swatch はネットワーク環境構築を参照。
3.5.3.3 smartmontools
smartmontools をインストールする。
# rpm –ivh /var/src/rpm/RPMS/i586/smartmontools-5.33-1.i586.rpm
図 3.5-32 smartmontools のインストール
smartmontools を起動する前に、設定ファイル(/etc/smartd.conf)にて、監視するデバイス
の設定を行い、サービスを起動する。表 3.5-11 は、/dev/md0,md1.md2 を監視し、ヘルス
チェックを root ユーザへ情報を送信する。という設定を行なっている。
/etc/smartd.conf 抜粋
# A very silent check.
Only report SMART health status if it fails
# But send an email in this case
#/dev/hdc -H -m [email protected]
/dev/md0 -H -m root
/dev/md1 -H -m root
/dev/md2 -H -m root
図 3.5-33 smartd.conf 設定例
smartd の起動することにより、監視を開始できる。
・監視用デーモンの開始
# /etc/init.d/smartd start
・監視用デーモンの常時起動設定
# chkconfig smartd on
図 3.5-34 smartmontools の監視デーモン起動
- 3-123 -
3.5.3.4 S/W RAID 5/1 機能検証項目
S/W RAID 環境下において、I/F ケーブルを引き抜き、擬似的なディスク I/O 障害を発生
させて、OS の挙動を調べる事とする。また、故障を想定してディスクの交換後、raidtools
を使用して、再構成される事を確認する。
3.5.3.5 S/W RAID 5/1 機能検証手順
稼動中にディスクの I/F ケーブルを抜き、擬似障害を発生させる。擬似障害発生後の
swatch 監視から通知される内容と、OS の挙動を確かめる。
S/W RAID に関しては、システムを一旦停止し、ディスクを入換え、raidhotadd コマンド
にて、再構成が行えることを確認する。
3.5.3.6 S/W RAID 5/1 機能評価結果と考察
H/W RAID に比べ、障害発生時に障害検出することはできないが、OSS ツールの組み合
わせ(swatch, smartmontools 等)により、障害検知を行うことは可能である。障害発生後は、
mdadm, raidhotadd コマンドを利用する事により、RAID 構成を復元することが出来る。
S/W RAID は、H/W RAID 程、コストをかけずに RAID 構成を組めるというメリットもあ
るが、デメリットとして、障害発生後のディスク交換時に、システムを停止するが必要が
ある。
3.5.4 LVM 機能評価環境
ディスク障害を発生させた時の OS の挙動を監視し、障害状態から回復する手順を確認す
る。LVM 構成にディスク障害を発生させた時の OS の挙動を監視し、復旧手順の確立をす
る。
3.5.4.1 ハードウェア構成
以下に LVM の検証を行なった環境を示す。
表 3.5-26 LVM 検証環境
ハード
CPU
Athlon64 3500+
メモリ
1GB
HDD
IDE 80GB x 2
表 3.5-27 LVM 構成時のパーティション情報
パ ー テ ィ シ ョ ン (hda)
パーティション(hdb)
/
10GB
swap
1GB
LVM
10GB
- 3-124 -
3.5.4.2 ソフトウェア構成
Kernel2.6 を採用している Turbolinux 10 Server を使用して評価を行なった。使用した
ソフトウェア構成を示す
表 3.5-28 ソフトウェア構成
ディストリビューション
Turbolinux 10 Server
kernel
2.6.8-5
LVM2
2.00
swatch
3.1.1-1
swatch はネットワーク環境構築を参照。
3.5.4.3 ロジカルボリュームの作成
ロジカルボリュームは、仮想ディスク上に作成されたパーティションを指す。ロジカル
ボリュームは通常パーティションと同様にマウントして使用できる。作成手順は以下に示
す 。 モ ジ ュ ー ル の 読 み 込 み と デ バ イ ス 作 成 を 行 な う 。 LVM の 設 定 を 行 な う 場 合 、
Device-Mapper と dm-snapshot のモジュールを読み込む。正常に読込まれたかを、lsmod
コマンドで確認する。
# modprobe dm-mod
# modprobe dm-snapshot
図 3.5-35 Device-Mapper 読込みコマンド
# lsmod
Module
Size
dm_snapshot
14876
dm_mod
48252
Used by
0
4 dm_mirror,dm_snapshot
図 3.5-36 Device-Mapper 読込み結果
“Device-Mapper 読込み結果”内で下線が引かれている情報が表示されていれば、LVM に必
要なモジュールが正しく読み込みこめていると判断できる。確認の後、Device-Mapper が
使用するデバイスファイル(/dev/mapper/control)を作成する。Turbolinux 10 Server の場合、
devmap_mknod.sh を実行することによりデバイスファイルが作成される。
# /sbin/devmap_mknod.sh
Creating /dev/mapper/control character device with major:10 minor:63.
図 3.5-37 Device-Mapper 作成スクリプト
LVM で管理できるパーティション(Linux LVM)を作成する。LVM 用パーティションの作成
は通常(FDISK)の操作と同じである。LVM で管理できるパーティションへの変更は、ファ
イルシステムタイプを、Linux LVM(8e)に変更することで利用できる。
- 3-125 -
# fdisk /dev/hdb
The number of cylinders for this disk is set to 119150.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): p
Disk /dev/hdb: 61.4 GB, 61492838400 bytes
16 heads, 63 sectors/track, 119150 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Device Boot
Start
End
Blocks
Id
System
/dev/hdb1
1
19842
10000336+
83
Linux
/dev/hdb2
19843
39684
10000368
83
Linux
Command (m for help): t
Partition number (1-4): 1
Hex code (type L to list codes): 8e
Changed system type of partition 1 to 8e (Linux LVM)
Command (m for help): t
Partition number (1-4): 2
Hex code (type L to list codes): 8e
Changed system type of partition 2 to 8e (Linux LVM)
Command (m for help): p
Disk /dev/hdb: 61.4 GB, 61492838400 bytes
16 heads, 63 sectors/track, 119150 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Device Boot
Start
End
Blocks
Id
System
/dev/hdb1
1
19842
10000336+
8e
Linux LVM
/dev/hdb2
19843
39684
10000368
8e
Linux LVM
Command (m for help): w
図 3.5-38 /dev/hda4 を Linux LVM に設定
- 3-126 -
次にフィジカルボリュームの作成を行なう。pvcreate コマンドにて、LVM で使用可能な物
理パーティションを作成することができる。確認方法は、pvdisplay コマンドにて情報の確
認可能である。
# pvcreate /dev/hdb1
Physical volume "/dev/hdb1" successfully created
図 3.5-39 pvcreate によるフィジカルボリュームの作成
作成結果を、pvdisplay で確認する。
# pvdisplay
--- NEW Physical volume --PV Name
/dev/hdb1
VG Name
PV Size
9.54 GB
Allocatable
NO
PE Size (KByte)
0
Total PE
0
Free PE
0
Allocated PE
0
PV UUID
IAnMKc-BJFE-q7Rt-13iq-cnwv-fkVW-6HwmAP
図 3.5-40 フィジカルボリュームの確認
フィジカルボリューム作成後に、仮想ディスクとなるボリュームグループを作成可能とな
る。作成には、vgcreate コマンドで作成することができる。作成結果は、vgdisplay コマン
ドで確認することができる。
# vgcreate vg_01 /dev/hdb1
Volume group "vg_01" successfully created
図 3.5-41 ボリュームグループの作成
作成結果を、vgdisplay で確認する。
# vgdisplay
--- Volume group --VG Name
vg_01
System ID
Format
lvm2
Metadata Areas
1
Metadata Sequence No
1
VG Access
read/write
VG Status
resizable
MAX LV
0
- 3-127 -
Cur LV
0
Open LV
0
Max PV
0
Cur PV
1
Act PV
1
VG Size
9.54 GB
PE Size
4.00 MB
Total PE
2441
Alloc PE / Size
0 / 0
Free
2441 / 9.54 GB
PE / Size
VG UUID
zIUKkt-iX2e-iu5C-MY6m-szUX-axi9-7XhHAt
図 3.5-42 ボリュームグループの確認
作成したボリュームグループ上にロジカルボリュームを作成する。作成後、lvdisplay にて
構成確認を行なう。
# lvcreate -L 4G -n lv01 vg_01
Logical volume "lv_01" created
図 3.5-43 ロジカルボリュームの作成
# lvdisplay
--- Logical volume --LV Name
/dev/vg_01/lv01
VG Name
vg_01
LV UUID
b06gne-048G-ysTU-XoTS-glVI-mbiK-oOc3Uc
LV Write Access
read/write
LV Status
available
# open
0
LV Size
4.00 GB
Current LE
1024
Segments
1
Allocation
inherit
Read ahead sectors
0
Block device
253:3
図 3.5-44 lvdisplay
作成したロジカルボリューム上にファイルシステムを作成する。ファイルシステムの作成
には、mkfs コマンドを使用する。ファイルシステム作成後、mount コマンドにてマウント
し、df コマンドでマウントされている確認を行なうことを勧める。
# mkfs.ext3 /dev/vg_01/lv01
- 3-128 -
mke2fs 1.35 (28-Feb-2004)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
524288 inodes, 1048576 blocks
52428 blocks (5.00%) reserved for the super user
First data block=0
32 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 27 mounts or
180 days, whichever comes first.
Use tune2fs -c or -i to override.
図 3.5-45 ロジカルボリュームの初期化
# mount /dev/vg_01/lv01 /mnt/lvm/
# df
Filesystem
1K-blocks
/dev/hda1
10317828
Used Available Use% Mounted on
5174084
4619628
32828
3885908
53% /
/dev/mapper/vg_01-lv01
4128448
1% /mnt/lvm
図 3.5-46 ロジカルボリュームのマウント
3.5.4.4 スナップショットの作成
スナップショットを作成する事により、選択した LVM 領域のコピーを作成する事ができ
る。
# lvcreate -s -L 4G -n snap01 /dev/vg_01/lv01
Logical volume "snap01" created
図 3.5-47 スナップショット作成
- 3-129 -
結果は lvdisplay にて確認することができる。
# lvdisplay
--- Logical volume --LV Name
/dev/vg_01/snap01
VG Name
vg_01
LV UUID
b06gne-048G-ysTU-XoTS-glVI-mbiK-oOc3Uc
LV Write Access
read/write
LV snapshot status
active destination for /dev/vg_01/lv01
LV Status
available
# open
0
LV Size
4.00 GB
Current LE
1024
Segments
1
Snapshot chunk size
8.00 KB
Allocated to snapshot
0.00%
Allocation
inherit
Read ahead sectors
0
Block device
253:3
図 3.5-48 ロジカルボリュームの構成確認
3.5.4.5 構成変更
LVM はディスクの増設による領域拡張に柔軟に対応する事ができる。追加ディスクを
LVM として定義し、pvcreate にてフィジカルボリュームとする。作業を行なう場合、
umount する必要がある。
# pvcreate /dev/hdc1
Physical volume "/dev/hdc1" successfully created
図 3.5-49 新規フィジカルボリュームの作成
追加分のフィジカルボリュームを既存のボリュームグループに追加する。これは、vgextend
コマンドにて追加することができる。
# vgextend vg_01 /dev/hdc1
Volume group "vg_01" successfully extended
図 3.5-50 既存ボリュームグループに新規フィジカルボリュームを追加
ボリュームサイズが増えたことを vgdisplay コマンドにて確認する。下線が引かれている
VG Size に違いがある事を確認する。
- 3-130 -
表 3.5-29 ボリュームグループの状況
# vgdisplay
# vgdisplay
--- Volume group --VG Name
--- Volume group --vg_01
VG Name
System ID
vg_01
System ID
Format
lvm2
Format
lvm2
Metadata Areas
1
Metadata Areas
2
Metadata Sequence No
4
Metadata Sequence No
5
VG Access
read/write
VG Access
read/write
VG Status
resizable
VG Status
resizable
MAX LV
0
MAX LV
0
Cur LV
2
Cur LV
2
Open LV
0
Open LV
0
Max PV
0
Max PV
0
Cur PV
1
Cur PV
2
Act PV
1
Act PV
2
VG Size
9.54 GB
VG Size
12.55 GB
PE Size
4.00 MB
PE Size
4.00 MB
Total PE
2443
Total PE
3212
Alloc PE / Size
2048 / 8.00 GB
Alloc PE / Size
2048 / 8.00 GB
Free
395 / 1.54 GB
Free
1164 / 4.55 GB
PE / Size
PE / Size
既存ロジカルボリュームのサイズを変更する。
# lvextend -L 11G /dev/vg_01/lv01
Extending logical volume lv01 to 11.00 GB
Logical volume lv01 successfully resized
図 3.5-51 ロジカルボリュームのサイズ変更
アンマウントし、フォーマットを行なう。
# umount /mnt/lvm/
# mkfs.ext3 /dev/vg_01/lv01
mke2fs 1.35 (28-Feb-2004)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
1441792 inodes, 2883584 blocks
144179 blocks (5.00%) reserved for the super user
- 3-131 -
First data block=0
88 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information:done
図 3.5-52 構成変更後のフォーマット
再度、マウントし容量が増えた事を確認する。
# mount /dev/vg_01/lv01 /mnt/lvm
# df
Filesystem
1K-ブロック
使用
使用可 使用% マウント位置
/dev/hda1
10317828
2932188
6861524
/dev/hda3
9851340
32916
9318000
30% /
1% /home
/dev/mapper/vg_01-lv01
11353328
32828
10743784
1% /mnt/lvm*
図 3.5-53 構成変更後確認
*/mnt/lvm は任意で作成したマウントポイントである。
3.5.4.6 LVM 機能検証項目
LVM 環境下において、I/F ケーブルを引き抜き、擬似的なディスク I/O を行えない状況
下において OS の挙動を調べる事とする。その際、復旧する手順についても検証する。
3.5.4.7 LVM 機能検証手順
稼動中にディスクの I/F ケーブルを抜き、擬似障害を発生させる。擬似障害発生後の
swatch 監視から通知される内容と、OS の挙動を確かめる。環境復旧時に何が問題となる
のか要因を調べ、対処法を確立する。
3.5.4.8 LVM 機能評価結果と考察
LVM 構成下において障害が発生した場合、RAID のようなミラーリング機能は備わって
いない為、記録されている情報の保守が必要になるが、LVM に実装されているスナップシ
- 3-132 -
ョット等の機能を使いこなすことにより、万が一の状況を未然に防ぐことができる。実際、
スナップショットを利用したバックアップを利用した大型 non-stop システムを運用してい
る実例もある。通常使用される ext3,ext2 のファイルシステムに比べ、環境構築に費やす時
間は多いが、運用開始以後のメンテナンス性、拡張性には優れたものがある為に使いやす
い機能であると思われる。
- 3-133 -
3.6 ダンプツールの評価
3.6.1 ダンプ採取ツール
diskdump、netdump、LKCD、kdump、mkdumpのダンプ採取ツールの紹介を行った
後、3.6.1.6 でダンプ採取ツールの比較を行い、3.6.1.7 でダンプ採取ツールの考察を行う。
3.6.1.1 diskdump
■ 概要
diskdump は富士通社が開発したダンプ採取方法であり、障害時にクラッシュダンプを
ディスク上に採取する仕組みである。この機能を使用するためには、カーネルに含まれ
る SCSI ドライバに修正が必要となるが、 Red Hat linux のディストリビューションは
標準で diskdump 機能が組み込まれており、カーネル再生成を行うことなく使用するこ
とができる。
採取されたダンプファイルは、crash、lcrash、Alicia ユーティリティで解析可能である。
尚、crash を使用する場合は、デバッグオプション付のカーネルを作成する必要がある。
http://sourceforge.net/projects/lkdump/
■ インストール環境
kernel 2.6.9-11.EL
カーネル
マシン アーキテクチャー i386
OS
DELL
PowerEdge 2600
Red Hat Enterprise Linux AS 4 update1
メモリ
2GB
■ 対応ダンプ編集ツール
crash、lcrash、Alicia
■ 導入手順
(1) インストールされている diskdump の確認
# rpm -qa |grep diskdump
diskdumputils-1.0.1-5
(2) ディスクの準備
diskdump の採取先として使用できるのは、以下のドライバを使用するディスクで
ある。
aic7xxx、aic79xx、mpt fusion、megaraid、ata_piix、sata_promise
(3) ダンプパーティションの作成
- 3-134 -
ダンプの採取先として用意したディスク上に、搭載メモリの 1.5 倍程度のダンプパ
ーティションを作成する。ここでは/dev/sdb1 を diskdump 用のパーティションと
する。
(4) ダンプデバイスの設定
/etc/sysconfig/diskdump を修正し、ダンプデバイス名を記述する。
DEVICE=/dev/sdb1
(5) ダンプデバイスの初期化
/etc/sysconfig/diskdump に登録したパーティションを dump disk 形式にフォーマ
ットするために、以下のコマンドを実行する。
# service diskdump initialformat
(6) diskdump サービスの開始
以下のコマンドを実行する。これにより、diskdump サービスがシステム起動時に
起動されるようになる。
# chkconfig diskdump on
以下のコマンドを実行し、diskdump サービスを起動する。
# service diskdump start
ファイル/proc/diskdump が作られ、ダンプデバイスの情報が記述されていれば、起
動は正常に完了している。
# cat /proc/diskdump
/dev/sdb1 63 39086082
■ 動作確認
(1) SysRq マジックキーの有効化
# echo 1 > /proc/sys/kernel/sysrq
(2) ダンプの採取
# echo c > /proc/sysrq-trigger
ダンプ採取後、halt される。
(3) ダンプファイルの確認
ダ ン プ は 、 サ ー バ 側 に /var/crash/ ク ラ イ ア ン ト I P ア ド レ ス - 採 取 日 時
( 例 :/var/crash/192.168.0.2-2005-09-09-21:59) フ ォ ル ダ が 作 成 さ れ そ の 中 に
vmcore ファイルとして保存される。
- 3-135 -
3.6.1.2 netdump
■ 概要
netdump は Red Hat 社が提供するクラッシュダンプをネットワーク経由で採取する為
の仕組みである。Red Hat Linux および、MIRACLE LINUX(V3.0SP1 以降)では標
準で対応されている。ダンプを取得するクライアントとダンプデータをネットワーク経
由で受け取って保存するサーバで構成され、クライアント/サーバ形式をとる。
採取されたダンプファイルは、crash、lcrash、Alicia ユーティリティで解析可能である。
尚、crash を使用する場合は、デバッグオプション付のカーネルを作成する必要がある。
■ インストール環境
<クライアント>
kernel 2.6.9-11.ELsmp
カーネル
マシン アーキテクチャー i386
OS
DELL
PowerEdge 2600
Red Hat Enterprise Linux AS 4 update1
メモリ
2GB
<サーバ>
カーネル
kernel 2.6.9-11.EL
マシン アーキテクチャー i386
OS
DELL
OptiPlex GX270
Red Hat Enterprise Linux AS 4 update1
メモリ
512MB
■ 対応ダンプ編集ツール
crash、lcrash、Alicia
■ 導入手順(サーバ)
(1) インストールパッケージの確認
netdump を行うサーバとクライアント間では ssh による認証を行う。また、
netdump-server は ssh-server と依存関係を持つ為、事前に ssh が導入されている
必要がある。
# rpm -qa |grep ssh-server
openssh-server-3.9p1-8.RHEL4.4
# rpm -qa |grep netdump-server
netdump-server-0.7.7-3
パッケージが導入されていない場合には、CD 等よりパッケージの導入を行う。
(2) パスワード設定
netdump-server の導入を行うと自動的に作成される netdump ユーザのパスワード
設定を行う。このパスワードはクライアントの認証を行う際に必要となる。
- 3-136 -
# passwd netdump
Changing password for user netdump.
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully.
(3) サービスの起動確認
ssh および netdump-server のサービスを手動にて起動し正常に起動できているか
ログを確認する。
# service sshd start
Starting sshd:
[ OK ]
# service netdump-server start
Starting netdump-server
[ OK ]
# tail /var/log/messages
(途中 略)
Sep
9 21:10:38 rhas4u1ipa sshd:
succeeded
Sep
9 21:10:45 rhas4u1ipa netdump-server: netdump-server startup succeeded
(4) サービス自動起動の設定
手動によりサービスの起動が確認できたら、再起動後にサービスが自動起動するよう設
定する。
# chkconfig sshd on
# chkconfig netdump on
# chkconfig –list sshd
sshd
0:off
1:off
2:on
3:on
4:on
5:on
6:off
# chkconfig –list netdump-server
netdump-server
0:off
1:off
2:on
3:on
4:on
5:on
6:off
■ 導入手順(クライアント)
(1) インストールされているパッケージの確認
# rpm -qa |grep netdump
netdump-0.7.7-3
パッケージが導入されていない場合には、CD 等よりパッケージの導入を行う。
(2) 設定ファイルの編集
/etc/sysconfig/netdump を修正しダンプの送信に使用する NIC および送信先(サー
バ)の IP アドレスを設定する。
DEV=eth0
- 3-137 -
NETDUMPADDR=192.168.0.4
NETDUMPADDR には IP アドレスを指定する。ネームサーバ等による名前解決は
利用できない為サーバのホスト名を指定することはできない。
(3) DSA 公開鍵の設定
netdump-server に DSA 公開鍵を登録する。以下の操作を行う前にクライアントと
サーバをネットワーク接続し、サーバ側で netdump-server の設定およびサービス
の起動を行っておく必要がある。
# service netdump propagate
[email protected]’s password:XXXXXXXXXXXXX
nn.nn.nn.nn にはサーバの IP アドレスが表示される。
XXXXXXXXXX にサーバで設定した netdump ユーザのパスワードを入力する。
(4) サービスの起動
netdump のサービスを手動にて起動し正常に起動できているかログを確認する。
# service netdump start
initializing netdump
[ OK ]
initializing netconsole local IP nn.nn.nn.nn
[ OK ]
# tail /var/log/messages
(途中 略)
Sep
9 21:28:57 rhas4u1ipa netdump: initializing netdump succeeded
Sep
9 21:28:57 rhas4u1ipa netdump: initializing netconsole succeeded
Sep
9 21:28:57 rhas4u1ipa kernel: netconsole: network logging started
(5) サービス自動起動の設定
手動によりサービスの起動が確認できたら、再起動後にサービスが自動起動するよう設
定する。
# chkconfig netdump on
# chkconfig –list netdump
netdump
0:off
1:off
2:on
3:on
4:on
5:on
6:off
■ 動作確認
(1) SysRq マジックキーの有効化
# echo 1 > /proc/sys/kernel/sysrq
(2) ダンプの採取
# echo c > /proc/sysrq-trigger
ダンプはネットワーク経由でサーバに転送される。ダンプ採取が終了するとクライ
アントは自動的にリブートされる。
- 3-138 -
(3) ダンプファイルの確認
ダ ン プ は 、 サ ー バ 側 に /var/crash/ ク ラ イ ア ン ト I P ア ド レ ス - 採 取 日 時
(例:/var/crash/192.168.0.2-2005-09-09-21:59)フォルダが作成されその中に vmcore
ファイルとして保存される。
- 3-139 -
3.6.1.3 LKCD
■ 概要
LKCD(Linux Kernel Crash Dump)は、メモリダンプ採取機能およびメモリダンプ
解析ツール(lcrash ユーティリティ)の提供を目的とし、米国 SGI 社で開発され GPL
ライセンスで公開された。その後、IBM 社、NEC 社、日立社、富士通社共同で拡張が
行われている。
MIRACLE LINUX V3.0 をインストールした場合、最小構成でも LKCD がインストー
ルされる。
http://lkcd.sourceforge.net/
■ インストール環境
カーネル
kernel 2.4.21-20.19AXsmp
マシン アーキテクチャー i386
OS
DELL
PowerEdge 2600
MIRACLE LINUX V3.0
2GB
メモリ
■ 対応ダンプ編集ツール
crash、lcrash、Alicia
■ 導入手順
(1) インストールされている LKCD の確認
# rpm -qa | grep lkcd
lkcdutils-4.2-10AX
lkcdutils-devel-4.2-10AX
(2) ダンプパーティションの作成
ダンプの採取先として用意したディスク上に、搭載メモリの 1.5 倍程度のダンプパ
ーティションを作成する。
領域確保後、/dev/vmdump にシンボリックリンクを張る。ここでは、/dev/sdb1 を
ダンプ用のパーティションとする。デフォルトのスワップ・パーティションをダン
プの吐き出し口にすることにより、システムのブートが早くなる。
# ln -s /dev/sdb1 /dev/vmdump
(3) LKCD の設定
/etc/sysconfig/dump を修正し LKCD の設定を行う。
DUMP_ACTIVE=1
DUMPDEV=/dev/vmdump
DUMPDIR=/var/log/dump
- 3-140 -
DUMP_SAVE=1
DUMP_LEVEL=8
DUMP_FLAGS=0x80000000 # disruptive disk dump is default for 2.4
DUMP_COMPRESS=2
PANIC_TIMEOUT=5
・ DUMP_ACTIVE
⇒ LKCD が稼動中かを示すパラメータ。デフォルトは”1”。
“1”
----
LKCD は稼動中
“0”
---- LKCD は非稼動
・ DUMPDEV
⇒
メモリ内容を保存するデバイスを示すパラメータ。デフォルトは
/dev/vmdump/dev/vmdump はシンボリックリンクとなっており、デフォルトでは
スワップ・デバイスがリンク先となっている。
・ DUMPDIR
⇒
ダンプ保存先ディレクトリを示すパラメータ。デフォルトは/var/log/dump。
・ DUMP_SAVE
⇒
ダンプ採取と crash レポート(ダンプのサマリ表示)の設定を示すパラメー
タ。デフォルトでは”1”。
“1”
---- ダンプ採取と crash レポート作成を行う。
“1” 以外 ----
crash レポート作成のみを行う。
・ DUMP_LEVEL
⇒
ダンプ採取領域を示すパラメータ。デフォルトは”8”。
“0” (DUMP_NONE)
----
ダンプ採取は行わない。
“1” (DUMP_HEADER) ----
先頭 128byte のダンプヘッダを採取。
“2” (DUMP_KERN)
----
ダンプヘッダ+使用カーネルページを採取。
“4” (DUMP_USER)
----
ダンプヘッダ+使用カーネルページ+
ユーザページを採取。
“8” (DUMP_ALL)
----
全て(未使用カーネルページも含め)採取。
・ DUMP_FLAGS
⇒
ダンプ採取後のリブートアクションを示すパラメータ。デフォルトは”0”。
“0” (DUMP_FLAG_NONE)
----
“1” (DUMP_FLAGS_NONDISRUPT) ----
- 3-141 -
リブートを行う。
リブートを行わない。
・ DUMP_COMPRESS
⇒
ダンプの圧縮機能を示すパラメータ。デフォルトは”2”。
“0” (DUMP_COMPRESS_NONE)
----
圧縮を行わない。
“1” (DUMP_COMPRESS_RLE)
----
RLE 圧縮を行う。
“2” (DUMP_COMPRESS_GZIP)
----
GZIP 圧縮を行う。
・ PANIC_TIMEOUT
⇒
ダンプ採取終了後のカーネルのアクションを示すパラメータ。デフォルト
は”5”。
“0”
“0” 以外
----
カーネルはスピンループのまま。(リブートを行わない)
---- ダンプ採取後、指定された秒数待ってからリブートを行う。
(4) LKCD 設定ファイルの反映
設定ファイルを反映させるために、以下のコマンドを実行する。
# lkcd config
(5) ダンプ保存ディレクトリの内容
LKCD の設定パラメータである DUMPDIR で示されたダンプ保存ディレクトリは、
・ ダンプファイルディレクトリ(DUMPDIR/xxx ⇒ xxx は数字で表される)
・ bounds ファイル
で構成される。bounds ファイルには、次にダンプファイルを保存する際に使用する
数字が含まれている。例えば、bounds ファイルの内容が『1』で、カーネルパニッ
クが発生した場合、ダンプ採取後は/var/log/dump/1 ディレクトリ内にダンプファイ
ルが保存される。このとき bounds ファイルの内容は『2』となっている。
次にダンプファイルディレクトリに保存される内容を示す。”n”は作成されたディレ
クトリ(=数字)を表している。
・ dump.n
⇒
crash ダンプファイル(LKCD 形式)
・ kerntypes.n
⇒
Linux カーネルのデータ構造が含まれているファイル。(Binary 形式)
Kerntypes ファイルは通常 Linux カーネルをコンパイルしたときに作成され、/boot
ディレクトリに Kerntypes-2.4.21-20.19AXsmp として保存される。
kerntypes.n ファイルはこの Kerntypes-2.4.21-20.19AXsmp ファイルのコピーと
なっている。
(例) /boot/Kerntypes-2.4.21-20.19AXsmp -> Kerntypes.n
- 3-142 -
・ map.n
⇒
Linux カーネルのシンボルテーブル(外部参照)が含まれているファイル。
(Text
形式)
map ファイルは通常、Linux Kernel をコンパイルしたときに作成され、/boot ディ
レクトリに System.map-2.4.21-20.19AXsmp として保存される。map.n ファイル
はこのファイルのコピーとなっている。
(例) /boot/System.map-2.4.21-20.19AXsmp -> map.n
・ analysis.n
⇒
自動的に作成される Crash レポートファイル。(Text 形式)
・ lcrash.n
⇒
/sbin にある lcrash ユーティリティのコピー。(Binary 形式)
■ 動作確認
(1) SysRq マジックキーの有効化
# echo 1 > /proc/sys/kernel/sysrq
(2) ダンプの採取
# echo c > /proc/sysrq-trigger
ダンプ採取後、PANIC_TIMEOUT パラメータ値が 0 以外の場合、リブートされる。
(3) ダンプファイルの確認
/var/log/dump ディレクトリ以下に保存されたファイルを確認する。
- 3-143 -
3.6.1.4 kdump
■ 概要
kexec は、システム再起動時に時間がかかるファームウェアやブートローダの手順を介
さずに、高速にリブートさせ、別のカーネルを起動させることができる。この kexec の
機能を使用して、障害が発生した時に、ダンプ採取用カーネルを起動させ、障害が発生
したメモリ空間にアクセスすることを可能にしたのが kdump である。
以下の手順では、障害が発生し、ダンプを採取される側のカーネルをファーストカー
ネル、ダンプを採取する側のカーネルをセカンドカーネルとして説明している。セカ
ンドカーネルは、ファーストカーネル起動後、kexec コマンドによりメモリ空間にロー
ドされる。ファーストカーネル クラッシュ時に、セカンドカーネルが起動される。
http://lse.sourceforge.net/kdump/
■ インストール環境
カーネル
kernel 2.6.13
マシン アーキテクチャー i386
OS
DELL
PowerEdge 2600
Red Hat Enterprise Linux AS 4 update1
メモリ
2GB
■ 対応ダンプ編集ツール
gdb
■ 導入手順
(1) ファイルのコピー
次のファイルをダウンロードし、任意のディレクトリにコピーする。
・ kexec-tool のソース
kexec-tools-1.101.tar.gz
・ kdump 用パッチ
kexec-tools-1.101-kdump.patch
・ カーネルソース
linux-2.6.13.tar.bz2
(2) kexec-tool に kdump のパッチを適用しインストール
# tar zxvf kexec-tools-1.101.tar.gz
# patch -p0 < kexec-tools-1.101-kdump.patch
# cd <kexec-toolを導入したディレクトリ>
# ./configure
# make
# make install
(3) Kernel 2.6.13 を展開
# tar jxvf linux-2.6.13.tar.bz2
- 3-144 -
(4) ファーストカーネルの生成
# make menuconfig
Processor type and features
--->
[*] kexec system call (EXPERIMENTAL)
(0x100000) Physical address where the kernel is loaded
File systems
--->
Pseudo filesystems
--->
[*] sysfs file system support
# make
# make modules_install
# make install
/boot/grub/menu.lst を修正し crashkernel パラメータを追加する。
title Red Hat Enterprise Linux AS (2.6.13)
root (hd0,0)
kernel /vmlinuz-2.6.13 ro root=LABEL=/ rhgb quiet crashkernel=64M@16M
initrd /initrd-2.6.13.img
ここで、crashkernel パラメータの 64M はセカンドカーネル用に確保するメモリ容
量であり、16M は確保するメモリ領域の最初のアドレスである。
設定完了後リブートしファーストカーネルを起動する。
# reboot
起動後、カーネルが 2.6.13 であることを確認する。
# uname –r
2.6.13
(5) セカンドカーネルの生成
# make menuconfig
Processor type and features
--->
[ ] Symmetric multi-processing support
[*] Local APIC support on uniprocessors
[*]
IO-APIC support on uniprocessors
[*] kernel crash dumps (EXPERIMENTAL)
(0x1000000) Physical address where the kernel is loaded
File systems
--->
Pseudo filesystems
[*]
セカンドカーネル起動時に
--->
/proc/vmcore support (EXPERIMENTAL)
[*] /dev file system support (OBSOLETE)
- 3-145 -
“Warning: unable to open an
initial console.” が出力される
場合の対応
Device Drivers
--->
SCSI device support
--->
今回は MPT SCSI デバイス
<*> SCSI device support
<*>
を使用している為この設定
SCSI disk support
Fusion MPT device support
--->
を行っている。
<*> Fusion MPT (base + ScsiHost) drivers
# make
# make
vmlinux
注意:kexec –p で使用されるセカンドカーネルには、vmlinux image を使用する。
bzImage は使用できない。
(6) kexec の実行
ファーストカーネルがカーネルパニックになった時に起動されるダンプ採取用セ
カンドカーネルを kexec コマンドでロードする。
# kexec -p ./vmlinux-2.6.13-2nd --crashdump --args-linux --append="root=/dev/sdb1 init
1 irqpool"
ここで指定している vmlinux-2.6.13-2nd は、(5)で作成したセカンドカーネルの
vmlinux image である。
(7) /dev/console の追加
セカンドカーネル起動時に"Warning: unable to open an initial console"と出力さ
れ、画面が表示されない場合の対応として、/dev/console を静的に作成する。
# mkdir test
# mount --bind / test
# cd test/dev
# mknod -m 660 console c 5 1
# cd ../..
# umount test
# rmdir test
■ 動作確認
(1) カーネルパニックによるセカンドカーネルへの切替え
ファーストカーネルのパニックにより、ダンプ採取のためのセカンドカーネルが起
動される。
テストのため、次の入力によりカーネルパニックを発生させる。
# echo 1 >/proc/sys/kernel/sysrq
# echo c >/proc/sysrq-trigger
(2) ダンプファイルへの書き込み
- 3-146 -
起動されたセカンドカーネルからは、二つのフォーマットで、クラッシュしたメモ
リ空間にアクセスすることが出来る。
・elf format
・raw format
# cp
/proc/vmcore
/proc/vmcore
/dev/oldmem
<dump-file>
コピーしたダンプファイルは、-g オプションで生成した vmlinux を使用して gdb
で解析することができる。また、このダンプファイルは、crash には対応されてい
ない。
linux-2.6.13/Documentation/kdump/に 、 gdb マ ク ロ gdbmacros.txt が あ り 、
bttnobp,btt,btpid,trapinfo などが追加されている。
[実行例]
# gdb ./vmlinux ./vmcore --command=gdbmacros.txt
#0
0xc011543c in crash_get_current_regs (regs=0xf6e81ef4)
at arch/i386/kernel/crash.c:102
102
regs->eip = (unsigned long)current_text_addr();
(gdb) bttnobp
pid 1; comm init:
===================
__alloc_pages + 617 in section .text
schedule_timeout + 82 in section .text
process_timeout in section .text
do_select + 880 in section .text
copy_to_user + 98 in section .text
cp_new_stat64 + 234 in section .text
__pollwait in section .text
sys_select + 744 in section .text
sysenter_past_esp + 84 in section .text
- 3-147 -
3.6.1.5 mkdump
■ 概要
mkdump(Mini Kernel Dump)はNTTデータ社、VA Linux社により開発され、kdump
と同じように障害が発生したカーネルとは別のダンプ採取用カーネル(ミニカーネル)
を使用してダンプ採取する機能である。ミニカーネルは、kexecなどをもとに開発され
ているが、kexecに対して次のような優位性がある。
・ ダンプイメージがミニカーネルにより、ディスクに書き出される。
・ ダンプフォーマット変換ツールにより、lcrashで解析が可能。
・ kexecは、セカンドカーネル起動時に、ファーストカーネルに上書きして稼動して
しまう。
障害が発生してダンプ採取される側にmkexecをロードし、パニック発生時にダンプ採
取用のミニカーネルを起動する。
http://mkdump.sourceforge.net/
■ インストール環境
カーネル
kernel 2.6.9
マシン アーキテクチャー i386
OS
DELL
PowerEdge 2600
Red Hat Enterprise Linux AS 4 update1
メモリ
2GB
■ 対応ダンプ編集ツール
crash、lcrash、Alicia
■ 導入手順
(1) ファイルのコピー
次のファイルをダウンロードし、任意のディレクトリにコピーする。
・ミニカーネルのパッチ
minik-2.6.9.-1.0.patch
・カーネルソース
linux-2.6.9.tar.bz2
・mkexec のソース
mkexec-2.6.9-1.0.taz
(2) ミニカーネルのパッチ適用
# tar jxvf linux-2.6.9.tar.bz2
# mv linux-2.6.9 linux-2.6.9-minik
# cp minik-2.6.9-1.0.patch
linux-2.6.9-minik
# cd linux-2.6.9-minik
# patch -p1 < minik-2.6.9-1.0.patch
(3) ミニカーネルの作成
- 3-148 -
# make menuconfig
General setup
--->
[*] Make dump mini kernel
[ ]
--- Run the mini kernel on PAE mode (default) (i386)
[ ] Support for paging of anonymous memory (swap)
Processor type and features
--->
[ ] Symmetric multi-processing support
Device Drivers
--->
Networking support
--->
[ ] Networking support
SCSI device support
--->
今回は MPT SCSI デバイス
<*> SCSI device support
<*>
を使用している為この設定
SCSI disk support
Fusion MPT device support
--->
を行っている。
<*> Fusion MPT (base + ScsiHost) drivers
File systems
--->
すべての項目を外し[ ]の状態にする
# make bzImage
作成したカーネルのコピー(名前を変更してコピーする。)
# cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.9-minik
# cp arch/i386/boot/compressed/vmlinux.bin /boot/vmlinux.bin-2.6.9-minik
(4) ダンプパーティションの作成
ダンプの採取先として用意したディスク上に、搭載メモリの 1.5 倍程度のダンプパ
ーティションを作成する。ここでは/dev/sdb1 をディスクダンプ用のパーティショ
ンとする。作成後、ダンプパーティションのメジャー番号とマイナー番号の確認を
行う。
# ls –l /dev/sdb1
brw-rw----
1 root disk 8, 1 Jun 24 12:59 /dev/sdb1
メジャー番号 : 8 マイナー番号 : 1 となる。
(5) /boot/grub/menu.lst の追加変更
作成したミニカーネルが正しく稼動するか確認するために、grub にミニカーネルの
項目を追加する。
title Linux-2.6.9-minik
kernel (hd0,0)/vmlinuz-2.6.9-minik mem=8M dump_dev=0x800001
dump_dev の”8”がメジャー番号、”1”がマイナー番号になる。
- 3-149 -
テストの為、ミニカーネルを起動してダンプ採取後リブートするかを確認する。
(6) mkexec のパッチ適用
# tar zxvf mkexec-2.6.9-1.0.taz
# tar jxvf linux-2.6.9.tar.bz2
# mv linux-2.6.9
linux-2.6.9-mkexec
# cd linux-2.6.9-mkexec
# patch -p1 < ../mkexec/PATCH/mkexec-v1.patch
(7) mkexec の作成
# make menuconfig
make 中に smp でエラーに
Processor type and features
--->
なる場合の対応
[ ] Symmetric multi-processing support
Device Drivers
--->
SCSI device support
make で Qlogic エラーとな
--->
SCSI low-level drivers
る場合の対応
--->
Qlogicのものすべて外す
# make ; make modules_install ; make install
設定完了後リブートし mkexec を起動する。
# reboot
起動後、カーネルが 2.6.9-mkexec であることを確認する。
# uname –r
2.6.9-mkexec
(8) mkexec.ko の作成
mkexec/kernel/Makefile.base を編集し自分の環境に合わせる。
KVER=
2.6.9-mkexec
KDIR=
<mkdumpを導入したディレクトリ>/linux-2.6.9-mkexec
KMODDIR=
/lib/modules/2.6.9-mkexec
make の準備
# cd <mkdumpを導入したディレクトリ>/mkexec
# ln -s asm-i386 include/asm
make の実行
# make ARCH=i386
- 3-150 -
mkexec/kernel/mkexec.ko が作成される。
■ 動作確認
(1) ミニカーネルダンプの実行
mkexec.ko のロード
# insmod <mkdumpを導入したディレクトリ>/mkexec/kernel/mkexec.ko
(2) ダンプを行う準備
/proc/mkexec の各項目にパラメータを入れる。
# echo 8 > /proc/mkexec/mem
# echo “0x800001” > /proc/mkexec/dumpdev
# echo “/boot/vmlinux.bin-2.6.9-minik” > /proc/mkexec/path
# echo 1 > /proc/mkexec/stats
(3) ダンプの採取
mkexec がロードされたこの状態で、カーネルパニックが発生すると、ミニカーネ
ルが実行される。
テストのために、次の入力で、ミニカーネルを実行させることができる。
# echo 2 > /proc/mkexec/stats
ダンプを実行した後、起動画面に戻り mkexec をインストールしたカーネルで正常
起動することを確認する。
(4) ダンプフォーマットの変換
ダンプパーティションに保存されたダンプを LKCD フォーマット形式のファイル
に変換する。
変換ツールの作成
# cd /usr/src
# tar zxvf mkd_conv.taz
# cd mkd_conv
# make
elf2lkcd_i386、mkd2lkcd_i386、mkd2lkcd_x86_64 が作成される。
・elf2lkcd_i386
i386 の vmcore フォーマットを LKCD フォーマットへ変換
・mkd2lkcd_i386
i386 の mkdump フォーマットを LKCD フォーマットへ変換
・mkd2lkcd_x86_64 x86_64 の mkdump フォーマットを LKCD フォーマットへ変換
ダンプフォーマットの変換実行
# ./mkd2lkcd_i386 /dev/sdb1 <dump-file>
ダンプパーティション /dev/sdb1 に保存されていたダンプがファイルに変換される。
- 3-151 -
3.6.1.6 ダンプ採取ツールの評価
前項までに記述したdiskdump、netdump、LKCD、kdump、mkdumpを実際に使用して
ダンプを採取し、その機能および操作性について評価を行った。ただし、各ダンプ採取ツ
ールの機能についてソースコードレベルでの調査は行っていない。
各ダンプ採取ツールの比較(2005年9月時点)を表 3.6-1に示す。
表 3.6-1
ダンプ採取ツールの比較(その1)
項目
2005 年 9 月時点
diskdump
netdump
LKCD
kdump
mkdump
○(update3 以
○(IA64 は
×
×
×
降)
update5 以降)
RHEL4.0
○
○
×
×
×
SLES8
×
○
○
×
×
SLES9
×
○
○
×
×
○(SP1 以降)
○
×
×
×
×
○
×
×
1.0.1-5
0.7.7-3
6.1.0
1.101
2.0
netdump
netdump
LKCD
ELF
LKCD
収録ディストリビューシ RHEL3.0
ョン
MIRACLE LINUX V3.0 ○(SP1 以降)
Turbolinux10S
最新バージョン
ダンプファイル形式
(手動変換が必
要)
対応解析ツール
採取トリガー
crash
○
○
○
×
○
lcrash
○
○
○
×
○
Alicia
○
○
○
×
○
gdb
-
-
-
○
-
oops
○
○
○
○
○
NMI watchdog
○
○
○
○
○
SysRq マ ジ ッ ク キ ー
○
○
○
○
○
実行コンテキスト
○
○
○
○
○
メモリ
○
○
○
○
○
キャッシュメモリ
×
×
×
×
×
スワップ領域
×
×
×
×
×
手動
自動
自動/手動を設定
手動
自動
(手動)
採取可能な情報
ダンプ採取による停止
後の再起動
可能
- 3-152 -
表 3.6-1
ダンプ採取ツールの比較(その2)
2005 年 9 月時点
項目
diskdump
netdump
LKCD
kdump
mkdump
ダンプファイルの
保存されるタイミ
ング
クラッシュ時にダン
プ用パーティション
にダンプイメージを
自動採取後、再起
動時に自動的に起
動されるシェルにて
解 析 ツ ール で 参 照
可能な形式に変換
して保存される。
クラッシュ時に自動
的にサーバ側への
転送が開始される。
転送完了時点でサ
ー バ の /var/crash
配下のディレ クトリ
に解析ツールで参
照可能な形式で保
存される。
クラッシュ時にダン
プ用パーティション
にダンプイメージを
自動採取後、再起
動時に自動的に起
動されるシェルにて
解析ツー ルで 参照
可能な形式に変換
して保存される。
セカンドカーネル起
動後手動にてダン
プファイルを保存す
る。
対応インタフェー
ス
以下のドライバを使
用するデバイスが
対応
以下のドライバを使
用する NIC が対応
カーネルに含まれる
ディ スク ドライ バに
は基本的に対応
カーネルに含まれる
デ ィ スク ド ライ バ に
は基本的に対応
セカンドカーネル起
動時に自動でダン
プ用パーティション
にダンプイメージを
採取。再起動後に
手動で変換 ツール
を使用して解析ツー
ルで参照可能な形
式のファイルに変換
する。
カーネルに含まれる
デ ィ スク ド ライ バ に
は基本的に対応
aic7xxx
e1000
aic79xx
tg3
mptfusion
bcm5700
Red Hat 以外のディ
ストリビューションに
はパッケージが含ま
れており、カーネル
再構築が必要な
kdump、 mkdump よ
りも設定が容易。ダ
ンプ採取後の再起
動の有無やダンプ
ファイルの圧縮保存
等を設定により変更
可能。
・ダンプイメージ採
取のために物理メ
モリサイズ以上の
領域を持つディスク
デバイスまたはパ
ーティションが必
要。スワップの情報
も採取可能である。
障害が発生したの
とは別のカーネルに
よりダンプイメ ージ
を採取するので確
実性が高い
障害が発生したの
とは別のカーネルに
よりダンプイメ ージ
を採取するので確
実性が高い
・標準で収録されて
いるディストリビュー
ションが無いのでカ
ーネルへのパッチ
適用およびカーネ
ル再構築が必要
・セカンドカーネル
起動後に手動にて
操作を行う必要が
る。
・標準で収録されて
いるディストリビュー
ションが無いのでカ
ーネルへのパッチ
適用およびカーネ
ル再構築が必要
・LSI53C1030 チップ
を使用した SCSI カ
ードでダンプが採取
できない現象が発
生しているが、原因
不明。
megaraid
ata_pix
特徴
留意点
sata_promise
Red Hat, MIRACLE
LINUX にはパッケ
ージが含まれてお
り、カーネル再構
築が必要な
kdump、mkdump よ
りも設定が容易
・ダンプイメージ採
取の為に物理メモリ
サイズ以上の領域
を持つディスクデバ
イスまたはパーティ
ションが必要。
・対応インタフェース
に記載したドライバ
を使用するディスク
以外は採取できな
い。
Red Hat, MIRACLE
LINUX にはパッケ
ージが含まれてお
り、カーネル再構
築 が 必 要 な
kdump、mkdump よ
りも設定が容易
・ダンプを採取する
マシンとは別にダン
プを保存する為の
サーバが必要とな
る。
・ NIC ド ラ イ バ が
netdump に対応して
いる必要がある。
・Teaming を行って
いる NIC は dump 送
信用としては使用で
きない。
・ network 経 由 で
UDP プロトコルにて
転送されるので転
送中にデータを喪
失する可能性があ
る。
- 3-153 -
■対応ディストリビューションによる比較
kdump および mkdump は標準で対応しているディストリビューションが現時点では
無い。したがってダンプ採取を行う為にはカーネルへのパッチの適用とカーネル再生成
が必要となる。LKCD は SLES(SUSE Linux Enterprise Server)、MIRACLE LINUX、
Turbolinux が対応しており、diskdump、netdump は RHEL、ML3.0 SP1 が対応して
いる。
■対応解析ツールによる比較
kdump は crash、lcrash では解析することができず、gdb での解析となる。それ以外
のダンプ採取ツールで採取したダンプファイルはダンプ解析ツール crash または
lcrash で解析することが可能である。(Alicia は内部的に crash、lcrash のどちらもラ
ッピングしており、kdump 以外の全てに使用可能である。)
■採取トリガーによる比較
いずれのダンプ採取ツールも oops、NMI、SysRq マジックキーのいずれかをトリガー
としてダンプ採取が可能である。
■採取可能な情報
いずれのダンプ採取ツールでも実行コンテキスト、メモリ等についての情報採取が可
能である。
■ダンプ採取後の再起動
mkdump、netdump はダンプ採取後自動的にカーネルが再起動される。
kdump はセカンドカーネルが起動した状態でコンソールからの操作待ちの状態とな
るため、手動によるダンプ採取後に再起動が必要である。
diskdump は、ダンプイメージをディスクへ出力した後、halt にて停止した状態とな
るため、手動による再起動が必要である。
LKCD は設定により、ダンプ採取後に自動で再起動を行うか否かを設定可能である。
■ダンプファイルの保存されるタイミング
netdump はクラッシュ時にダンプ解析ツールで参照可能な形式でダンプファイルが保
存される。
diskdump 、LKCD はクラッシュ時にダンプイメージがディスクに書き込まれ、再起動
時にダンプ解析ツールで参照可能な形式に変換されて保存される。
mkdump はクラッシュ後のセカンドカーネル起動時にダンプイメージがディスクに採
取される。再起動後に手動にてファイル形式変換ツールによりダンプ解析ツールで参照
可能な形式に変換する必要がある
kdump はクラッシュ後のセカンドカーネル起動時に自動でダンプの採取は行わない為、
セカンドカーネルが起動した状態で手動にてダンプファイルを保存する必要がある。
- 3-154 -
■対応インタフェースによる比較
kdump、mkdump、LKCD は基本的にカーネルに含まれるディスクのドライバに対応
している。
diskdump は diskdump 対応コードの入ったドライバを使用するディスクのみダンプ
採取が可能である。
netdump は netdump 対応ドライバを使用する NIC 経由でのみダンプ採取が可能であ
る。
3.6.1.7 ダンプ採取ツールの考察
ダンプ採取ツールを選択するにあたってはいくつかの基準が考えられる。この項では、
3.6.1.6項で述べた比較を元に、それらの基準のうち、ダンプ採取の確実性、採取ツール導
入の容易性、ダンプ採取の容易性、ダンプ採取後の再起動の有無といった点について考察
を行う。尚、各項目の見出し後の括弧内には3.6.1.6項の表3.6-1で関連する項目を記した。
■ダンプ採取の確実性 (ダンプファイルの保存されるタイミング、特徴)
障害発生時にメモリダンプが確実に採取できるかどうか、また採取した内容が信頼で
きるか否かをダンプ採取に使用するカーネルの点から考える。
kdump および mkdump は、クラッシュ発生時にダンプ採取の為のカーネル(セカン
ドカーネル)をそれまで稼働していたカーネル(ファーストカーネル)とは別のメモリ
空間に展開し、そのセカンドカーネルの制御によりダンプ採取を行う。これに対して、
diskdump、netdump、LKCD は、クラッシュが発生したカーネル自身の制御のもとに
ダンプ採取を行う。
セカンドカーネルを使用する方法は、
“ダンプを採取するような状況に陥ったカーネル
自身をダンプ採取のために使用する”という diskdump、netdump、LKCD の仕組みが
持つ構造的な問題を回避するのに有効な方法であり、現時点で存在する Linux のカーネ
ルダンプ採取としては、ダンプ採取の確実性および採取したダンプ内容の信頼性を高め
るという点で、セカンドカーネルを使用する kdump、mkdump に圧倒的な優位性が認
められる。
■ダンプ採取ツール導入の容易性
(収録ディストリビューション、留意点)
セカンドカーネルを使用する方法は、現在の主なディストリビューションが標準で対
応していない。その為、kdump および mkdump を使用するためにはユーザもしくはユ
ーザサポートを行うベンダが、パッチの適用およびカーネル再生成を行いシステムに適
用する必要がある。また、ユーザがカーネルにダンプ採取用のパッチを適用して使用す
ると、カーネルに起因する障害が発生した場合にディストリビューション・ベンダのサ
ポートが受けられなくなる事も考えられる。
このような点を考慮すると、セカンドカーネルを使用する方法はダンプ採取ツールの
機能としての利点は大きいが、Linux をシステムの一部として使用するユーザの立場か
ら見れば導入は容易ではない。これに対し diskdump、netdump、LKCD は標準で各デ
ィストリビューションが対応しており、パッケージの導入および設定方法も kdump、
- 3-155 -
mkdump に比較して容易である。
■ダンプ採取の容易性 (ダンプの保存されるタイミング、留意点)
ユーザ環境でシステムが稼働している状態でカーネルがクラッシュした場合を考え
ると、ダンプ採取の確実性と同時に、ダンプが容易に採取できる事。つまりダンプ採取
の容易性にも注目する必要がある。この点では、mkdump、LKCD、diskdump、netdump
は障害発生時に手動の操作を必要とせずに自動的にダンプが採取されるためダンプ採取
は容易だといえる。これに対し、kdump はクラッシュ時にセカンドカーネルが起動して
コンソールからの入力が可能となった時点で、手動でダンプ採取を行う必要がある。
kdump の今後の改善を期待したい。
■ダンプ採取後の再起動
(ダンプ採取による停止後の再起動)
ダンプ採取ツールの動作を考える時に、ダンプを採取するまでの動作とともに、ダン
プ採取後にカーネルが自動で再起動されるか否かは大きな運用ポイントとなる。
システムとしての復旧を最優先しダウンタイムを極力短くしたいシステムにおいては、
ダンプ採取後に速やかにカーネル再起動を行い、業務を再開することが求められる。ハ
ードウェアが原因の場合、再起動を行っても再度クラッシュが発生して結果的に最初の
障害発生時のダンプを消失するような事も考えられる。
このようにダンプ採取後に再起動するのが適当か否かは、システムの使用目的や冗長
構成の有無、障害発生原因がハードウェアによるものかソフトウェアによるものなのか
により異なる為、ダンプ採取ツールに求められる機能としては LKCD のようにダンプ採
取後の自動的な再起動の有無を設定により選択可能とすることが望ましい。このような
機能は、LKCD が実運用を強く意識して開発されたことを示すものであり、他のダンプ
採取ツールにも、是非反映させたい機能である。
表 3.6-2 ダンプ採取ツールの比較・考察
項目
diskdump
netdump
LKCD
kdump
mkdump
ダンプの確実性
×
×
×
○
○
ダンプ採取ツール導入の
○
○
○
×
×
○
△
○
×
○
○
×
○
容易性
ダンプ採取の容易性
(サーバが必要)
ダンプ採取後の再起動
△
○
(手動再起動)
■今後の方向性
今後ミッションクリティカルな分野において Linux を使用する機会は増大し、障害発
- 3-156 -
生時にダンプを採取することの重要性はますます高まっていくと考えられる。ミッショ
ンクリティカル環境では、セカンドカーネルによるダンプ採取が必須である、各ディス
トリビューションがそれをサポートする事によってダンプ採取ツール導入の容易性を高
める事が必要である。また、ミッションクリティカルに特化して考えるならば、ダンプ
採取にカーネルの機能を使用する現在のソフトウェア的なアプローチとは別に、メイン
フレーム等が持つハードウェア的な仕組みをエンタープライズサーバの必須機能として
組み込み、メモリダンプ採取を確実に行えるようにする方法等も、今後、検討の余地が
あるだろう。
- 3-157 -
3.6.2 ダンプ解析ツール
3.6.2.1 ツール概要
今回、調査対象としたダンプ解析ツールの概要を次に示す。
■crash
crash は、UNIX の crash ツールのインターフェースをベースに作成されたツールである。
ライブメモリ(稼動中のメモリ)、netdump/diskdump で採取されたカーネルダンプ、
LKCD (Linux Kernel Crash Dump)で採取されたカーネルダンプに対応している。
GDB(GNU Debugger)をラッピングしているため、GDB のコマンドも実行でき、また、
コマンドラインには GNU Readline を採用していたり、ページャなども外部のコマンドを
利用していたりと、lcrash のように独自で全てを抱え込むという仕様にはなっていない。
また、ダンプ編集のスピードアップの考慮や、C プログラミングでの動的ライブラリによ
る拡張コマンドの追加機能も備えている。
■lcrash
lcrash は、LKCD で採取されたダンプを編集するために作成されたツールである。
最新バージョンでは、netdump フォーマットに対応したため、crash と同等のダンプの
解析が行える。
カーネルのシンボル情報を得るのにデバッグオプション付きでコンパイルされたカーネ
ルを必要としない、また、異なるアーキテクチャ上で採取されたダンプにも対応できるよ
うになっている。
独自で sial というライブラリをもち、C 言語に非常に似た記述方法で作成したスクリプ
トをインタプリタとして動かせるエンジンを持っている。
■Alicia
Aliciaは、既存のLinuxカーネルダンプ解析ツールであるcrash/lcrashをラッピングした
ダンプ解析ツールであり(Alicia version1.1.0からlcrashにも対応)、Perl Shellを実装する。
これにより、Perl言語での解析スクリプト(LDAS)の作成と実行、Alicia標準関数による
メモリの参照、既存のcrashでの解析、などが実現される。
また、作成した解析スクリプトを残し、解析者同士で共有することにより、解析時間の短
縮や、カーネル教育用の資料としても利用できる。
■mdb
mdb は、Solaris オペレーティングシステム用の汎用デバッグツールである。Solaris
8
からカーネルデバッグツールの crash は mdb に変更され、mdb は一般モジュールとカーネ
ルの双方にデバッグ可能なデバックツールとして提供された。
- 3-158 -
表 3.6-3
ダンプ解析ツール一覧
crash
lcrash
Alicia
mdb
Linux
Linux
Linux
Solaris
UNIX SVR 系の
LKCD で採取された
crash/lcrash を ラ ッ
UNIX の adb、 crash
crash ツールのインタ
ダンプを編集するた
ピングしたダンプ解
コマンドの多くを提
ーフェースをベース
めに作成されたツー
析ツール
供(Solaris
に作成されたツール
ル
解析
・ライブメモリ
・ライブメモリ
・ライブメモリ
・ライブメモリ
対象
・LKCD
・LKCD
・LKCD
・モジュール
(Linux Kernel Crash
(Linux Kernel Crash
(Linux Kernel Crash
・core ダンプ
Dump)で作成された
Dump)で作成された
Dump)で作成された
・カーネルダンプ
カーネルダンプ
カーネルダンプ
カーネルダンプ
・netdump で作成さ
・netdump フォーマ
・netdump で作成さ
れたカーネルダンプ
ットにも対応をする
れたカーネルダンプ
対応 OS
起源
8 から
crash→mdb に)
ようになった
使用可(gdb)
使用不可
使用可(crash の gdb) 使用可(mdb)
コ マ ン
50 程度(gdb(400 程
50 程度
20 程度(crash/lcrash
ド の 種
度)は含まない)
デ バ ッ
ガ
500 程度
コマンドは含まない)
類
コ マ ン
C プログラミングに
sial マクロを使用し、 Perl 言語での解析ス
mdb デバッガモジュ
ド の 拡
より新しいコマンド
C 言語に非常に似た
クリプト(LDAS)に
ール API が提供され
張
作成が可能
記述方法でコマンド
よりコマンド作成が
ており、C 言語のプロ
作成が可能
可能
グラミングによりコ
マンド作成が可能
その他
・コマンドラインには ・ダンプ編集にあたっ
・reboot に「-d」フ
GNU Readline を採
て、カーネルのシンボ
ラグを設定してシス
用。ページャなども外
ル情報を得るのにデ
テムを再起動すると、
部のコマンドを利用
バッグオプション付
カーネルが強制的に
している
きでコンパイルされ
パニック状態になり、
・ダンプ編集にあたっ
たカーネルを必要と
クラッシュダンプが
て、カーネルのシンボ
しない
保存される。
ル情報を得るのにデ ・異なるアーキテクチ
バッグオプション付
ャ上で採取されたダ
きでコンパイルされ
ンプにも対応できる
たカーネルが必要
- 3-159 -
3.6.2.2 crash/lcrash/Alicia の比較
Linuxのダンプ解析ツールであるcrash/lcrash/Aliciaをコマンドレベルで比較したのが 表
3.6-4 である。
比較に用いたバージョンは以下のとおりである。
crash
:Ver 3.8.5
lcrash
:Ver 0.9.2
Alicia
:Ver 1.1.0
表 3.6-4
crash
crash/lcrash/Alicia コマンドマッピング表
lcrash
Alicia
コメント
*
--
*
ポインタへのショートカット
!command
--
!command
シェルへのエスケープおよびコマンドを実行する
alias
--
alias
コマンド別名を設定する
ascii
--
ascii
16 進法のストリングを ASCII に変換する
bt
bt
trace
t
strace
rd
bt
trace
t
strace
rd
バックトレース(スタックトレース)を表示する
デフォルト CPU のレジスタ情報を表示する
btop
--
btop
16 進アドレスとそのページ番号に変更する
dev
--
dev
デバイスデータを表示する
dis
dis
id
dis
id
逆アセンブルを行う
print
p
pb,pd,po,px
base
eval
-p
pb,pd,po,px
base
評価をおこなう
2、8、10、16進数の値を表示する
exit
quit
q, q!
デバッガを終了する
load
extend
--
コマンドセットの拡張
sial マクロをロードする
files
--
files
オープン・ファイルを表示する
foreach
--
foreach
システムのマルチタスクへのコマンドデータの表示を指
示する
fuser
--
fuser
指定されたファイルのユーザを表示する
eval
exit
quit
q, q!
extend
- 3-160 -
crash
lcrash
Alicia
コメント
gdb
--
gdb
gdb コマンドを実行する
help
help
?
version
help
?
version
使用可能なコマンドの一覧を表示する
lcrash のバージョン情報を表示する
irq
--
irq
IRQ を表示する
kmem
--
kmem
カーネルメモリ情報を表示する
list
walk
list
walk
リンクしたリストを表示する
log
--
log
ダンプ・システム・メッセージ・バッファを表示する
mach
--
mach
マシン固有のデータを表示する
mod
module
mod
module
モジュール情報およびシンボルとデバッグするデータの
ロードをおこなう
ロードしたモジュールまたはモジュールシンボルを表示
する
mount
--
mount
マウントされているファイルシステムに関する情報を出
力する
net
--
net
ネットワーク情報を表示する
p
print
p
pb, pd, po, px
-p
pb, pd, po, px
値を表示する
ps
ps
ps
アクティブプロセスを出力する
pte
--
pte
ページテーブルエントリを変換する
ptob
--
ptob
ページフレーム番号をそのバイト値に変換する
ptov
--
ptov
16 進物理アドレスをカーネルの仮想アドレスに変換する
rd
dump
md
od
rd
dump
md
od
指定された領域の書式付きメモリーダンプを出力する
repeat
--
repeat
コマンドを繰り返す
runq
--
runq
ランキュー上のタスクを表示する
search
--
search
カーネルのアドレス空間で特定の値を検索する
set
set
deftask
set
deftask
プロセス情況または内部クラッシュ変数をセットする
デフォルトの task をセット、または、デフォルトの task
のアドレスを表示する
- 3-161 -
crash
lcrash
Alicia
コメント
sig
--
sig
タスクシグナルハンドリング
struct
--
struct
構造体の内容を表示する
swap
--
swap
スワップ情報を表示する
sym
findsym
fsym
symbol
sym
findsym
fsym
symbol
シンボルをその仮想アドレスに変換する、またはその逆
シンボリックネーム/アドレスの関連情報を表示する
sys
stat
info
main
sys
stat
info
main
システム情報を表示する
task
task
task
タスク構造の内容
timer
--
timer
タイマキューデータ
union
--
union
union 構造体の内容
vm
--
vm
仮想メモリ情報を表示する
vtop
vtop
vtop
仮想アドレスを物理アドレスに変換する
waitq
--
waitq
待機キューリスト上のタスクリストを表示する
whatis
whatis
whatis
データのシンボルテーブルまたは型情報を表示する
wr
--
wr
メモリへの書き込み
q
quit
q, q!
quit
q, q!
デバッガを終了する
--
defcpu
defcpu
デフォルトの CPU をセット、または、デフォルトの CPU
を表示する
--
history
--
コマンドヒストリーをセットまたは表示する
--
ldcmds
ldcmds
動的にライブラリをロードする
--
mktrace
mt
mktrace
mt
スタックトレースを生成する
--
mmap
mmap
mmap_list 内のエントリの関連情報を表示する
--
namelist
nmlist
namelist
nmlist
オープンしたネームリストをリストする/追加する
--
page
page
page_list 内のエントリのページ構造から関連情報を表
示する
--
report
--
crash dump report (kernel failure が起こったときのシ
ステムの状態等)を表示する
- 3-162 -
crash
lcrash
Alicia
コメント
--
savedump
savedump
ライブダンプを生成する、または、ダンプサイズを小さく
する
--
sizeof
offset
sizeof
offset
バイト単位のデータタイプのサイズを表示し、加えて、構
造体メンバへのオフセットを表示する
--
symtab
symtab
シンボルテーブル情報を追加/削除/リストする
--
unload
unload
sial マクロをアンロードする
--
vi
-- (!vi)
vi セッションを開始する
--
--
kernel
メモリ内容を参照する
--
--
get_mem
指定したアドレスの内容を参照する
--
--
get_addr
指定したカーネル変数のアドレスを参照する
--
--
get_value
指定したカーネル変数の内容を参照する
--
--
get_increment
開いているダンプのワードサイズ(バイト)を得る
--
--
less
引数を less ページャで参照する
--
--
more
引数を more ページャで参照する
--
--
list_h
環状の list_head リンクをたどりリンク上のすべての構造
体アドレス配列を返す(LDAS)
--
--
list_c
親構造体の配下の子構造体の list_head リンクをたどりリ
ンク上のすべての構造体のアドレス配列を返す(LDAS)
--
--
list_s
入力されたアドレスからの list_head リンクをたどり、リ
ンク上のすべての構造体アドレス配列を返す(LDAS)
--
--
list_foreach
入力された配列内のアドレスの構造体アドレスと特定の
メンバの値を一覧表示する(LDAS)
--
--
list_task_vma
入力されたプロセスの仮想メモリ空間を一覧表示する
(LDAS)
--
--
task_dentries
入力されたプロセスがアタッチしているすべてのファイ
ル dentry 構造体のアドレスの配列を返す(LDAS)
--
--
dentry_parents
入力された dentry の親の dentry を/(ルート)までたどり
dentry 構造体のアドレスの配列を返す(LDAS)
--
--
get_dentry
入力されたフルパスのディレクトリまたはファイルの
dentry 構造体のアドレスを返す(LDAS)
--
--
get_task
入力された PID を持つ task_struct 構造体のアドレスを返
す(LDAS)
--
--
ts
インタラクティブに task_struct 構造体のメンバの値を表
示できる(LDAS)
- 3-163 -
crash
--
lcrash
Alicia
--
report
コメント
初期解析用レポート作成を行う
コマンドレベルで crash と lcrash を比較すると crash は gdb もラッピングしておりコマ
ンド数も多く充実している。Alicia は crash/lcrash をラッピングしているため crash/lcrash
コマンドはほとんどサポート可能であり、さらに独自のコマンドが追加されている。ただ
し、起動時に crash または lcrash を選択し使用するため、一度に双方のコマンドを使用す
ることはできない。
3.6.2.3 crash/lcrash コマンドと mdb コマンドとの網羅性の比較
他の OS との比較ということで Solaris のダンプ解析ツールである mdb に対してコマン
ドレベルでの比較をおこなった。mdb は一般モジュールのデバッガを兼ねているため、コ
マンド数が非常に多い。比較を行うにあたり、mdb の全てのコマンドを対象に比較を行う
とわかりづらいため、2つの切り口で比較を行った。
一つ目として 表 3.6-5 では、crash/lcrashのコマンドが表示可能な情報をmdbがどの程度網
羅しているかという視点で比較した。
比較に用いた各ツールのバージョンは以下のとおりである。
crash
:Ver 3.8.5
lcrash
:Ver 0.9.2
mdb
:Solaris
表 3.6-5
crash
10
crash/lcrash と mdb コマンドマッピング表
lcrash
mdb
コメント
*
--
--
ポインタへのショートカット
!command
--
!command
シェルへのエスケープおよびコマンドを実行する
alias
--
--
コマンド別名を設定する
ascii
--
--
16 進法のストリングを ASCII に変換する
bt
bt
trace
t
strace
rd
stack
regs
$c、$C
バックトレース(スタックトレース)を表示する
デフォルト CPU のレジスタ情報を表示する
btop
--
--
16 進アドレスとそのページ番号に変更する
dev
--
devnames
prtconf
デバイスデータを表示する
- 3-164 -
crash
lcrash
mdb
コメント
dis
dis
id
dis
逆アセンブルを行う
eval
print
p
pb,pd,po,px
base
eval
評価をおこなう
2、8、10、16進数の値を表示する
exit
quit
q, q!
quit
デバッガを終了する
extend
load
$<<
load
コマンドセットの拡張
sial マクロをロードする
files
--
--
オープン・ファイルを表示する
foreach
--
--
システムのマルチタスクへのコマンドデータの表示を
指示する
fuser
--
--
指定されたファイルのユーザを表示する
gdb
--
--
gdb コマンドを実行する
help
help
?
version
dcmds
使用可能なコマンドの一覧を表示する
lcrash のバージョン情報を表示する
irq
--
--
IRQ を表示する
kmem
--
kmalog
kmastat
kmausers
kmem_cache
kmem_log
kmem_verify
カーネルメモリ情報を表示する
list
walk
walk
リンクしたリストを表示する
log
--
--
ダンプ・システム・メッセージ・バッファを表示する
mach
--
cpuinfo
マシン固有のデータを表示する
mod
module
ctfinfo
modinfo
modctl
モジュール情報およびシンボルとデバッグするデータ
のロードをおこなう
ロードしたモジュールまたはモジュールシンボルを表
示する
mount
--
fsinfo
マウントされているファイルシステムに関する情報を
出力する
net
--
netstat
tcpb
ネットワーク情報を表示する
- 3-165 -
crash
lcrash
mdb
コメント
p
print
p
pb, pd, po, px
--
値を表示する
ps
ps
ps
ptree
アクティブプロセスを出力する
pte
--
--
ページテーブルエントリを変換する
ptob
--
--
ページフレーム番号をそのバイト値に変換する
--
--
16 進物理アドレスをカーネルの仮想アドレスに変換す
る
rd
dump
md
od
dump
指定された領域の書式付きメモリーダンプを出力する
repeat
--
--
コマンドを繰り返す
runq
--
--
ランキュー上のタスクを表示する
search
--
kgrep
カーネルのアドレス空間で特定の値を検索する
set
set
deftask
--
プロセス情況または内部クラッシュ変数をセットする
デフォルトの task をセット、または、デフォルトの
task のアドレスを表示する
sig
--
--
タスクシグナルハンドリング
struct
--
offsetof
構造体の内容を表示する
swap
--
swapinfo
スワップ情報を表示する
sym
findsym
fsym
symbol
nm
シンボルをその仮想アドレスに変換する、またはその
逆シンボリックネーム/アドレスの関連情報を表示す
る
sys
stat
info
main
status
システム情報を表示する
task
task
task
task_entry
タスク構造の内容
timer
--
--
タイマキューデータ
union
--
offsetof
union 構造体の内容
vm
--
--
仮想メモリ情報を表示する
vtop
vtop
vtop
仮想アドレスを物理アドレスに変換する
waitq
--
queue
待機キューリスト上のタスクリストを表示する
whatis
whatis
whatis
データのシンボルテーブルまたは型情報を表示する
ptov
- 3-166 -
crash
lcrash
mdb
コメント
wr
--
--
メモリへの書き込み
q
quit
q, q!
quit
デバッガを終了する
--
defcpu
--
デフォルトの CPU をセット、または、デフォルトの
CPU を表示する
--
history
--
コマンドヒストリーをセットまたは表示する
--
ldcmds
--
動的にライブラリをロードする
--
mktrace
mt
--
スタックトレースを生成する
--
mmap
--
mmap_list 内のエントリの関連情報を表示する
--
namelist
nmlist
--
オープンしたネームリストをリストする/追加する
--
page
page
page_list 内のエントリのページ構造から関連情報を
表示する
--
report
--
crash dump report (kernel failure が起こったときの
システムの状態等)を表示する
--
savedump
--
Live dump を生成する、または、ダンプサイズを小さ
くする
--
sizeof
offset
sizeof
バイト単位のデータタイプのサイズを表示し、加えて、
構造体メンバへのオフセットを表示する
--
symtab
--
シンボルテーブル情報を追加/削除/リストする
--
unload
unload
sial マクロをアンロードする
--
vi
--
vi セッションを開始する
crash/lcrash のコマンドのほとんどは mdb にも存在するが、files(オープン中のファイ
ルの表示)/irq(IRQ 情報の表示)/runq(RUNQ 情報の表示)等 crash にしか存在しない
コマンドも存在する。また、report のように一つのコマンドで crash dump report 情報を
表示できるのは lcrash のひとつの特徴である。
操作性としては、mdb はコマンドに“::”が必要で、慣れてしまえば問題ないのかも
しれないが、crash/lcrash と比較すると使いにくく感じた。
- 3-167 -
3.6.2.4 mdb コマンドと crash/lcrash コマンドとの網羅性の比較
「表3.6-5 mdbとcrash/lcrashコマンドマッピング表」ではmdbのコマンドのうちカーネ
ルダンプ解析に使用するコマンドに対して、crash/lcrashのコマンドがどの程度網羅してい
るかという視点で比較を行った。
比較に使用した各コマンドのバージョンは「3.6.2.3 crash/lcrashコマンドとmdbコマンド
との網羅性の比較」と同一である。
表 3.6-6
区分
mdb
mdb と crash/lcrash コマンドマッピング表
crash
lcrash
コメント
(gdb)
カーネルメモ
リアロケータ
dcmd allocdby
--
--
指定されたカーネルスレッドのアドレスを使用して、その
スレッドが割り当てたメモリのリストを新しい順に出力
する
dcmd bufctl
--
--
指定された bufctl address についての bufctl 情報の要約
を出力する
dcmd findleaks
--
--
フルセットの kmem デバッギング機能が有効になってい
る場合に、カーネルクラッシュダンプ時に効率的にメモリ
ーリークを検出する
dcmd freedby
--
--
指定されたカーネルスレッドのアドレスを使用して、その
スレッドが解放したメモリのリストを新しい順に出力す
る
dcmd kgrep
search
--
カーネルアドレス空間の中で、指定されたポインタサイズ
値を含んでいるポインタ整列アドレスを検索する
dcmd kmalog
kmem
--
カーネルメモリーアロケータトランザクションログ内の
イベントを表示する
dcmd kmastat
kmem
--
カーネルメモリーアロケータキャッシュおよび仮想メモ
リ領域のリストと該当する統計を表示する
dcmd kmausers
kmem
--
カーネルメモリアロケータの現在のメモリ割り当てが中
程度あるいは多いユーザに関する情報を出力する
dcmd kmem_cache
kmem
--
指定されたアドレスに格納されている kmem_cache 構
造体、またはアクティブ kmem_cache 構造体の完全なセ
ットをフォーマットして表示する
dcmd kmem_log
kmem
--
kmem トランザクションログの完全なセットを新しい順
にソートして表示する
dcmd kmem_verify
kmem
--
指定されたアドレスに格納されている kmem_cache 構
造体、またはアクティブ kmem_cache 構造体の完全なセ
ットの完全性を検証する
dcmd vmem
--
--
指定されたアドレスに格納されている vmem 構造体、ま
たはアクティブ vmem 構造体の完全なセットをフォーマ
ットして表示する
- 3-168 -
区分
mdb
crash
lcrash
コメント
(gdb)
dcmd vmem_seg
--
--
指定されたアドレスに格納されている vmem_seg 構造体
をフォーマットして表示する
dcmd whatis
whatis
(whatis)
whatis
指定されたアドレスに関する情報をレポートする
walk allocdby
--
--
指定された kthread_t 構造体のアドレスを開始点として
使用して、当該カーネルスレッドによって行われたメモリ
割り当てに対応する bufctl 構造体のセットに対して反復
適用する
walk bufctl
--
--
指定された kmem_cache_t 構造体のアドレスを開始点と
して使用して、このキャッシュに関連し割り当てられた
bufctl のセットに対して反復適用する
walk freectl
―
--
指定された kmem_cache_t 構造体のアドレスを開始点と
して使用して、このキャッシュに関連する空き bufctl のセ
ットに対して反復適用する
walk freedby
--
--
指定された kthread_t 構造体のアドレスを開始点として
使用して、このカーネルスレッドによって行われたメモリ
割り当て解除に対応する bufctl 構造体のセットに対して
反復適用する
walk freemem
--
--
指定された kmem_cache_t 構造体のアドレスを開始点と
して使用して、このキャッシュに関連する空きバッファの
セットに対して反復適用する
walk kmem
--
--
指定された kmem_cache_t 構造体のアドレスを開始点と
して使用して、このキャッシュに関連し割り当てられたバ
ッファのセットに対して反復適用する
Walk kmem_cache
--
--
アクティブな kmem_cache_t 構造体のセットに対して反
復適用する
walk
kmem_cpu_cache
--
--
指定された kmem_cache_t 構造体のアドレスを開始点と
して使用して、このキャッシュに関連する CPU ごとの
kmem_cpu_cache_t 構造体に対して反復適用する
walk kmem_slab
--
--
指定された kmem_cache_t 構造体のアドレスを開始点と
して使用して、関連する kmem_slab_t 構造体のセットに
対して反復適用する
walk kmem_log
--
--
kmem アロケータトランザクションログに格納されてい
る bufctl のセットに対して反復適用する
walk leak
--
--
指定された bufctl 構造体のアドレスを使用して、同様な割
り当てスタックトレースを持つ、リークが発生したメモリ
ーバッファに対応する bufctl 構造体のセットに対して反
復適用する
- 3-169 -
区分
mdb
crash
lcrash
コメント
(gdb)
ファイルシス
テム
仮想メモリ
walk leakbuf
--
--
定された bufctl 構造体のアドレスを使用して、同様な割り
当てスタックトレースを持つ、リークが発生したメモリー
バッファに対応するバッファドレスのセットに対して反
復適用する
dcmd fsinfo
mount
--
マウントされているファイルシステムのテーブルを表示
する
dcmd lminfo
--
--
ロックマネージャによって登録されたアクティブネット
ワークロックを持つ vnode のテーブルを表示する
dcmd vnode2path
--
--
指定された vnode アドレスに対応するパス名を表示する
walk buf
--
--
アクティブなブロック I/O 転送構造体 (buf_t 構造体) の
セットに対して反復適用する
dcmd addr2smap
--
--
カーネルの segmap アドレス空間セグメント内の指定さ
れたアドレスに対応する smap 構造体アドレスを出力す
る
dcmd as2proc
--
--
as_t アドレス as に対応するプロセスの proc_t アドレスを
表示する
dcmd memlist
--
--
指定された memlist 構造体または既知の memlist 構造体
の1つを表示する
dcmd memstat
--
--
システム全体のメモリ使用状況の要約を表示する
dcmd page
--
page
指定された page_t のプロパティを表示する
dcmd seg
--
--
指定されたアドレス空間セグメント (seg_t アドレス) を
フォーマットして表示する
dcmd swapinfo
swap
--
アクティブな swapinfo 構造体すべて、あるいは指定され
た swapinfo 構造体についての情報を表示する
dcmd vnode2smap
--
--
指定された vnode_t アドレスおよびオフセットに対応す
る smap 構造体アドレスを出力する
walk anon
--
--
指定された anon_map 構造体のアドレスを開始点として
使用して、関連する anon 構造体のセットに対して反復適
用する
walk memlist
--
--
指定された memlist 構造体のスパンに対して反復適用す
る
walk page
--
--
すべてのシステムの page 構造体に対して反復適用する
walk seg
--
--
指定された as_t 構造体のアドレスを開始点として使用し
て、指定されたアドレス空間に関連するアドレス空間セグ
メント (seg 構造体) のセットに対して反復適用する
walk swapinfo
swap
--
アクティブな swapinfo 構造体のリストに対して反復適
用する
- 3-170 -
mdb
区分
crash
lcrash
コメント
(gdb)
CPU と デ ィ
スパッチャ
デバイスドラ
イ バ と DDI
フレームワー
ク
dcmd callout
--
--
コールアウトテーブルを表示する
dcmd class
--
--
スケジューリングクラステーブルを表示する
dcmd cpuinfo
--
--
各 CPU 上で現在実行されているスレッドのテーブルを
表示する
walk cpu
--
--
カーネル CPU 構造体のセットに対して反復適用する
dcmd
binding_hash_entry
--
--
指定されたカーネル名とメジャー番号のバインディング
ハッシュテーブルエントリ (構造体 bind) のアドレスを
使用して、ノードバインディング名、メジャー番号、およ
び次の要素へのポインタを表示する
dcmd devbindings
--
--
名前を指定されたドライバについてすべてのインスタン
スのリストを表示する
dcmd devinfo
--
--
devinfo ノードに関連するシステムプロパティ及びドライ
バプロパティを出力する
dcmd
devinfo2driver
--
--
devinfo ノードに関連するドライバ (もしあれば) の名前
を出力する
dcmd prtconf
dev
--
devinfo で指定されたデバイスノードからカーネルデバイ
スツリーを表示する
dcmd major2name
--
--
指定されたメジャー番号に該当するドライバ名を表示す
る
dcmd
modctl2devinfo
--
--
指定された modctl アドレスに対応するすべてのデバイ
スノードを出力する
dcmd name2major
--
--
指定されたデバイスドライバ名を使用して、そのメジャー
番号を表示する
dcmd
--
--
指定された softstate 状態ポインタとデバイスインスタン
ス番号を使用して、そのインスタンスのソフトの状態を表
示する
walk binding_hash
--
--
指定されたカーネルバインディングハッシュテーブルエ
ントリの配列 (構造体 bind **) のアドレスを使用して、ハ
ッシュテーブル内のすべてのエントリを調べて、各構造体
bind のアドレスを戻す
walk devinfo
--
--
最初に、指定された devinfo の親に対して反復適用し、そ
れらを最下位から世代順に戻します。次に、指定された
devinfo 自身を戻します。その次に、指定された devinfo
の子に対して、世代順に最上位から最下位まで反復適用す
る
walk
devinfo_children
--
--
最初に、指定された devinfo を戻し、次に、指定された
devinfo の子に対して、世代順に最上位から最下位まで反
復適用する
softstate
- 3-171 -
区分
mdb
crash
lcrash
コメント
(gdb)
STREAMS
walk
devinfo_parents
--
--
指定された devinfo の親に対して、世代順に最上位から最
下位まで反復適用する
walk devi_next
--
--
指定された devinfo の兄弟に対して反復適用する
walk devnames
--
--
devnames 配列のエントリに対して反復適用する
walk softstate
--
--
指定された softstate ポインタを使用して、ドライバ状態
構造体への NULL 以外のポインタをすべて表示する
walk softstate_all
--
--
指定された softstate ポインタを使用して、ドライバ状態
構造体へのポインタをすべて表示する
dcmd mblk2dblk
--
--
指定された mblk_t のアド レスを使用して、対応する
dblk_t のアドレスを出力する
dcmd mblk_verify
--
--
1 つまたは複数のメッセージブロックの整合性を確認す
る
dcmd queue
waitq
--
指定された queue_t データ構造体をフィルタリングして
表示する
dcmd q2syncq
--
--
指定された queue_t のアドレスを使用して、対応する
syncq_t データ構造体のアドレスを出力する
dcmd q2otherq
--
--
指定された queue_t のアドレスを使用して、ピアな読み
取りまたは書き込み待ち行列構造体のアドレスを出力す
る
dcmd q2rdq
--
--
指定された queue_t のアドレスを使用して、対応する読
み取り待ち行列のアドレスを出力する
dcmd q2wrq
--
--
指定された queue_t のアドレスを使用して、対応する書
き込み待ち行列のアドレスを出力する
dcmd stream
--
--
指定された STREAM ヘッドを表す stdata_t 構造体のア
ドレスを使用して、カーネル STREAM データ構造体のイ
メージ図を表示する
dcmd syncq
--
--
指定された syncq_t データ構造体をフィルタリングし表
示する
dcmd syncq2q
--
--
指定された syncq_t のアドレスを使用して、対応する
queue_t データ構造体のアドレスを出力する
walk b_cont
--
--
指定された mblk_t のアドレスを使用して、b_cont ポイ
ンタに従いながら、関連するメッセージ構造体のセットに
対して反復適用する
walk b_next
--
--
指定された mblk_t のアドレスを使用して、b_next ポイ
ンタに従いながら、関連するメッセージ構造体のセットに
対して反復適用する
- 3-172 -
mdb
区分
crash
lcrash
コメント
(gdb)
ネットワーク
関連機能
ファイル、プ
ロセス、およ
walk qlink
--
--
指定された queue_t 構造体のアドレスを使用して、q_link
ポインタを使用しながら、関連する待ち行列のリストを調
べる
walk qnext
--
--
指定された queue_t 構造体のアドレスを使用して、q_next
ポインタを使用しながら、関連する待ち行列のリストを調
べる
walk readq
--
--
指定された stdata_t 構造体のアドレスを使用して、読み
取り側待ち行列構造体のリストを調べる
walk writeq
--
--
stdata を使用して、書き込み側待ち行列構造体のリストを
調べる
dcmd mi
--
--
指定されたカーネル MI_O を使用して、MI_O またはその
ペイロードをフィルタリングし表示する
dcmd netstat
net
--
ネットワークの統計とアクティブな接続を表示する
dcmd sonode
--
--
sonode オブジェクトをフィルタリングし表示する
dcmd tcpb
net
--
tcpb オブジェクトをフィルタリングし表示する
walk ar
--
--
指定された ar のアドレスを使用して、指定された ar か
ら最後の ar までのすべての ar オブジェクトを調べる
walk icmp
--
--
指定された icmp のアドレスを使用して、指定された
icmp から最後の icmp までのすべての icmp オブジェ
クトを調べる
walk ill
--
--
指定されたインタフェースリンク層構造体 (ill) のアドレ
スを使用して、指定された ill から最後の ill までのすべ
ての ill オブジェクトを調べる
walk ipc
--
--
指定された ipc のアドレスを使用して、指定された ipc
から最後の ipc までのすべての ipc オブジェクトを調
べる
walk mi
--
--
指定された MI_O のアドレスを使用して、この MI 内に
あるすべての MI_O を調べる
walk sonode
--
--
指定された sonode を使用して、指定された sonode か
ら始まる関連する sonode のリストを調べる
walk tcpb
--
--
指定された MI を使用して、指定された tcpb から最後の
TCP 接続までのすべての TCP 接続を調べる
walk udp
--
--
指定された MI のアドレスを使用して、指定された udp か
ら最後の udp までのすべての udp オブジェクトを調べ
る
dcmd fd
--
--
指定されたプロセスに関連するファイル記述子 fd-num
に対応する file_t アドレスを出力する
- 3-173 -
区分
mdb
crash
lcrash
コメント
(gdb)
びスレッド
同期プリミテ
ィブ
dcmd findstack
--
--
指定されたカーネルスレッド (kthread_t 構造体の仮想ア
ドレスによって識別される) に関連するスタックトレース
を出力する
dcmd pgrep
--
--
名前が regexp 正規表現パターンに適合するプロセスの
プロセス情報を表示する
dcmd pid2proc
--
--
指定されたプロセス ID に対応する proc_t アドレスを出
力する
dcmd pmap
--
--
指定されたプロセスアドレスに該当するプロセスのメモ
リマップを出力する
dcmd ps
ps
--
指定されたプロセスまたはすべてのアクティブなシステ
ムプロセスに関連する情報の要約を ps に似た形式で出力
する
dcmd ptree
ps
--
それぞれの親プロセスから派生した子プロセスを含むプ
ロセスツリーを出力する
dcmd task
task
task
アクティブなカーネルタスク構造体とそれに関連する ID
番号および属性のリストを出力する
dcmd thread
--
--
指定された kthread_t カーネル構造体のプロパティを表
示する
dcmd whereopen
--
--
指 定 さ れ た vnode_t ア ド レ ス を 使 用 し て 、 現 在 こ の
vnode を フ ァ イ ル テ ー ブ ル に 開 い て い る プ ロ セ ス の
proc_t アドレスを出力する
walk file
--
--
指定された proc_t 構造体のアドレスを開始点として使用
して、指定されたプロセスに関連し開いているファイル
(file_t 構造体) のセットに対して反復適用する
walk proc
--
--
アクティブなプロセス (proc_t) 構造体に対して反復適用
する
walk task
task
--
指定されたタスクポインタを使用して、指定されたタスク
のメンバであるプロセスの proc_t 構造体のリストに対し
て反復適用する
walk thread
--
--
カーネルスレッド (kthread_t) 構造体のセットに対して反
復適用する
dcmd rwlock
--
--
指定された読み取り書き込みロックのアドレスを使用し
て、現在のロックの状態と待機しているスレッドのリスト
を表示する
dcmd sobj2ts
--
--
同期オブジェクトのアドレスを対応するターンスタイル
のアドレスに変換して、ターンスタイルのアドレスを出力
する
dcmd turnstile
--
--
指定された turnstile_t のプロパティを表示する
- 3-174 -
区分
mdb
crash
lcrash
コメント
(gdb)
dcmd wchaninfo
--
--
指定された条件変数またはセマフォのアドレスを使用し
て、このオブジェクト上で現在待機しているスレッドを表
示する
walk blocked
--
--
指定された同期オブジェクトのアドレスを使用して、ブロ
ックされているカーネルスレッドのリストに対して反復
適用する
walk wchan
--
--
指定された条件変数またはセマフォのアドレスを使用し
て、ブロックされているカーネルスレッドのリストに対し
て反復適用する
dcmd cycinfo
--
--
CPU ごとに cyclic サブシステムの各 CPU の状態を表
示する
dcmd cyclic
--
--
指定されたアドレスの cyclic_t をフォーマットし、表示す
る
dcmd cyccover
--
--
cyclic サブシステムのコードカバレッジ情報を表示する
dcmd cyctrace
--
--
cyclic サブシステムのトレース情報を表示する
walk cyccpu
--
--
各 CPU の cyc_cpu_t 構造体に対して反復適用する
walk cyctrace
--
--
cyclic トレースバッファ構造体に対して反復適用する
dcmd taskq_entry
task
--
指定された taskq_entry 構造体の内容を出力する
walk taskq_entry
--
--
指 定 さ れ た taskq 構 造 体 の ア ド レ ス を 使 用 し て 、
taskq_entry 構造体のリストに対して反復適用する
dcmd errorq
--
--
指定されたエラー待ち行列に関連する情報の要約を表示
する
walk errorq
--
--
システムエラー待ち行列のリストを調べて、各エラー待ち
行列のアドレスを返す
walk errorq_data
--
--
指定されたエラー待ち行列のアドレスを使用して、保留中
の各エラーイベントデータバッファのアドレスを返す
構成
dcmd system
--
--
システム初期化中にカーネルが解析したときの system 構
成ファイルの内容を表示する
プロセス間通
信のデバッギ
ングサポート
(ipc)
dcmd ipcs
--
--
既知のメッセージ待ち行列、セマフォ、および共用メモリ
セグメントに対応するシステム全体の IPC 識別子のリス
トを表示する
dcmd msg
--
--
指定されたメッセージ待ち行列要素 (構造体 msg) のプ
ロパティを表示する
dcmd msqid
--
--
指定されたメッセージ待ち行列 IPC 識別子を対応するカ
ーネル実装構造体へのポインタに変換して、このカーネル
構造体のアドレスを出力する
cyclic
タスク待ち行
列
エラー待ち行
列
- 3-175 -
区分
mdb
crash
lcrash
コメント
(gdb)
ループバック
ファイルシス
テムのデバッ
ギングサポー
ト (lofs)
インターネッ
トプロトコル
モジュールの
デバッギング
サポート (ip)
カーネル実行
時リンカーの
dcmd msqid_ds
--
--
指 定 さ れ た msqid_ds 構 造 体 ま た は ア ク テ ィ ブ な
msqid_ds 構造体 (メッセージ待ち行列識別子) のテーブ
ルを出力する
dcmd semid
--
--
指定されたセマフォ IPC 識別子を対応するカーネル実装
構造体へのポインタに変換して、このカーネル構造体のア
ドレスを出力する
dcmd semid_ds
--
--
指 定 さ れ た semid_ds 構 造 体 ま た は ア ク テ ィ ブ な
semid_ds 構造体 (セマフォ識別子) のテーブルを出力す
る
dcmd shmid
--
--
指定された共用メモリ IPC 識別子を対応するカーネル実
装構造体へのポインタに変換して、このカーネル構造体の
アドレスを出力する
dcmd shmid_ds
--
--
指 定 さ れ た shmid_ds 構 造 体 ま た は ア ク テ ィ ブ な
shmid_ds 構造体 (共用メモリーセグメント識別子) のテ
ーブルを出力する
walk msgqueue
--
--
メッセージ待ち行列識別子に対応するアクティブな
msqid_ds 構造体を調べる
walk msq
--
--
現在指定されたメッセージ待ち行列に入っている
message 構造体に対して反復適用する
walk sem
--
--
セマフォ識別子に対応するアクティブな semid_ds 構造
体を調べる
walk shm
--
--
共用メモリセグメント識別子に対応するアクティブな
shmid_ds 構造体を調べる
dcmd lnode
--
--
指定された lnode_t 、また はカーネルの アクティブな
lnode_t 構造体のテーブルを出力する
dcmd lnode2dev
--
--
指定された lnode_t アドレスに対応する配下のループバ
ックマウントファイルシステムの dev_t (vfs_dev) を出力
する
dcmd lnode2rdev
--
--
指定された lnode_t アドレスに対応する配下のループバ
ックマウントファイルシステムの dev_t (li_rdev) を出力
する
walk lnode
--
--
カーネルのアクティブな lnode_t 構造体を調べる
dcmd ire
--
--
指定された ire_t、またはカーネルのアクティブな ire_t 構
造体のテーブルを出力する
walk ire
--
--
カーネルのアクティブな ire (Internet Route Entry) 構造
体を調べる
dcmd modctl
--
--
指 定 さ れ た modctl 、 ま た は カ ー ネ ル の ア ク テ ィ ブ な
modctl 構造体のテーブルを出力する
- 3-176 -
区分
mdb
crash
lcrash
コメント
(gdb)
デバッギング
サ ポ ー ト
(krtld)
USB フ レ ー
ムワークのデ
バッギングサ
ポート (uhci)
USB フ レ ー
ムワークのデ
バッギングサ
ポート (usba)
dcmd modhdrs
--
--
指定された modctl 構造体のアドレスを使用して、モジュ
ールの ELF 実行可能ヘッダーとセクションヘッダーを出
力する
dcmd modinfo
mod
module
アクティブカーネルモジュールに関する情報を出力する
walk modctl
mod
--
カーネルのアクティブな modctl 構造体のリストを調べ
る
dcmd uhci_qh
--
--
指 定 さ れ た USB UHCI コ ン ト ロ ー ラ の QH (Queue
Head) 構造体のアドレスを使用して、この構造体の内容を
出力する
dcmd uhci_td
--
--
指定された USB UHCI コントローラの TD (Transaction
Descriptor) 構造体のアドレスを使用して、この構造体の内
容を出力する
walk uhci_qh
--
--
指 定 さ れ た USB UHCI コ ン ト ロ ー ラ の QH (Queue
Head) 構造体のアドレスを使用して、このような構造体の
リストに対して反復適用する
walk uhci_td
--
--
指定された USB UHCI コントローラの TD (Transaction
Descriptor) 構造体のアドレスを使用して、このような構造
体のリストに対して反復適用する
dcmd
usba_debug_buf
--
--
USB デバッギング情報バッファを出力する
dcmd usb_hcdi_cb
--
--
指定されたホストコントローラのコールバック構造体
(usb_hcdi_cb) のアドレスを使用して、このコールバック
の要約情報を出力する
dcmd usb_device
--
--
指定された usb_device 構造体のアドレスを使用して、要
約情報を出力する
dcmd
usb_pipe_handle
--
--
指 定 さ れ た USB パ イ プ ハ ン ド ル 構 造 体
(usb_pipe_handle_impl) のアドレスを使用して、このハン
ドルの要約情報を出力する
walk usb_hcdi_cb
--
--
指定された USB ホストコントローラの devinfo ノード
のアドレスを使用して、このコントローラの
usb_hcdi_cb_t 構造体のリストに対して反復適用する
walk
usba_list_entry
--
--
指定された usba_list_entry 構造体のアドレスを使用し
て、このような構造体のチェインに対して反復適用する
3.6.2.5 ダンプ解析ツ--ル比較の考察
crash は、mdb に比べるとカーネルメモリアロケータ関連のコマンドが少ないが、内容
としてはかなり充実している。Crash ではカーネルメモリアロケータ関連のコマンド
- 3-177 -
を”kmem”コマンドのオプションで実装しているが、mdb はそれぞれ別のコマンドとしてサ
ポートしている。好みが分かれるところだろうが、コマンドが少なく、オプションによる
指定が可能な crash の方が覚えやすいように感じた。
mdb はカーネルダンプの解析のみならず通常のプログラムのデバッガを兼ねているためコ
マンド数は圧倒的に多く、Solaris 固有のデバッグ用構造体を編集するコマンドが多数見ら
れる。特にメモリ管理に関してその傾向が強い。Alicia は、crash/lcrash の機能の繰り返し、
組み合わせ等を LDAS として記述することが可能であり、mdb コマンドの中で有効だと思
われるコマンドを Alicia コマンドとして追加していくことが可能である。今回の mdb コマ
ンドの調査結果を元に Alicia の機能を更に高めていくことで、Linux のダンプ解析作業が
より快適に、より迅速に実施できる環境を整備していきたい。
- 3-178 -
3.7 OSS 障害解析ツールの問題点と対策
現在、OSS 障害解析ツールは既存ツール自体の問題を含め、商用のものと比べて解析ツ
ールが不足しているなど、様々な問題がある。
今回の障害解析ツール評価の結果、OSS 障害解析ツールの現状の問題点を次の表に示す。
対策については、既に対応が済んでいるものもあるが、現時点では、十分な対応ができて
いないため、今後の課題としているものもある。課題の解決方法の一つとして、OSS コミ
ュニティに提言することも考えられる。
図 3.7-1
項
番
1
分類
OSS 障害解析ツールの問題点
問題点
対策
sar コマンドの結果が欠落する
3.1.5.4 節の回避策参照
高負荷時に
strace コマンドがトレース対象プ
strace 出力を ramfs に出力する(改
特有の問題
ロセスの処理を遅延させてしまう
善策)
動作不良
strace
strace 4.5.9 で、修正済み
高負荷時に
特有の問題
2
3
コ
マ
ン
ド
の
--e
signal=SIGXXX(XXX は任意)オ
プションを使用すると、エラーが返
されてしまう
4
5
情報不足
情報不足
ダンプが取れても、その障害に至る
システム・ログ、アプリケーション
までの経緯が分からない
のログをダンプと一緒に採取する
ドキュメントが不足している(例:
OSS 障害解析に必要なドキュメン
/proc 下にどのような情報がどのよ
ト整備、公開
うなフォーマットで格納されてい
テナンスが今後の課題である
及び、継続的なメン
るか)
6
情報不足
カーネルパニック時にコンソール
シリアルコンソールを使用する
に表示されるメッセージが保存さ
れない
7
8
情報不足
情報不足
pthread_create のマニュアルに、
コミュニティへの改善提案が今後
ENOMEM の記述がない
の課題である
異なるバージョン間での挙動の違
カーネルのバージョン間での動作
い(例えば、出力数値の意味が異な
違いの情報を収集、公開していくこ
る等)が大きい
とが重要であるが、今後の課題であ
る
- 3-179 -
4 付録 <crash/lcrash/mdb コマンド結果比較>
crash
crash の出力結果
lrcash
ポインターへのショートカット
crash> *page c02943c0
*
struct page {
next = 0xc0fae740,
prev = 0xc0018fb0,
inode = 0x0,
offset = 0x3f000,
next_hash = 0xc02d6310,
count = {
counter = 0x1
},
flags = 0x310,
wait = 0xc02943d8,
pprev_hash = 0x0,
buffers = 0x0
}
シェルへのエスケープおよびコマンドを実行する
!comman crash> !ls
bin etc
lib
mnt
ossback prod tftpboot var
d
boot home
lost+found
mycomputer portal root tmp
dev initrd misc
opt
proc
sbin usr
コマンド別名を設定する
crash> alias
alias
ORIGIN ALIAS
builtin man
builtin ?
builtin quit
builtin sf
builtin sn
builtin hex
builtin dec
builtin g
builtin px
builtin pd
builtin for
builtin size
builtin dmesg
builtin last
COMMAND
help
help
q
set scroll off
set scroll on
set radix 16
set radix 10
gdb
p -x
p -d
foreach
*
log
ps –l
lcrash の出力結果
mdb
mdb の出力結果
--
--
--
!comman
d
>!ls
bin etc
lib
mnt
ossback prod tftpboot var
boot home
lost+found
mycomputer portal root tmp
dev initrd misc
opt
proc
sbin usr
::stack
> ::stack
vpanic(116f1d0, ff3eec00, 3, ff3efa80, 1f, ffbffb0c)
kadmin+0x550(5, 1, 0, 300003f97a8, 5, 0)
--
crash> alias kp kmem -p
ORIGIN ALIAS
COMMAND
runtime kp
kmem -p
16 進法のストリングをASCII に変換する
crash> ascii 62696c2f7273752f
ascii
62696c2f7273752f: /usr/lib
バックトレースを表示する
bt
--
task_list に含まれる task の stack trace を表示する
crash> bt
PID: 0
TASK: c0322a60 CPU: 0 COMMAND: "swapper"
#0 [c03b4fa4] smp_call_function_interrupt at c0118cda
bt,
デフォルトCPU のレジスタ情報を表示する
>> trace
================================================================
STACK TRACE FOR TASK: 0xc5934000(krnl-1)
- 4-1 -
#1 [c03b4fac] call_function_interrupt at c02d4b9d
EAX: 00000000 EBX: c03b4000 ECX: 00000000 EDX: 00000000 EBP: 004d7007
DS: 007b
ESI: 00000000 ES: 007b
EDI: c03eb120
CS: 0060
EIP: c01040ea ERR: fffffffb EFLAGS: 00000246
#2 [c03b4fe0] mwait_idle at c01040ea
#3 [c03b4fe8] cpu_idle at c01040a0
crash> bt –a
PID: 0
TASK: c0322a60 CPU: 0 COMMAND: "swapper"
#0 [c03b4fa4] smp_call_function_interrupt at c0118cda
#1 [c03b4fac] call_function_interrupt at c02d4b9d
EAX: 00000000 EBX: c03b4000 ECX: 00000000 EDX: 00000000 EBP: 004d7007
DS: 007b
ESI: 00000000 ES: 007b
EDI: c03eb120
CS: 0060
EIP: c01040ea ERR: fffffffb EFLAGS: 00000246
#2 [c03b4fe0] mwait_idle at c01040ea
#3 [c03b4fe8] cpu_idle at c01040a0
trace
t
strace
rd
0 do_coprocessor_error [0xc010cbc0]
1 restore_i387_fxsave+36 [0xc0112bc4]
2 restore_i387+120 [0xc0112c98]
3 restore_sigcontext+270 [0xc010b1de]
4 sys_sigreturn+204 [0xc010b2cc]
5 no_timing+5 [0xc03b80d1]
6 LKST_ETYPE_SYSCALL_ENTRY_HEADER_hook+53 [0xc03b8036]
================================================================
>> trace -f
================================================================
STACK TRACE FOR TASK: 0xc5934000(krnl-1)
0 do_coprocessor_error [0xc010cbc0]
RA=0x00000000, SP=0x00000000, FP=0x00000000, SIZE=0
PID: 0
TASK: f7f310b0 CPU: 1 COMMAND: "swapper"
#0 [f7f0bf7c] smp_call_function_interrupt at c0118cda
#1 [f7f0bf84] call_function_interrupt at c02d4b9d
EAX: 00000000 EBX: f7f0b000 ECX: 00000000 EDX: 00000000 EBP: 00000000
DS: 007b
ESI: 00000000 ES: 007b
EDI: 00000000
CS: 0060
EIP: c01040ea ERR: fffffffb EFLAGS: 00000246
#2 [f7f0bfb8] mwait_idle at c01040ea
#3 [f7f0bfc0] cpu_idle at c01040a0
PID: 0
TASK: f7f30b30 CPU: 2 COMMAND: "swapper"
#0 [f7f0dcec] disk_dump at f893ea54
#1 [f7f0dcf0] printk at c0124c8f
#2 [f7f0dcfc] freeze_other_cpus at f893e885
#3 [f7f0dd0c] start_disk_dump at f893e930
#4 [f7f0dd1c] try_crashdump at c0136eed
#5 [f7f0dd24] die at c010603f
#6 [f7f0dd58] LKST_ETYPE_OOPS_PGFAULT_HEADER_hook at c011d498
#7 [f7f0ddb4] vgacon_scroll at c01cbdd9
#8 [f7f0dde4] LKST_ETYPE_TIMER_MOD_HEADER_hook at c012c0ba
#9 [f7f0de00] poke_blanked_console at c020a096
#10 [f7f0de04] vt_console_print at c0209428
#11 [f7f0de24] __call_console_drivers at c0124a2d
#12 [f7f0de38] error_code at c02d4c88
EAX: 00000063 EBX: c035fc34 ECX: ee869000 EDX: f7f0df88 EBP: f7f0df88
DS: 007b
ESI: 00000063 ES: 007b
EDI: ee869000
CS: 0060
EIP: c020a974 ERR: ffffffff EFLAGS: 00010046
#13 [f7f0de74] sysrq_handle_crash at c020a974
#14 [f7f0de98] kbd_event at c02058b7
#15 [f7f0deb0] input_event at c026789e
#16 [f7f0dedc] atkbd_interrupt at c026aa8a
#17 [f7f0df28] i8042_interrupt at c0217291
#18 [f7f0df58] LKST_ETYPE_INT_HARDWARE_ENTRY_HEADER_hook at c0107a35
#19 [f7f0df84] common_interrupt at c02d4b3b
EAX: 00000000 EBX: f7f0d000 ECX: 00000000 EDX: 00000000 EBP: 00000000
DS: 007b
ESI: 00000000 ES: 007b
EDI: 00000000
CS: 0060
EIP: c01040ea ERR: ffffff01 EFLAGS: 00000246
#20 [f7f0dfb8] mwait_idle at c01040ea
#21 [f7f0dfc0] cpu_idle at c01040a0
1 restore_i387_fxsave+36 [0xc0112bc4]
RA=0x00000000, SP=0x00000000, FP=0x00000000, SIZE=0
2 restore_i387+120 [0xc0112c98]
RA=0x00000000, SP=0x00000000, FP=0x00000000, SIZE=0
3 restore_sigcontext+270 [0xc010b1de]
RA=0x00000000, SP=0x00000000, FP=0x00000000, SIZE=0
4 sys_sigreturn+204 [0xc010b2cc]
RA=0x00000000, SP=0x00000000, FP=0x00000000, SIZE=0
5 no_timing+5 [0xc03b80d1]
RA=0x00000000, SP=0x00000000, FP=0x00000000, SIZE=0
6 LKST_ETYPE_SYSCALL_ENTRY_HEADER_hook+53 [0xc03b8036]
RA=0x00000000, SP=0x00000000, FP=0x00000000, SIZE=0
================================================================
>> rd
CPU:
0 EIP:
0060:[<c03b81d7>]
EFLAGS: 00000246
eax: 00000000 ebx: bfffb4d8 ecx: bfffb4d8
esi: bfffb4d8 edi: c5935fb0 ebp: bfffb480
ds: 0068 es: 0068 ss: 0068
PID: 0
TASK: f7f305b0 CPU: 3 COMMAND: "swapper"
#0 [f7f0ef7c] smp_call_function_interrupt at c0118cda
#1 [f7f0ef84] call_function_interrupt at c02d4b9d
EAX: 00000000 EBX: f7f0e000 ECX: 00000000 EDX: 00000000 EBP: 00000000
DS: 007b
ESI: 00000000 ES: 007b
EDI: 00000000
CS: 0060
EIP: c01040ea ERR: fffffffb EFLAGS: 00000246
#2 [f7f0efb8] mwait_idle at c01040ea
#3 [f7f0efc0] cpu_idle at c01040a0
- 4-2 -
edx: c5934000
esp: c5935ec8
uadmin+0x104(5, 1, 0, 6d700000, 6d70, ffbffd91)
syscall_trap32+0xa8(5, 1, 0, 6d700000, 6d70, ffbffd91)
::regs
>::regs
%g0 = 0x0000000000000000
%l0 = 0x00000000ff3ec0c0
%g1 = 0x000000000113e000 ttyinit+0x1a8 %l1 = 0x00000000ff3ec8bc
%g2 = 0x000000000116f000
%l2 = 0x00000000ff3ec264
%g3 = 0x000000000140e000 kstat_data_type+0x70 %l3 = 0x00000000ff3ee4a4
%g4 = 0x00000000000006e0
%l4 = 0x00000000000217b4
%g5 = 0x0000000001449bf8 sysent32+0x6e0 %l5 = 0x0000000001000000 scb
%g6 = 0x0000000000000000
%l6 = 0x0000000000000000
%g7 = 0x000003000333a2e0
%l7 = 0x0000000000010883
%o0 = 0x000000000116f1d0
%i0 = 0x000000000116f1d0
%o1 = 0x000002a1008658f8
%i1 = 0x00000000ff3eec00
%o2 = 0x00000000ff3ec204
%i2 = 0x0000000000000003
%o3 = 0x0000000000031344
%i3 = 0x00000000ff3efa80
%o4 = 0x00000000ff3c3050
%i4 = 0x000000000000001f
%o5 = 0x00000000f0000000
%i5 = 0x00000000ffbffb0c
%o6 = 0x000002a100864fc1
%i6 = 0x000002a100865071
%o7 = 0x000000000104c150
panic+0x1c %i7 = 0x000000000113e788 kadmin+0x550
%ccr = 0x44 xcc=nZvc icc=nZvc
%fprs = 0x00 fef=0 du=0 dl=0
%asi = 0x00
%y = 0x0000000000000000
%pc = 0x0000000001037538 vpanic
%npc = 0x000000000103753c vpanic+4
%sp = 0x000002a100864fc1 unbiased=0x000002a1008657c0
%fp = 0x000002a100865071
%tick = 0x0000000000000000
%tba = 0x0000000000000000
%tt = 0x0
%tl = 0x0
%pil = 0x0
%pstate = 0x016 cle=0 tle=0 mm=TSO red=0 pef=1 am=0 priv=1 ie=1 ag=0
%cwp = 0x05 %cansave = 0x00
%canrestore = 0x00 %otherwin = 0x00
%wstate = 0x00 %cleanwin = 0x00
crash> bt
PID: 0
c03b4000:
c03b4010:
c03b4020:
c03b4030:
c03b4040:
c03b4050:
c03b4060:
c03b4070:
c03b4080:
c03b4090:
c03b40a0:
c03b40b0:
c03b40c0:
c03b40d0:
c03b40e0:
c03b40f0:
c03b4100:
c03b4110:
c03b4120:
c03b4130:
c03b4140:
c03b4150:
–r
TASK: c0322a60 CPU: 0 COMMAND: "swapper"
init_task default_exec_domain 00010008 00000000
00000000 00010000 ffffffff 00000000
init_thread_union 00000000 00000000 do_no_restart_syscall
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
crash> bt -t
PID: 0
TASK: c0322a60 CPU: 0 COMMAND: "swapper"
START: smp_call_function_interrupt at c0118cda
[c03b4fac] call_function_interrupt at c02d4ba2
[c03b4fd8] mwait_idle at c01040ea
[c03b4fe8] cpu_idle at c01040a2
[c03b4fec] start_kernel at c03b5784
[c03b4ffc] L6 at c0100211
crash> bt -e
PID: 0
TASK: c0322a60 CPU: 0
KERNEL-MODE EXCEPTION FRAME AT
EAX: 00000000 EBX: c03b4000
DS: 007b
ESI: 00000000
CS: 0060
EIP: c01040ea
COMMAND: "swapper"
c03b4fb0:
ECX: 00000000 EDX: 00000000 EBP: 004d7007
ES: 007b
EDI: c03eb120
ERR: fffffffb EFLAGS: 00000246
crash> bt -E
CPU 0 HARD IRQ STACK:
(none found)
CPU 1 HARD IRQ STACK:
(none found)
CPU 2 HARD IRQ STACK:
(none found)
CPU 3 HARD IRQ STACK:
(none found)
CPU 0 SOFT IRQ STACK:
(none found)
CPU 1 SOFT IRQ STACK:
(none found)
CPU 2 SOFT IRQ STACK:
(none found)
- 4-3 -
CPU 3 SOFT IRQ STACK:
(none found)
crash> bt -f
PID: 0
TASK: c0322a60 CPU: 0 COMMAND: "swapper"
#0 [c03b4fa4] smp_call_function_interrupt at c0118cda
[RA: c02d4ba2 SP: c03b4fa4 FP: c03b4fac SIZE: 12]
c03b4fa4: c03b4000 00000000 c02d4ba2
#1 [c03b4fac] call_function_interrupt at c02d4b9d
EAX: 00000000 EBX: c03b4000 ECX: 00000000 EDX: 00000000 EBP: 004d7007
DS: 007b
ESI: 00000000 ES: 007b
EDI: c03eb120
CS: 0060
EIP: c01040ea ERR: fffffffb EFLAGS: 00000246
[RA: c01040ea SP: c03b4fb0 FP: c03b4fe0 SIZE: 52]
c03b4fb0: c03b4000 00000000 00000000 00000000
c03b4fc0: c03eb120 004d7007 00000000 c032007b
c03b4fd0: 0000007b fffffffb c01040ea 00000060
c03b4fe0: 00000246
#2 [c03b4fe0] mwait_idle at c01040ea
[RA: c01040a2 SP: c03b4fe4 FP: c03b4fe8 SIZE: 8]
c03b4fe4: c03b4000 c01040a2
#3 [c03b4fe8] cpu_idle at c01040a0
[RA: 0 SP: c03b4ffc FP: c03b4ffc SIZE: 0]
16 進アドレスとそのページ番号に変更する
crash> btop 512a000
btop
512a000: 512a
--
--
--
::devna
mes
::prtco
nf
デバイスデータを表示する
dev
crash> dev
CHRDEV
NAME
1
mem
2
pty
3
ttyp
4
ttyS
5
cua
7
vcs
10
misc
13
input
29
fb
36
netlink
128
ptm
129
ptm
130
ptm
131
ptm
132
ptm
133
ptm
134
ptm
135
ptm
136
pts
137
pts
138
pts
139
pts
crash> dev -i
RESOURCE
RANGE
c0355060 0000-ffff
c03542a0 0000-001f
c03542bc 0020-003f
c03542d8 0040-005f
c03542f4 0060-006f
c1543600 0070-007f
c0354310 0080-008f
c035432c 00a0-00bf
OPERATIONS
c03761e0
c0376240
c0376240
c0376240
c0376240
c03768a0
c03764e0
c8856600
c03af660
c03b0f80
c0376240
c0376240
c0376240
c0376240
c0376240
c0376240
c0376240
c0376240
c0376240
c0376240
c0376240
c0376240
<memory_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<vcs_fops>
<misc_fops>
<input_fops>
<fb_fops>
<netlink_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<tty_fops>
<tty_fops>
>devnames
NAME
cn
rootnex
pseudo
ip
logindmux
icmp
fas
hme
eri
pcf8584
max1617
clone
sad
mm
iwscn
wc
conskbd
consms
tda8444
dump
se
log
DN_HEAD
30000aeb250
30000295d08
3000028c1f0
30000871b58
3000328c950
30000871078
0
0
30000293400
30000292cc0
30000291978
30000871d28
30000870b08
30000aeb080
300008703c8
30000870768
30000870938
30000870598
300002917a8
3000328c210
30000290588
30000aea3d0
>::prtconf
EVINFO
NAME
30000295d08
SUNW,Sun-Blade-1000
30000295b38
packages (driver not attached)
30000295798
SUNW,builtin-drivers (driver not attached)
300002955c8
deblocker (driver not attached)
300002953f8
disk-label (driver not attached)
30000295228
terminal-emulator (driver not attached)
30000295058
obp-tftp (driver not attached)
30000294e88
dropins (driver not attached)
NAME
PCI IO
dma1
pic1
timer
keyboard
rtc
dma page reg
pic2
- 4-4 -
c0354348
c0354364
c1543800
c1543780
c15435c0
c15437c0
c03addbc
c1543740
c1543580
c1532920
c153293c
c15432c0
c1533920
c1531878
c1532c78
c7c14680
c15324cc
c14f45c0
c15320cc
c15436c0
c1543700
00c0-00df
00f0-00ff
0170-0177
01f0-01f7
02f8-02ff
0376-0376
03c0-03df
03f6-03f6
03f8-03ff
0400-043f
0440-045f
0cf8-0cff
b000-cfff
c800-c8ff
dc00-dc1f
dc00-dc1f
de00-de1f
de00-de1f
ffa0-ffaf
ffa0-ffa7
ffa8-ffaf
dma2
fpu
ide1
ide0
serial(auto)
ide1
vga+
ide0
serial(auto)
Intel Corp. 82371AB/EB/MB PIIX4
Intel Corp. 82371AB/EB/MB PIIX4
PCI conf1
PCI Bus #01
ATI Technologies Inc 3D Rage LT
Intel Corp. 82557/8/9 [Ethernet
e100
Intel Corp. 82371AB/EB/MB PIIX4
usb-uhci
Intel Corp. 82371AB/EB/MB PIIX4
ide0
ide1
RESOURCE
c035507c
c079b000
c079b080
c03543b8
c03543fc
c0354418
c03543e0
c079b180
c0354380
c035439c
c079b200
c079b280
c1533958
c153185c
c153345c
bridge
c1532c5c
c7c14640
c153393c
c1531894
c1531078
RANGE
00000000-ffffffff
00000000-0009f7ff
0009f800-0009ffff
000a0000-000bffff
000c0000-000c7fff
000cb800-000cbfff
000f0000-000fffff
00100000-07fdffff
00100000-002895e6
002895e7-003b5587
07fe0000-07ff7fff
07ff8000-07ffffff
e5600000-e76fffff
e6000000-e6ffffff
e8000000-ebffffff
NAME
PCI mem
System RAM
reserved
Video RAM area
Video ROM
Extension ROM
System ROM
System RAM
Kernel code
Kernel data
ACPI Tables
ACPI Non-volatile Storage
PCI Bus #01
ATI Technologies Inc 3D Rage LT Pro AGP-133
Intel Corp. 440BX/ZX/DX - 82443BX/ZX/DX Host
ef7ff000-ef7fffff
ef7ff000-ef7fffff
ef800000-ef8fffff
ef8ff000-ef8fffff
efc00000-efcfffff
Intel Corp. 82557/8/9 [Ethernet Pro 100]
e100
PCI Bus #01
ATI Technologies Inc 3D Rage LT Pro AGP-133
Cirrus Logic CS 4614/22/24 [CrystalClear
SoundFusion Audio Accelerator]
Cirrus Logic CS 4614/22/24 [CrystalClear
SoundFusion Audio Accelerator]
Intel Corp. 82557/8/9 [Ethernet Pro 100]
e100
reserved
c153105c efdff000-efdfffff
30000294cb8
kbd-translator (driver not attached)
30000294ae8
ufs-file-system (driver not attached)
30000295968
chosen (driver not attached)
30000294918
openprom (driver not attached)
30000294578
client-services (driver not attached)
30000294748
options, instance #0
300002943a8
aliases (driver not attached)
300002941d8
memory (driver not attached)
30000294008
virtual-memory (driver not attached)
30000293d10
SUNW,UltraSPARC-III, instance #0
30000293b40
memory-controller, instance #0
30000293970
pci108e,8001, instance #0
300002935d0
ebus, instance #0
30000293230
flashprom (driver not attached)
30000293060
bbc (driver not attached)
30000292e90
ebus-ppm, instance #0
30000292cc0
SUNW,bbc-i2c, instance #0
30000292920
i2c-at24c64, instance #0
30000292750
i2c-at24c64, instance #1
30000292580
i2c-at24c64, instance #2
300002923b0
i2c-at24c64, instance #3
300002921e0
i2c-at24c64, instance #4
30000292010
idprom (driver not attached)
30000292af0
SUNW,bbc-i2c, instance #1
30000291b48
i2c-at24c64, instance #5
30000291978
i2c-max1617, instance #0
300002917a8
i2c-tda8444, instance #0
300002915d8
i2c-scm001 (driver not attached)
30000291408
i2c-at24c64, instance #6
30000291238
i2c-bridge (driver not attached)
30000291d18
SUNW,bbc-beep, instance #0
30000291068
SUNW,CS4231 (driver not attached)
30000290e98
ds1287, instance #0
30000290cc8
gpio (driver not attached)
30000290af8
pmc (driver not attached)
30000290928
fdthree (driver not attached)
30000290758
ns87317-ecpp (driver not attached)
30000290588
se, instance #0
30000293400
pci108e,1101, instance #0
300002903b8
pciclass,0c0010, instance #0
300002901e8
pciclass,0c0310, instance #0
3000028dd20
usbif,class3, instance #4
3000028db50
usbif,class3, instance #2
30000290018
pci1000,f, instance #0
3000028d7b0
sd (driver not attached)
3000028d5e0
st (driver not attached)
30000aea940
sd, instance #0 (driver not attached)
30000aeab10
sd, instance #1 (driver not attached)
30000aeaeb0
sd, instance #2 (driver not attached)
30000aebb60
sd, instance #3 (driver not attached)
30000aebd30
sd, instance #4 (driver not attached)
30000870cd8
sd, instance #5 (driver not attached)
300019c9b68
sd, instance #6
300019c9998
sd, instance #7 (driver not attached)
300019c97c8
sd, instance #8 (driver not attached)
300019c95f8
sd, instance #9 (driver not attached)
300019c9428
sd, instance #10 (driver not attached)
300019c9258
sd, instance #11 (driver not attached)
300019c9088
sd, instance #12 (driver not attached)
300019c8eb8
sd, instance #13 (driver not attached)
300019c8ce8
sd, instance #14 (driver not attached)
ACPI
ACPI
Pro AGP-133
Pro 100]
USB
IDE
c1532c94 eff00000-efffffff
c7c146c0 eff00000-efffffff
c079b300 ffff0000-ffffffff
crash> dev -p
PCI_DEV BU:SL.FN CLASS: VENDOR-DEVICE
c1533800 00:01.0 PCI bridge: Intel 440BX - 82443BX AGP
c1533c00 00:07.0 ISA bridge: Intel 82371AB PIIX4 ISA
c1532000 00:07.1 IDE interface: Intel 82371AB PIIX4 IDE
c1532400 00:07.2 USB Controller: Intel 82371AB PIIX4 USB
c1532800 00:07.3 Bridge: Intel 82371AB PIIX4 ACPI
c1532c00 00:0a.0 Ethernet controller: Intel 82557
c1531000 00:0b.0 Multimedia audio controller: Cirrus Logic [PCI_DEVICE 6003]
c1531800 01:00.0 VGA compatible controller: ATI [PCI_DEVICE 4c42]
逆アセンブルを行う
- 4-5 -
dis
crash> dis
0xc0130095
0xc0130098
0xc013009c
0xc013009e
0xc01300a6
0xc01300aa
0xc01300ae
0xc01300b2
0xc01300b7
0xc01300b9
0xc01300bd
0xc01300c0
sys_signal
<sys_signal>:
<sys_signal+3>:
<sys_signal+7>:
<sys_signal+9>:
<sys_signal+17>:
<sys_signal+21>:
<sys_signal+25>:
<sys_signal+29>:
<sys_signal+34>:
<sys_signal+36>:
<sys_signal+40>:
<sys_signal+43>:
crash> dis
0xc0138340
0xc0138341
0xc0138342
0xc0138343
0xc0138344
0xc0138347
0xc013834b
0xc013834f
0xc0138353
0xc0138357
0xc013835b
0xc013835f
0xc0138363
0xc0138367
0xc013836b
0xc013836f
0xc0138372
0xc0138374
je
0xc013837a
0xc013837d
0xc013837f
je
-r (do_no_page+65)
<do_no_page>:
push %ebp
<do_no_page+1>:
push %edi
<do_no_page+2>:
push %esi
<do_no_page+3>:
push %ebx
<do_no_page+4>:
sub
$0x3c,%esp
<do_no_page+7>:
mov
0x50(%esp),%eax
<do_no_page+11>:
mov
0x58(%esp),%edx
<do_no_page+15>:
mov
0x54(%esp),%esi
<do_no_page+19>:
mov
0x60(%esp),%ebx
<do_no_page+23>:
mov
%eax,0x38(%esp)
<do_no_page+27>:
mov
0x5c(%esp),%eax
<do_no_page+31>:
mov
%edx,0x34(%esp)
<do_no_page+35>:
mov
0x64(%esp),%edx
<do_no_page+39>:
mov
%eax,0x30(%esp)
<do_no_page+43>:
mov
%edx,0x2c(%esp)
<do_no_page+47>:
mov
0x30(%esi),%edx
<do_no_page+50>:
test %edx,%edx
<do_no_page+52>:
0xc0138741 <LKST_ETYPE_MEM_DO_NOPAGE_HEADER_hook+624>
<do_no_page+58>:
mov
0x8(%edx),%eax
<do_no_page+61>:
test %eax,%eax
<do_no_page+63>:
0xc0138741 <LKST_ETYPE_MEM_DO_NOPAGE_HEADER_hook+624>
sub
mov
mov
movl
mov
mov
lea
call
test
cmove
add
ret
$0x40,%esp
0x48(%esp),%edx
%esp,%ecx
$0xc0000000,0x24(%esp)
0x44(%esp),%eax
%edx,0x20(%esp)
0x20(%esp),%edx
0xc012facd <do_sigaction>
%eax,%eax
(%esp),%eax
$0x40,%esp
評価をおこなう
crash> eval 128m
eval
hexadecimal: 8000000 (128MB)
decimal: 134217728
octal: 1000000000
binary: 00001000000000000000000000000000
dis
id
print
p
pb,pd,
po,px
base
>>dis 0xc010cbc0
0xc010cbc0 <do_coprocessor_error>:
::dis
movb
>> dis -f sys_signal
0xc012eb00 <sys_signal>:
0x8305 subl
>> dis sys_signal 10
0xc012eb00 <sys_signal>:
0xc012eb03 <sys_signal+3>:
0xc012eb07 <sys_signal+7>:
0xc012eb0f <sys_signal+15>:
0xc012eb13 <sys_signal+19>:
0xc012eb17 <sys_signal+23>:
0xc012eb1b <sys_signal+27>:
0xc012eb1f <sys_signal+31>:
0xc012eb23 <sys_signal+35>:
0xc012eb27 <sys_signal+39>:
subl
movl
movl
movl
leal
movl
leal
movl
movl
movl
$0x1,0xc03e7e20
$0x4c,%esp (3 bytes)
$0x4c,%esp
0x54(%esp,1),%eax
$0xc0000000,0x30(%esp,1)
%eax,0x2c(%esp,1)
0xc(%esp,1),%eax
%eax,0x8(%esp,1)
0x2c(%esp,1),%eax
%eax,0x4(%esp,1)
0x50(%esp,1),%eax
%eax,(%esp,1)
>> print (*((struct task_struct *)0xc5c14000)->files.fd).
f_flags & 0x8000
32768
::eval
>> base 10
-------------------------------------------------hex: 0xa
decimal: 10
octal: 012
binary: 0b1010
--------------------------------------------------
終了する
exit
q, q!
::quit
コマンドセットの拡張 sial マクロをロードする
- 4-6 -
>::dis signal
signal:
signal+4:
signal+8:
signal+0xc:
signal+0x10:
signal+0x14:
signal+0x18:
signal+0x1c:
signal+0x20:
signal+0x24:
signal+0x28:
signal+0x2c:
signal+0x30:
signal+0x34:
signal+0x38:
signal+0x3c:
signal+0x40:
signal+0x44:
signal+0x48:
signal+0x4c:
signal+0x50:
signal+0x54:
signal+0x58:
signal+0x5c:
signal+0x60:
signal+0x64:
signal+0x68:
signal+0x6c:
signal+0x70:
signal+0x74:
signal+0x78:
signal+0x7c:
signal+0x80:
signal+0x84:
signal+0x88:
signal+0x8c:
signal+0x90:
signal+0x94:
signal+0x98:
signal+0x9c:
signal+0xa0:
signal+0xa4:
signal+0xa8:
save
sethi
add
call
mov
sethi
add
call
mov
sra
cmp
be,pn
nop
call
mov
orcc
be,pn
nop
call
mov
ldx
cmp
be,pn
nop
ldx
call
nop
sra
clr
call
mov
call
ldx
ldx
cmp
bne,a,pt
ldx
call
restore
call
mov
call
restore
%sp, -0xb0, %sp
%hi(0x149e000), %l4
%l4, 0x168, %l3
-0x9527c
<mutex_enter>
%l3, %o0
%hi(0x1457800), %g2
%g2, 0x2e0, %l5
-0x9528c
<mutex_enter>
%l5, %o0
%i0, 0, %l0
%l0, 0
%icc,+0x70
<signal+0x9c>
-0x8d4
<pid_lookup>
%l0, %o0
%g0, %o0, %l0
%xcc,+0x5c
<signal+0x9c>
-0x95238
<mutex_exit>
%l5, %o0
[%l0 + 8], %l0
%l0, 0
%xcc,+0x3c
<signal+0x94>
[%l0 + 0x10], %o0
-0x952d4
<mutex_enter>
%i1, 0, %o2
%o1
+0x25ebc
%l0, %o0
-0x9526c
[%l0 + 0x10],
[%l0 + 0x98],
%l0, 0
%xcc,-0x28
[%l0 + 0x10],
-0x95284
%g0, %l3, %o0
-0x9528c
%l5, %o0
-0x95294
%g0, %l3, %o0
<sigtoproc>
<mutex_exit>
%o0
%l0
<signal+0x64>
%o0
<mutex_exit>
<mutex_exit>
<mutex_exit>
extend
crash> extend extlib1.so extlib2.so
./extlib1.so: shared object loaded
./extlib2.so: shared object loaded
オープン・ファイルを表示する
crash> files
files
PID: 895
TASK: c5934000 CPU: 0
ROOT: /
CWD: /opt/es7000/bin
FD
FILE
DENTRY
INODE
0 c6542480 c68ffa80 c60e0280
1 c6542480 c68ffa80 c60e0280
2 c6542480 c68ffa80 c60e0280
load
COMMAND: "krnl-1"
TYPE
CHR
CHR
CHR
::load
$<<
--
--
--
--
PATH
/dev/pts/0
/dev/pts/0
/dev/pts/0
システムのマルチタスクへのコマンドデータの表示を指示する
foreach
crash> foreach bt
PID: 0
TASK: c0494000 CPU: 0 COMMAND: "swapper"
#0 [c0495ec0] LKST_ETYPE_PROCESS_CONTEXTSWITCH_HEADER_hook at c012d782
#1 [c0495ec4] scheduler_tick at c01297ac
#2 [c0495f24] smp_apic_timer_interrupt at c012176b
#3 [c0495f78] cpu_idle at c0109309
PID: 0
(active)
TASK: c8704000 CPU: 1
COMMAND: "swapper"
PID: 0
(active)
TASK: c8500000 CPU: 2
COMMAND: "swapper"
PID: 0
(active)
TASK: c6c66000 CPU: 3
COMMAND: "swapper"
PID: 1
TASK: c8706000 CPU: 1 COMMAND: "init"
bt: cannot resolve stack trace:
#0 [c8707e00] LKST_ETYPE_PROCESS_CONTEXTSWITCH_HEADER_hook at c012d782
bt: text symbols on stack:
[c8707e40] schedule at c0129b24
[c8707e64] __put_task_struct at c012de8b
[c8707eb8] schedule_timeout at c0143045
[c8707ec4] __pollwait at c019faf1
[c8707ed8] process_timeout at c0142fd0
[c8707ef0] do_select at c019fdcb
[c8707f3c] dput at c01a4e70
[c8707f60] sys_select at c01a031e
[c8707fa8] sys_fstat64 at c0190bd9
[c8707fb4] no_timing at c04960d1
[c8707fc0] LKST_ETYPE_SYSCALL_ENTRY_HEADER_hook at c0496036
bt: possible exception frame:
USER-MODE EXCEPTION FRAME AT c8707fc4:
EAX: 0000008e EBX: 0000000b ECX: bfffcd50 EDX: 00000000
DS: 002b
ESI: 00000000 ES: 002b
EDI: bfffcc88
SS: 002b
ESP: bfffcc50 EBP: bfffcf68
CS: 0023
EIP: b7577308 ERR: 0000008e EFLAGS: 00000246
PID: 2
TASK: c6c64000 CPU: 0 COMMAND: "migration/0"
#0 [c6c65eb0] LKST_ETYPE_PROCESS_CONTEXTSWITCH_HEADER_hook at c012d782
#1 [c6c65ef0] schedule at c0129b1f
#2 [c6c65f68] migration_task at c012d398
#3 [c6c65ff0] kernel_thread_helper at c01097fb
PID: 3
TASK: f7fa6000 CPU: 1 COMMAND: "migration/1"
#0 [f7fa7eb0] LKST_ETYPE_PROCESS_CONTEXTSWITCH_HEADER_hook at c012d782
#1 [f7fa7ef0] schedule at c0129b1f
#2 [f7fa7f68] migration_task at c012d398
#3 [f7fa7ff0] kernel_thread_helper at c01097fb
- 4-7 -
PID: 4
TASK: f7fa4000 CPU: 2 COMMAND: "migration/2"
#0 [f7fa5eb0] LKST_ETYPE_PROCESS_CONTEXTSWITCH_HEADER_hook at c012d782
#1 [f7fa5ef0] schedule at c0129b1f
#2 [f7fa5f68] migration_task at c012d398
#3 [f7fa5ff0] kernel_thread_helper at c01097fb
指定されたファイルのユーザを表示する
crash> fuser /usr/lib/libkfm.so.2.0.0
fuser
PID
TASK
COMM
USAGE
779 c5e82000 "kwm"
mmap
808 c5a8e000 "krootwm"
mmap
806 c5b42000 "kfm"
mmap
809 c5dde000 "kpanel"
mmap
--
--
--
--
gdb コマンドを実行する
gdb
使用可能なコマンドの一覧を表示する lcrash のバージョン情報を表示する
help
crash> help
*
alias
ascii
bt
btop
dev
dis
eval
exit
extend
files
foreach
fuser
gdb
help
irq
kmem
list
log
mach
mod
mount
net
p
ps
pte
ptob
ptov
rd
repeat
runq
search
set
sig
struct
swap
sym
sys
task
timer
union
vm
vtop
waitq
whatis
wr
q
help
?
version
crash version: 3.8-5
gdb version: 6.1
For help on any command above, enter "help <command>".
For help on input options, enter "help input".
For help on output options, enter "help output".
>> help
?
addtypes
base
bt
defcpu
deftask
dis
dt
dump
findsym
fsym
h
help
history
id
::dcmds
info
ldcmds
load
main
md
mktrace
mmap
module
mt
namelist
nmlist
od
offset
p
page
pb
pd
po
print
ps
px
q
q!
quit
rd
report
savedump
set
sizeof
stat
strace
symbol
symtab
t
task
trace
unload
version
vi
vtop
walk
whatis
>> version
lcrash 0.9.2 (xlcrash) build at May 13 2004 23:41:53
Lcrash is free software. It is covered by the GNU General Public License.
You are welcome to change it and/or distribute copies of it under certain
conditions. Type "help -C" to see the conditions. Absolutely no warranty
is given for Lcrash. Type "help -W" for warranty details.
IRQ を表示する
irq
crash> irq
IRQ: 0
STATUS: 0
HANDLER: c03faae0
typename:
startup:
shutdown:
enable:
disable:
ack:
end:
set_affinity:
ACTION: c03f9d48
handler:
flags:
mask:
name:
dev_id:
next:
DEPTH: 0
--
--
<ioapic_edge_irq_type>
"IO-APIC-edge"
<startup_edge_ioapic_irq>
<disable_edge_ioapic_irq>
<unmask_IO_APIC_irq>
<disable_edge_ioapic_irq>
<ack_edge_ioapic_irq>
<end_edge_ioapic_irq>
<set_ioapic_affinity>
<irq0>
c01151a0 <timer_interrupt>
20000000 (SA_INTERRUPT)
0
c032db68 "timer"
0
0
c032d13e
c0122f40
c0122f30
c0122430
c0122f30
c0123090
c01230c0
c01232c0
- 4-8 -
$<
$<<
$>
$?
$C
$G
$P
$Q
$V
$W
$X
$Y
$b
$c
$d
$e
$f
$g
$i
-
replace input with macro file
source macro file
log session to a file
print status and registers
print stack backtrace
enable/disable C++ demangling support
set debugger prompt string
quit debugger
get/set disassembly mode
re-open target in write mode
print floating point registers
print floating point registers
list traced software events
print stack backtrace
get/set default output radix
print listing of global symbols
print listing of source files
get/set C++ demangling options
print signals that are ignored
IRQ: 1
STATUS: 0
HANDLER: c03faae0
typename:
startup:
shutdown:
enable:
disable:
ack:
end:
set_affinity:
ACTION: c86fdd80
handler:
flags:
mask:
name:
dev_id:
next:
DEPTH: 0
IRQ: 2
STATUS: 0
HANDLER: c03f9760
typename:
startup:
shutdown:
enable:
disable:
ack:
end:
set_affinity:
ACTION: c03f979c
handler:
flags:
mask:
name:
dev_id:
next:
DEPTH: 0
c032d13e
c0122f40
c0122f30
c0122430
c0122f30
c0123090
c01230c0
c01232c0
<ioapic_edge_irq_type>
"IO-APIC-edge"
<startup_edge_ioapic_irq>
<disable_edge_ioapic_irq>
<unmask_IO_APIC_irq>
<disable_edge_ioapic_irq>
<ack_edge_ioapic_irq>
<end_edge_ioapic_irq>
<set_ioapic_affinity>
c02078e0 <keyboard_interrupt>
0
0
c032b4a1 "keyboard"
0
0
c032b47e
c0112d20
c0112d40
c0112e80
c0112d40
c0112d40
c0112d00
0
<i8259A_irq_type>
"XT-PIC"
<startup_8259A_irq>
<disable_8259A_irq>
<enable_8259A_irq>
<disable_8259A_irq>
<disable_8259A_irq>
<end_8259A_irq>
<irq2>
c010e390 <no_action>
0
0
c032b489 "cascade"
0
0
IRQ: 3
STATUS: 26 (IRQ_DISABLED|IRQ_PENDING|IRQ_WAITING)
HANDLER: c03faae0
<ioapic_edge_irq_type>
typename: c032d13e "IO-APIC-edge"
startup: c0122f40 <startup_edge_ioapic_irq>
shutdown: c0122f30 <disable_edge_ioapic_irq>
enable: c0122430 <unmask_IO_APIC_irq>
disable: c0122f30 <disable_edge_ioapic_irq>
ack: c0123090 <ack_edge_ioapic_irq>
end: c01230c0 <end_edge_ioapic_irq>
set_affinity: c01232c0 <set_ioapic_affinity>
ACTION: (none)
DEPTH: 0
カーネルメモリ情報の表示
kmem
crash> kmem –f
NODE
0
ZONE NAME
SIZE
FREE MEM_MAP START_PADDR START_MAPNR
0 DMA
4096
2678 c100002c
0
0
AREA
SIZE FREE_AREA_STRUCT BLOCKS PAGES
0
4k
c0449d58
0
0
1
8k
c0449d64
1
2
-::kmalo
g
::kmast
- 4-9 -
> ::kmalog slab
T-0.000000000 addr=301f6d26000 kmem_magazine_3
kmem_slab_create+0x278
kmem_slab_alloc+0x44
kmem_cache_alloc+0x154
kmem_cache_free+0xfc
ufs_idle_some+0x164
ufs_thread_idle+0x1b4
2
3
4
5
6
7
8
9
10
16k
32k
64k
128k
256k
512k
1024k
2048k
4096k
c0449d70
c0449d7c
c0449d88
c0449d94
c0449da0
c0449dac
c0449db8
c0449dc4
c0449dd0
1
0
1
1
1
0
0
1
2
4
0
16
32
64
0
0
512
2048
at
::kmaus
ers
::kmem_
cache
::kmem_
ZONE NAME
SIZE
FREE MEM_MAP START_PADDR START_MAPNR
1 Normal
225280
2957 c103c02c
1000000
4096
AREA
SIZE FREE_AREA_STRUCT BLOCKS PAGES
0
4k
c044b058
1357 1357
1
8k
c044b064
150
300
2
16k
c044b070
7
28
3
32k
c044b07c
1
8
4
64k
c044b088
3
48
5
128k
c044b094
0
0
6
256k
c044b0a0
1
64
7
512k
c044b0ac
1
128
8
1024k
c044b0b8
0
0
9
2048k
c044b0c4
0
0
10
4096k
c044b0d0
1 1024
log
::kmem_
verify
T-0.002343800 addr=301f982c000 kmem_magazine_3
kmem_slab_create+0x278
kmem_slab_alloc+0x44
kmem_cache_alloc+0x154
kmem_cache_free+0xfc
ufs_idle_some+0x164
ufs_thread_idle+0x1b4
T-0.004701200 addr=301f982a000 kmem_magazine_3
kmem_slab_create+0x278
kmem_slab_alloc+0x44
kmem_cache_alloc+0x154
kmem_cache_free+0xfc
ufs_idle_some+0x164
ufs_thread_idle+0x1b4
nr_free_pages: 6704 (verified)
>::kmastat
cache
name
------------------------kmem_magazine_1
kmem_magazine_3
kmem_magazine_7
kmem_magazine_15
kmem_magazine_31
kmem_magazine_47
kmem_magazine_63
kmem_magazine_95
kmem_magazine_143
kmem_slab_cache
kmem_bufctl_cache
kmem_bufctl_audit_cache
kmem_va_8192
kmem_va_16384
kmem_va_24576
kmem_va_32768
kmem_va_40960
kmem_va_49152
kmem_va_57344
kmem_va_65536
>kmem –F
NODE
0
ZONE NAME
0 DMA
AREA
SIZE
0
4k
AREA
SIZE
1
8k
c101655c
AREA
SIZE
2
16k
c101646c
AREA
SIZE
3
32k
AREA
SIZE
4
64k
c1000b6c
AREA
SIZE
5
128k
c1001e2c
AREA
SIZE
> ::kmem_cache
ADDR
0000030000008008
0000030000008248
0000030000008488
00000300000086c8
0000030000008908
0000030000008b48
0000030000008d88
0000030000008fc8
0000030000009208
0000030000009448
0000030000009688
00000300000098c8
0000030000009b08
000003000000a008
000003000000a248
000003000000a488
000003000000a6c8
000003000000a908
000003000000ab48
000003000000ad88
ZONE NAME
SIZE
FREE MEM_MAP START_PADDR START_MAPNR
2 HighMem 1376256
1069 c1d2002c
38000000
229376
AREA
SIZE FREE_AREA_STRUCT BLOCKS PAGES
0
4k
c044c358
7
7
1
8k
c044c364
3
6
2
16k
c044c370
0
0
3
32k
c044c37c
96
768
4
64k
c044c388
4
64
5
128k
c044c394
1
32
6
256k
c044c3a0
1
64
7
512k
c044c3ac
1
128
8
1024k
c044c3b8
0
0
9
2048k
c044c3c4
0
0
10
4096k
c044c3d0
0
0
SIZE
FREE MEM_MAP START_PADDR START_MAPNR
4096
2678 c100002c
0
0
FREE_AREA_STRUCT
c0449d58
FREE_AREA_STRUCT
c0449d64
FREE_AREA_STRUCT
c0449d70
FREE_AREA_STRUCT
c0449d7c
FREE_AREA_STRUCT
c0449d88
FREE_AREA_STRUCT
c0449d94
FREE_AREA_STRUCT
- 4-10 -
buf
buf
buf
memory
alloc alloc
size in use total
in use succeed fail
------ ------ ------ --------- --------- ----16 1248 1524
24576
1248
0
32 4113 4318
139264
4113
0
64 2166 2286
147456
2166
0
128 1695 1701
221184
1695
0
256
0
0
0
0
0
384
0
0
0
0
0
512
0
0
0
0
0
768
0
0
0
0
0
1152
0
0
0
0
0
56 2430 2465
139264
2430
0
24 10830 10848
262144
10830
0
128
0
0
0
0
0
8192 5609 5632 46137344
5609
0
16384
17
32
524288
17
0
24576
12
20
524288
12
0
32768
0
0
0
0
0
40960
0
0
0
0
0
49152
0
0
0
0
0
57344
0
0
0
0
0
65536
0
0
0
0
0
NAME
kmem_magazine_1
kmem_magazine_3
kmem_magazine_7
kmem_magazine_15
kmem_magazine_31
kmem_magazine_47
kmem_magazine_63
kmem_magazine_95
kmem_magazine_143
kmem_slab_cache
kmem_bufctl_cache
kmem_bufctl_audit_cache
kmem_va_8192
kmem_va_16384
kmem_va_24576
kmem_va_32768
kmem_va_40960
kmem_va_49152
kmem_va_57344
kmem_va_65536
FLAG
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0200
0200
0200
0200
0200
0200
0200
0200
CFLAG BUFSIZE BUFTOTL
080000
16
1524
080000
32
4318
080000
64
2286
080000
128
1701
080000
256
0
080000
384
0
080000
512
0
080000
768
0
080000
1152
0
080000
56
2465
080000
24
10848
080000
128
0
110000
8192
5632
110000
16384
32
110000
24576
20
110000
32768
0
110000
40960
0
110000
49152
0
110000
57344
0
0
110000
65536
6
256k
c1000f2c
AREA
SIZE
7
512k
AREA
SIZE
8
1024k
AREA
SIZE
9
2048k
c101682c
AREA
SIZE
10
4096k
c102d02c
c101e02c
c0449da0
000003000000afc8 kmem_alloc_8
000003000000b208 kmem_alloc_16
FREE_AREA_STRUCT
c0449dac
FREE_AREA_STRUCT
c0449db8
FREE_AREA_STRUCT
c0449dc4
> ::kmem_verify
Cache Name
kmem_alloc_8
kmem_alloc_16
kmem_alloc_24
kmem_alloc_32
kmem_alloc_40
kmem_alloc_48
FREE_AREA_STRUCT
c0449dd0
ZONE NAME
SIZE
FREE MEM_MAP START_PADDR START_MAPNR
1 Normal
225280
2976 c103c02c
1000000
4096
AREA
SIZE FREE_AREA_STRUCT
0
4k
c044b058
c1999854
c1a45550
c1b1a55c
c15e8a70
c125a8f4
c1aa2688
c182322c
>kmem –p
PAGE
c100002c
c1000068
c10000a4
c10000e0
c100011c
c1000158
c1000194
c10001d0
c100020c
c1000248
c1000284
c10002c0
c10002fc
c1000338
c1000374
c10003b0
c10003ec
c1000428
c1000464
c10004a0
c10004dc
c1000518
PHYSICAL
0
1000
2000
3000
4000
5000
6000
7000
8000
9000
a000
b000
c000
d000
e000
f000
10000
11000
12000
13000
14000
15000
MAPPING
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
INDEX CNT
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
FLAGS
8000
8000
8000
8000
8000
8000
8000
8000
8000
8000
8000
8000
0
0
0
0
0
0
0
0
0
0
crash> kmem –C
page_hash_table[0]
c45070e0
page_hash_table[1]
c45070a4
page_hash_table[2]
c3d71b64
c4507068
page_hash_table[3]
c4036b9c
c450702c
page_hash_table[4]
c4517670
- 4-11 -
0000 200000
0000 200000
8
16
6102
3048
Addr
Cache Integrity
70039428 clean
700396a8 clean
70039928 1 corrupt buffer
70039ba8 clean
7003a028 clean
7003a2a8 clean
page_hash_table[5]
c4517634
page_hash_table[6]
c45175f8
page_hash_table[7]
c45175bc
page_hash_table[8]
c4517580
page_hash_table[9]
c4517544
page_hash_table[10]
crash> kmem -i
PAGES
TOTAL MEM 1547863
FREE
6036
USED 1541827
SHARED 769436
BUFFERS
71882
CACHED 1428557
SLAB
31825
TOTAL
5.9 GB
23.6 MB
5.9 GB
2.9 GB
280.8 MB
5.4 GB
124.3 MB
PERCENTAGE
---0% of TOTAL MEM
99% of TOTAL MEM
49% of TOTAL MEM
4% of TOTAL MEM
92% of TOTAL MEM
2% of TOTAL MEM
TOTAL HIGH 1343440
FREE HIGH
374
TOTAL LOW 204423
FREE LOW
5662
5.1
1.5
798.5
22.1
86%
0%
13%
2%
TOTAL SWAP 1536213
SWAP USED
0
SWAP FREE 1536213
crash>kmem –s
ACHE
NAME
c0448880 kmem_cache
dc76cecc ip_fib_hash
f67c4afc urb_priv
f67c4bf0 ext3_xattr
f67c4ce4 journal_head
f67c4dd8 revoke_table
f67c4ecc revoke_record
c87aedd8 clip_arp_cache
c87aeecc ip_mrt_cache
c874f080 tcp_tw_bucket
c874f174 tcp_bind_bucket
c874f268 tcp_open_request
c874f35c inet_peer_cache
c874f450 secpath_cache
c874f544 xfrm_dst_cache
c874f638 ip_dst_cache
c874f72c arp_cache
c874f820 flow_cache
c874f914 blkdev_requests
c874fa08 kioctx
c874fafc kiocb
c874fbf0 dnotify_cache
GB
MB
MB
MB
of
of
of
of
TOTAL
TOTAL
TOTAL
TOTAL
MEM
HIGH
MEM
LOW
5.9 GB
---0
0% of TOTAL SWAP
5.9 GB 100% of TOTAL SWAP
OBJSIZE ALLOCATED
244
72
32
11
64
0
44
0
48
29
12
3
32
0
256
0
128
0
128
0
32
18
128
0
64
0
128
0
256
0
256
19
256
2
128
0
128
12288
128
0
128
0
20
0
crash>kmem –S
CACHE
NAME
OBJSIZE ALLOCATED
c0448880 kmem_cache
244
72
SLAB
MEMORY
TOTAL ALLOCATED FREE
dc76c000 dc76c080
16
1
15
FREE / [ALLOCATED]
dc76c080 (cpu 0 cache)
dc76c174 (cpu 0 cache)
TOTAL SLABS SSIZE
112
7
4k
336
3
4k
0
0
4k
0
0
4k
462
6
4k
500
2
4k
0
0
4k
0
0
4k
0
0
4k
0
0
4k
560
5
4k
0
0
4k
0
0
4k
0
0
4k
0
0
4k
150
10
4k
15
1
4k
0
0
4k
12840
428
4k
0
0
4k
0
0
4k
0
0
4k
TOTAL SLABS SSIZE
112
7
4k
- 4-12 -
dc76c268 (cpu 0
dc76c35c (cpu 0
dc76c450 (cpu 0
dc76c544 (cpu 0
dc76c638 (cpu 0
dc76c72c (cpu 0
dc76c820 (cpu 0
dc76c914 (cpu 0
dc76ca08 (cpu 0
dc76cafc (cpu 0
dc76cbf0 (cpu 0
dc76cce4 (cpu 0
dc76cdd8 (cpu 0
[dc76cecc]
SLAB
MEMORY
f67c4000 f67c4080
FREE / [ALLOCATED]
f67c4080 (cpu 3
f67c4174 (cpu 3
f67c4268 (cpu 3
f67c435c (cpu 3
f67c4450 (cpu 3
f67c4544 (cpu 3
f67c4638 (cpu 3
f67c472c (cpu 3
f67c4820 (cpu 3
f67c4914 (cpu 3
f67c4a08 (cpu 3
[f67c4afc]
[f67c4bf0]
[f67c4ce4]
[f67c4dd8]
[f67c4ecc]
cache)
cache)
cache)
cache)
cache)
cache)
cache)
cache)
cache)
cache)
cache)
cache)
cache)
TOTAL ALLOCATED FREE
16
5
11
cache)
cache)
cache)
cache)
cache)
cache)
cache)
cache)
cache)
cache)
cache)
crash> kmem –v
VM_STRUCT
ADDRESS
c86fde40 f8800000 c87909c0 f880d000 c8790780 f882d000 f688bf40 f882f000 f688bec0 f8834000 c86cff40 f8836000 c86cfec0 f8843000 c86cfe80 f8845000 c86cfd80 f8847000 c86cff00 f8849000 c86cfcc0 f8857000 f67c7f40 f8859000 f67c7ec0 f886a000 f67c7f00 f886c000 f67c7e40 f8885000 c86cf6c0 f8887000 c86cf640 f889f000 f67c7e80 f88a1000 f67c7d00 f88aa000 f67c7d40 f88ac000 f67c7a40 f88af000 f67c7a80 f88b1000 -
RANGE
SIZE
f880d000 53248
f882d000 131072
f882f000
8192
f8834000 20480
f8836000
8192
f8843000 53248
f8845000
8192
f8847000
8192
f8849000
8192
f8857000 57344
f8859000
8192
f886a000 69632
f886c000
8192
f8885000 102400
f8887000
8192
f889f000 98304
f88a1000
8192
f88aa000 36864
f88ac000
8192
f88af000 12288
f88b1000
8192
f88b8000 28672
crash >kmem –n
ODE
SIZE
PGLIST_DATA
0 1605632
c0448b80
BOOTMEM_DATA
c0577344
NODE_ZONES
c0448b80
c0449e80
c044b180
- 4-13 -
MEM_MAP START_PADDR START_MAPNR
c100002c
0
0
ZONE
0
1
2
NAME
DMA
Normal
HighMem
SIZE MEM_MAP START_PADDR START_MAPNR
4096 c100002c
0
0
225280 c103c02c
1000000
4096
1376256 c1d2002c
38000000
229376
リンクしたリストを表示する カーネル構造体またはメモリブロックのリンクされたリストをたどる
crash> list task_struct.p_pptr c169a000
>> walk -l
list
walk
c169a000
NUM NAME
SIZE
c0440000
===================================
c50d0000
0 mm_struct
292
c0562000
1 page
56
c0d28000
2 task_struct
1792
c7894000
3 vm_area_struct
68
c6a98000
4 module
96
c009a000
===================================
c0252000
>> walk list_head next 0xc03738c4 -h n -t
STRUCT ADDR
PREV LISTHEAD
NEXT
============================================
0 0xc6d80d08 0xc03738c4 0xc6d22108
0xc6d22108 0xc03738c4 0xc6d22108 0xc13e3a88
0xc13e3a88 0xc6d22108 0xc13e3a88 0xc6df0b88
0xc6df0b88 0xc13e3a88 0xc6df0b88 0xc7fccc88
0xc7fccc88 0xc6df0b88 0xc7fccc88 0xc6d21788
0xc6d21788 0xc7fccc88 0xc6d21788 0xc6d33088
0xc6d33088 0xc6d21788 0xc6d33088 0xc6d33288
0xc6d33288 0xc6d33088 0xc6d33288 0xc6d21d88
0xc6d21d88 0xc6d33288 0xc6d21d88 0xc6d21b88
0xc6d21b88 0xc6d21d88 0xc6d21b88 0xc6d21988
0xc6d21988 0xc6d21b88 0xc6d21988 0xc7fcc288
0xc7fcc288 0xc6d21988 0xc7fcc288 0xc6d21588
0xc6d21588 0xc7fcc288 0xc6d21588 0xc6d21388
0xc6d21388 0xc6d21588 0xc6d21388 0xc6d21188
0xc6d21188 0xc6d21388 0xc6d21188 0xc7fcc688
0xc7fcc688 0xc6d21188 0xc7fcc688 0xc7fcca88
0xc7fcca88 0xc7fcc688 0xc7fcca88 0xc7fcc888
0xc7fcc888 0xc7fcca88 0xc7fcc888 0xc7fcc488
0xc7fcc488 0xc7fcc888 0xc7fcc488 0xc12b6d08
0xc12b6d08 0xc7fcc488 0xc12b6d08 0xc6dd6b08
0xc6dd6b08 0xc12b6d08 0xc6dd6b08 0xc6dd6508
0xc6dd6508 0xc6dd6b08 0xc6dd6508 0xc6d69288
0xc6d69288 0xc6dd6508 0xc6d69288 0xc6df0d88
0xc6df0d88 0xc6d69288 0xc6df0d88 0xc6df0188
0xc6df0188 0xc6df0d88 0xc6df0188 0xc6d80d08
0xc6d80d08 0xc6df0188 0xc6d80d08 0xc03738c4
============================================
walk
ダンプ・システム・メッセージ・バッファーを表示する
log
Linux version 2.4.21-9.30AX ([email protected]) (gcc version 3.2.3 20030502
(
Asianux 1.0 3.2.3-35AX)) #1 Thu May 27 00:03:41 EDT 2004
BIOS-provided physical RAM map:
BIOS-e820: 0000000000000000 - 000000000009f800 (usable)
BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)
BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
BIOS-e820: 0000000000100000 - 0000000007fe0000 (usable)
BIOS-e820: 0000000007fe0000 - 0000000007ff8000 (ACPI data)
BIOS-e820: 0000000007ff8000 - 0000000008000000 (ACPI NVS)
BIOS-e820: 00000000ffff0000 - 0000000100000000 (reserved)
--
--
- 4-14 -
0MB HIGHMEM available.
127MB LOWMEM available.
On node 0 totalpages: 32736
zone(0): 4096 pages.
zone(1): 28640 pages.
zone(2): 0 pages.
Kernel command line: ro root=LABEL=/
Initializing CPU#0
Detected 451.031 MHz processor.
Console: colour VGA+ 80x25
Calibrating delay loop... 897.84 BogoMIPS
Memory: 120128k/130944k available (1573k kernel code, 9408k reserved, 1199k data
, 164k init, 0k highmem)
マシン固有のデータを表示する
crash> mach
mach
MACHINE TYPE:
MEMORY SIZE:
CPUS:
PROCESSOR SPEED:
HZ:
PAGE SIZE:
L1 CACHE SIZE:
KERNEL VIRTUAL BASE:
KERNEL VMALLOC BASE:
KERNEL STACK SIZE:
i686
128 MB
1
451 Mhz
100
4096
128
c0000000
c8800000
8192
--
::cpuin
fo
> ::cpuinfo
ID ADDR
FLG NRUN BSPL PRI RNRN KRNRN SWITCH THREAD
PROC
0 000014315b0 1b
0
0 0 no
no t-0
3000333a2e0 reboot
モジュール情報およびシンボルとデバッグするデータのロードをおこなう ロードしたモジュールまたはモジュールシンボルを表示する
mod
rash> mod
MODULE
c880d000
c881d000
c8835000
c884b000
c8855000
c885a000
c8863000
c8868000
c8891000
c88aa000
c88c5000
c88cf000
c88e2000
NAME
SIZE OBJECT FILE
jbd
50572 (not loaded) [CONFIG_KALLSYMS]
ext3
85704 (not loaded) [CONFIG_KALLSYMS]
usbcore
77152 (not loaded) [CONFIG_KALLSYMS]
usb-uhci
25836 (not loaded) [CONFIG_KALLSYMS]
input
5856 (not loaded) [CONFIG_KALLSYMS]
hid
22084 (not loaded) [CONFIG_KALLSYMS]
mousedev
5492 (not loaded) [CONFIG_KALLSYMS]
keybdev
2976 (not loaded) [CONFIG_KALLSYMS]
microcode
5816 (not loaded) [CONFIG_KALLSYMS]
scsi_mod 103336 (not loaded) [CONFIG_KALLSYMS]
sg
36140 (not loaded) [CONFIG_KALLSYMS]
floppy
56688 (not loaded) [CONFIG_KALLSYMS]
e100
56880 (not loaded) [CONFIG_KALLSYMS]
crash> mod -S
mod: NOTE: /lib/jbd.o: installed from initrd image
MODULE NAME
SIZE OBJECT FILE
c880d000 jbd
50572 /lib/modules/2.4.21-9.30AX/kernel/fs/jbd/jbd.o
mod: NOTE: /lib/ext3.o: installed from initrd image
c881d000 ext3
85704 /lib/modules/2.4.21-9.30AX/kernel/fs/ext3/ext3.o
c8835000 usbcore
77152 /lib/modules/2.4.21-9.30AX/kernel/drivers/usb/usbcore.o
c884b000 usb-uhci
25836 /lib/modules/2.4.21-9.30AX/kernel/drivers/usb/host/usb-uhci.o
c8855000 input
5856 /lib/modules/2.4.21-9.30AX/kernel/drivers/input/input.o
c885a000 hid
22084 /lib/modules/2.4.21-9.30AX/kernel/drivers/usb/hid.o
c8863000 mousedev
5492 /lib/modules/2.4.21-9.30AX/kernel/drivers/input/mousedev.o
c8868000 keybdev
2976 /lib/modules/2.4.21-9.30AX/kernel/drivers/input/keybdev.o
c8891000 microcode
5816 /lib/modules/2.4.21-9.30AX/kernel/arch/i386/kernel/microcode.o
c88aa000 scsi_mod 103336 /lib/modules/2.4.21-9.30AX/kernel/drivers/scsi/scsi_mod.o
c88c5000 sg
36140 /lib/modules/2.4.21-9.30AX/kernel/drivers/scsi/sg.o
module
>> module
ADDR
SIZE USED NAME
REFS
====================================================================
=======
0xc88e2000
56880
1 e100
[]
0xc88cf000
56688
0 floppy
[]
0xc88c5000
36140
0 sg
[]
0xc88aa000
103336
1 scsi_mod
[sg]
0xc8891000
5816
0 microcode
[]
0xc8868000
2976
0 keybdev
[]
0xc8863000
5492
0 mousedev
[]
0xc885a000
22084
0 hid
[]
0xc8855000
5856
0 input
[keybdev
mousedev
hid]
0xc884b000
25836
0 usb-uhci
[]
0xc8835000
77152
1 usbcore
[hid
usb-uhci]
0xc881d000
85704
3 ext3
[]
0xc880d000
50572
3 jbd
[ext3]
0xc0354fc0
0
1 kernel_module
[]
====================================================================
=======
>> module -f | more
EXPORTED MODULE SYMBOLS:
====================================================================
=======
Module: e100
Number of exported symbols: 69
ADDR NAME [MODULE]
--------------------------------------------------------------------------
- 4-15 -
::ctfin
fo
::modin
fo
::modct
l
>::ctfinfo
MODULE
unix
krtld
genunix
platmod
SUNW,UltraSPARC-III
specfs
TS
TS_DPTBL
ufs
fssnap_if
rootnex
options
sad
pseudo
schppm
xcalppm
ebus
pcisch
ssd
scsi
fcp
fctl
>::modinfo
ID
LOADADDR
0
1000000
1
105db8c
2
1070268
3
1170cd0
4
1171200
5
0
6
117e000
CTFDATA
300000b6000
0
30000100000
3000012a000
30000130000
3000021a000
3000025e000
3000012b87c
300002fe000
3000012ba48
30000306000
30000135f60
3000012be64
3000012bf2c
300000bf260
3000030c000
300000bf30c
30000330000
30000388000
3000035c000
3000037c000
30000304188
CTFSIZE
37472
0
165890
6267
17123
16370
11554
460
24965
703
10438
115
197
150
171
11995
879
18560
20851
14540
19078
6172
SIZE REV MODULE NAME
97d84 0 unix (?)
1873a 0 krtld (?)
14a31f 0 genunix (?)
709 0 platmod (?)
cac9 0 SUNW,UltraSPARC-III (?)
0 0 cl_bootstrap (?)
43db 1 specfs (filesystem for specfs)
0xc88e52e0
0xc88e92c0
0xc88ee60c
0xc88e9d20
0xc88e9980
0xc88e6d20
0xc88e9900
0xc88e3de0
0xc88e9680
0xc88e7e20
0xc88ee140
0xc88e74b0
0xc88e86f0
0xc88e2c50
0xc88e5220
e100_configure_device
e100_force_speed_duplex_to_phy
e100_full_driver_name
e100_eeprom_read
e100_handle_zlock
e100_alloc_non_tx_cmd
e100_update_link_state
e100_tx_srv
e100_phy_set_speed_duplex
e100_config_promisc
__insmod_e100_S.data_L7404
e100_wait_cus_idle
e100_mdi_read
e100_close
e100_isolate_driver
[e100]
[e100]
[e100]
[e100]
[e100]
[e100]
[e100]
[e100]
[e100]
[e100]
[e100]
[e100]
[e100]
[e100]
[e100]
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>> module -p | more
c88e52e0 e100_configure_device [e100]
c88e92c0 e100_force_speed_duplex_to_phy [e100]
c88ee60c e100_full_driver_name [e100]
c88e9d20 e100_eeprom_read
[e100]
c88e9980 e100_handle_zlock
[e100]
c88e6d20 e100_alloc_non_tx_cmd [e100]
c88e9900 e100_update_link_state [e100]
c88e3de0 e100_tx_srv
[e100]
c88e9680 e100_phy_set_speed_duplex
[e100]
c88e7e20 e100_config_promisc
[e100]
c88ee140 __insmod_e100_S.data_L7404
[e100]
c88e74b0 e100_wait_cus_idle
[e100]
c88e86f0 e100_mdi_read [e100]
c88e2c50 e100_close
[e100]
c88e5220 e100_isolate_driver
[e100]
c88e7a10 e100_config_init_82557 [e100]
c88e7be0 e100_force_config
[e100]
c88e32d0 e100_hw_init [e100]
c88e4ba0 e100_exec_non_cu_cmd [e100]
c88e3930 e100_watchdog [e100]
c88e4290 e100_refresh_txthld
[e100]
c88e9800 e100_phy_init [e100]
マウントされているファイルシステムに関する情報を出力する
crash> mount
mount
VFSMOUNT SUPERBLK TYPE DEVNAME DIRNAME
c1544100 c1542000 rootfs rootfs
/
c1544380 c148b000 ext3 /dev/root /
c1544340 c1542800 proc /proc
/proc
c1544300 c148bc00 usbdevfs usbdevfs /proc/bus/usb
c15443c0 c1530c00 ext3 /dev/hda1 /boot
c1544400 c1530400 devpts none
/dev/pts
c1544440 c7faa000 tmpfs none
/dev/shm
c1544480 c7faa400 ext3 /dev/hda2 /var
crash> mount –f
VFSMOUNT SUPERBLK TYPE DEVNAME
c1544100 c1542000 rootfs rootfs
OPEN FILES
No open files found
VFSMOUNT SUPERBLK TYPE
c1544380 c148b000 ext3
OPEN FILES
DENTRY
INODE
TYPE
c12bae00 c12c2b00 REG
--
MODCTL
142c5f0
143fa58
1440258
148c5b8
148f208
3000005bf08
3000005be88
3000005be08
3000005bd88
3000005bd08
3000005bb88
3000005bb08
3000005ba88
3000005ba08
3000005b908
3000005b988
3000005b888
3000005b808
3000005b788
3000005b708
3000005b688
3000005b608
o
DEVNAME DIRNAME
/dev/root /
PATH
lib/tls/libc-2.3.2.so
- 4-16 -
0
38dc
8dc
3493e
1c7
1b3a
210
0
181a
64b
434
2d85
15cb
11b05
23063
0
1
1
1
1
1
1
0
1
1
1
1
1
1
1
swapgeneric (?)
TS (time sharing sched class)
TS_DPTBL (Time sharing dispatch table)
ufs (filesystem for ufs)
fssnap_if (File System Snapshot Interface)
rootnex (sun4u root nexus 1.95)
options (options driver)
dma (?)
sad (STREAMS Administrative Driver ')
pseudo (nexus driver for 'pseudo')
schppm (schizo pm driver v1.2)
xcalppm (platform pm driver v1.18)
ebus (ebus nexus driver 1.44)
pcisch (PCI Bus nexus driver 1.214)
ssd (SCSI SSA/FCAL Disk Driver 1.418)
>::modctl
::fsinf
DIRNAME
/
0
1183ba8
1186d20
1186db0
11b8cae
11b8dce
11ba4fb
0
11babd7
11bc151
11bc62a
11bc97e
11bf2a3
11c0456
11d05fb
MODULE BITS FLAGS FILE
143a720
0x00 /platform/sun4u/kernel/sparcv9/unix
143fb00
0x00 misc/sparcv9/krtld
14402f0
0x00 genunix
148c658
0x00 misc/platmod
148f2b0
0x00 cpu/SUNW,UltraSPARC-III
0
0x00 misc/cl_bootstrap
3000006fe08
li 0x00 fs/specfs
0
0x00 misc/swapgeneric
3000006fb88
li 0x00 sched/TS
3000006fa48
li 0x00 sched/TS_DPTBL
3000006f908
li 0x00 fs/ufs
3000006f7c8
li 0x00 misc/fssnap_if
3000006f688
li 0x00 drv/rootnex
3000006f548
li 0x00 drv/options
0
0x00 drv/dma
3000006f2c8
li 0x00 drv/sad
3000006f188
li 0x00 drv/pseudo
3000006f048
li 0x00 drv/schppm
3000006ef08
li 0x00 drv/xcalppm
3000006edc8
li 0x00 drv/ebus
3000006ec88
li 0x00 drv/pcisch
3000006eb48
li 0x00 drv/ssd
> ::fsinfo
VFSP TYP
146bef8 2
3000026f688 5
3000026f5e8 15
3000026f4a8 12
3000026f368 4
3000026f2c8 4
3000026f228 4
3000026f188 11
3000026f0e8 4
3000026f048 4
3000026efa8 11
3000026ef08 2
3000026edc8 17
3000026ed28 17
3000026ebe8 17
3000026eb48 4
3000026eaa8 4
3000026e3c8
300032f5e10 7
3000026e008 4
DATA OPS
MOUNT
30000041dc8 ufs_vfsops
/
300008b8b10 prvfsops
/proc
30000273868 mntvfsops
/etc/mnttab
0 fdvfsops
/dev/fd
30000b948e8 nmvfsops
/etc/sysevent/devfsad...
30000b94a28 nmvfsops
/etc/sysevent/syseven...
30000b947a8 nmvfsops
/etc/sysevent/syseven...
30000973290 tmp_vfsops
/var/run
30000b943e8 nmvfsops
/etc/sysevent/picleve...
300013c3cf0 nmvfsops
/var/run/picld_door
300013d7c48 tmp_vfsops
/tmp
30000041508 ufs_vfsops
/space
3000026d558 auto_vfsops
/net
3000026d4a8 auto_vfsops
/home
3000026d3f8 auto_vfsops
/xfn
300015cdd08 nmvfsops
/var/run/syslog_door
300015cdbc8 nmvfsops
/var/run/name_service...
4
300015cd588 nmvfsops
/etc/saf/_cmdpipe
300032b4aa8 nfs_vfsops
/vol
3000320d328 nmvfsops
/tmp/.X11-pipe/X0
c12bab00
c5c00880
c59a2b80
c6eadc00
c6eada00
c6ead980
c6ead880
c7031a00
c7031680
c7031580
c7031480
c609f780
c609f700
c12c2100
c5c0c680
c5911480
c6e44180
c6e73d00
c6e73b00
c6e73700
c6f27500
c6fd6680
c6fd6280
c703bd80
c6064680
c6064480
REG
REG
REG
REG
REG
REG
REG
REG
REG
REG
REG
REG
REG
lib/ld-2.3.2.so
opt/es7000/bin/krnl-1
usr/share/locale/ja/LC_MESSAGES/libc.mo
usr/lib/gconv/libJIS.so
usr/lib/gconv/EUC-JP.so
usr/lib/gconv/gconv-modules.cache
usr/lib/locale/locale-archive
lib/libnss_files-2.3.2.so
lib/libdl-2.3.2.so
lib/libtermcap.so.2.0.8
bin/bash
lib/security/pam_limits.so
usr/lib/libcrack.so.2.7
crash> mount –i
FSMOUNT SUPERBLK TYPE DEVNAME
c1544100 c1542000 rootfs rootfs
DIRTY INODES
No dirty inodes found
300032f5af0 10
3000321f6b0 lo_vfsops
/home/sasaki
DIRNAME
/
VFSMOUNT SUPERBLK TYPE
c1544380 c148b000 ext3
DIRTY INODES
c12c2b08
c12c2908
c12c2508
c12c2108
c12b8c88
c5c0c688
DEVNAME DIRNAME
/dev/root /
VFSMOUNT SUPERBLK TYPE
c1544340 c1542800 proc
DIRTY INODES
No dirty inodes found
DEVNAME
/proc
DIRNAME
/proc
VFSMOUNT SUPERBLK TYPE DEVNAME DIRNAME
c1544300 c148bc00 usbdevfs usbdevfs /proc/bus/usb
DIRTY INODES
ネットワーク情報を表示する
crash> net
net
NET_DEVICE NAME
c037fec0 lo
c7e49000 eth0
crash> net -a
IP ADDRESS
172.24.33.254
(REACHABLE)
--
IP ADDRESS(ES)
127.0.0.1
172.24.33.85
::netst
at
::ire
HW TYPE
ETHER
HW ADDRESS
DEVICE STATE
00:09:b7:a0:43:80 eth0
crash> net -s
PID: 895
TASK: c5934000 CPU: 0
No open sockets.
::tcpb
02
COMMAND: "krnl-1"
- 4-17 -
>::netstat
TCPv4
St Local Address
Remote Address
000003000320c090 0
172.24.33.60.23
172.24.32.13.3195
TCPv6
St
Local Address
Remote Address
UDPv4
St Local Address
Remote Address
UDPv6
St
Local Address
Remote Address
AF_UNIX
Type
Vnode
Conn
Local Addr
Remote Addr
300018468f8
stream-ord 00000300098f96a0 0000000000000000
/var/run/smc898/cmdsock (none)
30001846ac0
stream-ord 0000000000000000 0000000000000000 (none)
(none)
30001846c88
stream-ord 0000030003290de0 0000000000000000
/tmp/.X11-unix/X0
(none)
30001846e50
dgram
0000000000000000 0000000000000000 (none)
(none)
30001847018
dgram
000003000184a2e8 0000000000000000 net_conn.sock
(none)
300018471e0
dgram
000003000184a4d0 0000000000000000 net_inp.sock
(none)
300018473a8
dgram
0000000000000000 0000000000000000 (none)
(none)
30001847570
dgram
0000000000000000 0000000000000000 (none)
(none)
>::ire
ADDR
30000b78148
30000b783c8
30000b78508
30000b78648
30000b78a08
30000b78b48
30000b78c88
30000b78dc8
30000b78f08
30000b79048
30000b79188
30000b792c8
30000b79408
30000b79548
30000b79688
30000b797c8
30000b79908
30000b79a48
30000b79b88
30000b79cc8
30000b79e08
300034ada50
>::tcpb
TCPBAddr
000003000085f800
00000300013c31d8
00000300013c3318
00000300013c2cd8
00000300013c2e18
00000300013c2a58
00000300013c2918
00000300013c27d8
00000300013c2698
00000300013c2558
00000300013c2198
00000300013c2058
00000300014b3e60
00000300014b3be0
00000300014b3960
00000300014b36e0
00000300014b3460
00000300014b2e20
00000300014b2920
00000300014b27e0
00000300014b26a0
00000300014b2560
SRC
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
0.0.0.0
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
172.24.33.60
127.0.0.1
172.24.33.60
St
-5
-3
-5
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
IP
v6
v4
v4
v6
v6
v4
v6
v6
v4
v6
v4
v6
v6
v6
v6
v6
v6
v4
v4
v4
v6
v6
DST
172.24.33.254
172.24.32.13
172.24.33.106
172.24.33.11
224.0.0.0
0.0.0.0
255.255.255.255
172.24.0.0
0.0.0.0
255.255.255.255
172.24.255.255
172.24.33.0
172.24.0.0
172.24.255.255
172.24.33.60
172.24.33.0
172.24.33.0
172.24.33.255
172.24.33.255
0.0.0.0
127.0.0.1
224.0.0.2
TCPAddr
0000030000049770
0000030000049b50
0000030000049390
0000030000048fb0
0000030000048bd0
00000300000487f0
0000030000048410
0000030000048030
00000300014b7b58
00000300014b7778
00000300014b7398
00000300014b6fb8
00000300014b6bd8
00000300014b67f8
00000300014b6418
00000300014b6038
00000300014a1b60
00000300014a1780
00000300014a13a0
00000300014a0fc0
00000300014a0be0
00000300014a0800
値の表示
p
crash> p jiffies
print
>>
jiffies = $1 = 843846
p
*)0xc5c14000)->files.fd).f_flags & 0x8000
pb, pd,
32768
print
(*((struct
task_struct
--
po, px
アクティブプロセスを出力する
ps
crash> ps
PID
PPID CPU TASK
ST %MEM
0
0 0 c03b6000 RU 0.0
VSZ
0
RSS COMM
0 [swapper]
ps
>> ps
Address
Uid
Pid
PPid Stat
Flags SIZE:RSS Command
-----------------------------------------------------------------------------
- 4-18 -
::ps
> ::ps
S
PID
R
0
PPID
0
PGID
0
SID
0
UID
FLAGS
ADDR NAME
0 0x00000019 0000000001438a38 sched
1
2
3
4
5
6
7
8
9
13
75
172
173
520
524
568
582
591
619
628
635
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
c7fa4000
c1468000
c154e000
c154c000
c1466000
c1464000
c1462000
c1460000
c1554000
c7120000
c7f54000
c7e3c000
c1324000
c7da2000
c6b4c000
c666c000
c65f4000
c65c4000
c6288000
c5e74000
c701c000
RU
RU
RU
IN
RU
RU
RU
RU
IN
RU
IN
IN
IN
RU
RU
IN
IN
RU
RU
RU
IN
0.4
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.5
0.4
1.2
0.7
0.5
2.8
0.4
0.3
1520
0
0
0
0
0
0
0
0
0
0
0
0
1572
1520
3776
2136
1576
6056
1560
1492
508
0
0
0
0
0
0
0
0
0
0
0
0
632
468
1596
888
628
3656
564
424
init
[keventd]
[kapmd]
[ksoftirqd/0]
[kswapd]
[kscand]
[bdflush]
[kupdated]
[mdrecoveryd]
[kjournald]
[khubd]
[kjournald]
[kjournald]
syslogd
klogd
sshd
xinetd
crond
xfs
atd
mingetty
c03b6000
0
0
0 0x00 0x00000000
0:0
swapper
c7fa4000
0
1
0 0x00 0x00000100 380:127 init
c1468000
0
2
1 0x00 0x00000040
0:0
keventd
c154e000
0
3
1 0x00 0x00000040
0:0
kapmd
c154c000
0
4
1 0x01 0x00000040
0:0
ksoftirqd/0
c1462000
0
7
1 0x00 0x00000040
0:0
bdflush
c1466000
0
5
1 0x00 0x00000840
0:0
kswapd
c1464000
0
6
1 0x00 0x00000040
0:0
kscand
c1460000
0
8
1 0x00 0x00000040
0:0
kupdated
c1554000
0
9
1 0x01 0x00000040
0:0
mdrecoveryd
c7120000
0
13
1 0x00 0x00000040
0:0
kjournald
c7f54000
0
75
1 0x01 0x00000040
0:0
khubd
c7e3c000
0
172
1 0x01 0x00000040
0:0
kjournald
c1324000
0
173
1 0x01 0x00000040
0:0
kjournald
c7da2000
0
520
1 0x00 0x00000040 393:158 syslogd
c6b4c000
0
524
1 0x00 0x00000140 380:117 klogd
c666c000
0
568
1 0x01 0x00000140 944:399 sshd
c65f4000
0
582
1 0x01 0x00000140 534:222 xinetd
c65c4000
0
591
1 0x00 0x00000040 394:157 crond
c6288000
43
619
1 0x00 0x00000140 1514:914 xfs
c5e74000
0
628
1 0x00 0x00000040 390:141 atd
c701c000
0
635
1 0x01 0x00000100 373:106 mingetty
c6ef8000
0
636
1 0x01 0x00000100 374:107 mingetty
c6ba4000
0
637
1 0x01 0x00000100 379:107 mingetty
c5e4c000
0
638
1 0x01 0x00000100 378:108 mingetty
c5e4a000
0
639
1 0x01 0x00000100 380:108 mingetty
c5e48000
0
640
1 0x01 0x00000100 380:108 mingetty
c6106000
0
641
582 0x00 0x00000100 433:176 in.telnetd
c60ce000
0
642
641 0x01 0x00000100 591:292 login
c6014000
500
643
642 0x01 0x00000100 1312:335 bash
c5d26000
500
678
643 0x01 0x00000100 1273:254 su
c5cca000
0
679
678 0x01 0x00000100 1312:349 bash
c5c16000
0
764
582 0x01 0x00000100 435:179 in.telnetd
c5c9e000
0
765
764 0x01 0x00000100 591:266 login
c5a14000
0
766
765 0x01 0x00000100 1313:344 bash
c59f0000
0
805
582 0x00 0x00000100 433:176 in.telnetd
c5998000
0
806
805 0x01 0x00000100 592:267 login
c595a000
0
807
806 0x01 0x00000100 1337:360 bash
c5934000
0
895
679 0x00 0x00100000 343:60
krnl-1
----------------------------------------------------------------------------39 processes found
- 4-19 -
::ptree
R
3
0
R
2
0
R
1
0
R 28676
1
R 28686 28676
R 28685 28676
R 11515
1
R
591
1
R
582
1
R
581
1
R
588
581
R
574
1
R
568
1
R
567
1
R
551
1
R
555
551
R
528
rpc.bootparamd
R
526
in.rarpd
R
492
1
R 26357
492
R 26355
492
0
0
0
0
0
0
28676 28676
28676 28676
28676 28676
11506
0
591
591
582
582
581
581
581
581
574
574
568
568
567
567
551
551
555
555
1
528
1
526
492
492
26357 26357
26355 26355
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0x00020019 000003000092a008 fsflush
0x00020019 000003000092aa20 pageout
0x00004008 000003000092b438 init
0x00020008 0000030009c4eb18 isdca
0x10024008 000003006e8dd540 istcpin
0x10024008 000003006e8d5550 istcpin
0x00004008 0000030009919520 java
0x00000008 0000030002f7c0b8 sshd
0x00004008 0000030002eee0b0 ttymon
0x00014008 0000030000b1d440 sac
0x00014008 000003000186f4c0 ttymon
0x00014008 000003000187d4b8 vold
0x00020008 000003000199f4d0 snmpXdmid
0x00000008 0000030002edc0a8 dmispd
0x00010008 0000030001916ab0 snmpdx
0x00004008 0000030001916098 mibiisa
528
0 0x00000008 0000030002e56068
526
0 0x00000008 000003000187caa0
0 0x00010008 0000030001636048 dtlogin
0 0x00004008 000003000199eab8 fbconsole
0 0x00000008 00000300017ee080 dtlogin
> ::ptree
0000000001438a38 sched
000003000092a008 fsflush
000003000092aa20 pageout
000003000092b438 init
0000030009c4eb18 isdca
000003006e8dd540 istcpin
000003006e8d5550 istcpin
0000030009919520 java
0000030002f7c0b8 sshd
0000030002eee0b0 ttymon
0000030000b1d440 sac
000003000186f4c0 ttymon
000003000187d4b8 vold
000003000199f4d0 snmpXdmid
0000030002edc0a8 dmispd
0000030001916ab0 snmpdx
0000030001916098 mibiisa
0000030002e56068 rpc.bootparamd
000003000187caa0 in.rarpd
0000030001636048 dtlogin
000003000199eab8 fbconsole
00000300017ee080 dtlogin
000003000187c088 dtgreet
0000030002f7cad0 Xsun
00000300017b2070 spo_test
000003000186eaa8 shutrcv
00000300017b2a88 atokmngdaemon
0000030002e56a80 cycliclog
0000030002e57498 par
00000300017eea98 net
00000300017ef4b0 out
00000300017fc078 inp
00000300017fca90 tim
00000300017fd4a8 hdl
00000300016c6a68 htt
0000030002e78a78 htt_server
000003000170c058 jserver
0000030002e79490 jserver_m
000003000170ca70 dpkeyserv
0000030001648040 keyserver
000003000155ea48 calserver
000003000170d488 sendmail
00000300016c6050 sendmail
0000030000b1ca28 utmpd
0000030001636a60 popper
0000030001648a58 powerd
000003000155e030 nscd
00000300015c4a50 cron
000003000155f460 syslogd
000003000125a018 sh
00000300013a4020 ntpdate
00000300013a5450 automountd
00000300014f4028 lockd
00000300014f4a40 statd
00000300013a4a38 inetd
0000030002edcac0 in.telnetd
000003000336b500 ksh
00000300033974f8 sh
00000300099180f0 sh
000003000333f4f0 reboot
00000300034c80d8 rpc.ttdbserverd
0000030000b1c010 rpcbind
000003000125aa30 picld
000003000125b448 syseventd
ページテーブルエントリを変換する
pte
crash> pte d8e067
PTE
--
--
--
--
--
--
PHYSICAL FLAGS
d8e067
d8e000
(PRESENT|RW|USER|ACCESSED|DIRTY)
ページフレーム番号をそのバイト値に変換する
ptob
crash> ptob 512a
512a: 512a000
16 進物理アドレスをカーネルの仮想アドレスに変換する
ptov
crash> ptov 56e000
VIRTUAL
PHYSICAL
c056e000 56e000
指定された領域の書式付きメモリーダンプを出力する
rd
crash> > rd 0xc010cbc0 10
dump
dump 0xc010cbc0 10
dump
c010cbc0: 7e2005c6 8b01c03e 8b042444 44892840
.. ~>...D$..@(.D
md
0xc010cbc0: 7e2005c6 8b01c03e 8b042444 44892840 : .. ~>...D$..@(.D
\/ 1 2 3 4 5 6 7 8 9 a b c d e f v123456789abcdef
c010cbd0: c9e90424 89fffffe 27bc8df6 00000000
$..........'....
od
0xc010cbd0: c9e90424 89fffffe 27bc8df6 00000000 : $..........'....
116f1d0: 666f7263 65642063 72617368 2064756d forced crash dum
c010cbe0: 0090ec81 9c890000
0xc010cbe0: 0090ec81 9c890000
: ........
コマンドを繰り返す
repeat
>116f1d0::dump
crash> repeat -1 p jiffies
--
--
jiffies = $2 = 843846
jiffies = $3 = 843846
- 4-20 -
jiffies = $4 = 843846
jiffies = $5 = 843846
ランキュー上のタスクを表示する
crash> runq
runq
RUNQUEUES[0]: c03e5980
ACTIVE PRIO_ARRAY: c03e5e18
[115] PID: 3
TASK: c154e000
PID: 5
TASK: c1466000
PID: 6
TASK: c1464000
PID: 8
TASK: c1460000
PID: 641
TASK: c6106000
PID: 1
TASK: c7fa4000
PID: 13
TASK: c7120000
PID: 520
TASK: c7da2000
PID: 2
TASK: c1468000
PID: 524
TASK: c6b4c000
PID: 7
TASK: c1462000
PID: 591
TASK: c65c4000
PID: 805
TASK: c59f0000
PID: 619
TASK: c6288000
PID: 628
TASK: c5e74000
EXPIRED PRIO_ARRAY: c03e59a0
[121] PID: 895
TASK: c5934000
--
--
--
kgrep
CPU: 0 COMMAND: "kapmd"
CPU: 0 COMMAND: "kswapd"
CPU: 0 COMMAND: "kscand"
CPU: 0 COMMAND: "kupdated"
CPU: 0 COMMAND: "in.telnetd"
CPU: 0 COMMAND: "init"
CPU: 0 COMMAND: "kjournald"
CPU: 0 COMMAND: "syslogd"
CPU: 0 COMMAND: "keventd"
CPU: 0 COMMAND: "klogd"
CPU: 0 COMMAND: "bdflush"
CPU: 0 COMMAND: "crond"
CPU: 0 COMMAND: "in.telnetd"
CPU: 0 COMMAND: "xfs"
CPU: 0 COMMAND: "atd"
CPU: 0
COMMAND: "krnl-1"
カーネルのアドレス空間で特定の値を検索する
search
プロセス情況または内部クラッシュ変数をセットする デフォルトのtask をセット,または,デフォルトのtask のアドレスを表示する
crash> set
set
set
>> set
PID: 895
COMMAND: "krnl-1"
deftask
Debug components: none
TASK: c5934000
CPU: 0
Trace threshold: 0
STATE: TASK_RUNNING (PANIC)
Iteration threshold: 10000
crash> set -v
scroll: on
radix: 10 (decimal)
refresh: on
print_max: 256
console: (not assigned)
debug: 0
core: off
hash: on
silent: off
edit: vi
namelist: /opt/dump/data/vmlinux
dumpfile: /opt/dump/data/dump.2
タスクシグナルハンドリング
PID: 895
TASK: c5934000 CPU: 0 COMMAND: "krnl-1"
sig
SIGPENDING: yes
SIGNAL: 0000000000000080
BLOCKED: 0000000000000000
SIGNAL_STRUCT: c153b9c0 COUNT: 1
SIG SIGACTION HANDLER
MASK
FLAGS
[1] c599a384 SIG_DFL 0000000000000000 0
[2] c599a398 SIG_DFL 0000000000000000 0
[3] c599a3ac SIG_DFL 0000000000000000 0
[4] c599a3c0 SIG_DFL 0000000000000000 0
--
--
--
- 4-21 -
[5] c599a3d4 SIG_DFL 0000000000000000 0
[6] c599a3e8 SIG_DFL 0000000000000000 0
[7] c599a3fc SIG_DFL 0000000000000000 0
[8] c599a410 SIG_DFL 0000000000000000 0
[9] c599a424 SIG_DFL 0000000000000000 0
[10] c599a438 SIG_DFL 0000000000000000 0
[11] c599a44c SIG_DFL 0000000000000000 0
[12] c599a460 SIG_DFL 0000000000000000 0
[13] c599a474 SIG_DFL 0000000000000000 0
[14]
c599a488
80483b0
0000000000002000
(SA_RESTORER|SA_RESTART)
[15] c599a49c SIG_DFL 0000000000000000 0
[16] c599a4b0 SIG_DFL 0000000000000000 0
[17] c599a4c4 SIG_DFL 0000000000000000 0
14000000
構造体の内容を表示する
crash> struct kernel_timeval
struct
struct kernel_timeval {
unsigned int tv_sec;
unsigned int tv_usec;
}
SIZE: 8
--
::offse
tof
スワップ情報を表示する
swap
--
crash> swap
FILENAME
TYPE
SIZE
/dev/hda5
PARTITION
265032k
USED
0k
::swapi
nfo
PCT PRIORITY
0%
> ::swapinfo
ADDR
0000030000058af8
-1
VNODE
PAGES
30000ba4b08
FREE NAME
65672
65672
/dev/dsk/c1t1d0s1
シンボルをその仮想アドレスに変換する,またはその逆 シンボリックネーム/アドレスの関連情報を表示する
crash> sym -l
>> findsym system_utsname
sym
findsym
c0100000 (A) _text
c0100000 (t) startup_32
ADDR OFFSET SECTION
NAME
TYPE
fsym
c01000a5 (t) checkCPUtype
c0100133 (t) is486
================================================================
symbol
c0100142 (t) is386
0xc03539e0
0 GLOBAL_DATA system_utsname
(unknown)
c010018c (t) L6
c010018e (t) ready
================================================================
c010018f (t) check_x87
c01001b6 (t) setup_idt
1 symbol found
c01001d3 (t) rp_sidt
c01001e0 (T) stack_start
c01001e8 (t) int_msg
c01001fc (t) ignore_int
c010021e (T) idt_descr
c0100224 (T) cpu_gdt_descr
c0101000 (T) swapper_pg_dir
c0102000 (T) pg0
c0103000 (T) pg1
c0104000 (T) pg2
c0105000 (T) pg3
c0106000 (T) empty_zero_page
c0107000 (T) _stext
c0107000 (T) stext
::nm
> ::nm
Value
|Size
|Type
0x0000000000000000|0x0000000000000000|NOTY
0x000000000143a1f4|0x0000000000000000|OBJT
0x0000000001006590|0x0000000000000000|NOTY
_fitos_fdtos_table
0x0000000001006e24|0x0000000000000000|NOTY
0x0000000001006e34|0x0000000000000000|NOTY
0x0000000001006610|0x0000000000000000|NOTY
_fitos_fdtos_done
0x0000000001006db0|0x0000000000000108|FUNC
0x0000000001006f80|0x0000000000000000|NOTY
fast_trap_dummy_call
0x00000000010069dc|0x0000000000000000|NOTY
0x00000000010067d0|0x0000000000000000|NOTY
0x0000000001006f00|0x0000000000000000|NOTY
0x00000000010064f4|0x0000000000000000|NOTY
_fitos_fitod_table
0x00000000010069cc|0x0000000000000000|NOTY
0x00000000010067c0|0x0000000000000000|NOTY
0x0000000001006574|0x0000000000000000|NOTY
_fitos_fitod_done
0x0000000001006adc|0x0000000000000000|NOTY
0x00000000010068d0|0x0000000000000000|NOTY
|Bind
|LOCL
|LOCL
|LOCL
|Other|Shndx
|0x0 |UNDEF
|0x0 |13
|0x0 |6
|Name
|
|_END_
|
|LOCL |0x0 |6
|LOCL |0x0 |6
|LOCL |0x0 |6
|mmu_trap_tl1_1
|mmu_trap_tl1_2
|
|LOCL |0x0 |6
|LOCL |0x0 |6
|mmu_trap_tl1
|
|LOCL
|LOCL
|LOCL
|LOCL
|start1
|start2
|stat_mmu
|
|0x0
|0x0
|0x0
|0x0
|6
|6
|6
|6
|LOCL |0x0 |6
|LOCL |0x0 |6
|LOCL |0x0 |6
|mark1
|mark2
|
|LOCL |0x0 |6
|LOCL |0x0 |6
|done1
|done2
システムデータ システム統計,log_buf を表示する
sys
crash> sys
SYSTEM MAP: /opt/dump/data/map.2
DEBUG KERNEL: /opt/dump/data/vmlinux (2.4.21-9.30AX.dbg)
stat
info
main
>> stat
sysname : Linux
nodename : asianux
release : 2.4.21-9.30AX
- 4-22 -
::statu
> ::status
s
debugging crash dump /var/crash/virgo/vmcore.1 (64-bit) from virgo
operating system: 5.9 Generic_117171-11 (sun4u)
CPUS: 1
version : #1 Thu May 27 00:03:41 EDT 2004
machine : i686
domainname : (none)
DATE: Thu Jun 17 17:55:20 2004
LOG_BUF:
DUMPFILE: /opt/dump/data/dump.2
UPTIME: 02:20:38
panic message: forced crash dump initiated at user request
dump content: kernel pages only
4
LOAD AVERAGE: 10.95, 4.09, 1.48
>> info
info
TASKS: 39
DUMP INFORMATION:
NODENAME: asianux
RELEASE: 2.4.21-9.30AX
VERSION: #1 Thu May 27 00:03:41 EDT 2004
MACHINE: i686 (451 Mhz)
MEMORY: 128 MB
PANIC: "sysrq"
architecture:
byte order:
pointer size:
bytes per word:
i386
little
32
4
kernel release:
memory size:
num phys pages:
number of cpus:
2.4.21
134086656 (0G 127M 896K 0Byte)
32736
1
>> main
Linux version : 0x00020415
Running linux 2.4.X [0x00020415]
/usr/share/sial/lcrash/ps.sial : line 31 : Warning: Non void
function should return a value.
タスク構造の内容
crash> task
task
PID: 895
TASK: c5934000 CPU: 0
struct task_struct {
state = 0,
flags = 1048576,
sigpending = 1,
addr_limit = {
seg = 3221225472
},
exec_domain = 0xc0354d80,
need_resched = 1,
ptrace = 0,
lock_depth = -1,
cpu = 0,
real_stack = 0xc5934000,
virtual_stack = 0x0,
user_pgd = 0x0,
prio = 121,
static_prio = 120,
run_list = {
next = 0xc03e5d80,
prev = 0xc03e5d80
},
array = 0xc03e59a0,
sleep_avg = 496,
last_run = 831028,
policy = 0,
cpus_allowed = 4294967295,
time_slice = 10,
first_time_slice = 0,
usage = {
counter = 5
},
tasks = {
COMMAND: "krnl-1"
task
::task
>> task
ADDR
UID
PID
PPID STATE
FLAGS CPU NAME
::task_
> ::task
ADDR TASKID PROJID REFCNT
FLAGS
00000300003f3d18
156
1
1 0x00000000
00000300003f3db8
98
3
1 0x00000000
00000300003f3e08
158
1
2 0x00000000
swapper
00000300003f3e58
155
3
1 0x00000000
==========================================================
00000300003f3ea8
127
3
3 0x00000000
============
00000300003f3ef8
1
0
53 0x00000000
1 active task struct found
00000300003f3f48
0
0
3 0x00000000
==========================================================
===========
0xc03b6000
0
0 4294967295
- 4-23 -
0
0
-
entry
next = 0xc03b6060,
prev = 0xc595a060
},
ptrace_children = {
next = 0xc5934068,
prev = 0xc5934068
},
ptrace_list = {
next = 0xc5934070,
prev = 0xc5934070
},
mm = 0xc5c86800,
active_mm = 0xc5c86800,
タイマキューデータ
crash> timer
timer
TVEC_BASES[0]: c03560a0
JIFFIES
843846
EXPIRES TIMER_LIST FUNCTION
844259 c042d680 c01acf40
844259 c042d680 c01acf40
844903 c151f634 c884dd60
845250 c6289ef4 c012bb40
845347 c5e75f74 c012bb40
845443 c593419c c0125cf0
845910 c04558c0 c0229740
846129 c03b1a28 c021bc90
847435 c7e492b8 c88e3930
851240 c03b1420 c022e0c0
874095 c04558e0 c0229a10
900000 c0455460 c0222110
900454 c0454680 c0215a40
900454 c0455fa0 c022ef30
903777 c042c3c0 c01ab170
1080073 c03b0e60 c0225570
1486502 c6d9fc58 c02470c0
1489002 c135b1d8 c02470c0
1495107 c6d9ebd8 c02470c0
--
<rs_timer>
<rs_timer>
<rh_int_timer_do>
<process_timeout>
<process_timeout>
<it_real_fn>
<rt_check_expire>
<neigh_periodic_timer>
<e100_watchdog>
<peer_check_expire>
<rt_secret_rebuild>
<rif_check_expire>
<flow_cache_new_hashrnd>
<ipfrag_secret_rebuild>
<blank_screen>
<psched_tick>
<tcp_keepalive_timer>
<tcp_keepalive_timer>
<tcp_keepalive_timer>
union 構造体の内容
crash> union bdflush_param
union
union bdflush_param {
struct {
int nfract;
int ndirty;
int dummy2;
int dummy3;
int interval;
int age_buffer;
int nfract_sync;
int nfract_stop_bdflush;
int dummy5;
} b_un;
unsigned int data[9];
}
SIZE: 36
仮想メモリ情報を表示する
crash> vm
vm
PID: 895
TASK: c5934000 CPU: 0 COMMAND: "krnl-1"
MM
PGD
RSS
TOTAL_VM
c5c86800 c58d0000 240k
1372k
VMA
START
END
FLAGS FILE
--
::offse
tof
--
- 4-24 -
c5956474
c5956584
c5956188
c5956430
c5956a4c
c59563ec
c5956694
c5956254
c5956540
8048000
8049000
b74a2000
b75d4000
b75d7000
b75ea000
b75eb000
b7600000
bfffa000
8049000
804a000
b75d4000
b75d7000
b75da000
b75eb000
b7600000
b7601000
c0000000
1875
101873
75
100073
100073
100073
875
100873
100177
crash> mv
PID: 895
MM
c5c86800
VMA
c5956474
VIRTUAL
8048000
VMA
c5956584
VIRTUAL
8049000
VMA
c5956188
VIRTUAL
b74a2000
b74a3000
b74a4000
b74a5000
b74a6000
b74a7000
b74a8000
b74a9000
b74aa000
–p
TASK: c5934000 CPU: 0
PGD
RSS
TOTAL_VM
c58d0000 240k
1372k
START
END
FLAGS
8048000 8049000 1875
PHYSICAL
5200000
START
END
FLAGS
8049000 804a000 101873
PHYSICAL
558a000
START
END
FLAGS
b74a2000 b75d4000
75
PHYSICAL
70eb000
70d9000
70d8000
70d7000
70d6000
70d5000
70d4000
70d3000
70d2000
crash> vm –v
ID: 895
TASK: c5934000 CPU: 0
struct vm_area_struct {
vm_mm = 0xc5c86800,
vm_start = 134512640,
vm_end = 134516736,
vm_next = 0xc5956584,
vm_page_prot = {
pgprot = 37
},
vm_flags = 6261,
vm_rb = {
rb_parent = 0xc595659c,
rb_color = 1,
rb_right = 0x0,
rb_left = 0x0
},
vm_next_share = 0x0,
vm_pprev_share = 0xc59565ac,
vm_ops = 0xc0371efc,
vm_pgoff = 0,
vm_file = 0xc5913580,
vm_raend = 0,
vm_private_data = 0x0
crash> vm -m
PID: 895
TASK: c5934000 CPU: 0
struct mm_struct {
mmap = 0xc5956474,
/opt/es7000/bin/krnl-1
/opt/es7000/bin/krnl-1
/lib/tls/libc-2.3.2.so
/lib/tls/libc-2.3.2.so
/lib/ld-2.3.2.so
/lib/ld-2.3.2.so
COMMAND: "krnl-1"
FILE
/opt/es7000/bin/krnl-1
FILE
/opt/es7000/bin/krnl-1
FILE
/lib/tls/libc-2.3.2.so
COMMAND: "krnl-1"
COMMAND: "krnl-1"
- 4-25 -
mm_rb = {
rb_node = 0xc5956404
},
mmap_cache = 0xc5956188,
free_area_cache = 1073741824,
non_executable_cache = 3076431872,
pgd = 0xc58d0000,
mm_users = {
counter = 1
},
mm_count = {
counter = 1
},
map_count = 9,
mmap_sem = {
count = 0,
wait_lock = <incomplete type>,
wait_list = {
next = 0xc5c86828,
prev = 0xc5c86828
crash> vm -R 75
PID: 895
TASK: c5934000 CPU: 0 COMMAND: "krnl-1"
MM
PGD
RSS
TOTAL_VM
c5c86800 c58d0000 240k
1372k
VMA
START
END
FLAGS FILE
c5956188 b74a2000 b75d4000
75 /lib/tls/libc-2.3.2.so
仮想アドレスを物理アドレスに変換する
crash> vtop c5934000
vtop
VIRTUAL PHYSICAL
c5934000 5934000
vtop
::vtop
>> vtop c5934000
VADDR
KADDR
PADDR
PAGE DIRECTORY: c0101000
PGD: c0101c58 => 58001e3
PAGE: 5800000 (4MB)
=========================================
PTE PHYSICAL FLAGS
0
0
(no mapping)
=========================================
PAGE
PHYSICAL
c1138390 5934000
MAPPING
0
0xc5934000 0xc5934000 0x5934000
> ::vtop
virtual 30000058af8 mapped to physical 1f0eaaf8
PFN
22836
INDEX CNT FLAGS
0 1 1400000
待機キューリスト上のタスクリストを表示する
waitq
crash> waitq buffer_wait
--
::queue
wait queue "buffer_wait" (c0373108) is empty
- 4-26 -
> ::queue
ADDR MODULE
FLAGS NBLK
00000300008f2008 fifostrrhead 044032
0 0000000000000000
00000300008f2290 usbkbm
002032
0 0000000000000000
00000300008f2518 USB HID STREAMS driver 201032
0 0000000000000000
00000300008f27a0 conskbd
04c032
0 0000000000000000
00000300008f2a28 usbms
002032
0 0000000000000000
00000300008f2cb0 USB HID STREAMS driver 201032
0 0000000000000000
00000300008f2f38 consms
042032
0 0000000000000000
00000300008f31c0 tcp
1100832
0 0000000000000000
00000300008f3448 ip
1202032
0 0000000000000000
00000300008f36d0 ip
042032
0 0000000000000000
00000300008f3958 conskbd
20c032
0 0000000000000000
00000300008f3be0 wc
042032
0 0000000000000000
00000300008bc010 strrhead
044032
0 0000000000000000
00000300008bc298 timod
1000832
0 0000000000000000
00000300008bc520 ip
002032
0 0000000000000000
00000300008bc7a8 eri
204032
0 0000000000000000
00000300008bca30 ip
042032
0 0000000000000000
00000300008bccb8 strrhead
044032
0 0000000000000000
00000300008bcf40
00000300008bd1c8
00000300008bd450
00000300008bd6d8
00000300008bd960
00000300008bdbe8
0000030001066018
00000300010662a0
0000030001066528
00000300010667b0
0000030001066a38
0000030001066cc0
0000030001066f48
00000300010671d0
0000030001067458
00000300010676e0
0000030001067968
0000030001067bf0
000003000147e020
000003000147e2a8
000003000147e530
000003000147e7b8
000003000147ea40
000003000147ecc8
000003000147ef50
000003000147f1d8
000003000147f460
データのシンボルテーブルまたは型情報を表示する
crash> whatis linux_binfmt
whatis
struct linux_binfmt {
struct linux_binfmt *next;
struct module *module;
int (*load_binary)(struct linux_binprm *, struct pt_regs *);
int (*load_shlib)(struct file *);
int (*core_dump)(long int, struct pt_regs *, struct file *);
long unsigned int min_coredump;
}
SIZE: 24
whatis
>> whatis linux_binfmt
struct linux_binfmt {
struct linux_binfmt *next;
struct module *module;
int (*load_binary)();
int (*load_shlib)();
int (*core_dump)();
long unsigned int min_coredump;
};
::whati
>> defcpu
--
s
メモリへの書き込み
wr
crash> wr my_debug_flag 1
--
デフォルトのCPU をセット,または,デフォルトのCPU を表示する
--
defcpu
No default cpu set
コマンドヒストリーをセットまたは表示する
--
history
>> history
--
1: print
2: help print
3: help
4: help eavl
5: help ?
6: ?
- 4-27 -
ip
strrhead
ttcompat
ldterm
wc
strrhead
strrhead
timod
udp
timod
udp
timod
tcp
arp
arp
eri
ip
ip
tl
strrhead
timod
tl
strrhead
timod
tcp
ip
udp
1202032
044032
000832
000832
202032
044032
044032
1000832
1000832
1000832
1000832
1000832
1100832
1002032
1002032
204032
042032
1202032
208832
044032
1000832
208832
044030
1000832
1100832
1202032
1000832
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
0 0000000000000000
動的にライブラリをロードする
--
ldcmds
--
livedum
--
ライブシステムメモリからダンプを生成する
--
p
スタックトレースを生成する
--
mktrace
--
mt
mmap_list 内のエントリの関連情報を表示する
--
mmap
--
>> mmap c03b6000
ADDR MM_COUNT MAP_COUNT
MMAP
===========================================
0xc03b6000 4294967295
0
0
===========================================
1 active mm_struct struct found
オープンしたネームリストをリストする/追加する
--
--
namelis
>> namelist
t
INDEX NAMELIST
nmlist
=================================================
0 kerntypes.2
=================================================
The current namelist is kerntypes.2 (0)
page_list 内のエントリのページ構造から関連情報を表示する
--
page
>> page | more
ADDR
PGNO COUNT
FLAGS
VIRTUAL
=================================================
0xc1000030
0
0
0x8000 0xc0000000
0xc1000068
1
0
0x8000 0xc0001000
0xc10000a0
2
0
0x8000 0xc0002000
0xc10000d8
3
0
0x8000 0xc0003000
0xc1000110
4
0
0x8000 0xc0004000
0xc1000148
5
0
0x8000 0xc0005000
0xc1000180
6
0
0x8000 0xc0006000
0xc10001b8
7
0
0x8000 0xc0007000
0xc10001f0
8
0
0x8000 0xc0008000
0xc1000228
9
0
0x8000 0xc0009000
0xc1000260
10
0
0x8000 0xc000a000
0xc1000298
11
0
0x8000 0xc000b000
0xc10002d0
12
0
0x8000 0xc000c000
0xc1000308
13
0
0x8000 0xc000d000
0xc1000340
14
0
0x8000 0xc000e000
0xc1000378
15
0
0x8000 0xc000f000
0xc10003b0
16
0
0x8000 0xc0010000
- 4-28 -
::page
> ::page
PAGE
00000700024d0ec8
0000070002124428
00000700024d0f40
00000700024d0fb8
000007000223bb90
0000070002167b38
00000700024d1030
0000070002267060
00000700024d10a8
000007000252d808
00000700025f3670
00000700024d1120
0000070002247620
0000070002376758
00000700024d1198
000007000264d490
000007000241c6d0
00000700024d1210
VNODE
142b7b0
300032f56a0
142b7b0
142b7b0
3006f004398
300032f56a0
142b7b0
3010b70f080
142b7b0
3000026e658
3000026e978
142b7b0
3000026ee78
3000026e158
142b7b0
3000190d840
3010b6cf898
142b7b0
OFFSET
30002f1a000
600133f1160000
30002f1c000
30002f1e000
0
60013322b30000
30002f20000
0
30002f22000
60002f2cd40000
60002d90010000
30002f24000
60002b05030000
60006560810000
30002f26000
0
0
30002f28000
SELOCK LCT COW IO FS ST
1 0 0 0 0 0
0 0 0 0 0 0
1 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 80
0 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 80
1 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 80
0 0 0 0 0 80
1 0 0 0 0 0
0xc10003e8
0xc1000420
0xc1000458
17
18
19
0
0
0
0x8000 0xc0011000
0x8000 0xc0012000
0x8000 0xc0013000
0000070002326118
0000070002445e18
00000700024d1288
00000700026d4d00
crash dump report (kernel failure が起こったときのシステムの状態等)を表示する
--
report
=======================
LCRASH CORE FILE REPORT
=======================
GENERATED ON:
Fri Jul 15 16:25:39 2005
TIME OF CRASH:
Thu Jun 17 17:55:18 2004
PANIC STRING:
sysrq
MAP:
map.2
DUMP:
dump
KERNTYPES:
kerntypes.2
================
COREFILE SUMMARY
================
The system died due to a software failure.
===================
UTSNAME INFORMATION
===================
sysname
nodename
release
version
machine
domainname
:
:
:
:
:
:
Linux
asianux
2.4.21-9.30AX
#1 Thu May 27 00:03:41 EDT 2004
i686
(none)
===============
LOG BUFFER DUMP
===============
4
====================
CURRENT SYSTEM TASKS
====================
ADDR
UID
PID PPID STATE
FLAGS CPU NAME
==================================================================
0xc03b6000
0
0 4294967295
0
0 - swapper
===========================
STACK TRACE OF FAILING TASK
===========================
- 4-29 -
--
300032f56a0
300032f52e0
142b7b0
3000026e478
6001337a050000
600135761c0000
30002f2a000
6000336c5d0000
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
================================================================
STACK TRACE FOR TASK: 0xc5934000 (krnl-1)
0 do_coprocessor_error [0xc010cbc0]
1 restore_i387_fxsave+36 [0xc0112bc4]
2 restore_i387+120 [0xc0112c98]
3 restore_sigcontext+270 [0xc010b1de]
4 sys_sigreturn+204 [0xc010b2cc]
5 no_timing+5 [0xc03b80d1]
6 LKST_ETYPE_SYSCALL_ENTRY_HEADER_hook+53 [0xc03b8036]
================================================================
Live dump を生成する,または,ダンプサイズを小さくする
--
savedum
--
p
バイト単位のデータタイプのサイズを表示し,加えて,構造体メンバーへのオフセットを表示する
--
sizeof
>> sizeof page
::sizeo
offset
Size of "page": 56 bytes
f
sial マクロをアンロードする
--
unload
unload
vi セッションを開始する
--
vi
- 4-30 -