2.3. 运行SystemTap脚本

SystemTap包含了许多用于监控系统活动的命令行工具。stap命令从SystemTap脚本中读取探测指令,把它们转化为C代码,构建一个内核模块,并加载到当前的Linux内核中。staprun命令会运行SystemTap检测模块,比如SystemTap通过交叉检测创建的内核模块。

运行stapstaprun需要较高的系统权限。由于不是每个运行SystemTap的用户都可以被授予root权限,对于那些没有权限的用户,你可以把他们的帐号加入到下面的用户组中:

  1. stapdev 该组内的成员可以使用stap运行SystemTap脚本,或staprun运行SystemTap检测模块。 运行stap命令包括把SystemTap脚本编译成内核模块并加载进内核。这一操作需要较高的系统访问权限。所以stapdev用户组下的成员会拥有较高的权限。不幸的是,这也意味着他们可以做到许多只有root用户才能做到的事。所以,你应该只把那些原可以拥有root权限的用户加到这个用户组中。

  2. stapusr 该组内的成员仅能使用staprun命令来运行SystemTap检测模块。另外,他们也只能在/lib/modules/kernel_version/systemtap/文件夹下运行模块。注意这个文件夹必须仅由root用户所拥有,而且仅对root用户可写。

stap命令从文件或标准输入中读取SystemTap脚本。要想让stap从文件中读取SystemTap脚本,需要在命令行中指定文件名:

  1. stap file_name

要想让stap从标准输入中读取SystemTap脚本,需要用-换掉文件名。记得把用到的命令行选项挪到-之前。举个例子,要让stap输出更多的运行信息,输入:

  1. echo "probe timer.s(1) {exit()}" | stap -v -

下面列出常用的stap命令行选项:

-v 让SystemTap会话输出更加详细的信息。你可以重复该选项多次来提高执行信息的详尽程度,举个例子:

  1. stap -vvv script.stp

当你的脚本在运行时发生了错误,可以加下这个选项查看更详细的输出信息。关于SystemTap错误信息的更多内容,请参考第6章,“解读错误信息”

-o file_name 将标准输出重定向到file_name

-S size[,count] 将输出文件的最大大小限制成sizeMB,存储文件的最大数目为count。这个命令实现了logrotate的功能,每个输出文件会以序列号作为后缀。(译注:logrotate会把日志切割成xxx.1, xxx.2, xxx.3的形式。每当一个日志文件达到最大大小时,新开一个日志文件。当日志文件数达到最大数目时,旧的日志文件会被删掉。)

-x process_id 设置SystemTap处理函数target()为指定PID。关于target()的更多信息,请参考SystemTap函数列表

-c ‘command’ 运行command,并在command结束时退出。该选项同时会把target()设置成command运行时的PID

-e ‘code’ 直接执行给定的code。(译注:如stap -v -e 'probe vfs.read {printf("read performed\n"); exit()}'

-F 进入SystemTap的飞行记录仪模式(flight recorder mode),并在后台运行该脚本。关于的更多信息,请参考下面的“飞行记录仪模式”。

关于stap的更多信息,请参考stap(1) man page。关于staprun和交叉检测的更多信息,请参考第2.2节“为其它计算机生成检测模块”,或staprun(8) man page。

飞行记录仪模式

SystemTap的飞行记录仪模式允许你长时间运行一个SystemTap脚本,并关注最新的输出。飞行记录仪模式会限制输出的生成量。

飞行记录仪模式还可以分成两种:内存型(in-memory)和文件型(file)。无论是哪一种,SystemTap脚本都是作为后台进程运行。

内存型飞行记录仪模式

当飞行记录仪模式(-F)没有跟输出文件选项(-o)一起使用时,SystemTap会把脚本输出结果存储在内核内存的缓冲区内。一旦SystemTap检测模块被加载并开始探测,检测过程会分离到后台运行。当感兴趣的事件发生后,你可以重新载入检测过程来查看内存缓冲区中最近的输出和之后的输出。

要想在内存型飞行记录仪模式下运行SystemTap,带-F选项运行stap命令:

  1. stap -F iotime.stp

一旦脚本启动了,stap会输出类似于如下的信息,告诉你怎么重新连接运行的脚本:

  1. Disconnecting from systemtap module.
  2. To reconnect, type "staprun -A stap_5dd0073edcb1f13f7565d8c343063e68_19556"

当感兴趣的事件发生后,运行对应的命令来连接当前运行的脚本,输出内存缓冲区中的最近的数据,并获取之后的输出:

  1. staprun -A stap_5dd0073edcb1f13f7565d8c343063e68_19556

默认情况下,缓冲区大小为1MB.你可以使用-s来调整这个值(单位是MB,会向2的幂取整)。举个例子,-s2将指定缓冲区大小为2MB.

flight_record_mode_in_memory

文件型飞行记录仪模式

在飞行记录仪模式下,你也可以把输出存储在文件中。你可以通过-o选项指定文件名,还可以通过-S选项来控制输出文件的大小和数目。

下面的命令会以文件型飞行记录仪模式启动SystemTap,输出到/tmp/iotime.log.[0-9]+,每个文件不超过1MB,保留最新的两个文件:

  1. stap -F -o /tmp/pfaults.log -S 1,2 pfaults.stp

这个命令会把PID输出到标准输出。稍候片刻,给这个进程发个SIGTERM终止它的运行:

  1. kill -s SIGTERM 7590

在这个例子里,仅仅有最新的两个文件被保留下来:其余的旧文件都被SystemTap移除了。使用ls -sh /tmp/pfaults.log.*验证下:

  1. 1020K /tmp/pfaults.log.5 44K /tmp/pfaults.log.6

要想查看最新数据,读取序号最大的输出文件,在这里指的是/tmp/pfaults.log.6