各名前空間は/proc/
対象をuts namespaceとし、utsns_get()にWARN_ONを仕込んでスタックトレースを取ったのが↓です。本当はftraceでやろうかと思ったんだけど、お手軽?なほうで。。。
[ 322.987517] Call Trace: [ 322.987523] [<ffffffff8158f61f>] dump_stack+0x4c/0x6e [ 322.987528] [<ffffffff81078d4a>] warn_slowpath_common+0x8a/0xc0 [ 322.987531] [<ffffffff81078e7a>] warn_slowpath_null+0x1a/0x20 [ 322.987535] [<ffffffff811161f7>] utsns_get+0x27/0xb0 [ 322.987540] [<ffffffff812179da>] ns_get_path+0x12a/0x1c0 [ 322.987544] [<ffffffff8125608f>] proc_ns_follow_link+0x9f/0xc0 [ 322.987548] [<ffffffff811ff03a>] ? touch_atime+0x12a/0x180 [ 322.987553] [<ffffffff811f2d4a>] path_openat+0x4ba/0x690 [ 322.987557] [<ffffffff811f43b9>] do_filp_open+0x49/0xd0 [ 322.987562] [<ffffffff812e0bda>] ? find_next_zero_bit+0x1a/0x30 [ 322.987566] [<ffffffff81201a27>] ? __alloc_fd+0xa7/0x130 [ 322.987570] [<ffffffff811e246d>] do_sys_open+0x14d/0x250 [ 322.987573] [<ffffffff811e258e>] SyS_open+0x1e/0x20 [ 322.987577] [<ffffffff81594eee>] system_call_fastpath+0x12/0x71
このトレースからproc_ns_follow_link() -> ns_get_path() -> utsns_get()という流れということがわかります。
proc_ns_follow_link()は以前の記事
でinodeからtask_struct構造体の取得の仕方を調べたとこですね。ns_get_path()を呼んでいるのはproc_ns_follow_link()のこの部分です。
45 if (ptrace_may_access(task, PTRACE_MODE_READ)) { 46 error = ns_get_path(&ns_path, task, ns_ops); 47 if (!error) 48 nd_jump_link(nd, &ns_path); 49 }
proc_ns_operations構造体は関数の冒頭でこのように取得しています。ここのPROC_I()もLinux: inodeからtask_struct構造体を取得 - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモで見ています。
36 const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
ns_get_path()はnsfs.cで定義されています。このファイルはnamespace用に最近追加されたファイルです。 それでは、ns_get_path()を見てみます。って、いきなりget()を読んでますね。
46 void *ns_get_path(struct path *path, struct task_struct *task, 47 const struct proc_ns_operations *ns_ops) 48 { 49 struct vfsmount *mnt = mntget(nsfs_mnt); 50 struct qstr qname = { .name = "", }; 51 struct dentry *dentry; 52 struct inode *inode; 53 struct ns_common *ns; 54 unsigned long d; 55 56 again: 57 ns = ns_ops->get(task);
ここで引数にtask_struct構造体を渡していて、それがutsns_get()に渡されて使われるわけです。
98 static struct ns_common *utsns_get(struct task_struct *task) 99 { 100 struct uts_namespace *ns = NULL; 101 struct nsproxy *nsproxy; 102 103 task_lock(task); 104 nsproxy = task->nsproxy; 105 if (nsproxy) { 106 ns = nsproxy->uts_ns; 107 get_uts_ns(ns); 108 } 109 task_unlock(task); 110 111 return ns ? &ns->ns : NULL; 112 }
Dockerエキスパート養成読本[活用の基礎と実践ノウハウ満載!] (Software Design plus)
- 作者: 杉山貴章,大瀧隆太,Yugui(Yuki Sonoda),中津川篤司,前佛雅人,松原豊,米林正明,松本勇気
- 出版社/メーカー: 技術評論社
- 発売日: 2015/06/18
- メディア: 大型本
- この商品を含むブログ (1件) を見る