[ruby] rubyで unsahre(2) 呼び出して マウント名前空間を分離する

ruby で unshare(2) というシステムコールを呼び出してマウント名前空間を変えてみる小さいコード書きました。

unshareについては http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/unshare.2.html

コード

たぶん rubyあんま関係無い

# /usr/include/asm/unistd_64.h:#define __NR_unshare				272
# /usr/include/linux/sched.h:#define CLONE_NEWNS	0x00020000	/* New namespace group? */

fork {
 # syscall unshare(2)
  unshare     = 272
  clone_newns = 0x00020000
  Kernel.syscall(unshare, clone_newns)

  # 子プロセスが新しい名前空間で mount する
  system "mount --no-mtab -t proc proc /tmp"

  # procな内容が表示される
  system "ls -hal /tmp/"
  exit 0
  # マウントの名前空間が分離されているので、子プロセスが死ぬとマウントも外れる
}

# 親プロセスは 子プロセスの mount が見えない。
sleep 2
system "ls -hal /tmp"


親プロセス・子プロセスともに ls /tmp を呼び出していますが、出力が違う結果になります。

  • 親プロセス
合計 972K
drwxrwxrwt.  5 root   root   4.0K  5月 19 08:45 2012 .
dr-xr-xr-x. 27 root   root   4.0K  5月 17 08:21 2012 ..
drwxrwxrwt   2 root   root   4.0K  5月 17 08:21 2012 .ICE-unix

... 略
  • 子プロセス
dr-xr-xr-x  128 root      root         0  5月 17 08:20 2012 .
dr-xr-xr-x.  27 root      root      4.0K  5月 17 08:21 2012 ..
dr-xr-xr-x    7 root      root         0  5月 17 08:20 2012 1
dr-xr-xr-x    7 root      root         0  5月 17 08:20 2012 10
... 略

要点

  • 子プロセスの mount は親プロセスに影響を与えない
  • 子プロセスが終了すると自動でumountされる

使いどころがあんまりありませんが、一時的に mount / umount する必要がある作業 で役だつ... かな? 特異なケースですね。

( 名前空間の仕組み自体は LXCで使われまくってます )


その他

  • ヘッダの定数をハードコードしてるのが行儀悪いですね ... 配布して使うならちゃんと拡張書いたりするのがよいですね
  • シェルで扱うなら /usr/bin/unshare というコマンドもあります