Add ActivatingConcurrencyMax for slice startup pacing
Introduce Slice.ActivatingConcurrencyMax to limit how many units within a slice hierarchy may be in activating state concurrently. Expose the setting over D-Bus, support transient/property parsing, enforce it during unit start dispatch, and re-check queued starts when units leave activating state. Document the new slice option and add a PID1 concurrency test covering queued startup behavior.
This commit is contained in:
committed by
Yu Watanabe
parent
6044c31038
commit
5f0d98e728
@@ -117,6 +117,65 @@ systemctl start sleepforever3@a.service
|
||||
systemctl stop concurrency1.slice
|
||||
systemctl reset-failed
|
||||
|
||||
# Test ActivatingConcurrencyMax
|
||||
cat >/run/systemd/system/concurrency-activating.slice <<EOF
|
||||
[Slice]
|
||||
ActivatingConcurrencyMax=2
|
||||
EOF
|
||||
|
||||
cat >/run/systemd/system/slow-start@.service <<EOF
|
||||
[Service]
|
||||
Slice=concurrency-activating.slice
|
||||
# Simulate slow startup
|
||||
ExecStartPre=/usr/bin/sleep 2
|
||||
ExecStart=/usr/bin/sleep infinity
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
# Start 3 services - only 2 should activate concurrently
|
||||
systemctl --no-block start slow-start@a.service
|
||||
systemctl --no-block start slow-start@b.service
|
||||
systemctl --no-block start slow-start@c.service
|
||||
|
||||
# Wait for jobs to be dispatched and first two to enter activating
|
||||
for _ in {1..20}; do
|
||||
jobs=$(systemctl list-jobs | grep -c "slow-start@.*start" || true)
|
||||
if [[ "$jobs" -eq 3 ]]; then
|
||||
activating=$(systemctl list-units --state=activating 'slow-start@*' --no-legend | wc -l)
|
||||
if [[ "$activating" -eq 2 ]]; then
|
||||
break
|
||||
fi
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
# Check that exactly 2 are activating (c should be queued)
|
||||
test "$(systemctl list-jobs | grep -c "slow-start@.*start")" -eq 3
|
||||
test "$(systemctl show -p ActiveState slow-start@a.service --value)" = "activating"
|
||||
test "$(systemctl show -p ActiveState slow-start@b.service --value)" = "activating"
|
||||
test "$(systemctl show -p ActiveState slow-start@c.service --value)" = "inactive"
|
||||
|
||||
# Wait for a and b to finish starting, then c to start and finish
|
||||
# a,b take ~2s to activate, then c starts and takes ~2s more
|
||||
sleep 5
|
||||
|
||||
# Now all should be active (c started when a/b finished activating)
|
||||
systemctl is-active slow-start@a.service
|
||||
systemctl is-active slow-start@b.service
|
||||
systemctl is-active slow-start@c.service
|
||||
|
||||
# Cleanup
|
||||
systemctl stop concurrency-activating.slice
|
||||
systemctl reset-failed
|
||||
rm /run/systemd/system/concurrency-activating.slice
|
||||
rm /run/systemd/system/slow-start@.service
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
# Final cleanup of original tests
|
||||
systemctl reset-failed
|
||||
|
||||
rm /run/systemd/system/concurrency1.slice
|
||||
rm /run/systemd/system/concurrency1-concurrency2.slice
|
||||
rm /run/systemd/system/concurrency1-concurrency3.slice
|
||||
|
||||
Reference in New Issue
Block a user