Best way to communicate from KEXT to Daemon and block until result is returned from Daemon
Asked Answered
S

3

10

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:

  1. 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?
  2. 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?
  3. Sockets: This could be last option since I would have to implement entire bidirectional communication channel from KEXT to Daemon.
  4. ioctl/sysctl: I don't know much about them. From what I have read, its not recommended option especially for bidirectional communication
  5. RPC-Mig: Again I don't know much about them. Looks complicated from what I have seen. Not sure if this is recommended way.
  6. 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.

Subjugate answered 25/4, 2012 at 5:58 Comment(1)
Did you find an example of how to implement this with sockets?Vermifuge
P
4

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).

Pavyer answered 25/4, 2012 at 6:59 Comment(2)
Thanks Graham for your inputs. I will explore using kernel socket option to communicate between KEXT and Daemon. Thanks again.Subjugate
How did you manage to get the socket connection with the Kext? AFAIK you need to use bootstrap.h which isn't available in the Kernel. Because of the need of mach_port_allocate and bootstrap_register.Kizzee
C
1

For what it's worth, autofs uses what I assume you mean by "RPC-Mig", so it's not too complicated (MIG is used to describe the RPC calls, and the stub code it generates handles calling the appropriate Mach-message sending and receiving code; there are special options to generate kernel-mode stubs).

However, it doesn't need to do any lookups, as automountd (the user-mode daemon to which the autofs kext sends messages) has a "host special port" assigned to it. Doing the lookups to find an arbitrary service would be harder.

Consequential answered 28/2, 2013 at 18:37 Comment(0)
N
0

If you want to use the socket established with ctl_register() on the KExt side, then beware: The communication from kext to user space (via ctl_enqueuedata()) works OK. However opposite direction is buggy on 10.5.x and 10.6.x.

After about 70.000 or 80.000 send() calls with SOCK_DGRAM in the PF_SYSTEM domain complete net stack breaks with disastrous consequences for complete system (hard turning off is the only way out). This has been fixed in 10.7.0. I workaround by using setsockopt() in our project for the direction from user space to kext as we only send very small data (just to allow/disallow some operation).

Nashner answered 24/5, 2012 at 14:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.