This eliminates a lot of stat() calls that happen when lualoader renders the
menu with the default settings, and greatly speeds up rendering on my
laptop.
ftype is nil if loader/loader.efi hasn't been updated yet, falling back to
lfs.attributes() to test.
This is technically incompatible with lfs, but not in a particularly
terrible way.
Reviewed-by: cem
MFC-after: 4 days
Differential Revision: https://reviews.freebsd.org/D27542
lualoader was previously not processing \ as escapes; this commit fixes
that and does better error checking on the value as well.
Additionally, loader.conf had some odd restrictions on values that make
little sense. Previously, lines like:
kernel=foo
Would simply be discarded with a malformed line complaint you might not
see unless you disable beastie.
lualoader tries to process these as well as it can and manipulates the
environment, while forthloader did minimal processing and constructed a
`set` command to do the heavy lifting instead. The lua approach was
re-envisioned from building a `set` command so that we can appropriately
reset the environment when, for example, boot environments change.
Lift the previous restrictions to allow unquoted values on the right hand
side of an expression. Note that an unquoted value is effectively:
[A-Za-z0-9-][A-Za-z0-9-_.]*
This commit also stops trying to weirdly limit what it can handle in a
quoted value. Previously it only allowed spaces, alphanumeric, and
punctuation, which is kind of weird. Change it here to grab as much as it
can between two sets of quotes, then let processEnvVar() do the needful and
complain if it finds something malformed looking.
My extremely sophisticated test suite is as follows:
<<EOF
X_01_simple_string="simple"
X_02_escaped_string="s\imple"
X_03_unquoted_val=3
X_04_unquoted_strval=simple_test
X_05_subval="${X_03_unquoted_val}"
X_06_escaped_subval="\${X_03_unquoted_val}"
X_07_embedded="truth${X_03_unquoted_val}"
X_08_escaped_embedded="truth\${X_03_unquoted_val}"
X_09_unknown="${unknown_val}"
X_10_unknown_embedded="truth${unknown_val}"
X_11_crunchy="crunch$unknown_val crunch"
X_12_crunchy="crunch${unknown_val}crunch"
Y_01_badquote="te"lol"
Y_02_eolesc="lol\"
Y_02_noteolesc="lol\\"
Y_03_eolvar="lol$"
Y_03_noteolvar="lol\$"
Y_04_badvar="lol${"
exec="echo Done!"
EOF
Future work may provide a stub loader module in userland so that we can
formally test the loader scripts rather than sketchy setups like the above
in conjunction with the lua-* tools in ^/tools/boot.
This fixes the positioning of the "Welcome to FreeBSD" heading, which was
misplaced after the recent update to Lua 5.4. The issue was previously
masked by a compatibility knob in Lua 5.3 that would cause float-tagged
numbers to render faithfully without the decimal component. Lua 5.4 dropped
that and ensures that it always prints a decimal component, even if it has
to append a ".0" to the value.
Standard division produces a "float", floor division (//) can be used to
guarantee an integer. Floating point operations have been completely ripped
out of the liblua compiled for the bootloader, so this is a nop. This is
decidedly better than trying to hack out the float tag entirely.
Reported-by: mjg, probably others
MFC-after: 3 days
Draw console on efi.
Add vbe framebuffer for BIOS loader (vbe off, vbe on, vbe list,
vbe set xxx).
autoload font (/boot/fonts) based on resolution and font size.
Add command loadfont (set font by file) and
variable screen.font (set font by size). Pass loaded font to kernel.
Export variables:
screen.height
screen.width
screen.depth
Add gfx primitives to draw the screen and put png image on the screen.
Rework menu draw to iterate list of consoles to enamble device specific
output.
Probably something else I forgot...
Relnotes: yes
Differential Revision: https://reviews.freebsd.org/D27420
loader_conf_dirs is the supporting mechanism for the included
/boot/loader.conf.d directory. When lualoader finishes processing all of
the loader_conf_files it finds after walking /boot/defaults/loader.conf,
it will now check any and all loader_conf_dirs and process files ending
in ".conf" as if they were a loader.conf.
Note that loader_conf_files may be specified in a loader.conf.d config
file, but loader_conf_dirs may *not*. It will only be processed as specified
in /boot/defaults/loader.conf and any loader_conf_files that were loaded
from there.
Reviewed by: allanjude, freqlabs, rpokala, tsoome
Includes suggestion from: imp
Relnotes: yes
Differential Revision: https://reviews.freebsd.org/D25608
luacheck rightfully complains that i is unused in the show-module-options
loop at the end (it was used for some debugging in the process).
We've added a new pager module that's compiled in, so declare that as an
acceptable global.
This effectively dumps everything lualoader knows about to the console using
the libsa pager; that particular lua interface was added in r368591.
A pager stub implementation has been added that just dumps the output as-is
as a compat shim for older loader binaries that do not have lpager. This
stub should be moved into a more appropriate .lua file if we add anything
else that needs the pager.
Specifically, we have:
- enable-module
- disable-module
- toggle-module
These can be used to add/remove modules to be loaded or force modules to be
loaded in spite of modules_blacklist. In the typical case, a user is
expected to use them to recover an issue happening due to a module directive
they've added to their loader.conf or because they discover that they've
under-specified what to load.
MFC after: 1 week
In the previous world order, any brand/logo was forced to pull in the
drawer and call drawer.add{Brand,Logo} with the name their brand/logo is
taking and a table describing it.
In the new world order, these files just need to return a table that maps
out graphics types to a table of the exact same format as what was
previously being passed back into the drawer. The appeal here is not needing
to grab a reference back to the drawer module and having a cleaner
data-driven looking format for these. The format has been renamed to 'gfx-*'
prefixes and each one can provide a logo and a brand.
drawer.addBrand/drawer.addLogo will remain in place until FreeBSD 13, as
there's no overhead to them and it's not yet worth the break in
compatibility with any pre-existing brands and logos.
Reviewed by: freqlabs
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D24966
Report what console the boot loader is telling the kernel to use:
o Dual (Serial Primary)
o Dual (Video Primary)
o Serial
o Video
This allows the user to interrupt the boot and tweak the cosnole, if
needed, in a trivial way. Useful for installs where the default
selected may not be quite what you want, or when you are running a
dual setup and need to toggle over to the other console being primary.
The 'c'/'C' keys will do the cycling through the consoles. Note:
you'll still have to drop into the loader to set details about serial
consoles. And this doesn't change the console the loader is using.
Reviewed by: kevans@
MFC After: 3 days
Differential Revision: https://reviews.freebsd.org/D26573
bootonce feature is temporary, one time boot, activated by
"bectl activate -t BE", "bectl activate -T BE" will reset the bootonce flag.
By default, the bootonce setting is reset on attempt to boot and the next
boot will use previously active BE.
By setting zfs_bootonce_activate="YES" in rc.conf, the bootonce BE will
be set permanently active.
bootonce dataset name is recorded in boot pool labels, bootenv area.
in case of nextboot, the nextboot_enable boolean variable is recorded in
freebsd:nvstore nvlist, also stored in boot pool label bootenv area.
On boot, the loader will process /boot/nextboot.conf if nextboot_enable
is "YES", and will set nextboot_enable to "NO", preventing /boot/nextboot.conf
processing on next boot.
bootonce and nextboot features are usable in both UEFI and BIOS boot.
To use bootonce/nextboot features, the boot loader needs to be updated on disk;
if loader.efi is stored on ESP, then ESP needs to be updated and
for BIOS boot, stage2 (zfsboot or gptzfsboot) needs to be updated
(gpart or other tools).
At this time, only lua loader is updated.
Sponsored by: Netflix, Klara Inc.
Differential Revision: https://reviews.freebsd.org/D25512
The checkpoints are another way of keeping the state of ZFS.
During the rewind, the pool has to be exported.
This makes checkpoints unusable when using ZFS as root.
Add the option to rewind the ZFS checkpoint at the boot time.
If checkpoint exists, a new option for rewinding a checkpoint will appear in
the bootloader menu.
We fully support boot environments.
If the rewind option is selected, the boot loader will show a list of
boot environments that existed before the checkpoint.
Reviewed by: tsoome, allanjude, kevans (ok with high-level overview)
Differential Revision: https://reviews.freebsd.org/D24920
At least one user has landed in a scenario where logo files appear to be
misnamed, and we failed to find them. Our fallback for missing logodefs is
orb/orbbw, based on the color status. In a scenario where we can't locate
the logos, though, this is not ideal. Add in one more layer of fallback
to properly just don't draw any logo if the fan has been jam packed with
foreign material.
PR: 246046
MFC after: 3 days
The previous interface was pretty bad, and required the caller to get some
implementation details correct that it really shouldn't need to (e.g.
loader_conf_files handling) and pass in an empty table for it to use.
The new and much improved interface, readConf, is much less of a hack;
hiding these implementation details and just doing the right thing.
config.lua will now use it to process /boot/defaults/loader.conf and the
subsequent loader_conf_files from there, and read-conf will also use it.
This improvement submitted by Olivier (cited below), loader_conf_files
handling from the original patch was changed to just clobber it before
processing and not bother restoring it after the fact following r360505
where it's now guaranteed to evade the loader environment.
PR: 244640
Submitted by: Olivier Certner (olivier freebsd free fr>
This new table should be used for transient values that don't need to end up
in the loader environment. Generally, these will be things that are internal
details that really aren't needed or interesting outside of the config
module (e.g. if we changed how ${module}_* directives work, they might use
this instead).
To start, populate it with loader_conf_files. Any specific value of
loader_conf_files isn't all that interesting; if we're going to export it,
we should really instead export a loader_conf_files that indicates all of
the configuration files we processed. This will be used to reduce
bookkeeping overhead in a future commit that cleans up readConfFiles.
While we're here, let's stylize these as functions instead of just raw text.
A future change may allow arbitrary data arguments to be passed some of
these, and the distinction is useful.
This makes sure that config.readConfFiles doesn't see a stale
loader_conf_files from before, in case the newly loaded file doesn't set it.
MFC after: 3 days
This is a straightforward match to the command used by many in forthloader;
it uses the newly-exported config.readConfFiles() to make sure that any
loader_conf_files gets done as appropriate.
PR: 244640
Submitted by: Olivier Certner <olivier freebsd free fr>
MFC after: 3 days
In the process, change it slightly: readConfFiles will take a string like
loader_conf_files in addition to the loaded_files table that it normally
takes. This is to facilitate the addition of a read-conf CLI command, which
will just pass in the single file to read and an empty table.
MFC after: 3 days
We don't actually need to fetch loader_conf_files as much as we do; we've
already fetched it once at the beginning, we only really need to fetch it
again after each file we've processed. If it changes, then we can stash that
off into our local prefiles.
While here, drop a note about the recursion so that I stop trying to
change it. It may very well make redundant some of the work we're doing, but
that's OK.
MFC after: 3 days
Make menu customizations easier by naming the entries and using the
names to build the table entries.
Reviewed by: kevans
Approved by: mav (mentor)
MFC after: 1 week
Sponsored by: iXsystems, Inc.
Differential Revision: https://reviews.freebsd.org/D24527
This hook can be useful, for example to run a local function to choose
different modules to load when a user has picked a different kernel
from the menu.
Reviewed by: kevans
Approved by: mav (mentor)
MFC after: 1 week
Sponsored by: iXsystems, Inc.
Differential Revision: https://reviews.freebsd.org/D24115
This may be used for the local module to hook in and load any additional
modules that it wants, since it can't modify the modules table internal to
config. We may consider adding API to do so at a later time, but I suspect
it will be more complicated to use with little return.
status is captured but ignored for the purpose of loading the hook. status
will be false if *any* module failed to load, but we typically don't let
that halt the boot so there's no reason to let it halt hooks. Some vendors
or setups may have expected fails that would be actively thwarted by
checking it.
We may, at a later date, consider adding an API for letting non-config
modules check which modules have successfully (or not) loaded in case an
unexpected failure *should* halt whatever they are doing.
MFC after: 3 days
The major problem with the current ordering is that loader.conf may contain
all of the magic we need to actually setup the console, so loading local.lua
prior to that can make it excessively difficult and annoying to debug
(whoops, sorry Ravi & Warner).
The new ordering has some implications, but I suspect they are a non-issue.
The first is that it's no longer possible for the local module to inject any
logic prior to loading config -- I suspect no one has relied on this. The
second implication is that the config.loaded hook is now useless, as the
local module will always be included after that hook would have fired.
For config.loaded, I will opt to leave it in, just in case we add an early
point for local lua to get injected or in case one wants to schedule some
deferred logic in a custom loader.lua. The overhead of having it if no hooks
will be invoked is relatively minimal.
Diagnosed by: imp
Reported by: imp, rpokala (most likely)
MFC after: 3 days
r354247 converted try_include to lfs + dofile with the loader.lua_path added
just before. Fortunately, there was a hardcoded /boot/lua fallback in case
loader.lua_path wasn't being set yet- I typo'd it as loader.lua_paths.
Fix the typo.
X-MFC-With: r354247
MFC after: 3 days
Actual modules get require()'d in, rather than try_include(). All instances
of try_include should be provided with proper hooks/API in the rest of
loader to do the work they need to do, since we can't rely on them to exist.
Convert this now to lfs + dofile since we won't really be treating them as
modules.
lfs is required because dofile will properly throw an error if the file
doesn't exist, which is not in the spirit of 'optionally included'.
Getting out of the pcall game allows us to provide a loader.exit() style
call that backs out to the common bits of loader (autoboot sequence unless
disabled with a loader.setenv("autoboot_delay", "NO")). The most ideal way
identified so far to implement loader.exit() is to throw a special
abort-style error that indicates to the caller in interp_lua that we've not
actually errored out, just continue execution. Otherwise, we have to hack in
logic to bubble up and return from loader.lua without continuing further,
which gets kind of ugly depending on the context in which we're aborting.
A compat shim is provided temporarily in case the executing loader doesn't
yet have loader.lua_path, which was just added in r354246.
Multiple places coordinate to 'know' where lua scripts are installed. Knock
this down to being formally defined (and overridable) in exactly one spot,
defs.mk, and spread the knowledge to loaders and liblua alike. A future
commit will expose this to lua as loader.lua_path, so it can build absolute
paths to lua scripts as needed.
MFC after: 1 week
Previously color.disabled would be calculated at color module load time,
then never touched again. We can detect serial boots beyond just what we're
told by loader.conf(5) so this works out in many cases, but we must
re-evaluate the situation after the config is loaded to make sure we're not
supposed to be forcing it enabled/disabled.
Discovered while trying to test r353872.
When colors are disabled, color.escape{fg,bg} would return the passed in
color rather than the proper ANSI sequence for the color.
color.escape{fg,bg} would be wrong.
Instead return '', as the associated reset* functions will also return ''.
This should get rid of the funky '2' and '4' in the kernel selector if
you're booting serial.
Reported by: npn
It's not uncommon these days for the terminals attached to serial consoles
to support ANSI escape sequences. However, we assume escape sequences may
break some serial consoles and default to not using them when boot_serial or
boot_multicons (or if console contains "comconsole" in the forth loader) for
broader compatibility. We also have loader_color which can be explicitly set
to "NO" to disable the use of ANSI escape sequences.
The problem is that loader_color=YES gets ignored when boot_serial=YES or
boot_multicons=YES (or when console contains "comconsole" in the forth
loader).
To fix, the existing default behavior remains unchanged when loader_color is
unset, loader_color=NO explicitly disables the use of ANSI escape sequences
still, and the change is that loader_color=YES can now be used to explicitly
allow ANSI escapes when a serial console is enabled.
Submitted by: Ryan Moeller <ryan@ixsystems.com>
Reviewed by: tsoome (forth), kevans (lua)
MFC after: 1 week
Sponsored by: iXsystems, Inc. (Ryan)
Differential Revision: https://reviews.freebsd.org/D21732
This command will trigger a reload of the configuration from disk. This is
useful if you've changed currdev from recovery media to local disk as much
as I have over the past ~2 hours and are tired of the extra keystrokes.
This is really just a glorified shortcut, but reload-conf is likely easier
to remember for other people and does save some keystrokes when reloading
the configuration. It is also resilient to the underlying config method
changing interface, but this is unlikely to happen.
MFC after: 1 week
The box drawing characters we use aren't necessarily safe with a serial
console; for instance, in the report by npn@, these were causing his xterm
to send back a sequence that lua picked up as input and halted the boot.
This is less than ideal.
Fallback to ASCII frames for console with 'comconsole' in it. This is a
partial revert r338108 by imp@ -- instead of removing the menu entirely and
disabling color/cursor sequences, just reverting the default frame to ASCII
is enough to not break in this setup.
Reported by: npn
Triaged and recommended by: tsoome
Replace mini cons25 emulator with teken, this does enable us proper console
terminal for loader and will make it possible to implement different
back end callbacks to draw to screen.
At this time we still only "draw" in text mode.
Assuming that the autoboot sequence was interrupted, we've done enough
cursor manipulation that the prompt for the password will be sufficiently
obscured a couple of lines up. Clear the screen and reset the cursor
position here, too.
MFC after: 1 week
This was previously an unconditional screen clear, regardless of whether or
not we would be prompting for any passwords. This is pointless, given that
the screen clear is only there to put our screen into a consistent state
before we draw the prompts and do cursor manipulation.
This is also the only screen clear besides that to draw the menu. One can
now see early pre-loader and loader output with the menu disabled, which may
be useful for diagnostics.
Reported by: ian
MFC after: 3 days
The previous iteration of try_include attempted to be 'friendly' and error()
out if we hit an error that wasn't ENOENT. This was semi-OK, but fragile as
it relied on pattern matching the error message.
Move the responsibility for handling failure to the caller. Following
a common lua pattern, we'll return the return value of the underlying
require() on success, or false and an error message.
Reported by: bcran
MFC after: 3 days
If module_blacklist isn't specified, we have an empty blacklist; effectively
the same as if module_blacklist="" were specified in loader.conf(5).
This was reported when switching to a BE that predated the module_blacklist
introduction, but the problem is valid all the same and likely to be tripped
over in other scenarios.
Reported by: bwidawsk
MFC after: 3 days
Some fixes:
- Maintain historical behavior more accurately w.r.t verbose_loading;
verbose_loading strictly prints "${module_name...}" and later "failed!"
or "ok" based on load success
- With or without verbose_loading, dump command_errbuf on load failure.
This usually happens prior to ok/failed if we're verbose_loading
Reviewed by: imp
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D17694
Currently, a timeout in the menu autoboot sequence would effectively do
nothing. We would return from the autoboot handling, then begin processing
the menu without redrawing it.
This change makes the behavior a little more friendly. Returning the user to
the menu can't have any good effects, so abort the autoboot sequence and
drop to the loader prompt.
MFC after: 3 days
In the majority of cases, a kernel is not loaded before we hit the menu.
However, if a password is set, we'll trigger autoboot and have loadelf'd
beforehand. We also need to take into account one dropping to the loader
prompt and twiddling with things manually; if they try to toggle through
kernels, we'll assume they mean it.
Reported by: trasz
MFC after: 3 days