]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Uphold/StopWhenUnneeded/BindsTo: requeue when job finishes 27244/head
authorLuca Boccassi <bluca@debian.org>
Wed, 12 Apr 2023 20:37:45 +0000 (21:37 +0100)
committerLuca Boccassi <bluca@debian.org>
Thu, 13 Apr 2023 12:28:25 +0000 (13:28 +0100)
When a unit is upheld and fails, and there are no state changes in
the upholder, it will not be retried, which is against what the
documentation suggests.

Requeue when the job finishes. Same for the other two queues.

src/core/job.c
test/units/testsuite-57-retry-fail.service [new file with mode: 0644]
test/units/testsuite-57-retry-upheld.service [new file with mode: 0644]
test/units/testsuite-57-retry-uphold.service [new file with mode: 0644]
test/units/testsuite-57.sh

index 334fbf770e49d4df0aa77e0c3a92e3336cfb33ff..826ef6809c144f1351280b47c1195556330c1216 100644 (file)
@@ -1051,6 +1051,12 @@ finish:
                         job_add_to_gc_queue(other->job);
                 }
 
+        /* Ensure that when an upheld/unneeded/bound unit activation job fails we requeue it, if it still
+         * necessary. If there are no state changes in the triggerer, it would not be retried otherwise. */
+        unit_submit_to_start_when_upheld_queue(u);
+        unit_submit_to_stop_when_bound_queue(u);
+        unit_submit_to_stop_when_unneeded_queue(u);
+
         manager_check_finished(u->manager);
 
         return 0;
diff --git a/test/units/testsuite-57-retry-fail.service b/test/units/testsuite-57-retry-fail.service
new file mode 100644 (file)
index 0000000..67f3407
--- /dev/null
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+Description=Failed Dependency Unit
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/bin/sh -c "if [ -f /tmp/testsuite-57-retry-fail ]; then exit 0; else exit 1; fi"
+Restart=no
diff --git a/test/units/testsuite-57-retry-upheld.service b/test/units/testsuite-57-retry-upheld.service
new file mode 100644 (file)
index 0000000..2f718a6
--- /dev/null
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+Description=Upheld Unit
+Requires=testsuite-57-retry-fail.service
+After=testsuite-57-retry-fail.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/bin/echo ok
diff --git a/test/units/testsuite-57-retry-uphold.service b/test/units/testsuite-57-retry-uphold.service
new file mode 100644 (file)
index 0000000..a01b131
--- /dev/null
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+Description=Upholding Unit
+Upholds=testsuite-57-retry-upheld.service
+
+[Service]
+ExecStart=/bin/sleep infinity
index 66d946bebc5d0c9e831fd4b8e43afb4bbbca82ad..24040c31892f9fc38afdd71c78766db5bc1ecadd 100755 (executable)
@@ -26,6 +26,33 @@ done
 
 systemctl stop testsuite-57-uphold.service
 
+# Idea is this:
+#    1. we start testsuite-57-retry-uphold.service
+#    2. which through Uphold= starts testsuite-57-retry-upheld.service
+#    3. which through Requires= starts testsuite-57-retry-fail.service
+#    4. which fails as /tmp/testsuite-57-retry-fail does not exist, so testsuite-57-retry-upheld.service
+#       is no longer restarted
+#    5. we create /tmp/testsuite-57-retry-fail
+#    6. now testsuite-57-retry-upheld.service will be restarted since upheld, and its dependency will
+#       be satisfied
+
+rm -f /tmp/testsuite-57-retry-fail
+systemctl start testsuite-57-retry-uphold.service
+
+while ! systemctl is-failed testsuite-57-retry-fail.service ; do
+    sleep .5
+done
+
+systemctl is-active testsuite-57-retry-upheld.service && { echo 'unexpected success'; exit 1; }
+
+touch /tmp/testsuite-57-retry-fail
+
+while ! systemctl is-active testsuite-57-retry-upheld.service ; do
+    sleep .5
+done
+
+systemctl stop testsuite-57-retry-uphold.service testsuite-57-retry-fail.service testsuite-57-retry-upheld.service
+
 # Idea is this:
 #    1. we start testsuite-57-prop-stop-one.service
 #    2. which through Wants=/After= pulls in testsuite-57-prop-stop-two.service as well