gpt4 book ai didi

linux - 如何在功能测试中模拟 INotify 失败?

转载 作者:可可西里 更新时间:2023-11-01 11:51:31 24 4
gpt4 key购买 nike

我有一个使用 inotify 跟踪文件系统更改的 Linux 应用程序。我想为它编写一个功能测试套件,从最终用户的角度测试应用程序,作为其中的一部分,我想测试文件系统失败的情况,特别是我想测试 inotify 失败。
具体来说,我想调用 inotify_init()inotify_add_watch()inotify_rm_watch() 调用和调用 read() 当测试需要时,inotify 文件描述符会返回错误。

但问题是我找不到如何模拟 inotify 失败的方法。我想知道是否有人已经遇到过这样的问题并且知道一些解决方案。

最佳答案

如果您想避免任何模拟,最好的办法就是通过直接达到操作系统限制来引发错误。例如,inotify_init 可能会因 EMFILE errno 而失败,如果调用进程已达到打开文件描述符的数量限制。要以 100% 的精度达到这样的条件,您可以使用两个技巧:

  1. 通过 changing values in procfs 动态控制正在运行的进程的限制
  2. 将您的应用程序进程分配给专用的 cgroup 并通过 cgroups API 为其提供约 0% 的 CPU 时间来“暂停”它(这就是 Android 限制后台应用程序并实现其节能“打瞌睡”模式的方式)。

inotify 所有可能的错误条件都记录在 inotifyinotify_initinotify_add_watch 的手册页中(我不认为 inotify_rm_watch 可能会失败,除非代码中存在纯粹的编程错误。

除了普通错误(例如遍历 /proc/sys/fs/inotify/max_user_watches)之外,inotify 有几种错误模式(队列空间耗尽、watch ID 重用),但这些不是严格意义上的“失败”。

当有人执行文件系统更改的速度快于您的 react 速度时,就会发生队列耗尽。它很容易重现:使用 cgroups 暂停您的程序,同时它有一个 inotify 描述符打开(因此事件队列不会耗尽)并通过修改观察到的文件/目录快速生成 很多 通知。一旦你有 /proc/sys/fs/inotify/max_queued_events 未处理的事件,并取消暂停你的程序,它将收到 IN_Q_OVERFLOW(并且可能会错过一些事件,这没有'不适合队列)。

Watch ID 重用的重现是乏味的,因为现代内核从类似文件描述符的行为切换到类似 PID 的 watch-ID 行为。您应该使用与测试 PID 重用时相同的方法——创建和销毁 很多 的 inotify watch ,直到整数 watch ID 回绕。

Inotify 还有一些棘手的极端情况,在正常操作期间很少发生(例如,我所知道的所有 Java 绑定(bind),包括 Android 和 OpenJDK,都不能正确处理所有这些情况):相同的 inode 问题和处理IN_UNMOUNT

相同 inode 问题在 inotify 文档中有很好的解释:

A successful call to inotify_add_watch() returns a unique watch descriptor for this inotify instance, for the filesystem object (inode) that corresponds to pathname. If the filesystem object was not previously being watched by this inotify instance, then the watch descriptor is newly allocated. If the filesystem object was already being watched (perhaps via a different link to the same object), then the descriptor for the existing watch is returned.

简而言之:如果您观看同一个文件的两个硬链接(hard link),它们的数字观看 ID 将相同。这种行为很容易导致失去对第二个 inotify watch 的跟踪,如果你将 watch 存储在 hashmap 之类的东西中,用整数 watch ID 键控。

第二个问题更难观察到,因此即使不是错误模式也很少得到正确支持:卸载分区,目前通过 inotify 观察到。棘手的部分是:Linux 文件系统不允许您在文件描述符打开它们时自行卸载,但是通过 inotify 观察文件不会阻止文件系统卸载。如果您的应用在单独的文件系统上观察文件,并且用户卸载了该文件系统,则您必须准备好处理由此产生的 IN_UNMOUNT 事件。

以上所有测试都应该可以在 tmpfs 文件系统上执行。

关于linux - 如何在功能测试中模拟 INotify 失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49503859/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com