Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Aug 2009 17:09:00 +0000
From:      Maslan <maslanbsd@gmail.com>
To:        Julian Elischer <julian@elischer.org>
Cc:        Ed Schouten <ed@80386.nl>, FreeBSD Hackers <freebsd-hackers@freebsd.org>
Subject:   Re: sosend() and mbuf
Message-ID:  <319cceca0908041008p2de4452duc55467abbb121e16@mail.gmail.com>
In-Reply-To: <319cceca0908041003o4c313bf6qff57a1f0b752b537@mail.gmail.com>
References:  <319cceca0908030119i3432a495ya60aa431dab0e1b1@mail.gmail.com> <86k51k4kvl.fsf@ds4.des.no> <86fxc84ksj.fsf@ds4.des.no> <200908040138.14743.max@love2party.net> <319cceca0908040227hf9a0f92jbf05b11e9f974994@mail.gmail.com> <20090804093036.GN1292@hoeg.nl> <319cceca0908040239k2accd7fen402db4c91687a267@mail.gmail.com> <4A786302.3090709@elischer.org> <319cceca0908041003o4c313bf6qff57a1f0b752b537@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Guys,

Here is the code, just scroll down and change kthread_create2() to
kthread_create() and it will crash

NOTE: i'm still working on the socket part, u can commend it.

Something wrong with proc0, and I can't figure it out

[-- Attachment #2 --]
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/malloc.h> 	/* malloc, free */
#include <sys/syscallsubr.h>	/* kern_xxx */
#include <sys/fcntl.h>		/* O_RDONLY, FREAD */
#include <sys/proc.h>		/* curthread */
#include <sys/stat.h>		/* struct stat */
#include <sys/socket.h>		/* struct socket, sockaddr */
#include <sys/socketvar.h>	/* soxxx */
#include <netinet/in.h>		/* IPPROTO_TCP */
#include <sys/mbuf.h>		/* mbuf */
#include <sys/kthread.h>	/* kthread_create */
#include <sys/unistd.h>		/* RFNOWAIT */
#include <machine/stdarg.h>	/* valist */
#include <sys/sched.h>		/* sched_add */
#include <sys/mutex.h>		/* mtx_xxx */

MALLOC_DEFINE(M_KERN, "kHTTP", "kHTTP memory");

/* prototypes */
void khttp_main(void);
void* mem_alloc(int);
void mem_free(void *);
int f_open(char *, int *);
int f_close(int);
int f_getsize(int);
int f_read(int, char *, int);
int kthread_create2(void (*func)(void *), void *, struct proc **, int, int, const char *, ...);

static int tstate;
#define T_START 0
#define T_STOP 1
#define T_EXIT 2
 
void khttp_main(){
	struct thread *td = curthread;
	int ret;
	int fd, size;
	char *buf = NULL;
	struct socket *s, *head, *c;
	struct sockaddr_in sa, *ca;
	struct iovec aiov;
	struct uio auio;
	char buf2[] = "lol";


	/* Files */

	ret = f_open("/var/khttp/index.html", &fd);

	size = f_getsize(fd);
	buf = mem_alloc(sizeof(char)*size);
	f_read(fd, buf, size);
	buf[size-1] = 0x0;
	printf("%s\n", buf);
	mem_free(buf);
	f_close(fd);


	/* Sockets */

	ret = socreate(PF_INET, &s, SOCK_STREAM, IPPROTO_TCP, td->td_ucred, td);
	printf("socreate -> %d, retval -> %d\n", ret, td->td_retval[0]);

	bzero(&sa, sizeof(sa));
	sa.sin_len = sizeof(sa);
	sa.sin_family = AF_INET;
	sa.sin_port = htons(8888);
	sa.sin_addr.s_addr = INADDR_ANY;
	sobind(s, (struct sockaddr *)&sa, td);
	printf("sobind -> %d, retval -> %d\n", ret, td->td_retval[0]);

	ret = solisten(s, 4, td);
	printf("solisten -> %d, retval -> %d\n", ret, td->td_retval[0]);

	if ((s->so_options & SO_ACCEPTCONN) == 0)
		printf("ERROR\n"); 

	if (!(s->so_options & SO_ACCEPTCONN))
		printf("NOT ACCEPTING\n");

	head = s;

	/* Main Loop */
	for(;;){
		tsleep(td, PDROP, "kHTTP tsleep", 2*hz);
		if(tstate == T_STOP) break;
	
		ACCEPT_LOCK();
		c = TAILQ_FIRST(&head->so_comp);
		if(c == NULL){
			ACCEPT_UNLOCK();
			continue;
		}
		TAILQ_REMOVE(&head->so_comp, c, so_list);
		head->so_qlen--;
		printf("c = 0x%x\n", (int)c);
		ACCEPT_UNLOCK();
		ret = soaccept(c, (struct sockaddr**)&ca);
		printf("soaccept -> %d, retval -> %d\n", ret, td->td_retval[0]);

		/* iovec */
		aiov.iov_base = buf;
		aiov.iov_len = strlen(buf2);
		/* auio */
		auio.uio_iov = &aiov;
		auio.uio_iovcnt = 1;
		auio.uio_offset = 0;
		auio.uio_resid = strlen(buf2);
		auio.uio_rw = UIO_WRITE;
		auio.uio_segflg = UIO_SYSSPACE;
		auio.uio_td = td;

		//ret = sosend(s, (struct sockaddr*)&client, &auio, NULL, NULL, 0, td); 
		//printf("sosend -> %d, retval -> %d\n", ret, td->td_retval[0]);
	}
	ret = soclose(s);
	printf("soclose -> %d, retval -> %d\n", ret, td->td_retval[0]);

	tstate = T_EXIT;
	kthread_exit(0);
}

void* mem_alloc(int size){
	return malloc(size, M_KERN, M_NOWAIT);
}

void mem_free(void *buf){
	free(buf, M_KERN);
}

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;
}

