From: Luca Boccassi Date: Wed, 12 Apr 2023 20:37:45 +0000 (+0100) Subject: Uphold/StopWhenUnneeded/BindsTo: requeue when job finishes X-Git-Tag: v254-rc1~724^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F27244%2Fhead;p=thirdparty%2Fsystemd.git Uphold/StopWhenUnneeded/BindsTo: requeue when job finishes 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. --- diff --git a/src/core/job.c b/src/core/job.c index 334fbf770e4..826ef6809c1 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -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 index 00000000000..67f34079d5f --- /dev/null +++ b/test/units/testsuite-57-retry-fail.service @@ -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 index 00000000000..2f718a61fa6 --- /dev/null +++ b/test/units/testsuite-57-retry-upheld.service @@ -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 index 00000000000..a01b131ed5b --- /dev/null +++ b/test/units/testsuite-57-retry-uphold.service @@ -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 diff --git a/test/units/testsuite-57.sh b/test/units/testsuite-57.sh index 66d946bebc5..24040c31892 100755 --- a/test/units/testsuite-57.sh +++ b/test/units/testsuite-57.sh @@ -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