谁动了我的文件 : 用systemtap监控

来源:互联网 发布:明教知乎 编辑:程序博客网 时间:2024/05/01 17:13

转载地址:http://blog.chinaunix.net/uid-24774106-id-3512909.html

  前些日子,我的同事Qing发现,在我们服务器上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

  1. root@manu:~/code/shell/temp# echo abefdf>/home/manu/code/shell/temp/abc.log
  2. 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为:


  我们的三元组是(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. }
  然后我们让stap来监控这个inode对应的文件

  1. root@manu:~/code/systemtap# stap inode_monitor.stp 0x8 0x6 2099351
  2. 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的目标。

   对于文件系统的监控,还有一个更好的神器,fanotify,这个宝贝专业,专门对付文件系统的监控,而且功能强大。有兴趣的筒子可以看下fanotify 监控文件系统,大牛刘明出品,讲的特别清楚,本来我想写一篇关于fanotify的博文,发现自己的功力还是不行,对这个主题理解不深,没有一个点能超越刘明前辈的博文,所以暂时告罢

参考文献
1 SystemTap:Instrumenting the Linux Kernel for Analyzing Performance and Functional Problems
2 SystemTap Beginners Guide
0 0
原创粉丝点击