夭折的一个补丁

May 26th, 2009 by 王 聪 Leave a reply »

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

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

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

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

C:
  1. #define BREAK(OPT, val) \
  2.        if (optname != SO_ALL)  \
  3.                break;          \
  4.        len += scnprintf(buf+len, *(int *)optlen - len, "%d\t%d\t%ld\t%d\n", \
  5.                level, OPT, (long)(val), (int)sizeof(val))
  6. #define STOP() if (optname == SO_ALL) { \
  7.                        *(int *)optlen = len; \
  8.                        return 0;       \
  9.                }

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

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

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

根据贵国法律法规和政策,部分文章内容未予显示。 powered by 滤霸

9 comments

  1. Kermit says:

    怎一个幸福了得啊……

    [Reply]

  2. kongove says:

    实验室rhel(Linux XYLinux 2.6.18-128.el5xen #1 SMP Wed Dec 17 12:22:24 EST 2008 i686 i686 i386 GNU/Linux)上怎么连fdinfo文件夹都没有

    [Reply]

  3. lovecreatesbeauty says:

    > http://wangcong.org/down/chapter2-beta.pdf
    > #include
    > #include
    > int main(X)
    > {exit(0 > puts((*(char *)&X == (char)X)?"Little
    > endian":"Big endian"));}

    the signature of your main function is wrong.
    read c-faq.com and correct the whole things yourself.

    [Reply]

    王 聪 reply on July 21, 2009 11:33 pm:

    that is a trick which you are not expected to understand.

    [Reply]

    lovecreatesbeauty@gmail.c0m reply on July 24, 2009 4:45 pm:

    do you mean this kind of stuff

    http://www.grex.org/~jhl/endiantest_cn.html

    Q: 20.9 我如何确定一个机器的字节顺序是大端还是小端?
    --------------------------------------------------------------
    A: 通常的技巧是使用一个指针:
    int x = 1;
    if(*(char *)&x == 1)
    printf("little-endian\n");
    else printf("big-endian\n");

    [Reply]

    王 聪 reply on July 27, 2009 9:21 pm:

    OBVIOUSLY NO.

    lovecreatesbeauty@gmail.c0m reply on July 24, 2009 5:30 pm:

    there're 73 main entry points in linux-2.6.30.2.tar.bz2. there's no one like your int main(X). trick aha.

    [Reply]

    王 聪 reply on July 27, 2009 9:21 pm:

    What makes your stupid brain think that Linux kernel should have?

Leave a Reply

葡驻京办ICP备07006283号