この互換性の問題をどのように解決しますか? 答え

これはまだRaymond Chenの翻訳であり、Habrに関する前のトピックのコメントへの回答ではないことを思い出してください。 こことそこにあるコメントの提案はかなり似ていますが。



コメントで提案された問題に対するいくつかの解決策を分析します。





エラーが発生する主なシナリオは、大きなディスク、小さなコンピューター、および電源コードを差し込める場所で構成されるNASデバイスであると見落としている人もいました。 このコンピューターのOSはROMにあり、完全なフラッシュによってのみ置き換えられます。 ベンダーがリリースするまで待つ必要があるため、ドライバーをダウンロードして更新するだけでは機能しません。



誤ったドライバーの定義に関して、CIFSプロトコル(別名SMB)は、どのバージョンがサーバー上にあるかを判別するのに十分な情報をクライアントに提供しません。 一般的なサーバーカテゴリ(OS / 2、Samba、Windows NTなど)を報告する「ファミリ」フィールドのみがあります。 クライアントが言うことができるのは、「さて、サーバーはSambaのあるバージョンで実行されています」です。 彼は、このバージョンが間違っているか修正されているかを言うことはできません。 唯一の方法は、エラーのあるサーバーで作業を開始するかどうかを決定し、それがどのように終了するかを確認することです。



エラーが発生した場合、すぐにリストを読み直すことはできません。エラーが検出された時点で、リストの一部がすでにクライアントに返されています。 アプリケーションはIShellFolder :: EnumObjectsを呼び出し、シェルはクイックリクエストを実行します。 アプリケーションは毎回IEnumIDList :: Nextを実行し、次の結果を取得します。 約100個の要素(ops)を返した後、サーバーは迅速なリクエストを中断する悪いものの1つであることがわかりました。 そして今何? 時間をさかのぼって、すでに彼に与えられたすべての要素をアプリケーションから取り除くことは不可能です。



別の提案は、タイプERROR_PLEASE_RESTARTの新しいエラーコードを返すことで、これは「うーん、サーバーに問題があります。 もう一度お試しください。遅いだけです。」 これは、サーバーが既に特定のエラー、つまりSTATUS_INVALID_LEVELを返しているため、「何もしない」とほぼ同じです。 この間違いは、「もう一度試してください」という意味ではなく、「申し訳ありませんが、できません」という意味です。 たとえば、「高速」モードでサーバーから応答を取得しようとしたときに完全に合法的に発生する可能性がありますが、サポートしていません。 しかし、プログラムの観点からの効果は同じです。 「FindNextFileがxyzエラーを返した場合、サーバーに問題があるため、要求を再試行する必要があります。」「ERROR_PLEASE_RESTART」または「STATUS_INVALID_LEVEL」または「PURPLE_LILACS」と呼びます。 どちらを選択しても、結果は同じです。新しいエラーを認識して正しく対応するには、既存のコードを変更する必要があります。 変更されないプログラムは、奇妙な動作を開始します。



実際、このバグとの戦いは数ヶ月続きました。 この間、「高速」モードで正常に動作しなかったデバイスがさらに多く見つかりました。 それらの一部はパッチを適用していないバージョンのSambaに基づいており、一部はSMBプロトコルの独自の実装を使用しており、Sambaで見つかったソリューションはそれらに対して機能しませんでした。 悪いことは、ほとんどのデバイスが非常に低予算であり、ファームウェアのアップグレードがまったくできないことでした。



完全にパッチが適用された一般的なLinuxディストリビューションでも、同様の問題が報告されています。



さらに、これらのデバイスの一部は、完全に異なる方法で「高速」リクエストを正しく処理しませんでした。 たとえば、私が扱っていたそのうちの1つはエラーコードを返しませんでした。 たとえば、各ファイルの最初の5文字を​​スキップし、残りを返すなど、単にジャンクデータを返しました。 同様のエラーをどのように識別できますか? サーバーが「OK、私はe.txtファイルを持っています」と言ったら、Windowsは応答します:「ああ、そうは思わない。 最初の5文字が抜けているこれらの悪いサーバーの1つに違いないと思いますが、実際にはreadme.txtを意味します。 しかし、実際にe.txtファイルがある場合はどうでしょうか?



デバイスの1つは、「高速」モードでアクセスされたときに単にクラッシュしました。 別のものがハングし、再起動が必要でした。 「ああ、再び、誰かがラップトップをWindows Vistaで動作させ、それを企業ネットワークに接続しました。 ファイルサーバーが再びクラッシュしました。」



「高速」クエリを使用する際のこのようなさまざまな誤った動作により、エラーのあるサーバーを自動検出するためのスクリプトが非現実的になりました。 特に、サーバーが正しく形成されたデータを返しますが、データが正しくない場合。 そして、決定が正しかったとしても、サーバーがクラッシュしただけでは保存されません。



したがって、決定は次のとおりでした。ローカルドライブ以外の「高速」クエリの使用を停止します。 最も一般的なファイルシステム(NTFS、FAT、CDFS、UDF)のドライバーは、完全にMicrosoftの制御下にあり、高速モードとの互換性についてテストされています。



これはすべて悲しいことですが、互換性を確保することを犠牲にします。



Raymondには、行われた提案の分析に関連する投稿がいくつかありますが、すべてを翻訳するわけではありません。 しかし、誰が気にしますか:



APIにフラグを追加してドライバーのバグを回避してもスケールしない



ゲームの終了後にルールを変更する場合は、十分に注意してください



新しいフラグを追加して、以前はデフォルトでオンになっていた動作を有効にします






All Articles