クラッシュせずに共有ライブラリをアップグレードする方法は?


18

ここでは、実行可能ファイルを書き換えることができ、プロセスは正常に実行されます-プロセスが再起動すると再読み込みされます。

ただし、プロセスの実行中に(devからテストサーバーへのscpを使用して)バイナリファイルを置き換えようとすると、「file busy」と表示されます。そして、共有ライブラリファイル(* .so)を置き換えると、それをリンクするすべてのプロセスがクラッシュします。

なぜそうなのか?何か不足していますか?プロセスを停止/クラッシュせずにバイナリファイルを置き換えるにはどうすればよいですか?


あなたは確認することができます.so使用してファイルをldd filename.so依存関係を確認するために
ラーフルパティル

私は依存関係を知っています。実行中のプロセスに影響を与えずにこれらのファイルを置き換える方法が必要です。リンクされた質問が意味するように
サム

ダウンタイムが必要です。または、次のようにすることができます stop app && create symlink of .so && start app
Rahul Patil

回答:


21

ソフトウェアパッケージがアップグレードされている場合でも正常に実行されるのはなぜですか?、ロックはファイル名ではなくiノードに配置されます。バイナリをロードして実行すると、ファイルはビジーとしてマークされます。そのため、書き込みをしようとするとETXTBSY(ファイルビジー)エラーが発生します。

現在、共有ライブラリの場合は少し異なります。ライブラリは、を使用してメモリをプロセスのアドレス空間にマップしmmap()ます。けれどもMAP_DENYWRITE、このチェック-指定することができ、Linux上で少なくともglibcは黙っ(manページによると、ソースをチェックして自由に感じる)、それを無視したスレッドを。したがって、実際にファイルを書き込むことができ、メモリマップされているため、変更はほとんどすぐに表示されます-つまり、一生懸命努力すると、ライブラリを上書きしてマシンをブリックすることができ ます。

したがって、更新する正しい方法は次のとおりです。

  1. ファイルを削除します。これにより、ファイルシステムからデータへの参照が削除され、使用する可能性のある新たに生成されたアプリケーションからアクセスできなくなります。 ;

  2. 内容が更新された新しいファイルを作成します。

新しく作成されたプロセスは更新されたコンテンツを使用し、実行中のアプリケーションは古いバージョンにアクセスします。これは、健全なパッケージ管理ユーティリティが行うことです。ただし、完全に危険がないわけではないことに注意してください。たとえばdlsym()、ライブラリのAPIがサイレントに変更されると、コードを動的にロードするアプリケーション(使用者や友人)に問題が発生します。

本当に安全な状態にしたい場合は、システムをシャットダウンし、別のオペレーティングシステムインスタンスからファイルシステムをマウントし、更新したシステムを再度更新して起動します。


6

rpmアップグレードも同じことを行います-クラッシュすることなくバイナリとライブラリを実行します。

だから違いは何ですか:

  1. ファイルのリンク解除
  2. 同じ名前で新しいファイルを書き込む

これはファイルをインプレースで置き換えません。in-use-binaryを参照するiノードは、開いている最後のオブジェクトが終了するまで「ビジー」のままです。新しいファイルは、新しいiノード番号で作成されます。

今、scpまたはcpファイルインプレースを交換しようとします- iノードが参照しているコンテンツを変更することになります。説明したとおり、これは機能しません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.