summaryrefslogtreecommitdiffstats
path: root/core/modules/zram-swap/data/opt/openslx/scripts/systemd-zram_swap
blob: 28a803d8a81d9b58225d37aeda6268ba58dcdac6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/bin/ash
# -----------------------------------------------------------------------------
#
# Copyright (c) 2013..2018 bwLehrpool-Projektteam
#
# This program/file is free software distributed under the GPL version 2.
# See https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
#
# If you have any feedback please consult https://bwlehrpool.de and
# send your feedback to support@bwlehrpool.de.
#
# General information about bwLehrpool can be found at https://bwlehrpool.de
#
# -----------------------------------------------------------------------------
#
# Local hard disk autodetection script for OpenSLX linux stateless clients,
# detecting swap and special partitions

#############################################################################

export PATH=$PATH:/opt/openslx/sbin:/opt/openslx/bin

# Add zram swap
# Some older ubuntu kernels had a problem here, see https://bugs.launchpad.net/ubuntu/+source/linux-lts-raring/+bug/1217189
# So make sure you're up to date

make_swap () {
	[ $# -ne 3 ] && echo "make_swap: Wrong parameter count $#" && return 1
	local USE="$1"
	local DEV="$2"
	local STREAMS="$3"
	echo "$USE" > "/sys/block/zram${DEV}/disksize" || return 1
	[ -n "$STREAMS" ] && echo "$STREAMS" > "/sys/block/zram${DEV}/max_comp_streams"
	(
		mkswap "/dev/zram${DEV}"
		swapon "/dev/zram${DEV}" -p 1000 # high priority (in case we have hdd swap 0x82, prefer zram)
	) &
}

# Count physical CPUs
CPUS=$(cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | sort -u | wc -l) # cat for *
if [ -z "$CPUS" ]; then
	echo "ERROR: Could not determine CPU core count"
else
	CPUS=1
fi

KERN=$(uname -r)
if [ "${KERN%%.*}" -le 4 ]; then
	DEVS=$CPUS
	[ "$DEVS" -gt "16" ] && DEVS=16 # zram can only handle up to 32 devices, the system can apparently even just handle 29 swap partitions, so use a reasonable upper limit
	STREAMS=
else
	DEVS=1
	STREAMS=$CPUS
fi

if [ -e "/sys/class/zram-control/hot_add" ]; then
	: # nothing to do, loaded and hot_add available
elif ! modprobe zram "num_devices=$DEVS"; then
	echo "ERROR: Could not load zram module"
	exit 1
fi

TOTAL=$(grep ^MemTotal /proc/meminfo | awk '{print $2}')
USE=$(( TOTAL / ( 2 * DEVS ) ))
echo "Have $CPUS cores, $TOTAL kb mem, use $USE kb zram swap each for $DEVS devices."
USE=$(( USE * 1024 ))
DEV=0
NUM=0
FAILS=0
while [ "$NUM" -lt "$DEVS" ]; do
	if [ -e "/sys/block/zram${DEV}" ]; then
		if ! [ -e "/sys/block/zram${DEV}/initstate" ] || [ "$(cat "/sys/block/zram${DEV}/initstate")" = 0 ]; then
			if make_swap "$USE" "$DEV" "$STREAMS"; then
				NUM=$(( NUM + 1 ))
			fi
		fi
		DEV=$(( DEV + 1 ))
	elif [ -e "/sys/class/zram-control/hot_add" ]; then
		DEV=$(cat /sys/class/zram-control/hot_add)
		if [ -z "$DEV" ]; then
			echo "ERROR: Cannot hot_add another zram device"
			break
		fi
		if make_swap "$USE" "$DEV" "$STREAMS"; then
			NUM=$(( NUM + 1 ))
		else
			FAILS=$(( FAILS + 1 ))
			if [ "$FAILS" -gt 4 ]; then
				echo "ERROR: Could not swap on hot added device -- giving up"
				break
			fi
		fi
		DEV=$(( DEV + 1 ))
	else
		echo "ERROR: Cannot add another zram device: No hot_add support"
		break
	fi
done

# Increase min free memory so we have enough mem available when trying to move
# something to zram swap. We want 1%, or at least 64MiB
CURRENT=$(cat "/proc/sys/vm/min_free_kbytes")
TOTAL=$(awk '{ if ($1 == "MemTotal:") { print $2; exit } }' /proc/meminfo)
WANT=$(( TOTAL / 100 ))
[ "$WANT" -gt 65535 ] || WANT=65535 # minimum 64M
if [ "$CURRENT" -lt "$WANT" ]; then
	echo "$WANT" > "/proc/sys/vm/min_free_kbytes"
fi

# Wait, so we don't trigger swap.target too early
wait

exit 0