UNIX / Linuxでディレクトリハードリンクが許可されていないのはなぜですか?

UNIX / Linuxでディレクトリハードリンクが許可されていないのはなぜですか?

私はUnix / Linuxがディレクトリへのハードリンクを許可しませんが、ソフトリンクを許可することを教科書で読みました。ループが発生したときにハードリンクを作成し、一定時間が経過した後に元のファイルを削除すると、いくつかのゴミの値を指すでしょうか?

ループがハードリンクが許可されない唯一の理由である場合、ディレクトリへのソフトリンクはなぜ許可されますか?

答え1

ハードリンクと元の名前を区別する方法がないので、これは単に悪い考えです。

ディレクトリへのハードリンクを許可すると、ファイルシステムの方向性非循環グラフ構造が破損し、潜在的にディレクトリループが生成され、fsck他のファイルツリーエクスプローラにエラーが発生しやすいディレクトリサブツリーがハングアップする可能性があります。

まず、これを理解するためにインデックスノードについて説明します。ファイルシステムのデータはディスクのブロックに保存され、inodeによって一緒に収集されます。 inodeをファイルと考えることができます。ただし、inodeにファイル名がありません。これがリンクが機能する場所です。

リンクは単にinodeへのポインタです。ディレクトリはリンクを保持するインデックスノードです。ディレクトリ内の各ファイル名は単にinodeへのリンクです。 Unixでファイルを開くとリンクも作成されますが、これは別の種類のリンクです(名前付きリンクではありません)。

ハードリンクは、対応する inode を指す追加のディレクトリエントリです。リンク数を指定する場合、ls -l権限の後の数字は次のとおりです。ほとんどの一般的なファイルにはリンクがあります。新しいファイルハードリンクを作成すると、両方のファイル名が同じinodeを指します。メモ:

% ls -l test
ls: test: No such file or directory
% touch test
% ls -l test
-rw-r--r--  1 danny  staff  0 Oct 13 17:58 test
% ln test test2
% ls -l test*
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test2
% touch test3
% ls -l test*
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test2
-rw-r--r--  1 danny  staff  0 Oct 13 17:59 test3
            ^
            ^ this is the link count

これで、ハードリンクのようなものがないことが確実にわかります。ハードリンクは一般名と同じです。上記の例testまたはでtest2元のファイルとは何ですか、ハードリンクとは何ですか?結局のところ、両方の名前が同じもの、同じinodeを指すので、(タイムスタンプを介して)実際にはわかりません。

% ls -li test*  
14445750 -rw-r--r--  2 danny  staff  0 Oct 13 17:58 test
14445750 -rw-r--r--  2 danny  staff  0 Oct 13 17:58 test2
14445892 -rw-r--r--  1 danny  staff  0 Oct 13 17:59 test3

この-iフラグは、ls行の先頭に inode 番号を表示します。とのinode番号testtest2同じですが、test3inode番号は異なります。

これでディレクトリを使用してこれを行うことができる場合は、ファイルシステムの異なるポイントにある2つの異なるディレクトリが同じエントリを指すことがあります。実際、サブディレクトリは親ディレクトリを指し、循環を作成できます。

このサイクルに注目する価値があるのはなぜですか?巡回中にループ中であることを検出する方法がないためです(巡回中にアノード番号は追跡されません)。duディスク使用量を理解するために、サブディレクトリへの再帰が必要なコマンドを作成すると想像してください。duループにいつ入るのかはどうすればわかりますか?duこの簡単なタスクを実行するには、エラーが発生しやすく、多くの帳簿が必要です。

シンボリックリンクは、多くのファイルシステムAPIが自動的に従う傾向がある特別な種類の「ファイル」であるため、まったく異なる獣です。シンボリックリンクは inode を直接指すのではなく、名前で指すので、存在しないターゲットを指すことができます。この概念はハードリンクには適していません。なぜなら、「ハードリンク」が存在するということは、ファイルが存在することを意味するからです。

duもしそうなら、シンボリックリンクは扱いやすくなりますが、ハードリンクは扱いやすくなるのはなぜですか?上から見ると、ハードリンクが通常のディレクトリエントリと変わらないことがわかります。しかし、シンボリックリンクは特別で検出可能でスキップできます!  duシンボリックリンクはシンボリックリンクなので、完全にスキップしてください!

% ls -l 
total 4
drwxr-xr-x  3 danny  staff  102 Oct 13 18:14 test1/
lrwxr-xr-x  1 danny  staff    5 Oct 13 18:13 test2@ -> test1
% du -ah
242M    ./test1/bigfile
242M    ./test1
4.0K    ./test2
242M    .

