mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-07 17:17:44 +03:00
job: Don't discard propagated restart jobs when unit is activating
When a service unit Requires= a socket, and the socket is restarted while the service is in state=activating, the propagated restart is being discarded. This is contrary to the documentation for Requires=, which states "this unit will be stopped (or restarted) if one of the other units is explicitly stopped (or restarted)".
This commit is contained in:
parent
01532c2d16
commit
dc06321fe3
src/core
test
@ -400,8 +400,22 @@ bool job_type_is_redundant(JobType a, UnitActiveState b) {
|
||||
b == UNIT_RELOADING;
|
||||
|
||||
case JOB_RESTART:
|
||||
return
|
||||
b == UNIT_ACTIVATING;
|
||||
/* Restart jobs must always be kept.
|
||||
*
|
||||
* For ACTIVE/RELOADING units, this is obvious.
|
||||
*
|
||||
* For ACTIVATING units, it's more subtle:
|
||||
*
|
||||
* Generally, if a service Requires= another unit, restarts of
|
||||
* the unit must be propagated to the service. If the service is
|
||||
* ACTIVATING, it must still be restarted since it might have
|
||||
* stale information regarding the other unit.
|
||||
*
|
||||
* For example, consider a service that Requires= a socket: if
|
||||
* the socket is restarted, but the service is still ACTIVATING,
|
||||
* it's necessary to restart the service so that it gets the new
|
||||
* socket. */
|
||||
return false;
|
||||
|
||||
case JOB_NOP:
|
||||
return true;
|
||||
@ -417,8 +431,12 @@ JobType job_type_collapse(JobType t, Unit *u) {
|
||||
switch (t) {
|
||||
|
||||
case JOB_TRY_RESTART:
|
||||
/* Be sure to keep the restart job even if the unit is
|
||||
* ACTIVATING.
|
||||
*
|
||||
* See the job_type_is_redundant(JOB_RESTART) for more info */
|
||||
s = unit_active_state(u);
|
||||
if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
|
||||
if (!UNIT_IS_ACTIVE_OR_ACTIVATING(s))
|
||||
return JOB_NOP;
|
||||
|
||||
return JOB_RESTART;
|
||||
|
8
test/testsuite-03.units/always-activating.service
Normal file
8
test/testsuite-03.units/always-activating.service
Normal file
@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=Service that never leaves state ACTIVATING
|
||||
Requires=always-activating.socket
|
||||
After=always-activating.socket
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
ExecStart=bash -c 'sleep infinity'
|
5
test/testsuite-03.units/always-activating.socket
Normal file
5
test/testsuite-03.units/always-activating.socket
Normal file
@ -0,0 +1,5 @@
|
||||
[Unit]
|
||||
Description=Socket that activates always-activating.service
|
||||
|
||||
[Socket]
|
||||
ListenStream=/run/test-03-always-activating.sock
|
@ -50,6 +50,15 @@ systemctl stop hello.service sleep.service hello-after-sleep.target
|
||||
|
||||
# TODO: add more job queueing/merging tests here.
|
||||
|
||||
# Test that restart propagates to activating units
|
||||
systemctl -T --no-block start always-activating.service
|
||||
systemctl list-jobs | grep 'always-activating.service'
|
||||
ACTIVATING_ID_PRE=$(systemctl show -P InvocationID always-activating.service)
|
||||
systemctl -T start always-activating.socket # Wait for the socket to come up
|
||||
systemctl -T restart always-activating.socket
|
||||
ACTIVATING_ID_POST=$(systemctl show -P InvocationID always-activating.service)
|
||||
[ "$ACTIVATING_ID_PRE" != "$ACTIVATING_ID_POST" ] || exit 1
|
||||
|
||||
# Test for irreversible jobs
|
||||
systemctl start unstoppable.service
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user