tcp_keepalive_time and rst Flag in NAT Environment

Here, I'm not going to explain the details of what is TCP keepalive, what are the 3 related parameters tcp_keepalive_time, tcp_keepalive_intvl, tcp_keepalive_probes mean.
You need to know, the default value of these 3 parameters with net.ipv4.tcp_keepalive_time = 7200, net.ipv4.tcp_keepalive_intvl = 75, net.ipv4.tcp_keepalive_probes = 9, especially the first one, tcp_keepalive_time may and usually will cause some nasty behavior to you in some environment like NAT.

Let's say, your client now wants to connect to server, via one or more nat in the middle way, whatever SNAT or DNAT. The nat server, no matter its' a router or a Linux based device with ip_forward on, need to maintain a TCP connections mapping table to track each incoming and outcoming connection, since the device's resource is limited, the table can't grow as large as it wants, so it needs to drop some connections which are idle for a period of time with no data change between client and server.

This phenomenon is quite common, not only in consumer oriented/low end/poor implementation router, but also in data center NAT servers. For most of these NAT server, their tcp_keepalive_time is usually set to 90s or around, so, if your client set the parameter larger than 90, and have no data communications for more than 90s, the NAT server will send a TCP package with RST flags to disconnect the both end.

In this situation, one workaround is to lower the keepalive interval than that, like 30s, if you can't control the NAT server.

Recently, when we sync data from MongoDB Master/Slave, note, the architecture is a little old, not the standard replica. We often observe a large amount of errors indicating the failure of synchronisation during creating index process after finishing synchronizing the MongoDB data. Below log is get from our slave server:

Fri Nov 14 12:52:00.356 [replslave] Socket recv() errno:110 Connection timed out 100.80.1.26:27018
Fri Nov 14 12:52:00.356 [replslave] SocketException: remote: 100.80.1.26:27018 error: 9001 socket exception [RECV_ERROR] server [100.80.1.26:27018]
Fri Nov 14 12:52:00.356 [replslave] DBClientCursor::init call() failedFri Nov 14 12:52:00.356 [replslave] repl: AssertionException socket error for mapping query
Fri Nov 14 12:52:00.356 [replslave] Socket flush send() errno:104 Connection reset by peer 100.80.1.26:27018
Fri Nov 14 12:52:00.356 [replslave]   caught exception (socket exception [SEND_ERROR] for 100.80.1.26:27018) in destructor (~PiggyBackData)
Fri Nov 14 12:52:00.356 [replslave] repl: sleep 2 sec before next pass
Fri Nov 14 12:52:02.356 [replslave] repl: syncing from host:100.80.1.26:27018
Fri Nov 14 12:52:03.180 [replslave] An earlier initial clone of 'sso_production' did not complete, now resyncing.
Fri Nov 14 12:52:03.180 [replslave] resync: dropping database sso_production
Fri Nov 14 12:52:04.272 [replslave] resync: cloning database sso_production to get an initial copy

100.80.1.26 is DNAT IP address for MongoDB master. As you can see, the slave receives reset from 100.80.1.26.

After some package capture and analysis, we get the conclusion with the root cause of tcp_keepalive_time related. If you are sensitive, you may consider TCP stack related issues when see "reset by peer" keyword at first glance.

Be careful, the same issue also occurs in some IMAP proxy, IPVS envionment, etc.  After many years hands-on online operations experience, I have to say, DNS and NAT are two potential threats of various issues, even in some so-called 100% uptime environment.

通过 tcpcopy(pf_ring) 对 BCM 5719 小包做的多组 benchmark

tcpcopy 在文档化、用户参与方式方面有很大的提升空间这个问题在之前已经专门说过。最终,在我们自己阅读代码的情况下,结合 pf_ring,坚持跑通了整个流程,用其对目前 BCM 5719 型号的网卡做了多组对比,结论见结尾。
使用 tcpcopy 做 benchmark,务必确定 tcpcopy 语法使用的正确性, 尽管互联网上绝大多数的文档以及官方文档都写的含糊不清。
比如,我们之前把过滤条件 -F "tcp and dst port 80" 写成了 -F "tcp and src port 80",造成的结果是在错误的基础上得出了一些奇葩的数据以及无法解释的现象,比如到 target server 的流量特别小,并且及其的不稳定,得到的 pps 也是非常的不稳定大到 400kpps/s,小到 20k  甚至 0。

