systemtap专家模式oneshot统计TCP半连接数量

大约不到两周前,我写了一个内核模块统计了TCP当前的半连接数量:
https://blog.csdn.net/dog250/article/details/105013772
该实现采用了扫描每一个Listener的方式,从而替代了扫描所有的连接再过滤的方式,以 O ( 1 ) O(1) O(1)复杂度替代了 O ( n ) O(n) O(n)复杂度。

随后,我又换了一种方式可以实时查看当前的半连接计数值:
https://blog.csdn.net/dog250/article/details/105022347

再之后,一发不可收拾,开始了二进制hook手艺之旅。

回到最开始的扫描每一个Listener的方法,虽然OK,但是需要维护一个procfs的文件,以提供数据的读取,若要支持半连接统计功能,一个内核模块就必须一直处在载入状态。

能不能改成oneshot模式呢?即输出完数值,模块即卸载。

其实很容易,直接在模块的init函数里进行计算,然后输出值后,将init函数return -1即可。但这又是逆经理…这不优雅。

这里采用了stap的Guru专家模式,oneshot输出数值到控制台后,即退出。代码如下:

// dump_halfconn_num.stp
%{
     
#include 
#include 
%}

function dump_halfconn_num:long()
%{
     
	unsigned int num = 0;
	int i;
	struct inet_hashinfo *hashinfo = &tcp_hashinfo;

	for (i = 0; i < INET_LHTABLE_SIZE; i++) {
     
		struct sock *sk;
		struct hlist_nulls_node *node;
		struct inet_listen_hashbucket *ilb;

		ilb = &hashinfo->listening_hash[i];
		spin_lock_bh(&ilb->lock);
		sk_nulls_for_each(sk, node, &ilb->head) {
     
			struct inet_connection_sock *icsk = inet_csk(sk);
			struct listen_sock *lopt;

			read_lock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
			lopt = icsk->icsk_accept_queue.listen_opt;
			if (lopt && lopt->qlen)
				num += lopt->qlen;
			read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
		}
		spin_unlock_bh(&ilb->lock);
	}

	STAP_PRINTF("系统中当前的半连接数量为:%d\n", num);

	STAP_RETVALUE = 0;
%}

probe begin
{
     
	dump_halfconn_num();
	exit(); // oneshot模式,dump完直接退出!
}

使用方法非常简单:

[root@localhost test]# stap -g ./dump_halfconn_num.stp
302
[root@localhost test]#

当然了,这是因为经理今天穿了皮鞋,而且还露着白袜子。


浙江温州皮鞋湿,下雨进水不会胖。

你可能感兴趣的:(TCP半连接统计,systemtap专家模式)