62b301
From 2b390a10d826f060a672d9f01c6ad43714691274 Mon Sep 17 00:00:00 2001
62b301
From: Anita Zhang <the.anitazha@gmail.com>
62b301
Date: Tue, 8 Jun 2021 00:04:35 -0700
62b301
Subject: [PATCH] test: add extended test for triggering mount rate limit
62b301
62b301
It's hard to trigger the failure to exit the rate limit state in
62b301
isolation as it needs multiple event sources in order to show that it
62b301
gets stuck in the queue. Hence why this is an extended test.
62b301
62b301
(cherry picked from commit 0c81900965a72b29eb76e0737ed899b925ee75b6)
62b301
62b301
Related: #1940973
62b301
---
62b301
 test/TEST-60-MOUNT-RATELIMIT/Makefile     |  1 +
62b301
 test/TEST-60-MOUNT-RATELIMIT/test.sh      | 48 +++++++++++++++
62b301
 test/TEST-60-MOUNT-RATELIMIT/testsuite.sh | 73 +++++++++++++++++++++++
62b301
 3 files changed, 122 insertions(+)
62b301
 create mode 120000 test/TEST-60-MOUNT-RATELIMIT/Makefile
62b301
 create mode 100755 test/TEST-60-MOUNT-RATELIMIT/test.sh
62b301
 create mode 100755 test/TEST-60-MOUNT-RATELIMIT/testsuite.sh
62b301
62b301
diff --git a/test/TEST-60-MOUNT-RATELIMIT/Makefile b/test/TEST-60-MOUNT-RATELIMIT/Makefile
62b301
new file mode 120000
62b301
index 0000000000..e9f93b1104
62b301
--- /dev/null
62b301
+++ b/test/TEST-60-MOUNT-RATELIMIT/Makefile
62b301
@@ -0,0 +1 @@
62b301
+../TEST-01-BASIC/Makefile
62b301
\ No newline at end of file
62b301
diff --git a/test/TEST-60-MOUNT-RATELIMIT/test.sh b/test/TEST-60-MOUNT-RATELIMIT/test.sh
62b301
new file mode 100755
62b301
index 0000000000..e3c9288546
62b301
--- /dev/null
62b301
+++ b/test/TEST-60-MOUNT-RATELIMIT/test.sh
62b301
@@ -0,0 +1,48 @@
62b301
+#!/usr/bin/env bash
62b301
+set -e
62b301
+TEST_DESCRIPTION="Test that mount/unmount storms can enter/exit rate limit state and will not leak units"
62b301
+
62b301
+. $TEST_BASE_DIR/test-functions
62b301
+
62b301
+test_setup() {
62b301
+    create_empty_image
62b301
+    mkdir -p $TESTDIR/root
62b301
+    mount ${LOOPDEV}p1 $TESTDIR/root
62b301
+
62b301
+    (
62b301
+        LOG_LEVEL=5
62b301
+        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
62b301
+
62b301
+        setup_basic_environment
62b301
+
62b301
+        # mask some services that we do not want to run in these tests
62b301
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
62b301
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
62b301
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
62b301
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
62b301
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
62b301
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
62b301
+
62b301
+        # setup the testsuite service
62b301
+        cat >$initdir/etc/systemd/system/testsuite.service <
62b301
+[Unit]
62b301
+Description=Testsuite service
62b301
+
62b301
+[Service]
62b301
+ExecStart=/bin/bash -x /testsuite.sh
62b301
+Type=oneshot
62b301
+StandardOutput=tty
62b301
+StandardError=tty
62b301
+NotifyAccess=all
62b301
+EOF
62b301
+        cp testsuite.sh $initdir/
62b301
+
62b301
+        setup_testsuite
62b301
+    ) || return 1
62b301
+    setup_nspawn_root
62b301
+
62b301
+    ddebug "umount $TESTDIR/root"
62b301
+    umount $TESTDIR/root
62b301
+}
62b301
+
62b301
+do_test "$@"
62b301
diff --git a/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh
62b301
new file mode 100755
62b301
index 0000000000..8158754667
62b301
--- /dev/null
62b301
+++ b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh
62b301
@@ -0,0 +1,73 @@
62b301
+#!/usr/bin/env bash
62b301
+set -eux
62b301
+set -o pipefail
62b301
+
62b301
+systemd-analyze log-level debug
62b301
+systemd-analyze log-target journal
62b301
+
62b301
+NUM_DIRS=20
62b301
+
62b301
+# mount/unmount enough times to trigger the /proc/self/mountinfo parsing rate limiting
62b301
+
62b301
+for ((i = 0; i < NUM_DIRS; i++)); do
62b301
+    mkdir "/tmp/meow${i}"
62b301
+done
62b301
+
62b301
+for ((i = 0; i < NUM_DIRS; i++)); do
62b301
+    mount -t tmpfs tmpfs "/tmp/meow${i}"
62b301
+done
62b301
+
62b301
+systemctl daemon-reload
62b301
+systemctl list-units -t mount tmp-meow* | grep -q tmp-meow
62b301
+
62b301
+for ((i = 0; i < NUM_DIRS; i++)); do
62b301
+    umount "/tmp/meow${i}"
62b301
+done
62b301
+
62b301
+# figure out if we have entered the rate limit state
62b301
+
62b301
+exited_rl=0
62b301
+timeout="$(date -ud "2 minutes" +%s)"
62b301
+while [[ $(date -u +%s) -le ${timeout} ]]; do
62b301
+    if journalctl -u init.scope | grep -q "(mount-monitor-dispatch) entered rate limit"; then
62b301
+        entered_rl=1
62b301
+        break
62b301
+    fi
62b301
+    sleep 5
62b301
+done
62b301
+
62b301
+# if the infra is slow we might not enter the rate limit state; in that case skip the exit check
62b301
+
62b301
+if [ "${entered_rl}" = "1" ]; then
62b301
+    exited_rl=0
62b301
+    timeout="$(date -ud "2 minutes" +%s)"
62b301
+    while [[ $(date -u +%s) -le ${timeout} ]]; do
62b301
+        if journalctl -u init.scope | grep -q "(mount-monitor-dispatch) left rate limit"; then
62b301
+            exited_rl=1
62b301
+            break
62b301
+        fi
62b301
+        sleep 5
62b301
+    done
62b301
+
62b301
+    if [ "${exited_rl}" = "0" ]; then
62b301
+        exit 24
62b301
+    fi
62b301
+fi
62b301
+
62b301
+# give some time for units to settle so we don't race between exiting the rate limit state and cleaning up the units
62b301
+
62b301
+sleep 60
62b301
+systemctl daemon-reload
62b301
+sleep 60
62b301
+
62b301
+# verify that the mount units are always cleaned up at the end
62b301
+
62b301
+if systemctl list-units -t mount tmp-meow* | grep -q tmp-meow; then
62b301
+    exit 42
62b301
+fi
62b301
+
62b301
+systemd-analyze log-level info
62b301
+
62b301
+echo OK >/testok
62b301
+
62b301
+exit 0