sosend() and mbuf

John Baldwin jhb at freebsd.org
Tue Aug 4 21:01:57 UTC 2009


On Monday 03 August 2009 5:25:27 pm Maslan wrote:
> No my code doesn't work, I thought it may be because that soaccept()
> -which is not found in man 9- is non-blocking, so i've to put my code
> in a thread.
> Now i got another problem, when I open a text file from this thread,
> the kernel crashes, I'm sure that its the thread.
> 
> kthread_create((void *)thread_main, NULL, NULL, RFNOWAIT, 0, "thread");
> 
> void thread_main(){
> 	struct thread *td = curthread;
> 	int ret;
> 	int fd;
> 	ret = f_open("/path/to/file.txt", &fd);
> 	printf("%d\n", ret);
> 	tsleep(td, PDROP, "test tsleep", 10*hz);
>         f_close(fd);
> 	kthread_exit(0);
> }
> 
> int f_open(char *filename, int *fd){
> 	struct thread *td = curthread;
> 	int ret = kern_open(td, filename, UIO_SYSSPACE, O_RDONLY, FREAD);
> 	if(!ret){
> 		*fd = td->td_retval[0];
> 		return 1;
> 	}
> 	return 0;
> }

kthread's / kproc's do not have a valid file descriptor table.  I think you 
are probably not going to be happy trying to stuff a full httpd in the 
kernel, btw.  I think instead you should look at creative ways of exposing 
certain bits of what you need to userland instead where possible.  
Alternatively, you could use a caching accelerator of some sort that maps 
known URLs to specific vnodes so you can reply to those directly, but when 
you miss in your cache you wake up a userland process which processes the URL 
and opens a file and you can then save the vnode from that file handle in 
your cache.  However, stuffing httpd into the kernel may not buy you an 
appreciable amount of gain relative to the expense of making it work.

BTW, kern_open() "works" in your module handler because the module handler 
runs in the kernel half of the thread from the kldload command.  And when you 
do "kern_open()" you are actually opening a new file descriptor in the 
kldload process.  This is quite a bad, bad idea to be indiscriminately 
screwing with user process' file descriptors behind their back.  A brief 
search in the archives should cover how to initalize the necessary vnode 
references for a kproc's file descriptor table so that namei() works (and 
then you can use vn_open(), but _not_ kern_open()).  I answered that question 
just last week in another thread ("Driver development question" on drivers@).

However, in general the kernel is not nearly as friendly an environment as 
userland, and it can be quite saner and easier to debug if you export certain 
bits of the kernel to userland to accelerate portions of your application 
than moving the application into the kernel in my experience.

-- 
John Baldwin


More information about the freebsd-hackers mailing list