サービス利用可能性を確保するには、ドライバが下記を実行できるようにしなければなりません。
障害デバイスを検出して障害を報告する
デバイスを取り除く (Solaris のホットプラグモデルでサポートされる)
新しいデバイスを追加する (Solaris のホットプラグモデルでサポートされる)
潜在的な障害を検出できるように定期的な健全性チェックを実行する
ドライバはリソースの無駄なコミットを避けるために、適切なポイントでデバイス状態をチェックしなければなりません。ddi_get_devstate(9F) 関数を使用すると、ドライバでフレームワークによって維持されているデバイスの現在の状態を判別できます。
ddi_devstate_t ddi_get_devstate(dev_info_t *dip); |
ドライバは通常、OFFLINE のデバイスを扱うときには呼び出されません。デバイス状態は一般に、再構成アクティビティによって変更されたというような、以前のデバイス障害レポートを反映します。
システムは、デバイスのサービス利用可能性に対する影響という観点から、障害を報告しなければなりません。一般に次の場合に、サービス損失が予期されます。
PIO または DMA エラーが検出された。
データ破壊が検出された。
デバイスがロックされている、またはハングしている (たとえば、コマンドが完了しない場合など)。
ドライバの設計時にあり得ないと見なされたために、ドライバが対処しないことになっている状態が発生した。
ddi_get_decstate(9F) から返されたデバイス状態が、デバイスが使用不能であることを示している場合、ドライバは新規または未処理の入出力要求をすべて拒否し、(可能であれば) 適切なエラーコード (EIO など) を返す必要があります。STREAMS ドライバでは、M_ERROR または M_HANGUP をアップストリームに送り、ドライバが使用不能であることを示さなければなりません。
各メジャーエントリポイントで、またオプションで操作のためにリソースをコミットする前、および障害の報告後に、デバイスの状態をチェックする必要があります。いずれかの段階で、デバイスが使用不能であることが判明した場合は、ドライバで必要なクリーンアップ処理 (リソースの解放など) を実行し、タイミングよく戻る必要があります。再試行または回復処理を試行してはなりません。障害の報告も不要です。状態は障害ではなく、状態はすでにフレームワークと管理エージェントに認識されています。状態は、現在の要求および他の未処理すなわちキュー内の要求に完了マークを付け、可能であれば再びエラー標識を出します。
ioctl() エントリポイントは、デバイスが使用不能で、他 (エラー状態の回復など) が引き続き動作中である場合、所定の ioctl 操作における、デバイスに対する入出力 (たとえば、ディスクのフォーマットなど) 障害を意味する問題を提示します。したがって、状態チェックはコマンド単位で行う必要があります。または、別のエントリポイントまたはマイナーデバイスモードを使用して、あらゆる状態でこれらの操作を実装できますが、この方法は既存アプリケーションとの互換性の点から制約を受ける可能性があります。
close() は、デバイスが使用不能な場合であっても、常に正常に完了しなければなりません。デバイスが使用不能な場合は、割り込みハンドラがその後のすべての割り込みに DDI_INTR_UNCLAIMED を返す必要があります。割り込みが引き続き発生する場合は、最終的に割り込みが禁止されることがあります。
次の関数は、ドライバがデバイス障害を検出したことをシステムに通知します。
void ddi_dev_report_fault(dev_info_t *dip, ddi_fault_impact_t impact, ddi_fault_location_t location, const char *message); |
impact パラメータは、デバイスの通常のサービス利用可能性に障害が与える影響を示します。このパラメータは、障害に対する適切な処置を決定するために、システムの障害管理コンポーネントが使用します。この処置によってデバイス状態が変化することがあります。サービスが損われる障害が発生すると、デバイス状態が DOWN に変わります。サービスが低下する障害の場合は、デバイス状態が DEGRADED に変わります。
デバイスは次の場合に、障害として報告されなければなりません。
PIO エラーが検出された。
破壊されたデータが検出された。
デバイスがロックアップされた。
できるだけ、ドライバが同じ障害を繰り返し報告しないようにします。特に、デバイスがすでに使用不能状態になっている場合に、ドライバがエラーを報告しても無駄です (望ましくありません) (ddi_get_devstate(9F) のマニュアルページを参照)。
接続プロセスでハードウェア障害が検出された場合、ドライバは ddi_dev_report_fault(9F) のを使用して障害を報告するとともに、DDI_FAILURE を返さなければなりません。
潜在的な障害とは、他のアクションが発生するまで明らかにならない障害のことです。たとえば、コールドスタンバイモードのデバイスで発生したハードウェア障害は、マスターデバイスで障害が発生するまで検出されない可能性があります。マスターデバイスで障害が発生した時点で、システムに 2 つの障害デバイスがあり、動作を継続できない可能性があることが判明します。
一般論として、未検出のままの潜在的障害は、最終的にシステム障害につながります。潜在的な障害を検査しなかった場合は、冗長型システム全体の可用性が損なわれる危険があります。これを回避するには、デバイスドライバで潜在的な障害を検出し、他の障害と同様に報告しなければなりません。
ドライバには、デバイスに対する定期的な健全性チェックを行うメカニズムが必要です。デバイスを第 2 デバイスすなわちフェイルオーバーデバイスにできる、障害耐久 (フォールトトレラント) の状況では、故障した第 2 デバイスを早い段階で検出することが重要です。そうすれば、第 1 デバイスで障害が発生しないうちに修理または交換することができます。
定期的な健全性チェックには、次のものがあります。
ボードに対してクイックアクセスチェック (書き込み、読み取り) を実行し、さらに ddi_check_acc_handle(9F) ルーチンを使用してデバイスをチェックする。
前回のポーリング以後、値がドライバの予期値と決定的に異なっているデバイスについて、レジスタまたはメモリーロケーションをチェックする。
一般に決定的な動作を示すデバイス機能には、ハートビートセマフォ、デバイスタイマー (たとえば、ダウンロードで使用されるローカル lbolt など)、イベントカウンタがあります。デバイスから更新済みの予想可能値を読み取ると、進行が順調であるかどうか、ある程度確かなことがわかります。
ドライバによる発行時に、発信要求 (送信ブロックまたはコマンド) にタイムスタンプを設定する。
定期的な健全性チェックで、期限を過ぎていながら完了していない要求を検索できます。
予定された次回のチェックまでに完了すべき、デバイスに対するアクションを開始する。
このアクションを割り込みにすると、デバイスの回路が割り込みのデリバリにまだ対応できるかどうかを確認するうえで理想的です。