私は、プロセスが終了した後にクリーンアップを行うLinuxカーネルで場所を見つけようとしています。具体的には、プロセスが-9シグナルで強制終了された後にオープンTCP接続を処理するかどうかを調べたいと思います。私はかなりすべての接続を閉じると確信していますが、詳細を見たいと思いますし、接続が正しく閉じられていない可能性がある場合。プロセスが終了した後、Linuxカーネルはどこで処理を行い、TCP接続をクリーンアップしますか?
Linuxカーネルソースへのポインタは大歓迎です。
私は、プロセスが終了した後にクリーンアップを行うLinuxカーネルで場所を見つけようとしています。具体的には、プロセスが-9シグナルで強制終了された後にオープンTCP接続を処理するかどうかを調べたいと思います。私はかなりすべての接続を閉じると確信していますが、詳細を見たいと思いますし、接続が正しく閉じられていない可能性がある場合。プロセスが終了した後、Linuxカーネルはどこで処理を行い、TCP接続をクリーンアップしますか?
Linuxカーネルソースへのポインタは大歓迎です。
プロセス終了の肉は、exit.c:do_exit()
によって処理されます。この関数はexit_files()
を呼び出し、put_files_struct()
を呼び出し、close_files()
を呼び出します。すべてのファイル上
close_files()
ループは、struct file
オブジェクトにfput()
を呼び出しそれぞれ、上filp_close()
を呼び出して、(すべてのソケットを含む)プロセスが開いているディスクリプタ。 struct file
への最後の参照が入力されると、fput()
はファイルオブジェクトの.release()
メソッドを呼び出します。これはソケットの場合sock_close()
の関数がnet/socket.c
になっています。
ソケットクリーンアップは、プロセスが終了した後にすべてのファイルディスクリプタを解放し、プロセスクリーンアップによって直接実行されないという副作用が多いと確信しています。
私は手足を外に出て、ネットワークプログラミングで共通の落とし穴を打っていると思います。プロセスが終了した後にアドレスにバインドしようとしたときに「使用中のアドレス」エラー(EADDRINUSE)が発生するという問題が発生していると推測されるのであれば、ソケットのTIME_WAITを実行しています。
このような場合は、タイムアウト(通常は60秒)を待つか、すぐに再利用できるようにソケットを変更することができます。あなたは、ハーフオープン接続の問題を抱えている、と完全にTCPがどのように機能するかを理解していないよう
int sock, ret, on;
struct sockaddr_in servaddr;
sock = socket(AF_INET, SOCK_STREAM, 0):
/* Enable address reuse */
on = 1;
ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
[EDIT]
あなたのコメントから、それが鳴ります。 TCPは、クライアントが死んでいるのか、またはアイドルなのかを知る方法がありません。 kill -9
クライアントプロセスの場合、4方向クローズハンドシェイクは決して完了しません。これはあなたのサーバにオープンな接続を残すべきではないので、何が起こっているかを確かめるためにネットワークダンプを取得する必要があります。
私はあなたがやっていることを正確に知らずにこれをどう対処すべきかについては言えませんが、TCP Keepalive hereについて読むことができます。いくつかのオプションは、空または空のメッセージを定期的にクライアントに送信すること(プロトコルの変更が必要な場合があります)、またはアイドル状態の接続でハードタイマーを設定することです(有効な接続が切断される可能性があります)。
ありがとうございます...ファイル記述子のクリーンアップは実際に接続の終了につながります。 Btw、私は別の問題に遭遇しています;-)私たちのサーバは、-9で殺されたクライアントからの古い接続を見ており、なぜそれを調べようとしています。今のところ解決策は、サーバーからのアイドル状態の接続を自動的に閉じてSO_KEEPALIVEを使用することですが、問題を理解しようとしています。 –
その後、半開きの接続に問題があるようです。私は私の答えを更新します。 – JimB
ありがとうございました。私はちょうど昨日、Tcp keepalive faqを読んでいます。アイドル状態の接続をサーバーに追加することも追加しました。サーバから「ping」を送信するプロトコルを変更することは選択肢ではありませんが、私たちはSO_KEEPALIVEとアイドル状態の接続を削除することを組み合わせて行います。私が混乱しているのは、私がkill -9をローカルでプレイしているとき、カーネルはこの接続をちょうど良いものにしようとしているということです。 Btw、クライアントとサーバーの両方が同じネットワーク上で制御されているため、この問題は1つの展開でのみ発生しています。 –
答えが好きで、カーネルの問題やネットワーキングの問題が発生した場合、私は興味があります。また、あなたの質問を更新することは、後にこれを偶然見つけた人を助けるでしょう。 – JimB
@JimB、あなたが私たちのネットワーク問題に興味があるなら、いいえ、私は何が問題なのか分かりません。これらのアイドル状態の接続を追加してso_keepaliveを使用するようにしましたが、あまりにも多くのトラフィックがあり、トラフィックダンプを実行して特定のパケットが失われるかどうかを確認するのは非常に難しいです。その閉鎖について、私は彼の答えで言及したソースをチェックしました。そして、Linuxカーネルは、プロセスがkillされたときにソケットを閉じることを少なくとも試みます。それが成功するかどうかは別の質問です。 –