Date: Sat, 27 Jul 2013 09:12:01 +0300 From: Konstantin Belousov <kostikbel@gmail.com> To: ret val <retval42@gmail.com> Cc: freebsd-drivers@freebsd.org Subject: Re: mysterious locking issue Message-ID: <20130727061201.GU5991@kib.kiev.ua> In-Reply-To: <CAHORHL=yF3V2--HxuahNDQjYRwThKZY0_gUXk0SsZA8gu8FDAQ@mail.gmail.com> References: <CAHORHL=yF3V2--HxuahNDQjYRwThKZY0_gUXk0SsZA8gu8FDAQ@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--QMcAIMJS2LNMCtSQ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable 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. >=20 > 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 >=20 > The backtrace looks like: > panic > _mtx_assert > thread_single > kern_execve > event_handler >=20 > 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. >=20 > 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> >=20 > int DEBUG=3D1; >=20 > static int make_args(struct image_args *args, char *fname, char **argv, > char **envv) { > int i; > size_t length; >=20 > memset(args, 0, sizeof(struct image_args)); > if(exec_alloc_args(args) !=3D 0) { > if(DEBUG) { > printf("exec_alloc_args() failed\n"); > uprintf("exec_alloc_args() failed\n"); > } > return ENOMEM; > } > // fname > args->fname =3D args->buf; > length =3D 1 + strlen(fname); > memcpy(args->fname, fname, length); > // args > args->begin_argv =3D args->buf + 1 + strlen(fname); > args->endp =3D args->begin_argv; >=20 > for(i =3D 0; argv[i] !=3D NULL; ++i) { > length =3D 1 + strlen(argv[i]); > memcpy(args->endp, argv[i], length); > args->stringspace -=3D length; > args->endp +=3D length; > (args->argc)++; > } > // envv > args->begin_envv =3D args->endp; > args->endp =3D args->begin_envv; > for(i =3D 0; envv[i] !=3D NULL; ++i) { > length =3D 1 + strlen(envv[i]); > memcpy(args->endp, envv[i], length); > args->stringspace -=3D length; > args->endp +=3D length; > (args->envc)++; > } > return 0; > } >=20 > static int runapp_init(void) { > int error; > char *argv[] =3D { "/usr/bin/logger", "it works", NULL }; > char *envv[] =3D { NULL }; > struct image_args args; > error =3D make_args(&args, argv[0], argv, envv); > if(error !=3D 0) { > return error; > } > error =3D kern_execve(curthread, &args, NULL); > if(error !=3D 0) { > if(DEBUG) { > printf("kern_execve() failed\n"); > uprintf("kern_execve() failed\n"); > } > return error; > } > return 0; > } >=20 > 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; > } >=20 > return EOPNOTSUPP; > } >=20 > static moduledata_t runapp_conf =3D { > "runapp", /* module name */ > event_handler, /* event handler */ > NULL /* extra data */ > }; >=20 > 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" --QMcAIMJS2LNMCtSQ Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.20 (FreeBSD) iQIcBAEBAgAGBQJR82SwAAoJEJDCuSvBvK1BuyYP/0SPZFQRd9sh0+XICE+8gdJi 5Wa6LnQluN3NjPPOOtFGva6ZsSzZ8VNUreGfFCETNQZ3fXz9F5M8WHIDdtAi1qFB GNWnS+lhyno7zpT4+SEWv1TowCJzrKYpiMPrFN4D4xQTIueBT5MNsWMSAOemCAi7 cVv7qaYp0azRmg4V0+ZjrsXHE/Wa8Lcz4vnpwKfjgvqIoTQ6TmGEbgMnSYR/dXZv WTk26Wn8K3pLe6jC2tqqJVEzy8EoRk7x5YCmTatNYFCFcQe3z2upFX004qtM/WSo 5I1w4SqNAiMOWXkPw2aBYK6pq2TacTQ0d/OIbcenFu2mef1ML9jWEwrg0kjAmBBn 1RjF5MCeomMkA59IGMpvzFyspul0qRXAeDYElpz5iht1VV9FGkqrIE+b7xJqRMb4 yr7BT/c0jN62hsAzRW9JQRgBICt3qoSWboRs2+q4MqZD5ZuVGOmruQZMxTDHWEen CgjzR2+uHl5IfMU6Qp5gwACFcuSHLwtkRXkzUHMURdwMMHGtL7dyM+KCcs7IDGNw /4d2b58/sLWv9jKvnjwuHQvZul/8wyeYLm0OUZzcN6MWEiIgsFecGCmLhATN2N5g Al1KDvelQ5I5QKCpVfb6V4HLzkQd+YPpZUGAyP0CIVUSOghEthqaFGVbxG8/s8zd jFNz+YkmInFrGIiWxWY2 =yCKh -----END PGP SIGNATURE----- --QMcAIMJS2LNMCtSQ--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130727061201.GU5991>