IT技术博客大学习 共学习 共进步

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

系统技术非业余研究 2013-07-29 23:17:18 浏览 6,324 次

   晚上朔海同学问:

   一个文件正在被进程写 我想查看这个进程 文件一直在增大 找不到谁在写 使用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处理这种问题很是神器。

建议继续学习

  1. Oracle MTS模式下 进程地址与会话信息 (阅读 14,186)
  2. Linux内存点滴 用户进程内存空间 (阅读 12,944)
  3. 深入理解Nginx之调试优化技巧 (阅读 8,103)
  4. Linux上进程的表示以及入门 (阅读 7,642)
  5. Linux下进程绑定多CPU运行 (阅读 7,101)
  6. 分析进程内存分配情况,解决程序性能问题 (阅读 6,682)
  7. 使用GDB调试多进程程序 (阅读 6,241)
  8. 进程运行于不同的 CPU 核 (阅读 5,822)
  9. Linux进程的层次关系 (阅读 5,602)
  10. 进程和线程关系及区别 (阅读 5,264)