ソフトウェアを実行しているときに、パッケージマネージャーを実行してソフトウェアをアップグレードすると、Linuxはパッケージアップグレードの実行プロセスを停止させないことに気づきました。 Linuxはこれをどのように行うのですか?
その理由は、Unixは実行中に実行可能ファイルをロックしないか、Linuxのようにロックしても、このロックはファイル名ではなくiノードに適用されるためです。つまり、ファイルを削除した(実際にはリンクを解除した)後も同じ(古い)データにアクセスし、基本的にパッケージの更新と同じ名前の新しいファイルに置き換えられた後も、開いたままのプロセスが同じ(古い)データにアクセスしています。
これは、UnixとWindowsの主な違いの1つです。後者はロックされているファイルを更新できません。ファイル名とiノード間のレイヤーが欠落しているため、通常は完全な再起動が必要なため、パッケージの更新やインストールに大きな手間がかかるためです。
実行可能ファイルは通常、一度開かれ、ファイル記述子にアタッチされます。単一の実行期間中に再度開かれたバイナリに対するファイル記述子はありません。たとえば、bash
を実行すると、exec()
は通常、/bin/bash
が指すiノードのファイル記述子を、呼び出し時に1回だけ作成します。
これは、実行中に(呼び出されたパスを使用して)自分自身を再度読み取ろうとしない単純なバイナリの場合、キャッシュされるコンテンツがぶら下がりiノードとして有効なままであることを意味します。つまり、以前のバージョンの実行可能ファイルのレプリカが基本的に存在します。
より複雑なケースでは、これにより問題が発生する可能性があります。たとえば、構成ファイルがアップグレードされ、その後再読み取りされる場合や、プログラムが実行されたパスを介してプログラム自体を再実行する場合があります。プログラムが相互接続されていて、1つがアップグレードの前に実行され、その後(おそらく最初のプログラムによって)実行された場合にも問題が発生する可能性があります。これは、一部のライブラリにも当てはまります。
ただし、単純なユースケースでは、プロセスを再起動せずにアップグレードしても安全です。