Systemtap PROCFS probes

3 minute read

背景

systemtap 虚拟文件交互探针, 在/proc/systemtap/MODNAME目录下对指定文件读写时触发.

These probe points allow procfs pseudo-files in /proc/systemtap/MODNAME to be created, read and written. Specify the name of the systemtap module as MODNAME. There are four probe point variants supported by the translator:  
  
  
procfs("PATH").read  
procfs("PATH").write  
procfs.read  
procfs.write  
  
  
PATH is the file name to be created, relative to /proc/systemtap/MODNAME. If no PATH is specified (as in the last two variants in the previous list), PATH defaults to "command".  
  
When a user reads /proc/systemtap/MODNAME/PATH, the corresponding procfs read probe is triggered. Assign the string data to be read to a variable named $value, as follows:  
  
procfs("PATH").read { $value = "100\n" }  
When a user writes into /proc/systemtap/MODNAME/PATH, the corresponding procfs write probe is triggered. The data the user wrote is available in the string variable named $value, as follows:  
  
procfs("PATH").write { printf("User wrote: %s", $value) }  

MODNAME不固定, 随机生成, PATH指文件名, PATH不指定的话默认名为command.

例如 :

以下探针在用户读取command时, 内容为$value指定的”abc\n”

[root@db-172-16-3-39 ~]# stap --vp 05 -e 'probe procfs.read { $value = "abc\n"; }'  
Eliding side-effect-free singleton block operator '{' at <input>:1:19  
Pass 2: analyzed script: 1 probe(s), 1 function(s), 1 embed(s), 0 global(s) using 147764virt/24452res/3256shr/22360data kb, in 10usr/0sys/6real ms.  

stap执行后, 自动创建MODNAME, 如下 :

[root@db-172-16-3-39 ~]# lsmod|grep stap  
stap_c8e98652dbf72a846df6f69d72aa98de_1058    74144  2  

进入/proc/systemtap/stap_c8e98652dbf72a846df6f69d72aa98de_1058/目录, 可以看到名为command的文件.

[root@db-172-16-3-39 ~]# cd /proc/systemtap/stap_c8e98652dbf72a846df6f69d72aa98de_1058/  
[root@db-172-16-3-39 stap_c8e98652dbf72a846df6f69d72aa98de_1058]# ll  
total 0  
-r-------- 1 root root 0 Oct  6 08:06 command  

用户读取这个文件时, 探针触发, 并输出给用户$value值abc\n.

[root@db-172-16-3-39 stap_c8e98652dbf72a846df6f69d72aa98de_1058]# cat command   
abc  

PATH命名探针举例 :

[root@db-172-16-3-39 ~]# stap --vp 05 -e 'probe procfs("digoal").read { $value = "abc\n"; }'  
Eliding side-effect-free singleton block operator '{' at <input>:1:29  
Pass 2: analyzed script: 1 probe(s), 1 function(s), 1 embed(s), 0 global(s) using 148284virt/24444res/3256shr/22880data kb, in 10usr/0sys/6real ms.  
  
[root@db-172-16-3-39 ~]# cd /proc/systemtap/stap_c6373a2dc49ccd7f60f51cb02d421026_1078/  
[root@db-172-16-3-39 stap_c6373a2dc49ccd7f60f51cb02d421026_1078]# ll  
total 0  
-r-------- 1 root root 0 Oct  6 08:06 digoal  
[root@db-172-16-3-39 stap_c6373a2dc49ccd7f60f51cb02d421026_1078]# cat digoal   
abc  

写探针举例, 当用户写文件时, 在探针的handler中可以通过$value读取到用户往文件写入的值.

[root@db-172-16-3-39 ~]# stap --vp 05 -e 'probe procfs("digoal").write { printf("%s", $value) }'  
Eliding side-effect-free singleton block operator '{' at <input>:1:30  
Pass 2: analyzed script: 1 probe(s), 1 function(s), 1 embed(s), 0 global(s) using 147320virt/24428res/3248shr/21916data kb, in 10usr/0sys/6real ms.  

往虚拟文件中写入两行 :

[root@db-172-16-3-39 ~]# cd /proc/systemtap/stap_96658768b416c658023814c8d71d4eb9_1098/  
[root@db-172-16-3-39 stap_96658768b416c658023814c8d71d4eb9_1098]# echo -e "Hello, I'm digoal\nWho are you?\n" > ./digoal  

