【问题标题】:Can Kernel Control API support multiple, simultaneous client connections?内核控制 API 可以支持多个同时的客户端连接吗?
【发布时间】:2016-01-20 11:42:20
【问题描述】:
我正在使用Kernel Control API (SYSPROTO_CONTROL) 让用户级应用程序根据Apple's documentation 中的代码从内核扩展请求信息。
在一个连接的客户端上,一切都按预期工作。如果第二个客户端在第一个客户端连接时尝试连接,则会失败并显示以下消息:-
错误 16(资源繁忙)。
然后第一个客户端会自动断开。
是否可以使用内核控制 API 连接两个客户端,如果不能,如果资源繁忙,是否是继续尝试连接的最佳解决方案?
【问题讨论】:
标签:
macos
sockets
kernel
kernel-extension
【解决方案1】:
我不知道这是否可行,但推荐的方法是始终只有一个用户空间客户端与一个内核扩展通信,通常是在用户空间中运行并由launchd 启动的后台守护程序。如果您希望多个其他应用程序或进程从您的内核扩展访问数据或以某种方式与之交互,那么这些将与用户空间守护进程对话,而不是直接与内核扩展对话,内核扩展也可以在用户空间中缓存数据作为跨越用户空间/内核空间桥对数据来说总是很昂贵,所以当 10 个进程都想要相同的数据时,最好只从内核中提取一次,然后使用您选择的任何 IPC 机制在用户空间中分发 10 次。
建议使用此设置,因为您应该将内核控制限制为根进程(使用CTL_FLAG_PRIVILEGED 标志),因此您的守护程序将作为这样的根进程运行,而普通应用程序和进程以当前用户的权限运行。这样的根助手守护程序可以捆绑在应用程序包中并使用SMJobBless API,守护程序会自动复制到/Library/PrivilegedHelperTools,并且它是嵌入式plist(请参阅SMJobBless 文档,仅在其头文件AFAIK 中可用)复制到/Library/LaunchDaemons 并注册到launchd。在这样的 plist 中,当守护程序应由 launchd 启动时,您可以使用各种触发器,例如当您的应用程序尝试连接到特定的 IPC UNIX 套接字时。然后,您在应用程序中要做的就是尝试打开该套接字,launchd 将为您检测并启动守护程序,然后它可以使用 launchd 的 API 来获取该连接的套接字并立即开始与您的应用程序对话。所以整个东西只安装一次,然后每次启动你的应用程序时都会自动启动。
对于SMJobBless 示例项目,see here。