From 4c7a0fc8d061b41fdd63eb19b6fc0a5c94668dde Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 12 Apr 2023 21:37:45 +0100 Subject: [PATCH] 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. --- src/core/job.c | 6 +++++ test/units/testsuite-57-retry-fail.service | 9 +++++++ test/units/testsuite-57-retry-upheld.service | 10 ++++++++ test/units/testsuite-57-retry-uphold.service | 7 +++++ test/units/testsuite-57.sh | 27 ++++++++++++++++++++ 5 files changed, 59 insertions(+) create mode 100644 test/units/testsuite-57-retry-fail.service create mode 100644 test/units/testsuite-57-retry-upheld.service create mode 100644 test/units/testsuite-57-retry-uphold.service 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 -- 2.47.3