]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sysupdate: refuse reboot/pending logic when a component is selected
authorArmaan Sandhu <armaan.sandhu0504@gmail.com>
Sat, 13 Jun 2026 07:25:51 +0000 (12:55 +0530)
committerLuca Boccassi <luca.boccassi@gmail.com>
Fri, 19 Jun 2026 18:52:24 +0000 (19:52 +0100)
The `pending` and `reboot` verbs, as well as the `--reboot` switch, compare
the newest installed version against the booted OS version (IMAGE_VERSION= from
os-release). When a component is selected via --component=, this compares the
component's version against the unrelated host OS version, which by design live
in separate version spaces. The result is arbitrary reboot decisions: depending
on the relative version strings sysupdate would either always or never reboot.

Refuse the combination with a clear error instead of silently performing a
bogus comparison. Correctly tracking a per-component booted version is left as a
future feature.

Fixes: https://github.com/systemd/systemd/issues/42330
man/systemd-sysupdate.xml
src/sysupdate/sysupdate.c
test/units/TEST-72-SYSUPDATE.sh

index 1dea457e133e52765306b36e75511613f86b60cb..3abccb05e4e5981ec9bb77cc7785e6aa1585ce39 100644 (file)
         updated together in a synchronous fashion. Simply define multiple transfer files within the same
         <filename>sysupdate.d/</filename> directory for these cases.</para>
 
-        <para>This option may not be combined with <option>--definitions=</option>.</para>
+        <para>This option may not be combined with <option>--definitions=</option>, nor with the
+        <command>pending</command> and <command>reboot</command> commands or the <option>--reboot</option>
+        switch, which only apply to the booted OS version.</para>
 
         <xi:include href="version-info.xml" xpointer="v251"/></listitem>
       </varlistentry>
         <term><option>--reboot</option></term>
 
         <listitem><para>When used in combination with the <command>update</command> commands and a new version is
-        installed, automatically reboots the system immediately afterwards.</para>
+        installed, automatically reboots the system immediately afterwards. This switch may not be combined with
+        <option>--component=</option>, as it only applies to the booted OS version.</para>
 
         <xi:include href="version-info.xml" xpointer="v251"/></listitem>
       </varlistentry>
index 92c40ddf71ab9810c4c767b3f537e87fd1eebb8a..8acf37fad1a9bf66d8be600fb50d1223914a9e64 100644 (file)
@@ -1555,6 +1555,10 @@ static int verb_update_impl(int argc, char **argv, UpdateActionFlags action_flag
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                       "The --instances-max argument must be >= 2 while updating");
 
+        if (arg_reboot && arg_component)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "The --reboot switch may not be combined with --component=, as automatic reboots only apply to the booted OS version.");
+
         if (arg_reboot) {
                 /* If automatic reboot on completion is requested, let's first determine the currently booted image */
 
@@ -1664,6 +1668,10 @@ static int verb_pending_or_reboot(int argc, char *argv[], uintptr_t _data, void
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "The --root=/--image= switches may not be combined with the '%s' operation.", argv[0]);
 
+        if (arg_component)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "The --component= switch may not be combined with the '%s' operation, which only applies to the booted OS version.", argv[0]);
+
         r = context_make_offline(&context, /* node= */ NULL,
                                  READ_DEFINITIONS_REQUIRES_ENABLED_TRANSFERS | READ_DEFINITIONS_REQUIRES_ANY_TRANSFERS);
         if (r < 0)
index 749af71a0681d567a6653d2c9147c85026b0ccf2..79a49efa2f5d67cb27aa6b82e5938a92757e06bf 100755 (executable)
@@ -579,6 +579,15 @@ EOF
 mkdir /run/sysupdate.d
 "$SYSUPDATE" --json=short components | grep -F '{"default":false,"components":["some-component"]}' >/dev/null
 
+# Regression test for https://github.com/systemd/systemd/issues/42330 — the
+# 'pending'/'reboot' verbs and the '--reboot' switch compare the newest installed
+# version against the booted OS version (IMAGE_VERSION= from os-release), which is
+# unrelated to component versions. Selecting a component must therefore be refused
+# rather than silently performing a bogus comparison.
+(! "$SYSUPDATE" --component=some-component pending)
+(! "$SYSUPDATE" --component=some-component reboot)
+(! "$SYSUPDATE" --component=some-component update --reboot)
+
 # Clean up regression test
 rmdir /run/sysupdate.d
 rm -rf /run/sysupdate.some-component.d