socket实现分析series(2)
时间:2010-08-26 来源:mtloveft
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) |
int socket(int domain, int type, int protocol) |
type 是通信方式, SOCK_STREAM, SOCK_DGRAM, SOCK_RAW
protocl 是协议 user space 调用socket()最终会返回一个文件描述符 kernel 又是怎么分配这个文件文件描述符的呢?
想了解kernel如何实现socket的,文件系统知识是不可少的。
因为socket的实现就是一种特殊的文件系统的实现。
文件系统的类型是sockfs
定义如下
static struct file_system_type sock_fs_type = { |
static int __init sock_init(void) |
它的定义下面有另外一行代码
core_initcall(sock_init); /* early initcall */
也就是在kernel 初始化的时候被调用,关于系统初始化
又是一大堆东西,暂时可以不考虑,只要知道系统初始化
时被调用就可以了。不过我以前画过一点儿关于初始化的
处理流程,可以稍微参考一下
下面的文章,地址 http://blog.chinaunix.net/u3/114767/showart_2301357.html register_filesystem就把sockfs注册到file_systems这个链表上了。
至于怎么注册的?请看下面的文章 http://blog.chinaunix.net/u3/114767/showart_2300161.html sockfs是虚拟文件系统,没有实际的物理介质,只存在于内存中。 然后调用kern_mount分配一个vfsmount结构即sock_mnt。这样同时
super block 等也生成了。 kern_mount的分析请参看下面文章 http://blog.chinaunix.net/u3/114767/showart_2291293.html 对于linux kernel,创建一个socket就是在sockfs文件系统里分配
相应的inode ,其实这个inode 和struct socket在内存上是连续的,也就关联了起来。
至于文件描述符,他是由curren即当前进程分配的一个
struct file ,它是一个跟inode 间接关联的。所以最终文件描述符和
socket关联起来了。
说的简单,代码倒是一大堆。慢慢分析。 先来看看sockfs的mount过程
sockfs中取得super block 的方法是sockfs_get_sb
所以mount 过程中会调用到他
static int sockfs_get_sb(struct file_system_type *fs_type, int flags, |
因为直接调用get_sb_pseudo,所以直接看它的代码
/* |
get_sb_pseudo的参数如下
第一个参数,fs_type = sock_fs_type即sockfs
第二个参数,"socket:"用于sockfs 的root的dentry的名称
第三个参数, sockfs_ops是sockfs 的super block 的操作VFT
,定义为
static const struct super_operations sockfs_ops = { |
第四个参数,sockfs 的magic number
第五个参数,即vfsmount,
所以sockfs 里分配inode 的方法是sock_alloc_inode
以后每次分配inode,都调用次方法
static struct inode *sock_alloc_inode(struct super_block *sb) |
socket_alloc的结构很有特点,就是把socket 和inode 关联了起来。
每次从cache里分配都是有两个结构。
struct socket_alloc { |
看结构就知道了,inode和socket被关联在一起了。知道其中一个就可以知道另外一个了。