这里列举我们测试环境使用的一组配置。
所有机器都是 RedHat 6.2 2.6.32-279.el6.x86_64,Tcpcopy 1.0 版本,PF_RING 6.0.1,BCM 5719,双网卡 bonding。另外,我们单台生产机器的流量都比较大,并且绝大多数都是 100B 以下的小包,所以对系统的要求还是比较高的。
为了避免后续的误解,先确定几个用语:
1. online server(OS): 即我们线上生产环境的机器
2. target server(TS): 是我们想做 benchmark 的那台机器,以测试其究竟能支撑多大的量
3. assistant server(AS): 是安装了 intercept 的机器
4. mirror server(MS): 通过 tcpcopy 的 mirror 工具把 OS 的流量复制到该台机器上

我们一共做了三大组 benchmark,每组下面包含若干小的 benchmark,包括:
1. tcpcopy + intercept
2. tcpcopy + intercept + tcpcopy mirror,加一个 mirror 是为了减少对 OS 的负载,这样 tcpcopy 在 MS 上运行
3. tcpcopy + intercept + 交换机 mirror,更直接的方式复制线上流量,保证对 OS 没有干扰,并且能保证 100% 全量复制 OS 的流量

Continue reading

PF_RING 对网络抓包性能的提升不仅仅是 30% – 40%

pf_ring 由于涉及的东西比较多,最初看的时候可能会云里雾里,不过多看几遍官方文档应该就能大致理解含义了。
安装的步骤可以看这里。 我建议还是自己跑一遍,这样能熟悉每个零部件的作用。要是实在没空,也可以直接用官方提供的 rpm, deb 安装。
这里提示下,除了编译出来的 pf_ring.ko 之外,如果你的 NIC 不支持 PF_RING™-aware driver,那么只能使用 mode 0,如果支持的话,可以使用 mode 1 以及 mode 2,三者在我们的系统上 benchmark 下来差距并不大,不过加载了 pf_ring.ko 跟不加载 pf_ring.ko 的差距那真是天壤之别了。基本目前主流的 Intel、Broadcom 的都支持(igb, ixgbe, e1000e, tg3, bnx2),注意,tg3 目前(10/18/2014)最新的稳定版本 6.0.1 并没有,需要使用 nightly builds 版本,PF_RING_aware/non-ZC-drivers/broadcom/tg3-3.136h,PF_RING_aware/non-ZC-drivers/2.6.x/broadcom/tg3/tg3-3.102 .2.6.x 目录下面的都是已经废弃的版本,就不要使用了。

