mount --make-shared を始めとした mount --make-XXX なコマンドを試してみました。
なお、ほとんど下記の RHEL のドキュメントを参考・・というかそのまま試しています。
次の環境で試しています。
- CentOS 7.2.1511 / kernel 3.10.0-327.el7.x86_64
また、すべて最初に unshare -m してから試しています(いちいちマウント解除するのが面倒だったから)。ので、最後の方にも書いていますが、/ がデフォで shared にはなっていません。CentOS 7.2 だと普通は / がデフォで shared なので unshare -m せずに試すと異なる結果になります。
mount --bind
次のようにすると、/usr の中身が /mnt でも見えるようになります。
mount --bind /usr /mnt
例えば /usr/bin と /mnt/bin が同じ内容になります。
ls /usr/bin
ls /mnt/bin
マウント元とマウント先のファイルシステムが同じである必要はないので、次のようにファイルシステムの種類を超えてマウントすることも可能です。
mount --bind /proc/$$ /mnt
わたしは cifs でマウントしたディレクトリの中を部分的にローカルにするためによく使ってます。
mount --rbind
mount --bind はマウント元のディレクトリの中にマウントされているファイルシステムには適用されないため、例えば次のようにマウントしても /mnt/proc/ の中になにもありません。
mount --bind / /mnt
ll /mnt/proc/
# total 0
mount --rbind を使えばマウント元のディレクトリの中にマウントされているファイルシステムもマウント先に適用されます。
mount --rbind / /mnt
ll /mnt/proc/
# total 0
# dr-xr-xr-x. 9 root root 0 May 7 03:44 1
# :
ちなみにこのマウントを解除するためには -R を指定して再帰的に解除する必要があります。
umount -R /mnt
mount --make-shared
mount --make-shared でマウントポイントを共有マウントポイントにできます。
例えば、次のように /media を /mnt にマウントしたとします。
mount --bind /media /mnt
この後 /media の中に何かをマウントしたとしても /mnt には反映されません(後述の通り unshare -m しているためです、unshare -m していなければ、デフォで / は共有マウントポイントになっています)。
mkdir -p /media/foo
mount -t tmpfs tmpfs /media/foo
touch /media/foo/test
ll /media/foo/
# total 0
# -rw-r--r--. 1 root root 0 May 7 02:57 test
ll /mnt/foo/
# total 0
しかし、次のように /media を共有マウントポイントにして、
mount --bind /media /media
mount --make-shared /media
/media を /mnt にマウントすると、
mount --bind /media /mnt
/media と /mnt でマウント情報が共有されるようになります。
mkdir -p /media/foo
mount -t tmpfs tmpfs /media/foo
touch /media/foo/test
ll /media/foo/
# total 0
# -rw-r--r--. 1 root root 0 May 7 03:01 test
ll /mnt/foo/
# total 0
# -rw-r--r--. 1 root root 0 May 7 03:01 test
また、逆に /mnt の中にマウントしたファイルシステムも、/media から見ることができます。
mkdir -p /mnt/bar
mount -t tmpfs tmpfs /mnt/bar
touch /mnt/bar/test
ll /mnt/bar
# total 0
# -rw-r--r--. 1 root root 0 May 7 03:03 test
ll /media/bar
# total 0
# -rw-r--r--. 1 root root 0 May 7 03:03 test
mount --make-slave
共有マウントポイントをマウントしたとき、前述の通り、マウント元(/media)で行われたマウントも、マウント先(/mnt)で行われたマウントも両方とも共有されますが、マウント先で mount --make-slave すれば、マウント先で行われたマウントはマウント元に反映されないようにすることができます。
先ほどと同じように /media を共有マウントポイントにします。
mount --bind /media /media
mount --make-shared /media
/media を /mnt にマウントします。
mount --bind /media /mnt
このままだと /mnt の中にマウントしたファイルシステムが /media にも見えます。
次のようにマウント先のマウントポイントを mount --make-slave でスレーブマウントポイントにします。
mount --make-slave /mnt
すると、/media の中にマウントしたファイルシステムは /mnt にも反映されますが、その逆は反映されなくなります。
mkdir -p /media/foo
mkdir -p /mnt/bar
mount -t tmpfs tmpfs /media/foo
mount -t tmpfs tmpfs /mnt/bar
touch /media/foo/test
touch /mnt/bar/test
ll /media/foo/
# total 0
# -rw-r--r--. 1 root root 0 May 7 03:11 test
ll /mnt/foo/
# total 0
# -rw-r--r--. 1 root root 0 May 7 03:11 test
ll /mnt/bar
# total 0
# -rw-r--r--. 1 root root 0 May 7 03:12 test
ll /media/bar
# total 0
mount --make-private
mount --make-private でマウントポイントをプライベートにすることができます。
これがデフォルトです。なので mount --make-shared の説明で示した最初の例がプライベートなマウントポイントの動作です。つまり /media の中に作成したマウントポイントが /mnt の中に反映されることはありませんし、その逆もありません(と思ってたんですが、unshare -m していない場合は / がデフォで shared になっています)。
既に shared となっているマウントポイントをマウントしたときに、マウント先で private に設定することもできます。
例えば先ほどと同じように /media を共有マウントポイントにして /mnt にマウントして、
mount --bind /media /media
mount --make-shared /media
mount --bind /media /mnt
次のようにマウント先を private にします。
mount --make-private /mnt
すると、/media の中のマウントも /mnt の中のマウントも反映されなくなります。
mkdir -p /media/foo
mkdir -p /mnt/bar
mount -t tmpfs tmpfs /media/foo
mount -t tmpfs tmpfs /mnt/bar
touch /media/foo/test
touch /mnt/bar/test
ll /media/foo/
# total 0
# -rw-r--r--. 1 root root 0 May 7 03:18 test
ll /mnt/foo/
# total 0
ll /mnt/bar
# total 0
# -rw-r--r--. 1 root root 0 May 7 03:19 test
ll /media/bar
# total 0
mount --make-unbindable
mount --make-unbindable で、そのマウントポイントをバインド不可にすることができます。
例えば次のようにすると / やその中のディレクトリが mount --bind できなくなります。
mount --make-unbindable /
mount --bind / /mnt
# mount: wrong fs type, bad option, bad superblock on /,
# missing codepage or helper program, or other error
mount --bind /media /mnt
# mount: wrong fs type, bad option, bad superblock on /media,
# missing codepage or helper program, or other error
mount --make-rshared|--make-rslave|--make-rprivate|--make-runbindable
mount --make-XXX はいずれも再帰的な効果はないため、例えば次のように / をバインド不可にしても、
mount --make-unbindable /
/proc のように別のマウントポイントには影響しません。
mount --bind /proc /mnt
ll /proc
# total 0
# dr-xr-xr-x. 9 root root 0 May 7 02:33 1
:
次のように r を付けると再帰的に適用されるため、/proc もバインド不可になります。
mount --make-runbindable /
mount --bind /proc /mnt
# mount: wrong fs type, bad option, bad superblock on /proc,
# missing codepage or helper program, or other error
同様に shared/slave/private も再帰的に適用することができます。
mount --make-rshared /mnt
mount --make-rslave /mnt
mount --make-rprivate /mnt
unshare -m と mount --make-private
下記の記事のようにディストリビューションによっては / がデフォで shared になっているらしく、unshare -m の後で mount --make-private しないとマウントが分離されないそうです。
うーん、ただ CentOS 7.2.1511 / kernel 3.10.0-327.el7.x86_64 で試している感じ mount --make-private しなくても大丈夫そうですけれども・・?
確かに unshare -m する前だとデフォで shared になっているんですが、unshare -m すると shared が落ちるようです。
cat /proc/$$/mountinfo | fgrep ' / / '
# 58 1 253:0 / / rw,relatime shared:1 - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota
unshare -m /bin/bash
cat /proc/$$/mountinfo | fgrep ' / / '
# 82 81 253:0 / / rw,relatime - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota
下記などを見た感じ、
- http://unix.stackexchange.com/questions/246312/why-is-my-bind-mount-visible-outside-its-mount-namespace
- https://bugzilla.redhat.com/show_bug.cgi?id=1209594
- https://rhn.redhat.com/errata/RHBA-2015-2093.html
これは、systemd でかつ util-linux < 2.27 の場合の問題で、util-linux >= 2.27 だと unshare -m で shared が伝播しないようになっており、RHEL/CentOS 7.2 にはそれがバックポートされているようです。
ので、RHEL/CentOS 7.2 なら mount --make-private は要らないっぽいです。