我想知道是否有任何方法可以检查/拦截 FreeBSD 上的 IO 操作。就像 ktrace 但如果我不知道这个过程(例如,这需要花费一些时间)。
答案1
对于监控和性能分析,您有一个非常强大的半可编程工具,称为跟踪。
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); }'
答案2
正如其他答案中所述,DTrace 是跟踪系统活动的强大工具,也可用于此任务。
一些 Dtrace 脚本是可移植的,但许多脚本是特定于操作系统的。许多有用的脚本可以在跟踪工具包,但 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));
}
简单(但不是很有用)的读/写脚本
#!/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;
}
您可能需要一些过滤器。例如不要跟踪 dtrace 自身:
syscall::foobar:entry
/execname != "dtrace"/
{
...
}
答案3
就我个人而言,我倾向于使用top -m io
.