diff --git a/src/core/mount.c b/src/core/mount.c index dcfbf970d7..b47bd12c96 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -2194,9 +2194,6 @@ static int mount_can_start(Unit *u) { assert(m); - if (sd_event_source_is_ratelimited(u->manager->mount_event_source)) - return -EAGAIN; - r = unit_test_start_limit(u); if (r < 0) { mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); diff --git a/src/core/unit.c b/src/core/unit.c index 31c5be4431..180dccc2b2 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1868,6 +1868,10 @@ int unit_start(Unit *u) { assert(u); + /* Let's hold off running start jobs for mount units when /proc/self/mountinfo monitor is rate limited. */ + if (u->type == UNIT_MOUNT && sd_event_source_is_ratelimited(u->manager->mount_event_source)) + return -EAGAIN; + /* If this is already started, then this will succeed. Note that this will even succeed if this unit * is not startable by the user. This is relied on to detect when we need to wait for units and when * waiting is finished. */ diff --git a/test/units/testsuite-60.sh b/test/units/testsuite-60.sh index 239d7b0d4c..8cb3f466b6 100755 --- a/test/units/testsuite-60.sh +++ b/test/units/testsuite-60.sh @@ -3,6 +3,56 @@ set -eux set -o pipefail +test_issue_20329() { + local tmpdir unit + tmpdir="$(mktemp -d)" + unit=$(systemd-escape --suffix mount --path "$tmpdir") + + # Set up test mount unit + cat > /run/systemd/system/"$unit" <&2 "Test mount \"$unit\" unit isn't mounted" + return 1 + } + mountpoint -q "$tmpdir" + + trap 'systemctl stop $unit' RETURN + + # Trigger the mount ratelimiting + cd "$(mktemp -d)" + mkdir foo + for ((i=0;i<50;++i)); do + mount --bind foo foo + umount foo + done + + # Unmount the test mount and start it immediately again via systemd + umount "$tmpdir" + systemctl start "$unit" + + # Make sure it is seen as mounted by systemd and it actually is mounted + [[ "$(systemctl show --property SubState --value "$unit")" = "mounted" ]] || { + echo >&2 "Test mount \"$unit\" unit isn't in \"mounted\" state" + return 1 + } + + mountpoint -q "$tmpdir" || { + echo >&2 "Test mount \"$unit\" is in \"mounted\" state, actually is not mounted" + return 1 + } +} + systemd-analyze log-level debug systemd-analyze log-target journal @@ -87,6 +137,9 @@ if systemctl list-units -t mount tmp-meow* | grep -q tmp-meow; then exit 42 fi +# test that handling of mount start jobs is delayed when /proc/self/mouninfo monitor is rate limited +test_issue_20329 + systemd-analyze log-level info echo OK >/testok