1. sock_create()函数:
创建socket的函数sys_socket(),在这个函数中调用sock_create()来完成创建。
在内核的net/socket.c文件中。
sys_socketcall()->sys_socket()->sock_create()。
实际调用__sock_create()函数执行创建任务。
2. __sock_create()函数:
sys_socketcall()->sys_socket()->sock_create()->__sock_create()。
调用函数sock_alloc()分配socket结构和文件节点。
int err;
struct socket *sock;
const struct net_proto_family *pf;
sock = sock_alloc(); // 分配socket结构空间
sock->type = type; // 记录socket类型
if (net_families[family] == NULL) // 检查协议族操作表
request_module("net-pf-%d", family); // 安装协议族操作表
pf = rcu_dereference(net_families[family]); // 取得协议族操作表
err = pf->create(net, sock, protocol); // 执行协议族的创建函数
*res = sock; // 返回创建的socket
3. sock_alloc()函数:
sys_socketcall()->sys_socket()->sock_create()->__sock_create()->sock_alloc()。
通过new_inode()函数分配socket网络文件系统的inode节点。
sock_mnt是socket网络文件系统的根节点。
在socket网络文件系统分配inode节点后,可以通过函数read()和write()找到socket进行读/写操作。
调用内联函数SOCKET_I()取得socket结构指针。
设置inode节点,如:标记为socket节点并记录下当前进程的信息,最后增加socket的使用计数。
struct inode *inode;
struct socket *sock;
inode = new_inode(sock_mnt->mnt_sb); // 在网络文件系统中创建文件节点同时分配socket结构
sock = SOCKET_I(inode); // 取得socket结构指针
4. SOCKET_I()函数:
sys_socketcall()->sys_socket()->sock_create()->__sock_create()->sock_alloc()->SOCKET_I()。
使用宏container_of。
重要数据结构socket_alloc。
在new_inode()函数中,在分配节点过程中会通过alloc_inode()函数调用超级块的函数操作表,最终是调用sock_alloc_inode()函数完成socket_alloc结构的分配。
struct socket_alloc
{
struct socket socket; // 分配的socket结构
struct inode vfs_inode; // 分配的文件节点结构
};
5. sock_alloc_inode()函数:
sys_socketcall()->sys_socket()->sock_create()->__sock_create()->sock_alloc()->new_inode()->alloc_inode()->sock_alloc_inode()。
从slab高速缓存sock_inode_cache直接进行分配,这个缓存块是在init_inodecache()函数中建立的,该函数在初始化函数sock_init()中被调用。
初始化socket中的等待队列,将socket的状态设为未连接。
struct socket_alloc *ei;
ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL); // 分配socket_alloc结构
init_waitqueue_head(&ei->socket.wait); // 初始化等待队列头
// 初始化socket
ei->socket.fasync_list = NULL;
ei->socket.state = SS_UNCONNECTED;
ei->socket.flags = 0;
ei->socket.ops = NULL;
ei->socket.sk = NULL;
ei->socket.file = NULL;
6. init_inodecache()函数:
调用kmem_cache_creat()函数以socket_alloc结构的长度为单位创建高速缓存。