了解Mac OS块设备和IOFilterScheme KEXT的缓冲

时间:2019-01-14 17:00:44

标签: macos kernel storage kernel-extension iofilterscheme

我试图了解IOFilterScheme KEXT的工作原理,以便最终自己开发。我已经尝试了一些示例程序,并且已经通过使用this sample获得了基本的加密功能。

但是,当我添加printf()语句并查看控制台日志时,我看到了一些令人困惑的行为。具体来说,我几乎从来没有看到过read()调用,除了配置东西时(例如mount_hfs和fsck_hfs)的几个进程。

例如,如果我从某个应用程序(例如:vim)在卷上(从挂载的磁盘映像中)写入一个新文件,则当我在控制台日志中看到相应的write()时,其PID为'vim'。在使用其他应用程序时也会看到此信息。

但是,如果我尝试从另一个应用程序(例如Sublime Text编辑器)中读取同一文件,则该文件可以很好地打开,但是在控制台日志中却看不到任何相应的read()条目。

通过查看DMG文件可以确定示例加密是否正常运行,但我看到的行为有两个问题:

1)我很难理解读写方面的情况。

2)最终,我想编写一个KEXT,其行为因要进行读取或写入的应用程序而异。为此,我需要从每个尝试访问文件的应用程序中获取一个实际的read()(至少是该应用程序首次访问该文件)。

进行了一些研究之后,似乎Mac OS上的块设备具有某种缓冲,但是我找不到太多的细节。实验上,我尝试在read()和write()调用中执行此行,但没有效果

super::IOStorage::synchronize(client, 0, 0);

如果有人可以告诉我如何获得对缓冲的更多控制,以便可以看到实际的read()调用,那就太好了。如果那不可能,那么我可能必须在另一个级别上编写我的加密驱动程序。但是,IOFilterScheme KEXT似乎(除了这一点之外)确实适合我的用例,因此我希望可以使其工作。

1 个答案:

答案 0 :(得分:1)

大多数情况下,缓存发生在文件级别的统一缓冲区缓存(UBC)中。文件系统本身可以执行任何类型的缓存,尤其是对于元数据(内部树结构等)。这是IOKit之上的许多层,因此您不受IOStorage驱动程序的影响。

  

2)最终,我想编写一个KEXT,其行为因要进行读取或写入的应用程序而异。为此,我需要从每个尝试访问文件的应用程序中获取一个实际的read()(至少是该应用程序首次访问该文件)。

尝试在块I / O kext中执行此操作可能是傻瓜的事。现代文件系统是复杂的野兽,因此您不能期望文件I / O与块I / O之间存在任何1:1对应关系。如果需要应用程序/文件级别的粒度,则需要使用kauth通过自己的文件系统或取决于您要执行的操作在VFS层上进行工作。如果您不担心使用Apple明确规定不使用的API(例如内部使用/学习),则还可以使用MAC框架kext API,它比kauth拥有更多的控制权。