~nabijaczleweli/klapki

f1e58143cefcce2447a0bcc2e350727855750f76 — наб autouploader a month ago 2897772 man
Manpage update by job 610005
8 files changed, 1735 insertions(+), 1106 deletions(-)

D index.txt
M klapki.8
M klapki.8.html
D klapki.8.html_fragment
D klapki.md
A klapki.pdf
A klapki.ps
A style.css
D index.txt => index.txt +0 -9
@@ 1,9 0,0 @@
klapki(8)          klapki.8.ronn

SHA1(3ssl)         https://manpages.debian.org/buster/libssl-doc/SHA1.3ssl.en.html
efibootmgr(8)      https://manpages.debian.org/buster/efibootmgr/efibootmgr.8.en.html
execl(3)           https://manpages.debian.org/buster/manpages-dev/execl.3.en.html
gethostname(2)     https://manpages.debian.org/buster/manpages-dev/gethostname.2.en.html
memfd_create(2)    https://manpages.debian.org/buster/manpages-dev/memfd_create.2.en.html

kernel-install(8)  https://www.freedesktop.org/software/systemd/man/kernel-install.html

M klapki.8 => klapki.8 +444 -217
@@ 1,243 1,470 @@
.\" generated with Ronn-NG/v0.9.1
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
.TH "KLAPKI" "8" "October 2021" "klapki developers"
.SH "NAME"
\fBklapki\fR \- EFI boot manager; or, well, an EFI bootorder compiler\.
.SH "SYNOPSIS"
\fBklapki\fR [\fB\-nvVEh\fR]… [\fBop\fR [\fBarg\fR…]]…
.SH "DESCRIPTION"
klapki(8) generates and manages EFI boot entries on platforms compatible therewith\.
.P
This command\-line interface is based on running a set of operations (see \fIOPS\fR) which modify the state and context, then settling the new set\-up, then committing it; this means that, barring I/O errors, \fB{dump}\fRing after the last operation with \fB\-n\fR is an accurate representation of what would be committed without it\.
.P
Care is taken to only write what is needed and only when it's needed – files and wanted entries are hashed with SHA1(3ssl) and only updated on mismatch; foreign entries are never touched, and klapki(8) prefers to abandon entries it doesn't understand than to accidentally mangle them\.
.P
Minimal state is stored, and it's only supplementary (see \fIUNINSTALLATION\fR)\. This means that removing all instances of a kernel boot entry with tools such as efibootmgr(8), the EFI Shell, or the platform UI will make klapki(8) forget about the kernel entirely, after minor complaints\.
.P
klapki(8)'s entries \fIcan\fR be moved across \fBBootNNNN\fR entries, however, so long as they are kept identical\.
.P
The entry description and kernel cmdline are controlled via small executable files, see \fIWISDOM\fR\.
.SH "OPTIONS"
.TP
\fB\-n\fR
Don't commit – nothing will be written to the filesystem or the firmware\.
.TP
\fB\-v\fR
Verbose operation\.
.TP
\fB\-V\fR
Very verbose – adds a \fB{dump}\fR op in\-between each specified op\.
.TP
\fB\-E\fR
Increase libefivar verbosity level\.
.IP
At time of writing, libefivar supports \fBLOG_VERBOSE\fR and \fBLOG_DEBUG\fR, which require \fB\-E\fR to be specified one and two times, respectively\.
.IP
See the \fISEE ALSO\fR sexion for details\.
.TP
\fB\-h\fR
Show a help message with these flags, recognised environment variables (see \fIENVIRONMENT\fR) and ops (see \fIOPS\fR)\.
.TP
\fBop\fR [\fBarg\fR…]
Specify an operation to run and arguments to pass to it\.
.IP
See \fIOPS\fR for more detail\.
.SH "ENVIRONMENT"
.TP
\fBKLAPKI_HOST\fR=
By default, klapki(8) uses the value found in \fB/etc/machine\-id\fR (or, failing that, the current hostname, as obtained with gethostname(2)) as the identifier for the host\.
.IP
If this environment variable is present, it will be used instead; note, that the host identifier is used verbatim as an EFI variable name under klapki's GUID (a8a9ad3a\-f831\-11ea\-946d\-674ccd7415cc)\.
.TP
\fBKLAPKI_WISDOM\fR=
To obtain the description and cmdline, klapki(8) invokes respectively\-named files under the wisdom root via execl(3), which is \fB/etc/klapki\fR by default\. This value overrides that path\. If not empty, a '/' is additionally appended before the executable name\.
.IP
See also \fIWISDOM\fR below\.
.TP
\fBKLAPKI_EFI_ROOT\fR=
By default, klapki(8) puts newly\-installed files in \fB\eklapki\e{host}\e{version}\fR under the ESP\.
.IP
If present, this overrides the constant prefix\. Par exemple, setting \fBKLAPKI_EFI_ROOT\fR= when adding a kernel will put it and the initrds directly under \fB\e{host}\e{version}\fR (note that by default this collides with kernel\-install(8))\.
.SH "OPS"
.TP
\fBdump\fR
Write some state (boot order, total boot entries, boot position, each wanted entry, boot variants) and context (our kernels, fresh kernels, deleted files) to the standard output\.
.TP
\fBbootpos\fR <\fBposition\fR>
Change the boot position to 0\-based <\fBposition\fR>\.
.IP
The cluster of entries for the current host can be placed at any point in the boot order; it's 0 (i\.e\. at the beginning) by default, but if you have another operating system or boot\-loader and wish to have it be the default, you can simply move klapki(8) down the required amount of entries\.
.IP
See description of addvariant below for sorting inside the cluster\.
.TP
\fBaddkernel\fR <\fBversion\fR> <\fBimage\fR> [\fBinitrd\fR…] <\fB""\fR>
Allocate entries for the kernel with version <\fBversion\fR> whose image resides at <\fBimage\fR> and initrds at [\fBinitrd\fR]…\. The list of initrds is terminated with an empty argument\.
.IP
This directive is ignored if a kernel with version <\fBversion\fR> is already known\. See delkernel below\.
.IP
The kernel image and initrds will be copied to the ESP (see \fBKLAPKI_EFI_ROOT\fR= in \fIENVIRONMENT\fR) during context commit\.
.TP
\fBdelkernel\fR <\fBversion\fR>
Purge all entries for which the version is <\fBversion\fR>\.
.IP
The kernel image, initrds and containing folder will, if not used, be removed from the ESP during context commit\.
.TP
\fBaddvariant\fR <\fBvariant\fR>
Add an explicit variant <\fBvariant\fR> to the end, if not already known\. Accompanying boot entries will be allocated in the derivation phase as needed\.
.IP
Variants are a global property, and a boot entry is generated for each variant (that is: for the implicit variant, represented by the empty string, in addition to any configured explicit variants)\.
.IP
The order of explicit variants is preserved within each version group, which are sorted highest\-to\-lowest\. For example: a host with two kernels (\fI5\.8\.0\-[12]\-amd64\fR) and two explicit variants (\fIdebug\fR, \fIsilent\fR) will produce the following entries (assume \fB$KLAPKI_WISDOM/description\fR linked to \fB/bin/echo\fR); note how the highest kernel version is at the top:
.br
\~\~5\.8\.0\-2\-amd64
.br
\~\~5\.8\.0\-2\-amd64 debug
.br
\~\~5\.8\.0\-2\-amd64 silent
.br
\~\~5\.8\.0\-1\-amd64
.br
\~\~5\.8\.0\-1\-amd64 debug
.br
\~\~5\.8\.0\-1\-amd64 silent
.IP
After running klapki(8) with "\fIdelvariant debug addvariant debug\fR", the two explicit variants are now ordered differently (\fIsilent\fR, \fIdebug\fR), and this is reflected in the boot order; note also how the implicit variant always sorts earlier than any explicit ones:
.br
\~\~5\.8\.0\-2\-amd64
.br
\~\~5\.8\.0\-2\-amd64 silent
.br
\~\~5\.8\.0\-2\-amd64 debug
.br
\~\~5\.8\.0\-1\-amd64
.br
\~\~5\.8\.0\-1\-amd64 silent
.br
\~\~5\.8\.0\-1\-amd64 debug
.TP
\fBdelvariant\fR <\fBvariant\fR>
Remove explicit variant <\fBvariant\fR>, if any; accompanying boot entries will purged in the derivation phase as needed\.
.SH "WISDOM"
The entry description and kernel cmdline are acquired by executing \fBdescription\fR and \fBcmdline\fR in \fB/etc/klapki\fR (or \fBKLAPKI_WISDOM=\fR, see \fIENVIRONMENT\fR) with the following arguments:
.br
0: "description" or "cmdline"
.br
1: kernel version
.br
2: boot variant
.P
And the standard output tied to a memfd (see memfd_create(2)), which is then trimmed, and all newlines are replaced with a single space\.
.P
klapki(8) stops processing if the child exits with a non\-zero status or is killed by a signal\. The special exit value 0x6B (107, ASCII 'k') is used to signal an error in execl(3)ing the wisdom binary\.
.P
Additional \fBinitrd=\fR statements \fIshould\fR work (with warnings, since the should\. Please report on the bug tracker/mailing list (see \fIREPORTING BUGS\fR) if you use them successfully!) and will not be managed by klapki(8),
.P
The simplest \fB/etc/klapki/description\fR would be a link to \fB/bin/echo\fR\. A simple \fBcmdline\fR is a \fB/bin/sh\fR shebang + \fBecho\fR command\. A cursed \fBcmdline\fR would be a \fB/bin/sh\fR shebang and an \fBawk '{gsub(/initrd=[^ ]+ ?/, ""); print}' /proc/cmdline\fR command\.
.SH "UNINSTALLATION"
Remove the EFI variable corresponding to the host (see \fIENVIRONMENT\fR) under klapki's GUID (a8a9ad3a\-f831\-11ea\-946d\-674ccd7415cc)\. This will purge the state for the host and hence abandon any entries left over, which remain bootable; to remove all klapki entries run \fB{delkernel}\fR first (see \fIOPS\fR), or remove them manually from the ESP and firmware afterward\.
.P
On Linux this involves running \fBchattr \-i\fR, then \fBrm\fR on \fB/sys/firmware/efi/efivars/{KLAPKI_HOST}\-a8a9ad3a\-f831\-11ea\-946d\-674ccd7415cc\fR\.
.SH "EXIT VALUES"
.nf
1 \- error reading configuration,
2 \- error loading state,
3 \- error resolving state,
4 \- error running an op,
5 \- error in propagation phase,
6 \- error in aging phase,
7 \- error in wisening phase,
8 \- error in saving phase,
9 \- error committing context,
10 \- error committing state\.
.fi
.SH "EXAMPLES"
A simple set\-up:
.IP "" 4
.nf
root@zoot:~# ls \-l description cmdline
\-rwxr\-xr\-x 1 root root 79 Sep 21 03:30 cmdline
lrwxrwxrwx 1 root root  9 Sep 20 04:30 description \-> /bin/echo
root@zoot:~# cat cmdline
.Dd October 18, 2021
.ds doc-volume-operating-system
.Dt KLAPKI 8
.Os klapki 0.1-13.9
.
.Sh NAME
.Nm klapki
.Nd EFI boot manager; or, well, an EFI bootorder compiler
.Sh SYNOPSIS
.Nm
.Op Fl nvVEh
.Oo Cm op Oo Ar arg Oc Ns … Oc Ns …
.
.Sh DESCRIPTION
Generates and manages EFI boot entries on platforms compatible therewith.
.Pp
This command-line interface is based on running a set of operations
.Pq see Sx OPS
which modify the state and context, then settling the new set-up, then committing it;
this means that, barring I/O errors,
.Cm dump Ns ing
after the last operation with
.Fl n
is an accurate representation of what would be committed without it.
.Pp
Care is taken to only write what is needed and only when it's needed \(em
files and wanted entries are hashed with SHA-1 and only updated on mismatch;
foreign entries are never touched, and
.Nm
prefers to abandon entries it doesn't understand than to accidentally mangle them.
.Pp
Minimal state is stored, and it's only supplementary
.Pq see Sx UNINSTALLATION .
This means that removing all instances of a kernel boot entry with tools such as
.Xr efibootmgr 8 ,
the EFI Shell, or the platform UI will make
.Nm
forget about the kernel entirely, after minor complaints.
.Pp
.Nm Ns 's
entries
.Em can
be moved across
.Li BootNNNN
entries, however, so long as they are kept identical.
.
.Sh OPTIONS
.Bl -tag -compact -width "@@"
.It Fl n
Don't commit \(em nothing will be written to the filesystem or firmware.
.
.It Fl v
Verbose operation.
.
.It Fl V
Very verbose \(em adds a
.Cm dump
.Cm op
in-between each specified
.Cm op .
.\" TOOD: Cm?
.
.It Fl E
Increase libefivar verbosity level.
At time of writing,
.Dv LOG_VERBOSE
and
.Dv LOG_DEBUG ,
are supported and require
.Fl E
to be specified once and twice, respectively.
.
.It Fl h
Show a help message with these flags, recognised environment variables
.Pq see Sx ENVIRONMENT
and ops
.Pq see Sx OPS .
.El
.
.Sh ENVIRONMENT
.Bl -tag -compact -width "KLAPKI_EFI_ROOT"
.It Ev KLAPKI_HOST
Overrides
.Nm klapi Ns 's
host identifier.
By default, the value found in
.Pa /etc/machine-id
(or, failing that, the current hostname) is used.
.Pp
Note, that the host identifier is used verbatim as an EFI variable name under
.Nm Ns 's
GUID
.Pq Li a8a9ad3a-f831-11ea-946d-674ccd7415cc .
.Pp
.
.It Ev KLAPKI_WISDOM
To obtain the description and cmdline,
.Nm
runs respectively-named files under the wisdom root, which is
.Pa /etc/klapki
by default.
This value overrides that path.
If not empty, a
.Sq Sy /
is additionally appended before the executable name.
.Pp
See also
.Sx WISDOM
below.
.Pp
.
.It Ev KLAPKI_EFI_ROOT
By default,
.Nm
puts newly-installed files in
.Pa \eklapki\e Ns Ar host Ns Pa \e Ns Ar version
under the ESP.
.Pp
If present, this overrides the constant prefix; for example, setting
.Ev KLAPKI_EFI_ROOT Ns =
when adding a kernel will put it and the initrds directly under
.Pa \e Ns Ar host Ns Pa \e Ns Ar version
.Pq note that by default this collides with Xr kernel-install 8
.El
.
.Sh OPS
.Bl -tag -compact -width "addvariant variant"
.It Cm dump
Write some state (boot order, total boot entries, boot position, each wanted entry, boot variants)
and context (our kernels, fresh kernels, deleted files) to the standard output stream.
.Pp
.
.It Cm bootpos Ar position
Change the boot position to
.Sy 0 Ns -based
.Ar position .
.Pp
The cluster of entries for the current host can be placed at any point in the boot order; it's
.Sy 0
(at the beginning) by default, but if you have another operating system or boot-loader and wish to have it be the default,
you can simply move
.Nm
down the required number of entries.
.Pp
See description of
.Cm addvariant
below for sorting inside the cluster.
.Pp
.
.It Cm addkernel Ar version image Oo Ar initrd Oc Ns … Cm \&""
Allocate entries for the kernel with
.Ar version
residing at
.Ar image
with initrds at
.Ar initrd .
The list of initrds is terminated with an empty argument.
.Pp
This directive is ignored if a kernel with
.Ar version
is already known.
See
.Cm delkernel
below.
.Pp
The kernel
.Ar image
and
.Ar initrd Ns s
will be copied to the ESP
.Pq see Ev KLAPKI_EFI_ROOT No in Sx ENVIRONMENT
during context commit.
.Pp
.
.It Cm delkernel Ar version
Purge all entries for which the version is
.Ar version .
.Pp
The kernel image, initrds, and containing folder will, if not used, be removed from the ESP during context commit.
.Pp
.
.It Cm addvariant Ar variant
Add an explicit
.Ar variant
to the end, if not already known.
Accompanying boot entries will be allocated in the derivation phase as needed.
.Pp
Variants are a global property, and each kernel has a boot entry generated for each variant
(that is: for the implicit variant, represented by the empty string, plus for any configured explicit variants).
.Pp
The order of explicit variants is preserved within each version group, which are sorted highest-to-lowest.
For example: a host with two kernels
.Pq Pa 5.8.0-[12]-amd64
and two explicit variants
.Pq Ar debug , silent
will produce the following entries
.Pq assuming Ev $KLAPKI_WISDOM Ns Pa /description No linked to Pa /bin/echo ;
note how the highest kernel version is at the top:
.Bl -item -compact -offset 4n
.It
.Li 5.8.0-2-amd64
.It
.Li 5.8.0-2-amd64 Ar debug
.It
.Li 5.8.0-2-amd64 Ar silent
.It
.Li 5.8.0-1-amd64
.It
.Li 5.8.0-1-amd64 Ar debug
.It
.Li 5.8.0-1-amd64 Ar silent
.El
.Pp
After running
.Nm
with
.Qq Cm delvariant Ar debug Cm addvariant Ar debug ,
the two explicit variants are now ordered differently
.Pq Ar silent , debug ,
and this is reflected in the boot order; note also how the implicit variant always sorts earlier than any explicit ones:
.Bl -item -compact -offset 4n
.It
.Li 5.8.0-2-amd64
.It
.Li 5.8.0-2-amd64 Ar silent
.It
.Li 5.8.0-2-amd64 Ar debug
.It
.Li 5.8.0-1-amd64
.It
.Li 5.8.0-1-amd64 Ar silent
.It
.Li 5.8.0-1-amd64 Ar debug
.El
.Pp
.
.It Cm delvariant Ar variant
Remove explicit
.Ar variant ,
if any; accompanying boot entries will purged in the derivation phase as needed.
.El
.
.Sh WISDOM
The entry description and kernel cmdline are acquired by executing
.Nm description
and
.Nm cmdline
in
.Pa /etc/klapki
.Pq or Ev KLAPKI_WISDOM , No see Sx ENVIRONMENT
with the following arguments:
.Bl -enum -compact -offset 4n -width "a"
.It
.Qq Li description
or
.Qq Li cmdline
.It
kernel version
.It
boot variant
.El
And the standard output tied to a pipe, which is then trimmed, and all newlines are replaced with a single space.
.Pp
Processing is stopped if the child exits with a non-zero status or is killed by a signal.
The special exit value
.Sy 0x6B Pq Sq Sy k
is used to signal an error in executing the wisdom binary.
.Pp
Additional
.Cm initrd=
statements
.Em should
work
(with warnings, hence the should.
Please report on the bug tracker/mailing list
.Pq see Sx REPORTING BUGS
if you use them successfully!) and will not be managed by
.Nm ,
.Pp
.Bl -item -compact
.It
The simplest
.Pa /etc/klapki/ Ns Nm description
would be a link to
.Pa /bin/echo .
.It
A simple
.Nm cmdline
is a
.Pa /bin/sh
shebang +
.Nm echo
command.
.It
A cursed
.Nm cmdline
would be a
.Pa /bin/sh
shebang and a
.Dl Nm sed Fl E Li 's/initrd=[^ ]+ ?//g' Ar /proc/cmdline
command.
.El
.
.Sh UNINSTALLATION
Remove the EFI variable corresponding to the host
.Pq see Sx ENVIRONMENT
under
.Nm klapki Ns 's GUID
.Pq Li a8a9ad3a-f831-11ea-946d-674ccd7415cc .
This will purge the state for the host, and, hence, abandon any entries left over, which remain bootable;
to remove all klapki entries run
.Cm delkernel
first
.Pq see Sx OPS ,
or remove them manually from the ESP and firmware afterward.
.Pp
Under Linux this involves running
.Nm chattr Fl i ,
then
.Nm rm
on
.Pq Pa /sys/firmware/efi/efivars/ Ns Ev $KLAPKI_HOST Ns Li -a8a9ad3a-f831-11ea-946d-674ccd7415cc .
.
.Sh EXIT STATUS
.Bl -tag -compact -width "AA"
.It Sy 0
success in all steps
.It Sy 1
error reading configuration
.It Sy 2
error loading state
.It Sy 3
error resolving state
.It Sy 4
error running an op
.It Sy 5
error in propagation phase
.It Sy 6
error in aging phase
.It Sy 7
error in wisening phase
.It Sy 8
error in saving phase
.It Sy 9
error committing context
.It Sy 10
error committing state
.El
.
.Sh EXAMPLES
A simple set-up:
.Bd -literal -compact -offset 4n
.Li # Nm ls Fl l Li description cmdline
-rwxr-xr-x 1 root root 79 Sep 21 03:30 cmdline
lrwxrwxrwx 1 root root  9 Sep 20 04:30 description -> /bin/echo
.Li # Nm cat Li cmdline
#!/bin/sh
echo root=ZFS=zoot/root console=ttyS0
.fi
.IP "" 0
.P
Add a kernel with a single initrd and a variant:
.IP "" 4
.nf
root@zoot:~# KLAPKI_HOST=zoot klapki addkernel 5\.8\.0\-2\-amd64 /boot/vmlinuz\-5\.8\.0\-2\-amd64 /boot/initrd\.img\-5\.8\.0\-2\-amd64 "" addvariant debug
.Ed
.Pp
Add a kernel with a single initrd, and a variant:
.Bd -literal -compact -offset 4n
.Li # Ev KLAPKI_HOST Ns Sy = Ns Ar zoot Nm Cm addkernel Li 5.8.0-2-amd64 /boot/vmlinuz-5.8.0-2-amd64 Cm \e
.Li " " /boot/initrd.img-5.8.0-2-amd64 Cm \&"" addvariant Li debug
EFI load: no config for this host (zoot) found; going to the top
Entry 000B changed
Entry 000D changed
Entry 000B: copied vmlinuz\-5\.8\.0\-2\-amd64 from /boot to \eKLAPKI\eZOOT\e5\.8\.0\-2\-AMD64\e
Entry 000B: copied initrd\.img\-5\.8\.0\-2\-amd64 from /boot to \eKLAPKI\eZOOT\e5\.8\.0\-2\-AMD64\e
Entry 000B: copied vmlinuz-5.8.0-2-amd64
            from /boot to \eKLAPKI\eZOOT\e5.8.0-2-AMD64\e
Entry 000B: copied initrd.img-5.8.0-2-amd64
            from /boot to \eKLAPKI\eZOOT\e5.8.0-2-AMD64\e
Updating state config
Updating boot order
Writing entry 000B
Writing entry 000D
.fi
.IP "" 0
.P
Success! But the new "debug" entry doesn't really do much:
.IP "" 4
.nf
root@zoot:~# efibootmgr
.Ed
.Pp
Success! But the new
.Ar debug
entry doesn't really do much:
.Bd -literal -compact -offset 4n
.Li # Nm efibootmgr
BootCurrent: 000D
Timeout: 0 seconds
BootOrder: 000B,000D,000C,000A,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009
Boot0000 through Boot0008 omitted
Boot0009* EFI Internal Shell    FvVol(7cb8bdc9\-f8eb\-4f34\-aaea\-3ee4af6516a1)/FvFile(7c04a583\-9e3e\-4f1c\-ad65\-e05268d0b4d1)
Boot000A* Linux Boot Manager    HD(1,GPT,0655a4fb\-e2e9\-4fa6\-b37b\-a52633aed855,0x800,0x76800)/File(\eEFI\esystemd\esystemd\-bootx64\.efi)
Boot000B* 5\.8\.0\-2\-amd64 HD(1,GPT,0655a4fb\-e2e9\-4fa6\-b37b\-a52633aed855,0x800,0x76800)/File(\eKLAPKI\eZOOT\e5\.8\.0\-2\-AMD64\eVMLINUZ\-5\.8\.0\-2\-AMD64)i\.n\.i\.t\.r\.d\.=\.\e\.k\.l\.a\.p\.k\.i\.\e\.z\.o\.o\.t\.\e\.5\|\.\|\.\|\.8\|\.\|\.\|\.0\.\-\.2\.\-\.a\.m\.d\.6\.4\.\e\.i\.n\.i\.t\.r\.d\|\.\|\.\|\.i\.m\.g\.\-\.5\|\.\|\.\|\.8\|\.\|\.\|\.0\.\-\.2\.\-\.a\.m\.d\.6\.4\. \.r\.o\.o\.t\.=\.Z\.F\.S\.=\.z\.o\.o\.t\./\.r\.o\.o\.t\. \.c\.o\.n\.s\.o\.l\.e\.=\.t\.t\.y\.S\.0\.
Boot000C* zoot 5\.8\.0\-1\-amd64    HD(1,GPT,0655a4fb\-e2e9\-4fa6\-b37b\-a52633aed855,0x800,0x76800)/File(\e62dd03a4928c412180b3024ac6c03a90\e5\.8\.0\-1\-amd64\elinux)i\.n\.i\.t\.r\.d\.=\.\e\.6\.2\.d\.d\.0\.3\.a\.4\.9\.2\.8\.c\.4\.1\.2\.1\.8\.0\.b\.3\.0\.2\.4\.a\.c\.6\.c\.0\.3\.a\.9\.0\.\e\.5\|\.\|\.\|\.8\|\.\|\.\|\.0\.\-\.1\.\-\.a\.m\.d\.6\.4\.\e\.i\.n\.i\.t\.r\.d\|\.\|\.\|\.i\.m\.g\.\-\.5\|\.\|\.\|\.8\|\.\|\.\|\.0\.\-\.1\.\-\.a\.m\.d\.6\.4\. \.r\.o\.o\.t\.=\.Z\.F\.S\.=\.z\.o\.o\.t\./\.r\.o\.o\.t\. \.c\.o\.n\.s\.o\.l\.e\.=\.t\.t\.y\.S\.0\.
Boot000D* 5\.8\.0\-2\-amd64 debug   HD(1,GPT,0655a4fb\-e2e9\-4fa6\-b37b\-a52633aed855,0x800,0x76800)/File(\eKLAPKI\eZOOT\e5\.8\.0\-2\-AMD64\eVMLINUZ\-5\.8\.0\-2\-AMD64)i\.n\.i\.t\.r\.d\.=\.\e\.k\.l\.a\.p\.k\.i\.\e\.z\.o\.o\.t\.\e\.5\|\.\|\.\|\.8\|\.\|\.\|\.0\.\-\.2\.\-\.a\.m\.d\.6\.4\.\e\.i\.n\.i\.t\.r\.d\|\.\|\.\|\.i\.m\.g\.\-\.5\|\.\|\.\|\.8\|\.\|\.\|\.0\.\-\.2\.\-\.a\.m\.d\.6\.4\. \.r\.o\.o\.t\.=\.Z\.F\.S\.=\.z\.o\.o\.t\./\.r\.o\.o\.t\. \.c\.o\.n\.s\.o\.l\.e\.=\.t\.t\.y\.S\.0\.
.fi
.IP "" 0
.P
Uncontrivedly, adding a conditional with another argument to enable debugging in the Intel PRO/100 driver and re\-running klapki(8) will work:
.IP "" 4
.nf
root@zoot:~# cat cmdline
Boot0009* EFI Internal Shell    FvVol(…)/FvFile(…)
Boot000A* Linux Boot Manager    HD(…)/File(\eEFI\esystemd\esystemd-bootx64.efi)
Boot000B* 5.8.0-2-amd64 HD(…)/
          File(\eKLAPKI\eZOOT\e5.8.0-2-AMD64\eVMLINUZ-5.8.0-2-AMD64)
          initrd=\eklapki\ezoot\e5.8.0-2-amd64\einitrd.img-5.8.0-2-amd64
          root=ZFS=zoot/root console=ttyS0
Boot000C* zoot 5.8.0-1-amd64    HD(…)/
          File(\e62dd03a4928c412180b3024ac6c03a90\e5.8.0-1-amd64\elinux)
          initrd=\e62dd03a4928c412180b3024ac6c03a90\e5.8.0-1-amd64\e
                 initrd.img-5.8.0-1-amd64
          root=ZFS=zoot/root console=ttyS0
Boot000D* 5.8.0-2-amd64 debug   HD(…)/
          File(\eKLAPKI\eZOOT\e5.8.0-2-AMD64\eVMLINUZ-5.8.0-2-AMD64)
          initrd=\eklapki\ezoot\e5.8.0-2-amd64\einitrd.img-5.8.0-2-amd64
          root=ZFS=zoot/root console=ttyS0
.Ed
.Pp
Uncontrivedly, adding a conditional with another argument to enable debugging in the Intel PRO/100 driver and re-running
.Nm
will work:
.Bd -literal -compact -offset 4n
.Li # Nm cat Li cmdline
#!/bin/sh
echo root=ZFS=zoot/root console=ttyS0
[ "$2" = "debug" ] && echo e100\.debug=16 || :
[ "$2" = "debug" ] && echo e100.debug=16 || :

root@zoot:~# KLAPKI_WISDOM=\. KLAPKI_HOST=zoot klapki
.Li # Ev KLAPKI_WISDOM Ns Sy = Ns Pa \&. Ev KLAPKI_HOST Ns Sy = Ns Ar zoot Nm
Entry 000D changed
Updating state config
Updating entry 000D
.fi
.IP "" 0
.P
Note, that, as expected, only the state configuration (which stores the hash of the wanted entry) and the debug entry itself was updated:
.IP "" 4
.nf
root@zoot:~# efibootmgr \-v
.Ed
.Pp
Note, that, as expected, only the state configuration (which stores the hash of the wanted entry) and the debug entry itself were updated:
.Bd -literal -compact -offset 4n
.Li # Nm efibootmgr Fl v
BootCurrent: 000D
Timeout: 0 seconds
BootOrder: 000B,000D,000C,000A,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009
Boot0000 through Boot000A and Boot000C omitted
Boot000B* 5\.8\.0\-2\-amd64 HD(1,GPT,0655a4fb\-e2e9\-4fa6\-b37b\-a52633aed855,0x800,0x76800)/File(\eKLAPKI\eZOOT\e5\.8\.0\-2\-AMD64\eVMLINUZ\-5\.8\.0\-2\-AMD64)i\.n\.i\.t\.r\.d\.=\.\e\.k\.l\.a\.p\.k\.i\.\e\.z\.o\.o\.t\.\e\.5\|\.\|\.\|\.8\|\.\|\.\|\.0\.\-\.2\.\-\.a\.m\.d\.6\.4\.\e\.i\.n\.i\.t\.r\.d\|\.\|\.\|\.i\.m\.g\.\-\.5\|\.\|\.\|\.8\|\.\|\.\|\.0\.\-\.2\.\-\.a\.m\.d\.6\.4\. \.r\.o\.o\.t\.=\.Z\.F\.S\.=\.z\.o\.o\.t\./\.r\.o\.o\.t\. \.c\.o\.n\.s\.o\.l\.e\.=\.t\.t\.y\.S\.0\.
Boot000D* 5\.8\.0\-2\-amd64 debug   HD(1,GPT,0655a4fb\-e2e9\-4fa6\-b37b\-a52633aed855,0x800,0x76800)/File(\eKLAPKI\eZOOT\e5\.8\.0\-2\-AMD64\eVMLINUZ\-5\.8\.0\-2\-AMD64)i\.n\.i\.t\.r\.d\.=\.\e\.k\.l\.a\.p\.k\.i\.\e\.z\.o\.o\.t\.\e\.5\|\.\|\.\|\.8\|\.\|\.\|\.0\.\-\.2\.\-\.a\.m\.d\.6\.4\.\e\.i\.n\.i\.t\.r\.d\|\.\|\.\|\.i\.m\.g\.\-\.5\|\.\|\.\|\.8\|\.\|\.\|\.0\.\-\.2\.\-\.a\.m\.d\.6\.4\. \.r\.o\.o\.t\.=\.Z\.F\.S\.=\.z\.o\.o\.t\./\.r\.o\.o\.t\. \.c\.o\.n\.s\.o\.l\.e\.=\.t\.t\.y\.S\.0\. \.e\.1\.0\.0\|\.\|\.\|\.d\.e\.b\.u\.g\.=\.1\.6\.
.fi
.IP "" 0
.SH "AUTHOR"
Written by наб <\fInabijaczleweli@nabijaczleweli\.xyz\fR>
.SH "SPECIAL THANKS"
Boot000B* 5.8.0-2-amd64 HD(…)/
          File(\eKLAPKI\eZOOT\e5.8.0-2-AMD64\eVMLINUZ-5.8.0-2-AMD64)
          initrd=\eklapki\ezoot\e5.8.0-2-amd64\einitrd.img-5.8.0-2-amd64
          root=ZFS=zoot/root console=ttyS0
Boot000D* 5.8.0-2-amd64 debug   HD(…)/
          File(\eKLAPKI\eZOOT\e5.8.0-2-AMD64\eVMLINUZ-5.8.0-2-AMD64)
          initrd=\eklapki\ezoot\e5.8.0-2-amd64\einitrd.img-5.8.0-2-amd64
          root=ZFS=zoot/root console=ttyS0 e100.debug=16
.Ed
.
.Sh REPORTING BUGS
.Lk https://todo.sr.ht/~nabijaczleweli/klapki
.Pp
.Mt ~nabijaczleweli/klapki@lists.sr.ht ,
archived at
.Lk https://lists.sr.ht/~nabijaczleweli/klapki .
.
.Sh SEE ALSO
.Xr gethostname 2 ,
.Xr memfd_create 2 ,
.Xr execl 3 ,
.Xr SHA1 3ssl ,
.Xr efibootmgr 8 ,
.Xr kernel-install 8
.Pp
.Lk https://git.sr.ht/~nabijaczleweli/klapki
.Pp
UEFI specification, Sexion 3.1.3 Load Options and related:
.Lk https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf
.Pp
libefivar verbosity levels:
.Lk https://github.com/rhboot/efivar/blob/36297adcb266f07bb06e725a0da377bc6e6aedd0/src/util.h#L328
.
.Sh AUTHORS
Written by
.An наб Aq nabijaczleweli@nabijaczleweli.xyz .
.
.Sh SPECIAL THANKS
To all who support further development, in particular:
.IP "\[ci]" 4
.Bl -bullet -offset 4n -compact -width 0
.It
ThePhD
.IP "\[ci]" 4
.It
Embark Studios
.IP "" 0
.SH "REPORTING BUGS"
<\fIhttps://todo\.sr\.ht/~nabijaczleweli/klapki\fR>
.P
<\fI~nabijaczleweli/klapki@lists\.sr\.ht\fR>, archived at <\fIhttps://lists\.sr\.ht/~nabijaczleweli/klapki\fR>
.SH "SEE ALSO"
<\fIhttps://git\.sr\.ht/~nabijaczleweli/klapki\fR>
.P
UEFI specification, Sexion 3\.1\.3 Load Options and related: <\fIhttps://uefi\.org/sites/default/files/resources/UEFI_Spec_2_8_final\.pdf\fR>
.P
libefivar verbosity levels: <\fIhttps://github\.com/rhboot/efivar/blob/36297adcb266f07bb06e725a0da377bc6e6aedd0/src/util\.h#L328\fR>
.El

M klapki.8.html => klapki.8.html +403 -336
@@ 1,370 1,437 @@
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv='content-type' content='text/html;charset=utf8'>
  <meta name='generator' content='Ronn-NG/v0.9.1 (http://github.com/apjanke/ronn-ng/tree/0.9.1)'>
  <title>klapki(8) - EFI boot manager; or, well, an EFI bootorder compiler.</title>
  <style type='text/css' media='all'>
  /* style: man */
  body#manpage {margin:0}
  .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
  .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
  .mp h2 {margin:10px 0 0 0}
  .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
  .mp h3 {margin:0 0 0 4ex}
  .mp dt {margin:0;clear:left}
  .mp dt.flush {float:left;width:8ex}
  .mp dd {margin:0 0 0 9ex}
  .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
  .mp pre {margin-bottom:20px}
  .mp pre+h2,.mp pre+h3 {margin-top:22px}
  .mp h2+pre,.mp h3+pre {margin-top:5px}
  .mp img {display:block;margin:auto}
  .mp h1.man-title {display:none}
  .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
  .mp h2 {font-size:16px;line-height:1.25}
  .mp h1 {font-size:20px;line-height:2}
  .mp {text-align:justify;background:#fff}
  .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
  .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
  .mp u {text-decoration:underline}
  .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
  .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
  .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
  .mp b.man-ref {font-weight:normal;color:#434241}
  .mp pre {padding:0 4ex}
  .mp pre code {font-weight:normal;color:#434241}
  .mp h2+pre,h3+pre {padding-left:0}
  ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
  ol.man-decor {width:100%}
  ol.man-decor li.tl {text-align:left}
  ol.man-decor li.tc {text-align:center;letter-spacing:4px}
  ol.man-decor li.tr {text-align:right;float:right}
  </style>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <link rel="stylesheet" href="style.css" type="text/css" media="all"/>
  <title>KLAPKI(8)</title>
</head>
<!--
  The following styles are deprecated and will be removed at some point:
  div#man, div#man ol.man, div#man ol.head, div#man ol.man.

  The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
  .man-navigation should be used instead.
-->
<body id='manpage'>
  <div class='mp' id='man'>

  <div class='man-navigation' style='display:none'>
    <a href="#NAME">NAME</a>
    <a href="#SYNOPSIS">SYNOPSIS</a>
    <a href="#DESCRIPTION">DESCRIPTION</a>
    <a href="#OPTIONS">OPTIONS</a>
    <a href="#ENVIRONMENT">ENVIRONMENT</a>
    <a href="#OPS">OPS</a>
    <a href="#WISDOM">WISDOM</a>
    <a href="#UNINSTALLATION">UNINSTALLATION</a>
    <a href="#EXIT-VALUES">EXIT VALUES</a>
    <a href="#EXAMPLES">EXAMPLES</a>
    <a href="#AUTHOR">AUTHOR</a>
    <a href="#SPECIAL-THANKS">SPECIAL THANKS</a>
    <a href="#REPORTING-BUGS">REPORTING BUGS</a>
    <a href="#SEE-ALSO">SEE ALSO</a>
  </div>

  <ol class='man-decor man-head man head'>
    <li class='tl'>klapki(8)</li>
    <li class='tc'></li>
    <li class='tr'>klapki(8)</li>
  </ol>

  

<h2 id="NAME">NAME</h2>
<p class="man-name">
  <code>klapki</code> - <span class="man-whatis">EFI boot manager; or, well, an EFI bootorder compiler.</span>
</p>
<h2 id="SYNOPSIS">SYNOPSIS</h2>

<p><code>klapki</code> [<code>-nvVEh</code>]… [<code>op</code> [<code>arg</code>…]]…</p>

<h2 id="DESCRIPTION">DESCRIPTION</h2>

<p><a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> generates and manages EFI boot entries on platforms compatible therewith.</p>

<p>This command-line interface is based on running a set of operations (see <a href="#OPS" title="OPS" data-bare-link="true">OPS</a>) which modify the state and context,
then settling the new set-up, then committing it; this means that, barring I/O errors,
<code>{dump}</code>ing after the last operation with <code>-n</code> is an accurate representation of what would be committed without it.</p>

<p>Care is taken to only write what is needed and only when it's needed –
files and wanted entries are hashed with <a class="man-ref" href="https://manpages.debian.org/buster/libssl-doc/SHA1.3ssl.en.html">SHA1<span class="s">(3ssl)</span></a> and only updated on mismatch;
foreign entries are never touched, and <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> prefers to abandon entries it doesn't understand than to accidentally mangle them.</p>

<p>Minimal state is stored, and it's only supplementary (see <a href="#UNINSTALLATION" title="UNINSTALLATION" data-bare-link="true">UNINSTALLATION</a>).
This means that removing all instances of a kernel boot entry with tools such as <a class="man-ref" href="https://manpages.debian.org/buster/efibootmgr/efibootmgr.8.en.html">efibootmgr<span class="s">(8)</span></a>, the EFI Shell,
or the platform UI will make <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> forget about the kernel entirely, after minor complaints.</p>

<p><a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a>'s entries <em>can</em> be moved across <code>BootNNNN</code> entries, however, so long as they are kept identical.</p>

<p>The entry description and kernel cmdline are controlled via small executable files, see <a href="#WISDOM" title="WISDOM" data-bare-link="true">WISDOM</a>.</p>

<h2 id="OPTIONS">OPTIONS</h2>

<dl>
<dt><code>-n</code></dt>
<dd>Don't commit – nothing will be written to the filesystem or the firmware.</dd>
<dt><code>-v</code></dt>
<dd>Verbose operation.</dd>
<dt><code>-V</code></dt>
<dd>Very verbose – adds a <code>{dump}</code> op in-between each specified op.</dd>
<dt><code>-E</code></dt>
<dd>Increase libefivar verbosity level.

    <p>At time of writing, libefivar supports <code>LOG_VERBOSE</code> and <code>LOG_DEBUG</code>,
which require <code>-E</code> to be specified one and two times, respectively.</p>

    <p>See the <a href="#SEE-ALSO" title="SEE ALSO" data-bare-link="true">SEE ALSO</a> sexion for details.</p>
</dd>
<dt><code>-h</code></dt>
<dd>Show a help message with these flags, recognised environment variables (see <a href="#ENVIRONMENT" title="ENVIRONMENT" data-bare-link="true">ENVIRONMENT</a>) and ops (see <a href="#OPS" title="OPS" data-bare-link="true">OPS</a>).</dd>
<dt>
<code>op</code> [<code>arg</code>…]</dt>
<dd>Specify an operation to run and arguments to pass to it.

    <p>See <a href="#OPS" title="OPS" data-bare-link="true">OPS</a> for more detail.</p>
</dd>
<body>
<table class="head">
  <tr>
    <td class="head-ltitle">KLAPKI(8)</td>
    <td class="head-vol">System Manager's Manual</td>
    <td class="head-rtitle">KLAPKI(8)</td>
  </tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">klapki</code> &#x2014; <span class="Nd">EFI boot
    manager; or, well, an EFI bootorder compiler</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<table class="Nm">
  <tr>
    <td><code class="Nm">klapki</code></td>
    <td>[<code class="Fl">-nvVEh</code>] [<code class="Cm">op</code>
      [<var class="Ar">arg</var>]&#x2026;]&#x2026;</td>
  </tr>
</table>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">Generates and manages EFI boot entries on platforms compatible
    therewith.</p>
<p class="Pp">This command-line interface is based on running a set of
    operations (see <a class="Sx" href="#OPS">OPS</a>) which modify the state
    and context, then settling the new set-up, then committing it; this means
    that, barring I/O errors, <code class="Cm">dump</code>ing after the last
    operation with <code class="Fl">-n</code> is an accurate representation of
    what would be committed without it.</p>
<p class="Pp">Care is taken to only write what is needed and only when it's
    needed &#x2014; files and wanted entries are hashed with SHA-1 and only
    updated on mismatch; foreign entries are never touched, and
    <code class="Nm">klapki</code> prefers to abandon entries it doesn't
    understand than to accidentally mangle them.</p>
<p class="Pp">Minimal state is stored, and it's only supplementary (see
    <a class="Sx" href="#UNINSTALLATION">UNINSTALLATION</a>). This means that
    removing all instances of a kernel boot entry with tools such as
    <a class="Xr" href="https://manpages.debian.org/bullseye/efibootmgr.8">efibootmgr(8)</a>,
    the EFI Shell, or the platform UI will make <code class="Nm">klapki</code>
    forget about the kernel entirely, after minor complaints.</p>
<p class="Pp" id="can"><code class="Nm">klapki</code>'s entries
    <a class="permalink" href="#can"><i class="Em">can</i></a> be moved across
    <code class="Li">BootNNNN</code> entries, however, so long as they are kept
    identical.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="OPTIONS"><a class="permalink" href="#OPTIONS">OPTIONS</a></h1>
<dl class="Bl-tag Bl-compact">
  <dt id="n"><a class="permalink" href="#n"><code class="Fl">-n</code></a></dt>
  <dd>Don't commit &#x2014; nothing will be written to the filesystem or
      firmware.</dd>
  <dt id="v"><a class="permalink" href="#v"><code class="Fl">-v</code></a></dt>
  <dd>Verbose operation.</dd>
  <dt id="V"><a class="permalink" href="#V"><code class="Fl">-V</code></a></dt>
  <dd>Very verbose &#x2014; adds a <code class="Cm">dump</code>
      <code class="Cm">op</code> in-between each specified
      <code class="Cm">op</code>.</dd>
  <dt id="E"><a class="permalink" href="#E"><code class="Fl">-E</code></a></dt>
  <dd>Increase libefivar verbosity level. At time of writing,
      <code class="Dv">LOG_VERBOSE</code> and <code class="Dv">LOG_DEBUG</code>,
      are supported and require <code class="Fl">-E</code> to be specified once
      and twice, respectively.</dd>
  <dt id="h"><a class="permalink" href="#h"><code class="Fl">-h</code></a></dt>
  <dd>Show a help message with these flags, recognised environment variables
      (see <a class="Sx" href="#ENVIRONMENT">ENVIRONMENT</a>) and ops (see
      <a class="Sx" href="#OPS">OPS</a>).</dd>
</dl>

<h2 id="ENVIRONMENT">ENVIRONMENT</h2>

<dl>
<dt>
<code>KLAPKI_HOST</code>=</dt>
<dd>By default, <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> uses the value found in <code>/etc/machine-id</code>
(or, failing that, the current hostname, as obtained with <a class="man-ref" href="https://manpages.debian.org/buster/manpages-dev/gethostname.2.en.html">gethostname<span class="s">(2)</span></a>)
as the identifier for the host.

    <p>If this environment variable is present, it will be used instead;
note, that the host identifier is used verbatim as an EFI variable name
under klapki's GUID (a8a9ad3a-f831-11ea-946d-674ccd7415cc).</p>
</dd>
<dt>
<code>KLAPKI_WISDOM</code>=</dt>
<dd>To obtain the description and cmdline, <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> invokes respectively-named files under the wisdom root via <a class="man-ref" href="https://manpages.debian.org/buster/manpages-dev/execl.3.en.html">execl<span class="s">(3)</span></a>,
which is <code>/etc/klapki</code> by default. This value overrides that path. If not empty, a '/' is additionally appended before the executable name.

    <p>See also <a href="#WISDOM" title="WISDOM" data-bare-link="true">WISDOM</a> below.</p>
</dd>
<dt>
<code>KLAPKI_EFI_ROOT</code>=</dt>
<dd>By default, <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> puts newly-installed files in <code>\klapki\{host}\{version}</code> under the ESP.

    <p>If present, this overrides the constant prefix.
Par exemple, setting <code>KLAPKI_EFI_ROOT</code>= when adding a kernel will put it and the initrds directly under <code>\{host}\{version}</code>
(note that by default this collides with <a class="man-ref" href="https://www.freedesktop.org/software/systemd/man/kernel-install.html">kernel-install<span class="s">(8)</span></a>).</p>
</dd>
</section>
<section class="Sh">
<h1 class="Sh" id="ENVIRONMENT"><a class="permalink" href="#ENVIRONMENT">ENVIRONMENT</a></h1>
<dl class="Bl-tag Bl-compact">
  <dt id="KLAPKI_HOST"><a class="permalink" href="#KLAPKI_HOST"><code class="Ev">KLAPKI_HOST</code></a></dt>
  <dd>Overrides <code class="Nm">klapi</code>'s host identifier. By default, the
      value found in <span class="Pa">/etc/machine-id</span> (or, failing that,
      the current hostname) is used.
    <p class="Pp">Note, that the host identifier is used verbatim as an EFI
        variable name under <code class="Nm">klapki</code>'s GUID
        (<code class="Li">a8a9ad3a-f831-11ea-946d-674ccd7415cc</code>).</p>
    <p class="Pp"></p>
  </dd>
  <dt id="KLAPKI_WISDOM"><a class="permalink" href="#KLAPKI_WISDOM"><code class="Ev">KLAPKI_WISDOM</code></a></dt>
  <dd>To obtain the description and cmdline, <code class="Nm">klapki</code> runs
      respectively-named files under the wisdom root, which is
      <span class="Pa">/etc/klapki</span> by default. This value overrides that
      path. If not empty, a
      &#x2018;<a class="permalink" href="#/"><b class="Sy" id="/">/</b></a>&#x2019;
      is additionally appended before the executable name.
    <p class="Pp">See also <a class="Sx" href="#WISDOM">WISDOM</a> below.</p>
    <p class="Pp"></p>
  </dd>
  <dt id="KLAPKI_EFI_ROOT"><a class="permalink" href="#KLAPKI_EFI_ROOT"><code class="Ev">KLAPKI_EFI_ROOT</code></a></dt>
  <dd>By default, <code class="Nm">klapki</code> puts newly-installed files in
      <span class="Pa">\klapki\</span><var class="Ar">host</var><span class="Pa">\</span><var class="Ar">version</var>
      under the ESP.
    <p class="Pp">If present, this overrides the constant prefix; for example,
        setting <code class="Ev">KLAPKI_EFI_ROOT</code>= when adding a kernel
        will put it and the initrds directly under
        <span class="Pa">\</span><var class="Ar">host</var><span class="Pa">\</span><var class="Ar">version</var>
        (note that by default this collides with
        <a class="Xr" href="https://manpages.debian.org/bullseye/kernel-install.8">kernel-install(8)</a>)</p>
  </dd>
</dl>

<h2 id="OPS">OPS</h2>

<dl>
<dt><code>dump</code></dt>
<dd>Write some state (boot order, total boot entries, boot position, each wanted entry, boot variants)
and context (our kernels, fresh kernels, deleted files) to the standard output.</dd>
<dt>
<code>bootpos</code> &lt;<code>position</code>&gt;</dt>
<dd>Change the boot position to 0-based &lt;<code>position</code>&gt;.

    <p>The cluster of entries for the current host can be placed at any point in the boot order;
it's 0 (i.e. at the beginning) by default, but if you have another operating system or boot-loader and wish to have it be the default,
you can simply move <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> down the required amount of entries.</p>

    <p>See description of addvariant below for sorting inside the cluster.</p>
</dd>
<dt>
<code>addkernel</code> &lt;<code>version</code>&gt; &lt;<code>image</code>&gt; [<code>initrd</code>…] &lt;<code>""</code>&gt;</dt>
<dd>Allocate entries for the kernel with version &lt;<code>version</code>&gt; whose image resides at &lt;<code>image</code>&gt; and initrds at [<code>initrd</code>]….
The list of initrds is terminated with an empty argument.

    <p>This directive is ignored if a kernel with version &lt;<code>version</code>&gt; is already known. See delkernel below.</p>

    <p>The kernel image and initrds will be copied to the ESP (see <code>KLAPKI_EFI_ROOT</code>= in <a href="#ENVIRONMENT" title="ENVIRONMENT" data-bare-link="true">ENVIRONMENT</a>) during context commit.</p>
</dd>
<dt>
<code>delkernel</code> &lt;<code>version</code>&gt;</dt>
<dd>Purge all entries for which the version is &lt;<code>version</code>&gt;.

    <p>The kernel image, initrds and containing folder will, if not used, be removed from the ESP during context commit.</p>
</dd>
<dt>
<code>addvariant</code> &lt;<code>variant</code>&gt;</dt>
<dd>Add an explicit variant &lt;<code>variant</code>&gt; to the end, if not already known. Accompanying boot entries will be allocated in the derivation phase as needed.

    <p>Variants are a global property, and a boot entry is generated for each variant
(that is: for the implicit variant, represented by the empty string, in addition to any configured explicit variants).</p>

    <p>The order of explicit variants is preserved within each version group, which are sorted highest-to-lowest.
For example: a host with two kernels (<em>5.8.0-[12]-amd64</em>) and two explicit variants (<em>debug</em>, <em>silent</em>) will produce the following entries
(assume <code>$KLAPKI_WISDOM/description</code> linked to <code>/bin/echo</code>); note how the highest kernel version is at the top:<br>
  5.8.0-2-amd64<br>
  5.8.0-2-amd64 debug<br>
  5.8.0-2-amd64 silent<br>
  5.8.0-1-amd64<br>
  5.8.0-1-amd64 debug<br>
  5.8.0-1-amd64 silent</p>

    <p>After running <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> with "<em>delvariant debug addvariant debug</em>", the two explicit variants are now ordered differently (<em>silent</em>, <em>debug</em>),
and this is reflected in the boot order; note also how the implicit variant always sorts earlier than any explicit ones:<br>
  5.8.0-2-amd64<br>
  5.8.0-2-amd64 silent<br>
  5.8.0-2-amd64 debug<br>
  5.8.0-1-amd64<br>
  5.8.0-1-amd64 silent<br>
  5.8.0-1-amd64 debug</p>
</dd>
<dt>
<code>delvariant</code> &lt;<code>variant</code>&gt;</dt>
<dd>Remove explicit variant &lt;<code>variant</code>&gt;, if any; accompanying boot entries will purged in the derivation phase as needed.</dd>
</section>
<section class="Sh">
<h1 class="Sh" id="OPS"><a class="permalink" href="#OPS">OPS</a></h1>
<dl class="Bl-tag Bl-compact">
  <dt id="dump"><a class="permalink" href="#dump"><code class="Cm">dump</code></a></dt>
  <dd>Write some state (boot order, total boot entries, boot position, each
      wanted entry, boot variants) and context (our kernels, fresh kernels,
      deleted files) to the standard output stream.
    <p class="Pp"></p>
  </dd>
  <dt id="bootpos"><a class="permalink" href="#bootpos"><code class="Cm">bootpos</code></a>
    <var class="Ar">position</var></dt>
  <dd>Change the boot position to <b class="Sy">0</b>-based
      <var class="Ar">position</var>.
    <p class="Pp">The cluster of entries for the current host can be placed at
        any point in the boot order; it's <b class="Sy">0</b> (at the beginning)
        by default, but if you have another operating system or boot-loader and
        wish to have it be the default, you can simply move
        <code class="Nm">klapki</code> down the required number of entries.</p>
    <p class="Pp">See description of <code class="Cm">addvariant</code> below
        for sorting inside the cluster.</p>
    <p class="Pp"></p>
  </dd>
  <dt id="addkernel"><a class="permalink" href="#addkernel"><code class="Cm">addkernel</code></a>
    <var class="Ar">version image</var> [<var class="Ar">initrd</var>]&#x2026;
    <code class="Cm">&quot;&quot;</code></dt>
  <dd>Allocate entries for the kernel with <var class="Ar">version</var>
      residing at <var class="Ar">image</var> with initrds at
      <var class="Ar">initrd</var>. The list of initrds is terminated with an
      empty argument.
    <p class="Pp">This directive is ignored if a kernel with
        <var class="Ar">version</var> is already known. See
        <code class="Cm">delkernel</code> below.</p>
    <p class="Pp">The kernel <var class="Ar">image</var> and
        <var class="Ar">initrd</var>s will be copied to the ESP (see
        <code class="Ev">KLAPKI_EFI_ROOT</code> <span class="No">in</span>
        <a class="Sx" href="#ENVIRONMENT">ENVIRONMENT</a>) during context
        commit.</p>
    <p class="Pp"></p>
  </dd>
  <dt id="delkernel"><a class="permalink" href="#delkernel"><code class="Cm">delkernel</code></a>
    <var class="Ar">version</var></dt>
  <dd>Purge all entries for which the version is <var class="Ar">version</var>.
    <p class="Pp">The kernel image, initrds, and containing folder will, if not
        used, be removed from the ESP during context commit.</p>
    <p class="Pp"></p>
  </dd>
  <dt id="addvariant"><a class="permalink" href="#addvariant"><code class="Cm">addvariant</code></a>
    <var class="Ar">variant</var></dt>
  <dd>Add an explicit <var class="Ar">variant</var> to the end, if not already
      known. Accompanying boot entries will be allocated in the derivation phase
      as needed.
    <p class="Pp">Variants are a global property, and each kernel has a boot
        entry generated for each variant (that is: for the implicit variant,
        represented by the empty string, plus for any configured explicit
        variants).</p>
    <p class="Pp">The order of explicit variants is preserved within each
        version group, which are sorted highest-to-lowest. For example: a host
        with two kernels (<span class="Pa">5.8.0-[12]-amd64</span>) and two
        explicit variants (<var class="Ar">debug</var>,
        <var class="Ar">silent</var>) will produce the following entries
        (assuming
        <code class="Ev">$KLAPKI_WISDOM</code><span class="Pa">/description</span>
        <span class="No">linked to</span> <span class="Pa">/bin/echo</span>);
        note how the highest kernel version is at the top:</p>
    <ul class="Bl-item Bd-indent Bl-compact">
      <li id="5.8.0-2-amd64"><a class="permalink" href="#5.8.0-2-amd64"><code class="Li">5.8.0-2-amd64</code></a></li>
      <li id="5.8.0-2-amd64~2"><a class="permalink" href="#5.8.0-2-amd64~2"><code class="Li">5.8.0-2-amd64</code></a>
          <var class="Ar">debug</var></li>
      <li id="5.8.0-2-amd64~3"><a class="permalink" href="#5.8.0-2-amd64~3"><code class="Li">5.8.0-2-amd64</code></a>
          <var class="Ar">silent</var></li>
      <li id="5.8.0-1-amd64"><a class="permalink" href="#5.8.0-1-amd64"><code class="Li">5.8.0-1-amd64</code></a></li>
      <li id="5.8.0-1-amd64~2"><a class="permalink" href="#5.8.0-1-amd64~2"><code class="Li">5.8.0-1-amd64</code></a>
          <var class="Ar">debug</var></li>
      <li id="5.8.0-1-amd64~3"><a class="permalink" href="#5.8.0-1-amd64~3"><code class="Li">5.8.0-1-amd64</code></a>
          <var class="Ar">silent</var></li>
    </ul>
    <p class="Pp">After running <code class="Nm">klapki</code> with
        &quot;<code class="Cm">delvariant</code> <var class="Ar">debug</var>
        <code class="Cm">addvariant</code> <var class="Ar">debug</var>&quot;,
        the two explicit variants are now ordered differently
        (<var class="Ar">silent</var>, <var class="Ar">debug</var>), and this is
        reflected in the boot order; note also how the implicit variant always
        sorts earlier than any explicit ones:</p>
    <ul class="Bl-item Bd-indent Bl-compact">
      <li id="5.8.0-2-amd64~4"><a class="permalink" href="#5.8.0-2-amd64~4"><code class="Li">5.8.0-2-amd64</code></a></li>
      <li id="5.8.0-2-amd64~5"><a class="permalink" href="#5.8.0-2-amd64~5"><code class="Li">5.8.0-2-amd64</code></a>
          <var class="Ar">silent</var></li>
      <li id="5.8.0-2-amd64~6"><a class="permalink" href="#5.8.0-2-amd64~6"><code class="Li">5.8.0-2-amd64</code></a>
          <var class="Ar">debug</var></li>
      <li id="5.8.0-1-amd64~4"><a class="permalink" href="#5.8.0-1-amd64~4"><code class="Li">5.8.0-1-amd64</code></a></li>
      <li id="5.8.0-1-amd64~5"><a class="permalink" href="#5.8.0-1-amd64~5"><code class="Li">5.8.0-1-amd64</code></a>
          <var class="Ar">silent</var></li>
      <li id="5.8.0-1-amd64~6"><a class="permalink" href="#5.8.0-1-amd64~6"><code class="Li">5.8.0-1-amd64</code></a>
          <var class="Ar">debug</var></li>
    </ul>
    <p class="Pp"></p>
  </dd>
  <dt id="delvariant"><a class="permalink" href="#delvariant"><code class="Cm">delvariant</code></a>
    <var class="Ar">variant</var></dt>
  <dd>Remove explicit <var class="Ar">variant</var>, if any; accompanying boot
      entries will purged in the derivation phase as needed.</dd>
</dl>

<h2 id="WISDOM">WISDOM</h2>

<p>The entry description and kernel cmdline are acquired by executing <code>description</code> and <code>cmdline</code> in <code>/etc/klapki</code> (or <code>KLAPKI_WISDOM=</code>, see <a href="#ENVIRONMENT" title="ENVIRONMENT" data-bare-link="true">ENVIRONMENT</a>)
with the following arguments:<br>
0: "description" or "cmdline"<br>
1: kernel version<br>
2: boot variant</p>

<p>And the standard output tied to a memfd (see <a class="man-ref" href="https://manpages.debian.org/buster/manpages-dev/memfd_create.2.en.html">memfd_create<span class="s">(2)</span></a>), which is then trimmed, and all newlines are replaced with a single space.</p>

<p><a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> stops processing if the child exits with a non-zero status or is killed by a signal.
The special exit value 0x6B (107, ASCII 'k') is used to signal an error in <a class="man-ref" href="https://manpages.debian.org/buster/manpages-dev/execl.3.en.html">execl<span class="s">(3)</span></a>ing the wisdom binary.</p>

<p>Additional <code>initrd=</code> statements <em>should</em> work (with warnings, since the should.
Please report on the bug tracker/mailing list (see <a href="#REPORTING-BUGS" title="REPORTING BUGS" data-bare-link="true">REPORTING BUGS</a>) if you use them successfully!) and will not be managed by <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a>,</p>

<p>The simplest <code>/etc/klapki/description</code> would be a link to <code>/bin/echo</code>.
A simple <code>cmdline</code> is a <code>/bin/sh</code> shebang + <code>echo</code> command.
A cursed <code>cmdline</code> would be a <code>/bin/sh</code> shebang and an <code>awk '{gsub(/initrd=[^ ]+ ?/, ""); print}' /proc/cmdline</code> command.</p>

<h2 id="UNINSTALLATION">UNINSTALLATION</h2>

<p>Remove the EFI variable corresponding to the host (see <a href="#ENVIRONMENT" title="ENVIRONMENT" data-bare-link="true">ENVIRONMENT</a>) under klapki's GUID (a8a9ad3a-f831-11ea-946d-674ccd7415cc).
This will purge the state for the host and hence abandon any entries left over, which remain bootable;
to remove all klapki entries run <code>{delkernel}</code> first (see <a href="#OPS" title="OPS" data-bare-link="true">OPS</a>), or remove them manually from the ESP and firmware afterward.</p>

<p>On Linux this involves running <code>chattr -i</code>, then <code>rm</code> on <code>/sys/firmware/efi/efivars/{KLAPKI_HOST}-a8a9ad3a-f831-11ea-946d-674ccd7415cc</code>.</p>

<h2 id="EXIT-VALUES">EXIT VALUES</h2>

<pre><code>1 - error reading configuration,
2 - error loading state,
3 - error resolving state,
4 - error running an op,
5 - error in propagation phase,
6 - error in aging phase,
7 - error in wisening phase,
8 - error in saving phase,
9 - error committing context,
10 - error committing state.
</code></pre>

<h2 id="EXAMPLES">EXAMPLES</h2>

<p>A simple set-up:</p>

<pre><code>root@zoot:~# ls -l description cmdline
</section>
<section class="Sh">
<h1 class="Sh" id="WISDOM"><a class="permalink" href="#WISDOM">WISDOM</a></h1>
<p class="Pp">The entry description and kernel cmdline are acquired by executing
    <code class="Nm">description</code> and <code class="Nm">cmdline</code> in
    <span class="Pa">/etc/klapki</span> (or
    <code class="Ev">KLAPKI_WISDOM</code>, <span class="No">see</span>
    <a class="Sx" href="#ENVIRONMENT">ENVIRONMENT</a>) with the following
    arguments:</p>
<ol class="Bl-enum Bd-indent Bl-compact">
  <li>&quot;<code class="Li">description</code>&quot; or
      &quot;<code class="Li">cmdline</code>&quot;</li>
  <li>kernel version</li>
  <li>boot variant</li>
</ol>
And the standard output tied to a pipe, which is then trimmed, and all newlines
  are replaced with a single space.
<p class="Pp" id="0x6B">Processing is stopped if the child exits with a non-zero
    status or is killed by a signal. The special exit value
    <a class="permalink" href="#0x6B"><b class="Sy">0x6B</b></a>
    (&#x2018;<a class="permalink" href="#k"><b class="Sy" id="k">k</b></a>&#x2019;)
    is used to signal an error in executing the wisdom binary.</p>
<p class="Pp" id="should">Additional <code class="Cm">initrd=</code> statements
    <a class="permalink" href="#should"><i class="Em">should</i></a> work (with
    warnings, hence the should. Please report on the bug tracker/mailing list
    (see <a class="Sx" href="#REPORTING_BUGS">REPORTING BUGS</a>) if you use
    them successfully!) and will not be managed by
    <code class="Nm">klapki</code>,</p>
<p class="Pp"></p>
<ul class="Bl-item Bl-compact">
  <li>The simplest
      <span class="Pa">/etc/klapki/</span><code class="Nm">description</code>
      would be a link to <span class="Pa">/bin/echo</span>.</li>
  <li>A simple <code class="Nm">cmdline</code> is a
      <span class="Pa">/bin/sh</span> shebang + <code class="Nm">echo</code>
      command.</li>
  <li>A cursed <code class="Nm">cmdline</code> would be a
      <span class="Pa">/bin/sh</span> shebang and a
    <div class="Bd Bd-indent"><code class="Li"><code class="Nm">sed</code>
      <code class="Fl">-E</code> <code class="Li">'s/initrd=[^ ]+ ?//g'</code>
      <var class="Ar">/proc/cmdline</var></code></div>
    command.</li>
</ul>
</section>
<section class="Sh">
<h1 class="Sh" id="UNINSTALLATION"><a class="permalink" href="#UNINSTALLATION">UNINSTALLATION</a></h1>
<p class="Pp">Remove the EFI variable corresponding to the host (see
    <a class="Sx" href="#ENVIRONMENT">ENVIRONMENT</a>) under
    <code class="Nm">klapki</code>'s GUID
    (<code class="Li">a8a9ad3a-f831-11ea-946d-674ccd7415cc</code>). This will
    purge the state for the host, and, hence, abandon any entries left over,
    which remain bootable; to remove all klapki entries run
    <code class="Cm">delkernel</code> first (see
    <a class="Sx" href="#OPS">OPS</a>), or remove them manually from the ESP and
    firmware afterward.</p>
<p class="Pp">Under Linux this involves running <code class="Nm">chattr</code>
    <code class="Fl">-i</code>, then <code class="Nm">rm</code> on
    (<span class="Pa">/sys/firmware/efi/efivars/</span><code class="Ev">$KLAPKI_HOST</code><code class="Li">-a8a9ad3a-f831-11ea-946d-674ccd7415cc</code>).</p>
</section>
<section class="Sh">
<h1 class="Sh" id="EXIT_STATUS"><a class="permalink" href="#EXIT_STATUS">EXIT
  STATUS</a></h1>
<dl class="Bl-tag Bl-compact">
  <dt id="0"><a class="permalink" href="#0"><b class="Sy">0</b></a></dt>
  <dd>success in all steps</dd>
  <dt id="1"><a class="permalink" href="#1"><b class="Sy">1</b></a></dt>
  <dd>error reading configuration</dd>
  <dt id="2"><a class="permalink" href="#2"><b class="Sy">2</b></a></dt>
  <dd>error loading state</dd>
  <dt id="3"><a class="permalink" href="#3"><b class="Sy">3</b></a></dt>
  <dd>error resolving state</dd>
  <dt id="4"><a class="permalink" href="#4"><b class="Sy">4</b></a></dt>
  <dd>error running an op</dd>
  <dt id="5"><a class="permalink" href="#5"><b class="Sy">5</b></a></dt>
  <dd>error in propagation phase</dd>
  <dt id="6"><a class="permalink" href="#6"><b class="Sy">6</b></a></dt>
  <dd>error in aging phase</dd>
  <dt id="7"><a class="permalink" href="#7"><b class="Sy">7</b></a></dt>
  <dd>error in wisening phase</dd>
  <dt id="8"><a class="permalink" href="#8"><b class="Sy">8</b></a></dt>
  <dd>error in saving phase</dd>
  <dt id="9"><a class="permalink" href="#9"><b class="Sy">9</b></a></dt>
  <dd>error committing context</dd>
  <dt id="10"><a class="permalink" href="#10"><b class="Sy">10</b></a></dt>
  <dd>error committing state</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1>
<p class="Pp">A simple set-up:</p>
<div class="Bd Bd-indent Li">
<pre><code class="Li">#</code> <code class="Nm">ls</code> <code class="Fl">-l</code> <code class="Li">description cmdline</code>
-rwxr-xr-x 1 root root 79 Sep 21 03:30 cmdline
lrwxrwxrwx 1 root root  9 Sep 20 04:30 description -&gt; /bin/echo
root@zoot:~# cat cmdline
<code class="Li">#</code> <code class="Nm">cat</code> <code class="Li">cmdline</code>
#!/bin/sh
echo root=ZFS=zoot/root console=ttyS0
</code></pre>

<p>Add a kernel with a single initrd and a variant:</p>

<pre><code>root@zoot:~# KLAPKI_HOST=zoot klapki addkernel 5.8.0-2-amd64 /boot/vmlinuz-5.8.0-2-amd64 /boot/initrd.img-5.8.0-2-amd64 "" addvariant debug
echo root=ZFS=zoot/root console=ttyS0</pre>
</div>
<p class="Pp">Add a kernel with a single initrd, and a variant:</p>
<div class="Bd Bd-indent Li">
<pre><code class="Li">#</code> <code class="Ev">KLAPKI_HOST</code><b class="Sy">=</b><var class="Ar">zoot</var> <code class="Nm"></code></pre>
klapki <code class="Cm">addkernel</code> <code class="Li">5.8.0-2-amd64
  /boot/vmlinuz-5.8.0-2-amd64</code> <code class="Cm">\</code>
<code class="Li"> /boot/initrd.img-5.8.0-2-amd64</code>
  <code class="Cm">&quot;&quot; addvariant</code> <code class="Li">debug</code>
EFI load: no config for this host (zoot) found; going to the top
Entry 000B changed
Entry 000D changed
Entry 000B: copied vmlinuz-5.8.0-2-amd64 from /boot to \KLAPKI\ZOOT\5.8.0-2-AMD64\
Entry 000B: copied initrd.img-5.8.0-2-amd64 from /boot to \KLAPKI\ZOOT\5.8.0-2-AMD64\
Entry 000B: copied vmlinuz-5.8.0-2-amd64
 from /boot to \KLAPKI\ZOOT\5.8.0-2-AMD64\
Entry 000B: copied initrd.img-5.8.0-2-amd64
 from /boot to \KLAPKI\ZOOT\5.8.0-2-AMD64\
Updating state config
Updating boot order
Writing entry 000B
Writing entry 000D
</code></pre>

<p>Success! But the new "debug" entry doesn't really do much:</p>

<pre><code>root@zoot:~# efibootmgr
Writing entry 000D</div>
<p class="Pp">Success! But the new <var class="Ar">debug</var> entry doesn't
    really do much:</p>
<div class="Bd Bd-indent Li">
<pre><code class="Li">#</code> <code class="Nm">efibootmgr</code>
BootCurrent: 000D
Timeout: 0 seconds
BootOrder: 000B,000D,000C,000A,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009
Boot0000 through Boot0008 omitted
Boot0009* EFI Internal Shell    FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(7c04a583-9e3e-4f1c-ad65-e05268d0b4d1)
Boot000A* Linux Boot Manager    HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\EFI\systemd\systemd-bootx64.efi)
Boot000B* 5.8.0-2-amd64 HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
Boot000C* zoot 5.8.0-1-amd64    HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\62dd03a4928c412180b3024ac6c03a90\5.8.0-1-amd64\linux)i.n.i.t.r.d.=.\.6.2.d.d.0.3.a.4.9.2.8.c.4.1.2.1.8.0.b.3.0.2.4.a.c.6.c.0.3.a.9.0.\.5...8...0.-.1.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.1.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
Boot000D* 5.8.0-2-amd64 debug   HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
</code></pre>

<p>Uncontrivedly, adding a conditional with another argument to enable debugging in the Intel PRO/100 driver and re-running <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> will work:</p>

<pre><code>root@zoot:~# cat cmdline
Boot0009* EFI Internal Shell    FvVol(&#x2026;)/FvFile(&#x2026;)
Boot000A* Linux Boot Manager    HD(&#x2026;)/File(\EFI\systemd\systemd-bootx64.efi)
Boot000B* 5.8.0-2-amd64 HD(&#x2026;)/
          File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)
          initrd=\klapki\zoot\5.8.0-2-amd64\initrd.img-5.8.0-2-amd64
          root=ZFS=zoot/root console=ttyS0
Boot000C* zoot 5.8.0-1-amd64    HD(&#x2026;)/
          File(\62dd03a4928c412180b3024ac6c03a90\5.8.0-1-amd64\linux)
          initrd=\62dd03a4928c412180b3024ac6c03a90\5.8.0-1-amd64\
                 initrd.img-5.8.0-1-amd64
          root=ZFS=zoot/root console=ttyS0
Boot000D* 5.8.0-2-amd64 debug   HD(&#x2026;)/
          File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)
          initrd=\klapki\zoot\5.8.0-2-amd64\initrd.img-5.8.0-2-amd64
          root=ZFS=zoot/root console=ttyS0</pre>
</div>
<p class="Pp">Uncontrivedly, adding a conditional with another argument to
    enable debugging in the Intel PRO/100 driver and re-running
    <code class="Nm">klapki</code> will work:</p>
<div class="Bd Bd-indent Li">
<pre><code class="Li">#</code> <code class="Nm">cat</code> <code class="Li">cmdline</code>
#!/bin/sh
echo root=ZFS=zoot/root console=ttyS0
[ "$2" = "debug" ] &amp;&amp; echo e100.debug=16 || :
[ &quot;$2&quot; = &quot;debug&quot; ] &amp;&amp; echo e100.debug=16 || :

root@zoot:~# KLAPKI_WISDOM=. KLAPKI_HOST=zoot klapki
<code class="Li">#</code> <code class="Ev">KLAPKI_WISDOM</code><b class="Sy">=</b><span class="Pa">.</span> <code class="Ev">KLAPKI_HOST</code><b class="Sy">=</b><var class="Ar">zoot</var> <code class="Nm"></code></pre>
klapki
Entry 000D changed
Updating state config
Updating entry 000D
</code></pre>

<p>Note, that, as expected, only the state configuration (which stores the hash of the wanted entry) and the debug entry itself was updated:</p>

<pre><code>root@zoot:~# efibootmgr -v
Updating entry 000D</div>
<p class="Pp">Note, that, as expected, only the state configuration (which
    stores the hash of the wanted entry) and the debug entry itself were
    updated:</p>
<div class="Bd Bd-indent Li">
<pre><code class="Li">#</code> <code class="Nm">efibootmgr</code> <code class="Fl">-v</code>
BootCurrent: 000D
Timeout: 0 seconds
BootOrder: 000B,000D,000C,000A,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009
Boot0000 through Boot000A and Boot000C omitted
Boot000B* 5.8.0-2-amd64 HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
Boot000D* 5.8.0-2-amd64 debug   HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0. .e.1.0.0...d.e.b.u.g.=.1.6.
</code></pre>

<h2 id="AUTHOR">AUTHOR</h2>

<p>Written by наб &lt;<a href="mailto:nabijaczleweli@nabijaczleweli.xyz" data-bare-link="true">nabijaczleweli@nabijaczleweli.xyz</a>&gt;</p>

<h2 id="SPECIAL-THANKS">SPECIAL THANKS</h2>

<p>To all who support further development, in particular:</p>

<ul>
Boot000B* 5.8.0-2-amd64 HD(&#x2026;)/
          File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)
          initrd=\klapki\zoot\5.8.0-2-amd64\initrd.img-5.8.0-2-amd64
          root=ZFS=zoot/root console=ttyS0
Boot000D* 5.8.0-2-amd64 debug   HD(&#x2026;)/
          File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)
          initrd=\klapki\zoot\5.8.0-2-amd64\initrd.img-5.8.0-2-amd64
          root=ZFS=zoot/root console=ttyS0 e100.debug=16</pre>
</div>
</section>
<section class="Sh">
<h1 class="Sh" id="REPORTING_BUGS"><a class="permalink" href="#REPORTING_BUGS">REPORTING
  BUGS</a></h1>
<p class="Pp"><a class="Lk" href="https://todo.sr.ht/~nabijaczleweli/klapki">https://todo.sr.ht/~nabijaczleweli/klapki</a></p>
<p class="Pp"><a class="Mt" href="mailto:~nabijaczleweli/klapki@lists.sr.ht">~nabijaczleweli/klapki@lists.sr.ht</a>,
    archived at
    <a class="Lk" href="https://lists.sr.ht/~nabijaczleweli/klapki">https://lists.sr.ht/~nabijaczleweli/klapki</a>.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
  ALSO</a></h1>
<p class="Pp"><a class="Xr" href="https://manpages.debian.org/bullseye/gethostname.2">gethostname(2)</a>,
    <a class="Xr" href="https://manpages.debian.org/bullseye/memfd_create.2">memfd_create(2)</a>,
    <a class="Xr" href="https://manpages.debian.org/bullseye/execl.3">execl(3)</a>,
    <a class="Xr" href="https://manpages.debian.org/bullseye/SHA1.3ssl">SHA1(3ssl)</a>,
    <a class="Xr" href="https://manpages.debian.org/bullseye/efibootmgr.8">efibootmgr(8)</a>,
    <a class="Xr" href="https://manpages.debian.org/bullseye/kernel-install.8">kernel-install(8)</a></p>
<p class="Pp"><a class="Lk" href="https://git.sr.ht/~nabijaczleweli/klapki">https://git.sr.ht/~nabijaczleweli/klapki</a></p>
<p class="Pp">UEFI specification, Sexion 3.1.3 Load Options and related:
    <a class="Lk" href="https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf">https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf</a></p>
<p class="Pp">libefivar verbosity levels:
    <a class="Lk" href="https://github.com/rhboot/efivar/blob/36297adcb266f07bb06e725a0da377bc6e6aedd0/src/util.h#L328">https://github.com/rhboot/efivar/blob/36297adcb266f07bb06e725a0da377bc6e6aedd0/src/util.h#L328</a></p>
</section>
<section class="Sh">
<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
<p class="Pp">Written by <span class="An">&#x043D;&#x0430;&#x0431;</span>
    &#x27E8;nabijaczleweli@nabijaczleweli.xyz&#x27E9;.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="SPECIAL_THANKS"><a class="permalink" href="#SPECIAL_THANKS">SPECIAL
  THANKS</a></h1>
<p class="Pp">To all who support further development, in particular:</p>
<ul class="Bl-bullet Bd-indent Bl-compact">
  <li>ThePhD</li>
  <li>Embark Studios</li>
</ul>

<h2 id="REPORTING-BUGS">REPORTING BUGS</h2>

<p>&lt;<a href="https://todo.sr.ht/~nabijaczleweli/klapki" data-bare-link="true">https://todo.sr.ht/~nabijaczleweli/klapki</a>&gt;</p>

<p>&lt;<a href="mailto:~nabijaczleweli/klapki@lists.sr.ht" data-bare-link="true">~nabijaczleweli/klapki@lists.sr.ht</a>&gt;, archived at &lt;<a href="https://lists.sr.ht/~nabijaczleweli/klapki" data-bare-link="true">https://lists.sr.ht/~nabijaczleweli/klapki</a>&gt;</p>

<h2 id="SEE-ALSO">SEE ALSO</h2>

<p>&lt;<a href="https://git.sr.ht/~nabijaczleweli/klapki" data-bare-link="true">https://git.sr.ht/~nabijaczleweli/klapki</a>&gt;</p>

<p>UEFI specification, Sexion 3.1.3 Load Options and related:
&lt;<a href="https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf" data-bare-link="true">https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf</a>&gt;</p>

<p>libefivar verbosity levels:
&lt;<a href="https://github.com/rhboot/efivar/blob/36297adcb266f07bb06e725a0da377bc6e6aedd0/src/util.h#L328" data-bare-link="true">https://github.com/rhboot/efivar/blob/36297adcb266f07bb06e725a0da377bc6e6aedd0/src/util.h#L328</a>&gt;</p>

  <ol class='man-decor man-foot man foot'>
    <li class='tl'>klapki developers</li>
    <li class='tc'>October 2021</li>
    <li class='tr'>klapki(8)</li>
  </ol>

  </div>
</section>
</div>
<table class="foot">
  <tr>
    <td class="foot-date">October 18, 2021</td>
    <td class="foot-os">klapki 0.1-13.9</td>
  </tr>
</table>
</body>
</html>

D klapki.8.html_fragment => klapki.8.html_fragment +0 -284
@@ 1,284 0,0 @@
<div class='mp'>

<h2 id="NAME">NAME</h2>
<p class="man-name">
  <code>klapki</code> - <span class="man-whatis">EFI boot manager; or, well, an EFI bootorder compiler.</span>
</p>
<h2 id="SYNOPSIS">SYNOPSIS</h2>

<p><code>klapki</code> [<code>-nvVEh</code>]… [<code>op</code> [<code>arg</code>…]]…</p>

<h2 id="DESCRIPTION">DESCRIPTION</h2>

<p><a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> generates and manages EFI boot entries on platforms compatible therewith.</p>

<p>This command-line interface is based on running a set of operations (see <a href="#OPS" title="OPS" data-bare-link="true">OPS</a>) which modify the state and context,
then settling the new set-up, then committing it; this means that, barring I/O errors,
<code>{dump}</code>ing after the last operation with <code>-n</code> is an accurate representation of what would be committed without it.</p>

<p>Care is taken to only write what is needed and only when it's needed –
files and wanted entries are hashed with <a class="man-ref" href="https://manpages.debian.org/buster/libssl-doc/SHA1.3ssl.en.html">SHA1<span class="s">(3ssl)</span></a> and only updated on mismatch;
foreign entries are never touched, and <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> prefers to abandon entries it doesn't understand than to accidentally mangle them.</p>

<p>Minimal state is stored, and it's only supplementary (see <a href="#UNINSTALLATION" title="UNINSTALLATION" data-bare-link="true">UNINSTALLATION</a>).
This means that removing all instances of a kernel boot entry with tools such as <a class="man-ref" href="https://manpages.debian.org/buster/efibootmgr/efibootmgr.8.en.html">efibootmgr<span class="s">(8)</span></a>, the EFI Shell,
or the platform UI will make <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> forget about the kernel entirely, after minor complaints.</p>

<p><a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a>'s entries <em>can</em> be moved across <code>BootNNNN</code> entries, however, so long as they are kept identical.</p>

<p>The entry description and kernel cmdline are controlled via small executable files, see <a href="#WISDOM" title="WISDOM" data-bare-link="true">WISDOM</a>.</p>

<h2 id="OPTIONS">OPTIONS</h2>

<dl>
<dt><code>-n</code></dt>
<dd>Don't commit – nothing will be written to the filesystem or the firmware.</dd>
<dt><code>-v</code></dt>
<dd>Verbose operation.</dd>
<dt><code>-V</code></dt>
<dd>Very verbose – adds a <code>{dump}</code> op in-between each specified op.</dd>
<dt><code>-E</code></dt>
<dd>Increase libefivar verbosity level.

    <p>At time of writing, libefivar supports <code>LOG_VERBOSE</code> and <code>LOG_DEBUG</code>,
which require <code>-E</code> to be specified one and two times, respectively.</p>

    <p>See the <a href="#SEE-ALSO" title="SEE ALSO" data-bare-link="true">SEE ALSO</a> sexion for details.</p>
</dd>
<dt><code>-h</code></dt>
<dd>Show a help message with these flags, recognised environment variables (see <a href="#ENVIRONMENT" title="ENVIRONMENT" data-bare-link="true">ENVIRONMENT</a>) and ops (see <a href="#OPS" title="OPS" data-bare-link="true">OPS</a>).</dd>
<dt>
<code>op</code> [<code>arg</code>…]</dt>
<dd>Specify an operation to run and arguments to pass to it.

    <p>See <a href="#OPS" title="OPS" data-bare-link="true">OPS</a> for more detail.</p>
</dd>
</dl>

<h2 id="ENVIRONMENT">ENVIRONMENT</h2>

<dl>
<dt>
<code>KLAPKI_HOST</code>=</dt>
<dd>By default, <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> uses the value found in <code>/etc/machine-id</code>
(or, failing that, the current hostname, as obtained with <a class="man-ref" href="https://manpages.debian.org/buster/manpages-dev/gethostname.2.en.html">gethostname<span class="s">(2)</span></a>)
as the identifier for the host.

    <p>If this environment variable is present, it will be used instead;
note, that the host identifier is used verbatim as an EFI variable name
under klapki's GUID (a8a9ad3a-f831-11ea-946d-674ccd7415cc).</p>
</dd>
<dt>
<code>KLAPKI_WISDOM</code>=</dt>
<dd>To obtain the description and cmdline, <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> invokes respectively-named files under the wisdom root via <a class="man-ref" href="https://manpages.debian.org/buster/manpages-dev/execl.3.en.html">execl<span class="s">(3)</span></a>,
which is <code>/etc/klapki</code> by default. This value overrides that path. If not empty, a '/' is additionally appended before the executable name.

    <p>See also <a href="#WISDOM" title="WISDOM" data-bare-link="true">WISDOM</a> below.</p>
</dd>
<dt>
<code>KLAPKI_EFI_ROOT</code>=</dt>
<dd>By default, <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> puts newly-installed files in <code>\klapki\{host}\{version}</code> under the ESP.

    <p>If present, this overrides the constant prefix.
Par exemple, setting <code>KLAPKI_EFI_ROOT</code>= when adding a kernel will put it and the initrds directly under <code>\{host}\{version}</code>
(note that by default this collides with <a class="man-ref" href="https://www.freedesktop.org/software/systemd/man/kernel-install.html">kernel-install<span class="s">(8)</span></a>).</p>
</dd>
</dl>

<h2 id="OPS">OPS</h2>

<dl>
<dt><code>dump</code></dt>
<dd>Write some state (boot order, total boot entries, boot position, each wanted entry, boot variants)
and context (our kernels, fresh kernels, deleted files) to the standard output.</dd>
<dt>
<code>bootpos</code> &lt;<code>position</code>&gt;</dt>
<dd>Change the boot position to 0-based &lt;<code>position</code>&gt;.

    <p>The cluster of entries for the current host can be placed at any point in the boot order;
it's 0 (i.e. at the beginning) by default, but if you have another operating system or boot-loader and wish to have it be the default,
you can simply move <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> down the required amount of entries.</p>

    <p>See description of addvariant below for sorting inside the cluster.</p>
</dd>
<dt>
<code>addkernel</code> &lt;<code>version</code>&gt; &lt;<code>image</code>&gt; [<code>initrd</code>…] &lt;<code>""</code>&gt;</dt>
<dd>Allocate entries for the kernel with version &lt;<code>version</code>&gt; whose image resides at &lt;<code>image</code>&gt; and initrds at [<code>initrd</code>]….
The list of initrds is terminated with an empty argument.

    <p>This directive is ignored if a kernel with version &lt;<code>version</code>&gt; is already known. See delkernel below.</p>

    <p>The kernel image and initrds will be copied to the ESP (see <code>KLAPKI_EFI_ROOT</code>= in <a href="#ENVIRONMENT" title="ENVIRONMENT" data-bare-link="true">ENVIRONMENT</a>) during context commit.</p>
</dd>
<dt>
<code>delkernel</code> &lt;<code>version</code>&gt;</dt>
<dd>Purge all entries for which the version is &lt;<code>version</code>&gt;.

    <p>The kernel image, initrds and containing folder will, if not used, be removed from the ESP during context commit.</p>
</dd>
<dt>
<code>addvariant</code> &lt;<code>variant</code>&gt;</dt>
<dd>Add an explicit variant &lt;<code>variant</code>&gt; to the end, if not already known. Accompanying boot entries will be allocated in the derivation phase as needed.

    <p>Variants are a global property, and a boot entry is generated for each variant
(that is: for the implicit variant, represented by the empty string, in addition to any configured explicit variants).</p>

    <p>The order of explicit variants is preserved within each version group, which are sorted highest-to-lowest.
For example: a host with two kernels (<em>5.8.0-[12]-amd64</em>) and two explicit variants (<em>debug</em>, <em>silent</em>) will produce the following entries
(assume <code>$KLAPKI_WISDOM/description</code> linked to <code>/bin/echo</code>); note how the highest kernel version is at the top:<br>
  5.8.0-2-amd64<br>
  5.8.0-2-amd64 debug<br>
  5.8.0-2-amd64 silent<br>
  5.8.0-1-amd64<br>
  5.8.0-1-amd64 debug<br>
  5.8.0-1-amd64 silent</p>

    <p>After running <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> with "<em>delvariant debug addvariant debug</em>", the two explicit variants are now ordered differently (<em>silent</em>, <em>debug</em>),
and this is reflected in the boot order; note also how the implicit variant always sorts earlier than any explicit ones:<br>
  5.8.0-2-amd64<br>
  5.8.0-2-amd64 silent<br>
  5.8.0-2-amd64 debug<br>
  5.8.0-1-amd64<br>
  5.8.0-1-amd64 silent<br>
  5.8.0-1-amd64 debug</p>
</dd>
<dt>
<code>delvariant</code> &lt;<code>variant</code>&gt;</dt>
<dd>Remove explicit variant &lt;<code>variant</code>&gt;, if any; accompanying boot entries will purged in the derivation phase as needed.</dd>
</dl>

<h2 id="WISDOM">WISDOM</h2>

<p>The entry description and kernel cmdline are acquired by executing <code>description</code> and <code>cmdline</code> in <code>/etc/klapki</code> (or <code>KLAPKI_WISDOM=</code>, see <a href="#ENVIRONMENT" title="ENVIRONMENT" data-bare-link="true">ENVIRONMENT</a>)
with the following arguments:<br>
0: "description" or "cmdline"<br>
1: kernel version<br>
2: boot variant</p>

<p>And the standard output tied to a memfd (see <a class="man-ref" href="https://manpages.debian.org/buster/manpages-dev/memfd_create.2.en.html">memfd_create<span class="s">(2)</span></a>), which is then trimmed, and all newlines are replaced with a single space.</p>

<p><a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> stops processing if the child exits with a non-zero status or is killed by a signal.
The special exit value 0x6B (107, ASCII 'k') is used to signal an error in <a class="man-ref" href="https://manpages.debian.org/buster/manpages-dev/execl.3.en.html">execl<span class="s">(3)</span></a>ing the wisdom binary.</p>

<p>Additional <code>initrd=</code> statements <em>should</em> work (with warnings, since the should.
Please report on the bug tracker/mailing list (see <a href="#REPORTING-BUGS" title="REPORTING BUGS" data-bare-link="true">REPORTING BUGS</a>) if you use them successfully!) and will not be managed by <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a>,</p>

<p>The simplest <code>/etc/klapki/description</code> would be a link to <code>/bin/echo</code>.
A simple <code>cmdline</code> is a <code>/bin/sh</code> shebang + <code>echo</code> command.
A cursed <code>cmdline</code> would be a <code>/bin/sh</code> shebang and an <code>awk '{gsub(/initrd=[^ ]+ ?/, ""); print}' /proc/cmdline</code> command.</p>

<h2 id="UNINSTALLATION">UNINSTALLATION</h2>

<p>Remove the EFI variable corresponding to the host (see <a href="#ENVIRONMENT" title="ENVIRONMENT" data-bare-link="true">ENVIRONMENT</a>) under klapki's GUID (a8a9ad3a-f831-11ea-946d-674ccd7415cc).
This will purge the state for the host and hence abandon any entries left over, which remain bootable;
to remove all klapki entries run <code>{delkernel}</code> first (see <a href="#OPS" title="OPS" data-bare-link="true">OPS</a>), or remove them manually from the ESP and firmware afterward.</p>

<p>On Linux this involves running <code>chattr -i</code>, then <code>rm</code> on <code>/sys/firmware/efi/efivars/{KLAPKI_HOST}-a8a9ad3a-f831-11ea-946d-674ccd7415cc</code>.</p>

<h2 id="EXIT-VALUES">EXIT VALUES</h2>

<pre><code>1 - error reading configuration,
2 - error loading state,
3 - error resolving state,
4 - error running an op,
5 - error in propagation phase,
6 - error in aging phase,
7 - error in wisening phase,
8 - error in saving phase,
9 - error committing context,
10 - error committing state.
</code></pre>

<h2 id="EXAMPLES">EXAMPLES</h2>

<p>A simple set-up:</p>

<pre><code>root@zoot:~# ls -l description cmdline
-rwxr-xr-x 1 root root 79 Sep 21 03:30 cmdline
lrwxrwxrwx 1 root root  9 Sep 20 04:30 description -&gt; /bin/echo
root@zoot:~# cat cmdline
#!/bin/sh
echo root=ZFS=zoot/root console=ttyS0
</code></pre>

<p>Add a kernel with a single initrd and a variant:</p>

<pre><code>root@zoot:~# KLAPKI_HOST=zoot klapki addkernel 5.8.0-2-amd64 /boot/vmlinuz-5.8.0-2-amd64 /boot/initrd.img-5.8.0-2-amd64 "" addvariant debug
EFI load: no config for this host (zoot) found; going to the top
Entry 000B changed
Entry 000D changed
Entry 000B: copied vmlinuz-5.8.0-2-amd64 from /boot to \KLAPKI\ZOOT\5.8.0-2-AMD64\
Entry 000B: copied initrd.img-5.8.0-2-amd64 from /boot to \KLAPKI\ZOOT\5.8.0-2-AMD64\
Updating state config
Updating boot order
Writing entry 000B
Writing entry 000D
</code></pre>

<p>Success! But the new "debug" entry doesn't really do much:</p>

<pre><code>root@zoot:~# efibootmgr
BootCurrent: 000D
Timeout: 0 seconds
BootOrder: 000B,000D,000C,000A,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009
Boot0000 through Boot0008 omitted
Boot0009* EFI Internal Shell    FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(7c04a583-9e3e-4f1c-ad65-e05268d0b4d1)
Boot000A* Linux Boot Manager    HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\EFI\systemd\systemd-bootx64.efi)
Boot000B* 5.8.0-2-amd64 HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
Boot000C* zoot 5.8.0-1-amd64    HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\62dd03a4928c412180b3024ac6c03a90\5.8.0-1-amd64\linux)i.n.i.t.r.d.=.\.6.2.d.d.0.3.a.4.9.2.8.c.4.1.2.1.8.0.b.3.0.2.4.a.c.6.c.0.3.a.9.0.\.5...8...0.-.1.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.1.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
Boot000D* 5.8.0-2-amd64 debug   HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
</code></pre>

<p>Uncontrivedly, adding a conditional with another argument to enable debugging in the Intel PRO/100 driver and re-running <a class="man-ref" href="klapki.8.html">klapki<span class="s">(8)</span></a> will work:</p>

<pre><code>root@zoot:~# cat cmdline
#!/bin/sh
echo root=ZFS=zoot/root console=ttyS0
[ "$2" = "debug" ] &amp;&amp; echo e100.debug=16 || :

root@zoot:~# KLAPKI_WISDOM=. KLAPKI_HOST=zoot klapki
Entry 000D changed
Updating state config
Updating entry 000D
</code></pre>

<p>Note, that, as expected, only the state configuration (which stores the hash of the wanted entry) and the debug entry itself was updated:</p>

<pre><code>root@zoot:~# efibootmgr -v
BootCurrent: 000D
Timeout: 0 seconds
BootOrder: 000B,000D,000C,000A,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009
Boot0000 through Boot000A and Boot000C omitted
Boot000B* 5.8.0-2-amd64 HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
Boot000D* 5.8.0-2-amd64 debug   HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0. .e.1.0.0...d.e.b.u.g.=.1.6.
</code></pre>

<h2 id="AUTHOR">AUTHOR</h2>

<p>Written by наб &lt;<a href="mailto:nabijaczleweli@nabijaczleweli.xyz" data-bare-link="true">nabijaczleweli@nabijaczleweli.xyz</a>&gt;</p>

<h2 id="SPECIAL-THANKS">SPECIAL THANKS</h2>

<p>To all who support further development, in particular:</p>

<ul>
  <li>ThePhD</li>
  <li>Embark Studios</li>
</ul>

<h2 id="REPORTING-BUGS">REPORTING BUGS</h2>

<p>&lt;<a href="https://todo.sr.ht/~nabijaczleweli/klapki" data-bare-link="true">https://todo.sr.ht/~nabijaczleweli/klapki</a>&gt;</p>

<p>&lt;<a href="mailto:~nabijaczleweli/klapki@lists.sr.ht" data-bare-link="true">~nabijaczleweli/klapki@lists.sr.ht</a>&gt;, archived at &lt;<a href="https://lists.sr.ht/~nabijaczleweli/klapki" data-bare-link="true">https://lists.sr.ht/~nabijaczleweli/klapki</a>&gt;</p>

<h2 id="SEE-ALSO">SEE ALSO</h2>

<p>&lt;<a href="https://git.sr.ht/~nabijaczleweli/klapki" data-bare-link="true">https://git.sr.ht/~nabijaczleweli/klapki</a>&gt;</p>

<p>UEFI specification, Sexion 3.1.3 Load Options and related:
&lt;<a href="https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf" data-bare-link="true">https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf</a>&gt;</p>

<p>libefivar verbosity levels:
&lt;<a href="https://github.com/rhboot/efivar/blob/36297adcb266f07bb06e725a0da377bc6e6aedd0/src/util.h#L328" data-bare-link="true">https://github.com/rhboot/efivar/blob/36297adcb266f07bb06e725a0da377bc6e6aedd0/src/util.h#L328</a>&gt;</p>
</div>

D klapki.md => klapki.md +0 -260
@@ 1,260 0,0 @@
klapki(8) -- EFI boot manager; or, well, an EFI bootorder compiler.
===================================================================

## SYNOPSIS

`klapki` [`-nvVEh`]… [`op` [`arg`…]]…

## DESCRIPTION

klapki(8) generates and manages EFI boot entries on platforms compatible therewith.

This command-line interface is based on running a set of operations (see [OPS][]) which modify the state and context,
then settling the new set-up, then committing it; this means that, barring I/O errors,
`{dump}`ing after the last operation with `-n` is an accurate representation of what would be committed without it.

Care is taken to only write what is needed and only when it's needed –
files and wanted entries are hashed with SHA1(3ssl) and only updated on mismatch;
foreign entries are never touched, and klapki(8) prefers to abandon entries it doesn't understand than to accidentally mangle them.

Minimal state is stored, and it's only supplementary (see [UNINSTALLATION][]).
This means that removing all instances of a kernel boot entry with tools such as efibootmgr(8), the EFI Shell,
or the platform UI will make klapki(8) forget about the kernel entirely, after minor complaints.

klapki(8)'s entries *can* be moved across `BootNNNN` entries, however, so long as they are kept identical.

The entry description and kernel cmdline are controlled via small executable files, see [WISDOM][].

## OPTIONS

  * `-n`:
    Don't commit – nothing will be written to the filesystem or the firmware.

  * `-v`:
    Verbose operation.

  * `-V`:
    Very verbose – adds a `{dump}` op in-between each specified op.

  * `-E`:
    Increase libefivar verbosity level.

    At time of writing, libefivar supports `LOG_VERBOSE` and `LOG_DEBUG`,
    which require `-E` to be specified one and two times, respectively.

    See the [SEE ALSO][] sexion for details.

  * `-h`:
    Show a help message with these flags, recognised environment variables (see [ENVIRONMENT][]) and ops (see [OPS][]).

  * `op` [`arg`…]:
    Specify an operation to run and arguments to pass to it.

    See [OPS][] for more detail.

## ENVIRONMENT

  * `KLAPKI_HOST`=:
    By default, klapki(8) uses the value found in `/etc/machine-id`
    (or, failing that, the current hostname, as obtained with gethostname(2))
    as the identifier for the host.

    If this environment variable is present, it will be used instead;
    note, that the host identifier is used verbatim as an EFI variable name
    under klapki's GUID (a8a9ad3a-f831-11ea-946d-674ccd7415cc).

  * `KLAPKI_WISDOM`=:
    To obtain the description and cmdline, klapki(8) invokes respectively-named files under the wisdom root via execl(3),
    which is `/etc/klapki` by default. This value overrides that path. If not empty, a '/' is additionally appended before the executable name.

    See also [WISDOM][] below.

  * `KLAPKI_EFI_ROOT`=:
    By default, klapki(8) puts newly-installed files in `\klapki\{host}\{version}` under the ESP.

    If present, this overrides the constant prefix.
    Par exemple, setting `KLAPKI_EFI_ROOT`= when adding a kernel will put it and the initrds directly under `\{host}\{version}`
    (note that by default this collides with kernel-install(8)).

## OPS

  * `dump`:
    Write some state (boot order, total boot entries, boot position, each wanted entry, boot variants)
    and context (our kernels, fresh kernels, deleted files) to the standard output.

  * `bootpos` &lt;`position`&gt;:
    Change the boot position to 0-based &lt;`position`&gt;.

    The cluster of entries for the current host can be placed at any point in the boot order;
    it's 0 (i.e. at the beginning) by default, but if you have another operating system or boot-loader and wish to have it be the default,
    you can simply move klapki(8) down the required amount of entries.

    See description of addvariant below for sorting inside the cluster.

  * `addkernel` &lt;`version`&gt; &lt;`image`&gt; [`initrd`…] &lt;`""`&gt;:
    Allocate entries for the kernel with version &lt;`version`&gt; whose image resides at &lt;`image`&gt; and initrds at [`initrd`]….
    The list of initrds is terminated with an empty argument.

    This directive is ignored if a kernel with version &lt;`version`&gt; is already known. See delkernel below.

    The kernel image and initrds will be copied to the ESP (see `KLAPKI_EFI_ROOT`= in [ENVIRONMENT][]) during context commit.

  * `delkernel` &lt;`version`&gt;:
    Purge all entries for which the version is &lt;`version`&gt;.

    The kernel image, initrds and containing folder will, if not used, be removed from the ESP during context commit.

  * `addvariant` &lt;`variant`&gt;:
    Add an explicit variant &lt;`variant`&gt; to the end, if not already known. Accompanying boot entries will be allocated in the derivation phase as needed.

    Variants are a global property, and a boot entry is generated for each variant
    (that is: for the implicit variant, represented by the empty string, in addition to any configured explicit variants).

    The order of explicit variants is preserved within each version group, which are sorted highest-to-lowest.
    For example: a host with two kernels (*5.8.0-[12]-amd64*) and two explicit variants (*debug*, *silent*) will produce the following entries
    (assume `$KLAPKI_WISDOM/description` linked to `/bin/echo`); note how the highest kernel version is at the top:<br />
    &nbsp;&nbsp;5.8.0-2-amd64<br />
    &nbsp;&nbsp;5.8.0-2-amd64 debug<br />
    &nbsp;&nbsp;5.8.0-2-amd64 silent<br />
    &nbsp;&nbsp;5.8.0-1-amd64<br />
    &nbsp;&nbsp;5.8.0-1-amd64 debug<br />
    &nbsp;&nbsp;5.8.0-1-amd64 silent

    After running klapki(8) with "*delvariant debug addvariant debug*", the two explicit variants are now ordered differently (*silent*, *debug*),
    and this is reflected in the boot order; note also how the implicit variant always sorts earlier than any explicit ones:<br />
    &nbsp;&nbsp;5.8.0-2-amd64<br />
    &nbsp;&nbsp;5.8.0-2-amd64 silent<br />
    &nbsp;&nbsp;5.8.0-2-amd64 debug<br />
    &nbsp;&nbsp;5.8.0-1-amd64<br />
    &nbsp;&nbsp;5.8.0-1-amd64 silent<br />
    &nbsp;&nbsp;5.8.0-1-amd64 debug

  * `delvariant` &lt;`variant`&gt;:
    Remove explicit variant &lt;`variant`&gt;, if any; accompanying boot entries will purged in the derivation phase as needed.

## WISDOM

The entry description and kernel cmdline are acquired by executing `description` and `cmdline` in `/etc/klapki` (or `KLAPKI_WISDOM=`, see [ENVIRONMENT][])
with the following arguments:<br />
0: "description" or "cmdline"<br />
1: kernel version<br />
2: boot variant

And the standard output tied to a memfd (see memfd_create(2)), which is then trimmed, and all newlines are replaced with a single space.

klapki(8) stops processing if the child exits with a non-zero status or is killed by a signal.
The special exit value 0x6B (107, ASCII 'k') is used to signal an error in execl(3)ing the wisdom binary.

Additional `initrd=` statements *should* work (with warnings, since the should.
Please report on the bug tracker/mailing list (see [REPORTING BUGS][]) if you use them successfully!) and will not be managed by klapki(8),

The simplest `/etc/klapki/description` would be a link to `/bin/echo`.
A simple `cmdline` is a `/bin/sh` shebang + `echo` command.
A cursed `cmdline` would be a `/bin/sh` shebang and an `awk '{gsub(/initrd=[^ ]+ ?/, ""); print}' /proc/cmdline` command.

## UNINSTALLATION

Remove the EFI variable corresponding to the host (see [ENVIRONMENT][]) under klapki's GUID (a8a9ad3a-f831-11ea-946d-674ccd7415cc).
This will purge the state for the host and hence abandon any entries left over, which remain bootable;
to remove all klapki entries run `{delkernel}` first (see [OPS][]), or remove them manually from the ESP and firmware afterward.

On Linux this involves running `chattr -i`, then `rm` on `/sys/firmware/efi/efivars/{KLAPKI_HOST}-a8a9ad3a-f831-11ea-946d-674ccd7415cc`.

## EXIT VALUES

    1 - error reading configuration,
    2 - error loading state,
    3 - error resolving state,
    4 - error running an op,
    5 - error in propagation phase,
    6 - error in aging phase,
    7 - error in wisening phase,
    8 - error in saving phase,
    9 - error committing context,
    10 - error committing state.

## EXAMPLES

  A simple set-up:

    root@zoot:~# ls -l description cmdline
    -rwxr-xr-x 1 root root 79 Sep 21 03:30 cmdline
    lrwxrwxrwx 1 root root  9 Sep 20 04:30 description -> /bin/echo
    root@zoot:~# cat cmdline
    #!/bin/sh
    echo root=ZFS=zoot/root console=ttyS0

  Add a kernel with a single initrd and a variant:

    root@zoot:~# KLAPKI_HOST=zoot klapki addkernel 5.8.0-2-amd64 /boot/vmlinuz-5.8.0-2-amd64 /boot/initrd.img-5.8.0-2-amd64 "" addvariant debug
    EFI load: no config for this host (zoot) found; going to the top
    Entry 000B changed
    Entry 000D changed
    Entry 000B: copied vmlinuz-5.8.0-2-amd64 from /boot to \KLAPKI\ZOOT\5.8.0-2-AMD64\
    Entry 000B: copied initrd.img-5.8.0-2-amd64 from /boot to \KLAPKI\ZOOT\5.8.0-2-AMD64\
    Updating state config
    Updating boot order
    Writing entry 000B
    Writing entry 000D

  Success! But the new "debug" entry doesn't really do much:

    root@zoot:~# efibootmgr
    BootCurrent: 000D
    Timeout: 0 seconds
    BootOrder: 000B,000D,000C,000A,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009
    Boot0000 through Boot0008 omitted
    Boot0009* EFI Internal Shell    FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(7c04a583-9e3e-4f1c-ad65-e05268d0b4d1)
    Boot000A* Linux Boot Manager    HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\EFI\systemd\systemd-bootx64.efi)
    Boot000B* 5.8.0-2-amd64 HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
    Boot000C* zoot 5.8.0-1-amd64    HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\62dd03a4928c412180b3024ac6c03a90\5.8.0-1-amd64\linux)i.n.i.t.r.d.=.\.6.2.d.d.0.3.a.4.9.2.8.c.4.1.2.1.8.0.b.3.0.2.4.a.c.6.c.0.3.a.9.0.\.5...8...0.-.1.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.1.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
    Boot000D* 5.8.0-2-amd64 debug   HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.

  Uncontrivedly, adding a conditional with another argument to enable debugging in the Intel PRO/100 driver and re-running klapki(8) will work:

    root@zoot:~# cat cmdline
    #!/bin/sh
    echo root=ZFS=zoot/root console=ttyS0
    [ "$2" = "debug" ] && echo e100.debug=16 || :

    root@zoot:~# KLAPKI_WISDOM=. KLAPKI_HOST=zoot klapki
    Entry 000D changed
    Updating state config
    Updating entry 000D

  Note, that, as expected, only the state configuration (which stores the hash of the wanted entry) and the debug entry itself was updated:

    root@zoot:~# efibootmgr -v
    BootCurrent: 000D
    Timeout: 0 seconds
    BootOrder: 000B,000D,000C,000A,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009
    Boot0000 through Boot000A and Boot000C omitted
    Boot000B* 5.8.0-2-amd64 HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0.
    Boot000D* 5.8.0-2-amd64 debug   HD(1,GPT,0655a4fb-e2e9-4fa6-b37b-a52633aed855,0x800,0x76800)/File(\KLAPKI\ZOOT\5.8.0-2-AMD64\VMLINUZ-5.8.0-2-AMD64)i.n.i.t.r.d.=.\.k.l.a.p.k.i.\.z.o.o.t.\.5...8...0.-.2.-.a.m.d.6.4.\.i.n.i.t.r.d...i.m.g.-.5...8...0.-.2.-.a.m.d.6.4. .r.o.o.t.=.Z.F.S.=.z.o.o.t./.r.o.o.t. .c.o.n.s.o.l.e.=.t.t.y.S.0. .e.1.0.0...d.e.b.u.g.=.1.6.

## AUTHOR

Written by наб &lt;<nabijaczleweli@nabijaczleweli.xyz>&gt;

## SPECIAL THANKS

To all who support further development, in particular:

  * ThePhD
  * Embark Studios

## REPORTING BUGS

&lt;<https://todo.sr.ht/~nabijaczleweli/klapki>&gt;

&lt;<mailto:~nabijaczleweli/klapki@lists.sr.ht>&gt;, archived at &lt;<https://lists.sr.ht/~nabijaczleweli/klapki>&gt;

## SEE ALSO

&lt;<https://git.sr.ht/~nabijaczleweli/klapki>&gt;

UEFI specification, Sexion 3.1.3 Load Options and related:
&lt;<https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf>&gt;

libefivar verbosity levels:
&lt;<https://github.com/rhboot/efivar/blob/36297adcb266f07bb06e725a0da377bc6e6aedd0/src/util.h#L328>&gt;

A klapki.pdf => klapki.pdf +0 -0
A klapki.ps => klapki.ps +591 -0
@@ 0,0 1,591 @@
%!PS-Adobe-3.0
%%Creator: groff version 1.22.4
%%CreationDate: Mon Oct 18 14:35:36 2021
%%DocumentNeededResources: font Times-Roman
%%+ font Times-Bold
%%+ font Courier-Bold
%%+ font Courier-Oblique
%%+ font Courier
%%+ font Times-Italic
%%+ font Symbol
%%DocumentSuppliedResources: procset grops 1.22 4
%%Pages: 5
%%PageOrder: Ascend
%%DocumentMedia: Default 595 842 0 () ()
%%Orientation: Portrait
%%EndComments
%%BeginDefaults
%%PageMedia: Default
%%EndDefaults
%%BeginProlog
%%BeginResource: procset grops 1.22 4
%!PS-Adobe-3.0 Resource-ProcSet
/setpacking where{
pop
currentpacking
true setpacking
}if
/grops 120 dict dup begin
/SC 32 def
/A/show load def
/B{0 SC 3 -1 roll widthshow}bind def
/C{0 exch ashow}bind def
/D{0 exch 0 SC 5 2 roll awidthshow}bind def
/E{0 rmoveto show}bind def
/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
/G{0 rmoveto 0 exch ashow}bind def
/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
/I{0 exch rmoveto show}bind def
/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
/K{0 exch rmoveto 0 exch ashow}bind def
/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
/M{rmoveto show}bind def
/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
/O{rmoveto 0 exch ashow}bind def
/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
/Q{moveto show}bind def
/R{moveto 0 SC 3 -1 roll widthshow}bind def
/S{moveto 0 exch ashow}bind def
/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
/SF{
findfont exch
[exch dup 0 exch 0 exch neg 0 0]makefont
dup setfont
[exch/setfont cvx]cvx bind def
}bind def
/MF{
findfont
[5 2 roll
0 3 1 roll
neg 0 0]makefont
dup setfont
[exch/setfont cvx]cvx bind def
}bind def
/level0 0 def
/RES 0 def
/PL 0 def
/LS 0 def
/MANUAL{
statusdict begin/manualfeed true store end
}bind def
/PLG{
gsave newpath clippath pathbbox grestore
exch pop add exch pop
}bind def
/BP{
/level0 save def
1 setlinecap
1 setlinejoin
DEFS/BPhook known{DEFS begin BPhook end}if
72 RES div dup scale
LS{
90 rotate
}{
0 PL translate
}ifelse
1 -1 scale
}bind def
/EP{
level0 restore
showpage
}def
/DA{
newpath arcn stroke
}bind def
/SN{
transform
.25 sub exch .25 sub exch
round .25 add exch round .25 add exch
itransform
}bind def
/DL{
SN
moveto
SN
lineto stroke
}bind def
/DC{
newpath 0 360 arc closepath
}bind def
/TM matrix def
/DE{
TM currentmatrix pop
translate scale newpath 0 0 .5 0 360 arc closepath
TM setmatrix
}bind def
/RC/rcurveto load def
/RL/rlineto load def
/ST/stroke load def
/MT/moveto load def
/CL/closepath load def
/Fr{
setrgbcolor fill
}bind def
/setcmykcolor where{
pop
/Fk{
setcmykcolor fill
}bind def
}if
/Fg{
setgray fill
}bind def
/FL/fill load def
/LW/setlinewidth load def
/Cr/setrgbcolor load def
/setcmykcolor where{
pop
/Ck/setcmykcolor load def
}if
/Cg/setgray load def
/RE{
findfont
dup maxlength 1 index/FontName known not{1 add}if dict begin
{
1 index/FID ne
2 index/UniqueID ne
and
{def}{pop pop}ifelse
}forall
/Encoding exch def
dup/FontName exch def
currentdict end definefont pop
}bind def
/DEFS 0 def
/EBEGIN{
moveto
DEFS begin
}bind def
/EEND/end load def
/CNT 0 def
/level1 0 def
/PBEGIN{
/level1 save def
translate
div 3 1 roll div exch scale
neg exch neg exch translate
0 setgray
0 setlinecap
1 setlinewidth
0 setlinejoin
10 setmiterlimit
[]0 setdash
/setstrokeadjust where{
pop
false setstrokeadjust
}if
/setoverprint where{
pop
false setoverprint
}if
newpath
/CNT countdictstack def
userdict begin
/showpage{}def
/setpagedevice{}def
mark
}bind def
/PEND{
cleartomark
countdictstack CNT sub{end}repeat
level1 restore
}bind def
end def
/setpacking where{
pop
setpacking
}if
%%EndResource
%%EndProlog
%%BeginSetup
%%BeginFeature: *PageSize Default
<< /PageSize [ 595 842 ] /ImagingBBox null >> setpagedevice
%%EndFeature
%%IncludeResource: font Times-Roman
%%IncludeResource: font Times-Bold
%%IncludeResource: font Courier-Bold
%%IncludeResource: font Courier-Oblique
%%IncludeResource: font Courier
%%IncludeResource: font Times-Italic
%%IncludeResource: font Symbol
grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72
def/PL 841.89 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron
/Zcaron/scaron/zcaron/Ydieresis/trademark/quotesingle/Euro/.notdef
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent
/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen
/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon
/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O
/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/circumflex
/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y
/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase/guillemotleft
/guillemotright/bullet/florin/fraction/perthousand/dagger/daggerdbl
/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen
/brokenbar/section/dieresis/copyright/ordfeminine/guilsinglleft
/logicalnot/minus/registered/macron/degree/plusminus/twosuperior
/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior
/ordmasculine/guilsinglright/onequarter/onehalf/threequarters
/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE
/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex
/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn
/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash
/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def
/Times-Italic@0 ENC0/Times-Italic RE/Courier@0 ENC0/Courier RE
/Courier-Oblique@0 ENC0/Courier-Oblique RE/Courier-Bold@0 ENC0
/Courier-Bold RE/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0
/Times-Roman RE
%%EndSetup
%%Page: 1 1
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF -.834(KLAPKI \(8\))72 48 R(System Manager')
131.659 E 2.5(sM)-.55 G 126.659(anual KLAPKI)-2.5 F(\(8\))1.666 E/F1 10
/Times-Bold@0 SF -.2(NA)72 96 S(ME).2 E/F2 10/Courier-Bold@0 SF(klapki)
102 108 Q F0 2.5<8a45>2.5 G(FI boot manager; or)-2.5 E 2.5(,w)-.4 G
(ell, an EFI bootorder compiler)-2.5 E F1(SYNOPSIS)72 132 Q F2(klapki)
102 144 Q F0([)3.333 E F2(\255nvVEh)2.499 E F0 2.5(][).833 G F2(op)-2.5
E F0([)6 E/F3 10/Courier-Oblique@0 SF(arg)A F0 1.666(]...)C 1.666(]...)
-1.666 G F1(DESCRIPTION)72 168 Q F0
(Generates and manages EFI boot entries on platforms compatible there)
102 180 Q(with.)-.25 E .301(This command-line interf)102 198 R .301
(ace is based on running a set of operations)-.1 F 1.666(\(s)4.467 G(ee)
-1.666 E F1(OPS)2.801 E F0 4.467(\)w)1.666 G .301
(hich modify the state and)-4.467 F(conte)102 210 Q .728
(xt, then settling the ne)-.15 F 3.229(ws)-.25 G .729
(et-up, then committing it; this means that, barring I/O errors,)-3.229
F F2(dump)3.229 E F0 .729(ing after)B(the last operation with)102 222 Q
F2<ad6e>4.166 E F0(is an accurate representation of what w)2.5 E
(ould be committed without it.)-.1 E .47(Care is tak)102 240 R .47
(en to only write what is needed and only when it')-.1 F 2.969(sn)-.55 G
.469(eeded \212 \214les and w)-2.969 F .469(anted entries are hashed)-.1
F .277(with SHA-1 and only updated on mismatch; foreign entries are ne)
102 252 R -.15(ve)-.25 G 2.777(rt).15 G .277(ouched, and)-2.777 F F2
(klapki)2.777 E F0 .277(prefers to aban-)2.777 F(don entries it doesn')
102 264 Q 2.5(tu)-.18 G(nderstand than to accidentally mangle them.)-2.5
E .643(Minimal state is stored, and it')102 282 R 3.143(so)-.55 G .643
(nly supplementary)-3.143 F 1.666(\(s)4.809 G(ee)-1.666 E F1(UNINST)
3.143 E(ALLA)-.9 E(TION)-.95 E F0 -.189 1.666(\). T)1.666 H .642
(his means that remo)-1.666 F(v-)-.15 E .063(ing all instances of a k)
102 294 R .063(ernel boot entry with tools such as)-.1 F/F4 10/Courier@0
SF(efibootmgr)2.563 E F0 .063(\(8\), the EFI Shell, or the platform UI)B
(will mak)102 306 Q(e)-.1 E F2(klapki)2.5 E F0(for)2.5 E
(get about the k)-.18 E(ernel entirely)-.1 E 2.5(,a)-.65 G
(fter minor complaints.)-2.5 E F2(klapki)102 324 Q F0 1.1 -.55('s e)D
(ntries).55 E/F5 10/Times-Italic@0 SF(can)2.5 E F0(be mo)2.5 E -.15(ve)
-.15 G 2.5(da).15 G(cross)-2.5 E F4(BootNNNN)2.5 E F0(entries, ho)2.5 E
(we)-.25 E -.15(ve)-.25 G .8 -.4(r, s).15 H 2.5(ol).4 G(ong as the)-2.5
E 2.5(ya)-.15 G(re k)-2.5 E(ept identical.)-.1 E F1(OPTIONS)72 348 Q F2
<ad6e>103.666 360 Q F0(Don')119 372 Q 2.5(tc)-.18 G
(ommit \212 nothing will be written to the \214lesystem or \214rmw)-2.5
E(are.)-.1 E F2<ad76>103.666 384 Q F0 -1.11(Ve)119 396 S
(rbose operation.)1.11 E F2<ad56>103.666 408 Q F0 -1.11(Ve)119 420 S
(ry v)1.11 E(erbose \212 adds a)-.15 E F2 -3.5(dump op)2.5 F F0
(in-between each speci\214ed)2.5 E F2(op)2.5 E F0(.)A F2<ad45>103.666
432 Q F0 .618(Increase libe\214v)119 444 R .618(ar v)-.25 F .618
(erbosity le)-.15 F -.15(ve)-.25 G 3.118(l. At).15 F .618
(time of writing,)3.118 F F4(LOG_VERBOSE)3.117 E F0(and)3.117 E F4
(LOG_DEBUG)3.117 E F0 3.117(,a)C .617(re supported)-3.117 F(and require)
119 456 Q F2<ad45>4.166 E F0(to be speci\214ed once and twice, respecti)
2.5 E -.15(ve)-.25 G(ly).15 E(.)-.65 E F2<ad68>103.666 468 Q F0(Sho)119
480 Q 3.036(wah)-.25 G .536
(elp message with these \215ags, recognised en)-3.036 F .537
(vironment v)-.4 F 2.203(ariables \()-.25 F(see)1.666 E F1(ENVIR)3.037 E
(ONMENT)-.3 E F0 4.703(\)a)1.666 G(nd)-4.703 E 1.666(ops \()119 492 R
(see)1.666 E F1(OPS)2.5 E F0 1.666(\).)1.666 G F1(ENVIR)72 516 Q(ONMENT)
-.3 E F4(KLAPKI_HOST)102 528 Q F0(Ov)197 528 Q(errides)-.15 E F2(klapi)
11.472 E F0 10.071 -.55('s h)D 8.971(ost identi\214er).55 F 13.971(.B)
-.55 G 11.471(yd)-13.971 G(ef)-11.471 E 8.971(ault, the v)-.1 F 8.971
(alue found in)-.25 F F4(/etc/machine-id)197 540 Q F0(\(or)2.5 E 2.5(,f)
-.4 G(ailing that, the current hostname\) is used.)-2.6 E 3
(Note, that the host identi\214er is used v)197 558 R 3
(erbatim as an EFI v)-.15 F 3(ariable name under)-.25 F F2(klapki)197
570 Q F0 1.1 -.55('s G)D 1.666(UID \().55 F F4
(a8a9ad3a-f831-11ea-946d-674ccd7415cc)1.666 E F0 1.666(\).)1.666 G F4
(KLAPKI_WISDOM)102 588 Q F0 2.23 -.8(To o)197 588 T .63
(btain the description and cmdline,).8 F F2(klapki)3.13 E F0 .63
(runs respecti)3.13 F -.15(ve)-.25 G .63(ly-named \214les under).15 F
2.011(the wisdom root, which is)197 600 R F4(/etc/klapki)4.511 E F0
2.011(by def)4.511 F 4.511(ault. This)-.1 F -.25(va)4.511 G 2.011(lue o)
.25 F -.15(ve)-.15 G 2.011(rrides that).15 F 2.5(path. If)197 612 R
(not empty)2.5 E 2.5(,a`)-.65 G F1(/)-2.5 E F0 2.5('i)C 2.5(sa)-2.5 G
(dditionally appended before the e)-2.5 E -.15(xe)-.15 G(cutable name.)
.15 E(See also)197 630 Q F1(WISDOM)2.5 E F0(belo)2.5 E -.65(w.)-.25 G F4
(KLAPKI_EFI_ROOT)102 648 Q F0 1.163(By def)197 648 R(ault,)-.1 E F2
(klapki)3.663 E F0 1.163(puts ne)3.663 F 1.162(wly-installed \214les in)
-.25 F F4(\\klapki\\)3.662 E F3(host)A F4(\\)A F3(version)A F0(un-)3.662
E(der the ESP)197 660 Q(.)-1.11 E 9.431(If present, this o)197 678 R
-.15(ve)-.15 G 9.431(rrides the constant pre\214x; for e).15 F 9.432
(xample, setting)-.15 F F4(KLAPKI_EFI_ROOT)197 690 Q F0 3.263(=w)C .763
(hen adding a k)-3.263 F .762
(ernel will put it and the initrds directly un-)-.1 F(der)197 702 Q F4
(\\)14.042 E F3(host)A F4(\\)A F3(version)A F0 1.666(\(n)15.708 G 11.542
(ote that by def)-1.666 F 11.543(ault this collides with)-.1 F
(klapki 0.1-13.9)72 750 Q(October 18, 2021)138.315 E(1)194.145 E 0 Cg EP
%%Page: 2 2
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF -.834(KLAPKI \(8\))72 48 R(System Manager')
131.659 E 2.5(sM)-.55 G 126.659(anual KLAPKI)-2.5 F(\(8\))1.666 E/F1 10
/Courier@0 SF(kernel-install)197 96 Q F0 -.834(\(8\) \))B/F2 10
/Times-Bold@0 SF(OPS)72 120 Q/F3 10/Courier-Bold@0 SF(dump)102 132 Q F0
.146(Write some state \(boot order)215 132 R 2.646(,t)-.4 G .146
(otal boot entries, boot position, each w)-2.646 F .145(anted entry)-.1
F(,)-.65 E .935(boot v)215 144 R .935(ariants\) and conte)-.25 F .935
(xt \(our k)-.15 F .935(ernels, fresh k)-.1 F .935
(ernels, deleted \214les\) to the stan-)-.1 F(dard output stream.)215
156 Q F3(bootpos)102 174 Q/F4 10/Courier-Oblique@0 SF(position)6 E F0
(Change the boot position to)215 174 Q F2(0)2.5 E F0(-based)A F4
(position)2.5 E F0(.)A .604
(The cluster of entries for the current host can be placed at an)215 192
R 3.103(yp)-.15 G .603(oint in the boot)-3.103 F .477(order; it')215 204
R(s)-.55 E F2(0)2.977 E F0 .477(\(at the be)2.977 F .477
(ginning\) by def)-.15 F .477(ault, b)-.1 F .477(ut if you ha)-.2 F .777
-.15(ve a)-.2 H .478(nother operating sys-).15 F 1.822
(tem or boot-loader and wish to ha)215 216 R 2.122 -.15(ve i)-.2 H 4.322
(tb).15 G 4.322(et)-4.322 G 1.822(he def)-4.322 F 1.822
(ault, you can simply mo)-.1 F -.15(ve)-.15 G F3(klapki)215 228 Q F0(do)
2.5 E(wn the required number of entries.)-.25 E(See description of)215
246 Q F3(addvariant)2.5 E F0(belo)2.5 E 2.5(wf)-.25 G
(or sorting inside the cluster)-2.5 E(.)-.55 E F3(addkernel)102 264 Q F4
(version image)6 E F0([)6 E F4(initrd)A F0 1.666(]...)C F3("").834 E F0
.492(Allocate entries for the k)215 276 R .492(ernel with)-.1 F F4
(version)2.992 E F0 .493(residing at)2.993 F F4(image)2.993 E F0 .493
(with initrds at)2.993 F F4(initrd)215 288 Q F0 5(.T)C
(he list of initrds is terminated with an empty ar)-5 E(gument.)-.18 E
2.307(This directi)215 306 R 2.607 -.15(ve i)-.25 H 4.807(si).15 G 2.307
(gnored if a k)-4.807 F 2.307(ernel with)-.1 F F4(version)4.807 E F0
2.306(is already kno)4.806 F 4.806(wn. See)-.25 F F3(delkernel)215 318 Q
F0(belo)2.5 E -.65(w.)-.25 G 5.855(The k)215 336 R(ernel)-.1 E F4(image)
8.355 E F0(and)8.355 E F4(initrd)8.355 E F0 8.355(sw)C 5.855
(ill be copied to the ESP)-8.355 F 1.666(\(s)10.022 G(ee)-1.666 E F1
(KLAPKI_EFI_ROOT)215 348 Q F0(in)6 E F2(ENVIR)2.5 E(ONMENT)-.3 E F0
4.166(\)d)1.666 G(uring conte)-4.166 E(xt commit.)-.15 E F3(delkernel)
102 366 Q F4(version)6 E F0(Pur)215 366 Q
(ge all entries for which the v)-.18 E(ersion is)-.15 E F4(version)2.5 E
F0(.)A 1.426(The k)215 384 R 1.426
(ernel image, initrds, and containing folder will, if not used, be remo)
-.1 F -.15(ve)-.15 G(d).15 E(from the ESP during conte)215 396 Q
(xt commit.)-.15 E F3(addvariant)102 414 Q F4(variant)6 E F0 .044
(Add an e)215 414 R(xplicit)-.15 E F4(variant)2.544 E F0 .044
(to the end, if not already kno)2.544 F 2.545(wn. Accompan)-.25 F .045
(ying boot)-.15 F(entries will be allocated in the deri)215 426 Q -.25
(va)-.25 G(tion phase as needed.).25 E -1.11(Va)215 444 S 1.39
(riants are a global property)1.11 F 3.89(,a)-.65 G 1.39(nd each k)-3.89
F 1.39(ernel has a boot entry generated for)-.1 F 1.48(each v)215 456 R
1.481(ariant \(that is: for the implicit v)-.25 F 1.481
(ariant, represented by the empty string,)-.25 F(plus for an)215 468 Q
2.5(yc)-.15 G(on\214gured e)-2.5 E(xplicit v)-.15 E(ariants\).)-.25 E
.644(The order of e)215 486 R .644(xplicit v)-.15 F .643
(ariants is preserv)-.25 F .643(ed within each v)-.15 F .643
(ersion group, which are)-.15 F 9.193(sorted highest-to-lo)215 498 R
11.693(west. F)-.25 F 9.194(or e)-.15 F 9.194(xample: a host with tw)
-.15 F 11.694(ok)-.1 G(ernels)-11.794 E(\()216.666 510 Q F1
(5.8.0-[12]-amd64)1.666 E F0 5.122(\)a)1.666 G .956(nd tw)-5.122 F 3.456
(oe)-.1 G .956(xplicit v)-3.606 F 2.622(ariants \()-.25 F F4(debug)1.666
E F0(,)A F4(silent)6.956 E F0 5.122(\)w)1.666 G(ill)-5.122 E .465
(produce the follo)215 522 R .466(wing entries)-.25 F 1.666(\(a)4.632 G
(ssuming)-1.666 E F1($KLAPKI_WISDOM/description)2.966 E F0(link)215 534
Q(ed to)-.1 E F1(/bin/echo)2.5 E F0 -3.332 1.666(\); n)1.666 H(ote ho)
-1.666 E 2.5(wt)-.25 G(he highest k)-2.5 E(ernel v)-.1 E
(ersion is at the top:)-.15 E F1(5.8.0-2-amd64)235 546 Q(5.8.0-2-amd64)
235 558 Q F4(debug)6 E F1(5.8.0-2-amd64)235 570 Q F4(silent)6 E F1
(5.8.0-1-amd64)235 582 Q(5.8.0-1-amd64)235 594 Q F4(debug)6 E F1
(5.8.0-1-amd64)235 606 Q F4(silent)6 E F0 .05(After running)215 624 R F3
(klapki)2.55 E F0 .05(with ")2.55 F F3(delvariant)A F4(debug)6.05 E F3
(addvariant)6.05 E F4(debug)6.05 E F0(",)A .767(the tw)215 636 R 3.267
(oe)-.1 G .767(xplicit v)-3.417 F .767(ariants are no)-.25 F 3.268(wo)
-.25 G .768(rdered dif)-3.268 F 2.434(ferently \()-.25 F F4(silent)1.666
E F0(,)A F4(debug)6.768 E F0 -2.564 1.666(\), a)1.666 H(nd)-1.666 E .369
(this is re\215ected in the boot order; note also ho)215 648 R 2.869(wt)
-.25 G .369(he implicit v)-2.869 F .369(ariant al)-.25 F -.1(wa)-.1 G
.369(ys sorts).1 F(earlier than an)215 660 Q 2.5(ye)-.15 G
(xplicit ones:)-2.65 E F1(5.8.0-2-amd64)235 672 Q F0(klapki 0.1-13.9)72
750 Q(October 18, 2021)138.315 E(2)194.145 E 0 Cg EP
%%Page: 3 3
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF -.834(KLAPKI \(8\))72 48 R(System Manager')
131.659 E 2.5(sM)-.55 G 126.659(anual KLAPKI)-2.5 F(\(8\))1.666 E/F1 10
/Courier@0 SF(5.8.0-2-amd64)235 96 Q/F2 10/Courier-Oblique@0 SF(silent)6
E F1(5.8.0-2-amd64)235 108 Q F2(debug)6 E F1(5.8.0-1-amd64)235 120 Q
(5.8.0-1-amd64)235 132 Q F2(silent)6 E F1(5.8.0-1-amd64)235 144 Q F2
(debug)6 E/F3 10/Courier-Bold@0 SF(delvariant)102 162 Q F2(variant)6 E
F0(Remo)215 162 Q .407 -.15(ve ex)-.15 H(plicit).15 E F2(variant)2.607 E
F0 2.607(,i)C 2.607(fa)-2.607 G -.15(ny)-2.607 G 2.607(;a).15 G(ccompan)
-2.607 E .107(ying boot entries will pur)-.15 F .108(ged in the)-.18 F
(deri)215 174 Q -.25(va)-.25 G(tion phase as needed.).25 E/F4 10
/Times-Bold@0 SF(WISDOM)72 198 Q F0 2.152(The entry description and k)
102 210 R 2.152(ernel cmdline are acquired by e)-.1 F -.15(xe)-.15 G
(cuting).15 E F3(description)4.651 E F0(and)4.651 E F3(cmdline)4.651 E
F0(in)4.651 E F1(/etc/klapki)102 222 Q F0 1.666(\(o)4.166 G(r)-1.666 E
F1(KLAPKI_WISDOM)2.5 E F0 6(,s)C(ee)-6 E F4(ENVIR)2.5 E(ONMENT)-.3 E F0
4.166(\)w)1.666 G(ith the follo)-4.166 E(wing ar)-.25 E(guments:)-.18 E
(1. ")122 234 Q F1(description)A F0 2.5("o)C 2.5(r")-2.5 G F1(cmdline)
-2.5 E F0(")A(2. k)122 246 Q(ernel v)-.1 E(ersion)-.15 E(3. boot v)122
258 Q(ariant)-.25 E .949(And the standard output tied to a pipe, which \
is then trimmed, and all ne)102 270 R .949
(wlines are replaced with a single)-.25 F(space.)102 282 Q .43
(Processing is stopped if the child e)102 300 R .429
(xits with a non-zero status or is killed by a signal.)-.15 F .429
(The special e)5.429 F .429(xit v)-.15 F(alue)-.25 E F4(0x6B)102 312 Q
F0 1.666(\(`)4.166 G F4(k)-1.666 E F0 -1.666 1.666('\) i)D 2.5(su)-1.666
G(sed to signal an error in e)-2.5 E -.15(xe)-.15 G
(cuting the wisdom binary).15 E(.)-.65 E(Additional)102 330 Q F3
(initrd=)3.575 E F0(statements)3.575 E/F5 10/Times-Italic@0 SF(should)
3.575 E F0 -.1(wo)3.575 G 1.075(rk \(with w).1 F 1.075
(arnings, hence the should.)-.1 F 1.075(Please report on the b)6.075 F
(ug)-.2 E(track)102 342 Q .373(er/mailing list)-.1 F 1.666(\(s)4.539 G
(ee)-1.666 E F4(REPOR)2.873 E .373(TING B)-.4 F(UGS)-.1 E F0 4.539(\)i)
1.666 G 2.873(fy)-4.539 G .372
(ou use them successfully!\) and will not be managed by)-2.873 F F3
(klapki)102 354 Q F0(,)A(The simplest)102 372 Q F1(/etc/klapki/)2.5 E F3
(description)A F0 -.1(wo)2.5 G(uld be a link to).1 E F1(/bin/echo)2.5 E
F0(.)A 2.5(As)102 384 S(imple)-2.5 E F3(cmdline)2.5 E F0(is a)2.5 E F1
(/bin/sh)2.5 E F0(shebang +)2.5 E F3(echo)2.5 E F0(command.)2.5 E 2.5
(Ac)102 396 S(ursed)-2.5 E F3(cmdline)2.5 E F0 -.1(wo)2.5 G(uld be a).1
E F1(/bin/sh)2.5 E F0(shebang and a)2.5 E F3 1.666(sed \255E)132 408 R
F1('s/initrd=[^ ]+ ?//g')6 E F2(/proc/cmdline)6 E F0(command.)102 420 Q
F4(UNINST)72 444 Q(ALLA)-.9 E(TION)-.95 E F0(Remo)102 456 Q 2.672 -.15
(ve t)-.15 H 2.372(he EFI v).15 F 2.372
(ariable corresponding to the host)-.25 F 1.666(\(s)6.538 G(ee)-1.666 E
F4(ENVIR)4.872 E(ONMENT)-.3 E F0 6.538(\)u)1.666 G(nder)-6.538 E F3
(klapki)4.873 E F0 3.473 -.55('s G)D(UID).55 E(\()103.666 468 Q F1
(a8a9ad3a-f831-11ea-946d-674ccd7415cc)1.666 E F0 -.193 1.666(\). T)1.666
H .639(his will pur)-1.666 F .638
(ge the state for the host, and, hence,)-.18 F 1.421(abandon an)102 480
R 3.921(ye)-.15 G 1.421(ntries left o)-3.921 F -.15(ve)-.15 G 2.221 -.4
(r, w).15 H 1.421(hich remain bootable; to remo).4 F 1.721 -.15(ve a)
-.15 H 1.422(ll klapki entries run).15 F F3(delkernel)3.922 E F0
(\214rst)3.922 E 1.666(\(s)103.666 492 S(ee)-1.666 E F4(OPS)2.5 E F0
-3.332 1.666(\), o)1.666 H 2.5(rr)-1.666 G(emo)-2.5 E .3 -.15(ve t)-.15
H(hem manually from the ESP and \214rmw).15 E(are afterw)-.1 E(ard.)-.1
E 21.449(Under Linux this in)102 510 R -.2(vo)-.4 G(lv).2 E 21.448
(es running)-.15 F F3 23.114(chattr \255i)23.948 F F0 23.948(,t)C(hen)
-23.948 E F3(rm)23.948 E F0(on)23.948 E(\()103.666 522 Q F1(/sys/firmwa\
re/efi/efivars/$KLAPKI_HOST-a8a9ad3a-f831-11ea-946d-674ccd7415cc)1.666 E
F0 1.666(\).)1.666 G F4 1.666(EXIT ST)72 546 R -.95(AT)-.9 G(US).95 E(0)
102 558 Q F0(success in all steps)119 558 Q F4(1)102 570 Q F0
(error reading con\214guration)119 570 Q F4(2)102 582 Q F0
(error loading state)119 582 Q F4(3)102 594 Q F0(error resolving state)
119 594 Q F4(4)102 606 Q F0(error running an op)119 606 Q F4(5)102 618 Q
F0(error in propag)119 618 Q(ation phase)-.05 E F4(6)102 630 Q F0
(error in aging phase)119 630 Q F4(7)102 642 Q F0
(error in wisening phase)119 642 Q F4(8)102 654 Q F0(error in sa)119 654
Q(ving phase)-.2 E F4(9)102 666 Q F0(error committing conte)119 666 Q
(xt)-.15 E F4(10)102 678 Q F0(error committing state)119 678 Q
(klapki 0.1-13.9)72 750 Q(October 18, 2021)138.315 E(3)194.145 E 0 Cg EP
%%Page: 4 4
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF -.834(KLAPKI \(8\))72 48 R(System Manager')
131.659 E 2.5(sM)-.55 G 126.659(anual KLAPKI)-2.5 F(\(8\))1.666 E/F1 10
/Times-Bold@0 SF(EXAMPLES)72 96 Q F0 2.5(As)102 108 S(imple set-up:)-2.5
E/F2 10/Courier@0 SF(#)122 120 Q/F3 10/Courier-Bold@0 SF 1.666(ls \255l)
6 F F2(description cmdline)6 E
(-rwxr-xr-x 1 root root 79 Sep 21 03:30 cmdline)122 132 Q
(lrwxrwxrwx 1 root root)122 144 Q 6(9S)12 G
(ep 20 04:30 description -> /bin/echo)-6 E(#)122 156 Q F3(cat)6 E F2
(cmdline)6 E(#!/bin/sh)122 168 Q(echo root=ZFS=zoot/root console=ttyS0)
122 180 Q F0(Add a k)102 198 Q(ernel with a single initrd, and a v)-.1 E
(ariant:)-.25 E F2 6(#K)122 210 S(LAPKI_HOST)-6 E F1(=)A/F4 10
/Courier-Oblique@0 SF(zoot)A F3(klapki addkernel)6 E F2
(5.8.0-2-amd64 /boot/vmlinuz-5.8.0-2-amd64)6 E F3(\\)6 E F2
(/boot/initrd.img-5.8.0-2-amd64)134 222 Q F3("" addvariant)6 E F2(debug)
6 E(EFI load: no config for this host \(zoot\) found; going to the top)
122 234 Q(Entry 000B changed)122 246 Q(Entry 000D changed)122 258 Q
(Entry 000B: copied vmlinuz-5.8.0-2-amd64)122 270 Q
(from /boot to \\KLAPKI\\ZOOT\\5.8.0-2-AMD64\\)194 282 Q
(Entry 000B: copied initrd.img-5.8.0-2-amd64)122 294 Q
(from /boot to \\KLAPKI\\ZOOT\\5.8.0-2-AMD64\\)194 306 Q
(Updating state config)122 318 Q(Updating boot order)122 330 Q
(Writing entry 000B)122 342 Q(Writing entry 000D)122 354 Q F0
(Success! But the ne)102 372 Q(w)-.25 E F4(debug)2.5 E F0(entry doesn')
2.5 E 2.5(tr)-.18 G(eally do much:)-2.5 E F2(#)122 384 Q F3(efibootmgr)6
E F2(BootCurrent: 000D)122 396 Q(Timeout: 0 seconds)122 408 Q(BootOrder\
: 000B,000D,000C,000A,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009)
122 420 Q(Boot0000 through Boot0008 omitted)122 432 Q(Boot0009)122 444 Q
/F5 10/Symbol SF(*)A F2(EFI Internal Shell)6 E
(FvVol\(...\)/FvFile\(...\))24 E(Boot000A)122 456 Q F5(*)A F2
(Linux Boot Manager)6 E
(HD\(...\)/File\(\\EFI\\systemd\\systemd-bootx64.efi\))24 E(Boot000B)122
468 Q F5(*)A F2(5.8.0-2-amd64 HD\(...\)/)6 E
(File\(\\KLAPKI\\ZOOT\\5.8.0-2-AMD64\\VMLINUZ-5.8.0-2-AMD64\))182 480 Q
(initrd=\\klapki\\zoot\\5.8.0-2-amd64\\initrd.img-5.8.0-2-amd64)182 492
Q(root=ZFS=zoot/root console=ttyS0)182 504 Q(Boot000C)122 516 Q F5(*)A
F2(zoot 5.8.0-1-amd64)6 E(HD\(...\)/)24 E
(File\(\\62dd03a4928c412180b3024ac6c03a90\\5.8.0-1-amd64\\linux\))182
528 Q(initrd=\\62dd03a4928c412180b3024ac6c03a90\\5.8.0-1-amd64\\)182 540
Q(initrd.img-5.8.0-1-amd64)224 552 Q(root=ZFS=zoot/root console=ttyS0)
182 564 Q(Boot000D)122 576 Q F5(*)A F2(5.8.0-2-amd64 debug)6 E
(HD\(...\)/)18 E
(File\(\\KLAPKI\\ZOOT\\5.8.0-2-AMD64\\VMLINUZ-5.8.0-2-AMD64\))182 588 Q
(initrd=\\klapki\\zoot\\5.8.0-2-amd64\\initrd.img-5.8.0-2-amd64)182 600
Q(root=ZFS=zoot/root console=ttyS0)182 612 Q F0(Uncontri)102 630 Q -.15
(ve)-.25 G(dly).15 E 3.016(,a)-.65 G .516
(dding a conditional with another ar)-3.016 F .516(gument to enable deb)
-.18 F .515(ugging in the Intel PR)-.2 F .515(O/100 dri)-.4 F -.15(ve)
-.25 G(r).15 E(and re-running)102 642 Q F3(klapki)2.5 E F0(will w)2.5 E
(ork:)-.1 E F2(#)122 654 Q F3(cat)6 E F2(cmdline)6 E(#!/bin/sh)122 666 Q
(echo root=ZFS=zoot/root console=ttyS0)122 678 Q 6([")122 690 S
($2" = "debug" ] && echo e100.debug=16 || :)-6 E F0(klapki 0.1-13.9)72
750 Q(October 18, 2021)138.315 E(4)194.145 E 0 Cg EP
%%Page: 5 5
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF -.834(KLAPKI \(8\))72 48 R(System Manager')
131.659 E 2.5(sM)-.55 G 126.659(anual KLAPKI)-2.5 F(\(8\))1.666 E/F1 10
/Courier@0 SF 6(#K)122 96 S(LAPKI_WISDOM)-6 E/F2 10/Times-Bold@0 SF(=)A
F1 6(.K)C(LAPKI_HOST)-6 E F2(=)A/F3 10/Courier-Oblique@0 SF(zoot)A/F4 10
/Courier-Bold@0 SF(klapki)6 E F1(Entry 000D changed)122 108 Q
(Updating state config)122 120 Q(Updating entry 000D)122 132 Q F0 .632
(Note, that, as e)102 150 R .633(xpected, only the state con\214guratio\
n \(which stores the hash of the w)-.15 F .633
(anted entry\) and the de-)-.1 F -.2(bu)102 162 S 2.5(ge).2 G
(ntry itself were updated:)-2.5 E F1(#)122 174 Q F4 1.666
(efibootmgr \255v)6 F F1(BootCurrent: 000D)122 186 Q(Timeout: 0 seconds)
122 198 Q(BootOrder: 000B,000D,000C,000A,0000,0001,0002,0003,0004,0005,\
0006,0007,0008,0009)122 210 Q
(Boot0000 through Boot000A and Boot000C omitted)122 222 Q(Boot000B)122
234 Q/F5 10/Symbol SF(*)A F1(5.8.0-2-amd64 HD\(...\)/)6 E
(File\(\\KLAPKI\\ZOOT\\5.8.0-2-AMD64\\VMLINUZ-5.8.0-2-AMD64\))182 246 Q
(initrd=\\klapki\\zoot\\5.8.0-2-amd64\\initrd.img-5.8.0-2-amd64)182 258
Q(root=ZFS=zoot/root console=ttyS0)182 270 Q(Boot000D)122 282 Q F5(*)A
F1(5.8.0-2-amd64 debug)6 E(HD\(...\)/)18 E
(File\(\\KLAPKI\\ZOOT\\5.8.0-2-AMD64\\VMLINUZ-5.8.0-2-AMD64\))182 294 Q
(initrd=\\klapki\\zoot\\5.8.0-2-amd64\\initrd.img-5.8.0-2-amd64)182 306
Q(root=ZFS=zoot/root console=ttyS0 e100.debug=16)182 318 Q F2(REPOR)72
342 Q 1.666(TING B)-.4 F(UGS)-.1 E(https://todo.sr)102 354 Q
(.ht/~nabijaczleweli/klapki)-1 E F1(~nabijaczleweli/klapki@lists.sr.ht)
102 372 Q F0 2.5(,a)C(rchi)-2.5 E -.15(ve)-.25 G 2.5(da).15 G(t)-2.5 E
F2(https://lists.sr)2.5 E(.ht/~nabijaczleweli/klapki)-1 E F0(.)A F2
1.666(SEE ALSO)72 396 R F1(gethostname)102 408 Q F0(\(2\),)A F1
(memfd_create)2.5 E F0(\(2\),)A F1(execl)2.5 E F0(\(3\),)A F1(SHA1)2.5 E
F0(\(3ssl\),)A F1(efibootmgr)2.5 E F0(\(8\),)A F1(kernel-install)102 420
Q F0(\(8\))A F2(https://git.sr)102 438 Q(.ht/~nabijaczleweli/klapki)-1 E
F0(UEFI speci\214cation, Se)102 456 Q
(xion 3.1.3 Load Options and related:)-.15 E F2(https://ue\214.or)102
468 Q(g/sites/default/\214les/r)-.1 E(esour)-.18 E
(ces/UEFI_Spec_2_8_\214nal.pdf)-.18 E F0(libe\214v)102 486 Q(ar v)-.25 E
(erbosity le)-.15 E -.15(ve)-.25 G(ls:).15 E F2(https://github)102 498 Q
(.com/rhboot/e\214v)-.4 E(ar/blob/36297adcb266f07b)-.1 E
(b06e725a0da377bc6e6aedd0/sr)-.1 E(c/util.h#L328)-.18 E -.5(AU)72 522 S
(THORS).5 E F0(Written by)102 534 Q(<nabijaczle)5 E(weli@nabijaczle)-.25
E(weli.xyz>.)-.25 E F2 1.666(SPECIAL THANKS)72 558 R F0 1.6 -.8(To a)102
570 T(ll who support further de).8 E -.15(ve)-.25 G
(lopment, in particular:).15 E F2<83>122 582 Q F0(ThePhD)2.5 E F2<83>122
594 Q F0(Embark Studios)2.5 E(klapki 0.1-13.9)72 750 Q(October 18, 2021)
138.315 E(5)194.145 E 0 Cg EP
%%Trailer
end
%%EOF

A style.css => style.css +297 -0
@@ 0,0 1,297 @@
/* $OpenBSD: mandoc.css,v 1.33 2019/06/02 16:50:46 schwarze Exp $ */
/*
 * Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
 *
 * Written by Ingo Schwarze <schwarze@openbsd.org>.
 * I place this file into the public domain.
 * Permission to use, copy, modify, and distribute it for any purpose
 * with or without fee is hereby granted, without any conditions.
 */
/* Tooltips removed. */

/* Global defaults. */

html {		max-width: 65em;
		--bg: #FFFFFF;
		--fg: #000000; }
body {		background: var(--bg);
		color: var(--fg);
		font-family: Helvetica,Arial,sans-serif; }
h1 {		font-size: 110%; }
table {		margin-top: 0em;
		margin-bottom: 0em;
		border-collapse: collapse; }
/* Some browsers set border-color in a browser style for tbody,
 * but not for table, resulting in inconsistent border styling. */
tbody {		border-color: inherit; }
tr {		border-color: inherit; }
td {		vertical-align: top;
		padding-left: 0.2em;
		padding-right: 0.2em;
		border-color: inherit; }
ul, ol, dl {	margin-top: 0em;
		margin-bottom: 0em; }
li, dt {	margin-top: 1em; }

.permalink {	border-bottom: thin dotted;
		color: inherit;
		font: inherit;
		text-decoration: inherit; }
* {		clear: both }

/* Search form and search results. */

fieldset {	border: thin solid silver;
		border-radius: 1em;
		text-align: center; }
input[name=expr] {
		width: 25%; }

table.results {	margin-top: 1em;
		margin-left: 2em;
		font-size: smaller; }

/* Header and footer lines. */

table.head {	width: 100%;
		border-bottom: 1px dotted #808080;
		margin-bottom: 1em;
		font-size: smaller; }
td.head-vol {	text-align: center; }
td.head-rtitle {
		text-align: right; }

table.foot {	width: 100%;
		border-top: 1px dotted #808080;
		margin-top: 1em;
		font-size: smaller; }
td.foot-os {	text-align: right; }

/* Sections and paragraphs. */

.manual-text {
		margin-left: 3.8em; }
.Nd { }
section.Sh { }
h1.Sh {		margin-top: 1.2em;
		margin-bottom: 0.6em;
		margin-left: -3.2em; }
section.Ss { }
h2.Ss {		margin-top: 1.2em;
		margin-bottom: 0.6em;
		margin-left: -1.2em;
		font-size: 105%; }
.Pp {		margin: 0.6em 0em; }
.Sx { }
.Xr { }

/* Displays and lists. */

.Bd { }
.Bd-indent {	margin-left: 3.8em; }

.Bl-bullet {	list-style-type: disc;
		padding-left: 1em; }
.Bl-bullet > li { }
.Bl-dash {	list-style-type: none;
		padding-left: 0em; }
.Bl-dash > li:before {
		content: "\2014  "; }
.Bl-item {	list-style-type: none;
		padding-left: 0em; }
.Bl-item > li { }
.Bl-compact > li {
		margin-top: 0em; }

.Bl-enum {	padding-left: 2em; }
.Bl-enum > li { }
.Bl-compact > li {
		margin-top: 0em; }

.Bl-diag { }
.Bl-diag > dt {
		font-style: normal;
		font-weight: bold; }
.Bl-diag > dd {
		margin-left: 0em; }
.Bl-hang { }
.Bl-hang > dt { }
.Bl-hang > dd {
		margin-left: 5.5em; }
.Bl-inset { }
.Bl-inset > dt { }
.Bl-inset > dd {
		margin-left: 0em; }
.Bl-ohang { }
.Bl-ohang > dt { }
.Bl-ohang > dd {
		margin-left: 0em; }
.Bl-tag {	margin-top: 0.6em;
		margin-left: 5.5em; }
.Bl-tag > dt {
		float: left;
		margin-top: 0em;
		margin-left: -5.5em;
		padding-right: 0.5em;
		vertical-align: top; }
.Bl-tag > dd {
		clear: right;
		column-count: 1;  /* Force block formatting context. */
		width: 100%;
		margin-top: 0em;
		margin-left: 0em;
		margin-bottom: 0.6em;
		vertical-align: top; }
.Bl-compact {	margin-top: 0em; }
.Bl-compact > dd {
		margin-bottom: 0em; }
.Bl-compact > dt {
		margin-top: 0em; }

.Bl-column { }
.Bl-column > tbody > tr { }
.Bl-column > tbody > tr > td {
		margin-top: 1em; }
.Bl-compact > tbody > tr > td {
		margin-top: 0em; }

.Rs {		font-style: normal;
		font-weight: normal; }
.RsA { }
.RsB {		font-style: italic;
		font-weight: normal; }
.RsC { }
.RsD { }
.RsI {		font-style: italic;
		font-weight: normal; }
.RsJ {		font-style: italic;
		font-weight: normal; }
.RsN { }
.RsO { }
.RsP { }
.RsQ { }
.RsR { }
.RsT {		text-decoration: underline; }
.RsU { }
.RsV { }

.eqn { }
.tbl td {	vertical-align: middle; }

.HP {		margin-left: 3.8em;
		text-indent: -3.8em; }

/* Semantic markup for command line utilities. */

table.Nm { }
code.Nm {	font-style: normal;
		font-weight: bold;
		font-family: monospace; }
.Fl {		font-style: normal;
		font-weight: bold;
		font-family: monospace; }
.Cm {		font-style: normal;
		font-weight: bold;
		font-family: monospace; }
.Ar {		font-style: italic;
		font-weight: normal;
		font-family: monospace; }
.Op {		display: inline; }
.Ic {		font-style: normal;
		font-weight: bold;
		font-family: monospace; }
.Ev {		font-style: normal;
		font-weight: normal;
		font-family: monospace; }
.Pa {		font-style: italic;
		font-weight: normal; }

/* Semantic markup for function libraries. */

.Lb { }
code.In {	font-style: normal;
		font-weight: bold;
		font-family: inherit; }
a.In { }
.Fd {		font-style: normal;
		font-weight: bold;
		font-family: inherit; }
.Ft {		font-style: italic;
		font-weight: normal; }
.Fn {		font-style: normal;
		font-weight: bold;
		font-family: inherit; }
.Fa {		font-style: italic;
		font-weight: normal; }
.Vt {		font-style: italic;
		font-weight: normal; }
.Va {		font-style: italic;
		font-weight: normal; }
.Dv {		font-style: normal;
		font-weight: normal;
		font-family: monospace; }
.Er {		font-style: normal;
		font-weight: normal;
		font-family: monospace; }

/* Various semantic markup. */

.An { }
.Lk { }
.Mt { }
.Cd {		font-style: normal;
		font-weight: bold;
		font-family: inherit; }
.Ad {		font-style: italic;
		font-weight: normal; }
.Ms {		font-style: normal;
		font-weight: bold; }
.St { }
.Ux { }

/* Physical markup. */

.Bf {		display: inline; }
.No {		font-style: normal;
		font-weight: normal; }
.Em {		font-style: italic;
		font-weight: normal; }
.Sy {		font-style: normal;
		font-weight: bold; }
.Li {		font-style: normal;
		font-weight: normal;
		font-family: monospace; }

/* Tooltip support. */

h1.Sh, h2.Ss {	position: relative; }
.Li, .An, .Ar, .Cd, .Cm, .Dv, .Em, .Er, .Ev, .Fa, .Fd, .Fl, .Fn, .Ft,
.Ic, code.In, .Lb, .Lk, .Ms, .Mt, .Nd, code.Nm, .Pa, .Rs,
.St, .Sx, .Sy, .Va, .Vt, .Xr {
		display: inline-block;
		position: relative; }

/* Overrides to avoid excessive margins on small devices. */

@media (max-width: 37.5em) {
.manual-text {
		margin-left: 0.5em; }
h1.Sh, h2.Ss {	margin-left: 0em; }
.Bd-indent {	margin-left: 2em; }
.Bl-hang > dd {
		margin-left: 2em; }
.Bl-tag {	margin-left: 2em; }
.Bl-tag > dt {
		margin-left: -2em; }
.HP {		margin-left: 2em;
		text-indent: -2em; }
}

/* Overrides for a dark color scheme for accessibility. */

@media (prefers-color-scheme: dark) {
html {		--bg: #1E1F21;
		--fg: #EEEFF1; }
:link {		color: #BAD7FF; }
:visited {	color: #F6BAFF; }
}