Home > Linux, 工具介绍 > Linux下如何知道文件被那个进程写

Linux下如何知道文件被那个进程写

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: Linux下如何知道文件被那个进程写

晚上朔海同学问:

一个文件正在被进程写 我想查看这个进程 文件一直在增大 找不到谁在写 使用lsof也没找到

这个问题挺有普遍性的,解决方法应该很多,这里我给大家提个比较直观的方法。

linux下每个文件都会在某个块设备上存放,当然也都有相应的inode, 那么透过vfs.write我们就可以知道谁在不停的写入特定的设备上的inode。
幸运的是systemtap的安装包里带了inodewatch.stp,位于/usr/local/share/doc/systemtap/examples/io目录下,就是用来这个用途的。
我们来看下代码:

$ cat inodewatch.stp 
#! /usr/bin/env stap

probe vfs.write, vfs.read
{
  # dev and ino are defined by vfs.write and vfs.read
  if (dev == MKDEV($1,$2) # major/minor device
      && ino == $3)
    printf ("%s(%d) %s 0x%x/%u\n",
      execname(), pid(), probefunc(), dev, ino)
}

这个脚本的使用方法如下: stap inodewatch.stp major minor ino

下面我们构造个场景: dd不停的写入一个文件,查出这个文件的ino, 以及它所在设备的major, minor, 运行stap脚本就可以得到答案。


场景交代好了,我们来演示下:

$ pwd
/home/chuba
$ df
Filesystem           1K-blocks      Used Available Use% Mounted on
...
/dev/sdb1            1621245336 825209568 713681236  54% /home
...
$ ls -al /dev/sdb1
brw-rw---- 1 root disk 8, 17 Oct 24 11:22 /dev/sdb1  
$ rm -f test.dat && dd if=/dev/zero of=test.dat
^C9912890+0 records in
9912890+0 records out
5075399680 bytes (5.1 GB) copied, 26.8189 s, 189 MB/s

这个终端模拟文件的不停写入,同时在另外一个终端查验谁干的。这里我们已经知道设备的major/minor为8/17

$ stat -c '%i' test.dat
25337884
$ sudo stap /usr/local/share/doc/systemtap/examples/io/inodewatch.stp 8 17 25337884
dd(740) vfs_write 0x800011/25337884
dd(740) vfs_write 0x800011/25337884
dd(740) vfs_write 0x800011/25337884
dd(740) vfs_write 0x800011/25337884
dd(740) vfs_write 0x800011/25337884
dd(740) vfs_write 0x800011/25337884
...

看到了吧,dd是罪魁祸首,pid是740, 搞定收工!
小结: systemtap处理这种问题很是神器。

