If we've fetched menu.entries and it turns out it's a function, call it to
get the actual menu entries.
This will be used to swap multi-/single- user boot options if we're booting
single user by default (boot_single="YES" in loader.conf(5)). It can also be
used fairly easily for other non-standard situations.
Instead of directly listing them in menu.welcome and menu.boot_options,
store them at menu.welcome.entries and welcome.boot_options.entries.
This will come into play later when we need to re-order the welcome menu if
boot_single is specified.
Menus are actually defined as entries in the 'menu' table. These local
declarations have not been used in the history of our in-tree lua scripts,
so give them the boot.
Loading the kernel and modules can be really slow. Loading before the menu
draws and every time one changes kernel/boot environment is even more
painful.
Defer loading until we either boot, auto-boot, or escape to loader prompt.
We still need to deal with configuration changes as the boot environment
changes, but this is generally much quicker.
This commit strips all ELF loading out of config.load/config.reload so that
these are purely for configuration. config.loadelf has been created to deal
with kernel/module loads. Unloading logic has been ripped out, as we won't
need to deal with it in the menu anymore.
Discussed in part with: allanjude
r329550 introduced config.kernel_loaded. config.load() doesn't provide a
means of overriding the kernel to load, but that likely isn't necessary as
it will not be a common case. When loading the kernel, just attempt to load
the kernel previously loaded and specified in config.kernel_loaded.
If we haven't loaded a kernel yet, config.kernel_loaded will be unset/nil
and the "default"/first kernel found will be loaded. If we've loaded a
kernel, we'll try to load that same kernel again and fallback to the default
kernel if we need to.
This in also in support of upcoming boot environment support.
'nil' means the 'first kernel found in module_path', which is the same
interpretation as passing 'nil' to loadkernel.
Otherwise, it denotes the name of a kernel that we've successfully loaded.
When reloaded later, we will still need to do the full search again to
locate the actual kernel in case things have changed, so just the name is
good enough.
This is in support of upcoming boot environment support. vfs.root.mountfrom
and currdev will be changed, then we will reload configuration and attempt
to reload the currently chosen kernel unless we shouldn't.
In the worst case scenario, we have no passwords to prompt for and we end up
just clearing the screen twice before we draw the menu or proceed with boot.
In the best case scenario, we don't try drawing password prompts amidst a
bunch of kernel/module loading.
This solve problem when booting with efi on armv7
Reviewed by: imp, tsoome
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D14415
Some other points I think we need to be consistent on:
- Spacing around string concatenation (always)
- Test against 'nil' explicitly rather than relying on 'not' for things that
reasonably won't be returning a boolean. e.g. loader.getenv
Eventually this will all get formalized somewhere.
Once we've successfully loaded a kernel, we add its directory to
module_path. If we switch kernels with the kernel selector, we again prepend
the kernel directory to the current module_path and end up with multiple
kernel paths, potentially with mismatched kernel/modules, added to
module_path.
Fix it by caching module_path at load() time and using the cached version
whenever we load a new kernel.
In a similar fashion to FILE, provide thin shims for the standard directory
manipulation functions.
Reviewed by: imp
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D14417
These are the style points that I'd like to try and maintain in our lua
scripts:
- Parentheses around conditionals
- Trailing semicolons, except on block terminators
- s:method(...) instead of string.method(s, ...) where applicable
There's likely more, but that'll get hammered out as we continue.
Prompt for GELI passphrase when geom_eli_passphrase_prompt has been set to
"YES" in loader.conf(5).
This entailed breaking out the password prompt into its own function that
can be reused between the password compare bits and this prompt that simply
takes the entered password and passes it along in the environment as
kern.geom.eli.passphrase.
I've also added a TODO to re-evaluate later if we want the "password
masking" -- it is currently not functional, so one still can't observe the
length of the password typed at the prompt.
This is the procedure that config.loadkernel tries to go through, but
reloading kernel config didn't use this function. Amend config.loadkernel to
take an optional other_kernel.
While here, be a little more verbose ("Trying to load kernel") so that it's
easy to follow where we've gone wrong.
1.) Instead of string.function(s, ...), use s:function(...)
2.) Don't try to concatenate `res`, it was just tested to be nil
3.) Note that "Loading configuration" is configured modules, and be a little
more precise in mentioning what failed ("loading of one or more modules")
An empty module_path to start with isn't ideal, but if all modules are
contained within a kernel directory (which is what we just tested) then it
isn't strictly an error. Don't assume that module_path has a value already.
When we fail to load the kernel, printing the result (which is guaranteed to
be nil) is not intended; print the name of the kernel.
autoboot_delay=NO is documented to wait for input and *not* autoboot, which
is the exact opposite of the current behavior.
Additionally, autoboot_delay=-1 is documented to disallow the user from
interrupting the boot (i.e. autoboot immediately), which was not previously
honored.
This also fixes the case insensitive comparison to be truly case
insensitive. This is kind of nit-picky, but the previous version would only
accept "no" and "NO".
Don't move this into config.reload because we may want to force reloads if
/boot changes out from under us later.
As a caution: changing kernels in lualoader at the moment might not be
loading all of your modules (in my testing, at least) from loader.conf(5).
This is a known problem.
Decimals screw up the escape sequence and the cursor will not get set. Right
now this only affects setting the cursor for drawing "Welcome to FreeBSD" --
the resulting number after our (x+(w/2)-9) calculation gets output as
"14.0."
This should be fixed at the interpreter level, rather than here, but this is
not a widespread problem at the moment so we'll fix it up in further work.
Reported by: David Wolfskill <david@catwhisker.org>
Reviewed by: imp
Differential Revision: https://reviews.freebsd.org/D14375
ffs_sbget() may return a superblock buffer even if it fails, so the
caller must be prepared to free it in this case. Moreover, when tasting
alternate superblock locations in a loop, ffs_sbget()'s readfunc
callback must free the previously allocated buffer.
Reported and tested by: pho
Reviewed by: kib (previous version)
Differential Revision: https://reviews.freebsd.org/D14390