同じファイルシステムの「mount --bind」ディレクトリからファイルへの「ハードリンク」を作成できないのはなぜですか?


9

元の問題

1つのファイルシステムにファイルがあります。 /data/src/file

そして私はそれをハードリンクしたいと思います: /home/user/proj/src/file

しかし/home、1つのディスク上にあり/data、別のディスク上にあるため、エラーが発生します。

$ cd /home/user/proj/src
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

さて、デバイス間でハードリンクできないことを学びました。理にかなっています。

手元の問題

だから私は空想を得て、のファイルシステムsrc上にあるフォルダーをバインドマウントすると思いました/data

$ mkdir -p /data/other/src
$ cd /home/user/proj
$ sudo mount --bind /data/other/src src/
$ cd src
$ # (now we're technically on `/data`'s file system, right?)
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

なぜこれがまだ機能しないのですか?

回避策

/dataバインドされたディレクトリではなく「実際の」ディレクトリにいる限り、ハードリンクを作成できるので、私はこの設定が正しいことを知っています。

$ cd /data/other/src
$ ln /data/src/file .
$ # OK
$ cd /home/user/proj/src
$ ls -lh
total 35M
-rw------- 2 user user 35M Jul 17 22:22 file

$

一部のシステム情報

$ uname -a
Linux <host> 4.10.0-24-generic #28-Ubuntu SMP Wed Jun 14 08:14:34 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ findmnt
.
.
.
├─/home                               /dev/sdb8   ext4       rw,relatime,data=ordered
│ └─/home/usr/proj/src             /dev/sda2[/other/src]
│                                                 ext4       rw,relatime,data=ordered
└─/data                               /dev/sda2   ext4       rw,relatime,data=ordered

$ mountpoint -d /data
8:2

$ mountpoint -d /home/usr/proj/src/
8:2

:状況をわかりやすくするためにファイルとディレクトリの名前を手動で変更したため、コマンドの読み取りにタイプミスがある場合があります。


2
フォルダをどこにマウントしてもかまいません。それらは異なるパーティションで物理的です。各パーティションには独自のファイルテーブルがあり、ハードリンクはこのテーブルに記録されます。
user996142 2017

2
ここでのポイントは、ファイルが物理的に異なるパーティション上にないことです。同じパーティションの同じファイルシステムです。違いはバインドマウントです。
roaima

バインドマウントは単なるフィクションです。ディスク上のデータ構造は変更されません。ファイルシステムはまだ物理的に分離されています。
Bob Eager 2017

しかし、ハードリンクを作成すると/data、バインドマウントディレクトリからiノードにアクセスできるので、バインドマウントはと同じパーティション上にある必要があります/data。または、ハードリンクがデバイス間で機能していて、これは違法ですが、とにかく機能します。何が欠けていますか?
jdk1.0 2017

回答:


6

コードにコメントが欠けているのは残念です。時間バインドマウントがv2.4で実装されたので、誰もそれを便利だと思ったことはありません。きっとあなたがしなければならないすべて.mnt->mnt_sbはそれが言うところの代わり.mntです...

それは、サブツリーの周りにセキュリティ境界を与えるからです。

PS:それはかなり何度も議論されていましたが、検索を避けるために:例えばmount --bind / tmp / tmpを検討してください; これで、/ tmpに書き込み可能であっても、ユーザーがroot fsがない他の場所へのリンクを作成できない状況が発生しました。同様の技術は他の分離のニーズでも機能します-基本的に、名前の変更/リンクを特定のサブツリーに限定できます。IOW、それは意図的な機能です。ツリーの束をchrootにバインドして、メインツリーで1年後などに再配置する方法に関係なく、予測可能な制限を取得できることに注意してください。

- アルヴィーロ

スレッドの下の方に具体的な例があります

mount -r --bindが適切に機能するようになると(ページキャッシュの共有を許可しながら、必要な共有ライブラリのコピーをchroot jail内に配置するために使用します)、この機能はセキュリティを破壊します。

mkdir /usr/lib/libs.jail
for i in $LIST_OF_LIBRARIES; do
ln /usr/lib/$i /usr/lib/libs.jail/$i
done
mount -r /usr/lib/libs.jail /jail/lib
chown prisoner /usr/log/jail
mount /usr/log/jail /jail/usr/log
chrootuid /jail prisoner /bin/untrusted &

保護は十分ですが、囚人が/jail/lib/libfoo.so(書き込みはEROFSを返す)を/ jail / usr / logにリンクして、書き込み可能な場所に置くことは避けたいと思います。


-1

クロスデバイスリンクを実行できない理由は、あいまいさを導入するためです。ファイルのディレクトリエントリには、(単純なシステムでは)関連するファイルのiノード番号が含まれます。ハードリンク(別のディレクトリエントリのみ)にも同じiノード番号を含める必要があります。これは問題ありませんが、iノード番号は単一のファイルシステム内でのみ一意です(通常、1から始まる高密度のセットです)。

バインドマウントはその問題を修正しません。はい、それは構造の一種の「フィクション」を構成しますが、1つのファイルシステム上のすべてのiノードに番号を付け直して、関係する両方のファイルシステム全体で一意であることを確認します!それはばかげたことでしょう。

この制限は、UNIXシステムでは常に存在していました。シンボリックリンクは、これを解決するために部分的に発明されました。機能的にまったく同じではないことは知っていますが、通常は問題ありません。

シンボリックリンクを試しますか?(ln -s


ここでは、iノードの再番号付けの名前はありません。2つのビューを持つ、基礎となるファイルシステムは1つだけです。
Gilles「SO-邪悪なことをやめよう」

シンボリックリンクが欲しくない理由の1つは、パスが長く、を実行するのが面倒だったためls -lです。最初はちょっとばかげた推論ですが、それからうさぎの穴につながり、ハードリンクで何が起こっているのかについて
知りました

@ギレス、それは私が言っていたものです。私が言っていたのは、iノードの再番号付けがばかげているということです。なぜ正解が反対票を投じられたかはわかりません。
Bob Eager 2017

あなたは正しい結論を出しますが、あなたの説明は非常に多くの場所で間違っており、あなたの答えは全体として非常に誤解を招きます。良い説明はsourcejediの答えを見てください。
Gilles「SO-邪悪なことをやめよう」

エラーはまったくありませんが、はっきりしているはずです。
Bob Eager 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.