如何按需打印当前对文件系统的读取和写入?

如何按需打印当前对文件系统的读取和写入?

我有兴趣获取有关文件系统读取和写入的统计信息,特别是 NFS 挂载的统计信息。

我知道有很多工具,例如iostatnfsstatinotifywait每个程序都存在问题。

由于层次结构的复杂性,我无法使用任何需要我遍历文件系统或明确提及文件名的东西。

有没有一个程序可以按需执行以下操作?

  1. 显示读/写
  2. 显示读/写路径
  3. 显示字节数

按需,我的意思是执行时间。第(3)点不是强制性的。

例如,我希望能够执行以下操作:

$ magicIOprogram
read, 512, /path/to/file1
read, 256, /path/to/file2
write, 15, /path/to/file3
write, 10562, /path/to/file4

如果有办法使用我不知道的上述工具来获取这些信息,那么它也将是一个足够的解决方案。

答案1

你可能想尝试系统水龙头

这里稍微修改一下例子显示每 100 毫秒打开、读取和写入:

#! /usr/bin/env stap

global fileread, filewrite

probe syscall.open.return {
    if ($return != -1) {
        printf("open, %s, %d/%d\n", user_string($filename), pid(), $return)
    }
}

probe syscall.read.return {
    p = pid()
    fd = $fd
    bytes = $return
    if (bytes > 0)
        fileread[p, fd] += bytes
}

probe syscall.write.return {
    p = pid()
    fd = $fd
    bytes = $return
    if (bytes > 0)
        filewrite[p, fd] += bytes
}

probe timer.ms(100) {
    foreach (v = [p,fd] in fileread) {
        printf("read, %d, %d/%d\n", v, p, fd)
    }                                                                                                                                                                                          
    delete fileread                                                                                                                                                                            
    foreach (v = [p,fd] in filewrite) {                                                                                                                                                        
        printf("write, %d, %d/%d\n", v, p, fd)                                                                                                                                                 
    }                                                                                                                                                                                          
    delete filewrite                                                                                                                                                                           
}

输出行的格式为:

  • 打开,(路径名),(pid)/(fd)

  • 读取,(字节),(pid)/(fd)

  • 写入,(字节),(pid)/(fd)

答案2

Linux的审计可以得到第1点和第2点的信息。

假设您正在运行 RHEL/CentOS 6 并安装了一个 nfs 共享/mnt/nfs/foo

$ tree /mnt/nfs/foo
/mnt/nfs/foo
|-- a
|   `-- foo
|-- b
    `-- bar

您需要在中定义以下规则/etc/audit/audit.rules

# Delete existing rules
-D
# Set buffer size
-b 320
# Log read and write operations
-w /mnt/nfs/foo -p r -k read -k nfs
-w /mnt/nfs/foo -p w -k write -k nfs

然后auditd使用 重新加载服务/etc/init.d/auditd reload

完成后,您可以使用ausearchaureport读取由以下命令生成的事件日志auditd

$ cat /mnt/nfs/foo/a/foo
$ echo 'test' > /mnt/nfs/foo/b/bar
$ ausearch -k nfs | aureport -f
File Report
===============================================
# date time file syscall success exe auid event
===============================================
1. 07/15/2015 11:39:04 /mnt/nfs/foo/a/foo 2 yes /bin/cat 500 59
2. 07/15/2015 11:39:05 /mnt/nfs/foo/b/bar 2 yes /bin/bash 500 60

需要注意的是,它只能从客户端收集信息。如果您的客户端不受信任,您将无法使用此方法来安全地确定他们通过 nfs 访问的内容。

相关内容