Merge pull request #17417 from anitazha/more_systoomd
More systemd-oomd tweaks
This commit is contained in:
commit
15a6c4bf8b
|
@ -117,6 +117,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
static int run(int argc, char *argv[]) {
|
static int run(int argc, char *argv[]) {
|
||||||
_cleanup_(notify_on_cleanup) const char *notify_msg = NULL;
|
_cleanup_(notify_on_cleanup) const char *notify_msg = NULL;
|
||||||
_cleanup_(manager_freep) Manager *m = NULL;
|
_cleanup_(manager_freep) Manager *m = NULL;
|
||||||
|
_cleanup_free_ char *swap = NULL;
|
||||||
|
unsigned long long s = 0;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
log_setup_service();
|
log_setup_service();
|
||||||
|
@ -131,8 +133,17 @@ static int run(int argc, char *argv[]) {
|
||||||
|
|
||||||
/* Do some basic requirement checks for running systemd-oomd. It's not exhaustive as some of the other
|
/* Do some basic requirement checks for running systemd-oomd. It's not exhaustive as some of the other
|
||||||
* requirements do not have a reliable means to check for in code. */
|
* requirements do not have a reliable means to check for in code. */
|
||||||
if (access("/proc/swaps", F_OK) < 0)
|
|
||||||
return log_error_errno(errno, "Swap not enabled: %m");
|
/* SwapTotal is always available in /proc/meminfo and defaults to 0, even on swap-disabled kernels. */
|
||||||
|
r = get_proc_field("/proc/meminfo", "SwapTotal", WHITESPACE, &swap);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to get SwapTotal from /proc/meminfo: %m");
|
||||||
|
|
||||||
|
r = safe_atollu(swap, &s);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse SwapTotal from /proc/meminfo: %s: %m", swap);
|
||||||
|
if (s == 0)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Requires swap to operate");
|
||||||
|
|
||||||
if (!is_pressure_supported())
|
if (!is_pressure_supported())
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Pressure Stall Information (PSI) is not supported");
|
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Pressure Stall Information (PSI) is not supported");
|
||||||
|
|
|
@ -57,7 +57,7 @@ static void test_oomd_cgroup_kill(void) {
|
||||||
|
|
||||||
/* If we don't have permissions to set xattrs we're likely in a userns or missing capabilities */
|
/* If we don't have permissions to set xattrs we're likely in a userns or missing capabilities */
|
||||||
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_test", "test", 4, 0);
|
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_test", "test", 4, 0);
|
||||||
if (IN_SET(r, -EPERM, -ENOTSUP))
|
if (ERRNO_IS_PRIVILEGE(r) || ERRNO_IS_NOT_SUPPORTED(r))
|
||||||
return (void) log_tests_skipped("Cannot set user xattrs");
|
return (void) log_tests_skipped("Cannot set user xattrs");
|
||||||
|
|
||||||
/* Do this twice to also check the increment behavior on the xattrs */
|
/* Do this twice to also check the increment behavior on the xattrs */
|
||||||
|
|
1
test/TEST-56-OOMD/Makefile
Symbolic link
1
test/TEST-56-OOMD/Makefile
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../TEST-01-BASIC/Makefile
|
48
test/TEST-56-OOMD/test.sh
Executable file
48
test/TEST-56-OOMD/test.sh
Executable file
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
TEST_DESCRIPTION="systemd-oomd Memory Pressure Test"
|
||||||
|
|
||||||
|
. $TEST_BASE_DIR/test-functions
|
||||||
|
|
||||||
|
check_result_nspawn() {
|
||||||
|
local ret=1
|
||||||
|
local journald_report=""
|
||||||
|
local pids=""
|
||||||
|
[[ -e $1/testok ]] && ret=0
|
||||||
|
if [[ -e $1/skipped ]]; then
|
||||||
|
echo "TEST-56-OOMD was skipped:"
|
||||||
|
cat $1/skipped
|
||||||
|
ret=0
|
||||||
|
fi
|
||||||
|
[[ -f $1/failed ]] && cp -a $1/failed $TESTDIR
|
||||||
|
save_journal $1/var/log/journal
|
||||||
|
[[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
|
||||||
|
echo $JOURNAL_LIST
|
||||||
|
test -s $TESTDIR/failed && ret=$(($ret+1))
|
||||||
|
[ -n "$TIMED_OUT" ] && ret=$(($ret+1))
|
||||||
|
check_asan_reports "$1" || ret=$(($ret+1))
|
||||||
|
_umount_dir $initdir
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
||||||
|
check_result_qemu() {
|
||||||
|
local ret=1
|
||||||
|
mount_initdir
|
||||||
|
[[ -e $initdir/testok ]] && ret=0
|
||||||
|
if [[ -e $initdir/skipped ]]; then
|
||||||
|
echo "TEST-56-OOMD was skipped:"
|
||||||
|
cat $initdir/skipped
|
||||||
|
ret=0
|
||||||
|
fi
|
||||||
|
[[ -f $initdir/failed ]] && cp -a $initdir/failed $TESTDIR
|
||||||
|
save_journal $initdir/var/log/journal
|
||||||
|
check_asan_reports "$initdir" || ret=$(($ret+1))
|
||||||
|
_umount_dir $initdir
|
||||||
|
[[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
|
||||||
|
echo $JOURNAL_LIST
|
||||||
|
test -s $TESTDIR/failed && ret=$(($ret+1))
|
||||||
|
[ -n "$TIMED_OUT" ] && ret=$(($ret+1))
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
||||||
|
do_test "$@" 56
|
|
@ -65,6 +65,7 @@ BASICTOOLS=(
|
||||||
echo
|
echo
|
||||||
env
|
env
|
||||||
false
|
false
|
||||||
|
getconf
|
||||||
getent
|
getent
|
||||||
getfacl
|
getfacl
|
||||||
grep
|
grep
|
||||||
|
|
34
test/units/testsuite-56-slowgrowth.sh
Executable file
34
test/units/testsuite-56-slowgrowth.sh
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eu -o pipefail
|
||||||
|
|
||||||
|
PAGE_SIZE=$(getconf PAGE_SIZE)
|
||||||
|
BLOAT_ITERATION_TARGET=$(( 100 << 20 )) # 100 MB
|
||||||
|
BLOAT_HOLDER=()
|
||||||
|
PID="$$"
|
||||||
|
|
||||||
|
function bloat {
|
||||||
|
local set_size=$(cat "/proc/$PID/statm" | cut -d " " -f2)
|
||||||
|
local mem_usage=$(( "$set_size" * "$PAGE_SIZE" ))
|
||||||
|
local target_mem_size=$(( "$mem_usage" + "$1" ))
|
||||||
|
|
||||||
|
BLOAT_HOLDER=()
|
||||||
|
while [[ "$mem_usage" -lt "$target_mem_size" ]]; do
|
||||||
|
echo "target $target_mem_size"
|
||||||
|
echo "mem usage $mem_usage"
|
||||||
|
BLOAT_HOLDER+=( $(printf "%0.sg" {1..1000000}) )
|
||||||
|
set_size=$(cat "/proc/$PID/statm" | cut -d " " -f2)
|
||||||
|
mem_usage=$(( "$set_size" * "$PAGE_SIZE" ))
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function run {
|
||||||
|
local arr=()
|
||||||
|
|
||||||
|
while [[ true ]]; do
|
||||||
|
bloat "$BLOAT_ITERATION_TARGET"
|
||||||
|
arr+=( "$BLOAT_HOLDER" )
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
run
|
7
test/units/testsuite-56.service
Normal file
7
test/units/testsuite-56.service
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[Unit]
|
||||||
|
Description=TESTSUITE-56-OOMD
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStartPre=rm -f /failed /skipped /testok
|
||||||
|
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
|
||||||
|
Type=oneshot
|
70
test/units/testsuite-56.sh
Executable file
70
test/units/testsuite-56.sh
Executable file
|
@ -0,0 +1,70 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -ex
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
systemd-analyze log-level debug
|
||||||
|
systemd-analyze log-target console
|
||||||
|
|
||||||
|
# Loose checks to ensure the environment has the necessary features for systemd-oomd
|
||||||
|
[[ "$( awk '/SwapTotal/ { print $2 }' /proc/meminfo )" != "0" ]] || echo "no swap" >> /skipped
|
||||||
|
[[ -e /proc/pressure ]] || echo "no PSI" >> /skipped
|
||||||
|
cgroup_type=$(stat -fc %T /sys/fs/cgroup/)
|
||||||
|
if [[ "$cgroup_type" != *"cgroup2"* ]] && [[ "$cgroup_type" != *"0x63677270"* ]]; then
|
||||||
|
echo "no cgroup2" >> /skipped
|
||||||
|
fi
|
||||||
|
[[ -e /skipped ]] && exit 0 || true
|
||||||
|
|
||||||
|
cat > /etc/systemd/system/testworkload.slice <<EOF
|
||||||
|
[Slice]
|
||||||
|
CPUAccounting=true
|
||||||
|
MemoryAccounting=true
|
||||||
|
IOAccounting=true
|
||||||
|
TasksAccounting=true
|
||||||
|
ManagedOOMMemoryPressure=kill
|
||||||
|
ManagedOOMMemoryPressureLimitPercent=50%
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create a lot of memory pressure by setting memory.high to a very small value
|
||||||
|
cat > /etc/systemd/system/testbloat.service <<EOF
|
||||||
|
[Service]
|
||||||
|
MemoryHigh=2M
|
||||||
|
Slice=testworkload.slice
|
||||||
|
ExecStart=/usr/lib/systemd/tests/testdata/units/testsuite-56-slowgrowth.sh
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# This generates no memory pressure
|
||||||
|
cat > /etc/systemd/system/testchill.service <<EOF
|
||||||
|
[Service]
|
||||||
|
MemoryHigh=2M
|
||||||
|
Slice=testworkload.slice
|
||||||
|
ExecStart=sleep infinity
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
systemctl start testbloat.service
|
||||||
|
systemctl start testchill.service
|
||||||
|
|
||||||
|
# Verify systemd-oomd is monitoring the expected units
|
||||||
|
oomctl | grep "/testworkload.slice"
|
||||||
|
oomctl | grep "50%"
|
||||||
|
|
||||||
|
# systemd-oomd watches for elevated pressure for 30 seconds before acting.
|
||||||
|
# It can take time to build up pressure so either wait 5 minutes or for the service to fail.
|
||||||
|
timeout=$(date -ud "5 minutes" +%s)
|
||||||
|
while [[ $(date -u +%s) -le $timeout ]]; do
|
||||||
|
if ! systemctl status testbloat.service; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 15
|
||||||
|
done
|
||||||
|
|
||||||
|
# testbloat should be killed and testchill should be fine
|
||||||
|
if systemctl status testbloat.service; then exit 42; fi
|
||||||
|
if ! systemctl status testchill.service; then exit 24; fi
|
||||||
|
|
||||||
|
systemd-analyze log-level info
|
||||||
|
|
||||||
|
echo OK > /testok
|
||||||
|
|
||||||
|
exit 0
|
Loading…
Reference in a new issue