声明:本文为原创
#####请转贴时保留以下内容######
作者:GTT
请提出宝贵意见Mail:mtloveft@hotmail.com 
Linux Version:2.6.33
提示:本文是介绍linux 网络协议栈初始化!
  
 
core_initcall级别的网络初始化方法还有net_inuse_init
首先看看它的source code,然后分析这个网络初始化方法都干了些什么。
| static __init int net_inuse_init(void){
 if (register_pernet_subsys(&net_inuse_ops))
 panic("Cannot initialize net inuse counters");
 
 return 0;
 }
 | 
 
register_pernet_subsys方法在一个网络命名空间里注册子系统。
 
注册net_inuse_ops,它的定义如下
| static struct pernet_operations net_inuse_ops = {.init = sock_inuse_init_net,
 .exit = sock_inuse_exit_net,
 }
 | 
 
 
我们再看看register_pernet_subsys是如何注册这个op的。
它的代码如下
| int register_pernet_subsys(struct pernet_operations *ops){
 int error;
 mutex_lock(&net_mutex);
 error = register_pernet_operations(first_device, ops);
 mutex_unlock(&net_mutex);
 return error;
 }
 | 
 
 
继续跟进register_pernet_operations
看看它的source code 
| static int register_pernet_operations(struct list_head *list, struct pernet_operations *ops){
 int error;
 
 if (ops->id) {
 again:
 error = ida_get_new_above(&net_generic_ids, 1, ops->id);
 if (error < 0) {
 if (error == -EAGAIN) {
 ida_pre_get(&net_generic_ids, GFP_KERNEL);
 goto again;
 }
 return error;
 }
 }
 error = __register_pernet_operations(list, ops);
 if (error) {
 rcu_barrier();
 if (ops->id) ida_remove(&net_generic_ids, *ops->id);
 }
 
 return error;
 }
 | 
 
 
如果ops设定了id,那么分配新的ID,然后执行__register_pernet_operations看看它的source code
| static int __register_pernet_operations(struct list_head *list,struct pernet_operations *ops)
 {
 int err = 0;
 err = ops_init(ops, &init_net);
 if (err) ops_free(ops, &init_net);
 return err;
 
 }
 | 
 
再稍微介绍一下,初始化网络命名空间方法ops_init的source 如下
| static int ops_init(const struct pernet_operations *ops, struct net *net){
 int err;
 if (ops->id && ops->size) {
 void *data = kzalloc(ops->size, GFP_KERNEL);
 if (!data) return -ENOMEM;
 
 err = net_assign_generic(net, *ops->id, data);
 if (err) {
 kfree(data);
 return err;
 }
 }
 if (ops->init)
 return ops->init(net);
 return 0;
 }
 | 
 
如果设定了ops的id和size,那么从内核堆内存里申请size大小的内存。重新设定net。
然后调用ops设定的init方法。
其实在新的网络命名空间里,之前设定的ops,将都被重新设定一遍。也就是子网络命名空间,继承了
父网络命名空间的内容。