systemtap监控磁盘操作

       怎么在linux系统下面找到,对磁盘操作最多的进程,systemtap自带的例子disktop.stp,就能实现这个功能,在doc/systemtap/examples/io目录里面,运行一下看看stap -v disktop.stp,显示如下       

       由上图可以看出最繁忙的进程和磁盘了,贴一下代码,------后面为我写的备注

 

# Copyright (C) 2007 Oracle Corp.

#

# Get the status of reading/writing disk every 5 seconds,

# output top ten entries 

#

# This is free software,GNU General Public License (GPL);

# either version 2, or (at your option) any later version.

#

# Usage:

#  ./disktop.stp

#

 

global io_stat,device

global read_bytes,write_bytes

 

probe vfs.read.return {

  if ($return>0) { ----vfs_read返回的为读取的字节书,这边表示读取的字节书大于0

    if (devname!="N/A") {/*skip read from cache*/

      io_stat[pid(),execname(),uid(),ppid(),"R"] += $return  -----累计每个进程读取的字节数

      device[pid(),execname(),uid(),ppid(),"R"] = devname

      read_bytes += $return    ------总的读取字节数

    }

  }

}

 

probe vfs.write.return {

  if ($return>0) {  

    if (devname!="N/A") { /*skip update cache*/

      io_stat[pid(),execname(),uid(),ppid(),"W"] += $return

      device[pid(),execname(),uid(),ppid(),"W"] = devname

      write_bytes += $return

    }

  }

}

 

probe timer.ms(5000) {  ----每5000ms操作一次

  /* skip non-read/write disk */

  if (read_bytes+write_bytes) {

 

    printf("\n%-25s, %-8s%4dKb/sec, %-7s%6dKb, %-7s%6dKb\n\n",

           ctime(gettimeofday_s()),

           "Average:", ((read_bytes+write_bytes)/1024)/5,

           "Read:",read_bytes/1024,

           "Write:",write_bytes/1024)

 

    /* print header */

    printf("%8s %8s %8s %25s %8s %4s %12s\n",

           "UID","PID","PPID","CMD","DEVICE","T","BYTES")

  }

  /* print top ten I/O */

  foreach ([process,cmd,userid,parent,action] in io_stat- limit 10) -----iostat-表示降序排序,limit表示取前10

    printf("%8d %8d %8d %25s %8s %4s %12d\n",

           userid,process,parent,cmd,

           device[process,cmd,userid,parent,action],

           action,io_stat[process,cmd,userid,parent,action])

 

  /* clear data */

  delete io_stat

  delete device

  read_bytes = 0

  write_bytes = 0  

}

 

probe end{

  delete io_stat

  delete device

  delete read_bytes

  delete write_bytes

}

   有个疑问,上面的devname值从何而来,看一下tapset/vfs.stp,里面有一段

probe vfs.read.return = kernel.function("vfs_read").return

{

name = "vfs.read"

retstr = sprintf("%d", $return)

file = $file   ---vfs_read传入的参数

pos = $pos  ---vfs_read传入的参数

buf = $buf    ---vfs_read传入的参数

bytes_to_read = $count  ---vfs_read传入的参数

dev = __file_dev($file)

devname = __find_bdevname(dev, __file_bdev($file))

ino = __file_ino($file)

ret = $return

bytes_read = $return > 0 ? $return : 0

error = $return < 0 ? $return : 0

error_str = error ? errno_str(error) : ""

}

    vfs_read函数原型ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) 

    其实用stap -L 'kernel.function("vfs_read")就会把参数和返回值都列出来    


     这么简单的代码就把一个复杂的监控给实现了,systemtap真神器!

 

猜你喜欢

转载自xieyj.iteye.com/blog/1858097