声明:本文为原创
#####请转贴时保留以下内容######
作者: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,将都被重新设定一遍。也就是子网络命名空间,继承了
父网络命名空间的内容。
阅读(1937) | 评论(1) | 转发(0) |