在Linux中,从文件句柄确定文件路径


Determine file path from file handle in Linux

我有一个守护进程,它打开一个文件并在整个操作过程中(通常一次持续许多天)对其进行写操作。为了支持日志旋转,我希望能够识别句柄所引用的文件何时从原始位置移到了新位置。

这可能吗?对于这种情况,Fstat()没有给我任何有用的东西。

我目前的解决方案是,在日志写入功能中,测试日志文件的存在,如果它不存在,关闭旧句柄并打开一个新句柄。这种方法是有效的,但它是一种hack,并且有局限性。在我的例子中,我们的系统组使用一个工具进行日志旋转,该工具要求他们在旋转文件后触摸该文件,这导致我的守护进程继续认为其文件句柄指向正确的位置。

我有个想法。它是不可移植的,我不完全确定它是否有效或可靠,它让我有点畏缩,但你可能可以在/proc/%d/fd/%d上使用readlink,其中第一个%dgetpid()的结果,第二个是你的文件描述符。

这里有一些注意事项。首先,整个"获取路径+对该路径做一些事情"的方法在面对并发发生的重命名时将具有竞争条件。此外,您的日志文件可以有其他链接。我不确定/proc中的链接在面对重命名时的行为是什么。

您可以定期重新获取文件句柄(模式为a),例如每24小时一次。这允许您继续记录日志,尽管存在愚蠢和错误(因为在重命名文件和重新触摸它之间存在不可避免的竞争条件)日志旋转实用程序。

fstat为您提供了一个索引节点号,当日志被旋转时,它将发生变化。

参见http://php.net/manual/en/function.fstat.php和http://www.php.net/manual/en/function.lstat.php

可以比较fstatlstat的索引节点数;如果不一致,重新打开。

过去Unix守护进程处理此问题的标准方法是捕获SIGHUP并将其用作重新打开日志文件的信号,并让日志旋转脚本发送SIGHUP