Index: stand/defaults/loader.conf.5 =================================================================== --- stand/defaults/loader.conf.5 (révision 360566) +++ stand/defaults/loader.conf.5 (copie de travail) @@ -23,7 +23,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd October 6, 2018 +.Dd April 29, 2020 .Dt LOADER.CONF 5 .Os .Sh NAME @@ -91,6 +91,10 @@ .It Ar loader_conf_files Defines additional configuration files to be processed right after the present file. +.Ar loader_conf_files +should be treated as write-only. +One cannot depend on any value remaining in the loader environment or carried +over into the kernel environment. .It Ar kernel Name of the kernel to be loaded. If no kernel name is set, no additional Index: stand/lua/cli.lua =================================================================== --- stand/lua/cli.lua (révision 360566) +++ stand/lua/cli.lua (copie de travail) @@ -125,6 +125,11 @@ core.autoboot(argstr) end +cli['read-conf'] = function(...) + local _, argv = cli.arguments(...) + config.readConf(assert(core.popFrontTable(argv))) +end + cli['reload-conf'] = function(...) config.reload() end Index: stand/lua/config.lua =================================================================== --- stand/lua/config.lua (révision 360566) +++ stand/lua/config.lua (copie de travail) @@ -61,6 +61,17 @@ local WORDEXPR = "([%w]+)" local WORDREPL = WORDEXPR:gsub('%%', '%%%%') +-- Entries that should never make it into the environment; each one should have +-- a documented reason for its existence, and these should all be implementation +-- details of the config module. +local loader_env_restricted_table = { + -- loader_conf_files should be considered write-only, and consumers + -- should not rely on any particular value; it's a loader implementation + -- detail. Moreover, it's not a particularly useful variable to have in + -- the kenv. Save the overhead, let it get fetched other ways. + loader_conf_files = true, +} + local function restoreEnv() -- Examine changed environment variables for k, v in pairs(env_changed) do @@ -88,14 +99,31 @@ env_restore = {} end +-- XXX This getEnv/setEnv should likely be exported at some point. We can save +-- the call back into loader.getenv for any variable that's been set or +-- overridden by any loader.conf using this implementation with little overhead +-- since we're already tracking the values. +local function getEnv(key) + if loader_env_restricted_table[key] ~= nil or + env_changed[key] ~= nil then + return env_changed[key] + end + + return loader.getenv(key) +end + local function setEnv(key, value) + env_changed[key] = value + + if loader_env_restricted_table[key] ~= nil then + return 0 + end + -- Track the original value for this if we haven't already if env_restore[key] == nil then env_restore[key] = {value = loader.getenv(key)} end - env_changed[key] = value - return loader.setenv(key, value) end @@ -340,34 +368,6 @@ return status end -local function readConfFiles(loaded_files) - local f = loader.getenv("loader_conf_files") - if f ~= nil then - for name in f:gmatch("([%w%p]+)%s*") do - if loaded_files[name] ~= nil then - goto continue - end - - local prefiles = loader.getenv("loader_conf_files") - - print("Loading " .. name) - -- These may or may not exist, and that's ok. Do a - -- silent parse so that we complain on parse errors but - -- not for them simply not existing. - if not config.processFile(name, true) then - print(MSG_FAILPARSECFG:format(name)) - end - - loaded_files[name] = true - local newfiles = loader.getenv("loader_conf_files") - if prefiles ~= newfiles then - readConfFiles(loaded_files) - end - ::continue:: - end - end -end - local function readFile(name, silent) local f = io.open(name) if f == nil then @@ -488,6 +488,40 @@ return status end +function config.readConf(file, loaded_files) + if loaded_files == nil then + loaded_files = {} + end + + if loaded_files[file] ~= nil then + return + end + + print("Loading " .. file) + + -- The final value of loader_conf_files is not important, so just + -- clobber it here. We'll later check if it's no longer nil and process + -- the new value for files to read. + setEnv("loader_conf_files", nil) + + -- These may or may not exist, and that's ok. Do a + -- silent parse so that we complain on parse errors but + -- not for them simply not existing. + if not config.processFile(file, true) then + print(MSG_FAILPARSECFG:format(file)) + end + + loaded_files[file] = true + + -- Going to process "loader_conf_files" extra-files + local loader_conf_files = getEnv("loader_conf_files") + if loader_conf_files ~= nil then + for name in loader_conf_files:gmatch("[%w%p]+") do + config.readConf(name, loaded_files) + end + end +end + -- other_kernel is optionally the name of a kernel to load, if not the default -- or autoloaded default from the module_path function config.loadKernel(other_kernel) @@ -596,13 +630,8 @@ file = "/boot/defaults/loader.conf" end - if not config.processFile(file) then - print(MSG_FAILPARSECFG:format(file)) - end + config.readConf(file) - local loaded_files = {file = true} - readConfFiles(loaded_files) - checkNextboot() local verbose = loader.getenv("verbose_loading") or "no" Index: stand/lua/config.lua.8 =================================================================== --- stand/lua/config.lua.8 (révision 360566) +++ stand/lua/config.lua.8 (copie de travail) @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 9, 2018 +.Dd April 30, 2020 .Dt CONFIG.LUA 8 .Os .Sh NAME @@ -59,6 +59,24 @@ A lookup will be done as needed to determine what value .Ev idx actually corresponds to. +.It Fn config.readConf file loaded_files +Process +.Pa file +as a configuration file +.Po e.g., as +.Pa loader.conf +.Pc +and then processing files listed in +.Ev loader_conf_files +variable +.Po see +.Xr loader.conf 5 +.Pc . +The caller may optionally pass in a table as the +.Ev loaded_files +argument, which uses filenames as keys and any non-nil value to +indicate that the file named by the key has already been loaded and +should not be loaded again. .It Fn config.processFile name silent Process and parse .Ev name @@ -171,8 +189,10 @@ The following hooks are defined in .Nm : .Bl -tag -width "config.reloaded" -offset indent -.It config.loaded -.It config.reloaded +.It Fn config.loaded +.It Fn config.reloaded +.It Fn kernel.loaded +.It Fn modules.loaded .El .Sh SEE ALSO .Xr loader.conf 5 ,