boot-manager.toml(5)
NAME
boot-manager.toml - configuration for boot-manager(8)
SYNOPSIS
/etc/boot-manager.toml
DESCRIPTION
This file configures boot-manager(8), and it's the whole configuration surface. The kernel package's post-transaction trigger runs boot-manager update with no arguments, so every knob a system needs is set here and nowhere else.
Do I need one?
Not necessarily. A system with no /etc/boot-manager.toml runs entirely on the defaults below. A file you name explicitly with boot-manager update --config is different: that one must exist.
Every setting has a default except entry_token and cmdline. Those two fall back to the kernel-install(8) locations at run time -- but not offline. See COMPOSE-TIME USE, below.
SYNTAX
It's a small subset of TOML, parsed without a TOML library:
- key = value lines, one per line, at the top level or in [initrd].
- Values are double-quoted strings, bare integers, or a single-line array of double-quoted strings. An array element can't contain a comma.
[initrd]is the only section. Everything before it is top-level.- A
#starts a comment, on a line of its own or after a value. A#inside a quoted string is part of the string -- kernel command lines may contain one. - Blank lines are ignored.
An unknown key, an unknown section, a malformed value, an unquoted string or stray text after a value is a parse error, and update stops. That's deliberate. A typo in boot configuration should fail loudly, not quietly drop a setting.
SETTINGS
Top level
boot_rootpath- $BOOT: the mounted EFI system partition, or the ext4 /boot on an XBOOTLDR split. Boot entries are written under <boot_root>/loader/entries/, and each kept kernel's image and initrd under <boot_root>/<entry_token>/<kver>/. Must not be empty. Default: /boot.
entry_tokenstring- Namespaces this machine's entries and its kernel directories on $BOOT. It's the kernel-install(8) entry token, usually the machine ID. When unset,
updatereads /etc/machine-id at run time. No default. cmdlinestring- The kernel command line, written as the options line of every entry. When unset,
updatereads /etc/kernel/cmdline at run time, the way kernel-install(8) does: lines starting with#are dropped, and the rest is joined with single spaces. No default. timeoutinteger- Menu timeout in seconds, written to <boot_root>/loader/loader.conf. Only the default and timeout lines of that file belong to
boot-manager. Any other line an administrator adds is kept. Default:5. extrainteger- How many additional previously booted kernels to keep per kernel type, on top of the mandatory set: the running kernel, the last known good one, each type's tip, and a not-yet-booted update.
0keeps only the mandatory set. Default:3. triesinteger- systemd-boot boot-counting attempts, stamped into the entry filename of a kernel that hasn't booted successfully yet, as <token>-<kver>+<tries>.conf. Default:
3. See "How does boot counting fit in?" below.
[initrd]
tierstring- Which initrd strategy
updatedrives:none,hostorthin. Default:none. See "Which tier do I want?" below. templatearray of strings- The generator command line for tier
host, as an argv, not a shell string. Required, and rejected when empty, if the tier ishost. Ignored otherwise. See "Writing a template" below.
Which tier do I want?
If your kernel can find and mount its root filesystem on its own, you don't need an initrd at all, and you want none. If the storage driver is a module, you need one, and you want host.
none- No initrd. Entries carry no initrd line, and firmware boots the kernel directly. This is the default.
host- Generate an initrd on this machine, by running template.
thin- Reserved. Not implemented yet, and selecting it is an error.
Writing a template
boot-manager knows nothing about any particular generator. dracut, mkinitcpio or a script of your own all drop in here. Choosing the flags, including whether to bundle early microcode, is the template's business.
These placeholders are substituted per kernel:
{kver}: the kernel version being generated for.{modules_dir}: that kernel's materialized module tree, asboot-managerserves it, at a path ending in lib/modules/<kver>. That's the shape dracut's--kmoddirinsists on.{output}: where the generated initrd must be written. A template that leaves this out produces nothing, and that's reported as an error.{sysroot}: the root filesystem the initrd is for. That's / on a running system, and the--sysrootof anupdate --offlinepass. Hand it to a generator that takes one (dracut's--sysroot), so its modules, rules and configuration come from that system, not from whatever machine runs the pass.
Generated initrds are cached under /var/lib/boot-manager/initrds/<kver>/, keyed by (kver, template). Change the template, and the next pass regenerates and reaps what it superseded. The key is taken before substitution, so a compose-time pass and the composed system's own passes share it.
How does boot counting fit in?
systemd-boot spends one of the tries per attempt by renaming the entry file. A kernel that never reaches boot-complete.target within them is sorted to the end of the menu. The count also bounds how often update arms an unproven tip as the one-shot entry: once the counter is spent, it isn't armed again.
It doesn't demote a saved default, though. That's why boot-manager never saves an unproven kernel as the default in the first place.
Set tries = 0 to turn counting off and write the plain entry name. That's the right setting for a boot loader that doesn't implement counting, which today is every loader except systemd-boot. Success markers don't depend on it either way. They're written to <state>/booted/ by boot-manager-report-booted.service, which pulls in boot-complete.target on its own where no loader has.
COMPOSE-TIME USE
boot-manager update --offline composes a bootable image instead of updating the running system, and there entry_token and cmdline are required.
Why no fallback?
Because the build host's /etc/machine-id and /etc/kernel/cmdline aren't the image's. A silent fallback would bake the builder's identity and root device into somebody else's image. An image builder knows both values, so it has to say so.
Does tier host work offline?
Yes. The compose pass reads the kernel's module tree out of its image for the generator, and removes it when the pass ends. A template that names {sysroot} then needs update --sysroot, since / is the build host, not the image. boot-manager refuses the pass without it.
boot_root should point into the tree being composed too, just like --usr and --state.
EXAMPLES
An atomic system whose kernel needs no initrd. This is about the shortest useful file:
boot_root = "/boot"
timeout = 3
extra = 1
[initrd]
tier = "none"
A conventional system generating initrds with dracut, keeping more history:
boot_root = "/boot"
cmdline = "root=LABEL=root ro quiet"
timeout = 5
extra = 3
[initrd]
tier = "host"
template = ["dracut", "--kmoddir", "{modules_dir}", "{output}", "{kver}"]
template must be a single-line array. There's no line continuation.
An image being composed, where both identity values are spelled out:
boot_root = "/boot"
entry_token = "0a1b2c3d4e5f60718293a4b5c6d7e8f9"
cmdline = "root=PARTLABEL=root ro"
timeout = 3
extra = 0
[initrd]
tier = "none"
A system installed onto hardware whose storage driver is a module. It generates a generic initrd with dracut, both at install time and on every later update:
boot_root = "/boot"
entry_token = "0a1b2c3d4e5f60718293a4b5c6d7e8f9"
timeout = 3
extra = 1
[initrd]
tier = "host"
template = ["dracut", "--sysroot", "{sysroot}", "--kmoddir", "{modules_dir}", "--no-hostonly", "--force", "{output}", "{kver}"]
FILES
- /etc/boot-manager.toml
- This file.
- /etc/machine-id
- Fallback for entry_token.
- /etc/kernel/cmdline
- Fallback for cmdline.
SEE ALSO
boot-manager(8), machine-id(5), kernel-install(8), systemd-boot(7), dracut(8)
AUTHOR
Auke Kok <sofar@foo-projects.org>