hdiutil
可以将包含HFS+分区的DMG文件附加和分离到选定的挂载点。但是,它使用DiskImages.framework
的私有 API。我的目标是使此任务完全编程化,因此我在内核驱动程序领域寻找替代方案。
在深入研究<sys/mount.h>
表示的 KPI 时,我发现了根据匹配的 fsid 卸载文件系统的有用方法:
int vfs_unmountbyfsid(fsid_t *fsid, int flags, vfs_context_t ctx)
但是,我们对挂载有相反的操作吗?
没有用于启动挂载的公共 KPI,我什至不知道com.apple.kpi.private
中的函数。然而,在用户空间中,您可以使用的不仅仅是DiskImages.framework:有DiskArbitration.framework
,当然还有mount(2)
的POSIX系统调用。
我认为您可能在这里将两个概念混为一谈,它们实际上是完全独立的:
- 打开磁盘映像并创建虚拟块设备以访问其内容
- 在块设备上挂载文件系统。
磁盘映像支持不是 xnu 内核的固有部分。它们在IOHDIXController
对象中实现(代码在 kext 中),您可以在 IORegistry 中找到附加到IOResources
。当用户双击.dmg文件或类似文件时,diskimages-helper
守护进程会打开并解析它,并指示IOHDIXController创建一个新的IODiskImageBlockStorageDeviceOutKernel
实例(IOBlockStorageDevice
子类)。这对操作系统来说就像一个物理块设备,通常的IOBlockStorageDriver
->IOMedia
->IOPartitionScheme
->IOMedia
->IOMediaBSDClient
对象的堆栈在其上配置自身。然后,这会导致设备发现事件在diskarbitrationd
中触发,然后进入该过程的第二部分:根据需要在新发现的IOMedia
对象的/dev/diskXsY
节点上调用mount(2)
。
据我所知,HDIX 子系统尚未开放。因此,如果要实现自己的磁盘映像格式,则需要重新创建类似于Apple的diskimage-helper
和IOHDIXController.kext
的东西。如果您愿意,您可以完全在内核中实现它,尽管这可能不是一个好主意。
第二部分,挂载,如果您使用的是 IOStorage 堆栈,则由 diskarbitration d 自动完成,但您可以通过磁盘仲裁异议来影响它。有关详细信息,请参阅 DiskArbitration .framework。但这也可以让您影响diskimages-helper
处理的磁盘映像的挂载,因此,如果您使用的是它支持的映像格式,则无需编写自己的映像格式,只需拦截挂载并自己做任何您想做的事情。
你也可以完全绕过 IOStorage 堆栈,只在 kext 中创建 BSD 开发节点。在这种情况下,diskarbitration d 应该不会注意到它,您需要从守护程序显式调用mount()
。
我希望这能澄清事情。