Re: Deadlock in My KEXT with NKE
Re: Deadlock in My KEXT with NKE
- Subject: Re: Deadlock in My KEXT with NKE
- From: Matt Jaffa <email@hidden>
- Date: Sat, 14 Feb 2004 15:58:15 -0700
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 | email@hidden
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 | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.