根据我阅读的文档和xnu源代码,我了解到Mac OS X 使用统一缓冲区缓存(UBC)缓存文件 I/O. UBC根据可用的RAM增长尽可能大,但UBC页面是内存越来越紧张时首先被牺牲的页面.
在我的驱动程序中,我处理各种磁盘元数据.我希望能够使用UBC或类似的机制来保持MRU缓存这些数据以加快速度,同时让内核能够在需要时收回内存.然而,元数据不代表文件数据,因此不直接落入UBC的域.是否有我可以使用的低级机制,或者我可以以某种方式仅使用UBC中处理缓冲区本身的部分?
我目前正在寻找HFS +源代码,试图弄清楚它是否以及如何缓存文件系统元数据,尽管没有太大的成功.
主要的替代方案当然是为缓存保留特定的内存区域并进行自己的LRU剔除.我可以选择一个固定的缓存大小或者使用某种启发式方法,但是当RAM丰富时它总是会占用太少的内存,而当它没有时它会占用太多的内存.
更新:
在搜索了一些之后,我发现IOBufferMemoryDescriptor可以使用该kIOMemoryPurgeable选项创建实例.这允许你调用IOMemoryDescriptor::setPurgeable()它来标记内存"公平游戏"以便丢弃.我会尝试并用结果更新问题.
我正在尝试对Mac上的磁盘分区表进行微妙的修改; 特别是,我需要更改分区的类型.diskutil不支持这个,所以我不能使用它.gpt如果磁盘未使用,它可以正常工作(例如,通过修改的命令行实用程序).如果是,则在打开设备文件时失败:
int fd = open("/dev/disk1", O_RDWR);
Run Code Online (Sandbox Code Playgroud)
fd为-1并errno指示错误"资源忙".
我意识到我可以从不同的驱动器重启机器,从那里修改原始磁盘,然后重新启动.但是,从我的应用程序内部实现自动化/可靠性并不容易.此外,diskutil编辑实时设备的分区表没有问题,也没有bootcamp安装程序.
有没有一种已知的方法来做到这一点?最糟糕的情况是,我可以尝试在内核中执行此操作,但是kexts并非真正用于执行一次性操作,而我需要做的事情在用户空间中非常简单,但在内核中却相当困难.
有任何想法吗?
注意:我正在运行所有内容sudo,因此它不应该是权限问题.
我们有一个启动守护进程(必然由于各种原因)以root身份运行,并通过网络与服务器组件通信.它需要对服务进行身份验证,因此在首次获取密码时,我们会将其保存到系统密钥链中.在随后的发布中,我们的想法是从密钥链中检索密码并使用它来验证网络服务.
这一直运行良好,但在macOS 10.12上,现有代码停止工作,我们已经完全不知道如何解决这个问题.归结为:
无论我们是保存新密码还是检索旧密码,我们都会使用以下方法获取对系统密钥链的引用:
SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, &system_keychain);
Run Code Online (Sandbox Code Playgroud)
我们还禁用了用户交互以获得良好的衡量标准,尽管我们希望它在守护进程的上下文中已经关闭.
SecKeychainSetUserInteractionAllowed(false);
Run Code Online (Sandbox Code Playgroud)
将新密码保存到钥匙串时,我们会使用
OSStatus status = SecKeychainAddInternetPassword(
system_keychain,
urlLength, server_base_url,
0, NULL,
usernameLength, username,
0, NULL,
0,
kSecProtocolTypeAny, kSecAuthenticationTypeAny,
passwordLength, password,
NULL);
Run Code Online (Sandbox Code Playgroud)
这很有用.报告成功,我可以在Keychain Access.app的"系统"钥匙串中看到该项目.
在我们的守护进程的后续运行中检索它是通过以下行完成的:
status = SecKeychainFindInternetPassword(
system_keychain,
urlLength, url,
0, NULL,
usernameLength, username,
0, NULL,
0,
kSecProtocolTypeAny, kSecAuthenticationTypeAny,
&passwordLength, &password_data,
NULL);
Run Code Online (Sandbox Code Playgroud)
不幸的是,errSecAuthFailed由于我们不清楚的原因,这已经开始返回.
我们检查了一些额外的细节以及我们尝试过的东西,但无济于事:
SecKeychainAddInternetPassword,但这似乎没有任何区别.SecKeychainUnlock(),但正如文档所示,这似乎是多余的.Keychain Access.app原因SecKeychainFindInternetPassword()产生errSecItemNotFound,正如你所期望的.所以它绝对可以找到保存的项目,它不允许读取它.钥匙串文档不是很容易阅读,而是部分相当重复.("为了做Y,你需要做Y",但没有提到为什么你想要做Y.)尽管如此,我认为我已经完成并理解了大部分内容.我们特定设置的各个方面都没有详细介绍(从守护程序访问),但似乎很清楚,访问以前由同一个应用程序保存的项目不需要任何特殊授权或身份验证.这与我们所看到的行为直接矛盾.
有任何想法吗?
我知道如何将数据发送到 DriverKit 并返回一些值,即应用程序调用和驱动程序从应用程序IOConnectCallStructMethod()填充。OSDatastructureOutput
在我的应用程序中,它使用IOConnectCallAsyncScalarMethod()kext 来sendAsyncResult64()让应用程序知道传入的事件。但是,该方法sendAsyncResult64()在 DriverKit 中不可用。
我看到AsyncCompletion看起来像解决方案,但不知道如何实现它。有人知道该怎么办吗?感谢任何建议!
我们为macOS 上的虚拟文件系统 (VFS )开发了内核扩展 (KEXT),以将我们的软件与 Adobe InDesign 或 Microsoft Word 等外部程序集成。我们的软件和 KEXT 被许多客户使用。
看起来 KEXT 已被弃用,并且可能会在 macOS 的未来版本中完全删除,特别是在基于 Apple Silicon 的计算机上。请参阅 Apple 在其 安全指南中的声明:
“这就是为什么我们强烈鼓励开发人员在 macOS 中删除对未来采用 Apple 芯片的 Mac 电脑的 kext 支持之前采用系统扩展”
因此,我们目前正在研究可能的替代方案。
Apple 建议迁移到系统扩展而不是 KEXT。然而,我们发现的唯一与 VFS 相关的 API 是实现一个基于NSFileProviderReplicatedExtension 的文件提供程序。
不幸的是,它NSFileProviderReplicatedExtension有几个缺陷:
enumerators. 因此,必须首先枚举(列出)文件夹内的所有内容。否则无法访问。但是,我们无法枚举我们的 VFS。我们的 VFS 的大部分内容都是完全动态的。它仅在客户端第一次访问时存在。此类动态内容还包括动态参数,例如客户端的区域设置或将放置图像的框的大小。由于我们事先不知道这些参数,因此我们无法提前枚举VFS的内容。这意味着,NSFileProviderReplicatedExtension当前状态下的 an 并不是“真实”VFS 的替代品,因此我们不能将其用作当前 VFS KEXT 的替代品。
我的问题:
macos vfs kernel-extension fileprovider-extension macos-system-extension
我是 Apple DriverKit SDK 的新手,我不清楚如何注册我的设备驱动程序,以便它可以作为操作系统中的相机使用。我是否必须在 IOService 的 Start 函数中注册流函数?我在互联网上搜索答案,但找不到。
我需要从自定义 USB 摄像头读取数据,然后通过自定义驱动程序使其可用。
你们有人能帮我吗?
我需要在Mac OS X上获取已安装本地卷的列表.以前,Cocoa类NSWorkspace有一个获取此类卷的挂载点数组的mountedLocalVolumePaths方法.从Lion开始,现在已经弃用了这个,在文档中没有提示我们应该使用什么.
我发现提供此信息的唯一其他Apple特定API是CoreServices.framework中的FSGetVolumeInfo函数.如果你通过此列举了已安装卷kFSInvalidVolumeRefNum的卷参数和1..1的volumeIndex.它HFSUniStr255通过volumeName输出参数返回卷名(作为a ),通过rootDirectory输出参数返回挂载点作为a FSRef,然后可以使用转换为URL CFURLCreateFromFSRef().
这似乎有点复杂和不必要的低级别.
也存在BSD级的功能,getfsstat()并且getmntinfo()其中两个发射的阵列statfs结构.API似乎比核心服务版本更健全.
我应该使用更高级别的替代品吗?
我不确定如何com.apple.developer.driverkit.transport.usb在我的 dext 权利文件中设置密钥。Info.plist 文件已经包含该IOKitPersonalities字典,并且阅读该com.apple.developer.driverkit.transport.usb字典后,它看起来应该包含与 的条目具有相同信息的条目IOKitPersonalities。
项目的权利文件与WWDC 驱动程序套件视频中显示的内容非常相似,将其设置为:
<key>com.apple.developer.driverkit.transport.usb</key>
<true/>
Run Code Online (Sandbox Code Playgroud)
当我将其设置为 时<true/>,系统扩展启动。在看到应用程序的日志行之前,我确实看到了这样的一些行:
...
2020-05-06 12:23:19.229709+0200 0x51ac2 Default 0x0 0 0 kernel: DK: IOUserServer(sc.example.MyUserUSBInterfaceDriver-0x100002aad)::exit(CDHash check failed)
Run Code Online (Sandbox Code Playgroud)
这个权利应该只反映字典中的内容吗IOKitPersonalities?
钥匙完全拔掉后,我得到:
...
2020-05-06 12:23:19.229709+0200 0x51ac2 Default 0x0 0 0 kernel: DK: IOUserServer(sc.example.MyUserUSBInterfaceDriver-0x100002aad)::exit(CDHash check failed)
2020-05-06 12:23:19.253517+0200 0x51ac2 Default 0x0 0 0 kernel: DK: IOUserServer(sc.example.MyUserUSBInterfaceDriver-0x100002aae)::exit(Entitlements check failed)
Run Code Online (Sandbox Code Playgroud)
..所以我想钥匙一定在那里。
我正在查看与应用程序相关的日志行log stream --source | grep MyUserUSBInterfaceDriver
我们已请求与 DriverKit 相关的所有权利。我们得到的内容如下:
com.apple.developer.driverkitcom.apple.developer.driverkit.transport.hidcom.apple.developer.driverkit.family.hid.devicecom.apple.developer.driverkit.family.hid.eventservicecom.apple.developer.driverkit.family.hid.virtual.device我们刚刚了解到,如果我们想要分发能够与 DriverKit 通信的应用程序,则com.apple.developer.driverkit.userclient-access需要授权。但是我们不知道如何生成包含此权利的配置文件。在向 Apple 发送请求权利时,我们是否遗漏了某些内容?或者当我们选择适当的功能时,该权利已在某些项目上准备就绪?
我尝试以编程方式在 Mac OS 中添加带有驱动程序的虚拟 USB 设备。IOKit 文档说:传统上,虚拟设备的驱动程序在 IOResources 上匹配,因为虚拟设备不发布自己的 nub。此类驱动程序的另一个示例是 HelloIOKit KEXT(在“使用 Xcode 创建设备驱动程序”中描述),它匹配 IOResources,因为它不控制任何硬件。
但是我没有找到在系统中添加虚拟设备的方法。我怎样才能做到这一点?