1
0
mirror of https://github.com/systemd/systemd synced 2026-04-22 23:15:20 +02:00

Compare commits

..

No commits in common. "34c4dff4d2e592e90dd9833fee4ce1ac981e8ea9" and "27a5281f4b58d4556dfae392957cc190555f663a" have entirely different histories.

9 changed files with 259 additions and 501 deletions

43
NEWS
View File

@ -21,42 +21,13 @@ CHANGES WITH 251:
for breaking backward compatibility instead, as nobody should be for breaking backward compatibility instead, as nobody should be
affected, given the state of the current interface. affected, given the state of the current interface.
* Service monitor environment variables will only be passed to * Service monitor environment variables will only be passed to OnFailure=/OnSuccess=
OnFailure=/OnSuccess= handlers if exactly one unit lists the handler handlers if exactly one unit lists the handler unit as OnFailure=/OnSuccess=.
unit as OnFailure=/OnSuccess=. Therefore, $MONITOR_METADATA is no Therefore, $MONITOR_METADATA is no longer used, and instead separate
longer used, and instead separate variables are used: variables are used: $MONITOR_SERVICE_RESULT, $MONITOR_EXIT_CODE,
$MONITOR_SERVICE_RESULT, $MONITOR_EXIT_CODE, $MONITOR_EXIT_STATUS, $MONITOR_EXIT_STATUS, $MONITOR_INVOCATION_ID and $MONITOR_UNIT.
$MONITOR_INVOCATION_ID and $MONITOR_UNIT. For cases when a single For cases when a single handler needs to watch multiple units, use a
handler needs to watch multiple units, use a templated handler. templated handler.
* kernel-install's and bootctl's Boot Loader Specification Type #1
entry generation logic has been reworked. The user may now pick
explicitly by which "token" string to name the installation's boot
entries, through the new /etc/kernel/entry-token file or the new
--entry-token= switch to bootctl. By default — as before — the
entries are named after the local machine ID. However, in "golden
image" environments, where the machine ID shall be initialized on
first boot (as opposed to at installation time before first boot) the
machine ID is not be available at build time to name the entry
after. In this case the the --entry-token= switch to bootctl (or the
/etc/kernel/entry-token file) may be used to override the "token" to
identify the entry by, and use another ID, for example the IMAGE_ID=
or ID= fields from /etc/os-release. This will make the OS images
independent of any machine ID, and ensure that the images will not
carry any identifiable information before first boot, but on the
other hand means that multiple parallel installations of the very
same image on the same disk cannot be supported. Summary: if you are
building golden images that shall acquire identity information
exclusively on first boot, make sure to both remove /etc/machine-id
*and* to write /etc/kernel/entry-token to the value of the IMAGE_ID
or ID field of /etc/os-release or another suitable identifier before
deploying the image.
* The --make-machine-id-directory= switch to bootctl has been replaced
by --make-entry-directory=, given that the entry directory is not
necessarily named after the machine ID, but after some other suitable
ID as selected via --entry-token= described above. The old name of
the option is still understood to maximize compatibility.
* Services with Restart=always and a failing ExecCondition= will no longer * Services with Restart=always and a failing ExecCondition= will no longer
be restarted, to bring ExecCondition= in line with Condition*= settings. be restarted, to bring ExecCondition= in line with Condition*= settings.

View File

@ -258,60 +258,23 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>--make-entry-directory=yes|no</option></term> <term><option>--make-machine-id-directory=yes|no</option></term>
<listitem><para>Controls creation and deletion of the <ulink <listitem><para>Control creation and deletion of the top-level machine ID directory on the file
url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink> Type #1 entry system containing boot loader entries (i.e. beneath the file system returned by the
directory on the file system containing resources such as kernel images and initial RAM disk images <option>--print-boot-path</option> option, see above) during <option>install</option> and
during <option>install</option> and <option>remove</option>, respectively. The directory is named <option>remove</option>, respectively. Defaults to <literal>no</literal>. See
after the entry token, as specified with <option>--entry-token=</option> parameter described below,
and is placed immediately below the <varname>$BOOT</varname> root directory (i.e. beneath the file
system returned by the <option>--print-boot-path</option> option, see above). Defaults to
<literal>no</literal>.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--entry-token=</option></term>
<listitem><para>Controls how to name and identify boot loader entries for this OS
installation. Accepted during <option>install</option>, and takes one of <literal>auto</literal>,
<literal>machine-id</literal>, <literal>os-id</literal>, <literal>os-image-id</literal> or an
arbitrary string prefixed by <literal>literal:</literal> as argument.</para>
<para>If set to <option>machine-id</option> the entries are named after the machine ID of the running
system (e.g. <literal>b0e793a9baf14b5fa13ecbe84ff637ac</literal>). See
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> for <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
details about the machine ID concept and file.</para> details about the machine ID concept and file.</para>
<para>If set to <option>os-id</option> the entries are named after the OS ID of the running system, <para>Overriding this may be desirable to hide the machine ID from the (unencrypted) ESP, configure a
i.e. the <varname>ID=</varname> field of <citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry>
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry> script, or, conversely, commit a transient machine ID.</para>
(e.g. <literal>fedora</literal>). Similar, if set to <option>os-image-id</option> the entries are
named after the OS image ID of the running system, i.e. the <varname>IMAGE_ID=</varname> field of
<filename>os-release</filename> (e.g. <literal>vendorx-cashier-system</literal>).</para>
<para>If set to <option>auto</option> (the default), the <filename>/etc/kernel/entry-token</filename> <para>The top-level machine ID directory is useful to allow smooth multi-boot installations: each
file will be read if it exists, and the stored value used. Otherwise if the local machine ID is installed OS instance will have a different machine ID and thus a separate directory to place its
initialized it is used. Otherwise <varname>IMAGE_ID=</varname> from <filename>os-release</filename> boot-time resources in. If this feature is turned off with this option, care needs to be taken that
will be used, if set. Otherwise, <varname>ID=</varname> from <filename>os-release</filename> will be multiple OS instances do not place conflicting files on the shared ESP and Extended Boot Loader
used, if set.</para> Partitions, or that multiple OS instances are not possible.</para></listitem>
<para>Unless set to <literal>machine-id</literal>, or when
<option>--make-entry-directory=yes</option> is used the selected token string is written to a file
<filename>/etc/kernel/entry-token</filename>, to ensure it will be used for future entries. This file
is also read by
<citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
in order to identify under which name to generate boot loader entries for newly installed kernels, or
to determine the entry names for removing old ones.</para>
<para>Using the machine ID for naming the entries is generally preferable, however there are cases
where using the other identifiers is a good option. Specifically: if the identification data that the
machine ID entails shall not be stored on the (unencrypted) <varname>$BOOT</varname> partition, or if
the ID shall be generated on first boot and is not known when the entries are prepared. Note that
using the machine ID has the benefit that multiple parallel installations of the same OS can coexist
on the same medium, and they can update their boot loader entries independently. When using another
identifier (such as the OS ID or the OS image ID), parallel installations of the same OS would try to
use the same entry name. To support parallel installations, the installer must use a different entry
token when adding a second installation.</para></listitem>
</varlistentry> </varlistentry>
<xi:include href="standard-options.xml" xpointer="no-pager"/> <xi:include href="standard-options.xml" xpointer="no-pager"/>

View File

