boot/loader: Handle the /boot/modules.local
authorzrj <rimvydas.jasinskas@gmail.com>
Tue, 26 Apr 2016 14:28:27 +0000 (17:28 +0300)
committerzrj <zrj@dragonflybsd.org>
Thu, 28 Apr 2016 14:33:27 +0000 (17:33 +0300)
Weather /boot/modules.local is used during boot or by kldload(8)
is controlled by a new "local_modules" loader variable.

If local_modules is set to "YES", /boot/modules.local is also
appended to kern.module_path sysctl variable for use by kldload(8).
Setting variable to any other value disables that.

By default allow modules to searched in /boot/modules.local directory
since it does not shadow the default kernel modules and has lower
directory search priority.

sys/boot/common/load_elf.c
sys/boot/common/loader.8
sys/boot/common/module.c
sys/boot/dloader/cmds.c
sys/boot/dloader/loader-bootp.conf
sys/boot/dloader/loader.conf

index 2f6c1f2..829daf8 100644 (file)
@@ -204,6 +204,7 @@ __elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result)
     if (ef.kernel) {
        char *mptr;
        char *fpend;
+       char *modlocal;
        const char *prefix = "";
 
        mptr = malloc(strlen(fullpath) * 2 + 10 + 16);
@@ -216,6 +217,12 @@ __elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result)
        *fpend = 0;
        if (strcmp(mptr, "/boot") == 0)
                sprintf(mptr, "/boot/modules");
+
+       /* Append modules.local for kernel if requested */
+       modlocal = getenv("local_modules");
+       if (modlocal != NULL && strcmp(modlocal, "YES") == 0)
+               strncat(mptr, ";/boot/modules.local", strlen(fullpath) * 2 + 26);
+
        /* this will be moved to "module_path" on boot */
        setenv("exported_module_path", mptr, 1);
        free(mptr);
index 886142b..b1facea 100644 (file)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD: src/sys/boot/common/loader.8,v 1.57 2003/06/29 20:57:55 brueffer Exp $
 .\"
-.Dd July 23, 2015
+.Dd April 28, 2016
 .Dt LOADER 8
 .Os
 .Sh NAME
@@ -551,6 +551,15 @@ See also
 command.
 .It Va LINES
 Define the number of lines on the screen, to be used by the pager.
+.It Va local_modules
+Setting this variable to
+.Dq Li YES
+causes
+.Pa /boot/modules.local
+to be included after
+.Va modules_path
+directories list and passed to kernel for
+.Xr kldload 8 .
 .It Va module_path
 Sets the list of directories which will be searched for modules named in a
 .Nm load
index d3b04a6..72335f8 100644 (file)
@@ -69,6 +69,7 @@ static void                   moduledir_rebuild(void);
 static vm_offset_t     loadaddr = 0;
 
 static const char      *default_searchpath ="modules;KERNEL";
+static const char      *local_module_path = "../modules.local";
 
 static STAILQ_HEAD(, moduledir) moduledir_list = STAILQ_HEAD_INITIALIZER(moduledir_list);
 
@@ -1021,7 +1022,7 @@ static void
 moduledir_rebuild(void)
 {
     struct     moduledir *mdp, *mtmp;
-    const char *path, *cp, *ep;
+    const char *path, *cp, *ep, *modlocal;
     int                cplen;
 
     path = getenv("module_path");
@@ -1062,6 +1063,31 @@ moduledir_rebuild(void)
        if (*ep == 0)
            break;
     }
+    /*
+     * Include modules.local if requested
+     */
+    modlocal = getenv("local_modules");
+    if (modlocal != NULL && strcmp(modlocal, "YES") == 0) {
+       cp = local_module_path;
+       cplen = strlen(local_module_path);
+       STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
+           if (strlen(mdp->d_path) != (unsigned)cplen || bcmp(cp, mdp->d_path, cplen) != 0)
+               continue;
+           mdp->d_flags &= ~MDIR_REMOVED;
+           break;
+       }
+       if (mdp == NULL) {
+           mdp = malloc(sizeof(*mdp) + cplen + 1);
+           if (mdp == NULL)
+               return;
+           mdp->d_path = (char*)(mdp + 1);
+           bcopy(local_module_path, mdp->d_path, cplen);
+           mdp->d_path[cplen] = 0;
+           mdp->d_hints = NULL;
+           mdp->d_flags = 0;
+           STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link);
+       }
+    }
     /*
      * Delete unused directories if any
      */
index 16ea658..8de1ab4 100644 (file)
@@ -88,6 +88,7 @@ static char *kenv_vars[] = {
        "kernel_options",
        "kernelname",
        "loaddev",
+       "local_modules",
        "module_path",
        "num_ide_disks",
        "prompt",
index eb13f4e..6809eb7 100644 (file)
@@ -14,7 +14,7 @@
 
 default_kernel="kernel"
 kernel="kernel.BOOTP"
-bootfile="kernel.BOOTP"        # Kernel name (possibly absolute path)
+bootfile="kernel.BOOTP"                # Kernel name (possibly absolute path)
 kernel_options=""
 
 
@@ -39,6 +39,7 @@ bitmap_type="splash_image_data" # and place it on the module_path
 #loader_color="NO"             # Set to YES for a color version of Fred
 #console="vidconsole"          # Set the current console
 #currdev="disk1s1a"            # Set the current device
+local_modules="YES"            # Use local modules and firmware
 module_path=";modules"         # Set the module search path
 #prompt="OK"                   # Set the command prompt
 #root_disk_unit="0"            # Force the root disk unit number
index 0dca075..033bcda 100644 (file)
@@ -15,7 +15,7 @@
 # WARNING: Do not set default_kernel here, it is set conditionally
 #         in dloader.menu
 kernel="kernel"
-bootfile="kernel"      # Kernel name (possibly absolute path)
+bootfile="kernel"              # Kernel name (possibly absolute path)
 kernel_options=""
 
 
@@ -42,6 +42,7 @@ bitmap_type="splash_image_data" # and place it on the module_path
 #fred_is_red="NO"              # Show Fred in red scheme rather than blue
 #console="vidconsole"          # Set the current console
 #currdev="disk1s1a"            # Set the current device
+local_modules="YES"            # Use local modules and firmware
 #module_path=";modules"                # Set the module search path
 #prompt="OK"                   # Set the command prompt
 #root_disk_unit="0"            # Force the root disk unit number