manager: fix/change evaluation of ConditionFirstBoot
The code to evaluate the kernel command line option was busted because it was doing 'return b == !!r' at a point where 'r > 0'. Thus we'd return "true" in both cases: $ SYSTEMD_PROC_CMDLINE=systemd.condition-first-boot build/systemd-analyze condition 'ConditionFirstBoot=true' test.service: ConditionFirstBoot=true succeeded. Conditions succeeded. $ SYSTEMD_PROC_CMDLINE=systemd.condition-first-boot build/systemd-analyze condition 'ConditionFirstBoot=false' test.service: ConditionFirstBoot=false succeeded. Conditions succeeded. We only use 'ConditionFirstBoot=true' in units, so this wasn't noticed. But I think the logic is broken in general: the condition should evaluate as true only during initial boot. If we rerun the units at later points, we should not consider ConditionFirstBoot to be true. Also, the first boot logic is also used in pid1 itself. AFAICT, for two things: in first boot machine-id is initialized transiently (this allows first-boot operations to be restarted if boot fails), and preset-all is executed. But this logic was different and separate from the logic to evaluate ConditionFirstBoot. The distinction is abolished, and the operations in pid1 now use the same logic as ConditionFirstBoot, which means that the kernel command line option is checked, and condition_test_first_boot() just tests whether pid1 thinks we're in first boot. This makes things easier to grok for the user: there's just one condition for "first boot" and it applies to both pid1 and units.
This commit is contained in:
@@ -1455,15 +1455,18 @@
|
||||
<term><varname>ConditionFirstBoot=</varname></term>
|
||||
|
||||
<listitem><para>Takes a boolean argument. This condition may be used to conditionalize units on
|
||||
whether the system is booting up for the first time. This roughly means that <filename>/etc/</filename>
|
||||
is unpopulated (for details, see "First Boot Semantics" in
|
||||
whether the system is booting up for the first time. This roughly means that <filename>/etc/</filename>
|
||||
was unpopulated when the system started booting (for details, see "First Boot Semantics" in
|
||||
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
|
||||
This may be used to populate <filename>/etc/</filename> on the first boot after factory reset, or
|
||||
when a new system instance boots up for the first time.</para>
|
||||
First boot is considered finished (this condition will evaluate as false) after the manager
|
||||
has finished the startup phase.</para>
|
||||
|
||||
<para>This condition may be used to populate <filename>/etc/</filename> on the first boot after
|
||||
factory reset, or when a new system instance boots up for the first time.</para>
|
||||
|
||||
<para>For robustness, units with <varname>ConditionFirstBoot=yes</varname> should order themselves
|
||||
before <filename>first-boot-complete.target</filename> and pull in this passive target with
|
||||
<varname>Wants=</varname>. This ensures that in a case of an aborted first boot, these units will
|
||||
<varname>Wants=</varname>. This ensures that in a case of an aborted first boot, these units will
|
||||
be re-run during the next system startup.</para>
|
||||
|
||||
<para>If the <varname>systemd.condition-first-boot=</varname> option is specified on the kernel
|
||||
|
||||
Reference in New Issue
Block a user