Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Jul 2013 00:46:09 -0400
From:      ret val <retval42@gmail.com>
To:        freebsd-drivers@freebsd.org
Subject:   mysterious locking issue
Message-ID:  <CAHORHL=yF3V2--HxuahNDQjYRwThKZY0_gUXk0SsZA8gu8FDAQ@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
--bcaec51b1b6f215daa04e276f0ae
Content-Type: text/plain; charset=ISO-8859-1

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.

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.

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

--bcaec51b1b6f215daa04e276f0ae--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAHORHL=yF3V2--HxuahNDQjYRwThKZY0_gUXk0SsZA8gu8FDAQ>