祝玩得开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Linux, 工具介绍 Tags: , ,
  1. portl4t
    March 12th, 2013 at 22:09 | #1

    遍历所有/proc/$pid/fd/的项也能做到吧

    [Reply]

    dtrace Reply:

    可能。但是如果使用的时间片比较大,而process比较多的时候,不等遍历到就已经结束了。

    还是solaris/mac/bsd的dtrace可以分分钟搞定
    # Files opened by process,
    dtrace -n ‘syscall::open*:entry { printf(“%s %s”,execname,copyinstr(arg0)); }’
    CPU ID FUNCTION:NAME
    0 14 open:entry gnome-netstatus- /dev/kstat
    0 14 open:entry man /var/ld/ld.config
    0 14 open:entry man /lib/libc.so.1
    0 14 open:entry man /usr/share/man/man.cf

    [Reply]

  2. vampire
    March 12th, 2013 at 22:28 | #2

    @portl4t
    关键是谁在写。

    [Reply]

  3. March 12th, 2013 at 22:46 | #3

    lsof 也可以:

    lsof /home/chuba/test.dat

    [Reply]

    Yu Feng Reply:

    lsof查出owner

    [Reply]

    沈锋 Reply:

    lsof /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3
    COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    chrome 13177 feng mem REG 8,7 35304 8259168 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3
    chrome 13182 feng mem REG 8,7 35304 8259168 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3
    emacs 15650 feng mem REG 8,7 35304 8259168 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3
    java 19995 feng mem REG 8,7 35304 8259168 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3
    awesome 30162 feng mem REG 8,7 35304 8259168 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3
    evilvte 30282 feng mem REG 8,7 35304 8259168 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3

    [Reply]

    Sebastian Reply:

    看标题~ 大牛找的是进程不是ower.

    Yu Feng Reply:

    right

  4. zijia
    March 12th, 2013 at 22:51 | #4

    顶一下如灯塔般的霸爷~

    [Reply]

  5. leon
    March 12th, 2013 at 23:43 | #5

    把/proc/sys/vm/block_dump 打开,也可以有这样的效果。

    [Reply]

    Sebastian Reply:

    请问“/proc/sys/vm/block_dump”用这个如何实现?

    [Reply]

    Sebastian Reply:

    请问用block_dump如何实现?

    [Reply]

    Yu Feng Reply:

    blktrace轻松实现。

    [Reply]

    leon Reply:

    这就是个开关,echo 1 > /proc/sys/vm/block_dump 就可以打开,写入0关闭。
    dump的内容用dmesg可以看到。

    [Reply]

    Yu Feng Reply:

    en

  6. hptdx
    March 13th, 2013 at 07:37 | #6

    曾经在solaris上面自己写了一个脚本来搞定此事(ptree),到了linux下,基本都用lsof来搞定了。

    [Reply]

  7. March 13th, 2013 at 09:00 | #7

    那为啥会 lsof 查不到呢?

    [Reply]

  8. saintak
    March 13th, 2013 at 11:03 | #8

    fedora17上路径是/usr/share/systemtap/testsuite/systemtap.examples/io

    [Reply]

  9. saintak
    March 13th, 2013 at 11:04 | #9

    @沈锋
    其实fuser也可以。。。。

    [Reply]

    tanyangxf Reply:

    瞬间完成的监控不出来吧,长时间没释放的到是没问题,如果是有需要就写一下日志这监控不出来吧

    [Reply]

  10. March 13th, 2013 at 21:44 | #10

    lsof看inode没有压力的飘过

    [Reply]

  11. huanzi
    March 18th, 2013 at 15:59 | #11

    Distributor ID: CentOS
    Description: CentOS release 5.6 (Final)
    Release: 5.6
    Codename: Final
    请问为什么在以上操作系统上找不到这个文件?

    [Reply]

  12. March 27th, 2013 at 13:24 | #12

    原来dd是罪魁祸首,pid是740,谢谢你分享…

    [Reply]

  13. nexpro
    April 12th, 2013 at 13:44 | #13

    那为啥会 lsof 查不到呢? +1

    [Reply]

    Yu Feng Reply:

    lsof查出来的是owner吧,而且即使可以也是查出瞬间的动作。

    [Reply]

  14. June 25th, 2013 at 17:07 | #14

    您好,从您博客中学习到这个方法,不过木有成功呀,求助:
    1. 我的inodewatch.stp在不同的目录下
    /usr/share/doc/systemtap-client-1.8/examples/io/inodewatch.stp
    不过内容一致,应该是不影响的吧~

    内核版本:2.6.32-279.14.1.el6.x86_64
    我运行“rpm -qf /usr/bin/stap”得到的结果是:
    systemtap-client-1.8-7.el6.x86_64
    systemtap-devel-1.8-7.el6.x86_64

    2. 然后根据您用法,我在boot分区随便建一个文件,并写入内容……
    然后调用stap去找到哪个进程在写该文件!报错了……
    [root@test boot]# stap /usr/share/doc/systemtap-client-1.8/examples/io/inodewatch.stp 8 1 25
    semantic error: while resolving probe point: identifier ‘kernel’ at /usr/share/systemtap/tapset/vfs.stp:820:19
    source: probe vfs.write = kernel.function(“vfs_write”)
    ^

    semantic error: missing x86_64 kernel/module debuginfo under ‘/lib/modules/2.6.32-279.14.1.el6.x86_64/build’
    semantic error: while resolving probe point: identifier ‘vfs’ at /usr/share/doc/systemtap-client-1.8/examples/io/inodewatch.stp:3:7
    source: probe vfs.write, vfs.read
    ^

    semantic error: no match
    semantic error: while resolving probe point: identifier ‘kernel’ at /usr/share/systemtap/tapset/vfs.stp:752:18
    source: probe vfs.read = kernel.function(“vfs_read”)
    ^

    semantic error: while resolving probe point: identifier ‘vfs’ at /usr/share/doc/systemtap-client-1.8/examples/io/inodewatch.stp:3:18
    source: probe vfs.write, vfs.read
    ^

    Pass 2: analysis failed. Try again with another ‘–vp 01’ option.
    Missing separate debuginfos, use: debuginfo-install kernel-2.6.32-279.14.1.el6.x86_64

    正在http://sourceware.org/systemtap/ 继续学习中……
    求指导: lin_credible@163.com. 或者直接回复,万分感谢~~

    [Reply]

    Yu Feng Reply:

    系统的符号信息没安装好。

    [Reply]

    Taolinran Reply:

    嗯,谢谢啦~

    [Reply]

  15. long904
    October 15th, 2013 at 11:28 | #15

    stap /usr/local/share/doc/systemtap/examples/io/inodewatch.stp 8 7 48
    parse error: expected ‘)’
    saw: operator ‘;’ at /usr/local/share/doc/systemtap/examples/io/inodewatch.stp:7:11
    source: && ino == $3)
    ^
    1 parse error.
    Pass 1: parse failed. Try again with another ‘–vp 1’ option.
    —— 运行提示以上错误。查找过,也还是没能解决。请问这是什么原因呢?怎么解决。应该不是系统符号信息问题吧?期待回复。谢谢!

    [Reply]

    Yu Feng Reply:

    不大像。符号问题你看下其他文件可以正常运行吗? 我怀疑是stap版本太低。

    [Reply]

    long904 Reply:

    感谢回复。今天抽空升级了一下stap版本,由原来1.8升级到2.3.但还是有问题
    semantic error: while resolving probe point: identifier ‘kernel’ at /usr/local/systemtap/share/systemtap/tapset/linux/vfs.stp:836:19
    source: probe vfs.write = kernel.function(“vfs_write”)
    系统内核是2.6.32-71.el6.x86_64。

    [Reply]

    long904 Reply:

    感谢回复。
    今天抽空升级了一下stap版本,由原来1.8升级到2.3.但还是有问题
    semantic error: while resolving probe point: identifier ‘kernel’ at /usr/local/systemtap/share/systemtap/tapset/linux/vfs.stp:836:19
    source: probe vfs.write = kernel.function(“vfs_write”)
    系统内核是2.6.32-71.el6.x86_64。

    [Reply]

  16. Watson
    April 2nd, 2014 at 09:45 | #16

    Hi,If my Linux system use the volume to manager the disk, I would not get the
    8,7 by this command,

    ls -al /dev/sdb1
    ++++++++++++++
    so, how to?
    /dev/mapper/vg_water-lv_home

    Thanks a lot.
    Watson

    [Reply]

  17. November 7th, 2014 at 11:29 | #17

    请问我的这个报错具体应该怎么解决?
    semantic error: while resolving probe point: identifier ‘kernel’ at /usr/share/systemtap/tapset/linux/vfs.stp:836:19
    source: probe vfs.write = kernel.function(“vfs_write”)
    ^

    semantic error: missing x86_64 kernel/module debuginfo [man warning::debuginfo] under ‘/lib/modules/2.6.32-431.23.3.el6.centos.plus.x86_64/build’
    semantic error: while resolving probe point: identifier ‘vfs’ at /usr/share/doc/systemtap-client-2.3/examples/io/inodewatch.stp:3:7
    source: probe vfs.write, vfs.read
    ^

    semantic error: no match
    semantic error: while resolving probe point: identifier ‘kernel’ at /usr/share/systemtap/tapset/linux/vfs.stp:768:18
    source: probe vfs.read = kernel.function(“vfs_read”)
    ^

    semantic error: while resolving probe point: identifier ‘vfs’ at /usr/share/doc/systemtap-client-2.3/examples/io/inodewatch.stp:3:18
    source: probe vfs.write, vfs.read
    ^

    Pass 2: analysis failed. [man error::pass2]

    [Reply]

  1. March 12th, 2013 at 22:59 | #1
  2. August 11th, 2013 at 21:11 | #2