2

サーバー プロセスがあり、このサーバー プロセスには、それ自体を更新するコマンドを与えることができます。更新を保存し、system() を使用して更新スクリプトをバックグラウンドで実行します。更新スクリプトは、親プロセスを強制終了し、バイナリを削除して置き換え、再起動します。

再起動されたプロセスは、デバッグしようとしたときにさまざまな理由で失敗しましたが、今回は、割り当てようとしている TCP ポートが既に使用されているためです。私は、子プロセスが開いているポートを継承し、それが更新されたサーバー プロセスに継承されると推測しています。その結果、ポートは、プロセスが再度割り当てるために解放されません。

更新スクリプトを起動する方法は次のとおりです。

system("/usr/local/bin/update_script.sh > /dev/null 2>&1 &");

次に、スクリプトは次のことを行います。

killall server_process
rm /usr/local/bin/server_process
cp /tmp/update/server_process /usr/local/bin
server_process > /dev/null 2>&1 &

これを機能させる方法について何か提案はありますか? 更新を実行する前にサーバープロセスがその親ではなくなるように、更新スクリプトを切り離す方法はありますか? または、子プロセスが親のリソースを継承しないようにしますか?

ありがとう。

補遺: 解決策はFD_CLOEXEC、開いているすべてのファイル記述子に設定することです。残念ながら、これらの fd の一部はライブラリに埋もれており、それらを設定するには真剣にハックする必要がありますFD_CLOEXEC。どういうわけか、デフォルトにする必要がFD_CLOEXECあります。または、開いているすべての fd を反復処理して (方法は?)、 set など、思い切ったことをする必要がありますFD_CLOEXEC

4

1 に答える 1

1

更新スクリプトの開始方法を変更します。

switch(fork()) {
case -1: /* error */
    break;
default: /* parent */
    break;
case 0: /* child */
    for (i=3; i<1000; i++) close(i);
    system("/usr/local/bin/update_script.sh > /dev/null 2>&1");
    exit(0);
}

それはそれを行う必要があります。

于 2013-04-23T10:42:53.930 に答える