Improved zramswap

I improved the script a bit and removed the dependency on grep and awk
Here is an improved version that allows to:

  1. Manually set the size of the RAM used. SIZE=x and SIZE_TYPE=y where y can be KiB,MiB or GiB (Default).
  2. Prevent use of unsupported compression algorithms.
  3. Prevent the use of more as max RAM ZRAM_MAX_PERCENT=x (50% Default)
  4. RAM_PERCENT is used to config a percentage of max ram (20% Default). A non-zero SIZE= takes precedence.

You can start/enable it as usual:
systemctl enable --now zramswap-trimoon


File /etc/zramswap.conf :

SIZE=8
RAM_PERCENT=25
# See: cat /sys/block/zram0/comp_algorithm
# One of: lzo [lzo-rle] lz4 lz4hc 842 zstd
ZRAM_COMPRESSION_ALGO=zstd

File /usr/lib/systemd/scripts/zramctrl.trimoon :

#!/bin/bash
declare -i ZRAM_MAX_PERCENT=50
declare -i RAM_PERCENT=0 SIZE=0

if [ -f /etc/zramswap.conf ]; then
	source /etc/zramswap.conf
fi

start() {
	local Item Multiplier AVAILABLE_ALGO
	local -i Amount RAM_TOTAL_BYTES ZRAM_SIZE ZRAM_SIZE_REQ FOUND_ALGO

	test $RAM_PERCENT -eq 0 && RAM_PERCENT=20
	test $RAM_PERCENT -gt $ZRAM_MAX_PERCENT && RAM_PERCENT=$ZRAM_MAX_PERCENT
	# echo $RAM_PERCENT

	# Grab max memory
	while read -r Item Amount Multiplier; do
		test "$Item" != "MemTotal:" && continue
		# echo "|$Item|$Amount|$Multiplier|"
		case $Multiplier in
			kB)	RAM_TOTAL_BYTES=$((Amount * 1024)) ;;
			mB)	RAM_TOTAL_BYTES=$((Amount * (1024**2) )) ;;
			gB)	RAM_TOTAL_BYTES=$((Amount * (1024**3) )) ;;
			*)	RAM_TOTAL_BYTES=$Amount ;;
		esac
		# echo "$RAM_TOTAL_BYTES $RAM_PERCENT"
	done </proc/meminfo

	# SIZE=8
	# Manual size config?
	if test $SIZE -gt 0; then
		case "${SIZE_TYPE:-GiB}" in
			KiB)	ZRAM_SIZE_REQ=$((SIZE * 1024)) ;;
			MiB)	ZRAM_SIZE_REQ=$((SIZE * (1024**2) )) ;;
			GiB)	ZRAM_SIZE_REQ=$((SIZE * (1024**3) )) ;;
			*)		ZRAM_SIZE_REQ=$SIZE ;;
		esac
		if test $ZRAM_SIZE_REQ -gt $((RAM_TOTAL_BYTES * ZRAM_MAX_PERCENT / 100)); then
			ZRAM_SIZE=$((RAM_TOTAL_BYTES * ZRAM_MAX_PERCENT / 100))
			echo "Using: $ZRAM_SIZE Bytes (Clipped at $ZRAM_MAX_PERCENT% of max.)"
		else
			ZRAM_SIZE=$ZRAM_SIZE_REQ
			echo "Using: $ZRAM_SIZE Bytes ($SIZE ${SIZE_TYPE:-GiB})"
		fi
	else
		ZRAM_SIZE=$((RAM_TOTAL_BYTES * RAM_PERCENT / 100))
		echo "Using: $ZRAM_SIZE Bytes ($RAM_PERCENT% of max.)"
	fi

	# Load the zram module
	modprobe zram
	if test -n "$ZRAM_COMPRESSION_ALGO"; then
		# Iterate over available compression algorithms.
		for AVAILABLE_ALGO in $(</sys/block/zram0/comp_algorithm); do
			# Remove brackets from active one
			AVAILABLE_ALGO=${AVAILABLE_ALGO#[}
			AVAILABLE_ALGO=${AVAILABLE_ALGO%]}
			# echo "$AVAILABLE_ALGO"
			if test "$ZRAM_COMPRESSION_ALGO" = "$AVAILABLE_ALGO"; then
				FOUND_ALGO=1
				break
			fi
		done
		# Only change algorithm when available.
		if test $FOUND_ALGO -eq 1; then
			echo "$ZRAM_COMPRESSION_ALGO" > /sys/block/zram0/comp_algorithm
		fi
	fi

	# Setup the ZRam swap.
	echo $ZRAM_SIZE > /sys/block/zram0/disksize
	mkswap /dev/zram0 -L zram0
	swapon -p 100 /dev/zram0
}

stop() {
  swapoff /dev/zram0
  rmmod zram
}

case $1 in
  start|stop) "$1" ;;
esac

File /usr/lib/systemd/system/zramswap-trimoon.service :

[Unit]
Description=Zram-based swap (compressed RAM block devices)
Documentation=https://forum.manjaro.org/t/improved-zramswap/34767

[Service]
Type=oneshot
ExecStart=/usr/lib/systemd/scripts/zramctrl.trimoon start
ExecStop=/usr/lib/systemd/scripts/zramctrl.trimoon stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

> systemctl status zramswap-trimoon | xclip
● zramswap-trimoon.service - Zram-based swap (compressed RAM block devices)
     Loaded: loaded (/usr/lib/systemd/system/zramswap-trimoon.service; enabled; vendor preset: disabled)
     Active: active (exited) since Fri 2020-10-30 15:53:08 +03; 47min ago
       Docs: https://forum.manjaro.org/t/improved-zramswap/34767
   Main PID: 49644 (code=exited, status=0/SUCCESS)
      Tasks: 0 (limit: 38400)
     Memory: 0B
     CGroup: /system.slice/zramswap-trimoon.service

Eki 30 15:53:08 manjaro systemd[1]: Starting Zram-based swap (compressed RAM block devices)...
Eki 30 15:53:08 manjaro zramctrl.trimoon[49644]: Using: 8589934592 Bytes (8 GiB)
Eki 30 15:53:08 manjaro zramctrl.trimoon[49656]: Setting up swapspace version 1, size = 8 GiB (8589930496 bytes)
Eki 30 15:53:08 manjaro zramctrl.trimoon[49656]: LABEL=zram0, UUID=8458757a-fb36-4088-894b-ba1ec9e48fa2
Eki 30 15:53:08 manjaro systemd[1]: Finished Zram-based swap (compressed RAM block devices).

If the owner/maintainer of the zramswap AUR package sees this he may update his version with this one while renaming the above versions without the trimoon parts :wink:
See also my comment there

5 Likes