web-dev-qa-db-ja.com

Linuxはシンボリックリンクをどのように処理しますか?

あるプロセスがシンボリックリンクを読みたいときに何が起こっているのですか?読み取りまたは書き込みプロセス中にシンボリックリンクが変更された場合はどうなりますか?

たとえば、2つの巨大な同様の100Gファイル/mnt/1/mnt/2があります。 /mnt/1は、シンボリックリンク/home/user/fileから入手できます。一部のプログラムA/home/user/fileの読み取りを開始します。しばらくすると、リンクが/mnt/1から/mnt/2に変更されますが、Aはまだファイルを読み取っています。

プログラムは絶対パスをキャッシュしますか?

シンボリックリンクが変更されたために失敗してエラーになりますか、それとも何も起こらなかったように正常に動作しますか?

/home/user/fileがブロックデバイスにリンクされている場合(たとえば、2つの複製されたiSCSIディスク)は異なりますか?

11
rush

シンボリックリンクは、ファイルシステム内の実際のファイルの名前( inode )を指します。システムがそのシンボリックリンクを解決して実際のファイルを見つけて開くと、ファイルのiノードが検出されて使用されます。その時点で、ファイルに到達するために使用したパスは重要ではありません。 OSがキャッシュしないものは、iノードによってファイルから読み取られます。私が理解しているように、ハードリンクを介してファイルの読み取りを開始し、そのハードリンクを削除することができます (ファイルがまだ他の場所からリンクされている限り)、およびファイルが解決されている限り(名前string-> inode)、問題は発生しません。

9
Kevin

symbolicリンクは、ターゲットファイルのlocation(パスとファイル名)を含む小さなファイルであり、ディレクトリエントリに、シンボリックリンクであることを示すフラグが付いています。

シンボリックリンクを開くと、OSはその場所をたどってターゲットファイルを見つけます。ターゲット自体がシンボリックリンクである場合、シンボリックリンクではないファイルがnotのファイルを指すまで、ターゲットもそのロケーションに従います(1)(2)。 FinalFile)と呼びましょう。次に、OSはFinalFileinode を取得します(inodeは変更時間などのメタデータを含み、ファイルのデータへのポインターも持っています)。最後にFinalFileのiノードが開かれます。これ以降、プロセスはそのiノードを使用してファイルの読み取り/書き込みを行います。結果として、シンボリックリンクの名前またはパスの変更、シンボリックリンクの削除、パスまたはパスの名前の変更FinalFile、またはFinalFile(3)の削除は、処理する;同じiノードからまだ読み取っています。

ほとんどの場合、シンボリックリンクのファイルデータ操作はFinalFileに影響します(たとえば、シンボリックリンクの読み取りと書き込みはFinalFileの読み取り/書き込みになります)が、例外があります。 readlink()システムコールは、シンボリックリンク自体の内容を読み取ります。

一方、ファイルのメタデータ操作(名前の変更や削除など)は通常、シンボリックリンクに影響します。ただし、ここにも例外があります。lstat()システムコールはstat()に似ていますが、FinalFile(ではなく、シンボリックリンク自体に関する情報を返します。 2)。


(1)レベルの数には制限があり、シンボリックリンク内の場所が相対パスの場合、状況は少し複雑になります。

(2)詳細はsymlink(7):シンボリックリンクの処理を参照してください。 _man 7 symlink_

(3)rmコマンドまたはunlink()システムコールは、ファイルを物理的に削除しません。ファイルのiノードを指すディレクトリエントリを削除します。 bothの場合にのみファイル自体が削除されます。a)そのiノードを参照するディレクトリエントリ(ハードリンク)がなく、b)ファイルを開いているプロセスがない場合。

6
Keith Thompson

これはLinuxに対してほぼ透過的であり、運用システムよりも、使用しているファイルシステムとの関連性がはるかに高くなります。

これは通常のファイルではなく、非常に小さなファイルでもあります。たとえば、シンボリックリンク自体をVFATパーティションにコピーするだけでは機能するシンボリックリンクを作成できません。これは、ファイルシステムによって直接記録されるためです。

ハードリンクへのシンボリックリンクの違いは、予定がハードリンクのようにデータセクターにポイントするのではなく、ハードリンクにあることです。

例:

テスト1:

echo 'data' >file.txt

これにより、セクター10〜20を指すハードリンクfile.txtが作成されます*(*説明のための数字のみ)。

テスト2:

ではどうすればよいですか?

ln file.txt file_2.txt

これにより、セクター10〜20(file.txtと同じ)を指すハードリンクfile_2.txtが作成されたため、file.txtを削除してもセクター10〜20は予約されており、file_2.txt内のデータを表示できます... 。 (file.txtとfile_2.txtはどちらもオリジナルと同じです)

テスト3:

ln -s file.txt file_sym.txt 

シンボリックリンクfile_sym.txtをハードリンクfile.txtに向けたため、file_sym.txtにアクセスしようとするとfile.txtが表示されますが、file.txtを削除すると、file_symはターゲットを検出できなくなります。

これらはファイルシステム、たとえばLinuxのext4モジュール(またはカーネルでコンパイルされている場合)によって管理されます。Linuxや他のUnixを使用しているかどうかは関係ありません。