diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -445,6 +445,9 @@ SYSINIT(linker_kernel, SI_SUB_KLD, SI_ORDER_ANY, linker_init_kernel_modules, NULL); +/* error for unsatisfied dependency */ +#define EUNSDEP (ELAST + 1) + static int linker_load_file(const char *filename, linker_file_t *result) { @@ -483,7 +486,7 @@ */ if (error != ENOENT) { foundfile = 1; - if (error == EEXIST) + if (error == EEXIST || error == EUNSDEP) break; } if (lf) { @@ -541,7 +544,7 @@ * can recognize this special case and not post bogus * dialog boxes. */ - if (error != EEXIST) + if (error != EEXIST && error != EUNSDEP) error = ENOEXEC; } else error = ENOENT; /* Nothing found */ @@ -565,6 +568,8 @@ error = linker_load_module(NULL, modname, NULL, verinfo, result); sx_xunlock(&kld_sx); + if (error == EUNSDEP) + error = ENOEXEC; return (error); } @@ -1227,6 +1232,8 @@ *fileid = lf->id; } linker_kldload_unbusy(LINKER_UB_LOCKED); + if (error == EUNSDEP) + error = ENOEXEC; return (error); } @@ -2355,8 +2362,33 @@ } error = linker_load_module(NULL, modname, lf, verinfo, NULL); if (error) { - printf("KLD %s: depends on %s - not available or" - " version mismatch\n", lf->filename, modname); + switch (error) { + case ENOENT: + printf("KLD %s: depends on %s - not available\n", + lf->filename, modname); + break; + case EEXIST: + printf("KLD %s: depends on %s - version mismatch\n", + lf->filename, modname); + break; + case ENOEXEC: + printf("KLD %s: depends on %s - file format unrecognized\n", + lf->filename, modname); + break; + case ENOMEM: + printf("KLD %s: depends on %s - no memory\n", + lf->filename, modname); + break; + case EUNSDEP: + printf("KLD %s: depends on %s - transitive dependency error\n", + lf->filename, modname); + break; + default: + printf("KLD %s: depends on %s - can not load, error %d\n", + lf->filename, modname, error); + } + + error = EUNSDEP; break; } } @@ -2364,9 +2396,11 @@ if (error) return (error); linker_addmodules(lf, start, stop, 0); - return (error); + return (0); } +#undef EUNSDEP + static int sysctl_kern_function_list_iterate(const char *name, void *opaque) {