我们先来简单看一下系统调用close(int fd)的流程。该系统调用会调用到内核中的函数:
asmlinkage long sys_close(unsigned int fd)
参 数fd给我们一个很好的线索,我们可以很方便地找到相应的struct file结构:file = current->files->fd[fd]。取出了这个至关重要的数据结构后,我们归还fd给系统,同时,设current-> file->fd[fd]=NULL。使我们创建的socket完全跟系统和进程分离。最后再销毁struct file结构。
销毁struct file的很多细节我们不关注,但在某一步,一个叫__fput(struct file *file)的函数中,有这样一个调用:
file->f_op->release(inode, file);
它实际调用到了sock_close函数,该函数又会调用到sock_release函数。sock_release函数又调用我们my_inet模块提供的myinet_release函数完成实际的socket销毁工作,同时,释放inode。
上面讲述的是一个大致的流程,我们重点关注的还是如何在我们的my_inet模块中实现套接字的销毁。下面先看一下myinet_release函数的实现:
int myinet_release(struct socket *sock)
{
struct sock *sk = sock->sk;
if (sk) {
long timeout = 0;
myip_mc_drop_socket(sk);
if (sock_flag(sk, SOCK_LINGER) &&
!(current->flags & PF_EXITING))
timeout = sk->sk_lingertime;
sock->sk = NULL;
sk->sk_prot->close(sk, timeout);
}
return 0;
}
可见,在我们的模块中,我们关注的其实是sock->sk的销毁,它是网络层一个套接字表示。myip_mc_drop_socket是离开组播组(如果曾加入过组播组的话),我们目前不关注。关于timeout我们也暂时不关心。
这里调用到了我们对应的协议的close函数,暂时,我们不去关注很多细节,只要记得在这个函数中应该调用sk_common_release最后完成对sock->sk的资源释放即可。
没有评论:
发表评论