Index: stand/common/boot.c =================================================================== --- stand/common/boot.c +++ stand/common/boot.c @@ -32,10 +32,12 @@ */ #include +#include #include #include "bootstrap.h" +static int try_kernel(const char *kernel, int argc, char *argv[]); static char *getbootfile(int try); static int loadakernel(int try, int argc, char* argv[]); @@ -44,6 +46,58 @@ static int autoboot_tried; +static int +try_kernel(const char *kernel, int argc, char *argv[]) +{ + char kernel_module_path[PATH_MAX]; + char *new_module_path; + const char *module_path; + int module_path_len, rv; + + /* find/load the kernel module */ + module_path = NULL; + new_module_path = NULL; + rv = mod_loadkld(kernel, argc - 2, argv + 2); + if (rv == 0) + goto exit; + /* + * Still nothing ... try again with a modified module_path to include + * the supposed location of this explicitly specified kernel + */ + module_path = getenv("module_path"); + sprintf(kernel_module_path, "/boot/%s", kernel); + if (module_path != NULL) { + module_path_len = strlen(kernel_module_path); + /* + 1 for the separator */ + module_path_len += strlen(module_path) + 1; + new_module_path = malloc(module_path_len + 1); + snprintf(new_module_path, module_path_len + 1, + "%s;%s", kernel_module_path, module_path); + } else + new_module_path = kernel_module_path; + if (setenv("module_path", new_module_path, 1) != 0) + goto fail; + rv = mod_loadkld(default_bootfiles, argc - 2, argv + 2); + if (rv == 0) + goto exit; +fail: + rv = CMD_ERROR; + /* We failed! Try to restore module_path */ + if (module_path != NULL) + /* + * We're already on a failure path, not a whole lot we can do + * if this fails. + */ + setenv("module_path", module_path, 1); + else + /* module_path ws not previously set */ + unsetenv("module_path"); +exit: + if (module_path != NULL) + free(new_module_path); + return (rv); +} + /* * The user wants us to boot. */ @@ -66,9 +120,9 @@ return(CMD_ERROR); } - /* find/load the kernel module */ - if (mod_loadkld(argv[1], argc - 2, argv + 2) != 0) - return(CMD_ERROR); + if (try_kernel(argv[1], argc, argv) != 0) + return (CMD_ERROR); + /* we have consumed all arguments */ argc = 1; }