夭折的一个补丁

这个补丁其实本来是我分配到的一个任务,不过在我们内部讨论时被拒了,所以放出来也无妨。再说了,在我们内部提交补丁的第一原则是必须首先在LKML上得到认可,没什么秘密。:-)

这个任务其实很简单,就是要把socket的一些选项给通过/proc导出,这些选项就是通过setsockopt(2)设置的那些。

初看这个任务感觉很简单,无怪乎就是一个/proc下的interface,然后就是通过某种方式把数据传输过来。但仔细一看其实不简单,因为setsockopt(2)并没有把这些数据集中存储起来,而是分散地存放到各个角落,然后通过switch/case的方式逐个判断。所以这里问题就来了,在某种程度上,其实我们要的就是一种“迭代”,而无奈的是,这些数据太过离散而不能迭代!这就是难点所在!

怎么解决呢?我首先想到的是用hash,把这些数据通过链表连起来,用其level和optname作关键字。后来想想其实这样也很麻烦,而且越往下想越麻烦。。。这时我就开始反思是不是该往简单里想想了?我盯住那switch/case,发现它既然能阻止我“迭代”,那我也能用它来“迭代”!对,我的主意就是用fall through!于是下面这个技巧就出来乐~~!

[c]

define BREAK(OPT, val)

   if (optname != SO_ALL)  
           break;          
   len += scnprintf(buf+len, *(int *)optlen - len, "%dt%dt%ldt%dn", 
           level, OPT, (long)(val), (int)sizeof(val))

define STOP() if (optname == SO_ALL) {

                   *(int *)optlen = len; 
                   return 0;       
           }

[/c]

其余的就很简单了,尤其是/proc的函数接口,感觉那块儿代码算是很整洁的,相当值得一读。

当然了,正如开头所说,现实是很残酷的,这个补丁被拒绝了,因为大牛David Miller不喜欢,他说这个是Solaris上有的东西,这并不代表Linux就一定要有,如果真的需要这个功能,我们还有systemtap,而且程序本身有义务自己打印socket的设置选项,如果调试的话。

如果你要有兴趣的话可以试试我这个补丁,但真要用的话还得自己完善一下,尤其是输出格式。:-)