.so
プロセスの実行中にシンボリックリンク.soファイルをロードするプロセスを更新すると、競合が発生する問題が発生しました。
初めて起動したときに共有ライブラリ(.so)をロードする長期実行プロセスがあり、プロセスが実行された後も長い間これらの共有ライブラリを使用することができます。プロセスによってロードされる共有ライブラリは、実際には.so
実際へのシンボリックリンクです(すべて.so
を各プロセスに関連付けられた構造化ディレクトリに配置します)。場合によっては、いくつかの修正を適用し、.soファイルを再コンパイルする必要がありますが、これにより、更新された.soのシンボルにアクセスするといくつかの長期実行プロセスがクラッシュすることがわかりました。
私の理解によると、プロセスがシンボリックリンクの代わりに実際の.soをロードしている場合、.so(新しいinodeで.soファイルを削除して再生成)を再コンパイルするときに古いThe inodeが発生するため、この動作は表示されませんになります。 .soは、そのファイルを開いたすべてのプロセスが閉じられるまで存在し続けなければなりません。私が見ている問題は、ターゲット.soの代わりにシンボリックリンクを開くプロセスによるものだと思います。したがって、長期実行プロセスは、ターゲット.soの代わりにシンボリックリンクinodeのみを保持します.so
。しかし、私の理論が正しいことを確認するのに十分な情報はありません。
すべてのプロセッサがファイルを閉じるまで、ファイルのinodeは存在しますか?ファイルをマッピングするがファイル記述子を開かないプロセスでこれは機能しますか?
シンボリックリンクのopen / mmapはシンボリックリンクのインデックスノードのみを追跡しますか?それとも、オペレーティングシステムがターゲットファイルのinodeを破損するのを防ぎますか?
答え1
はい、Linux(および他のすべてのPOSIX互換カーネル)では、すべてのプロセッサがファイルを閉じるまでファイルのinodeが存在します。これにはマッピングファイルが含まれます。
これは次のために発生します。POSIX:
mmap() 関数は、ファイル記述子 fildes に関連付けられたファイルに追加の参照を追加します。これは、対応するファイル記述子の後続のclose()によって削除されません。ファイルへのマッピングがもう存在しない場合、参照は削除されます。
シンボリックリンクの開く/ mmapは対応するinodeのみを追跡します。宛先ファイル(使用の極端な場合を除いて
O_PATH
)。呼び出されると、パス内のすべてのシンボリックリンクが検証され、open()
ファイル記述子はターゲットファイルのみを参照します。これをテストできます。
- ファイルを生成する
/tmp/original
/tmp/symlink
次を指すシンボリックリンクを作成します。/tmp/original
/tmp/symlink
プログラムで開く(例:Pythonシェルに入力)f = open('/tmp/symlink', 'r')
- 見ている
/proc/<pid of the program>/fd
- ファイル記述子は以下を指します。
/tmp/original
- ファイルを生成する
再コンパイル時に.soファイルが直接作成されず、実際に削除され、再生成されるか、長期実行プロセスが.sodlopen
ファイルを動的に再開するなどの方法を使用しないことを確認してください。
私が考えることができるもう1つの可能性は、遅延バインディングが長期実行プロセスで.soファイルのロードを遅らせることです。
環境で長期実行プロセスを開始して、遅延バインディングによって問題が発生したことを確認し、LD_BIND_NOW=1
再コンパイルによってまだプロセスが中断されていることを確認できます。