mnt_nsはinit_nsproxyにあるデータの中で唯一コンパイル時に値が入っていないので、どのようデータが設定されていくのかを見てみる。mnt_nsの作成はcreate_mnt_ns()で実施していて、以前のエントリー「φ(・・*)ゞ ウーン mount namespaceめも - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモ」で見た部分ではあるけど、最初はどうやっているのかを見てなかったんですね。
ブート処理の場合は以下のようにstart_kernel()の中から初期化される。
start_kernel() @init/main.c --> vfs_caches_init() @fs/dcache.c --> mnt_init() fs/namespace.c --> init_mount_tree() @fs/namespace.c --> create_mnt_ns() @fs/namespace.c
ここで、namespaceが絡んでくるのはinit_mount_tree()からなのでその辺を。
最初にroot filesystemのマウント処理を行う。
2804 static void __init init_mount_tree(void) 2805 { 2806 struct vfsmount *mnt; 2807 struct mnt_namespace *ns; 2808 struct path root; 2809 struct file_system_type *type; 2810 2811 type = get_fs_type("rootfs"); 2812 if (!type) 2813 panic("Can't find rootfs type"); 2814 mnt = vfs_kern_mount(type, 0, "rootfs", NULL); 2815 put_filesystem(type); 2816 if (IS_ERR(mnt)) 2817 panic("Can't create rootfs"); 2818
次にマウントしたファイルシステムのデータを引数としてcreate_mnt_ns()を呼ぶ。create_mnt_ns()が終わったらinit_taskのnsproxt(init_nsproxt)にnamespaceを設定し、mnt_nsの参照カウンタを一つ増やすところまでがnamespaceの処理。
2819 ns = create_mnt_ns(mnt); 2820 if (IS_ERR(ns)) 2821 panic("Can't allocate initial namespace"); 2822 2823 init_task.nsproxy->mnt_ns = ns; 2824 get_mnt_ns(ns);
create_mnt_ns()は最初にalloc_mnt_ns()でインスタンスの作成。これは以前のエントリを参照。エラーが無ければif文の中が実行される。
2572 /** 2573 * create_mnt_ns - creates a private namespace and adds a root filesystem 2574 * @mnt: pointer to the new root filesystem mountpoint 2575 */ 2576 static struct mnt_namespace *create_mnt_ns(struct vfsmount *m) 2577 { 2578 struct mnt_namespace *new_ns = alloc_mnt_ns(&init_user_ns); 2579 if (!IS_ERR(new_ns)) { 2580 struct mount *mnt = real_mount(m); 2581 mnt->mnt_ns = new_ns; 2582 new_ns->root = mnt; 2583 list_add(&mnt->mnt_list, &new_ns->list); 2584 } else { 2585 mntput(m); 2586 } 2587 return new_ns; 2588 } 2589
real_mount()はcontainer_ofマクロを使ってstruct vfsmount構造体からstruct mountの変数にアクセスする。 そして、マウントポイントのstruct mountにあるnamespaceに作成したnew_nsを設定し、new_nsのルートファイルシステムにmntを設定。最後にnew_nsのリストにmntが繋がれる。
mnt_namespaceはこのような構造体でfs/mount.hにて定義。
5 struct mnt_namespace { 6 atomic_t count; 7 unsigned int proc_inum; 8 struct mount * root; 9 struct list_head list; 10 struct user_namespace *user_ns; 11 u64 seq; /* Sequence number to prevent loops */ 12 wait_queue_head_t poll; 13 u64 event; 14 };
fs/namespace.cだとこの構造体のリストにデータを追加するのはcopy_mnt_nsくらいだけど他でも操作があるのかどうか。。。
- 作者: 白崎博生
- 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
- 発売日: 2014/10/01
- メディア: 大型本
- この商品を含むブログを見る