はじめに
前回までで、Linux から NVMe command を直接打つ入口と、Identify の基本についてまで解説してきました。
今回お話するのは SMART / Health Information Log です。
ここでは Identify のように「どんな device か」を見るというより、
- 温度はどうか
- 予備領域はどれくらい残っているか
- どれくらい使われているか
- どれくらい read / write されているか
のような、より運用に近い情報を見ていきます。
まずは実際の出力を見る
たとえば mock では、次のような値が出るようにしていました。
Composite Temperature : 313 K (40 C)
Available Spare : 100 %
Available Spare Threshold : 10 %
Percentage Used : 8 %
Data Units Read : 1234567890
Data Units Write : 987654321
Controller Busy Time : 540 minutes
Power On Hours : 4800 hours
Warning Composite Temperature Time : 358 minutes
Critical Composite Temperature Time : 368 minutes
Temperature Sensor 1 : 312 K (39 C)
Temperature Sensor 4 : no report
この時点で、SMART Log は単に数値を並べるだけでは読みにくいと分かります。
どの項目が重要か、何の単位か、どういう意味で見るべきかを整理しないと、出力しても解釈しづらいままです。
理論: SMART Log でまず見たい項目
今回読んでいるのは、Get Log Page で取得する SMART / Health Information です。
返ってくるのは 512 byte の log page で、そこに温度や寿命、カウンタ類がまとまっています。
最初の段階で特に見たかったのは、次の項目です。
Composite Temperature
device 全体の温度を見るための項目。Available Spare
予備領域がどれくらい残っているかを見る項目。Available Spare Threshold
Available Spareがどこまで下がると warning 相当になるかの基準。Percentage Used
どれくらい使い込まれているかを見る指標。Data Units Read/Data Units Written
どれくらい read / write されてきたかを見る大きなカウンタ。Controller Busy Time
controller が busy だった累積時間。Power On Hours
通電時間。Warning Composite Temperature Time/Critical Composite Temperature Time
warning / critical な温度状態にあった累積時間。
このあたりが取れると、温度、予備領域、使用率、read / write の積み上がり、稼働時間をまとめて把握できます。
温度関係
Composite Temperature はそのまま読むと Kelvin です。
313 のような値だけを見ても、直感的には少し分かりにくいです。
そのため表示では、
313 K40 C
のように、Kelvin と Celsius の両方を出す形にしました。
また、温度センサも同じように Kelvin で入っています。
ただしセンサ値が 0 の時はそのセンサは report していないと判断し、 no report としています。
使用状況
使用状況に関する項目は以下のとおりです。
Available SpareAvailable Spare ThresholdPercentage Used
です。
これらは数値だけ見ると意味が少し薄いですが、実際には割合として読むものなので % を付けるだけでかなり分かりやすくなります。
特に Percentage Used は、値自体は小さな整数でも「どれくらい使い込まれているか」を見る重要な項目です。
Warning項目
Critical Warning についてもビット列として入っていますが、ここは単に 0x00 や 0x02 を出すだけでなく、必要なら各 bit の意味を展開した方が読みやすくなります。
一方で、全部 OK の時まで細かく出すと少しうるさいので、実装では 0 の時は簡潔に、非ゼロの時だけ詳細を見る形に寄せています。
Data Units Read / Written
SMART Log で特に引っかかったのが、Data Units Read と Data Units Written の解釈でした。
この値は単純な byte 数ではなく、1000 × 512 byte 単位のカウンタです。
つまり、
1なら 512,000 byte 相当NならN * 512,000 byte相当
という見方になります。
ただし、これはそのまま厳密な byte 数を返しているというより、単位付きのカウンタとして扱う方が自然です。
そのため表示では、
- 生のカウンタ値を出す
- 必要なら概算の容量に直して補助表示する
という方が分かりやすいと考えました。
時間系の項目は名前だけだと誤解しやすい
SMART Log の中で、名前だけだと誤解しやすかったのが時間系の項目です。
例えば、
Warning Composite Temperature TimeCritical Composite Temperature Time
は、単位は minutes です。
さらに、
Total Time for Thermal Management Temperature 1Total Time for Thermal Management Temperature 2
は、名前に Temperature が入っていますが、こちらも温度ではなく seconds 単位の時間 です。
このあたりは値を取るだけではなく、
- 何の単位か
- 温度なのか時間なのか
を表示側で明示しないと、かなり誤解しやすい項目でした。
128bit のカウンタが普通に出てくる
SMART Log で印象的だったのは、かなり大きなカウンタが普通に入っていることです。
例えば、
Data Units ReadData Units WrittenHost Read CommandsHost Write CommandsController Busy TimePower On Hours
のような値は、実装では __uint128_t で持っています。
つまり、SMART Log は「温度や寿命の目安を見るだけ」の log page ではなく、長期間の利用履歴をかなり大きなカウンタで持つ log page でもあります。
実装としては offset を読んで __uint128_t に詰めるだけですが、理論側では「SMART には 128bit のカウンタが普通にある」という前提を持っておかないと、型の選び方や表示方法で迷いやすい項目でした。
実装は意外と薄い
実装そのものとしてやっていることは、そこまで複雑ではありません。
- 512 byte を受け取る
- 必要な offset を decode する
- 表示時に単位や意味を補う
という流れです。
今回の SMART Log で本当に大事だったのは、byte 列を読む手順よりも、その値が 何の単位で、どういう意味を持っているか を整理することでした。
まとめ
今回のSMARTでは、実装面よりも、機能面としてややこしい単位あたりを注意しながら実装しました。
特に時間とData Unit単位はややこしい部分です。
次はこの続きとして、Error Information Log について解説します。