问题描述:
一个文件正在被进程写
我想查看哪个进程在写这个文件。
解决思路:
Linux 下每个文件都会在某个块设备上存放,当然也都有相应的 inode ,那么透过 vfs.write 我们就可以知道谁在不停的写入特定的设备上的 inode。
那用什么工具呢? 这个神器就是systemtap ,具体的命令就是stap。
参考:http://cccgw.info/2012/07/systemtap%E5%85%A5%E9%97%A8/
安装很简单:yum -y install systemtap
但是这个安装完毕,还需要内核的支持,不然会报错。具体的说就是需要安装kernel-debuginfo包。
安装过程:
1 查看内核版本
uname -r
2.6.32-279.el6.x86_64
2 下载相应的包:
wget http://debuginfo.centos.org/6/x86_64/kernel-debuginfo-2.6.32-279.el6.x86_64.rpm
wget http://debuginfo.centos.org/6/x86_64/kernel-debuginfo-common-2.6.32-279.el6.x86_64.rpm
3 安装rpm包:
rpm -ivh kernel-debuginfo-2.6.32-279.el6.x86_64.rpm kernel-debuginfo-common-2.6.32-279.el6.x86_64.rpm
4 确保安装包正常:
rpm -qa|grep kernel-debug
kernel-debuginfo-common-x86_64-2.6.32-279.el6.x86_64
kernel-debuginfo-2.6.32-279.el6.x86_64
好了,测试下stap的可用性吧:
执行命令:stap -v -e 'probe vfs.read {printf("read performed\n"); exit()}'
显示下面结果:
Pass 1: parsed user script and 83 library script(s) using 194448virt/23176res/3056shr kb, in 130usr/10sys/142real ms.
Pass 2: analyzed script: 1 probe(s), 1 function(s), 3 embed(s), 0 global(s) using 427088virt/122744res/8316shr kb, in 1400usr/90sys/1493real ms.
Pass 3: using cached /root/.systemtap/cache/4a/stap_4a1eb85edba807357c24d4e1a07bc9d7_1471.c
Pass 4: using cached /root/.systemtap/cache/4a/stap_4a1eb85edba807357c24d4e1a07bc9d7_1471.ko
Pass 5: starting run.
read performed
Pass 5: run completed in 0usr/30sys/346real ms.
说明stap可以用了。
用法:
stap stap预制脚本.stp major minor 文件inode
(systemstap,major,minor ,这些不明白的去google吧)
比如我想知道我的/root/debug.log 是谁写的,例子:
df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
34G 11G 21G 35% /
ls -l /dev/mapper/VolGroup-lv_root
lrwxrwxrwx. 1 root root 7 Aug 31 2012 /dev/mapper/VolGroup-lv_root -> ../dm-0
继续找:
ls -l /dev/dm-0
brw-rw----. 1 root disk 253, 0 Aug 31 2012 /dev/dm-0
看到了么? 253是major number ,0 是minor number
再找文件的inode:
stat -c '%i' /root/debug.log
523308
组合命令来吧:
stap /usr/share/doc/systemtap-client-1.7/examples/io/inodewatch.stp 253 0 523302
astroc(740) vfs_write 0x800011/25337884
astroc(740) vfs_write 0x800011/25337884
astroc(740) vfs_write 0x800011/25337884
astroc(740) vfs_write 0x800011/25337884
找到罪魁祸首了,pid为740的astroc程序。