web-dev-qa-db-ja.com

コンテンツを含む既存のフォルダーを「マウントオーバー」するとどうなりますか?

現在/tmpには一時ファイルがいくつか含まれています。ハードドライブ(/dev/sdc1)を/tmpの上にマウントすると、ハードドライブ上のファイルが表示されます。ハードドライブをマウントすると、/tmpの実際の内容はどうなりますか?ハードドライブがマウントされているときに/tmpの実際のコンテンツに対してr/w操作を実行できますか?

python@lanix / $ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       286G   43G  229G  16% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            3.8G  4.0K  3.8G   1% /dev
tmpfs           766M  1.4M  765M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            3.8G   38M  3.8G   1% /run/shm
none            100M   24K  100M   1% /run/user
/dev/sdb1       7.5G  2.7G  4.9G  35% /mnt
/dev/sdc1       932G  242G  691G  26% /tmp
91
user

ハードドライブをマウントすると、/ tmpの実際の内容はどうなりますか?

ほとんど何もない。それらは表示されないだけで、通常のファイルシステムトラバーサルでは到達できません。

ハードドライブがマウントされている間に/ tmpの実際のコンテンツに対してr/w操作を実行することは可能ですか?

はい。 「元の」/tmp内で開いているファイルハンドルがあったプロセスは、引き続きそれらを使用できます。別の場所に/をバインドマウントすることで、別の場所に「再出現」させることもできます。

# mount -o bind / /somewhere/else
# ls /somewhere/else/tmp  

これは、起こっていることをよりよく(私は願って)感じるために実行できる小さな実験です。

注:これは、完全に正しいことを試みたり、実際に起こっていることを網羅的に説明したりするものではありません。ただし、全体像がわかる程度に正確である必要があります。

私は自分のマシンにmeというユーザーを作成し、彼の家にランダムなディレクトリを作成しました。

me@home $ pwd
/home/me/tmp
me@home $ echo hello > some_file
me@home $ ls  
some_file
me@home $ cat some_file 
hello

この時点で、異常なことは何もありません。これは、プレーンファイルを含むプレーンディレクトリです。私はそのセッションをそのまま開いたままにし、そのcwdをテストディレクトリ内に残します。

ルートとして、小さなファイルシステムを作成し、/home/me/tmpにマウントします。

root@home # dd if=/dev/zero of=./fs bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00467318 s, 2.2 GB/s

root@home # mkfs -t ext2 ./fs 
mke2fs 1.42.12 (29-Aug-2014)
[... snip ...]
Writing superblocks and filesystem accounting information: done

root@home # mount ./fs /home/me/tmp

次に、meとして新しいターミナルを開き、周りを見回します。

me@home #2 $ cd tmp
me@home #2 $ ls
lost+found
me@home #2 $ cat some_file
cat: some_file: No such file or directory
me@home #2 $ echo bye bye > some_file
-su: some_file: Permission denied

したがって、作成したファイルは明らかに存在しません。 lost+foundディレクトリは、extファイルシステムのルートを示します。そして、書き込み権限を失ったので、それは明らかに元のディレクトリではありません。

最初のmeセッションに戻り、世界がどのように見えるかを見てみましょう。

me@home $ echo something else > other_file

書き込み問題ありません。

me@home $ cat some_file other_file 
hello
something else

元のファイルはそのまま残り、新しいファイルは問題なく作成されました。

えっ?どうしたの?

最初のセッションは、別のファイルシステムをルートマウントするルートによってオーバーレイされる前にディレクトリに入りました。このマウントアクションは、元のファイルシステムにはまったく影響しません。シェルプロセスは、元のファイルシステムのディレクトリへの完全に有効なハンドルを持ち、それとの対話を続行できます。 beneathの周りを走るようなものです カーペット マウントポイント。

マウントが設定された後、2番目のセッションがディレクトリに入りました。そのため、新しい空のファイルシステムが表示されます。そして、システム管理者が権限を無効にしたため、要求されたスペースを使用できません...修正しましょう。

root@home # chown me:users /home/me/tmp
me@home #2 $ echo bye bye > some_file
me@home #2 $ ls 
lost+found  some_file
me@home #2 $ cat some_file 
bye bye

セッション1は敷物の下から脱出できますか? (かび臭くなっています。)

承知しました!セッション1がファイルシステムツリーを上に移動してマウントから外れると、内部へのハンドルが失われ、他の人と同じようにマウントに従います。

me@home $ cd
me@home $ pwd
/home/me
me@home $ cd tmp
me@home $ cat some_file other_file
bye bye
cat: other_file: No such file or directory

セッション2と同じビュー。通常に戻ります。

しかし、ファイルが消えていないことをどのようにして知っていますか?もう誰も見ていません!

これは、バインドマウントが便利になる瞬間の1つです。すでにマウントされているファイルシステムを別の場所にマウントできます。

me@home $ mkdir ~/bind
root@home # mount -o bind /home/me /home/me/bind

(はい、ファイルシステムを「それ自体の内部」にバインドマウントできます。クールなトリックですね。)

me@home $ ls bind/tmp
other_file  some_file
me@home $ cat bind/tmp/*
something else
hello

だから彼らは確かにそこにいて、行動の準備ができています。それは単にそれらが元の場所で見えない/到達できないということです、マウントはそれらを通常のディレクトリトラバーサルから隠します。


これをいじってみることをお勧めします。再生されている「トリック」を理解すれば、それほど複雑ではありません。そして、いったんGot It™を実行したら、ユニオンファイルシステムを調べて、カーペットをさらに引っ張ってください:-)

ただし、ブートプロセスが完了した後は、/tmpまたは/var(またはコアOSディレクトリのいずれか)をマウントすることは、実際にはお勧めできません。多くのアプリケーションはこれらのディレクトリに状態を残し、それらの周りでマウントゲームをプレイすると深刻な混乱を招く可能性があります。

132
Mat