{	
第  1  回    
コンテナ情報交換会  
@東京
Kernel/LXC/OpenVZ/Virtuozzo/Linux-­‐‑Vserver/etc	
                 2013年10月5日
Ñ  自己紹介
Ñ   36歳(昭和51年(1976年)12月生まれ)
Ñ   古き良きインフラエンジニアです
Ñ   ジブリをこよなく愛してます
Ñ   Kernelを弄るのが好きです
Ñ   最近テレフォニー/UCの分野に目覚めました
山本  政秀  /  QLOOG  
  @masahide7
2
Ñ  Docker	
	
Ñ  お手軽な実行環境の構築手法	
	
Ñ  面白いデバッグ手法  -­‐‑  hot-­‐‑patching	
アジェンダ
3
hKps://github.com/dotcloud/docker/
早速ですが、dockerって知ってますか?
4
Docker  containers  are  both  hardware-­‐‑agnostic  and  platform-­‐‑agnostic.  This  means  that  they  can  run  
anywhere,  from  your  laptop  to  the  largest  EC2  compute  instance  and  everything  in  between  -­‐‑  and  they  don'ʹt  
require  that  you  use  a  particular  language,  framework  or  packaging  system.  That  makes  them  great  building  
blocks  for  deploying  and  scaling  web  apps,  databases  and  backend  services  without  depending  on  a  
particular  stack  or  provider.
5
Ñ  デモ環境	
	
[root@lxcbase-­‐‑local  dockerwk]#  go  version	
go  version  go1.1  linux/amd64	
	
[root@lxcbase-­‐‑local  dockerwk]#  docker  version	
Version:  0.3.4	
Git  Commit:  1c09165+CHANGES	
	
[root@lxcbase-­‐‑local  dockerwk]#  uname  -­‐‑a	
Linux  lxcbase-­‐‑local.qloog.ne.jp  3.9.4-­‐‑QLOOG  #2  SMP  PREEMPT  Sat  Jun  
1  02:59:16  JST  2013  x86_64  x86_64  x86_64  GNU/Linux	
	
[root@lxcbase-­‐‑local  dockerwk]#  ls                          	
./      aufs-­‐‑aufs-­‐‑util/                  docker/    go1.1.linux-­‐‑amd64.tar.gz    
libarchive-­‐‑3.1.2.tar.gz    util-­‐‑linux-­‐‑2.23.1.tar.xz	
../    aufs-­‐‑aufs3-­‐‑standalone/    go/            libarchive-­‐‑3.1.2/                  util-­‐‑linux-­‐‑2.23.1/	
dockerのデモ  
6
Ñ  デーモン起動	
[root@lxcbase-­‐‑local  docker]#  docker  -­‐‑d  -­‐‑b  lxcbr1  >/var/log/docker.log  2>&1  &	
	
Ñ  イメージの検索とインストール(busybox)	
[root@lxcbase-­‐‑local  docker]#  docker  search  busy	
2013/05/31  23:23:31  GET  /v1.1/images/search?term=busy	
Found  8  results  matching  your  query  ("ʺbusy"ʺ)	
NAME                                    DESCRIPTION	
test422/busybox              	
shykes/busybox                	
lopter/busybox                	
kencochrane/busybox      	
busybox                              	
vieux/busybox                  	
vieux/busybox.test        	
vieux/busyboxreadme  	
	
[root@lxcbase-­‐‑local  /]#  docker  pull  busybox	
2013/06/01  03:03:38  POST  /v1.1/images/create?fromImage=busybox&registry=&tag=	
Pulling  repository  busybox  from  hKps://index.docker.io/v1	
Pulling  image  e9aa60c60128cad1  (latest)  from  busybox	
7
Ñ  イメージ上でコンテナプロセスを生成(これだけ!)	
[root@lxcbase-­‐‑local  ~]#  docker  run  -­‐‑i  -­‐‑t  busybox  /bin/sh	
	
BusyBox  v1.19.3  (Ubuntu  1:1.19.3-­‐‑7ubuntu1.1)  built-­‐‑in  shell  (ash)	
Enter  'ʹhelp'ʹ  for  a  list  of  built-­‐‑in  commands.	
	
/  #  uname  -­‐‑a	
Linux  9526b79d150a  3.9.4-­‐‑QLOOG  #2  SMP  PREEMPT  Sat  Jun  1  02:59:16  JST  2013  
x86_64  GNU/Linux	
/  #  ip  a	
1:  lo:  <LOOPBACK,UP,LOWER_UP>  mtu  65536  qdisc  noqueue  	
        link/loopback  00:00:00:00:00:00  brd  00:00:00:00:00:00	
        inet  127.0.0.1/8  scope  host  lo	
              valid_lft  forever  preferred_lft  forever	
        inet6  ::1/128  scope  host  	
              valid_lft  forever  preferred_lft  forever	
45:  eth0:  <BROADCAST,MULTICAST,UP,LOWER_UP>  mtu  1500  qdisc  pfifo_fast  qlen  
1000	
        link/ether  be:6d:92:19:da:5e  brd  ff:ff:ff:ff:ff:ff	
        inet  10.20.30.12/24  brd  10.20.30.255  scope  global  eth0	
              valid_lft  forever  preferred_lft  forever	
        inet6  fe80::bc6d:92ff:fe19:da5e/64  scope  link  	
              valid_lft  forever  preferred_lft  forever	
	
8
Ñ  続き	
/  #  while  :;  do  sleep  1;  echo  test;  done	
test	
test	
test	
test	
	
Ñ  先ほどコンテナを起動したコマンドのプロセスを強制終了	
[root@lxcbase-­‐‑local  /]#  pgrep  -­‐‑lf  busybox	
7540  docker  run  -­‐‑i  -­‐‑t  busybox  /bin/sh	
	
[root@lxcbase-­‐‑local  /]#  kill  -­‐‑9  7540	
	
Ñ  コンテナプロセスの一覧の表示(まだ裏で動いている)	
[root@lxcbase-­‐‑local  /]#  docker  ps	
ID                                    IMAGE                              COMMAND                          CREATED                          STATUS                            PORTS	
9526b79d150a                busybox:latest            /bin/sh                          7  minutes  ago              Up  7  minutes    	
	
Ñ  そのコンテナにアタッチ            	
[root@lxcbase-­‐‑local  /]#  docker  aKach  9526b79d150a	
test	
test	
test	
test	
^C	
/  #	
9
Ñ  busyboxじゃなくもう少しちゃんとした環境を入れてみる(ubuntuイメージ)	
[root@lxcbase-­‐‑local  /]#  docker  pull  ubuntu	
Pulling  repository  ubuntu  from  hKps://index.docker.io/v1	
Pulling  image  27cf784147099545  ()  from  ubuntu	
Pulling  27cf784147099545  metadata	
Pulling  27cf784147099545  fs  layer	
Downloading  94863360/?  (n/a)	
Pulling  image  
8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c  (precise)  
from  ubuntu	
Pulling  8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c  
metadata	
Pulling  8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c  fs  
layer	
Downloading  58337280/?  (n/a)	
Pulling  image  b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc  
(quantal)  from  ubuntu	
Pulling  b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc  
metadata	
Pulling  b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc  fs  
layer	
Downloading  10240/?  (n/a)	
[root@lxcbase-­‐‑local  /]#  	
10
Ñ  ubuntuイメージでコンテナつくってsh起動(またまたこれだけ!)	
[root@lxcbase-­‐‑local  ~]#  docker  run  -­‐‑i  -­‐‑t  ubuntu  /bin/sh	
	
Ñ  コンテナの中で諸情報を出してみる	
#  ip  a  s  dev  eth0	
49:  eth0:  <BROADCAST,MULTICAST,UP,LOWER_UP>  mtu  1500  qdisc  pfifo_fast  
state  UP  qlen  1000	
        link/ether  ea:5b:3b:45:d8:d5  brd  ff:ff:ff:ff:ff:ff	
        inet  10.20.30.14/24  brd  10.20.30.255  scope  global  eth0	
              valid_lft  forever  preferred_lft  forever	
        inet6  fe80::e85b:3bff:fe45:d8d5/64  scope  link  	
              valid_lft  forever  preferred_lft  forever	
#  uname  -­‐‑a	
Linux  133fc6d7edbf  3.9.4-­‐‑QLOOG  #2  SMP  PREEMPT  Sat  Jun  1  02:59:16  JST  2013  
x86_64  x86_64  x86_64  GNU/Linux	
#  df  -­‐‑hP	
df:  cannot  read  table  of  mounted  file  systems:  No  such  file  or  directory	
#  ps  axufw	
USER              PID  %CPU  %MEM        VSZ      RSS  TTY            STAT  START      TIME  COMMAND	
root                  1    0.0    0.0      4392      612  ?                S        18:47      0:00  /bin/sh	
root                15    0.0    0.0    15268    1076  ?                R+      18:48      0:00  ps  axufw	
11
Ñ  コマンド一発で全部やってくれる爽快感	
Ñ  ホスト上で自由自在に諸々悩まずに環境を構成できる(依存関係の問題
等)	
Ñ  Gitに似た考え方で変更点をリポジトリで追跡管理でき、作成したイメー
ジはdotcloudのリポジトリで公開できる(hKps://index.docker.io/v1/)	
Ñ  ブートにまつわる諸問題から解放される(systemdやUpstart等意識しなく
て良い、そもそもブートと言う考え方自体が不要になる。別名前空間での
フォークと言った方が良いかも)	
	
Ñ  LXCの非常に小さなオーバヘッドの恩恵を効果的に享受できる	
	
Ñ  ドキュメントは hKp://docs.docker.io/en/latest/ 	
Ñ  Vagrantについて一言	
    hKp://docs.docker.io/en/latest/installation/vagrant/	
#  git  clone  hKps://github.com/dotcloud/docker.git	
#  cd  docker	
#  vagrant  up	
dockerのまとめ
12
Ñ  ちょっと変わった実行環境の構築手法  
楽しんだ所で次の話題
13
Ñ  特定のバージョンのphpを全く別の環境に
もっていってそのまま利用する手法のデモ	
PHP  5.3.3  (cgi-­‐‑fcgi)  x86_64を	
32bit(i686)のdockerコンテナへ持って行く!  	
実行環境構築デモ  
14
Ñ  KernelがIA32エミュ有効
(CONFIG_IA32_EMULATION=y)なx86_64ならbit  width
に関係なくコンテナ間でバイナリを自由に使い回せる	
	
Ñ  よって、ポータブル版を一つ作れば、環境毎に動的言語の
処理系の様なバイナリやライブラリ一式を再構築しなくて
済む	
	
Ñ  コンテナの利便性の中でポータビリティの部分に焦点を当
てた考え方	
実行環境構築のまとめ
15
Ñ  Kernelの面白いデバッグ手法	
Ñ   hot-­‐‑patching/kernel  function  hijacking  
最後の話題
16
Ñ  有名どころでksplice(hKp://www.ksplice.com/)	
 (オラクルに買収された)	
	
Ñ  reboot無しのセキュリティパッチ	
Ñ  Kernel関数の挿げ替えw	
	
	
hot-­‐‑patchingとは?
17
Ñ  とりあえず関数「pid_revalidate」を挿げ替え
てみる。	
Ñ  ※これは、/proc/[pid]がstatされる時に必ず呼
ばれる(例えばpsやtopを打ったときプロセス
毎に呼ばれる)のでプロセスのtask_struct構造
体とそこから連結されている様々なデータ構造
をデバッグするのにちょうど良い
早速デモ!
18
1576  /*	
1577    *            Exceptional  case:  normally  we  are  not  allowed  to  unhash  a  busy	
1578    *  directory.  In  this  case,  however,  we  can  do  it  -­‐‑  no  aliasing  problems	
1579    *  due  to  the  way  we  treat  inodes.	
1580    *	
1581    *  Rewrite  the  inode'ʹs  ownerships  here  because  the  owning  task  may  
have	
1582    *  performed  a  setuid(),  etc.	
1583    *	
1584    *  Before  the  /proc/pid/status  file  was  created  the  only  way  to  read	
1585    *  the  effective  uid  of  a  /process  was  to  stat  /proc/pid.    Reading	
1586    *  /proc/pid/status  is  slow  enough  that  procps  and  other  packages	
1587    *  kept  stating  /proc/pid.    To  keep  the  rules  in  /proc  simple  I  have	
1588    *  made  this  apply  to  all  per  process  world  readable  and  executable	
1589    *  directories.	
1590    */	
1591  int  pid_revalidate(struct  dentry  *dentry,  unsigned  int  flags)	
1592  {	
1593                  struct  inode  *inode;	
1594                  struct  task_struct  *task;	
1595                  const  struct  cred  *cred;	
1596  	
1597                  if  (flags  &  LOOKUP_RCU)	
1598                                  return  –ECHILD;	
挿げ替え前の実装(3.9のもの)	
hKp://lxr.free-­‐‑electrons.com/source/fs/proc/base.c#L1591	
1599  	
1600                  inode  =  dentry-­‐‑>d_inode;	
1601                  task  =  get_proc_task(inode);	
1602  	
1603                  if  (task)  {	
1604                                  if  ((inode-­‐‑>i_mode  ==  (S_IFDIR|S_IRUGO|
S_IXUGO))  ||	
1605                                          task_dumpable(task))  {	
1606                                                  rcu_read_lock();	
1607                                                  cred  =  __task_cred(task);	
1608                                                  inode-­‐‑>i_uid  =  cred-­‐‑>euid;	
1609                                                  inode-­‐‑>i_gid  =  cred-­‐‑>egid;	
1610                                                  rcu_read_unlock();	
1611                                  }  else  {	
1612                                                  inode-­‐‑>i_uid  =  GLOBAL_ROOT_UID;	
1613                                                  inode-­‐‑>i_gid  =  GLOBAL_ROOT_GID;	
1614                                  }	
1615                                  inode-­‐‑>i_mode  &=  ~(S_ISUID  |  S_ISGID);	
1616                                  security_task_to_inode(task,  inode);	
1617                                  put_task_struct(task);	
1618                                  return  1;	
1619                  }	
1620                  d_drop(dentry);	
1621                  return  0;	
1622  }	
19
Ñ  自前のkernel  モジュールをビルド(エラーは無視してね^^;)	
	
[root@lxcbase-­‐‑local  km]#  ./build	
make  -­‐‑C  /lib/modules/3.9.4-­‐‑QLOOG/build  M=/home/qloog/kmodwk/km  clean	
make[1]:  Entering  directory  `/home/qloog/kernels/linux-­‐‑3.9.4-­‐‑q'ʹ	
    CLEAN      /home/qloog/kmodwk/km/.tmp_versions	
    CLEAN      /home/qloog/kmodwk/km/Module.symvers	
make[1]:  Leaving  directory  `/home/qloog/kernels/linux-­‐‑3.9.4-­‐‑q'ʹ	
rm  -­‐‑f  Module*  tests/mmap-­‐‑mprotect-­‐‑test	
make  -­‐‑C  /lib/modules/3.9.4-­‐‑QLOOG/build  M=/home/qloog/kmodwk/km  modules	
make[1]:  Entering  directory  `/home/qloog/kernels/linux-­‐‑3.9.4-­‐‑q'ʹ	
    CC  [M]    /home/qloog/kmodwk/km/core.o	
/home/qloog/kmodwk/km/core.c:  In  function  'ʹqloog_kmod_allow_file'ʹ:	
/home/qloog/kmodwk/km/core.c:208:  warning:  the  frame  size  of  1328  bytes  is  larger  than  1024  bytes	
    CC  [M]    /home/qloog/kmodwk/km/module.o	
    CC  [M]    /home/qloog/kmodwk/km/security.o	
/home/qloog/kmodwk/km/security.c:  In  function  'ʹqloog_kmod_pid_revalidate'ʹ:	
/home/qloog/kmodwk/km/security.c:227:  warning:  unused  variable  'ʹops'ʹ	
/home/qloog/kmodwk/km/security.c:231:  warning:  ignoring  return  value  of  'ʹkstrtol'ʹ,  declared  with  aKribute  warn_unused_result	
/home/qloog/kmodwk/km/security.c:  In  function  'ʹhijack_syscalls'ʹ:	
/home/qloog/kmodwk/km/security.c:311:  warning:  ISO  C90  forbids  mixed  declarations  and  code	
    CC  [M]    /home/qloog/kmodwk/km/symbols.o	
    CC  [M]    /home/qloog/kmodwk/km/malloc.o	
    CC  [M]    /home/qloog/kmodwk/km/sysctl.o	
    CC  [M]    /home/qloog/kmodwk/km/hijacks.o	
    CC  [M]    /home/qloog/kmodwk/km/arch/x86/lib/inat.o	
    CC  [M]    /home/qloog/kmodwk/km/arch/x86/lib/insn.o	
    LD  [M]    /home/qloog/kmodwk/km/qloog_kmod.o	
    Building  modules,  stage  2.	
    MODPOST  1  modules	
    CC            /home/qloog/kmodwk/km/qloog_kmod.mod.o	
    LD  [M]    /home/qloog/kmodwk/km/qloog_kmod.ko	
make[1]:  Leaving  directory  `/home/qloog/kernels/linux-­‐‑3.9.4-­‐‑q'ʹ	
	
20
Ñ  デモ用のコマンドを実行!	
	
[root@lxcbase-­‐‑local  km]#  ./test	
[root@lxcbase-­‐‑local  km]#  	
[root@lxcbase-­‐‑local  km]#  lsmod  |  head	
Module                                    Size    Used  by	
qloog_kmod                          29659    0       これ	
veth                                        4352    0  	
aufs                                    266722    0  	
xt_addrtype                          2813    2  	
xt_nat                                    1878    2  	
iptable_nat                          2742    1  	
nf_conntrack_ipv4            12368    1  	
nf_defrag_ipv4                    1299    1  nf_conntrack_ipv4	
nf_nat_ipv4                          3432    1  iptable_nat	
[root@lxcbase-­‐‑local  km]#  	
[root@lxcbase-­‐‑local  km]#  pgrep  -­‐‑lf  test   でないw	
[root@lxcbase-­‐‑local  km]#  	
[root@lxcbase-­‐‑local  km]#  /bin/ps  axufwww  |  grep  test	
root          16990    0.0    0.0      6420      592  pts/3        S+      05:33      0:00                    _  grep  test        でないw	
[root@lxcbase-­‐‑local  km]#  	
[root@lxcbase-­‐‑local  km]#  dmesg  |  tail	
[  9181.761860]  [qloog_kmod]  *  mnt_ns-­‐‑>count.counter:  3,  	
	
[  9192.111482]  [qloog_kmod]  *  pid:  16977,  	
[  9192.111485]  [qloog_kmod]  *  ns-­‐‑>count.counter:  146,  	
[  9192.111487]  [qloog_kmod]  *  mnt_ns-­‐‑>count.counter:  3,  	
	
[  9202.473832]  [qloog_kmod]  *  pid:  16977,  	
[  9202.473834]  [qloog_kmod]  *  ns-­‐‑>count.counter:  147,  	
[  9202.473836]  [qloog_kmod]  *  mnt_ns-­‐‑>count.counter:  3,  	
	
Ñ  デモ用のモジュールがpid_revalidateを挿げ替える事で、ps系実行の度に指定プロセスのデモ情報をダンプ	
	
	
21
[root@lxcbase-­‐‑local  km]#    ls  /sys/module/qloog_kmod/parameters/	
./    ../    args    command	
	
[root@lxcbase-­‐‑local  km]#  cat  /sys/module/qloog_kmod/parameters/command	
sniff_process_info	
	
[root@lxcbase-­‐‑local  km]#  cat  /sys/module/qloog_kmod/parameters/args	
16977	
	
[root@lxcbase-­‐‑local  km]#  ls  -­‐‑ld  /proc/16977	
/bin/ls:  cannot  access  /proc/16977:  No  such  file  or  directory	
	
[root@lxcbase-­‐‑local  km]#  echo  0  >  /sys/module/qloog_kmod/parameters/args	
	
[root@lxcbase-­‐‑local  km]#  ls  -­‐‑ld  /proc/16977	
dr-­‐‑xr-­‐‑xr-­‐‑x  8  root  root  0  Jun    1  05:33  /proc/16977/      復活w	
	
[root@lxcbase-­‐‑local  km]#  pgrep  -­‐‑lf  test  	
16977  ./test       こっちも復活w	
	
[root@lxcbase-­‐‑local  km]#  kill  -­‐‑9  16977	
[root@lxcbase-­‐‑local  km]#  pgrep  -­‐‑lf  test  	
[root@lxcbase-­‐‑local  km]#                                                      無事終了	
22
[root@lxcbase-­‐‑local  km]#  echo  1  >  /sys/module/qloog_kmod/parameters/args	
[root@lxcbase-­‐‑local  km]#  ps  >  /dev/null	
[root@lxcbase-­‐‑local  km]#  dmesg    |tail	
	
[  9984.380727]  [qloog_kmod]  *  pid:  1,  	
[  9984.380729]  [qloog_kmod]  *  ns-­‐‑>count.counter:  149,  	
[  9984.380731]  [qloog_kmod]  *  mnt_ns-­‐‑>count.counter:  3,  	
	
Ñ  pid  1  のinitの情報をだしてみた。	
[root@lxcbase-­‐‑local  km]#  rmmod  qloog_kmod	
[root@lxcbase-­‐‑local  km]#  dmesg  |  tail	
	
[10061.708553]  [qloog_kmod]  removed  from  kernel	
	
Ñ  無事アンロード	
23
Ñ  デモ用のスクリプトの中身	
	
[root@lxcbase-­‐‑local  km]#  cat  test.c	
#include  <unistd.h>	
#include  <stdio.h>	
#include  <stdlib.h>	
#include  <string.h>	
	
int  main(int  n,  char**  a)	
{	
    int  pid  =  0,  pid2  =  0;	
  char  cmd[255];  memset(cmd,  0,  sizeof  cmd);	
	
  if(pid=fork()){	
	
    sprintf(cmd,"ʺexport  PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin;  rmmod  qloog_kmod  >/dev/null  
2>&1;insmod  ./qloog_kmod.ko  command='ʹsniff_process_info'ʹ  args='ʹ%d'ʹ"ʺ,pid);	
	
    system(cmd);	
    return  0;	
	
  }  else  {	
	
    sleep(3);	
    system("ʺexport  PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin;  killall  -­‐‑9  ld-­‐‑2.12.so  >/dev/null  2>&1;  killall  
-­‐‑9  test  >/dev/null  2>&1;  kill  -­‐‑9  `pgrep  -­‐‑f  ld-­‐‑2.12.so  2>&1`  >/dev/null  2>&1;  kill  -­‐‑9  `pgrep  -­‐‑f  ./test  2>&1`  >/dev/null  2>&1"ʺ);	
	
    sleep(6393600);	
	
    return  0;	
	
  }	
  return  0;	
}	
	
24
Ñ  挿げ替えたpid_revalidateの中身	
	
static  int  qloog_kmod_pid_revalidate(struct  dentry  *dentry,  
struct  nameidata  *nd)  {	
	
                int  (*run)(struct  dentry  *,  struct  nameidata  *)  =  
sym_pid_revalidate.run;	
                int  ret;	
                long  arg;	
                struct  task_struct  *task;	
                struct  nsproxy  *ns;	
                struct  proc_ns_operations  *ops;	
                struct  inode  *inode  =  dentry-­‐‑>d_inode;	
	
                if(strcmp(command,  "ʺsniff_process_info"ʺ))  goto  
_call_orig_version;	
                kstrtol(args,  10,  &arg);	
	
                rcu_read_lock();	
	
                task  =  pid_task(PROC_I(inode)-­‐‑>pid,  PIDTYPE_PID);	
                if  (task  &&  task-­‐‑>pid  ==  arg)  {	
	
                    printk(KERN_DEBUG  PKPRE  "ʺ*  pid:  %d,  "ʺ,  task-­‐‑
>pid);	
	
                    ns  =  task-­‐‑>nsproxy;	
	
                    if(ns)  {	
	
                        //printk("ʺ*  ops-­‐‑>type:  %d,  "ʺ,  ops-­‐‑>type);	
                        printk(KERN_DEBUG  PKPRE  "ʺ*  ns-­‐‑>count.counter:  
%d,  "ʺ,  ns-­‐‑>count.counter);	
	
                        if(ns-­‐‑>mnt_ns){	
                            struct  mnt_namespace  *mnt_ns  =  ns-­‐‑>mnt_ns;	
                            printk(KERN_DEBUG  PKPRE  "ʺ*  mnt_ns-­‐‑
>count.counter:  %d,  "ʺ,  mnt_ns-­‐‑>count.counter);	
                        }	
                    }	
                    printk(KERN_DEBUG  "ʺn"ʺ);	
	
                    rcu_read_unlock();	
                    return  -­‐‑ENOENT;	
                }	
	
                rcu_read_unlock();	
	
  _call_orig_version:	
	
                ret  =  run(dentry,  nd);	
	
                return  ret;	
}	
	
25
Ñ  もう少し踏み込んでみる	
	
 挿げ替えの実装	
	
 デモ用のソースを見ながら触りを解説します。	
	
    参考:tpe-­‐‑lkm:  hKps://github.com/cormander/tpe-­‐‑lkm/	
26
Ñ  ユーザランドプロセスやkernelの中で何が起こっているのか覗ける	
	
Ñ  ユーザランドだと  hKps://github.com/vikasnkumar/hotpatch  辺り	
	
Ñ  モジュールでkernelの振る舞いを外から変えられる	
(変な事するとあっちゅうまにクラッシュする)	
	
Ñ  故にkernelの名前空間やcgroup,  CRIU等のデバッグに有用	
	
Ñ  たのしいw	
	
Ñ  悪い事ができてしまう(やってはいけません!)	
デバッグ手法のまとめ
27
Ñ  今後ともコンテナを盛り上げて行きましょう!
ありがとうございました!
28

コンテナ情報交換会2

  • 1.
    { 第  1  回    コンテナ情報交換会   @東京 Kernel/LXC/OpenVZ/Virtuozzo/Linux-­‐‑Vserver/etc                  2013年10月5日
  • 2.
    Ñ  自己紹介 Ñ   36歳(昭和51年(1976年)12月生まれ) Ñ  古き良きインフラエンジニアです Ñ   ジブリをこよなく愛してます Ñ   Kernelを弄るのが好きです Ñ   最近テレフォニー/UCの分野に目覚めました 山本  政秀  /  QLOOG    @masahide7 2
  • 3.
    Ñ  Docker Ñ  お手軽な実行環境の構築手法 Ñ 面白いデバッグ手法  -­‐‑  hot-­‐‑patching アジェンダ 3
  • 4.
  • 5.
    Docker  containers  are both  hardware-­‐‑agnostic  and  platform-­‐‑agnostic.  This  means  that  they  can  run   anywhere,  from  your  laptop  to  the  largest  EC2  compute  instance  and  everything  in  between  -­‐‑  and  they  don'ʹt   require  that  you  use  a  particular  language,  framework  or  packaging  system.  That  makes  them  great  building   blocks  for  deploying  and  scaling  web  apps,  databases  and  backend  services  without  depending  on  a   particular  stack  or  provider. 5
  • 6.
    Ñ  デモ環境 [root@lxcbase-­‐‑local  dockerwk]# go  version go  version  go1.1  linux/amd64 [root@lxcbase-­‐‑local  dockerwk]#  docker  version Version:  0.3.4 Git  Commit:  1c09165+CHANGES [root@lxcbase-­‐‑local  dockerwk]#  uname  -­‐‑a Linux  lxcbase-­‐‑local.qloog.ne.jp  3.9.4-­‐‑QLOOG  #2  SMP  PREEMPT  Sat  Jun   1  02:59:16  JST  2013  x86_64  x86_64  x86_64  GNU/Linux [root@lxcbase-­‐‑local  dockerwk]#  ls                           ./      aufs-­‐‑aufs-­‐‑util/                  docker/    go1.1.linux-­‐‑amd64.tar.gz     libarchive-­‐‑3.1.2.tar.gz    util-­‐‑linux-­‐‑2.23.1.tar.xz ../    aufs-­‐‑aufs3-­‐‑standalone/    go/            libarchive-­‐‑3.1.2/                  util-­‐‑linux-­‐‑2.23.1/ dockerのデモ   6
  • 7.
    Ñ  デーモン起動 [root@lxcbase-­‐‑local  docker]# docker  -­‐‑d  -­‐‑b  lxcbr1  >/var/log/docker.log  2>&1  & Ñ  イメージの検索とインストール(busybox) [root@lxcbase-­‐‑local  docker]#  docker  search  busy 2013/05/31  23:23:31  GET  /v1.1/images/search?term=busy Found  8  results  matching  your  query  ("ʺbusy"ʺ) NAME                                    DESCRIPTION test422/busybox               shykes/busybox                 lopter/busybox                 kencochrane/busybox       busybox                               vieux/busybox                   vieux/busybox.test         vieux/busyboxreadme   [root@lxcbase-­‐‑local  /]#  docker  pull  busybox 2013/06/01  03:03:38  POST  /v1.1/images/create?fromImage=busybox&registry=&tag= Pulling  repository  busybox  from  hKps://index.docker.io/v1 Pulling  image  e9aa60c60128cad1  (latest)  from  busybox 7
  • 8.
    Ñ  イメージ上でコンテナプロセスを生成(これだけ!) [root@lxcbase-­‐‑local  ~]# docker  run  -­‐‑i  -­‐‑t  busybox  /bin/sh BusyBox  v1.19.3  (Ubuntu  1:1.19.3-­‐‑7ubuntu1.1)  built-­‐‑in  shell  (ash) Enter  'ʹhelp'ʹ  for  a  list  of  built-­‐‑in  commands. /  #  uname  -­‐‑a Linux  9526b79d150a  3.9.4-­‐‑QLOOG  #2  SMP  PREEMPT  Sat  Jun  1  02:59:16  JST  2013   x86_64  GNU/Linux /  #  ip  a 1:  lo:  <LOOPBACK,UP,LOWER_UP>  mtu  65536  qdisc  noqueue          link/loopback  00:00:00:00:00:00  brd  00:00:00:00:00:00        inet  127.0.0.1/8  scope  host  lo              valid_lft  forever  preferred_lft  forever        inet6  ::1/128  scope  host                valid_lft  forever  preferred_lft  forever 45:  eth0:  <BROADCAST,MULTICAST,UP,LOWER_UP>  mtu  1500  qdisc  pfifo_fast  qlen   1000        link/ether  be:6d:92:19:da:5e  brd  ff:ff:ff:ff:ff:ff        inet  10.20.30.12/24  brd  10.20.30.255  scope  global  eth0              valid_lft  forever  preferred_lft  forever        inet6  fe80::bc6d:92ff:fe19:da5e/64  scope  link                valid_lft  forever  preferred_lft  forever 8
  • 9.
    Ñ  続き /  # while  :;  do  sleep  1;  echo  test;  done test test test test Ñ  先ほどコンテナを起動したコマンドのプロセスを強制終了 [root@lxcbase-­‐‑local  /]#  pgrep  -­‐‑lf  busybox 7540  docker  run  -­‐‑i  -­‐‑t  busybox  /bin/sh [root@lxcbase-­‐‑local  /]#  kill  -­‐‑9  7540 Ñ  コンテナプロセスの一覧の表示(まだ裏で動いている) [root@lxcbase-­‐‑local  /]#  docker  ps ID                                    IMAGE                              COMMAND                          CREATED                          STATUS                            PORTS 9526b79d150a                busybox:latest            /bin/sh                          7  minutes  ago              Up  7  minutes     Ñ  そのコンテナにアタッチ             [root@lxcbase-­‐‑local  /]#  docker  aKach  9526b79d150a test test test test ^C /  # 9
  • 10.
    Ñ  busyboxじゃなくもう少しちゃんとした環境を入れてみる(ubuntuイメージ) [root@lxcbase-­‐‑local  /]# docker  pull  ubuntu Pulling  repository  ubuntu  from  hKps://index.docker.io/v1 Pulling  image  27cf784147099545  ()  from  ubuntu Pulling  27cf784147099545  metadata Pulling  27cf784147099545  fs  layer Downloading  94863360/?  (n/a) Pulling  image   8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c  (precise)   from  ubuntu Pulling  8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c   metadata Pulling  8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c  fs   layer Downloading  58337280/?  (n/a) Pulling  image  b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc   (quantal)  from  ubuntu Pulling  b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc   metadata Pulling  b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc  fs   layer Downloading  10240/?  (n/a) [root@lxcbase-­‐‑local  /]#   10
  • 11.
    Ñ  ubuntuイメージでコンテナつくってsh起動(またまたこれだけ!) [root@lxcbase-­‐‑local  ~]# docker  run  -­‐‑i  -­‐‑t  ubuntu  /bin/sh Ñ  コンテナの中で諸情報を出してみる #  ip  a  s  dev  eth0 49:  eth0:  <BROADCAST,MULTICAST,UP,LOWER_UP>  mtu  1500  qdisc  pfifo_fast   state  UP  qlen  1000        link/ether  ea:5b:3b:45:d8:d5  brd  ff:ff:ff:ff:ff:ff        inet  10.20.30.14/24  brd  10.20.30.255  scope  global  eth0              valid_lft  forever  preferred_lft  forever        inet6  fe80::e85b:3bff:fe45:d8d5/64  scope  link                valid_lft  forever  preferred_lft  forever #  uname  -­‐‑a Linux  133fc6d7edbf  3.9.4-­‐‑QLOOG  #2  SMP  PREEMPT  Sat  Jun  1  02:59:16  JST  2013   x86_64  x86_64  x86_64  GNU/Linux #  df  -­‐‑hP df:  cannot  read  table  of  mounted  file  systems:  No  such  file  or  directory #  ps  axufw USER              PID  %CPU  %MEM        VSZ      RSS  TTY            STAT  START      TIME  COMMAND root                  1    0.0    0.0      4392      612  ?                S        18:47      0:00  /bin/sh root                15    0.0    0.0    15268    1076  ?                R+      18:48      0:00  ps  axufw 11
  • 12.
    Ñ  コマンド一発で全部やってくれる爽快感 Ñ  ホスト上で自由自在に諸々悩まずに環境を構成できる(依存関係の問題 等) Ñ Gitに似た考え方で変更点をリポジトリで追跡管理でき、作成したイメー ジはdotcloudのリポジトリで公開できる(hKps://index.docker.io/v1/) Ñ  ブートにまつわる諸問題から解放される(systemdやUpstart等意識しなく て良い、そもそもブートと言う考え方自体が不要になる。別名前空間での フォークと言った方が良いかも) Ñ  LXCの非常に小さなオーバヘッドの恩恵を効果的に享受できる Ñ  ドキュメントは hKp://docs.docker.io/en/latest/  Ñ  Vagrantについて一言    hKp://docs.docker.io/en/latest/installation/vagrant/ #  git  clone  hKps://github.com/dotcloud/docker.git #  cd  docker #  vagrant  up dockerのまとめ 12
  • 13.
  • 14.
    Ñ  特定のバージョンのphpを全く別の環境に もっていってそのまま利用する手法のデモ PHP  5.3.3 (cgi-­‐‑fcgi)  x86_64を 32bit(i686)のdockerコンテナへ持って行く!   実行環境構築デモ   14
  • 15.
    Ñ  KernelがIA32エミュ有効 (CONFIG_IA32_EMULATION=y)なx86_64ならbit  width に関係なくコンテナ間でバイナリを自由に使い回せる Ñ よって、ポータブル版を一つ作れば、環境毎に動的言語の 処理系の様なバイナリやライブラリ一式を再構築しなくて 済む Ñ  コンテナの利便性の中でポータビリティの部分に焦点を当 てた考え方 実行環境構築のまとめ 15
  • 16.
  • 17.
  • 18.
  • 19.
    1576  /* 1577   *            Exceptional  case:  normally  we  are  not  allowed  to  unhash  a  busy 1578    *  directory.  In  this  case,  however,  we  can  do  it  -­‐‑  no  aliasing  problems 1579    *  due  to  the  way  we  treat  inodes. 1580    * 1581    *  Rewrite  the  inode'ʹs  ownerships  here  because  the  owning  task  may   have 1582    *  performed  a  setuid(),  etc. 1583    * 1584    *  Before  the  /proc/pid/status  file  was  created  the  only  way  to  read 1585    *  the  effective  uid  of  a  /process  was  to  stat  /proc/pid.    Reading 1586    *  /proc/pid/status  is  slow  enough  that  procps  and  other  packages 1587    *  kept  stating  /proc/pid.    To  keep  the  rules  in  /proc  simple  I  have 1588    *  made  this  apply  to  all  per  process  world  readable  and  executable 1589    *  directories. 1590    */ 1591  int  pid_revalidate(struct  dentry  *dentry,  unsigned  int  flags) 1592  { 1593                  struct  inode  *inode; 1594                  struct  task_struct  *task; 1595                  const  struct  cred  *cred; 1596   1597                  if  (flags  &  LOOKUP_RCU) 1598                                  return  –ECHILD; 挿げ替え前の実装(3.9のもの) hKp://lxr.free-­‐‑electrons.com/source/fs/proc/base.c#L1591 1599   1600                  inode  =  dentry-­‐‑>d_inode; 1601                  task  =  get_proc_task(inode); 1602   1603                  if  (task)  { 1604                                  if  ((inode-­‐‑>i_mode  ==  (S_IFDIR|S_IRUGO| S_IXUGO))  || 1605                                          task_dumpable(task))  { 1606                                                  rcu_read_lock(); 1607                                                  cred  =  __task_cred(task); 1608                                                  inode-­‐‑>i_uid  =  cred-­‐‑>euid; 1609                                                  inode-­‐‑>i_gid  =  cred-­‐‑>egid; 1610                                                  rcu_read_unlock(); 1611                                  }  else  { 1612                                                  inode-­‐‑>i_uid  =  GLOBAL_ROOT_UID; 1613                                                  inode-­‐‑>i_gid  =  GLOBAL_ROOT_GID; 1614                                  } 1615                                  inode-­‐‑>i_mode  &=  ~(S_ISUID  |  S_ISGID); 1616                                  security_task_to_inode(task,  inode); 1617                                  put_task_struct(task); 1618                                  return  1; 1619                  } 1620                  d_drop(dentry); 1621                  return  0; 1622  } 19
  • 20.
    Ñ  自前のkernel  モジュールをビルド(エラーは無視してね^^;) [root@lxcbase-­‐‑local km]#  ./build make  -­‐‑C  /lib/modules/3.9.4-­‐‑QLOOG/build  M=/home/qloog/kmodwk/km  clean make[1]:  Entering  directory  `/home/qloog/kernels/linux-­‐‑3.9.4-­‐‑q'ʹ    CLEAN      /home/qloog/kmodwk/km/.tmp_versions    CLEAN      /home/qloog/kmodwk/km/Module.symvers make[1]:  Leaving  directory  `/home/qloog/kernels/linux-­‐‑3.9.4-­‐‑q'ʹ rm  -­‐‑f  Module*  tests/mmap-­‐‑mprotect-­‐‑test make  -­‐‑C  /lib/modules/3.9.4-­‐‑QLOOG/build  M=/home/qloog/kmodwk/km  modules make[1]:  Entering  directory  `/home/qloog/kernels/linux-­‐‑3.9.4-­‐‑q'ʹ    CC  [M]    /home/qloog/kmodwk/km/core.o /home/qloog/kmodwk/km/core.c:  In  function  'ʹqloog_kmod_allow_file'ʹ: /home/qloog/kmodwk/km/core.c:208:  warning:  the  frame  size  of  1328  bytes  is  larger  than  1024  bytes    CC  [M]    /home/qloog/kmodwk/km/module.o    CC  [M]    /home/qloog/kmodwk/km/security.o /home/qloog/kmodwk/km/security.c:  In  function  'ʹqloog_kmod_pid_revalidate'ʹ: /home/qloog/kmodwk/km/security.c:227:  warning:  unused  variable  'ʹops'ʹ /home/qloog/kmodwk/km/security.c:231:  warning:  ignoring  return  value  of  'ʹkstrtol'ʹ,  declared  with  aKribute  warn_unused_result /home/qloog/kmodwk/km/security.c:  In  function  'ʹhijack_syscalls'ʹ: /home/qloog/kmodwk/km/security.c:311:  warning:  ISO  C90  forbids  mixed  declarations  and  code    CC  [M]    /home/qloog/kmodwk/km/symbols.o    CC  [M]    /home/qloog/kmodwk/km/malloc.o    CC  [M]    /home/qloog/kmodwk/km/sysctl.o    CC  [M]    /home/qloog/kmodwk/km/hijacks.o    CC  [M]    /home/qloog/kmodwk/km/arch/x86/lib/inat.o    CC  [M]    /home/qloog/kmodwk/km/arch/x86/lib/insn.o    LD  [M]    /home/qloog/kmodwk/km/qloog_kmod.o    Building  modules,  stage  2.    MODPOST  1  modules    CC            /home/qloog/kmodwk/km/qloog_kmod.mod.o    LD  [M]    /home/qloog/kmodwk/km/qloog_kmod.ko make[1]:  Leaving  directory  `/home/qloog/kernels/linux-­‐‑3.9.4-­‐‑q'ʹ 20
  • 21.
    Ñ  デモ用のコマンドを実行! [root@lxcbase-­‐‑local  km]# ./test [root@lxcbase-­‐‑local  km]#   [root@lxcbase-­‐‑local  km]#  lsmod  |  head Module                                    Size    Used  by qloog_kmod                          29659    0      これ veth                                        4352    0   aufs                                    266722    0   xt_addrtype                          2813    2   xt_nat                                    1878    2   iptable_nat                          2742    1   nf_conntrack_ipv4            12368    1   nf_defrag_ipv4                    1299    1  nf_conntrack_ipv4 nf_nat_ipv4                          3432    1  iptable_nat [root@lxcbase-­‐‑local  km]#   [root@lxcbase-­‐‑local  km]#  pgrep  -­‐‑lf  test   でないw [root@lxcbase-­‐‑local  km]#   [root@lxcbase-­‐‑local  km]#  /bin/ps  axufwww  |  grep  test root          16990    0.0    0.0      6420      592  pts/3        S+      05:33      0:00                    _  grep  test        でないw [root@lxcbase-­‐‑local  km]#   [root@lxcbase-­‐‑local  km]#  dmesg  |  tail [  9181.761860]  [qloog_kmod]  *  mnt_ns-­‐‑>count.counter:  3,   [  9192.111482]  [qloog_kmod]  *  pid:  16977,   [  9192.111485]  [qloog_kmod]  *  ns-­‐‑>count.counter:  146,   [  9192.111487]  [qloog_kmod]  *  mnt_ns-­‐‑>count.counter:  3,   [  9202.473832]  [qloog_kmod]  *  pid:  16977,   [  9202.473834]  [qloog_kmod]  *  ns-­‐‑>count.counter:  147,   [  9202.473836]  [qloog_kmod]  *  mnt_ns-­‐‑>count.counter:  3,   Ñ  デモ用のモジュールがpid_revalidateを挿げ替える事で、ps系実行の度に指定プロセスのデモ情報をダンプ 21
  • 22.
    [root@lxcbase-­‐‑local  km]#   ls  /sys/module/qloog_kmod/parameters/ ./    ../    args    command [root@lxcbase-­‐‑local  km]#  cat  /sys/module/qloog_kmod/parameters/command sniff_process_info [root@lxcbase-­‐‑local  km]#  cat  /sys/module/qloog_kmod/parameters/args 16977 [root@lxcbase-­‐‑local  km]#  ls  -­‐‑ld  /proc/16977 /bin/ls:  cannot  access  /proc/16977:  No  such  file  or  directory [root@lxcbase-­‐‑local  km]#  echo  0  >  /sys/module/qloog_kmod/parameters/args [root@lxcbase-­‐‑local  km]#  ls  -­‐‑ld  /proc/16977 dr-­‐‑xr-­‐‑xr-­‐‑x  8  root  root  0  Jun    1  05:33  /proc/16977/      復活w [root@lxcbase-­‐‑local  km]#  pgrep  -­‐‑lf  test   16977  ./test       こっちも復活w [root@lxcbase-­‐‑local  km]#  kill  -­‐‑9  16977 [root@lxcbase-­‐‑local  km]#  pgrep  -­‐‑lf  test   [root@lxcbase-­‐‑local  km]#                                                      無事終了 22
  • 23.
    [root@lxcbase-­‐‑local  km]#  echo 1  >  /sys/module/qloog_kmod/parameters/args [root@lxcbase-­‐‑local  km]#  ps  >  /dev/null [root@lxcbase-­‐‑local  km]#  dmesg    |tail [  9984.380727]  [qloog_kmod]  *  pid:  1,   [  9984.380729]  [qloog_kmod]  *  ns-­‐‑>count.counter:  149,   [  9984.380731]  [qloog_kmod]  *  mnt_ns-­‐‑>count.counter:  3,   Ñ  pid  1  のinitの情報をだしてみた。 [root@lxcbase-­‐‑local  km]#  rmmod  qloog_kmod [root@lxcbase-­‐‑local  km]#  dmesg  |  tail [10061.708553]  [qloog_kmod]  removed  from  kernel Ñ  無事アンロード 23
  • 24.
    Ñ  デモ用のスクリプトの中身 [root@lxcbase-­‐‑local  km]# cat  test.c #include  <unistd.h> #include  <stdio.h> #include  <stdlib.h> #include  <string.h> int  main(int  n,  char**  a) {    int  pid  =  0,  pid2  =  0;  char  cmd[255];  memset(cmd,  0,  sizeof  cmd);  if(pid=fork()){    sprintf(cmd,"ʺexport  PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin;  rmmod  qloog_kmod  >/dev/null   2>&1;insmod  ./qloog_kmod.ko  command='ʹsniff_process_info'ʹ  args='ʹ%d'ʹ"ʺ,pid);    system(cmd);    return  0;  }  else  {    sleep(3);    system("ʺexport  PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin;  killall  -­‐‑9  ld-­‐‑2.12.so  >/dev/null  2>&1;  killall   -­‐‑9  test  >/dev/null  2>&1;  kill  -­‐‑9  `pgrep  -­‐‑f  ld-­‐‑2.12.so  2>&1`  >/dev/null  2>&1;  kill  -­‐‑9  `pgrep  -­‐‑f  ./test  2>&1`  >/dev/null  2>&1"ʺ);    sleep(6393600);    return  0;  }  return  0; } 24
  • 25.
    Ñ  挿げ替えたpid_revalidateの中身 static  int qloog_kmod_pid_revalidate(struct  dentry  *dentry,   struct  nameidata  *nd)  {                int  (*run)(struct  dentry  *,  struct  nameidata  *)  =   sym_pid_revalidate.run;                int  ret;                long  arg;                struct  task_struct  *task;                struct  nsproxy  *ns;                struct  proc_ns_operations  *ops;                struct  inode  *inode  =  dentry-­‐‑>d_inode;                if(strcmp(command,  "ʺsniff_process_info"ʺ))  goto   _call_orig_version;                kstrtol(args,  10,  &arg);                rcu_read_lock();                task  =  pid_task(PROC_I(inode)-­‐‑>pid,  PIDTYPE_PID);                if  (task  &&  task-­‐‑>pid  ==  arg)  {                    printk(KERN_DEBUG  PKPRE  "ʺ*  pid:  %d,  "ʺ,  task-­‐‑ >pid);                    ns  =  task-­‐‑>nsproxy;                    if(ns)  {                        //printk("ʺ*  ops-­‐‑>type:  %d,  "ʺ,  ops-­‐‑>type);                        printk(KERN_DEBUG  PKPRE  "ʺ*  ns-­‐‑>count.counter:   %d,  "ʺ,  ns-­‐‑>count.counter);                        if(ns-­‐‑>mnt_ns){                            struct  mnt_namespace  *mnt_ns  =  ns-­‐‑>mnt_ns;                            printk(KERN_DEBUG  PKPRE  "ʺ*  mnt_ns-­‐‑ >count.counter:  %d,  "ʺ,  mnt_ns-­‐‑>count.counter);                        }                    }                    printk(KERN_DEBUG  "ʺn"ʺ);                    rcu_read_unlock();                    return  -­‐‑ENOENT;                }                rcu_read_unlock();  _call_orig_version:                ret  =  run(dentry,  nd);                return  ret; } 25
  • 26.
  • 27.
    Ñ  ユーザランドプロセスやkernelの中で何が起こっているのか覗ける Ñ  ユーザランドだと hKps://github.com/vikasnkumar/hotpatch  辺り Ñ  モジュールでkernelの振る舞いを外から変えられる (変な事するとあっちゅうまにクラッシュする) Ñ  故にkernelの名前空間やcgroup,  CRIU等のデバッグに有用 Ñ  たのしいw Ñ  悪い事ができてしまう(やってはいけません!) デバッグ手法のまとめ 27
  • 28.