git: 3eb3a802a31b - stable/14 - stand/lua: per-product conf if requested via product_vars

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 16 Apr 2024 20:12:29 UTC
The branch stable/14 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=3eb3a802a31ba84d70e1be50c793ec34bec3614f

commit 3eb3a802a31ba84d70e1be50c793ec34bec3614f
Author:     Stéphane Rochoy <stephane.rochoy@stormshield.eu>
AuthorDate: 2023-05-04 07:23:47 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-04-16 19:54:21 +0000

    stand/lua: per-product conf if requested via product_vars
    
    If product_vars is set, it must be a space separated list of environment
    variable names to walk through to guess the product. Each time a product can be
    guessed (i.e., the corresponding variable is defined), prepend
    /boot/loader.conf.d/PRODUCT/ to loader_conf_dirs.
    
    It can be typically used as follow:
    
        smbios.system.planar.maker="PLANAR_MAKER"
        smbios.system.planar.product="PLANAR_PRODUCT"
        smbios.system.product="PRODUCT"
        uboot.m_product="M_PRODUCT"
        product_vars="smbios.system.planar.maker smbios.system.planar.product smbios.system.product uboot.m_product"
    
    to read files found in the following directories, in that order:
    
        /boot/loader.conf.d/PLANAR_MAKER
        /boot/loader.conf.d/PLANAR_PRODUCT
        /boot/loader.conf.d/PRODUCT
        /boot/loader.conf.d/M_PRODUCT
    
    Reviewed by: imp, kevans
    Pull Request: https://github.com/freebsd/freebsd-src/pull/759
    
    [[ The commit, revert, commit has been squashed dpwn ]]
    (cherry picked from commit c343eedc6db381ac76e489f8ae0304898b71c5db)
    (cherry picked from commit 994865caf250ea2a59b7b842e44680931e8b19f6)
    (cherry picked from commit 754cac4b283eb024a3a6a194130199c860e32ebf)
---
 stand/defaults/loader.conf.5 | 34 +++++++++++++++++++++++++++++++++-
 stand/lua/config.lua         | 25 +++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/stand/defaults/loader.conf.5 b/stand/defaults/loader.conf.5
index 42e5712d93b8..0d82a3dac9b3 100644
--- a/stand/defaults/loader.conf.5
+++ b/stand/defaults/loader.conf.5
@@ -21,7 +21,7 @@
 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
-.Dd January 10, 2024
+.Dd February 2, 2024
 .Dt LOADER.CONF 5
 .Os
 .Sh NAME
@@ -138,6 +138,38 @@ present file.
 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 product_vars
+When set, must be a space separated list of environment variable names to walk
+through to guess product information.
+The order matters as reading a config file override the previously defined
+values.
+Undefined variables are silently ignored.
+.Pp
+When product information can be guessed, for each product information found,
+append
+.Pa /boot/loader.conf.d/PRODUCT
+to
+.Ar loader_conf_dirs .
+It can be typically used as follow:
+.Bd -literal
+smbios.system.planar.maker="PLANAR_MAKER"
+smbios.system.planar.product="PLANAR_PRODUCT"
+smbios.system.product="PRODUCT"
+uboot.m_product="M_PRODUCT"
+product_vars="smbios.system.planar.maker smbios.system.planar.product smbios.system.product uboot.m_product"
+.Ed
+.Pp
+to read files found in the following directories, in that order:
+.Bl -bullet -compact
+.It
+.Pa /boot/loader.conf.d/PLANAR_MAKER
+.It
+.Pa /boot/loader.conf.d/PLANAR_PRODUCT
+.It
+.Pa /boot/loader.conf.d/PRODUCT
+.It
+.Pa /boot/loader.conf.d/M_PRODUCT
+.El
 .It Ar kernel
 Name of the kernel to be loaded.
 If no kernel name is set, no additional
diff --git a/stand/lua/config.lua b/stand/lua/config.lua
index 8fdc805ee983..210bb9338783 100644
--- a/stand/lua/config.lua
+++ b/stand/lua/config.lua
@@ -658,12 +658,37 @@ function config.readConf(file, loaded_files)
 
 	if load_conf_dirs then
 		local loader_conf_dirs = getEnv("loader_conf_dirs")
+
+		-- If product_vars is set, it must be a list of environment variable names
+		-- to walk through to guess product information. The order matters as
+		-- reading a config files override the previously defined values.
+		--
+		-- If product information can be guessed, for each product information
+		-- found, also read config files found in /boot/loader.conf.d/PRODUCT/.
+		local product_vars = getEnv("product_vars")
+		if product_vars then
+			local product_conf_dirs = ""
+			for var in product_vars:gmatch("%S+") do
+				local product = getEnv(var)
+				if product then
+					product_conf_dirs = product_conf_dirs .. " /boot/loader.conf.d/" .. product
+				end
+			end
+
+			if loader_conf_dirs then
+				loader_conf_dirs = loader_conf_dirs .. product_conf_dirs
+			else
+				loader_conf_dirs = product_conf_dirs
+			end
+		end
+
 		if loader_conf_dirs ~= nil then
 			for name in loader_conf_dirs:gmatch("[%w%p]+") do
 				if lfs.attributes(name, "mode") ~= "directory" then
 					print(MSG_FAILDIR:format(name))
 					goto nextdir
 				end
+
 				for cfile in lfs.dir(name) do
 					if cfile:match(".conf$") then
 						local fpath = name .. "/" .. cfile