TenForward

技術ブログ。はてなダイアリーから移転しました

マウントプロパゲーション(6)〜 mountinfoファイル(2)〜

これまでの続きです。

これまでと同様に完全に私個人が理解するための資料です。間違いの指摘は大歓迎です。

前回書ききれなかった /proc/[PID]/mountinfo ファイルのエントリーのお話です。

unbindableの場合

unbindableを指定した場合は次のようなエントリになります。

369 31 252:2 /root/test/test/orig /root/test/test/bind rw,relatime unbindable - ext4 /dev/vda2 rw

propagate_fromの場合

propagete_fromはslaveマウントなのですが、slaveとなっているマウントからmasterが見えないときに表示されます。これは、例えばchrootしたあと、masterとなるマウントがroot範囲外となった場合などに起こります。

f:id:defiant:20200703221733p:plain
図1 slaveが連鎖している様子

図1のように、②を③にバインドマウントし、③を④にバインドマウントし、②は③のmaster、③は④のmasterとなっているとします(③のようにmasterかつslaveという設定ができます)。

このようにslaveが連鎖した状態で①の/mntchrootすると、④からmasterである③は見えません。③は②のslaveであり、④から②は見えますので、④のエントリにはpropagate_from:②のように書かれます。実際は②はマウントポイントではないので、IDとしては①のIDが書かれます。

文章にするとわかりづらいですね。実際に試してみましょう(実際に試してもわかりづらいですが…)。

まずは後の操作の準備を行います。ここでは次のような操作を行います。

  1. //mntにバインドマウントする
  2. /proc/mnt/procにバインドマウントする
  3. /mntを一度privateにする。これは/mntはsharedにしたいのですが、他と共有を行わない独立したsharedとするためです
  4. /mntをsharedにする

これで/mntは独自のIDを持つsharedマウントとなります。

# mount --bind / /mnt          ... (1)
# mount --bind /proc /mnt/proc ... (2)
# mount --make-private /mnt    ... (3)
# mount --make-shared /mnt     ... (4)
# cat /proc/self/mountinfo | grep "/mnt"
231 25 8:1 / /mnt rw,relatime shared:124 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
238 231 0:4 / /mnt/proc rw,nosuid,nodev,noexec,relatime shared:13 - proc proc rw

ここでmountinfoファイルを確認すると上のようになります。ここで/mntに割り当たっているIDは124となっていますが、これは他とマウントは共有していないマウントです。

次にひとつめのslaveマウントを作成します。図1の②を③にバインドマウントします。

# mkdir /mnt2/etc
# mount --bind /mnt/etc /mnt2/etc
# cat /proc/self/mountinfo | grep "/mnt"
231 25 8:1 / /mnt rw,relatime shared:124 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
238 231 0:4 / /mnt/proc rw,nosuid,nodev,noexec,relatime shared:13 - proc proc rw
252 25 8:1 /etc /mnt2/etc rw,relatime shared:124 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered

これだけでは上のように③(/mnt2/etc)は②(/mnt/etc、つまりは①の/mnt)とマウントを共有するsharedマウントになっていますので、slaveに設定した上で、あとで行うバインドマウントのためにsharedにも設定します。

  1. ③(`/mnt2/etc')をslaveに設定する
  2. ③をsharedに設定する
# mount --make-slave /mnt2/etc  ... (1)
# mount --make-shared /mnt2/etc ... (2)
# cat /proc/self/mountinfo | grep "/mnt"
231 25 8:1 / /mnt rw,relatime shared:124 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
238 231 0:4 / /mnt/proc rw,nosuid,nodev,noexec,relatime shared:13 - proc proc rw
252 25 8:1 /etc /mnt2/etc rw,relatime shared:131 master:124 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered

mountinfoを確認すると③(/mnt2/etc)は独自のID(131)を持つshared、かつ①のマウント(②のマウントポイント)を参照するslaveとなっています(masterが①のIDである124)。

さらに次のslaveマウントを行います。

  1. ③(/mnt2/etc)を④(/mnt/tmp/etc)にバインドマウントする
  2. ④(/mnt/tmp/etc)をslaveに設定する
# mkdir /mnt/tmp/etc
# mount --bind /mnt2/etc /mnt/tmp/etc ... (1)
# mount --make-slave /mnt/tmp/etc     ... (2)
# cat /proc/self/mountinfo | grep "/mnt"
231 25 8:1 / /mnt rw,relatime shared:124 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
238 231 0:4 / /mnt/proc rw,nosuid,nodev,noexec,relatime shared:13 - proc proc rw
252 25 8:1 /etc /mnt2/etc rw,relatime shared:131 master:124 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
265 231 8:1 /etc /mnt/tmp/etc rw,relatime master:131 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered

mountinfoを確認すると④(/mnt/tmp/etc)は③(/mnt/etc)をmasterとするslaveになっていることがわかります。

これで図1の状態になりましたので、①(/mnt)にchrootしてみましょう。

# chroot /mnt
# cat /proc/self/mountinfo
231 25 8:1 / / rw,relatime shared:124 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
238 231 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:13 - proc proc rw
265 231 8:1 /etc /tmp/etc rw,relatime master:131 propagate_from:124 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered

③(/mnt2/etc)が④(/mnt/tmp/etc)から見えなくなりましたので、④のエントリーには②(つまりは①)のIDである124がpropagate_fromとして表示されています。