#!/bin/sh
# First the limits systemd's process 1 raises before any unit: fs.file-max to
# LONG_MAX, fs.nr_open to the largest value the kernel takes,
# net.unix.max_dgram_qlen to 512; a value already larger stays, a refused write
# is ignored. Then sysctl.d(5) with procps (sysctl --system: same file order
# and overrides as systemd-sysctl, then /etc/sysctl.conf). As in systemd-sysctl
# a key may fail if it is written with a leading "-", or if the kernel refuses
# the write (read-only, permission).
P=/proc/sys

# raise FILE VALUE: VALUE if larger than the current one; 1 if the write fails
raise() {
	[ -w "$1" ] || return 0
	# whole file at once: proc_dointvec returns nothing at an offset above 0
	cur=$(cat "$1" 2>/dev/null) || return 0
	[ "$cur" -ge "$2" ] 2>/dev/null && return 0
	{ echo "$2" >"$1"; } 2>/dev/null
}

bits=$(getconf LONG_BIT 2>/dev/null) || bits=64
if [ "$bits" = 64 ]; then
	raise "$P/fs/file-max" 9223372036854775807
	max=2147483584
else
	raise "$P/fs/file-max" 2147483647
	max=1073741792
fi
# min(INT_MAX, SIZE_MAX / sizeof(void *)) rounded down to BITS_PER_LONG, halved while refused
while [ "$max" -ge "$bits" ] && ! raise "$P/fs/nr_open" "$max"; do
	max=$((max / 2))
done
raise "$P/net/unix/max_dgram_qlen" 512

if out=$(sysctl -q --system 2>&1 >/dev/null); then
	exit 0
fi

dirs="/etc/sysctl.d /run/sysctl.d /usr/local/lib/sysctl.d /usr/lib/sysctl.d /lib/sysctl.d"
optional=$(for f in $(for d in $dirs; do echo "$d"/*.conf; done) /etc/sysctl.conf; do
	[ -r "$f" ] && sed -n 's/^[[:space:]]*-\([^=[:space:]]*\)[[:space:]]*=.*/\1/p' "$f"
done)

set -f
r=0
while IFS= read -r l; do
	case $l in
	*'permission denied on key'*) continue ;;
	*'setting key "'*': Read-only file system' | *'setting key "'*': Permission denied' | *'setting key "'*': Operation not permitted') continue ;;
	*'setting key "'*)
		k=${l#*setting key \"}
		k=${k%%\"*}
		;;
	*'cannot stat /proc/sys/'*)
		k=${l#*cannot stat /proc/sys/}
		k=$(echo "${k%%:*}" | tr / .)
		;;
	*)
		echo "$l" >&2
		r=1
		continue
		;;
	esac
	ok=
	for p in $optional; do
		# shellcheck disable=SC2254
		case $k in $p) ok=1 ;; esac
	done
	[ -n "$ok" ] && continue
	echo "$l" >&2
	r=1
done <<EOF
$out
EOF
exit $r
