Date: Sat, 27 Jul 2013 12:35:40 -0400 From: ret val <retval42@gmail.com> To: Konstantin Belousov <kostikbel@gmail.com> Cc: freebsd-drivers@freebsd.org Subject: Re: mysterious locking issue Message-ID: <CAHORHLmJnz3BW1411rmb0ojr3vAFAL3Riq=jbZRexbn%2B9x0r%2Bg@mail.gmail.com> In-Reply-To: <20130727061201.GU5991@kib.kiev.ua> References: <CAHORHL=yF3V2--HxuahNDQjYRwThKZY0_gUXk0SsZA8gu8FDAQ@mail.gmail.com> <20130727061201.GU5991@kib.kiev.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
Alright, this is making much more sense now. Thank you. Would it be possible to create a new thread and sleep until the kernel is fully initialized? Is there some event I could possible wait for? While my approach now seems wrong, It seems like this should be doable. On Sat, Jul 27, 2013 at 2:12 AM, Konstantin Belousov <kostikbel@gmail.com>wrote: > On Sat, Jul 27, 2013 at 12:46:09AM -0400, ret val wrote: > > I'm working on porting a driver form Linux that uses the usermode helper > > API to call a user land program from the driver. Yes, I know this is > ugly. > > Yes, I'm sure sure there would of been many better other ways to go about > > this... For right now I'm just doing a straight port. > Kernel startup is single-threaded and owns the Giant. You are trying > to call kern_execve() from the startup thread, which is the immediate > cause of your problem. > > If you think about this some more, you would see that this cannot work > when module is initialized at the boot. Because kernel is not fully > initialized yet, the scheduler and usermode does not work, and there > is no filesystem mounted from which to execute the image. Much worse > is that you are trying to change the executing image of the usermode > program for a situation where there is no usermode and the process which > is executing is the kernel startup. > > FWIW, your code also does not quite work for the kldload case as well. > You are execing in the context of the kldload, not allowing the normal > kldload operation to finish. > > > > > Anyway, I working on my own routine for this but unfortunately I get a > > kernel panic on boot when my module is loaded. Oddly enough it works fine > > if I load it by hand after boot. I get the following: panic: mutex Giant > > owned at /usr/src/sys/kern/kern_thread.c:616 > > > > The backtrace looks like: > > panic > > _mtx_assert > > thread_single > > kern_execve > > event_handler > > > > Ive tried switching to SI_SUB_EXEC without any luck. Does anyone know how > > to go about fixing this? I cant seem to wrap my head around this. > This is not fixable. > > > > > Incase I cant attach my code, here it is: > > #include <sys/param.h> > > #include <sys/module.h> > > #include <sys/kernel.h> > > #include <sys/systm.h> > > #include <sys/syscallsubr.h> > > #include <sys/imgact.h> > > #include <vm/vm_extern.h> > > #include <sys/kthread.h> > > #include <sys/proc.h> > > > > int DEBUG=1; > > > > static int make_args(struct image_args *args, char *fname, char **argv, > > char **envv) { > > int i; > > size_t length; > > > > memset(args, 0, sizeof(struct image_args)); > > if(exec_alloc_args(args) != 0) { > > if(DEBUG) { > > printf("exec_alloc_args() failed\n"); > > uprintf("exec_alloc_args() failed\n"); > > } > > return ENOMEM; > > } > > // fname > > args->fname = args->buf; > > length = 1 + strlen(fname); > > memcpy(args->fname, fname, length); > > // args > > args->begin_argv = args->buf + 1 + strlen(fname); > > args->endp = args->begin_argv; > > > > for(i = 0; argv[i] != NULL; ++i) { > > length = 1 + strlen(argv[i]); > > memcpy(args->endp, argv[i], length); > > args->stringspace -= length; > > args->endp += length; > > (args->argc)++; > > } > > // envv > > args->begin_envv = args->endp; > > args->endp = args->begin_envv; > > for(i = 0; envv[i] != NULL; ++i) { > > length = 1 + strlen(envv[i]); > > memcpy(args->endp, envv[i], length); > > args->stringspace -= length; > > args->endp += length; > > (args->envc)++; > > } > > return 0; > > } > > > > static int runapp_init(void) { > > int error; > > char *argv[] = { "/usr/bin/logger", "it works", NULL }; > > char *envv[] = { NULL }; > > struct image_args args; > > error = make_args(&args, argv[0], argv, envv); > > if(error != 0) { > > return error; > > } > > error = kern_execve(curthread, &args, NULL); > > if(error != 0) { > > if(DEBUG) { > > printf("kern_execve() failed\n"); > > uprintf("kern_execve() failed\n"); > > } > > return error; > > } > > return 0; > > } > > > > static int event_handler(struct module *module, int event, void *arg) { > > switch(event) { > > case MOD_LOAD: > > printf("Hello, World! I'm loaded!\n"); > > uprintf("Hello, World! I'm loaded!\n"); > > return runapp_init(); > > case MOD_UNLOAD: > > case MOD_QUIESCE: > > printf("Bye Bye Cruel World!\n"); > > printf("Bye Bye Cruel World!\n"); > > return 0; > > } > > > > return EOPNOTSUPP; > > } > > > > static moduledata_t runapp_conf = { > > "runapp", /* module name */ > > event_handler, /* event handler */ > > NULL /* extra data */ > > }; > > > > DECLARE_MODULE(runapp, runapp_conf, SI_SUB_DRIVERS, SI_ORDER_ANY); > > > _______________________________________________ > > freebsd-drivers@freebsd.org mailing list > > http://lists.freebsd.org/mailman/listinfo/freebsd-drivers > > To unsubscribe, send any mail to " > freebsd-drivers-unsubscribe@freebsd.org" > >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAHORHLmJnz3BW1411rmb0ojr3vAFAL3Riq=jbZRexbn%2B9x0r%2Bg>