Best way to communicate from KEXT to Daemon and block until result is returned from Daemon
iokit, kernel-extension, launch-daemon, mach, macos
Solution
The pattern I've used for that process is to have the user-space process initiate a socket connection to the KEXT; the KEXT creates a new thread to handle messages over that socket and sleeps the thread. When the KEXT detects an event it needs to respond to, it wakes the messaging thread and uses the existing socket to send data to the daemon. On receiving a response, control is passed back to the requesting thread to decide whether to veto the operation.
I don't know of any single resource that will describe that whole pattern completely, but the relevant KPIs are discussed in Mac OS X Internals (which seems old, but the KPIs haven't changed much since it was written) and OS X and iOS Kernel Programming (which I was a tech reviewer on).
Problem
In KEXT, I am listening for file close via vnode or file scope listener. For certain (very few) files, I need to send file path to my system daemon which does some processing (this has to happen in daemon) and returns the result back to KEXT. The file close call needs to be blocked until I get response from daemon. Based on result I need to some operation in close call and return close call successfully. There is lot of discussion on KEXT communication related topic on the forum. But they are not conclusive and appears be very old (year 2002 around). This requirement can be handled by `FtlSendMessage(...)` Win32 API. I am looking for equivalent of that on Mac Here is what I have looked at and want to summarize my understanding: - Mach message: Provides very good way of bidirectional communication using sender and reply ports with queueing mechansim. However, the mach message APIs (e.g. `mach_msg`, `mach_port_allocate`, `bootstrap_look_up`) don't appear to be KPIs. The mach API `mach_msg_send_from_kernel` can be used, but that alone will not help in bidirectional communication. Is my understanding right? - IOUserClient: This appears be more to do with communicating from User space to KEXT and then having some callbacks from KEXT. I did not find a way to initiate communication from KEXT to daemon and then wait for result from daemon. Am I missing something? - Sockets: This could be last option since I would have to implement entire bidirectional communication channel from KEXT to Daemon. - `ioct`l/`sysctl`: I don't know much about them. From what I have read, its not recommended option especially for bidirectional communication - RPC-Mig: Again I don't know much about them. Looks complicated from what I have seen. Not sure if this is recommended way. - KUNCUserNotification: This appears to be just providing notification to the user from KEXT. It does not meet my requirement. Supported platform is (10.5 onwards). So looking at the requirement, can someone suggest and provide some pointers on this topic? Thanks in advance.