安庆

导航

ss 显示unix 域 的socket 缓冲区不正确

一个unix 域socket,平时我们用ss -auxp 来查看是否有数据在内核没有到用户态,

[root@localhost unix]#  ss -auxp |grep -i server.o
u_str  LISTEN     0      20     server.socket 59714016              * 0                     users:(("server.o",pid=45578,fd=7))
u_str  ESTAB      0      0       * 59169156              * 59169157              users:(("server.o",pid=45578,fd=3),("gdb",pid=45482,fd=3))
u_str  ESTAB      0      0       * 59169157              * 59169156              users:(("server.o",pid=45578,fd=4),("gdb",pid=45482,fd=4))
u_str  ESTAB      **9**      0      server.socket 59714017              * 59682769              users:(("server.o",pid=45578,fd=8))

比如最后一行的9,就说明有9个字节的数据还在内核中,没有recv。

那么,当看到为0的时候,是不是说明一定不在内核中呢?答案是否定的。

同样的环境,我们将unix_diag模块卸载掉,然后重新读取,发现还是能看到 :

[root@localhost /]# lsmod |grep unix
unix_diag              12601  0

[root@localhost unix]# rmmod unix_diag
[root@localhost unix]#
[root@localhost unix]#
[root@localhost unix]# lsmod |grep unix_diag

然后卸载之后,再用ss去查看一下,发现输出没有变化:

[root@localhost unix]#  ss -auxp |grep -i server.o
u_str  LISTEN     0      20     server.socket 59714016              * 0                     users:(("server.o",pid=45578,fd=7))
u_str  ESTAB      0      0       * 59169156              * 59169157              users:(("server.o",pid=45578,fd=3),("gdb",pid=45482,fd=3))
u_str  ESTAB      0      0       * 59169157              * 59169156              users:(("server.o",pid=45578,fd=4),("gdb",pid=45482,fd=4))
u_str  ESTAB      **9**     0      server.socket 59714017              * 59682769              users:(("server.o",pid=45578,fd=8))

这个时候查看一下模块,发现又被加载进去了,

[root@localhost /]# lsmod |grep unix
unix_diag              12601  0

原来ss会去加载对应的 unix_diag模块。

我们将 mv unix_diag.ko.xz unix_diag.ko.xz_bak ,改名,然后再次获取:

[root@localhost unix]# ss -auxp |grep -i server.o
u_str  ESTAB      0      0       * 59169156              * 0                     users:(("server.o",pid=45578,fd=3),("gdb",pid=45482,fd=3))
u_str  ESTAB      0      0       * 59169157              * 0                     users:(("server.o",pid=45578,fd=4),("gdb",pid=45482,fd=4))
u_str  LISTEN     0      0      server.socket 59714016              * 0                     users:(("server.o",pid=45578,fd=7))
u_str  ESTAB      **0**      0      server.socket 59714017              * 0                     users:(("server.o",pid=45578,fd=8))

发现读不到数据了,最后一行从9 变成了0.

因为unix域的数据在ss中展示,需要读取:

sk_diag_show_rqlen 这个函数,而如果没有加载 unix_diag,则会默认显示为0.

对于大量使用unix域通信的os,建议默认开启: CONFIG_UNIX_DIAG

posted on 2021-10-09 10:45  _备忘录  阅读(297)  评论(0编辑  收藏  举报