lualoader: add be-list and be-switch commands

This is useful for driving BE changes from the loader command prompt,
rather than having to use the menu.  Note that the active carousel in
the boot environment carousel doesn't currently reflect a switch in
boot environments done this way- I'm considering this only a minor bug,
as you probably can't or won't go back to the menu if you're using these
commands.

Reviewed by:	imp (previous version)
This commit is contained in:
Kyle Evans
2026-06-04 08:57:16 -05:00
parent 4f7d987015
commit c7ff706b31
5 changed files with 97 additions and 8 deletions
+23
View File
@@ -160,6 +160,29 @@ cli["disable-module"] = function(...)
setModule(argv[1], false)
end
cli['be-list'] = function(...)
local _, argv = cli.arguments(...)
if #argv ~= 0 then
print("usage error: be-list")
return
end
for _, bootenv in core.bootenvIter() do
print(bootenv)
end
end
cli['be-switch'] = function(...)
local _, argv = cli.arguments(...)
if #argv == 0 then
print("usage error: be-switch beName")
return
end
local env = argv[1]
core.switchBE(env)
end
cli["toggle-module"] = function(...)
local _, argv = cli.arguments(...)
if #argv == 0 then
+43
View File
@@ -314,6 +314,21 @@ function core.bootenvFilter(func)
return oldf
end
function core.bootenvIter()
local envs = core.bootenvList()
if #envs ~= 0 then
local root = "zfs:" .. loader.getenv("zfs_be_root") .. "/"
for idx, bespec in ipairs(envs) do
bespec = bespec:gsub("^" .. root, "")
envs[idx] = bespec
end
end
return next, envs, nil
end
function core.bootenvList()
local bootenv_count = tonumber(loader.getenv(bootenv_list .. "_count"))
local bootenvs = {}
@@ -567,6 +582,34 @@ function core.nextConsoleChoice()
end
end
function core.switchBE(env)
-- This branch will most likely be taken by the switch-be CLI command,
-- not by the menu. We could do some more validation that it's a valid
-- BE and let the user fully specify a zfs:be/dataset to avoid the
-- validation, but this isn't done at the moment.
if not env:match("^zfs:") then
local root = loader.getenv("zfs_be_root")
if not root then
print("ZFS BE root not available -- no action taken")
return
end
if not env:match("^" .. root) then
env = "zfs:" .. root .. "/" .. env
else
env = "zfs:" .. env
end
end
loader.setenv("vfs.root.mountfrom", env)
loader.setenv("currdev", env .. ":")
config.reload()
if loader.getenv("kernelname") ~= nil then
loader.perform("unload")
end
end
-- The graphical-enabled loaders have unicode drawing character support. The
-- text-only ones do not. We check the old and new bindings for term_drawrect as
-- a proxy for unicode support, which will work on older boot loaders as well
+16 -1
View File
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd April 8, 2026
.Dd June 4, 2026
.Dt CORE.LUA 8
.Os
.Sh NAME
@@ -175,6 +175,12 @@ returns true, then the boot environment is retained in the list.
Otherwise, the boot environment is hidden.
The old filter, if any, is returned to allow the caller to compose a filter on
top of another filter.
.It Fn core.bootenvIter
Returns an iterator over the known boot environment list.
The returned boot environment names do not include the boot environmnt root,
which would need to be added back on from the
.Ev zfs_be_root
environment variable.
.It Fn core.bootenvList
Returns a table of boot environments, or an empty table.
These will be picked up using the
@@ -229,6 +235,15 @@ If there are no elements, this returns nil and nil.
If there is one element, this returns the front element and an empty table.
This will not operate on truly associative tables; numeric indices are
required.
.It Fn core.switchBE beName
Switch to the requested
.Fa beName .
It may be either be formatted as a fully-qualified loader dataset path
.Dq zfs:pool/ROOT/beName ,
or like one of
.Dq pool/ROOT/beName
or
.Dq beName .
.It Fn core.loaderTooOld
Returns true if the loader is too old.
Specifically, this means, is the loader old enough to require one or more
+1 -6
View File
@@ -53,12 +53,7 @@ local function OnOff(str, value)
end
local function bootenvSet(env)
loader.setenv("vfs.root.mountfrom", env)
loader.setenv("currdev", env .. ":")
config.reload()
if loader.getenv("kernelname") ~= nil then
loader.perform("unload")
end
core.switchBE(env)
end
local function multiUserPrompt()
+14 -1
View File
@@ -26,7 +26,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd November 14, 2025
.Dd June 4, 2026
.Dt LOADER 8
.Os
.Sh NAME
@@ -97,6 +97,19 @@ and
.Pp
.Bl -tag -width indent -compact
.\" sort the following entries according to the second field
.It Ic be-list
Lists the boot environments that are visible to
.Nm .
The listed names may be used directly with
.Ic be-switch .
.It Ic be-switch Ar beName
Switch to the
.Ar beName
boot environment.
The
.Nm
configuration will be reloaded from the new root, and any previously loaded
kernel and modules will be immediately unloaded.
.It Ic boot-conf
Load the
.Nm