これはおおよそユニバーサルUFS。
私が理解したのは、絶対パス(たとえば)が与えられると、/home/userU/file.txt
すべてのディレクトリとファイルがディスクにアクセスすることです。したがって、この場合、ディスクは4回アクセスされます。
1、1、1、1/
home/
/userU
file.txt
私の質問は
- 上記のファイルのinodeを指すハードリンクが与えられたら
/hL
、ディスクアクセス順序は何ですか? - 上記のファイルを指すソフトリンクが与えられた場合
/sL
、ディスクアクセス順序は何か?
3つの場合すべて、inodeまたは他のデータが最初にキャッシュされていないと仮定します。
答え1
背景
次のディレクトリ設定があるとします。
$ ll
total 0
-rw-r--r-- 2 root root 0 Jul 29 23:36 afile.txt
-rw-r--r-- 2 root root 0 Jul 29 23:36 hL
lrwxrwxrwx 1 root root 9 Jul 30 01:22 sL -> afile.txt
それでは、2つの質問を見てみましょう。
質問
- 上記のファイルのinodeを指すハードリンク/ hLが与えられた場合、ディスクアクセス順序は何ですか?
ハードリンクを使用すると、指す元のファイル/ディレクトリと同じinode参照があります。したがって、これを読み取るための追加のHDDアクセスはありません。
たとえば、
$ stat hL | head -3
File: ‘hL’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 667668 Links: 2
そして
$ stat afile.txt | head -3
File: ‘afile.txt’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 667668 Links: 2
この2つの唯一の違いは名前です。したがって、両方のパスはHDDアクセス回数が等しくなります。
- 上記のファイルを指すソフトリンク/ sLが与えられた場合、ディスクアクセス順序は何ですか?
しかし、ソフトリンクを介して追加のHDDアクセスが可能です。これらの追加アクセスは、ファイルがあるディレクトリのメタデータへのアクセスですsL
。これにより、ファイルが実際にシンボリックリンクであり、他のファイル/ディレクトリを指すという詳細が返されます。
たとえば、
$ stat sL | head -3
File: ‘sL’ -> ‘afile.txt’
Size: 9 Blocks: 0 IO Block: 4096 symbolic link
Device: fd00h/64768d Inode: 681295 Links: 1
ここでは、そのタイプが "Symbolic Link"であり、afile.txt
。
では、読む順序はどうなりますか?
Bashシェル自体を使用して、これらのファイル/ディレクトリに対してコマンドを実行すると、どのように機能するかをstrace
確認できます。
[pid 18098] stat("/tmp/adir/hL", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid 18098] open("/tmp/adir/hL", O_RDONLY) = 3
[pid 18098] fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
これはコマンドの出力ですmore /tmp/adir/hL
。
のため/tmp/adir/hL
:
- 統計/オープン(/) → 統計/オープン(tmp) → 統計/オープン(adir) → 統計/オープン(hL)
のため/tmp/adir/sL
:
- 統計/オープン(/)→統計/オープン(tmp)→統計/オープン(adir)→統計/オープン(sL)→統計/オープン(afile.txt)
詳しくは
これシンボリックリンクのウィキペディアページまた、これらすべてを避けてください。
inode内にリンク値を保存すると、ディスクブロックとディスク読み取りが保存されますが、オペレーティングシステムはまだリンクのパス名を解決する必要があります。これを行うには、常に追加のinodeを読み、通常は他の(おそらく多くの)ディレクトリを読み、リストを処理する必要があります。リンクのパスコンポーネントに一致するものが見つかるまで、ファイルと各ファイルのinodeを検索します。クイックシンボリックリンクは、リンクが同じディレクトリにあるファイルを指している場合にのみ、他のシンボリックリンクよりもはるかに優れたパフォーマンスを提供します。
引用する
答え2
両方の質問は実際に「どのように機能しますか?」という同じ質問path_resolution
なので、この観点から全体のプロセスを見てください。
~からパス解像度(7)私達は読みます:
ファイル名(またはパス名)は次のように解析されます。
次に、最初のステップがハードリンクとシンボリックリンクの両方に共通していることがわかります(システムはルートチェックの開始点を決定します。ルートディレクトリ、/
chrootディレクトリ、または現在のディレクトリ)。
パス名が "/"文字で始まる場合、検索開始ディレクトリは呼び出しプロセスのルートディレクトリです。 (プロセスは親プロセスからルートディレクトリを継承します。通常、これはファイル階層のルートディレクトリになります。プロセスはchroot(2)システムコールを使用して別のルートディレクトリを取得できます。プロセスは完全にプライベートマウントを取得できます。存在する場合は、パス名の "/" 部分を処理する CLONE_NEWNS フラグのセットと一緒に Clone(2) システム呼び出しを呼び出して、名前空間 (またはその祖先の 1 つ) が開始されます。
パス名が「/」文字で始まらない場合、解析プロセスの開始ディレクトリはプロセスの現在の作業ディレクトリです。 (これも親から継承されます。chdir(2)システムコールを使用して変更できます。)
「/」文字で始まるパス名は絶対パス名です。 「/」で始まらないパス名は相対パス名です。
ご覧のとおり、ハードリンクとシンボリックリンクの始点に違いはありません。しかし、道を歩き始めるとき、次のステップは違いを生み出します。
現在の検索ディレクトリを検索開始ディレクトリに設定します。これで、パス名の最後ではない各コンポーネント(コンポーネントは「/」文字で区切られた部分文字列)について、そのコンポーネントは現在のルックアップディレクトリから取得されます。
プロセスに現在検索されているディレクトリに対する検索権限がない場合、EACCESエラー(「許可拒否」)が返されます。
コンポーネントが見つからない場合は、ENOENTエラー(「該当するファイルまたはディレクトリはありません」)が返されます。コンポーネントが見つかったがディレクトリまたはシンボリックリンクではない場合、ENOTDIRエラー(「ディレクトリではない」)が返されます。
コンポーネントが見つかり、ディレクトリの場合は、現在の検索ディレクトリをそのディレクトリに設定し、次のコンポーネントに移動します。
説明に示すように、ファイルとハードリンクのパスチェックに違いはありません。プロセスは同じです。シンボリックリンクはどうですか?追加資料:
コンポーネントが見つかり、それがシンボリックリンクである場合は、まずシンボリックリンクを確認します(現在の検索ディレクトリを開始検索ディレクトリとして使用)。エラーが発生すると、このエラーが返されます。結果がディレクトリでない場合、ENOTDIRエラーが返されます。シンボリックリンクが正常にチェックされ、ディレクトリを返すと、現在のルックアップディレクトリをそのディレクトリに設定し、次のコンポーネントに移動します。パス名のプレフィックス( "dirname")コンポーネントにファイル名が含まれている場合、そのファイル名はディレクトリへのシンボリックリンクとして解決されます(ディレクトリのプレフィックスコンポーネントにシンボリックリンクを含めることができるため、ここで検証プロセスには再帰が含まれますすることができます)。存在する)。スタックオーバーフローからカーネルを保護し、サービス拒否を防ぐために、最大再帰深度と追従する最大シンボリックリンク数に制限があります。最大値を超えると、ELOOPエラー(「シンボリックリンクレベルが多すぎます」)が返されます。
上記のように、シンボリックリンクの確認には追加のディスクアクセス操作が必要なので、次の2つの質問に答えてください。
上記のファイルのinodeを指すハードリンク/ hLが与えられた場合、ディスクアクセス順序は何ですか?
そして
上記のファイルを指すソフトリンク/ sLが与えられた場合、ディスクアクセス順序は何ですか?
ハードリンクアクセスは通常のファイルアクセスと変わりませんが、シンボリックリンク解決には追加のディスクアクセス操作が必要であると結論付けることができます。シンボリックリンクの解決。
追加資料: