SystemTap 是监控和跟踪运行中的linux 内核的操作的动态方法,SystemTap 应用:对管理员,SystemTap可用于监控系统性能,找出系统瓶颈,而对于开发者,可以查看他们的程序运行时在linux系统内核内部的运行情况,下面我们来看看systemtap监控应用与碰到的问题分析。

应用场景:一天,在我们服务器上php代码路径下多了一个log文件,从没注意到有这个log文件,但是log文件的格式明显不是我们生成的,格式比较简单,甚至没有function name,log level,明显是我们使用的某个第三方库的输出,到底是那个进程调用第三方库干的坏事?我们当然是有怀疑对象的,从log的语义也可以初步判断是那个进程干的这件事,可是没有证据.

有的童鞋就说了,对这个可疑进程直接执行lsof -p pid或者对文件执行 lsof file不就OK 了,如果这个进程打开了这个莫名其妙的文件,就证明的确是可疑进程写了这个log文件,可惜的是这个进程不是daemon,而且执行时间特别短,来不及对他进行lsof.

这有到了我们systemtap横空出世的时候了,systemtap由于他的可定制,几乎是一把无所不能的瑞士军刀,第一思路就是监控sys_open,看下到底是那个进程在作死,打开了这个莫名其妙的文件.

方法一:监控sys_open

我们都知道systemtap可以监控系统调用,open作为一个系统调用,我们自然可以监控,如果open的文件恰好是我们要追踪的文件,我们就将pid,execname 打印出来,真相大白,代码如下:

  1. function is_open_creating:long (flag:long)
  2. {
  3. CREAT_FLAG = 4 // 0x4 = 00000100b
  4. if (flag & CREAT_FLAG)
  5. {
  6. return 1
  7. }
  8. return 0
  9. }
  10. probe begin
  11. {
  12. printf("monitor file beginn")
  13. }
  14. probe kernel.function("sys_open")
  15. {
  16. if(user_string($filename)== "/home/manu/shell/temp/abc.log")
  17. {
  18. creating = is_open_creating($mode);
  19. if(creating)
  20. {
  21. printf("pid %ld (%s) create the file %sn",pid(),execname(),user_string($filename));
  22. }
  23. else
  24. {
  25. printf("pid %ld (%s) open the file %s n",pid(),execname(),user_string($filename));
  26. }
  27. }
  28. }

OK,我们开始监控,看看能否捕捉到捣乱者,代码如下:

  1. root@manu:~/code/systemtap#
  2. root@manu:~/code/systemtap# stap file_monitor.stp
  3. monitor file begin

我们在另一个终端l中echo创建这个/home/manu/shell/temp/abc.log,代码如下:

root@manu:~/code/shell/temp# echo abefdf >/home/manu/code/shell/temp/abc.log

root@manu:~/code/shell/temp#

我们看到stap捕捉到了这个事件,代码如下:

  1. root@manu:~/code/systemtap# stap file_monitor.stp
  2. monitor file begin
  3. pid 3024 (bash) create the file /home/manu/code/shell/temp/abc.log

Stap捕捉到进程名为bash,PID为3024的进程create了这个文件,目前为止,一切都好,可惜这种方法有个致命的缺陷。filename是进程调用系统调用 open时 输入的文件名,可能输入全路径/home/manu/shell/temp/abc.log,也可能输入的是相对路径,如果输入的是相对路径,我们的stap不能捕捉到这个事件.

比如我们再次想abc.log追加写:

  1. root@manu:~/code/shell/temp# echo "second line " >> abc.log
  2. root@manu:~/code/shell/temp# cat abc.log
  3. abefdf
  4. second line
  5. root@manu:~/code/shell/temp#

另一端没有stap没有检测到任何事件.

这种方法有缺陷,因为我们不能够假设进程输入的绝对路径还是相对路径.

方法二:监控文件的inode

文件的名字表示方法可能不同,比如当前路径是 /home/manu/shell/temp/,下面表示的都是同一个文件,这就给上面一种方法带来的困难.

  1. abc.log
  2. ./abc.log
  3. ../temp/abc.log
  4. /home/manu/shell/temp/abc.log
  5. …..

如果我们的文件在磁盘上,那么只要有,主设备号,次设备好,inode,这三个元素,就唯一确定了一个文件,我们还是监控刚才的abc.log,对于我的文件在/dev/sda6,对应的主设备号和次设备号是,0x8,0x6,abc.log对应的inode为:

361way:/opt # ll -ali abc.log

2099351 -rwxr-xr-x 1 root root 17623 Sep  2 22:55 abc.log

我们的三元组是(0x08,0x06,2099351),下面是我们的监控脚本inode_monitor.stp,代码如下:

  1. probe begin
  2. {
  3. printf("watch inode %d %d %ld beginn",$1,$2,$3)
  4. }
  5. probe vfs.write
  6. {
  7. if (dev == MKDEV($1,$2) # major/minor device
  8. && ino == $3)
  9. printf ("%s(%d) %s 0x%x/%un",execname(), pid(), probefunc(), dev, ino)
  10. }  //phpfensi.com

然后我们让stap来监控这个inode对应的文件,代码如下:

root@manu:~/code/systemtap# stap inode_monitor.stp 0x8 0x6 2099351

watch inode 8 6 2099351 begin

开始我们的实验,我们在shell终端上echo两句写入abc.log,在写一个test.sh脚本去写这个abc.log,实验如下:

  1. root@manu:~/code/shell/temp# echo abefdf >abc.log
  2. root@manu:~/code/shell/temp# echo "second line" > ./abc.log
  3. root@manu:~/code/shell/temp# cat test.sh
  4. #!/bin/sh
  5. echo "third line " >> ./abc.log
  6. root@manu:~/code/shell/temp# ./test.sh

stap监控脚本的输出如下:

  1. root@manu:~/code/systemtap# stap inode_monitor.stp 0x8 0x6 2099351
  2. watch inode 8 6 2099351 begin
  3. bash(3024) vfs_write 0x800006/2099351
  4. bash(3024) vfs_write 0x800006/2099351
  5. test.sh(9484) vfs_write 0x800006/2099351

我们看到这三个事件都被捕捉到了,也就完成了我们监控这个文件,判断到底是那个进程写入这个log的目标.

systemtap作为一个动态监控和跟踪linux内核的工具,其功能还可以发掘更多,更多内容可以查看IBM社区或systemtap官方网站,同时也可以了解DTrace、ProbeVue,这两者在unix平台上,及fanotify,下一代的inotify文件监控,同类工具.

其他性能工具OProfile、Valgrind、Perf、 redhat MGR 等回头再总结学习.

systemtap [主设备号,次设备好,inode]监控文件的更多相关文章

  1. [ARM-Linux开发] 主设备号--驱动模块与设备节点联系的纽带

    一.如何对设备操作 linux中对设备进行操作是通过文件的方式进行的,包括open.read.write.对于设备文件,一般称其为设备节点,节点有一个属性是设备号(主设备号.次设备号),其中主设备号将 ...

  2. linux设备管理之主设备号与次设备号

    主设备号和次设备号 一个字符设备或者块设备都有一个主设备号和次设备号.主设备号和次设备号统称为设备号.主设备号用来表示一个特定的驱动程序.次设备号用来表示使用该驱动程序的其他设备.(主设备号和控制这类 ...

  3. linux driver ------ platform模型,通过杂项设备(主设备号是10)注册设备节点

    注册完设备和驱动之后,就需要注册设备节点 Linux杂项设备出现的意义在于:有很多简单的外围字符设备,它们功能相对简单,一个设备占用一个主设备号对于内核资源来说太浪费.所以对于这些简单的字符设备它们共 ...

  4. alloc_chrdev_region申请一个动态主设备号,并申请一系列次设备号

    ret = alloc_chrdev_region(&ndev, 0, 1, "chr_dev"); //分配设备号 alloc_chrdev_region申请一个动态主设 ...

  5. Linux:主设备号和次设备号

    http://www.linuxidc.com/Linux/2011-03/33863.htm     Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备 ...

  6. Linux中如何通过设备号找到设备

    关于Linux中的设备文件,设备文件用来为操作系统和用户提供它们代表的设备接口.所有的Linux设备文件均位于/dev目录下,是根(/)文件系统的一个组成部分,因为这些设备文件在操作系统启动过程中必须 ...

  7. Linux中设备号及设备文件【转】

    本文转载自:http://blog.csdn.net/ymangu666/article/details/39292651 主.次设备号 应用程序可以通过对/dev 目录下的设备文件读写,从而访问实际 ...

  8. 通过某个进程号显示该进行打开的文件 lsof -p 1 11. 列出多个进程号对应的文件信息 lsof -p 123,456,789 5. 列出某个用户打开的文件信息 lsof -u username

    linux命令 — lsof 查看进程打开那些文件 或者 查看文件给那个进程使用 lsof命令是什么? 可以列出被进程所打开的文件的信息.被打开的文件可以是 1.普通的文件,2.目录  3.网络文件系 ...

  9. php使用inotify扩展监控文件或目录,如果发生改变,就执行指定命令

    通过inotify扩展监控文件或目录的变化,如果发生变化,就执行命令. 可以应用于 swoole 中,如果文件发生变化,就执行 kill -USR1 进程PID 来实现热更新. <?php cl ...

随机推荐

  1. Android Linux自带iptables配置IP访问规则

    利用Linux自带iptables配置IP访问规则,即可做到防火墙效果

  2. C# Winform开发框架企业版V4.0新特性

    企业版V4.0 - 新特性 C/S系统开发框架-企业版 V4.0 (Enterprise Edition) 简介: http://www.csframework.com/cs-framework-4. ...

  3. Python 基础-python环境变量、模块初识及字符类型

    (1).模块内置模块.第三方模块.自定义模块初识模块:sys \ os一般标准库存放路径 C:\Users\Administrator\AppData\Local\Programs\Python\Py ...

  4. Matlab绘图系列之高级绘图

    Matlab绘图系列之高级绘图 原帖地址: http://blog.163.com/enjoy_world/blog/static/115033832007865616218/ Matlab绘图 20 ...

  5. dyld: lazy symbol binding failed: Symbol not found: _objc_setProperty_nonatomic

    这个错误,一般在高版本设备里面不会出现,而在低版本会出现比如你的项目或者引入的静态库的Deployment Target设置成了ios6.0而你的测试设备是ios5.0甚至更低,就会出现如上错误.因为 ...

  6. 减少 WAF 漏报的 8 种方法 !

    近十年来,WAF 已经逐渐发展成熟,被软件行业接受并成为无数企业保护应用的不二选择.很多大型企业甚至相继亲自设计或通过并购涉足其中,在这个硕大的市场里逐鹿竞争,同时也推动了应用层防火墙的技术演进. 与 ...

  7. Bomb Game

    hdu3622:http://acm.hdu.edu.cn/showproblem.php?pid=3622 题意:你有n次,每次你可以在平面上放置一个点,并且每一次都会有两个位置可以选,每一次只能选 ...

  8. zoj 3841 Cards

    题意:给你52张牌,已知一个牌的序列,然后利用剩余的牌,能排成多少个序列,这个序列比已知的序列字典序小. 思路:从左到右尽可能放比已知序列相应位置小,找不到就放一样,然后求组合数就可以.多重集排列定理 ...

  9. 【POJ】2528 Mayor's posters

    离散化+线段树.数组开的不够大,wa了N多回. #include <iostream> #include <cstdio> #include <cstring> # ...

  10. 从 mian 函数开始一步一步分析 nginx 执行流程(三)

    如不做特殊说明,本博客所使用的 nginx 源码版本是 1.0.14,[] 中是代码所在的文件! 这一节我们分析ngx_start_worker_processes(),该函数代码比较少,因为它通过调 ...