答え2

マウントポイントに加えて、すべてのディレクトリには1つの親ディレクトリがあります..

1つの方法はpwddevice:inodeに "。"そして「..」があることを確認することです。同じ場合は、ファイルシステムのルートに到達しました。それ以外の場合は、親ディレクトリで現在のディレクトリの名前を見つけてスタックにプッシュし、「../.」を最初に「../..」と比較し、次に「../../.」を比較し始めます。待つ。ルートが見つかったら、スタックを取り出し、名前の印刷を開始します。このアルゴリズムは、すべてのディレクトリに親ディレクトリが1つしかないという事実に依存します。

ディレクトリへのハードリンクが許可されている場合は、複数の親ディレクトリのいずれ..かを指す必要がありますか?これがディレクトリハードリンクを許可しない強力な理由です。

ディレクトリへのシンボリックリンクは問題を引き起こしません。プログラムが必要な場合は、lstat()パス名の各部分に対して操作を実行し、シンボリックリンクが見つかったタイミングを検出できます。このpwdアルゴリズムは、ターゲットディレクトリの実際の絶対パス名を返します。ターゲットディレクトリを指すテキスト(シンボルリンク)がどこかにあるという事実はほとんど関係ありません。このシンボリックリンクの存在はグラフに循環を生成しません。

答え3

この問題についていくつか追加したいと思います。ディレクトリへのハードリンクはLinuxでは許可されていますが、制限された方法で許可されています。

これをテストする1つの方法は、ディレクトリの内容を一覧表示するときに2つの特別なディレクトリ「.」を見つけることです。そして「..」。私たちが知っている限り、「.」は同じディレクトリを指し、「..」は親ディレクトリを指します。

したがって、「a」が親ディレクトリであり、ディレクトリ「b」が子ディレクトリであるディレクトリツリーを作成しましょう。

 a
 `-- b

ディレクトリ「a」のインデックスノードを確認してください。 「a」ディレクトリで操作を実行すると、「. ls -la」が表示されます。ディレクトリも同じinodeを指します。

797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 a

ここでは、「a」ディレクトリに3つのハードリンクがあることがわかります。これは、inode 797358に「.」という名前のハードリンクが3つあるためです。 「a」ディレクトリでは、名前は「..」です。 「b」ディレクトリでは、名前は「a」です。

$ ls -ali a/
797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 .

$ ls -ali a/b/
797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 ..

したがって、ここでは、ハードリンクがディレクトリを親ディレクトリとサブディレクトリにリンクするためにのみ使用されることがわかります。したがって、サブディレクトリがないディレクトリには2つのハードリンクしかないため、「b」ディレクトリには2つのハードリンクしかありません。

フリーディレクトリのハードリンクを防ぐ理由の1つは、ファイルシステムを巡回するプログラムを混乱させる可能性がある無限参照循環を防ぐことです。

ファイルシステムはツリーで構成されており、ツリーは循環参照を持つことができないため、これは避けるべきです。

答え4

ディレクトリへのハードリンク生成は回復できません。次のような結果があるとします。

/dir1
├──this.txt
├──directory
│  └──subfiles
└──etc

にハードリンクしました/dir2

これで、/dir2これらのファイルとディレクトリの両方が含まれます。

気が変わったらどうなりますか?私はできませんrmdir /dir2(空ではないから)

再帰的に削除すると/dir2…それも削除されます/dir1

IMHO、これがこれを避ける良い理由です!

編集する:

コメントでは、ディレクトリを操作してディレクトリを削除することを提案しますrm。ただし、rm空でないディレクトリでは失敗し、ディレクトリがハードリンクされているかどうかにかかわらず、この動作を維持する必要があります。したがって、接続を切断することはできませんrm。新しいパラメータを使用rmし、「inodeの参照数が1より大きい場合にのみディレクトリの接続を解除してください」と言います。

これは最終的にもう一つの最も驚くべき原則を破ります。つまり、作成したディレクトリハードリンクを削除することは、通常のファイルハードリンクを削除するのと同じではありません。

私の文章を再表現します。追加の開発がなければ、ハードリンク生成を元に戻すことはできません。 (現在のコマンドは現在の動作と一致せず、削除を処理できないためです。)

より多くの開発者がこのイベントを処理できるようにすると、トラップの数とデータ損失のリスクシステムがどのように機能するのか十分にわからない場合、このような開発はIMHO、これがディレクトリのハードリンクを制限する良い理由であることを意味します。

関連情報