int f_close(int fd){
	struct thread *td = curthread;
	int ret = kern_close(td, fd);
	if(!ret)
		return 1;
	return 0;
}

int f_getsize(int fd){
	struct thread *td = curthread;
	struct stat st;
	int ret = kern_fstat(td, fd, &st);
	if(!ret)
		return st.st_size;
	return 0;
}

int f_read(int fd, char *buf, int size){
	struct thread *td = curthread;
	int ret;
	struct iovec aiov;
	struct uio auio;

	/* iovec */
	aiov.iov_base = buf;
	aiov.iov_len = size;
	/* auio */
	auio.uio_iov = &aiov;
	auio.uio_iovcnt = 1;
	auio.uio_offset = 0;
	auio.uio_resid = size;
	auio.uio_rw = UIO_READ;
	auio.uio_segflg = UIO_SYSSPACE;
	auio.uio_td = td;

	ret = kern_readv(td, fd, &auio);
	if(!ret)
		return 1;
	return 0;
}

int
kthread_create2(void (*func)(void *), void *arg,
    struct proc **newpp, int flags, int pages, const char *fmt, ...)
{
	int error;
	va_list ap;
	struct thread *td;
	struct proc *p2;

	if (!proc0.p_stats)
		panic("kthread_create called too soon");

	error = fork1(curthread, RFFDG | RFPROC | RFSTOPPED | flags,
	    pages, &p2);
	if (error)
		return error;

	/* save a global descriptor, if desired */
	if (newpp != NULL)
		*newpp = p2;

	/* this is a non-swapped system process */
	PROC_LOCK(p2);
	p2->p_flag |= P_SYSTEM | P_KTHREAD;
	mtx_lock(&p2->p_sigacts->ps_mtx);
	p2->p_sigacts->ps_flag |= PS_NOCLDWAIT;
	mtx_unlock(&p2->p_sigacts->ps_mtx);
	PROC_UNLOCK(p2);

	/* set up arg0 for 'ps', et al */
	va_start(ap, fmt);
	vsnprintf(p2->p_comm, sizeof(p2->p_comm), fmt, ap);
	va_end(ap);

	/* call the processes' main()... */
	td = FIRST_THREAD_IN_PROC(p2);
	cpu_set_fork_handler(td, func, arg);
	TD_SET_CAN_RUN(td);

	/* Delay putting it on the run queue until now. */
	if (!(flags & RFSTOPPED)) {
		thread_lock(td);
		sched_add(td, SRQ_BORING); 
		thread_unlock(td);
	}

	return 0;
}

static int handler(module_t mod, int op, void *arg){
	int err = 0;
	switch(op){
		case MOD_LOAD:
			tstate = T_START;
			printf("kHTTP loaded.\n");
			kthread_create2((void *)khttp_main, NULL, NULL, RFNOWAIT, 0, "kHTTP");
			break;
		case MOD_UNLOAD:
			tstate = T_STOP;
			for(;;){
				if(tstate == T_EXIT) break;
				tsleep(curthread, PDROP, "kHTTP tsleep", 2*hz);
			}
			printf("kHTTP unloaded.\n");
			break;
		default:
			err = EOPNOTSUPP;
			break;
	}
	return(err);
}

static moduledata_t mod_data= {
	"khttp",
	handler,
	0
};

MODULE_VERSION(khttp, 1);
DECLARE_MODULE(kttp, mod_data, SI_SUB_KLD, SI_ORDER_ANY);

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?319cceca0908041008p2de4452duc55467abbb121e16>