一般的应用也不大用到 pf_ring,不过如果是一些 IDS、snort 之类的系统,就派上用场了。我们的情况有点特殊,某条产品线由于前端的机器网卡比较弱(BCM5719),再加上发过来的绝大多数都是 75B 以下的小包,导致 rx_discards 以每秒数 k 的恐怖值增加。最初想抓包看看发过来的都是什么样结构的包,结果普通的 tcpdump 就完全没法用了,传统的 BPF(libpcap) 抓包相比简直是弱爆了。下面两张图,一张是通过 ntopng(也是使用的传统的 pcap)分析的包的大小,跟 iptraf 结果一致,一个只抓到了 2% 不到的包:-(


有需求就有动力了,后来研究了下 pf_ring,情况立马变好转了。看看下面两个对比就知道了。

加载了 pf_ring 的:
$ sudo /var/tmp/pfring/PF_RING-6.0.1/userland/tcpdump-4.1.1/tcpdump   -i bond1 -n -c 1000000 -w tmp
tcpdump: listening on bond1, link-type EN10MB (Ethernet), capture size 8192 bytes
1000000 packets captured
1000000 packets received by filter
0 packets dropped by kernel

使用传统 libpcap 抓包的:
$ sudo tcpdump   -i bond1 -n -c 1000000 -w tmp
tcpdump: listening on bond1, link-type EN10MB (Ethernet), capture size 65535 bytes
1000000 packets captured
1722968 packets received by filter
722784 packets dropped by kernel
12139 packets dropped by interface

所以说,pf_ring 对抓包的提升不仅仅是官方宣传的 30%-40% 的提升,更是一种技术对另外一种技术的革新,以及实际生产效率的大幅度提升。
另外,广告下 ntop.org 这个网站,上面有不少有意思的玩意儿,ntop, ntopng,再比如代替 OpenDPI 的 nDPI。我曾经玩过 OpenDPI,没几天官方就不更新了,这东西最重要的是实时的分析目前主流的协议,好在 nDPI 站在巨人肩膀上发扬光大了。提醒一下,这个也仅仅做娱乐只用,如果要实打实的,还是去买设备。

不要乱用 TCP ECN flag

前段时间处理了一个 case,现象很简单,同网络环境下的机器,绝大多数的机器都无法 curl 访问 example.com,仅有少部分的可以 curl 访问,并且他们的 mtr 的路径一模一样,机器的配置应该也有一样。
对比一下,可以访问的:
$ curl -IL "http://example.com:80/rest"
-v
* About to connect() to example.com port 80 (#0)
*   Trying example.com… connected
* Connected to example.com (example.com) port 80 (#0)
> HEAD /rest HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3
> zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: example.com
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx
Server: nginx
< Date: Fri, 24 Oct 2014 07:13:23 GMT
Date: Fri, 24 Oct 2014 07:13:23 GMT
< Content-Type: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
< Content-Length: 0
Content-Length: 0
< Connection: keep-alive
Connection: keep-alive
< s-rt: 2
s-rt: 2

<
* Connection #0 to host example.com left intact
* Closing connection #0

访问超时的:
curl -IL "http://example.com:80/rest" -v
* About to connect() to example.com port 80 (#0)
*   Trying example.com… Connection timed out
* couldn't connect to host
* Closing connection #0
curl: (7) couldn't connect to host

最初以为是 example.com(泛指) 的问题,后来联系了下我们的服务方,确认没有问题。当时想到一种可能是否是由于 SNAT 出口的 timestamps, tcp recycle 的时间戳问题引起的,后来确认了下,并不存在这个问题。BTW,要确认是不是 ts 的问题很简单,把客户端的 ts 给关闭再测试就知道是不是这个问题了。
直接抓包,惊奇的发现,根据经验,第一次的 TCP 连接,9bit 的 Flags 区域只应该有 SYN 标识位是被设置的,但是连不上的机器的 flags 竟然是 SYN, ECN, CWR 三个 bit 都被设置了。

看了下 wiki 对 ECN 的解释,以及 stackexchange 的实践,原因就很明显了,这条经过的 routing 上肯定有不支持 ECN 的 router,收到带有 ECN flag 的包之后就直接丢弃了,
可以访问的那部分机器由于 /proc/sys/net/ipv4/tcp_ecn 的默认值 2,可以接受带有 ECN 的包,但是不会主动发送,其余的机器由于明确的设置为了 1,这些包到从目的地返回源的过程中被中间 router 丢弃了。
2000 的统计显示,全球有 8% 的网络不可达跟 ECN 有关系。十多年过去了,理论上讲,应该有所改善。

最近半个月的工作[14P]

5 月发生的事,6 月补充完,9 月发出来 ;-)


5 月 13 日周二
开始我们另外一个核心 IDC 最后一次常规性 10G 升级,下面的一部分我们后来把他总结成了《5 月故障总结(post-mortem)》
回家睡了会儿,3:00 am 起床,4:00am 开始连续干了 6h
回公司休息了 1h,塞了点巧克力复活
中午去水立方进行了常规的 1h 训练
回来面(对了,我们目前招高级应用运维工程师 PE,有兴趣的给我简历,邮箱是 w 在 umeng 点 com)了一个候选人,结果在我问到第二个问题的时候就怂了,第一个问题是常规性的自我介绍,第二个问题也是我最喜欢问的问题之一,最近半个月在做什么
由于 uplink 依然在老的网络环境中,我们老的 3750X 到新的 Nexus 中间的 8G port channel 链路中的一条物理链路由于 LB 的算法不科学,导致其打满丢包的状态,当机立断,直接让 NE 更改了 LB 的算法,效果明显

5 月 14 日周三
由于 uplink 这个不稳定因素的存在,开会讨论最后一次也是最重要的升级以及收尾工作,由原本的周四凌晨升级提前到了周三凌晨进行
10G 的最后一次也是最重要的升级,应为涉及到切换我们的 uplink,迁移我们的 GW 以及我们两地双机房中间的互联链路迁移
晚上去和颐休息了 3h,凌晨 3 点干到早上 7 点,期间除了 uplink 切换成功之外,其他的均已失败回滚告终,回酒店休息了 3h
中午回公司继续,讨论了凌晨出现的一些问题以及解决方案,其中我们两地双机房互联链路不通的问题最后发现是 HSRP 的问题
凌晨 GW 迁移失败之后,我跟我们 ne, director 回公司模拟了一下当时出现问题的场景,想了几种可能的原因,不过都被实际的模拟结果所否定,唯一的可能性就是服务器会自动的更新 arp 表,找到新的 GW 地址
下班之前,上面遇到的所有问题都已经找到了问题的根源,想到了对策,唯独 GW 的问题,这个对我们整个生产环境的影响绝对是毁灭性的,一旦 GW 迁移失败,我们所有跨 VLAN 的访问都将失败,由于当时时间太紧迫,根本没有时间让我去 debug 就回滚了,我也就无法得知当时真正的现象以及后续的细节
临走之前,我们 director 问我要不要他过去帮忙,我当时是拍着胸脯说的「相信我,你回家休息吧」,虽然我当时有 95% 的把握确认了上面提到的迁移失败的原因以及 80% 左右的把握让我在非常短的时间内 debug 找到问题并且修复,其后者是最具有挑战性的

现在看到的我们的还是 1G 的上联,等你看到这篇博客的时候,应该已经升级到了 10G 的上联了

5 月 15 日周四
这次升级提前预留了充足的时间,从 3:30 – 6:00,我觉得 3h 的时间足够我 debug 一个中等难度的线上问题了
跟昨晚一样,先是回酒店休息了一下,凌晨 2 点开足马力一直干到了早上 8 点多,GW 的问题也在我们开始的第一步被我很快的发现了问题的原因并且修复,两地双机房互联 HSRP 的问题也后续被我们 ne 一举解决,「基本完美」收官,为什么这么说?因为后续的几天出现了若干的问题,好在都不是我们核心的 Nexus 引起的
回酒店休息到 11 点,打车回家准备继续休息,结果在车上就收到报警说我们的一台前端的 ngx 挂了,当时电话跟我们工程师沟通了下,看现象不大像是新升级的网络造成的,回家又花了 1h 时间救了把火,最后查明原因发现确实跟网络没有关系,只不过在这个敏感的时间点上,出现任何的问题,正常人都会不由得往网络上面倾斜
下午先赶到公司跟我们 director 沟通了进展的,然后赶到清华,在那儿度过了下午剩余的时间,干嘛的了?我花了 3h 的时间去拜拜 RMS 大神,花了 1h 的时间跑到教室外面的走廊插上了 3G 网卡排查了一起路由问题
RMS 大神确实蛮有意思的,下面这三段视频是我当时在现场拍的,虽然 RMS 说不要把这些视频照片传到 youtube, instgram 上,但我还是本着共享的精神跟大家分享了:

  1. Windows is malware
  2. Dancing during class break
  3. St. iGNUcius avatar

下午在会场收到反馈说,我们某个 storm cluster 的处理性能出现了问题,时间点跟我们升级网络的时间几乎吻合,但是从我们内网的各项监控指标来看,数值得到了前所未有的好转,pkg loss 由原来的 8% 直接变为了 0,latency 也由原来高峰时期动辄 4, 5ms 直接下降到了 0.2ms 以下,直觉告诉我几乎不可能是核心网络引起的,但是,没有更有力的数据来证明这些
看码农们在邮件里面以 「猜测」、「推脱」的姿态开始了问题的 debug 之后,我直接以「明天人齐了一起讨论下吧。」结束了这场闹剧
听完演讲之后本想回公司报个销就回去休息的,结果的结果,碰巧我们一个核心业务线上出现了很严重的性能问题,伴着麦当劳雪碧继续搞到了接近凌晨,没找到的问题原因,但是紧急扩容了一些机器,情况有所好转

两个出口的 ngx 都挂了


两个出口的流量一个跌没了一个直接爆了

Continue reading

Redhat & Ubuntu systemtap 安装及使用

原本以为是个比较简单的活儿,后来忙了一个晚上加半个白天差不多五六个小时的时间才搞定,主要时间都花在 Ubuntu 上了,归结起来是 Ubuntu 在商业化技术支持方面跟 Redhat 比还是有不少差距的。不管是哪个发行版本,默认都不会安装 debuginfo 的包,所以最重要的是搞定这几个包。
Redhat 的安装教程直接参照官方的说明
RedHat 默认的 Subscription 里面的 Base-Channel(Red Hat Enterprise Linux Server (v. 6 for 64-bit x86_64) 只包含 kernel-debuginfo-common 这个包,但是不包含 kernel-debuginfo 这个包,后来才发现在 Subscription 里面增加一个 RHEL Server Debuginfo (v.6 for x86_64) channel 就能找到后者了。当时没注意,于是 kernel-debuginfo-common 使用的是官方的 repo,而 kernel-debuginfo 则是用的是 CentOS 的 repo,理论上来说,应该没什么大区别,但是实践发现还是有问题的,比如 Build Date 不通,会导致 "build-id mismatch" 的问题:
# stap test.stp
ERROR: Build-id mismatch: "kernel" vs. "vmlinux" byte 0 (0x3d vs 0xfe) address
0xffffffff81508160 rc 0
Warning: /usr/bin/staprun exited with status: 1
Pass 5: run failed.  Try again with another '–vp 00001' option.

可以通过下面的方式验证:
# rpm -qif /boot/vmlinuz-2.6.32-279.el6.x86_64 /usr/lib/debug/lib/modules/2.6.32-279.el6.x86_64/vmlinux

或者:
# rpm -qi kernel-debuginfo-2.6.32-279.el6.x86_64
Name        : kernel-debuginfo             Relocations: (not relocatable)
Version     : 2.6.32                            Vendor: CentOS
Release     : 279.el6                       Build Date: Fri 22 Jun 2012
09:31:57 PM CST
Install Date: Wed 21 May 2014 01:26:13 AM CST      Build Host:
c6b9.bsys.dev.centos.org
Group       : Development/Debug             Source RPM:
kernel-2.6.32-279.el6.src.rpm
Size        : 1521941269                       License: GPLv2
Signature   : RSA/SHA1, Mon 25 Jun 2012 06:12:09 AM CST, Key ID
0946fca2c105b9de
Packager    : CentOS BuildSystem <http://bugs.centos.org>
URL         : http://www.kernel.org/
Summary     : Debug information for package kernel
Description :
This package provides debug information for package kernel.
This is required to use SystemTap with kernel-2.6.32-279.el6.x86_64.

# rpm -qi kernel-debuginfo-common-x86_64-2.6.32-279.el6.x86_64
Name        : kernel-debuginfo-common-x86_64  Relocations: (not relocatable)
Version     : 2.6.32                            Vendor: Red Hat, Inc.
Release     : 279.el6                       Build Date: Thu 14 Jun 2012
08:20:19 AM CST
Install Date: Wed 21 May 2014 12:34:47 AM CST      Build Host:
x86-008.build.bos.redhat.com
Group       : Development/Debug             Source RPM:
kernel-2.6.32-279.el6.src.rpm
Size        : 180674047                        License: GPLv2
Signature   : RSA/8, Thu 14 Jun 2012 08:49:26 AM CST, Key ID 199e2f91fd431d51
Packager    : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
URL         : http://www.kernel.org/
Summary     : Kernel source files used by kernel-debuginfo packages
Description :
This package is required by kernel-debuginfo subpackages.
It provides the kernel source files common to all builds.

总之,保证下面几个包的完全出自同一个 repo,对应的 $(uname -r) 一样就可以了。
kernel-2.6.32-279.el6.x86_64
kernel-debuginfo-common-x86_64-2.6.32-279.el6.x86_64
kernel-debuginfo-2.6.32-279.el6.x86_64

更新之后:
# rpm -qif /boot/vmlinuz-2.6.32-279.el6.x86_64 /usr/lib/debug/lib/modules/2.6.32-279.el6.x86_64/vmlinux
Name        : kernel                       Relocations: (not relocatable)
Version     : 2.6.32                            Vendor: Red Hat, Inc.
Release     : 279.el6                       Build Date: Thu 14 Jun 2012
08:20:19 AM CST
Install Date: Mon 25 Feb 2013 11:25:11 AM CST      Build Host:
x86-008.build.bos.redhat.com
Group       : System Environment/Kernel     Source RPM:
kernel-2.6.32-279.el6.src.rpm
Size        : 119491893                        License: GPLv2
Signature   : RSA/8, Thu 14 Jun 2012 08:44:50 AM CST, Key ID 199e2f91fd431d51
Packager    : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
URL         : http://www.kernel.org/
Summary     : The Linux kernel
Description :
The kernel package contains the Linux kernel (vmlinuz), the core of any
Linux operating system.  The kernel handles the basic functions
of the operating system: memory allocation, process allocation, device
input and output, etc.
Name        : kernel-debuginfo             Relocations: (not relocatable)
Version     : 2.6.32                            Vendor: Red Hat, Inc.
Release     : 279.el6                       Build Date: Thu 14 Jun 2012
08:20:19 AM CST
Install Date: Wed 21 May 2014 01:35:13 AM CST      Build Host:
x86-008.build.bos.redhat.com
Group       : Development/Debug             Source RPM:
kernel-2.6.32-279.el6.src.rpm
Size        : 1521941269                       License: GPLv2
Signature   : RSA/8, Thu 14 Jun 2012 08:48:56 AM CST, Key ID 199e2f91fd431d51
Packager    : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
URL         : http://www.kernel.org/
Summary     : Debug information for package kernel
Description :
This package provides debug information for package kernel.
This is required to use SystemTap with kernel-2.6.32-279.el6.x86_64.

然后通过默认的 repo,按部就班的安装 systemtap 就可以了。确认下 /lib/modules/2.6.34.7/build 是 ln 到 /usr/src/kernels/2.6.32-279.el6.x86_64/。

Ubuntu 的可以参照这篇文档来做,对于 10.04 2.6.32-38-server 的机器来说,依然还是可行的。
添加 repo,安装对应的 linux-image-$(uname -r)-dbgsym:
codename=$(lsb_release -c | awk  '{print $2}')
sudo tee /etc/apt/sources.list.d/ddebs.list << EOF
deb http://ddebs.ubuntu.com/ ${codename}      main restricted universe multiverse
deb http://ddebs.ubuntu.com/ ${codename}-security main restricted universe multiverse
deb http://ddebs.ubuntu.com/ ${codename}-updates  main restricted universe multiverse
deb http://ddebs.ubuntu.com/ ${codename}-proposed main restricted universe multiverse
EOF

sudo apt-key adv –keyserver keyserver.ubuntu.com –recv-keys ECDCAD72428D7C01
sudo apt-get update
sudo apt-get install linux-image-$(uname -r)-dbgsym

不过当一切都安装好了之后,发现 kernel 的版本号并不是真正对应的,默认机器跑的是 2.6.32-38.85,新安装的 debuginfo 是 2.6.32-38.83:
root@unode10-plog-db1:~# dpkg -l | grep linux-image
ii  linux-image-2.6.32-38-server        2.6.32-38.85                                      Linux kernel image for version 2.6.32 on x86
ii  linux-image-2.6.32-38-server-dbgsym 2.6.32-38.83                                      Linux kernel debug image for version 2.6.32

所以把 linux-image 也换了,直接跟 2.6.32-38.83 统一,ftp.ubuntu.com 上找到对应的 linux-image-2.6.32-38-server_2.6.32-38.83_amd64.deb,dpkg 安装就好了。

安装只是个开始,用来发现诊断问题才是真正开始把工具给利用起来。Dtrace 的作者 Brendan 11 年的时候写了篇使用心得,撇开一些主观的情绪因素,上面遇到的一些问题还是值得参考的。
Systemtap 的使用可以参考官方的两篇文档,一篇入门,一篇相当于 manual,其实这些都能直接 man 到。

然后就是根据需求 google 各种 stp 脚本了,跑出来的结果如果不熟悉 kernel function & syscall 的话,需要花些时间理解下,否则没法分析问题了。
如果需要在 production 机器上做,直接安装 systemtap-runtime,在同等配置的机器上把 ko 文件做好丢到 production 上跑就好了。后来偶然的机会发现了一篇不错的中文安装文档