9

プロセスが.soライブラリをロードしていて、ライブラリの新しいバージョンが利用可能な場合、プロセスを再起動せずに新しいライブラリに切り替えることは可能ですか?または、答えは、ライブラリ内の既存の関数の1つにパラメータが変更されているかどうかなどによって異なりますか?

私は数百のプロセスを実行し、それぞれが数十のライブラリをロードするかなり大きなシステムで作業しています。ライブラリは特定の機能を提供し、別々のチームによって提供されます。したがって、ライブラリの1つが変更された場合(バグ修正など)、実行中のプロセスに影響を与えることなく、ライブラリを内部で公開するのが理想的です。出来ますか ?

編集ありがとう!私の場合、新しいライブラリが利用可能になると、実行中のすべてのプロセスがそのライブラリの使用を開始する必要があります。古いバージョンで実行し、後で新しいバージョンを取得するオプションはありません。したがって、より安全なオプションは、プロセスをリロードすることです。

4

8 に答える 8

6

興味深い手法の1つは、チェックポイントの復元手順で失敗する傾向がありますが、目に見えない再起動を行うことです。

サーバープロセスまたはそれが何であれ、必要なすべての情報をディスクファイルに保存します。ファイル記述子番号と現在の状態を含みます。次に、サーバープロセスはexecシステムコールを実行して自身を実行し、現在のバージョンを置き換えます。次に、ディスクファイルから状態を読み取り、何も起こらなかったかのようにファイル記述子の提供を再開します。

すべてがうまくいけば、再起動は見えず、新しいプロセスは更新されたすべてのライブラリを使用しています。

于 2012-04-03T23:46:10.213 に答える
6

プロセスが実行されている状態で、リンクされたライブラリをその場でアップグレードすることはできません。試みることもできますが、成功した場合(「テキストファイルは使用中です」というエラーメッセージで失敗しない場合)、プロセスを再起動して、新しいライブラリをメモリにマッピングする必要があります。

lsofコマンドを使用して、リンクされているライブラリ(ランタイムまたはリンクタイム)を確認できます。

lsof -p <process_pid> | grep ' mem '
于 2012-04-03T21:25:16.603 に答える
4

少なくとも、ライブラリのインターフェイスがバージョン間で変更されないようにする必要があります。それが保証されている場合は、dlopen / dlsymを使用してライブラリを動的にロードすることを検討し、dlcloseで再ロードできるかどうかを確認します。

私はこれを自分でやったことはありませんが、それが私が最初に追求する道です。このようにしたら、結果を公開できますか?

于 2012-04-04T12:14:03.927 に答える
4

Linuxはいくつかの動的ローダーインターフェースを提供し、プロセスは実行時に動的ライブラリをロードできます。Linuxが提供するdlopenとdlsysmで問題が解決する場合があります。

于 2013-03-18T09:22:32.283 に答える
1

ライブラリがかなり定期的に変更されることを期待し、稼働時間を維持することを期待する場合は、そのようなライブラリが実際に緩く結合されたコンポーネント(サービスなど)になるようにシステムを再設計する必要があると思います。

そうは言っても、質問に対する私の答えは「はい」です。特定の状況下では、プロセスを再起動せずに共有ライブラリを更新することが可能です。ほとんどの場合、たとえば、ライブラリのAPIが変更されたとき、データセグメントの配置が変更されたとき、ライブラリが内部スレッドを維持しているときなど、それは不可能だと思います。リストはかなり長いです。

コードの非常に小さなバグ修正については、ptraceを使用してプロセスのメモリ空間に書き込み、そこから動的リンクに関して/lib/ld-linux.soが行うことをやり直すことができます。正直なところ、それは非常に複雑な活動です。

于 2012-04-03T22:28:07.710 に答える
0

lddプロセスのバイナリは、調べる1つの方法です。理論的には可能ですが、実行中のLinuxカーネルをいじくり回すkspliceなどのユーティリティが存在することは確かですが、実行中のプロセスをいじくり回すことはお勧めできません。

アップグレードするだけで、実行中のプロセスは古いバージョンで続行され、再起動時に新しいバージョンを取得します。これは、パッケージ管理システムが適切で、インストールに適したものがわかっていることを前提としています。

于 2012-04-03T20:57:31.053 に答える
0

-h共有ライブラリのバージョン管理とldオプションについて知りたい場合があります。

これを使用する1つの方法は次のとおりです。

ビルドシステムでバージョンカウンターを維持します。共有ライブラリを構築するには、次のものを使用します。

ld ..... -h mylibrary.so.$VERSION

ただし、それを単なるプレーンとして開発ツリーのライブラリに配置しますmylibrary.so。(.so全体を.aファイルに入れることを含むハックもあります)。

これで、実行時に、ライブラリを使用するプロセスが完全バージョンの名前を探します。新しいバージョンを公開するには、画像に新しいバージョンを追加するだけです。古いバージョンに対してリンクされた実行中のプログラムは、引き続きそれを使用します。プログラムが再リンクされ、新しいプログラムに対してテストされると、新しい実行可能ファイルがロールアウトされます。

于 2012-04-03T21:07:44.443 に答える
0

使用中の.soをアップグレードできる場合とできない場合があります。これは主に、それを実行しようとする方法に依存しますが、実行しているカーネルの安全性の保証にも依存します。

これを行わないでください:cat new.so> old.so ...最終的に、プロセスがページに何かを要求しようとし、それが正しい場所にないことに気付く可能性があるためです。物事のアドレスが変更される可能性があり、それでも同じiノードであるため、これは問題です。ファイルのバイトを上書きしているだけです。

ただし、次の場合:mv new.so old.so実行中のプロセスは、古いライブラリの名前のないiノードを保持できますが、プロセスの新しい呼び出しは新しいファイルを取得するため、ほとんどのシステムで問題ありません。しかし、一部のカーネルは、おそらくそれら自体の単純さのために、おそらく注意を払って、使用中の.soをmvさせたくないのです。

于 2012-04-03T22:05:26.307 に答える