一个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