Solaris 8 のソフトウェア開発 (追補)

破壊されたデータの検出

以下の節では、どこでデータ破壊が発生する可能性があるか、およびそれらを検出するにはどのような手順が必要かについて説明します。

デバイス管理および管理データの破壊

ドライバは、PIO によるか DMA によるかを問わず、デバイスから取得したデータは壊れている可能性があるということを想定しなければなりません。特に、デバイスから得たデータから読み取った、または計算されたポインタ、メモリーオフセット、配列インデックスは、慎重に扱ってください。この種の値は有害な場合があり、参照に利用される場合、カーネルパニックを引き起こす可能性があります。この種の値はすべて、範囲および整列 (必要な場合) をチェックしてから使用してください。

ポインタが有害でなくても、誤った結果を導く可能性もあります。たとえば、オブジェクトの有効なインスタンスを指し示していても、該当する正しいインスタンスではないことがあります。可能であれば、ドライバはポインタと指示先オブジェクトをクロスチェックするか、またはポインタによって取得したデータの妥当性を検証すべきです。

他のタイプのデータ (パケット長、ステータスワード、チャネル ID など) も誤った結果を導く可能性があります。データの各タイプを可能な範囲でチェックすべきです。たとえば、パケット長の場合は、範囲をチェックして、負ではないか、収容バッファより大きくないかどうかを確認できます。また、ステータスワードの場合は、「不可能」ビットの有無をチェックできます。チャネル ID は有効 ID のリストと突き合わせます。

値を使用して Stream を識別する場合、ドライバは Stream が実際に存在しているかどうかを確認しなければなりません。STREAMS 処理は非同期の性質があるので、デバイスの割り込みがまだ処理されないうちに、Stream が取り除かれてしまうことがあります。

ドライバはデバイスからデータを再読み込みしてはなりません。データは 1 回だけ読み取って、妥当性を検証し、ドライバのローカル状態で格納します。こうすることによって、最初に読み取って検証したときには正しかったが、後で再読み取りしたときには正しくないというデータによる危険性を回避することができます。

さらに、連続して BUSY 状態を返すデバイス、または別のバッファ処理を要求するデバイスがシステム全体をロックアップすることがないように、ドライバで、すべてのループがバインドされていることも確認すべきです。

受信したデータの破壊

デバイスエラーによって、受信バッファに壊れたデータが格納されてしまうことがあります。このような破壊を、デバイスドメインの外 (たとえば、ネットワーク内など) で発生した破壊と区別することはできません。通常は、プロトコルスタックのトランスポート層やデバイスを使用するアプリケーション内部での整合性チェックなど、この種の破壊に対処する既存のソフトウェアが既に配備されています。

ディスクドライバなどのように、受信したデータの整合性を上位層でチェックしない場合は、ドライバ内部で整合性をチェックすることができます。受信したデータの破壊を検出する方法は、一般にデバイス固有です (チェックサム、CRC など)。

障害の検出

従来のデバイスドライバでは、障害を検出した場合に、デバイスまでのデータパスを無効にできます。PIO アクセスが無効にされている場合にそのデバイスから読み取りを行おうとすると、undefined 値が返り、書き込みが無視されます。DMA アクセスが無効にされている場合は、デバイスはメモリーへのアクセスが禁止される可能性があり、または読み取り時に未定義データを受け取り、書き込みが廃棄される可能性があります。

デバイスドライバは次の DDI ルーチンを使用することによって、データパスが無効にされているかどうかを検出することができます。

各関数は、指定のハンドルによって示されたデータパスに影響を与えるような障害が検出されているかどうかを調べます。いずれかの関数が DDI_FAILURE を返した場合、そのデータパスに障害があります。ドライバは ddi_dev_report_fault(9F) を使用してその障害を報告し、必要なクリーンアップを実行し、さらに可能であれば、呼出側に適切なエラーを返す必要があります。