Watchdog的kqueue实现尝试打开新文件引发权限崩溃,如何解决?
Watchdog的kqueue实现尝试打开新文件引发权限崩溃,如何解决?
我之前也碰到过类似的问题,其实这完全是watchdog的kqueue后端和Linux上的inotify后端实现机制不一样导致的:
- 咱们在Linux上用的inotify是内核直接推送文件变化事件,根本不需要打开目标文件,自然不会碰到权限问题;
- 但kqueue(像macOS、BSD这类系统用的)的watchdog实现,为了能盯着新创建的文件后续有没有其他变化,会试着打开这个新文件来注册对应的kevent。要是这个文件是其他用户(比如www)创建的,权限不让当前用户碰,就会直接抛出
PermissionError,而且watchdog的kqueue后端没处理这个异常,直接把监控线程搞崩了。
临时救急:让权限错误不致命
要是不想动watchdog的源码,用猴子补丁就能搞定——把kqueue观察者里注册kevent的方法包装一下,碰到权限错误就忽略掉,这样监控线程就不会崩了。
在你自己的脚本开头加上这段代码就行:
import logging from watchdog.observers.kqueue import KqueueObserver # 给kqueue观察者打补丁,捕获权限错误 original_register_kevent = KqueueObserver._register_kevent def patched_register_kevent(self, path, is_directory=False): try: return original_register_kevent(self, path, is_directory) except PermissionError: log = logging.getLogger(__name__) log.warning(f"没法监控文件 {path}:权限不够,跳过这个文件的后续监控啦") KqueueObserver._register_kevent = patched_register_kevent
加了这个之后,再碰到其他用户创建的无权限文件,脚本只会打个警告,监控线程该跑还是跑,不会直接崩掉。
长期根治:给官方提Bug
你说的这个问题确实是watchdog的kqueue后端的设计漏洞——它没处理文件权限不足的异常,导致线程直接挂掉。建议你去watchdog的官方仓库提交个Bug报告,把场景说清楚(其他用户创建无权限文件时监控线程崩溃),官方应该会在后续版本里修复,比如自动捕获这类异常,跳过没权限的文件就行。
另外,要是你根本不需要盯着新文件的后续变化,理论上可以改kqueue后端的逻辑,不让它注册新文件的kevent,但这得动库的源码,不如用猴子补丁来得方便。
内容来源于stack exchange
相关产品推荐
相关产品推荐

