Re: Deadlock in My KEXT with NKE
Vincent, I have been trying to implement this System control socket, but can't seem to get it to work, The problem is I don't know how to make sockets within the KERNEL connect up with the socket in my Daemon. I wan't the Daemon socket to act as the server and the KEXT socket to call out when it has work to do then wait to receive a message back. I can do this with AF_UNIX when it is daemon to daemon, but I can't get KEXT to daemon sockets to work. Do you know of any code out there that can demonstrate the KEXT connecting to a daemon socket? Thanks, Matt On Feb 13, 2004, at 12:43 AM, Vincent Lubet wrote: On Feb 12, 2004, at 1:30 PM, matt jaffa wrote: With the daemon I pass in a socket structure that was created within my daemon, so that the KEXT creates its own AF_UNIX socket with socreate, and then binds them with unp_connect as webdav uses, but somebody earlier pointed out that webdav uses a file descriptor to do that, but my approach won't work, If my approach doesn't work, then How can I go about using local sockets to fix my problem, like how do i connect the two up? Although it should work in principle, having a listening socket in the Kernel does not work due to implementation limitations. Using an AF_UNIX socket is quite complicated, much harder than using a system control socket (SYSPROTO_CONTROL). I have found an example that illustrates how simple it is to write such a communication channel. It shows how to set socket options from user land to the kernel as well as how to send data up from the kernel on the control socket. ----- code start here ---- /* * Sample System Socket Controller NKE * * Copyright(C) 2002-2004 Apple Computer, Inc. All rights reserved. */ #include <mach/mach_types.h> #include <sys/types.h> #include <sys/param.h> #include <sys/mbuf.h> #include <sys/kern_control.h> #include <sys/systm.h> static int hellosysprotoctl_connect(kern_ctl_ref , void *); static void hellosysprotoctl_disconnect(kern_ctl_ref , void *); static int hellosysprotoctl_set(kern_ctl_ref , void *, int , void *, size_t ); /* * Important: * * The creator code must registered with Apple DTS * To register a creator code go to http://developer.apple.com/dev/cftype/ */ static struct kern_ctl_reg reg = { 1234, /* Bad example, this is not a registered creator code!!! */ 0, CTL_FLAG_PRIVILEGED, 0, 0, hellosysprotoctl_connect, hellosysprotoctl_disconnect, NULL, hellosysprotoctl_set, NULL, { 0, 0, 0, 0 } }; static kern_ctl_ref ctlref = 0; /* Reference of the kernel controller */ static unsigned long count = 0; /* Prevent unloading KEXT while in use */ int hellosysprotoctl_connect(kern_ctl_ref ctlref, void *userdata) { count++; return 0; } void hellosysprotoctl_disconnect(kern_ctl_ref ctlref, void *userdata) { count--; return; } int hellosysprotoctl_set(kern_ctl_ref ctlref, void *userdata, int opt, void *data, size_t len) { return ctl_enqueuedata(ctlref, data, len, 0); } kern_return_t hellosysprotoctl_start (kmod_info_t * ki, void * d) { if (ctl_register(®, 0, & ctlref); != 0) return KERN_FAILURE; return KERN_SUCCESS; } kern_return_t hellosysprotoctl_stop (kmod_info_t * ki, void * d) { if (count > 0) return KERN_FAILURE; if (ctlref != 0) if (ctl_deregister(ref) != 0) return KERN_FAILURE; return KERN_SUCCESS; } ----- code stops here ---- This is the code of a userland tool that communicates with the controller: ----- code starts here ---- /* * Control tool * * Copyright(C) 2002-2004 Apple Computer, Inc. All rights reserved. */ #include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> #include <sys/errno.h> #include <sys/kern_control.h> #include <sys/sys_domain.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main(int argc, const char **argv) { int s; struct sockaddr_ctl sc; int i; int maxlen = 0; unsigned char *buf = NULL; s = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); if (s < 0) { perror("socket SYSPROTO_CONTROL"); exit(0); } bzero(&sc, sizeof(struct sockaddr_ctl)); sc.sc_len = sizeof(struct sockaddr_ctl); sc.sc_family = AF_SYSTEM; sc.ss_sysaddr = AF_SYS_CONTROL; sc.sc_id = 1234; /* Creator code registered with Apple DTS */ sc.sc_unit = 0; if (connect(s, (struct sockaddr *)&sc, sizeof(struct sockaddr_ctl))) { perror("connect"); exit(0); } for (i = 1; i < argc; i++) { ssize_t n; size_t len = strlen(argv[i]) + 1; /* optname is meaningful to the kernel controller */ if (setsockopt(s, SYSPROTO_CONTROL, i, argv[i], len) == -1) { perror("send"); continue; } printf("setsockopt %lu: %s\n", len, argv[i]); if (len > maxlen) { maxlen = len; if (buf) free(buf); buf = malloc(maxlen); } n = recv(s, buf, maxlen, 0); if (n == -1) { perror("recv"); continue; } printf("recv %d\n", n); } if (buf) close(s); return 0; } ----- code stops here ---- Let me know if this suits your needs. Vincent _______________________________________________ darwin-kernel mailing list | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored. _______________________________________________ darwin-kernel mailing list | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.
participants (1)
-
Matt Jaffa