检查 FreeBSD 系统上的 IO 操作

Ser*_*mov 5 freebsd io hook trace

我会知道有什么方法可以检查/拦截 FreeBSD 上的 IO 操作。像 ktrace 一样,但如果我不知道这个过程(例如,这需要一些时间)。

Rui*_*iro 5

对于监视和性能分析,您有一个非常强大的半可编程工具,称为dtrace

dtrace 允许构建命令行或小程序,这些程序将允许您遵循必须的系统调用。

它有点强大和复杂。你可以找到一些例子,包括一本非常有趣的书系统性能:企业和云

DTrace 工具页面

DTrace,一种在不同操作系统(Solaris、Mac OS X、FreeBSD 等)中可用的动态跟踪实现。DTrace 通过提供应用程序和系统内部结构的新详细视图,帮助解决服务器上的问题,达到以前难以或不可能访问的水平。它提供了一种语言来编写类似于 C 和 awk 的基于事件的 DTrace 脚本。

# Files opened by process:
dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'

# Read bytes by process:
dtrace -n 'sysinfo:::readch { @bytes[execname] = sum(arg0); }'

# Write bytes by process:
dtrace -n 'sysinfo:::writech { @bytes[execname] = sum(arg0); }'

# Read size distribution by process:
dtrace -n 'sysinfo:::readch { @dist[execname] = quantize(arg0); }'

# Write size distribution by process:
dtrace -n 'sysinfo:::writech { @dist[execname] = quantize(arg0); }'
Run Code Online (Sandbox Code Playgroud)


小智 5

正如其他答案中所说,DTrace 是跟踪系统活动的强大工具,也可用于此任务。

一些 Dtrace 脚本是可移植的,但许多是特定于操作系统的。在Dtrace Toolkit 中可以找到许多有用的脚本,但是 rwsnoot 和 opensnoop 在 FreeBSD 下还不能工作。

要监视打开的系统调用,可以使用此脚本:

#!/usr/sbin/dtrace -s

dtrace:::BEGIN
{
    printf("%5s %5s %s","UID","PID", "Command  Path");
}

syscall::open*:entry
{
    printf("%5d %5d %s %s", uid, pid, execname,
                    probefunc == "open" ? copyinstr(arg0) : copyinstr(arg1));
}
Run Code Online (Sandbox Code Playgroud)

用于读/写的简单(但不是很有用)脚本

#!/usr/sbin/dtrace -s

syscall::*read:entry,
syscall::*write:entry
{
    printf("%5d %s CALL %s(%d, .., %d)", pid, execname, probefunc, arg0, arg2);
    self->fd = arg0;
}

syscall::*readv:entry,
syscall::*writev:entry
{
     printf("%5d %s CALL %s(%d, ...)", pid, execname, probefunc, arg0);
}

syscall::*read*:return
{
    printf("%5d %s fd %d read %d bytes", pid, execname, self->fd, arg0);
    self->fd = 0;
}

syscall::*write*:return
{
    printf("%5d %s fd %d wrote %d bytes", pid, execname, self->fd, arg0);
    self->fd = 0;
}
Run Code Online (Sandbox Code Playgroud)

您可能需要一些过滤器。例如 不要跟踪 dtrace 自我:

syscall::foobar:entry
/execname != "dtrace"/
{
    ...
}
Run Code Online (Sandbox Code Playgroud)