@ -39,21 +39,21 @@
<filename>/boot/</filename>, <filename>/efi/</filename>, or <filename>/boot/efi/</filename>, see below. <filename>/boot/</filename>, <filename>/efi/</filename>, or <filename>/boot/efi/</filename>, see below.
</para> </para>
<para><command>kernel-install</command> will run the executable files ("plugins") located in the <para><command>kernel-install</command> will execute the files
directory <filename>/usr/lib/kernel/install.d/</filename> and the local administration directory located in the directory <filename>/usr/lib/kernel/install.d/</filename>
<filename>/etc/kernel/install.d/</filename>. All files are collectively sorted and executed in lexical and the local administration directory <filename>/etc/kernel/install.d/</filename>.
order, regardless of the directory in which they live. However, files with identical filenames replace All files are collectively sorted and executed in lexical order, regardless of the directory in
each other. Files in <filename>/etc/kernel/install.d/</filename> take precedence over files with the which they live. However, files with identical filenames replace each other.
same name in <filename>/usr/lib/kernel/install.d/</filename>. This can be used to override a Files in <filename>/etc/kernel/install.d/</filename> take precedence over files with the same name
system-supplied executables with a local file if needed; a symbolic link in in <filename>/usr/lib/kernel/install.d/</filename>. This can be used to override a system-supplied
<filename>/etc/kernel/install.d/</filename> with the same name as an executable in executables with a local file if needed; a symbolic link in <filename>/etc/kernel/install.d/</filename>
<filename>/usr/lib/kernel/install.d/</filename>, pointing to <filename>/dev/null</filename>, disables the with the same name as an executable in <filename>/usr/lib/kernel/install.d/</filename>,
executable entirely. Executables must have the extension <literal>.install</literal>; other extensions pointing to <filename>/dev/null</filename>, disables the executable entirely. Executables must have the
are ignored.</para> extension <literal>.install</literal>; other extensions are ignored.</para>
<para>An executable placed in these directories should return <constant>0</constant> on success. It may <para>An executable should return <constant>0</constant> on success. It may also
also return <constant>77</constant> to cause the whole operation to terminate (executables later in return <constant>77</constant> to cause the whole operation to terminate
lexical order will be skipped).</para> (executables later in lexical order will be skipped).</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -64,45 +64,37 @@
<term><command>add <replaceable>KERNEL-VERSION</replaceable> <replaceable>KERNEL-IMAGE</replaceable> [<replaceable>INITRD-FILE</replaceable> ...]</command></term> <term><command>add <replaceable>KERNEL-VERSION</replaceable> <replaceable>KERNEL-IMAGE</replaceable> [<replaceable>INITRD-FILE</replaceable> ...]</command></term>
<listitem> <listitem>
<para>This command expects a kernel version string and a path to a kernel image file as <para>This command expects a kernel version string and a path to a kernel image file as
arguments. Optionally, one or more initial RAM disk images may be specified as well (note that arguments. <command>kernel-install</command> calls the executables from
plugins might generate additional ones). <command>kernel-install</command> calls the executable <filename>/usr/lib/kernel/install.d/*.install</filename> and
files from <filename>/usr/lib/kernel/install.d/*.install</filename> and <filename>/etc/kernel/install.d/*.install</filename> with the following arguments:
<filename>/etc/kernel/install.d/*.install</filename> (i.e. the plugins) with the following
arguments:</para>
<programlisting>add <replaceable>KERNEL-VERSION</replaceable> <filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename> <replaceable>KERNEL-IMAGE</replaceable> [<replaceable>INITRD-FILE</replaceable> ...]</programlisting> <programlisting>add <replaceable>KERNEL-VERSION</replaceable> <filename>$BOOT/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename> <replaceable>KERNEL-IMAGE</replaceable> [<replaceable>INITRD-FILE</replaceable> ...]</programlisting>
</para>
<para>The third argument directly refers to the path where to place kernel images, initial RAM disk
images and other resources for <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot
Loader Specification</ulink> Type #1 entries (the "entry directory"). If other boot loader schemes
are used the parameter may be ignored. The <replaceable>ENTRY-TOKEN</replaceable> string is
typically the machine ID and is supposed to identify the local installation on the system. For
details see below.</para>
<para>Two default plugins execute the following operations in this case:</para> <para>Two default plugins execute the following operations in this case:</para>
<itemizedlist> <itemizedlist>
<listitem><para><command>kernel-install</command> creates <listitem><para><command>kernel-install</command> creates
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL-VERSION</replaceable></filename>, <filename>$BOOT/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable></filename>,
if enabled (see <varname>$KERNEL_INSTALL_LAYOUT</varname>).</para></listitem> if enabled (see <varname>$KERNEL_INSTALL_LAYOUT=</varname>).</para></listitem>
<listitem><para><filename>50-depmod.install</filename> runs <listitem><para><filename>50-depmod.install</filename> runs
<citerefentry project='man-pages'><refentrytitle>depmod</refentrytitle><manvolnum>8</manvolnum></citerefentry> for the <citerefentry project='man-pages'><refentrytitle>depmod</refentrytitle><manvolnum>8</manvolnum></citerefentry> for the
<replaceable>KERNEL-VERSION</replaceable>.</para></listitem> <replaceable>KERNEL-VERSION</replaceable>.</para></listitem>
<listitem><para><filename>90-loaderentry.install</filename> copies <listitem><para><filename>90-loaderentry.install</filename>
<replaceable>KERNEL-IMAGE</replaceable> to copies <replaceable>KERNEL-IMAGE</replaceable> to
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/linux</filename>. <filename>$BOOT/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/linux</filename>.
If <replaceable>INITRD-FILE</replaceable>s are provided, it also copies them to If <replaceable>INITRD-FILE</replaceable>s are provided, it also copies them to
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL_VERSION</replaceable>/<replaceable>INITRD-FILE</replaceable></filename>. <filename>$BOOT/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL_VERSION</replaceable>/<replaceable>INITRD-FILE</replaceable></filename>.
It also creates a boot loader entry according to the <ulink It also creates a boot loader entry according to the <ulink
url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink> (Type #1) in url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink> in
<filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>. <filename>$BOOT/loader/entries/<replaceable>MACHINE-ID</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>.
The title of the entry is the <replaceable>PRETTY_NAME</replaceable> parameter specified in The title of the entry is the <replaceable>PRETTY_NAME</replaceable> parameter specified in
<filename>/etc/os-release</filename> or <filename>/usr/lib/os-release</filename> (if the former <filename>/etc/os-release</filename> or <filename>/usr/lib/os-release</filename> (if the former is
is missing), or "Linux <replaceable>KERNEL-VERSION</replaceable>", if unset.</para> missing), or "Linux <replaceable>KERNEL-VERSION</replaceable>", if unset.</para>
<para>If <varname>$KERNEL_INSTALL_LAYOUT</varname> is not "bls", this plugin does nothing.</para></listitem> <para>If <varname>$KERNEL_INSTALL_LAYOUT=</varname> is not "bls", this plugin does nothing.</para></listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -112,13 +104,13 @@
<para>This command expects a kernel version string as single argument. This calls executables from <para>This command expects a kernel version string as single argument. This calls executables from
<filename>/usr/lib/kernel/install.d/*.install</filename> and <filename>/usr/lib/kernel/install.d/*.install</filename> and
<filename>/etc/kernel/install.d/*.install</filename> with the following arguments: <filename>/etc/kernel/install.d/*.install</filename> with the following arguments:
<programlisting>remove <replaceable>KERNEL-VERSION</replaceable> <filename>$BOOT/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename></programlisting>
</para> </para>
<programlisting>remove <replaceable>KERNEL-VERSION</replaceable> <filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename></programlisting> <para>Afterwards, <command>kernel-install</command> removes the directory
<filename>$BOOT/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename>
<para>Afterwards, <command>kernel-install</command> removes the entry directory and its contents.</para>
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename>
and its contents, if it exists.</para>
<para>Two default plugins execute the following operations in this case:</para> <para>Two default plugins execute the following operations in this case:</para>
@ -126,18 +118,14 @@
<listitem><para><filename>50-depmod.install</filename> removes the files generated by <command>depmod</command> for this kernel again.</para></listitem> <listitem><para><filename>50-depmod.install</filename> removes the files generated by <command>depmod</command> for this kernel again.</para></listitem>
<listitem><para><filename>90-loaderentry.install</filename> removes the file <listitem><para><filename>90-loaderentry.install</filename> removes the file
<filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>.</para></listitem> <filename>$BOOT/loader/entries/<replaceable>MACHINE-ID</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>.</para></listitem>
<listitem><para><command>kernel-install</command> removes
<filename>$BOOT/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable></filename>,
if enabled (see <varname>$KERNEL_INSTALL_LAYOUT=</varname>).</para></listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><command>inspect</command></term>
<listitem>
<para>Shows the various paths and parameters configured or auto-detected. In particular shows the
values of the various <varname>$KERNEL_INSTALL_*</varname> environment variables listed
below.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
@ -147,9 +135,9 @@
<para>The partition where the kernels and <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot <para>The partition where the kernels and <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot
Loader Specification</ulink> snippets are located is called <varname>$BOOT</varname>. Loader Specification</ulink> snippets are located is called <varname>$BOOT</varname>.
<command>kernel-install</command> determines the location of this partition by checking <command>kernel-install</command> determines the location of this partition by checking
<filename>/efi/</filename>, <filename>/boot/</filename>, and <filename>/boot/efi/</filename> in turn. The <filename>/efi/</filename>, <filename>/boot/</filename>, and <filename>/boot/efi/</filename>
first location where <filename>$BOOT/loader/entries/</filename> or in turn. The first location where <filename>$BOOT/loader/entries/</filename> or
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/</filename> exists is used.</para> <filename>$BOOT/$MACHINE_ID/</filename> exists is used.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -175,57 +163,36 @@
<para>If <option>--verbose</option> is used, <varname>$KERNEL_INSTALL_VERBOSE=1</varname> will be set for <para>If <option>--verbose</option> is used, <varname>$KERNEL_INSTALL_VERBOSE=1</varname> will be set for
the plugins. They may output additional logs in this case.</para> the plugins. They may output additional logs in this case.</para>
<para>If <varname>$MACHINE_ID</varname> is set and not empty when <command>kernel-install</command> is <para>If <varname>MACHINE_ID=</varname> is set and not empty, it will be used as <replaceable>MACHINE-ID</replaceable>,
invoked, it will be used as <replaceable>MACHINE-ID</replaceable>, overriding any automatic detection overriding any automatic detection attempts. The value must be a valid machine ID (32 hexadecimal characters).</para>
attempts. The value must be a valid machine ID (32 hexadecimal characters).</para>
<para><varname>$KERNEL_INSTALL_MACHINE_ID</varname> is set for the plugins to the desired <para><varname>KERNEL_INSTALL_MACHINE_ID=</varname> is set for the plugins to the desired <replaceable>MACHINE-ID</replaceable>
<replaceable>MACHINE-ID</replaceable> to use. It's always a 128bit ID, and typically the ID from either 32 hexadecimal characters or the special value <literal>Default</literal>.</para>
<filename>/etc/machine-id</filename> or the one passed in via <varname>$MACHINE_ID</varname>. (If no <para><varname>KERNEL_INSTALL_BOOT_ROOT=</varname> is set for the plugins to the root directory (mount point, usually) of the hierarchy
machine ID was specified via these methods it might be generated randomly by where boot-loader entries, kernel images, and associated resources should be placed. Can be overridden by setting <varname>BOOT_ROOT=</varname>.</para>
<command>kernel-install</command>, in which case it only applies to this invocation.)</para>
<para><varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname> is set for the plugins to the desired entry "token" <para><varname>KERNEL_INSTALL_LAYOUT=bls|other|...</varname> is set for the plugins to specify the installation layout.
to use. It's an identifier that shall be used to identify the local installation, and is often the Defaults to <option>bls</option> if <filename>$BOOT/<replaceable>MACHINE-ID</replaceable></filename> exists, or <option>other</option> otherwise.
machine ID, i.e. same as <varname>$KERNEL_INSTALL_MACHINE_ID</varname>, but might also be a different Additional layout names may be defined by convention. If a plugin uses a special layout,
type of identifier, for example a fixed string or the <varname>ID=</varname>, it's encouraged to declare its own layout name and configure <varname>layout=</varname> in <filename>install.conf</filename> upon initial installation.</para>
<varname>IMAGE_ID=</varname> values from <filename>/etc/os-release</filename>. The string passed here
will be used to name Boot Loader Specification entries, or the directories the kernel image and initial
RAM disk images are placed into. Note that while oftentimes
<varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname> and <varname>$KERNEL_INSTALL_MACHINE_ID</varname> are set
to the same value, the latter is guaranteed to be a valid 32 character ID in lowercase hexadecimals while
the former can be any short string. The entry token to use is read from
<filename>/etc/kernel/entry-token</filename>, if it exists. Otherwise a few possible candidates below the
<varname>$BOOT</varname> are searched for Boot Loader Specification Type 1 entry directories, and if
found the entry token is derived from that. If that is not successful the machine ID is used as
fallback.</para>
<para><varname>$KERNEL_INSTALL_BOOT_ROOT</varname> is set for the plugins to the absolute path of the <para><varname>KERNEL_INSTALL_INITRD_GENERATOR=...</varname> is set for plugins to select the initrd generator.
root directory (mount point, usually) of the hierarchy where boot loader entries, kernel images, and This should be configured as <varname>initrd_generator=</varname> in <filename>install.conf</filename>.
associated resources should be placed. This usually is the path where the XBOOTLDR partition or the ESP </para>
(EFI System Partition) are mounted, and also conceptually referred to as <varname>$BOOT</varname>. Can be
overridden by setting <varname>$BOOT_ROOT</varname>.</para>
<para><varname>$KERNEL_INSTALL_LAYOUT=bls|other|...</varname> is set for the plugins to specify the <para><varname>KERNEL_INSTALL_STAGING_AREA=...</varname> is set for plugins to a path to a directory.
installation layout. Defaults to <option>bls</option> if Plugins may drop files in that directory, and they will be installed as part of the loader entry, based
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable></filename> exists, or <option>other</option> on the file name and extension.</para>
otherwise. Additional layout names may be defined by convention. If a plugin uses a special layout, it's
encouraged to declare its own layout name and configure <varname>layout=</varname> in
<filename>install.conf</filename> upon initial installation. The following values are currently
understood:</para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term>bls</term> <term>bls</term>
<listitem> <listitem>
<para>Standard <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader <para>Standard <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink> layout,
Specification</ulink> Type #1 layout, compatible with compatible with <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>: entries in
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>: <filename>$BOOT/loader/entries/<replaceable>MACHINE-ID</replaceable>-<replaceable>KERNEL-VERSION</replaceable>[+<replaceable>TRIES</replaceable>].conf</filename>,
entries in kernel and initrds under <filename>$BOOT/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename></para>
<filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>[+<replaceable>TRIES</replaceable>].conf</filename>, <para>Provided by <filename>90-loaderentry.install</filename>.</para>
kernel and initrds under
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename></para>
<para>Implemented by <filename>90-loaderentry.install</filename>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -235,15 +202,6 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<para><varname>$KERNEL_INSTALL_INITRD_GENERATOR</varname> is set for plugins to select the initrd
generator. This should be configured as <varname>initrd_generator=</varname> in
<filename>install.conf</filename>.
</para>
<para><varname>$KERNEL_INSTALL_STAGING_AREA</varname> is set for plugins to a path to a directory.
Plugins may drop files in that directory, and they will be installed as part of the loader entry, based
on the file name and extension.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -289,23 +247,27 @@
implement boot attempt counting with a counter embedded in the entry file name.</para> implement boot attempt counting with a counter embedded in the entry file name.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<filename>/etc/kernel/entry-token</filename>
</term>
<listitem>
<para>If this file exists it is read and used as "entry token" for this system, i.e. is used for
naming Boot Loader Specification entries, see
<varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname> above for details.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<filename>/etc/machine-id</filename> <filename>/etc/machine-id</filename>
</term> </term>
<listitem> <listitem>
<para>The content of this file specifies the machine identification <para>The content of this file specifies the machine identification
<replaceable>MACHINE-ID</replaceable>.</para> <replaceable>MACHINE-ID</replaceable>. If <filename>/etc/machine-id</filename>
cannot be read or is temporary (backed by a file on <constant>tmpfs</constant>),
<command>kernel-install</command> will use <literal>Default</literal> instead.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<filename>/etc/machine-info</filename>
</term>
<listitem>
<para>If this file contains the <varname>KERNEL_INSTALL_MACHINE_ID</varname> variable,
<command>kernel-install</command> will use it as <replaceable>MACHINE-ID</replaceable> instead of
the contents of <filename>/etc/machine-id</filename>. If the variable is not found in
<filename>/etc/machine-info</filename>, <command>kernel-install</command> will try to save the
machine ID it uses to install to <varname>$BOOT</varname> to this file.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -313,9 +275,9 @@
<filename>/etc/os-release</filename> <filename>/etc/os-release</filename>
<filename>/usr/lib/os-release</filename> <filename>/usr/lib/os-release</filename>
</term> </term>
<listitem> <listitem>
<para>Read by <filename>90-loaderentry.install</filename>. <para>Read by <filename>90-loaderentry.install</filename>.
If available, <varname>PRETTY_NAME=</varname> is read from these files and used as the title of the boot menu entry. If available, <varname>PRETTY_NAME</varname> is read from these files and used as the title of the boot menu entry.
Otherwise, <literal>Linux <replaceable>KERNEL-VERSION</replaceable></literal> will be used.</para> Otherwise, <literal>Linux <replaceable>KERNEL-VERSION</replaceable></literal> will be used.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -129,6 +129,17 @@
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>KERNEL_INSTALL_MACHINE_ID=</varname></term>
<listitem><para>Specifies the installation-specific installation directory
<command>kernel-install</command> should use. The value must be a valid machine ID (32 hexadecimal
characters). This would generally be the original machine-id that was used when the boot loader
entries for this installation were first added. When not set, the current value of
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
will be used.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>VENDOR=</varname></term> <term><varname>VENDOR=</varname></term>

View File

@ -798,16 +798,6 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
goto from_tm; goto from_tm;
} }
/* Support OUTPUT_SHORT and OUTPUT_SHORT_PRECISE formats */
tm = copy;
k = strptime(t, "%b %d %H:%M:%S", &tm);
if (k) {
if (*k == '.')
goto parse_usec;
else if (*k == 0)
goto from_tm;
}
tm = copy; tm = copy;
k = strptime(t, "%y-%m-%d %H:%M", &tm); k = strptime(t, "%y-%m-%d %H:%M", &tm);
if (k && *k == 0) { if (k && *k == 0) {

View File

@ -28,7 +28,6 @@
#include "glyph-util.h" #include "glyph-util.h"
#include "main-func.h" #include "main-func.h"
#include "mkdir.h" #include "mkdir.h"
#include "os-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h" #include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
@ -57,22 +56,13 @@ static bool arg_print_dollar_boot_path = false;
static bool arg_touch_variables = true; static bool arg_touch_variables = true;
static PagerFlags arg_pager_flags = 0; static PagerFlags arg_pager_flags = 0;
static bool arg_graceful = false; static bool arg_graceful = false;
static int arg_make_entry_directory = false; /* tri-state: < 0 for automatic logic */ static int arg_make_machine_id_directory = 0;
static sd_id128_t arg_machine_id = SD_ID128_NULL; static sd_id128_t arg_machine_id = SD_ID128_NULL;
static char *arg_install_layout = NULL; static char *arg_install_layout = NULL;
static enum {
ARG_ENTRY_TOKEN_MACHINE_ID,
ARG_ENTRY_TOKEN_OS_IMAGE_ID,
ARG_ENTRY_TOKEN_OS_ID,
ARG_ENTRY_TOKEN_LITERAL,
ARG_ENTRY_TOKEN_AUTO,
} arg_entry_token_type = ARG_ENTRY_TOKEN_AUTO;
static char *arg_entry_token = NULL;
STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep); STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep); STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
STATIC_DESTRUCTOR_REGISTER(arg_install_layout, freep); STATIC_DESTRUCTOR_REGISTER(arg_install_layout, freep);
STATIC_DESTRUCTOR_REGISTER(arg_entry_token, freep);
static const char *arg_dollar_boot_path(void) { static const char *arg_dollar_boot_path(void) {
/* $BOOT shall be the XBOOTLDR partition if it exists, and otherwise the ESP */ /* $BOOT shall be the XBOOTLDR partition if it exists, and otherwise the ESP */
@ -180,133 +170,32 @@ static int load_install_machine_id_and_layout(void) {
return 0; return 0;
} }
static int settle_entry_token(void) { static int settle_install_machine_id(void) {
int r;
switch (arg_entry_token_type) {
case ARG_ENTRY_TOKEN_AUTO: {
_cleanup_free_ char *buf = NULL;
r = read_one_line_file("/etc/kernel/entry-token", &buf);
if (r < 0 && r != -ENOENT)
return log_error_errno(r, "Failed to read /etc/kernel/entry-token: %m");
if (!isempty(buf)) {
free_and_replace(arg_entry_token, buf);
arg_entry_token_type = ARG_ENTRY_TOKEN_LITERAL;
} else if (sd_id128_is_null(arg_machine_id)) {
_cleanup_free_ char *id = NULL, *image_id = NULL;
r = parse_os_release(NULL,
"IMAGE_ID", &image_id,
"ID", &id);
if (r < 0)
return log_error_errno(r, "Failed to load /etc/os-release: %m");
if (!isempty(image_id)) {
free_and_replace(arg_entry_token, image_id);
arg_entry_token_type = ARG_ENTRY_TOKEN_OS_IMAGE_ID;
} else if (!isempty(id)) {
free_and_replace(arg_entry_token, id);
arg_entry_token_type = ARG_ENTRY_TOKEN_OS_ID;
} else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No machine ID set, and /etc/os-release carries no ID=/IMAGE_ID= fields.");
} else {
r = free_and_strdup_warn(&arg_entry_token, SD_ID128_TO_STRING(arg_machine_id));
if (r < 0)
return r;
arg_entry_token_type = ARG_ENTRY_TOKEN_MACHINE_ID;
}
break;
}
case ARG_ENTRY_TOKEN_MACHINE_ID:
if (sd_id128_is_null(arg_machine_id))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No machine ID set.");
r = free_and_strdup_warn(&arg_entry_token, SD_ID128_TO_STRING(arg_machine_id));
if (r < 0)
return r;
break;
case ARG_ENTRY_TOKEN_OS_IMAGE_ID: {
_cleanup_free_ char *buf = NULL;
r = parse_os_release(NULL, "IMAGE_ID", &buf);
if (r < 0)
return log_error_errno(r, "Failed to load /etc/os-release: %m");
if (isempty(buf))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "IMAGE_ID= field not set in /etc/os-release.");
free_and_replace(arg_entry_token, buf);
break;
}
case ARG_ENTRY_TOKEN_OS_ID: {
_cleanup_free_ char *buf = NULL;
r = parse_os_release(NULL, "ID", &buf);
if (r < 0)
return log_error_errno(r, "Failed to load /etc/os-release: %m");
if (isempty(buf))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "ID= field not set in /etc/os-release.");
free_and_replace(arg_entry_token, buf);
break;
}
case ARG_ENTRY_TOKEN_LITERAL:
assert(!isempty(arg_entry_token)); /* already filled in by command line parser */
break;
}
if (isempty(arg_entry_token) || !string_is_safe(arg_entry_token))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Selected entry token not valid: %s", arg_entry_token);
log_debug("Using entry token: %s", arg_entry_token);
return 0;
}
static bool use_boot_loader_spec_type1(void) {
/* If the layout is not specified, or if it is set explicitly to "bls" we assume Boot Loader
* Specification Type #1 is the chosen format for our boot loader entries */
return !arg_install_layout || streq(arg_install_layout, "bls");
}
static int settle_make_entry_directory(void) {
int r; int r;
r = load_install_machine_id_and_layout(); r = load_install_machine_id_and_layout();
if (r < 0) if (r < 0)
return r; return r;
r = settle_entry_token(); bool layout_non_bls = arg_install_layout && !streq(arg_install_layout, "bls");
if (r < 0) if (arg_make_machine_id_directory < 0) {
return r; if (layout_non_bls || sd_id128_is_null(arg_machine_id))
arg_make_machine_id_directory = 0;
bool layout_type1 = use_boot_loader_spec_type1(); else {
if (arg_make_entry_directory < 0) { /* Automatic mode */ r = path_is_temporary_fs("/etc/machine-id");
if (layout_type1) { if (r < 0)
if (arg_entry_token == ARG_ENTRY_TOKEN_MACHINE_ID) { return log_debug_errno(r, "Couldn't determine whether /etc/machine-id is on a temporary file system: %m");
r = path_is_temporary_fs("/etc/machine-id"); arg_make_machine_id_directory = r == 0;
if (r < 0) }
return log_debug_errno(r, "Couldn't determine whether /etc/machine-id is on a temporary file system: %m");
arg_make_entry_directory = r == 0;
} else
arg_make_entry_directory = true;
} else
arg_make_entry_directory = false;
} }
if (arg_make_entry_directory > 0 && !layout_type1) if (arg_make_machine_id_directory > 0 && sd_id128_is_null(arg_machine_id))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"KERNEL_INSTALL_LAYOUT=%s is configured, but Boot Loader Specification Type #1 entry directory creation was requested.", "Machine ID not found, but bls directory creation was requested.");
if (arg_make_machine_id_directory > 0 && layout_non_bls)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"KERNEL_INSTALL_LAYOUT=%s is configured, but bls directory creation was requested.",
arg_install_layout); arg_install_layout);
return 0; return 0;
@ -1150,14 +1039,14 @@ static int remove_subdirs(const char *root, const char *const *subdirs) {
return r < 0 ? r : q; return r < 0 ? r : q;
} }
static int remove_entry_directory(const char *root) { static int remove_machine_id_directory(const char *root) {
assert(root); assert(root);
assert(arg_make_entry_directory >= 0); assert(arg_make_machine_id_directory >= 0);
if (!arg_make_entry_directory || !arg_entry_token) if (!arg_make_machine_id_directory || sd_id128_is_null(arg_machine_id))
return 0; return 0;
return rmdir_one(root, arg_entry_token); return rmdir_one(root, SD_ID128_TO_STRING(arg_machine_id));
} }
static int remove_binaries(const char *esp_path) { static int remove_binaries(const char *esp_path) {
@ -1249,7 +1138,7 @@ static int install_loader_config(const char *esp_path) {
const char *p; const char *p;
int r; int r;
assert(arg_make_entry_directory >= 0); assert(arg_make_machine_id_directory >= 0);
p = prefix_roota(esp_path, "/loader/loader.conf"); p = prefix_roota(esp_path, "/loader/loader.conf");
if (access(p, F_OK) >= 0) /* Silently skip creation if the file already exists (early check) */ if (access(p, F_OK) >= 0) /* Silently skip creation if the file already exists (early check) */
@ -1266,9 +1155,9 @@ static int install_loader_config(const char *esp_path) {
fprintf(f, "#timeout 3\n" fprintf(f, "#timeout 3\n"
"#console-mode keep\n"); "#console-mode keep\n");
if (arg_make_entry_directory) { if (arg_make_machine_id_directory) {
assert(arg_entry_token); assert(!sd_id128_is_null(arg_machine_id));
fprintf(f, "default %s-*\n", arg_entry_token); fprintf(f, "default %s-*\n", SD_ID128_TO_STRING(arg_machine_id));
} }
r = fflush_sync_and_check(f); r = fflush_sync_and_check(f);
@ -1285,33 +1174,100 @@ static int install_loader_config(const char *esp_path) {
return 1; return 1;
} }
static int install_entry_directory(const char *root) { static int install_machine_id_directory(const char *root) {
assert(root); assert(root);
assert(arg_make_entry_directory >= 0); assert(arg_make_machine_id_directory >= 0);
if (!arg_make_entry_directory) if (!arg_make_machine_id_directory)
return 0; return 0;
assert(arg_entry_token); assert(!sd_id128_is_null(arg_machine_id));
return mkdir_one(root, arg_entry_token); return mkdir_one(root, SD_ID128_TO_STRING(arg_machine_id));
} }
static int install_entry_token(void) { static int install_machine_info_config(void) {
_cleanup_free_ char *contents = NULL;
size_t length;
bool need_install_layout = true, need_machine_id;
int r; int r;
assert(arg_make_entry_directory >= 0); assert(arg_make_machine_id_directory >= 0);
assert(arg_entry_token);
/* Let's save the used entry token in /etc/kernel/entry-token if we used it to create the entry /* We only want to save the machine-id if we created any directories using it. */
* directory, or if anything else but the machine ID */ need_machine_id = arg_make_machine_id_directory;
if (!arg_make_entry_directory && arg_entry_token_type == ARG_ENTRY_TOKEN_MACHINE_ID) _cleanup_fclose_ FILE *orig = fopen("/etc/machine-info", "re");
return 0; if (!orig && errno != ENOENT)
return log_error_errno(errno, "Failed to open /etc/machine-info: %m");
r = write_string_file("/etc/kernel/entry-token", arg_entry_token, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755); if (orig) {
_cleanup_free_ char *install_layout = NULL, *machine_id = NULL;
r = parse_env_file(orig, "/etc/machine-info",
"KERNEL_INSTALL_LAYOUT", &install_layout,
"KERNEL_INSTALL_MACHINE_ID", &machine_id);
if (r < 0)
return log_error_errno(r, "Failed to parse /etc/machine-info: %m");
rewind(orig);
if (!isempty(install_layout))
need_install_layout = false;
if (!isempty(machine_id))
need_machine_id = false;
if (!need_install_layout && !need_machine_id) {
log_debug("/etc/machine-info already has KERNEL_INSTALL_MACHINE_ID=%s and KERNEL_INSTALL_LAYOUT=%s.",
machine_id, install_layout);
return 0;
}
r = read_full_stream(orig, &contents, &length);
if (r < 0)
return log_error_errno(r, "Failed to read /etc/machine-info: %m");
}
_cleanup_(unlink_and_freep) char *dst_tmp = NULL;
_cleanup_fclose_ FILE *dst = NULL;
r = fopen_temporary_label("/etc/machine-info", /* The path for which to the look up the label */
"/etc/machine-info", /* Where we want the file actually to end up */
&dst, /* The temporary file we write to */
&dst_tmp);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to write entry token '%s' to /etc/kernel/entry-token", arg_entry_token); return log_debug_errno(r, "Failed to open temporary copy of /etc/machine-info: %m");
if (contents)
fwrite_unlocked(contents, 1, length, dst);
bool no_newline = !contents || contents[length - 1] == '\n';
if (need_install_layout) {
const char *line = "\nKERNEL_INSTALL_LAYOUT=bls\n" + no_newline;
fwrite_unlocked(line, 1, strlen(line), dst);
no_newline = false;
}
const char *mid_string = SD_ID128_TO_STRING(arg_machine_id);
if (need_machine_id)
fprintf(dst, "%sKERNEL_INSTALL_MACHINE_ID=%s\n",
no_newline ? "" : "\n",
mid_string);
r = fflush_and_check(dst);
if (r < 0)
return log_error_errno(r, "Failed to write temporary copy of /etc/machine-info: %m");
if (fchmod(fileno(dst), 0644) < 0)
return log_debug_errno(errno, "Failed to fchmod %s: %m", dst_tmp);
if (rename(dst_tmp, "/etc/machine-info") < 0)
return log_error_errno(errno, "Failed to replace /etc/machine-info: %m");
log_info("%s /etc/machine-info with%s%s%s",
orig ? "Updated" : "Created",
need_install_layout ? " KERNEL_INSTALL_LAYOUT=bls" : "",
need_machine_id ? " KERNEL_INSTALL_MACHINE_ID=" : "",
need_machine_id ? mid_string : "");
return 0; return 0;
} }
@ -1355,10 +1311,8 @@ static int help(int argc, char *argv[], void *userdata) {
" --no-pager Do not pipe output into a pager\n" " --no-pager Do not pipe output into a pager\n"
" --graceful Don't fail when the ESP cannot be found or EFI\n" " --graceful Don't fail when the ESP cannot be found or EFI\n"
" variables cannot be written\n" " variables cannot be written\n"
" --make-entry-directory=yes|no|auto\n" " --make-machine-id-directory=yes|no|auto\n"
" Create $BOOT/ENTRY-TOKEN/ directory\n" " Create $BOOT/$MACHINE_ID\n"
" --entry-token=machine-id|os-id|os-image-id|auto|literal:…\n"
" Entry token to use for this installation\n"
"\nSee the %2$s for details.\n", "\nSee the %2$s for details.\n",
program_invocation_short_name, program_invocation_short_name,
link, link,
@ -1378,8 +1332,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_NO_VARIABLES, ARG_NO_VARIABLES,
ARG_NO_PAGER, ARG_NO_PAGER,
ARG_GRACEFUL, ARG_GRACEFUL,
ARG_MAKE_ENTRY_DIRECTORY, ARG_MAKE_MACHINE_ID_DIRECTORY,
ARG_ENTRY_TOKEN,
}; };
static const struct option options[] = { static const struct option options[] = {
@ -1394,9 +1347,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "no-variables", no_argument, NULL, ARG_NO_VARIABLES }, { "no-variables", no_argument, NULL, ARG_NO_VARIABLES },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "graceful", no_argument, NULL, ARG_GRACEFUL }, { "graceful", no_argument, NULL, ARG_GRACEFUL },
{ "make-entry-directory", required_argument, NULL, ARG_MAKE_ENTRY_DIRECTORY }, { "make-machine-id-directory", required_argument, NULL, ARG_MAKE_MACHINE_ID_DIRECTORY },
{ "make-machine-id-directory", required_argument, NULL, ARG_MAKE_ENTRY_DIRECTORY }, /* Compatibility alias */
{ "entry-token", required_argument, NULL, ARG_ENTRY_TOKEN },
{} {}
}; };
@ -1454,40 +1405,14 @@ static int parse_argv(int argc, char *argv[]) {
arg_graceful = true; arg_graceful = true;
break; break;
case ARG_ENTRY_TOKEN: { case ARG_MAKE_MACHINE_ID_DIRECTORY:
const char *e;
if (streq(optarg, "machine-id")) {
arg_entry_token_type = ARG_ENTRY_TOKEN_MACHINE_ID;
arg_entry_token = mfree(arg_entry_token);
} else if (streq(optarg, "os-image-id")) {
arg_entry_token_type = ARG_ENTRY_TOKEN_OS_IMAGE_ID;
arg_entry_token = mfree(arg_entry_token);
} else if (streq(optarg, "os-id")) {
arg_entry_token_type = ARG_ENTRY_TOKEN_OS_ID;
arg_entry_token = mfree(arg_entry_token);
} else if ((e = startswith(optarg, "literal:"))) {
arg_entry_token_type = ARG_ENTRY_TOKEN_LITERAL;
r = free_and_strdup_warn(&arg_entry_token, e);
if (r < 0)
return r;
} else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Unexpected parameter for --entry-token=: %s", optarg);
break;
}
case ARG_MAKE_ENTRY_DIRECTORY:
if (streq(optarg, "auto")) /* retained for backwards compatibility */ if (streq(optarg, "auto")) /* retained for backwards compatibility */
arg_make_entry_directory = -1; /* yes if machine-id is permanent */ arg_make_machine_id_directory = -1; /* yes if machine-id is permanent */
else { else {
r = parse_boolean_argument("--make-entry-directory=", optarg, &b); r = parse_boolean_argument("--make-machine-id-directory=", optarg, &b);
if (r < 0) if (r < 0)
return r; return r;
arg_make_machine_id_directory = b;
arg_make_entry_directory = b;
} }
break; break;
@ -1956,7 +1881,7 @@ static int verb_install(int argc, char *argv[], void *userdata) {
if (r < 0) if (r < 0)
return r; return r;
r = settle_make_entry_directory(); r = settle_install_machine_id();
if (r < 0) if (r < 0)
return r; return r;
@ -1983,11 +1908,11 @@ static int verb_install(int argc, char *argv[], void *userdata) {
if (r < 0) if (r < 0)
return r; return r;
r = install_entry_directory(arg_dollar_boot_path()); r = install_machine_id_directory(arg_dollar_boot_path());
if (r < 0) if (r < 0)
return r; return r;
r = install_entry_token(); r = install_machine_info_config();
if (r < 0) if (r < 0)
return r; return r;
@ -2020,7 +1945,7 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
if (r < 0) if (r < 0)
return r; return r;
r = settle_make_entry_directory(); r = settle_install_machine_id();
if (r < 0) if (r < 0)
return r; return r;
@ -2042,7 +1967,7 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
if (q < 0 && r >= 0) if (q < 0 && r >= 0)
r = q; r = q;
q = remove_entry_directory(arg_esp_path); q = remove_machine_id_directory(arg_esp_path);
if (q < 0 && r >= 0) if (q < 0 && r >= 0)
r = 1; r = 1;
@ -2052,7 +1977,7 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
if (q < 0 && r >= 0) if (q < 0 && r >= 0)
r = q; r = q;
q = remove_entry_directory(arg_xbootldr_path); q = remove_machine_id_directory(arg_xbootldr_path);
if (q < 0 && r >= 0) if (q < 0 && r >= 0)
r = q; r = q;
} }

View File

@ -29,7 +29,6 @@ INITRD_OPTIONS_SHIFT=4
[ "$KERNEL_INSTALL_LAYOUT" = "bls" ] || exit 0 [ "$KERNEL_INSTALL_LAYOUT" = "bls" ] || exit 0
MACHINE_ID="$KERNEL_INSTALL_MACHINE_ID" MACHINE_ID="$KERNEL_INSTALL_MACHINE_ID"
ENTRY_TOKEN="$KERNEL_INSTALL_ENTRY_TOKEN"
BOOT_ROOT="$KERNEL_INSTALL_BOOT_ROOT" BOOT_ROOT="$KERNEL_INSTALL_BOOT_ROOT"
BOOT_MNT="$(stat -c %m "$BOOT_ROOT")" BOOT_MNT="$(stat -c %m "$BOOT_ROOT")"
@ -42,10 +41,10 @@ fi
case "$COMMAND" in case "$COMMAND" in
remove) remove)
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "Removing $BOOT_ROOT/loader/entries/$ENTRY_TOKEN-$KERNEL_VERSION*.conf" echo "Removing $BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION*.conf"
exec rm -f \ exec rm -f \
"$BOOT_ROOT/loader/entries/$ENTRY_TOKEN-$KERNEL_VERSION.conf" \ "$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION.conf" \
"$BOOT_ROOT/loader/entries/$ENTRY_TOKEN-$KERNEL_VERSION+"*".conf" "$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION+"*".conf"
;; ;;
add) add)
;; ;;
@ -69,26 +68,17 @@ elif [ -r /usr/lib/kernel/cmdline ]; then
else else
BOOT_OPTIONS="$(tr -s "$IFS" '\n' </proc/cmdline | grep -ve '^BOOT_IMAGE=' -e '^initrd=' | tr '\n' ' ')" BOOT_OPTIONS="$(tr -s "$IFS" '\n' </proc/cmdline | grep -ve '^BOOT_IMAGE=' -e '^initrd=' | tr '\n' ' ')"
fi fi
BOOT_OPTIONS="${BOOT_OPTIONS% }" BOOT_OPTIONS="${BOOT_OPTIONS% }"
# If the boot entries are named after the machine ID, then suffix the kernel
# command line with the machine ID we use, so that the machine ID remains
# stable, even during factory reset, in the initrd (where the system's machine
# ID is not directly accessible yet), and if the root file system is volatile.
if [ "$ENTRY_TOKEN" = "$MACHINE_ID" ]; then
BOOT_OPTIONS="$BOOT_OPTIONS systemd.machine_id=$MACHINE_ID"
fi
if [ -r /etc/kernel/tries ]; then if [ -r /etc/kernel/tries ]; then
read -r TRIES </etc/kernel/tries read -r TRIES </etc/kernel/tries
if ! echo "$TRIES" | grep -q '^[0-9][0-9]*$'; then if ! echo "$TRIES" | grep -q '^[0-9][0-9]*$'; then
echo "/etc/kernel/tries does not contain an integer." >&2 echo "/etc/kernel/tries does not contain an integer." >&2
exit 1 exit 1
fi fi
LOADER_ENTRY="$BOOT_ROOT/loader/entries/$ENTRY_TOKEN-$KERNEL_VERSION+$TRIES.conf" LOADER_ENTRY="$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION+$TRIES.conf"
else else
LOADER_ENTRY="$BOOT_ROOT/loader/entries/$ENTRY_TOKEN-$KERNEL_VERSION.conf" LOADER_ENTRY="$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION.conf"
fi fi
if ! [ -d "$ENTRY_DIR_ABS" ]; then if ! [ -d "$ENTRY_DIR_ABS" ]; then
@ -126,10 +116,7 @@ mkdir -p "${LOADER_ENTRY%/*}" || {
{ {
echo "title $PRETTY_NAME" echo "title $PRETTY_NAME"
echo "version $KERNEL_VERSION" echo "version $KERNEL_VERSION"
if [ "$ENTRY_TOKEN" = "$MACHINE_ID" ]; then echo "machine-id $MACHINE_ID"
# See similar logic above for the systemd.machine_id= kernel command line option
echo "machine-id $MACHINE_ID"
fi
echo "options $BOOT_OPTIONS" echo "options $BOOT_OPTIONS"
echo "linux $ENTRY_DIR/linux" echo "linux $ENTRY_DIR/linux"

View File

@ -25,7 +25,6 @@ usage()
echo "Usage:" echo "Usage:"
echo " $0 [OPTIONS...] add KERNEL-VERSION KERNEL-IMAGE [INITRD-FILE ...]" echo " $0 [OPTIONS...] add KERNEL-VERSION KERNEL-IMAGE [INITRD-FILE ...]"
echo " $0 [OPTIONS...] remove KERNEL-VERSION" echo " $0 [OPTIONS...] remove KERNEL-VERSION"
echo " $0 [OPTIONS...] inspect"
echo "Options:" echo "Options:"
echo " -h, --help Print this help" echo " -h, --help Print this help"
echo " -v, --verbose Increase verbosity" echo " -v, --verbose Increase verbosity"
@ -73,18 +72,14 @@ else
[ $# -ge 1 ] && shift [ $# -ge 1 ] && shift
fi fi
if [ "$COMMAND" = "inspect" ]; then if [ $# -lt 1 ]; then
KERNEL_VERSION="" echo "Error: not enough arguments" >&2
else exit 1
if [ $# -lt 1 ]; then
echo "Error: not enough arguments" >&2
exit 1
fi
KERNEL_VERSION="$1"
shift
fi fi
KERNEL_VERSION="$1"
shift
layout= layout=
initrd_generator= initrd_generator=
@ -94,75 +89,44 @@ elif [ -r "/usr/lib/kernel/install.conf" ]; then
. /usr/lib/kernel/install.conf . /usr/lib/kernel/install.conf
fi fi
# If /etc/machine-id is initialized we'll use it, otherwise we'll use a freshly # Prefer to use an existing machine ID from /etc/machine-info or /etc/machine-id. If we're using the machine
# generated one. If the user configured an explicit machine ID to use in # ID /etc/machine-id, try to persist it in /etc/machine-info. If no machine ID is found, try to generate
# /etc/machine-info to use for our purpose, we'll use that instead (for # a new machine ID in /etc/machine-info. If that fails, use "Default".
# compatibility). [ -z "$MACHINE_ID" ] && [ -r /etc/machine-info ] && . /etc/machine-info && MACHINE_ID="$KERNEL_INSTALL_MACHINE_ID"
[ -z "$MACHINE_ID" ] && [ -r /etc/machine-info ] && . /etc/machine-info && MACHINE_ID="$KERNEL_INSTALL_MACHINE_ID" [ -z "$MACHINE_ID" ] && [ -r /etc/machine-id ] && read -r MACHINE_ID </etc/machine-id
[ -z "$MACHINE_ID" ] && [ -r /etc/machine-id ] && read -r MACHINE_ID </etc/machine-id [ -n "$MACHINE_ID" ] && [ -z "$KERNEL_INSTALL_MACHINE_ID" ] && echo "KERNEL_INSTALL_MACHINE_ID=$MACHINE_ID" >>/etc/machine-info
[ -z "$MACHINE_ID" ] && MACHINE_ID="$(systemd-id128 new)" [ -z "$MACHINE_ID" ] && NEW_MACHINE_ID="$(systemd-id128 new)" && echo "KERNEL_INSTALL_MACHINE_ID=$NEW_MACHINE_ID" >>/etc/machine-info
[ -z "$MACHINE_ID" ] && [ -r /etc/machine-info ] && . /etc/machine-info && MACHINE_ID="$KERNEL_INSTALL_MACHINE_ID"
[ -z "$MACHINE_ID" ] && MACHINE_ID="Default"
# Now that we determined the machine ID to use, let's determine the "token" for [ -z "$BOOT_ROOT" ] && for suff in "$MACHINE_ID" "loader/entries"; do
# the boot loader entry to generate. We use that for naming the directory below for pref in "/efi" "/boot" "/boot/efi" ; do
# $BOOT where we want to place the kernel/initrd and related resources, as well
# for naming the .conf boot loader spec entry. Typically this is just the
# machine ID, but it can be anything else, too, if we are told so.
[ -z "$ENTRY_TOKEN" ] && [ -r /etc/kernel/entry-token ] && read -r ENTRY_TOKEN </etc/kernel/entry-token
if [ -z "$ENTRY_TOKEN" ]; then
# If not configured explicitly, then use a few candidates: the machine ID,
# the IMAGE_ID= and ID= fields from /etc/os-release and finally the fixed
# string "Default"
ENTRY_TOKEN_SEARCH="$MACHINE_ID"
[ -r /etc/os-release ] && . /etc/os-release
[ -n "$IMAGE_ID" ] && ENTRY_TOKEN_SEARCH="$ENTRY_TOKEN_SEARCH $IMAGE_ID"
[ -n "$ID" ] && ENTRY_TOKEN_SEARCH="$ENTRY_TOKEN_SEARCH $ID"
ENTRY_TOKEN_SEARCH="$ENTRY_TOKEN_SEARCH Default"
else
ENTRY_TOKEN_SEARCH="$ENTRY_TOKEN"
fi
# NB: The $MACHINE_ID is guaranteed to be a valid machine ID, but
# $ENTRY_TOKEN can be any string that fits into a VFAT filename, though
# typically is just the machine ID.
[ -z "$BOOT_ROOT" ] && for suff in $ENTRY_TOKEN_SEARCH; do
for pref in "/efi" "/boot" "/boot/efi"; do
if [ -d "$pref/$suff" ]; then if [ -d "$pref/$suff" ]; then
BOOT_ROOT="$pref" BOOT_ROOT="$pref"
ENTRY_TOKEN="$suff"
break 2 break 2
fi fi
done done
done done
[ -z "$BOOT_ROOT" ] && for pref in "/efi" "/boot" "/boot/efi"; do
if [ -d "$pref/loader/entries" ]; then
BOOT_ROOT="$pref"
break
fi
done
[ -z "$BOOT_ROOT" ] && for pref in "/efi" "/boot/efi"; do [ -z "$BOOT_ROOT" ] && for pref in "/efi" "/boot/efi"; do
if mountpoint -q "$pref"; then if mountpoint -q "$pref"; then
BOOT_ROOT="$pref" BOOT_ROOT="$pref"
break break
fi fi
done done
[ -z "$BOOT_ROOT" ] && BOOT_ROOT="/boot" [ -z "$BOOT_ROOT" ] && BOOT_ROOT="/boot"
[ -z "$ENTRY_TOKEN" ] && ENTRY_TOKEN="$MACHINE_ID"
if [ -z "$layout" ]; then if [ -z "$layout" ]; then
# Administrative decision: if not present, some scripts generate into /boot. # Administrative decision: if not present, some scripts generate into /boot.
if [ -d "$BOOT_ROOT/$ENTRY_TOKEN" ]; then if [ -d "$BOOT_ROOT/$MACHINE_ID" ]; then
layout="bls" layout="bls"
else else
layout="other" layout="other"
fi fi
fi fi
ENTRY_DIR_ABS="$BOOT_ROOT/$ENTRY_TOKEN/$KERNEL_VERSION" ENTRY_DIR_ABS="$BOOT_ROOT/$MACHINE_ID/$KERNEL_VERSION"
# Provide a directory where to store generated initrds # Provide a directory where to store generated initrds
cleanup() { cleanup() {
@ -174,7 +138,6 @@ trap cleanup EXIT
KERNEL_INSTALL_STAGING_AREA="$(mktemp -d -t -p /tmp kernel-install.staging.XXXXXXX)" KERNEL_INSTALL_STAGING_AREA="$(mktemp -d -t -p /tmp kernel-install.staging.XXXXXXX)"
export KERNEL_INSTALL_MACHINE_ID="$MACHINE_ID" export KERNEL_INSTALL_MACHINE_ID="$MACHINE_ID"
export KERNEL_INSTALL_ENTRY_TOKEN="$ENTRY_TOKEN"
export KERNEL_INSTALL_BOOT_ROOT="$BOOT_ROOT" export KERNEL_INSTALL_BOOT_ROOT="$BOOT_ROOT"
export KERNEL_INSTALL_LAYOUT="$layout" export KERNEL_INSTALL_LAYOUT="$layout"
export KERNEL_INSTALL_INITRD_GENERATOR="$initrd_generator" export KERNEL_INSTALL_INITRD_GENERATOR="$initrd_generator"
@ -207,7 +170,7 @@ case "$COMMAND" in
fi fi
if [ "$MAKE_ENTRY_DIR_ABS" -eq 0 ]; then if [ "$MAKE_ENTRY_DIR_ABS" -eq 0 ]; then
# Compatibility with earlier versions that used the presence of $BOOT_ROOT/$ENTRY_TOKEN # Compatibility with earlier versions that used the presence of $BOOT_ROOT/$MACHINE_ID
# to signal to 00-entry-directory to create $ENTRY_DIR_ABS # to signal to 00-entry-directory to create $ENTRY_DIR_ABS
# to serve as the indication to use or to not use the BLS # to serve as the indication to use or to not use the BLS
if [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ]; then if [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ]; then
@ -242,18 +205,6 @@ case "$COMMAND" in
fi fi
;; ;;
inspect)
echo "KERNEL_INSTALL_MACHINE_ID: $KERNEL_INSTALL_MACHINE_ID"
echo "KERNEL_INSTALL_ENTRY_TOKEN: $KERNEL_INSTALL_ENTRY_TOKEN"
echo "KERNEL_INSTALL_BOOT_ROOT: $KERNEL_INSTALL_BOOT_ROOT"
echo "KERNEL_INSTALL_LAYOUT: $KERNEL_INSTALL_LAYOUT"
echo "KERNEL_INSTALL_INITRD_GENERATOR: $KERNEL_INSTALL_INITRD_GENERATOR"
echo "ENTRY_DIR_ABS: $KERNEL_INSTALL_BOOT_ROOT/$ENTRY_TOKEN/\$KERNEL_VERSION"
# Assert that ENTRY_DIR_ABS actually matches what we are printing here
[ "${ENTRY_DIR_ABS%/*}" = "$KERNEL_INSTALL_BOOT_ROOT/$ENTRY_TOKEN" ] || { echo "Assertion didn't pass." >&2; exit 1; }
;;
*) *)
echo "Error: unknown command '$COMMAND'" >&2 echo "Error: unknown command '$COMMAND'" >&2
exit 1 exit 1

View File

@ -73,8 +73,6 @@ int main(int argc, char *argv[]) {
test_one("12-10-03 12:13"); test_one("12-10-03 12:13");
test_one("2012-12-30 18:42"); test_one("2012-12-30 18:42");
test_one("2012-10-02"); test_one("2012-10-02");
test_one("Mar 12 12:01:01");
test_one("Mar 12 12:01:01.687197");
test_one("Tue 2012-10-02"); test_one("Tue 2012-10-02");
test_one("yesterday"); test_one("yesterday");
test_one("today"); test_one("today");