アップグレード中であっても、ソフトウェアパッケージが正常に実行されるのはなぜですか?


29

ソフトウェアを実行しているときに、パッケージマネージャーを実行してソフトウェアをアップグレードすると、Linuxがパッケージアップグレードの実行プロセスを停止させないことに気付きます。Linuxはこれをどのように行いますか?

回答:


35

理由は、実行中にUnixが実行可能ファイルをロックしないか、Linuxのように実行可能であっても、このロックはファイル名ではなくiノードに適用されるためです。つまり、ファイルを開いたままにするプロセスは、ファイルが削除(実際にはリンク解除)され、同じ名前の新しいファイルに置き換えられた後でも、同じ(古い)データにアクセスします。

これは、UnixとWindowsの主な違いの1つです。後者は、ファイル名とiノードの間にレイヤーがないため、ロックされているファイルを更新できません。通常、完全な再起動が必要なため、パッケージの更新やインストールが面倒です。


10
明確にするために、Linuxでは、実行中の実行可能ファイルを変更することはできません。ただし、ファイルのリンクを解除して、同じ名前の新しいファイルに置き換えることができます。
cjm

Linuxでは、実行中に実行可能ファイルを変更できます。あなたが何をしているのかを本当に知っていない限り、結果は予測できないでしょう。明示されていない「同じ名前」ポイントを追加しました。
jlliagre

4
@jlliagre私が誤解していない限り、あなたは私が知っている限りではできません:sprunge.us/egiR
クリスダウン

2
ただし、NFTSのすてきな点-コマンドラインまたは別のプログラムから名前を変更した場合、同じ名前のファイルをそこに戻すことができ、元のファイルを開いているプログラムには影響しません。(エクスプローラーの名前変更コマンドはこれに対して機能しません)
ステファンドナル

1
@cjm Linuxでの「ファイルテキストビジー」保護については正しいです、回答が更新されました。Solarisにはそのような制限はありませんが、私にとってはこれはもっとよく知っています。ただし、両方のOSで共有ライブラリを変更できます。
jlliagre

18

実行可能ファイルは通常、一度開かれ、ファイル記述子に添付され、単一の実行期間中に再度開かれたバイナリへのファイル記述子はありません。たとえば、を実行した場合bashexec()通常は、/bin/bash呼び出し時に一度だけポイントされたiノードのファイル記述子を作成します。

これは、実行中に(呼び出されたパスを使用して)実行中に自分自身の再読み取りを試行しない単純なバイナリの場合、キャッシュされたコンテンツはダングリングiノードとして有効なままになることを意味します。これは、実行可能ファイルの以前のバージョンのレプリカが本質的に存在することを意味します。

より複雑な場合、これは問題を引き起こす可能性があります。たとえば、構成ファイルをアップグレードしてから再読み取りしたり、プログラムを実行元のパスから再実行したりできます。プログラムが相互接続されていて、1つがアップグレードの前に実行され、1つが(おそらく最初のプログラムによって)実行された場合にも問題が発生する可能性があります。これは、一部のライブラリにも当てはまります。

ただし、単純なユースケースでは、プロセスを再起動せずにアップグレードしても安全です。


1
単純な場合でも、他の危険は、実行中のアプリケーションがバイナリのキャッシュコピーを使用しているため、アプリケーションを手動で再起動するまで古いバージョンのコードを実行し続けることです。これはほとんどの場合問題ではありませんが、アップグレードにセキュリティ修正が含まれている場合、パッチがインストールされているにもかかわらず、古いバージョンがまだ実行されているため、システムは依然として脆弱です。
ダン・ニーリー

1
最初の段落が不正確であると思います。Unix / Linuxカーネルは、実行可能プログラムを一度にロードするのではなく、メモリマップします。つまり、実際に使用されるページのみが最終的にRAMに格納されます。これが、Linuxでの「テキストファイルビジー」保護の要点です。実行可能ファイルの一部が起動されてから長く読み取られないという保証はありません。さらに、十分な大きさのプログラムでは一部のページがロードされることはありません。これは、動的にロードされるライブラリーではさらに当てはまります。たとえば、bashバイナリは約200の4Kページであり、それらがすべて平均セッションで使用されるかどうかはわかりません。
jlliagre

@jlliagre私はialloc()、ページ自体のメモリマッピングではなく、読み取り時にカーネル構造体へのing について話していました。現代のext *ファイルシステムでは、iノードは最終的にカーネル内(およびVMサブシステム内)で一貫していると思いますか?
クリスダウン

実行後、実行可能コンテンツの一部が実行後に長時間読み込まれないという保証はありません。また、実行中にしばらくしてから同じページが再び読み込まれないという保証もありません。
jlliagre

@jlliagre正しい、しかしそれは私が意図したものではない。おそらく、答えの中で少し言葉を刻んだのかもしれませんが、私が意図したことをより明確にしようとします。
クリスダウン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.