![监视尝试访问不存在的文件或目录的进程](https://linux22.com/image/69617/%E7%9B%91%E8%A7%86%E5%B0%9D%E8%AF%95%E8%AE%BF%E9%97%AE%E4%B8%8D%E5%AD%98%E5%9C%A8%E7%9A%84%E6%96%87%E4%BB%B6%E6%88%96%E7%9B%AE%E5%BD%95%E7%9A%84%E8%BF%9B%E7%A8%8B.png)
我们正在将网站从一个服务器配置迁移到新配置,并且网站将位于与以前不同的路径中。我们计划认真检查并用新路径替换旧路径,但如果我们错过任何路径,是否有某种方法可以监视任何试图访问旧路径的进程,并知道该进程所拥有的 UID 是什么?
答案1
您可以使用这个小 systemtap 脚本:
#!/usr/bin/stap
function proc:string() { return sprintf("PID(%d) UID(%d) PROC(%s)", pid(), uid(), execname()) }
probe syscall.open.return, syscall.stat.return,
syscall.open64.return ?, syscall.stat64.return ? {
filename = user_string($filename)
if ($return < 0) {
printf("failed %s on %s by %s\n", pn(), proc(), filename)
}
}
它将在返回时挂钩系统调用 open 和 stat (您可以复制/粘贴代码,也许我忘记了其他一些系统调用)。由于系统调用是与内核通信的唯一方式,因此您不会错过任何东西。该脚本将产生这种输出:
failed syscall.stat.return on PID(4203) UID(1000) PROC(bash) by /tmp/rofl
failed syscall.stat.return on PID(4203) UID(1000) PROC(bash) by /tmp/hihi
使用 systemtap 的优点包括:
- 对过程的干扰较小
- 系统范围(不仅是受监视的进程),但您可以直接在脚本中减少其选择
- 资源消耗较少(仅显示失败的操作,而不是所有操作之后都进行 grep)
- 您可以改进脚本以获取有关调用程序的详细信息(例如,其回溯、调用时间等)。这取决于您的应用程序。
对于缺点:
- 不是标准的,您必须安装它(但足够标准,可以在大多数发行版上使用)。在 Redhat 及变体上:
sudo yum install systemtap
- 需要有调试信息来构建模块。在 Redhat 及变体上:
sudo debuginfo-install kernel
一些有用的链接:Tapset(包含的函数)索引,和一个初学者指南
祝您移民顺利!
答案2
像这样的事情应该这样做:
strace -f \
-e trace=open,stat,stat64,lstat,lstat64,chdir,mkdir,rename,symlink,creat \
-o >(grep "the paths you want to catch" > log) \
commandToStartYourServer
您希望-f
交换机跟踪子进程。跟踪选项是fabricate
用于跟踪 IO 的子集(制造跟踪"open,stat,stat64,lstat,lstat64,execve,exit_group,chdir,mkdir,rename,clone,vfork,fork,symlink,creat"
)
这通过 grep 和进程替换(基本上是系统级别的管道)过滤输出来进一步限制磁盘 IO。
答案3
你可以使用 fatrace。大多数现代系统中应该存在内核支持 (fanotify),但 fatrace 用户空间应用程序不在某些操作系统的标准存储库中。如果您的旧文件位于单独的文件系统上,则 fatrace 特别好。
http://www.lanedo.com/filesystem-monitoring-linux-kernel/
--
更常见的是auditd,尽管使用起来有点困难。
http://linux-audit.com/configuring-and-auditing-linux-systems-with-audit-daemon/
--
当符号链接允许通过完全不同的路径进行访问时,通过路径监视文件使用情况存在一个根本问题,因此您可能需要特别注意这一点。