执行完以上写入后, 探针的handler, printf(“%s”, $value)输出了用户使用echo -e “Hello, I’m digoal\nWho are you?\n” > ./digoal写入的值.

Pass 2: analyzed script: 1 probe(s), 1 function(s), 1 embed(s), 0 global(s) using 147320virt/24428res/3248shr/21916data kb, in 10usr/0sys/6real ms.  
Hello, I'm digoal  
Who are you?  

读写探针举例 :

[root@db-172-16-3-39 ~]# stap --vp 05 -e 'probe procfs("digoal").read { $value = "abc\n"; } probe procfs("digoal").write { printf("%s", $value) }'  
Eliding side-effect-free singleton block operator '{' at <input>:1:29  
Eliding side-effect-free singleton block operator '{' at <input>:1:80  
Pass 2: analyzed script: 2 probe(s), 2 function(s), 1 embed(s), 0 global(s) using 147328virt/24460res/3264shr/21924data kb, in 0usr/0sys/6real ms.  
  
[root@db-172-16-3-39 systemtap]# lsmod|grep stap  
stap_b8c49f4eed3186e72a6dc47a0ffe4c8b_1410    76320  2   
[root@db-172-16-3-39 systemtap]# cd /proc/systemtap/stap_b8c49f4eed3186e72a6dc47a0ffe4c8b_1410/  
[root@db-172-16-3-39 stap_b8c49f4eed3186e72a6dc47a0ffe4c8b_1410]# ll  
total 0  
-rw------- 1 root root 0 Oct  6 08:12 digoal  
[root@db-172-16-3-39 stap_b8c49f4eed3186e72a6dc47a0ffe4c8b_1410]# cat digoal   
abc  
[root@db-172-16-3-39 stap_b8c49f4eed3186e72a6dc47a0ffe4c8b_1410]# echo -e "Hello, I'm digoal\nWho are you?\n" > ./digoal  
  
Pass 2: analyzed script: 2 probe(s), 2 function(s), 1 embed(s), 0 global(s) using 147324virt/24456res/3264shr/21920data kb, in 0usr/0sys/6real ms.  
Hello, I'm digoal  
Who are you?  

最后, 使用procfs探针注意, 如果用户未退出虚拟文件系统目录, 例如/proc/systemtap/stap_96658768b416c658023814c8d71d4eb9_1098/, 那么在探针结束时,如 Ctrl+C, 不能及时收回mod. 对于这种情况可以退出改目录, 使用rmmod删除对应的mod.

[root@db-172-16-3-39 ~]# stap --vp 05 -e 'probe procfs.read { $value = "abc\n"; }'  
Eliding side-effect-free singleton block operator '{' at <input>:1:19  
Pass 2: analyzed script: 1 probe(s), 1 function(s), 1 embed(s), 0 global(s) using 148280virt/24432res/3256shr/22876data kb, in 10usr/0sys/6real ms.  
Error inserting module '/tmp/stapLYrleG/stap_c8e98652dbf72a846df6f69d72aa98de_1058.ko': File exists  
WARNING: /usr/bin/staprun exited with status: 1  
Pass 5: run failed.  Try again with another '--vp 00001' option.  
  
[root@db-172-16-3-39 ~]# lsmod|grep stap  
Module                  Size  Used by  
stap_a8bfea9ea582644b887b62bb4323e296_1370    76192  1   
stap_c8e98652dbf72a846df6f69d72aa98de_1058    74144  0   
  
[root@db-172-16-3-39 ~]# rmmod stap_c8e98652dbf72a846df6f69d72aa98de_1058  
[root@db-172-16-3-39 ~]# rmmod stap_a8bfea9ea582644b887b62bb4323e296_1370  
ERROR: Module stap_a8bfea9ea582644b887b62bb4323e296_1370 is in use  
[root@db-172-16-3-39 ~]# lsmod|grep stap  
stap_a8bfea9ea582644b887b62bb4323e296_1370    76192  0   
  
[root@db-172-16-3-39 stap_a8bfea9ea582644b887b62bb4323e296_1370]# cd  
  
[root@db-172-16-3-39 ~]# rmmod stap_a8bfea9ea582644b887b62bb4323e296_1370  

参考

1. https://sourceware.org/systemtap/langref/Probe_points.html#SECTION00056000000000000000

2. man lsmod, rmmod, modinfo

Flag Counter

digoal’s 大量PostgreSQL文章入口