2 -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
3 -- All rights reserved.
5 -- Redistribution and use in source and binary forms, with or without
6 -- modification, are permitted provided that the following conditions
8 -- 1. Redistributions of source code must retain the above copyright
9 -- notice, this list of conditions and the following disclaimer.
10 -- 2. Redistributions in binary form must reproduce the above copyright
11 -- notice, this list of conditions and the following disclaimer in the
12 -- documentation and/or other materials provided with the distribution.
14 -- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 -- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 -- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 -- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 -- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 -- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 -- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 -- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 -- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 function config.setKey(k, n, v)
34 if modules[k] == nil then
40 function config.dumpModules()
41 print("== Dumping modules");
42 for k, v in pairs(modules) do
45 print("== Dump ended");
48 local pattern_table = {
51 process = function(k, v) end
53 -- module_load="value"
55 str = "^%s*([%w_]+)_load%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
56 process = function(k, v)
57 if modules[k] == nil then
60 modules[k].load = v:upper();
63 -- module_name="value"
65 str = "^%s*([%w_]+)_name%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
66 process = function(k, v)
67 config.setKey(k, "name", v);
70 -- module_type="value"
72 str = "^%s*([%w_]+)_type%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
73 process = function(k, v)
74 config.setKey(k, "type", v);
77 -- module_flags="value"
79 str = "^%s*([%w_]+)_flags%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
80 process = function(k, v)
81 config.setKey(k, "flags", v);
84 -- module_before="value"
86 str = "^%s*([%w_]+)_before%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
87 process = function(k, v)
88 config.setKey(k, "before", v);
91 -- module_after="value"
93 str = "^%s*([%w_]+)_after%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
94 process = function(k, v)
95 config.setKey(k, "after", v);
98 -- module_error="value"
100 str = "^%s*([%w_]+)_error%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
101 process = function(k, v)
102 config.setKey(k, "error", v);
107 str = "^%s*exec%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
108 process = function(k, v)
109 if loader.perform(k) ~= 0 then
110 print("Failed to exec '"..k.."'");
116 str = "^%s*([%w%p]+)%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
117 process = function(k, v)
118 if loader.setenv(k, v) ~= 0 then
119 print("Failed to set '"..k.."' with value: "..v.."");
125 str = "^%s*([%w%p]+)%s*=%s*(%d+)%s*(.*)",
126 process = function(k, v)
127 if loader.setenv(k, v) ~= 0 then
128 print("Failed to set '"..k.."' with value: "..v.."");
134 function config.isValidComment(c)
136 local s = c:match("^%s*#.*");
138 s = c:match("^%s*$");
147 function config.loadmod(mod, silent)
149 for k, v in pairs(mod) do
150 if v.load == "YES" then
152 if v.flags ~= nil then
153 str = str .. v.flags .. " ";
155 if v.type ~= nil then
156 str = str .. "-t " .. v.type .. " ";
158 if v.name ~= nil then
164 if v.before ~= nil then
165 if loader.perform(v.before) ~= 0 then
167 print("Failed to execute '"..v.before.."' before loading '"..k.."'");
173 if loader.perform(str) ~= 0 then
175 print("Failed to execute '" .. str .. "'");
177 if v.error ~= nil then
178 loader.perform(v.error);
183 if v.after ~= nil then
184 if loader.perform(v.after) ~= 0 then
186 print("Failed to execute '"..v.after.."' after loading '"..k.."'");
193 --if not silent then print("Skiping module '".. k .. "'"); end
200 function config.parse(name, silent)
201 local f = io.open(name);
204 print("Failed to open config: '" .. name.."'");
212 text, r = io.read(f);
216 print("Failed to read config: '" .. name.."'");
224 for line in text:gmatch("([^\n]+)") do
226 if line:match("^%s*$") == nil then
229 for i, val in ipairs(pattern_table) do
230 local k, v, c = line:match(val.str);
234 if config.isValidComment(c) then
237 print("Malformed line ("..n.."):\n\t'"..line.."'");
245 if found == false then
246 print("Malformed line ("..n.."):\n\t'"..line.."'");
256 -- other_kernel is optionally the name of a kernel to load, if not the default
257 -- or autoloaded default from the module_path
258 function config.loadkernel(other_kernel)
259 local flags = loader.getenv("kernel_options") or "";
260 local kernel = other_kernel or loader.getenv("kernel");
262 local try_load = function (names)
263 for name in names:gmatch("([^;]+)%s*;?") do
264 r = loader.perform("load "..flags.." "..name);
272 local load_bootfile = function()
273 local bootfile = loader.getenv("bootfile");
275 -- append default kernel name
279 bootfile = bootfile..";kernel";
282 return try_load(bootfile);
285 -- kernel not set, try load from default module_path
286 if kernel == nil then
287 local res = load_bootfile();
292 print("No kernel set, failed to load from module_path");
296 local module_path = loader.getenv("module_path");
299 if other_kern ~= nil then
302 -- first try load kernel with module_path = /boot/${kernel}
303 -- then try load with module_path=${kernel}
304 local paths = {"/boot/"..kernel, kernel};
306 for k,v in pairs(paths) do
308 loader.setenv("module_path", v);
309 res = load_bootfile();
311 -- succeeded add path to module_path
313 if module_path ~= nil then
314 loader.setenv("module_path", v..";"..
321 -- failed to load with ${kernel} as a directory
323 res = try_load(kernel);
327 print("Failed to load kernel '"..kernel.."'");
334 function config.load(file)
337 file = "/boot/defaults/loader.conf";
340 if not config.parse(file) then
341 -- print("Failed to parse configuration: '"..file.."'");
344 local f = loader.getenv("loader_conf_files");
346 for name in f:gmatch("([%w%p]+)%s*") do
347 if not config.parse(name) then
348 -- print("Failed to parse configuration: '"..name.."'");
353 print("Loading kernel...");
356 print("Loading configured modules...");
357 if not config.loadmod(modules) then
358 print("Could not load one or more modules!");
362 function config.reload(kernel)
363 local kernel_loaded = false;
365 -- unload all modules
366 print("Unloading modules...");
367 loader.perform("unload");
369 if (kernel ~= nil) then
370 print("Trying to load '" .. kernel .. "'")
371 kernel_loaded = config.loadkernel(kernel);
372 if (kernel_loaded) then
373 print("Kernel '"..kernel.."' loaded!");
377 -- failed to load kernel or it is nil
379 if (not kernel_loaded) then
380 print("Loading default kernel...");
385 config.loadmod(modules);