Configure compressed swap using zram
device at system boot.
There are two distinct packages that provide systemd service to configure compressed swap using zram
device at system boot.
There is nothing difficult here, but studying different solutions will help you to create your own solution.
Install extra modules for the running kernel.
$ sudo apt install linux-modules-extra-$(uname -r)
zram-tools
Install zram-tools package.
$ sudo apt install zram-tools
Inspect default configuration.
$ cat /etc/default/zramswap
# Specifies amount of zram devices to create. # By default, zramswap-start will use all available cores. #CORES=1 # Specifies the amount of RAM that should be used for zram # based on a percentage the total amount of available memory #PERCENTAGE=10 # Specifies a static amount of RAM that should be used for # the ZRAM devices, this is in MiB #ALLOCATION=256 # Specifies the priority for the swap devices, see swapon(2) # for more details. #PRIORITY=100
Inspect service.
$ systemctl status zramswap.service
● zramswap.service - Linux zramswap setup Loaded: loaded (/lib/systemd/system/zramswap.service; enabled; vendor preset: enabled) Active: active (exited) since Mon 2021-01-04 21:31:41 UTC; 5s ago Docs: man:zramswap(8) Process: 11068 ExecStart=/usr/sbin/zramswap start (code=exited, status=0/SUCCESS) Main PID: 11068 (code=exited, status=0/SUCCESS)
Inspect zram
devices.
$ zramctl
NAME DISKSIZE DATA COMPR ALGORITHM STREAMS ZERO-PAGES TOTAL MEM-LIMIT MEM-USED MIGRATED MOUNTPOINT /dev/zram1 128M 4K 73B lzo-rle 2 0 12K 0B 12K 0B [SWAP] /dev/zram0 128M 84K 13.5K lzo-rle 2 0 168K 0B 168K 0B [SWAP]
Inspect swap devices.
$ swapon -status
Filename Type Size Used Priority /dev/zram0 partition 131068 256 100 /dev/zram1 partition 131068 0 100
This solution uses a simple service file …
[Unit] Description=Linux zramswap setup Documentation=man:zramswap(8) [Service] EnvironmentFile=-/etc/default/zramswap ExecStart=/usr/sbin/zramswap start ExecStop=/usr/sbin/zramswap stop ExecReload=/usr/sbin/zramswap restart Type=oneshot RemainAfterExit=true [Install] WantedBy=multi-user.target
… and a slightly outdated shell scripts.
#!/bin/bash # This script does the following: # zramswap start: # * Space is assigned to each zram device, then swap is initialized on # there # zramswap stop: # * Undo start # * Also attempts to remove zram module at the end # TODO: # * Migrate to using zramctl from util-linux for the setup, # (this will close debian bug #917643): # then also: # - add option for compression algorythm # - ammount of compression streams # - Make use of the zramctl stats too function start { #Set some defaults: ALLOCATION=256 # ZRAM Swap you want assigned, in MiB PRIORITY=100 # Swap priority, see swapon(2) for more details # Get amount of available CPU cores, set to 1 if not detected correctly if [ ! -f /proc/cpuinfo ]; then echo "WARNING: Can't find /proc/cpuinfo, is proc mounted?" echo " Using a single core for zramswap..." CORES=1 else CORES=$(grep -c ^processor /proc/cpuinfo) fi # Override above from config file, if it exists if [ -f /etc/default/zramswap ]; then . /etc/default/zramswap fi ALLOCATION=$((ALLOCATION * 1024 * 1024)) # convert amount from MiB to bytes if [ -n "$PERCENTAGE" ]; then totalmemory=$(awk '/MemTotal/{print $2}' /proc/meminfo) # in KiB ALLOCATION=$((totalmemory * 1024 * $PERCENTAGE / 100)) fi # Initialize zram devices modprobe zram num_devices=$CORES # Assign memory to zram devices, initialize swap and activate # Decrementing $CORE, because cores start counting at 0 for CORE in $(seq 0 $(($CORES - 1))); do echo $(($ALLOCATION / $CORES)) > /sys/block/zram$CORE/disksize mkswap /dev/zram$CORE swapon -p $PRIORITY /dev/zram$CORE done } function status { orig_data_size="0" for file in /sys/block/zram*/*_data_size ; do if [ $file = "/sys/block/zram*/*_data_size" ]; then compress_ratio="0" break fi read file_content < $file what=$(basename $file) eval "$what=\$(($what + $file_content))" compress_ratio=$(echo "scale=2; $orig_data_size / $compr_data_size" | bc) done echo "compr_data_size: $((compr_data_size / 1024)) KiB" echo "orig_data_size: $((orig_data_size / 1024)) KiB" echo "compression-ratio: $compress_ratio" } function stop { for swapspace in $(swapon -s | awk '/zram/{print $1}'); do swapoff $swapspace done modprobe -r zram } function usage { echo "Usage:" echo " zramswap start - start zram swap" echo " zramswap stop - stop zram swap" echo " zramswap status - prints some statistics" } if [ "$1" = "start" ]; then start fi if [ "$1" = "stop" ]; then stop fi if [ "$1" = "status" ]; then status fi if [ "$1" = "" ]; then usage fi
There is a bug report #917643 that suggests a more modern approach.
KERNEL=="zram0", SUBSYSTEM=="block", DRIVER=="", ACTION=="add", ATTR{initstate}=="0", PROGRAM="/bin/sh -c 'echo $(($(LANG=C free -k | grep -e \"^Mem:\" | sed -e \"s/^Mem: *//\" -e \"s/ *.*//\")*2))KiB'", ATTR{disksize}="$result", RUN+="/sbin/mkswap $env{DEVNAME}", TAG+="systemd"
zram-config
Install zram-config package.
$ sudo apt install zram-config
Inspect service.
$ systemctl status zram-config.service
● zram-config.service - Initializes zram swaping Loaded: loaded (/lib/systemd/system/zram-config.service; enabled; vendor preset: enabled) Active: inactive (dead)
Start service.
$ sudo systemctl start zram-config.service
Inspect service status.
$ systemctl status zram-config.service
● zram-config.service - Initializes zram swaping Loaded: loaded (/lib/systemd/system/zram-config.service; enabled; vendor preset: enabled) Active: active (exited) since Mon 2021-01-04 22:16:22 UTC; 4s ago Process: 1555 ExecStart=/usr/bin/init-zram-swapping (code=exited, status=0/SUCCESS) Main PID: 1555 (code=exited, status=0/SUCCESS)
Inspect zram
devices.
$ zramctl --output-all
NAME DISKSIZE DATA COMPR ALGORITHM STREAMS ZERO-PAGES TOTAL MEM-LIMIT MEM-USED MIGRATED MOUNTPOINT /dev/zram1 984.1M 4K 74B lzo-rle 2 0 12K 0B 12K 0B [SWAP] /dev/zram0 984.1M 4K 74B lzo-rle 2 0 12K 0B 12K 0B [SWAP]
Inspect swap devices.
$ swapon -status
Filename Type Size Used Priority Filename Type Size Used Priority /dev/zram0 partition 1007668 0 5 /dev/zram1 partition 1007668 0 5
This solution uses a simple service file …
[Unit] Description=Initializes zram swaping [Service] ExecStart=/usr/bin/init-zram-swapping ExecStop=/usr/bin/end-zram-swapping Type=oneshot RemainAfterExit=true [Install] WantedBy=multi-user.target
… and a slightly outdated shell scripts.
#!/bin/sh # load dependency modules NRDEVICES=$(grep -c ^processor /proc/cpuinfo | sed 's/^0$/1/') if modinfo zram | grep -q ' zram_num_devices:' 2>/dev/null; then MODPROBE_ARGS="zram_num_devices=${NRDEVICES}" elif modinfo zram | grep -q ' num_devices:' 2>/dev/null; then MODPROBE_ARGS="num_devices=${NRDEVICES}" else exit 1 fi modprobe zram $MODPROBE_ARGS # Calculate memory to use for zram (1/2 of ram) totalmem=`LC_ALL=C free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/ *.*//'` mem=$(((totalmem / 2 / ${NRDEVICES}) * 1024)) # initialize the devices for i in $(seq ${NRDEVICES}); do DEVNUMBER=$((i - 1)) echo $mem > /sys/block/zram${DEVNUMBER}/disksize mkswap /dev/zram${DEVNUMBER} swapon -p 5 /dev/zram${DEVNUMBER} done
#!/bin/sh if DEVICES=$(grep zram /proc/swaps | awk '{print $1}'); then for i in $DEVICES; do swapoff $i done fi rmmod zram
Additional notes
These tools do not use udev
or zramctl
utility, so the best possible solution is to read about compressed RAM based block devices and create your own customized solution.