Directory Not Empty、消せない幽霊


削除できないファイル最近部門NASテストチームは非常に奇妙な問題に遭遇した.SMB共有フォルダが存在するファイルツリーを削除したとき、サブディレクトリのすべてのファイルを削除した後、このサブディレクトリを削除したとき、システムが「Directory Not Empty」というエラーを報告し、使用例テストに合格しなかった.このディレクトリを開くと、確かに削除に成功していないファイルがあり、I/Oツールのログを確認した.すべてのファイルが正常に削除されたことをレポートします.I/Oツールに問題があって正確にエラーを報告していないのか、このツール開発者の研究を経て確認したところ、ツールに問題はないようで、この問題は最初は開発チームにボールを蹴られ、SMB 2サーバーの問題だと認められなかった.死活はネットワークパケットを捕まえて確認させなければならない.
ネット分析の偽専門家として、自分も厚かましくNASテストチームに擦り込んで強引に力を入れ、この懸案を誰が落石するかを望んでいる.
スナップショットの再生まず、スナップショットパラメータを設定し、問題を再現する手順がスムーズです.テストパラメータに変更がないため、問題がスムーズに再現され、問題が発生した時点のネットワークパケットがすべてキャプチャされます.
Windows 2106のクライアントで、パッケージツールwireshark(対応するコマンドラインツールはtshark)を開き、関連パラメータを設定します.
$ tshark -i ens1 -B 4096 -s 1024 -w client-traffic.pcap

パラメータの意味は、インタフェースens 1上で長さ1024バイトの各フレームをキャプチャする、これらのフレームをclient-trafficに存在させることである.pcapのファイルに
分析は、ネットワーク・パケットをキャプチャした後、パケットの分析を開始します.
同様にtsharkコマンドにより解析を解包し、開いた内容をそれぞれ要約ファイルclient-trafficにリダイレクトする.summaryと詳細展開フォーマットのclient-traffic.detailファイル:
$ tshark -t ud -Y "ip.addr==" -r client-traffic.pcap >>client-traffic.summary

$ tshark -t ud -O smb2 -Y "ip.addr==" -r client-traffic.pcap >>client-traffic.detail

Client-trafficを開きます.summaryファイルの後のステップは、削除に成功していないファイル(ファイル名:VCL 8 iMkGWgll 2 VJoEFMUa 0 FKp 1 DJHEG 2)が最後に現れたフレームを見つけることです.簡単にテキスト検索で位置決めできます.対応するフレームを見つけた後、この操作はCreate操作で、プロトコル[MS-SMB 2]によると、削除操作は3元操作Create/SetInfo/Closeのセットで実現され、Delete-On-Closeと呼ばれています.我々が探しているのは削除操作であるため、このCreate(Frame#210725)要求は三元削除の第一歩であり、その後のフレームは一つ一つ探していると大胆に推測できる.やはり第2ステップSetInfo(Frame#210727)と第3ステップClose(Frame#210757)が見つかり、このフレーム展開によりFileID属性が前の2ステップの操作対象と一致していることが確認された)の2つの要求と対応するサーバ側からの返信:最後にCloseはサーバからの返信が得られなかった
Delete-On-closeオペレーションの最初の2つのステップDelete-On-closeオペレーションの最初の2つのステップが最後のステップのcloseリクエスト(Frame#210757)にサーバ側からの返信が得られなかった場合、問題は明らかにここで、なぜサーバが最後のステップのcloseオペレーションに応答しなかったのかを分析し続けた.
最後にCloseはサーバから返信されませんでした
奇妙なことに、このclose操作が発行されてから0.1秒以内に何の返事も得られず、TCP層のタイムアウト再送(RTO)(Frame#210765)が出発した.道理で同じ実験室の内部ネットワークの下では、ネットワーク状況は非常に良く、RTOの発生は基本的に不可能である(高速再送でも極めて珍しい).サーバにダウンタイムが発生しない限り.このとき、私たちのテストでSMB 2のCA機能(Continues Availability:高信頼性、サーバの再起動やフェイルオーバを許容)をテストするために、エラー注入のテスト例を導入することがよくあることをふと思い出しました.テストログをもう一度見てみると、やはりファイルの作成と削除操作と同時にサーバノードの再起動操作が実行されていることがわかりました.タイムスタンプの表示と問題が発生した時点はずっと続いています.発生した問題はCAに関係しています.
ファイルを削除してサーバーを再起動
通常のCAプロセスを見てみると、クライアントの1つのSMB 2リクエストがサーバの再起動に遭遇した場合、ネットワークは一時的に切断され、送信されたリクエストは数回のタイムアウト再送信後にサービスの再起動後に送信されたTCPリセットリクエスト(RST)(Frame#210769)を受信し、クライアント側はこのリクエストを受信するとネットワークが切断されたことを知ることができ、後続の操作が継続されるため、TCPの接続を再確立(3回の握手によりFrame#210770,#210771,#210772)し、セッション(Session Setup.Frame#210776)と共有ファイルルートディレクトリとの接続(Tree Connect.Frame#210785)を再交渉(Negotiate.Frame#210773)して確立しなければならない.このときクライアントはCreate操作(Frame#210787)によりターゲットファイルへの接続を再開し(client-traffic.detailで展開後のCreate操作のRECONNECT情報が見られる)、サーバに接続してその前のステップからCAの機能特性を実現する
Frame#210773-#210786リビルドセッション
Client-traffic.detailでは、210787フレーム目の展開の詳細を見つけると、再接続(RECONNECT)操作を試みていることがわかります.
Frame#210787展開詳細
これまでクライアントのすべての操作はプロトコルの規定に従って行われていたが、今回の再接続後にファイルがサーバ再起動前の操作に接続され、ターゲットファイルの削除に成功したのではないか.答えを知るには、再接続操作に対するサービスの返信応答を確認し、サーバの返信のフレームを見つけて展開する必要があります.
Frame #210790
サーバは、再接続されたファイルが見つからなかった(STATUS_OBJECT_NAME_NOT_FOUND)と答え、クライアントは当然、サービスが再起動する前にターゲットファイルが正常に削除されたと考えているが、再起動によってネットワークが切断されたため、返信が成功しなかった.したがって、クライアントが残りのファイルの削除を継続することは、削除ディレクトリエラー(Frame#210838)が発生したことを知っている.ここでは、クライアントがプロトコルに厳格に従って要求したことを肯定することができ、サーバは、再接続された返信(Frame#210790)でファイルの削除に成功したことを誤って通知し、クライアントを誤導した.これは明らかにSMB 2サーバのBugです
Frame #210838
プロトコルのこのサーバ返信(Frame#210790)の定義を見てみましょう.
SMB 2プロトコル定義
Persistentのファイルハンドルがグローバルハンドルテーブルに見つからない場合(closeに成功したと仮定)、STATUS_に戻ります.OBJECT_NAME_NOT_FOUNDの返信
最後にこれらのネットワークパッケージに基づいて、開発チームと確実に交流した後、彼らはこのBugを受け入れて修復しました.
wiresharkによって、多くの複雑で奇妙な問題がその背後にある秘密の会話を探究し、いかなるクモの跡を得て問題の根源を見つけることができることが明らかになった.
SMB 2プロトコル: