socket相关的开机初始化分析

针对内核3.9

系统开启时,会使用init/main.c,然后再里面调用kernel_init(),在里面会再调用do_basic_setup(),调用do_initcalls(),调用do_one_initcall(),这个函数会去把注册了所有需要初始化的系统调用一一初始化。而网络模块由于全部都是基于socket在进行,所以,相关网络模块,在do_one_initcall()中会通过core_init()调用sock_init()来把网络文件系统登记在整个linux的文件系统中。其中core_init()非常重要,负责在内核初始化阶段把这些需要初始化的函数集中放在一个section里然后之后一个一个的进行处理。代码为:

286 #define core_initcall(fn) module_init(fn)

297 #define module_init(initfn)

298 static inline initcall_t __inittest(void)

299 { return initfn; }

300 int init_module(void) __attribute__((alias(#initfn)));

Sock_init的过程在2.6和3.9的内核中变化较大,代码如下:

static int __init sock_init(void)

2602 {

2603 int err;

2604 /*

2605 * Initialize the network sysctl infrastructure.

2606 */

2607 err = net_sysctl_init();

2608 if (err)

2609 goto out;

2610

2611 /*

2612 * Initialize skbuff SLAB cache

2613 */

2614 skb_init();

2615

2616 /*

2617 * Initialize the protocols module.

2618 */

2619

2620 init_inodecache();

2621

2622 err = register_filesystem(&sock_fs_type);

2623 if (err)

2624 goto out_fs;

2625 sock_mnt = kern_mount(&sock_fs_type);

2626 if (IS_ERR(sock_mnt)) {

2627 err = PTR_ERR(sock_mnt);

2628 goto out_mount;

2629 }

然后一句一句地进行分析,我们知道sysctl设置和显示在/proc/sys目录中的内核参数.能用sysctl来设置或重新设置连网功能,如IP转发、IP碎片去除及源路由检查等。而2607行调用net_sysctl_init()来对其进行初始化,我们来看怎么初始化的。

83 static struct ctl_table_header *net_header;

84 __init int net_sysctl_init(void)

85 {

86 static struct ctl_table empty[1];

87 int ret = -ENOMEM;

92 net_header = register_sysctl("net", empty);

93 if (!net_header)

94 goto out;

95 ret = register_pernet_subsys(&sysctl_pernet_ops);

96 if (ret)

97 goto out;

98 register_sysctl_root(&net_sysctl_root);

99 out:

100 return ret;

101 }

首先调用register_sysctl()进行把新的sysctl注册到ctl表中去,然后调用register_pernet_subsys()利用超级块操作表注册块设备表(此处由于我还没有学习过文件系统所以没懂),最后调用register_sysctl_root(),这个函数实际上什么都没有,官方给的注释是为了避免局限性把这个系统所在位置注册为空,说实话,没怎么懂,还望指教。

回到sock_init(void)中,skb_init()是为了初始化slab,不关心。然后是init_inodecache(),这个函数负责对inode进行处理,大概是要创建一块用于socket相关的inode的调整缓存,以方便之后对inode进行创建和释放。

然后是 register_filesystem(struct file_system_type * fs),负责将socket文件系统注册到内核中。代码如下:

69 int register_filesystem(struct file_system_type * fs)

70 {

71 int res = 0;

72 struct file_system_type ** p;

73

74 BUG_ON(strchr(fs->name, '.'));

75 if (fs->next)

76 return -EBUSY;

77 write_lock(&file_systems_lock);

78 p = find_filesystem(fs->name, strlen(fs->name));

79 if (*p)

80 res = -EBUSY;

81 else

82 *p = fs;

83 write_unlock(&file_systems_lock);

84 return res;

85 }

可以看到这里实际上是把一个新的文件系统注册到file_system_type这个全局变量的链表里,这里涉及到file_system_type这个数据结构,其中核心部分如下:

1802 struct file_system_type {

1803 const char *name;

1804 int fs_flags;

1811 struct dentry *(*mount) (struct file_system_type *, int,

1812 const char *, void *);

1813 void (*kill_sb) (struct super_block *);

1814 struct module *owner;

1815 struct file_system_type * next;

1826 };

其中struct dentry *(*mount) (struct file_system_type *, int,const char *, void *);是一个函数指针(也可以理解成钩子函数),负责指明哪个函数来处理,比如此处需要用到的sock_fs_type,就通过mount来规定使用sockfs_mount来进行注册。

326 static struct file_system_type sock_fs_type = {

327 .name = "sockfs",

328 .mount = sockfs_mount,

329 .kill_sb = kill_anon_super,

330 };

再回到sock_init(void),最后使用sock_mnt = kern_mount(&sock_fs_type);来把网络文件系统安装上。实际上是调用vfs_kern_mount(),大概是在虚拟文件系统下进行内存分配之类的工作,没看懂。

这里有一个非常优美的地方,在最后调用kern_mount(&sock_fs_type)时,会利用到sock_fs_type数据结构里的钩子函数sockfs_mount,然后继续调用mount_pseudo()执行实际上的安装,该函数是与文件系统相关的,是后面能执行socket等函数的先决条件。其中涉及文件系统,暂不讨论。

以上便是socket的初始化过程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容