mirror of
https://github.com/foundObjects/zram-swap.git
synced 2026-08-13 12:33:17 +02:00
Initial code push
This commit is contained in:
parent
461049a206
commit
4241a70d94
5 changed files with 207 additions and 1 deletions
32
README.md
32
README.md
|
|
@ -1,2 +1,32 @@
|
|||
# zram-swap
|
||||
zram swap setup + teardown with systemd unit & /etd/default configuration
|
||||
Simple zram swap setup + teardown script with systemd unit & /etc/default configuration
|
||||
|
||||
https://github.com/foundObjects/zram-swap
|
||||
|
||||
### Installation
|
||||
|
||||
```
|
||||
git clone https://github.com/foundObjects/zram-swap.git
|
||||
cd zram-swap && sudo bash install.sh
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
zram-swap.service will be started automatically during boot.
|
||||
|
||||
The default allocation creates a zram device that should use around half of physical memory when completely full.
|
||||
|
||||
Edit `/etc/default/zram-swap-service` if you'd like to change compression algorithms or swap allocation and then restart zram-swap with `systemctl restart zram-swap.service`.
|
||||
|
||||
Run `zramctl` during use to monitor swap compression and real memory usage.
|
||||
|
||||
### Debugging
|
||||
|
||||
Either start zram-swap.sh with `bash -x zram-swap.sh` or `./zram-swap.sh -x (start|stop)` to see what's going wrong.
|
||||
|
||||
To dump the full execution trace during service start/stop edit /etc/systemd/systemd/zram-swap.service and add -x to the following two lines:
|
||||
|
||||
```
|
||||
ExecStart=/usr/local/sbin/zram-swap.sh -x init
|
||||
ExecStop=/usr/local/sbin/zram-swap.sh -x end
|
||||
```
|
||||
|
|
|
|||
16
install.sh
Executable file
16
install.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
[[ "$EUID" == 0 ]] || { echo "This script requires root." && exit 1; }
|
||||
set -ex
|
||||
|
||||
if systemctl -q is-active zram-swap.service; then
|
||||
systemctl stop zram-swap.service
|
||||
fi
|
||||
|
||||
install -o root zram-swap.sh /usr/local/sbin/zram-swap.sh
|
||||
install -o root zram-swap-service /etc/default/zram-swap-service
|
||||
install -o root zram-swap.service /etc/systemd/system/zram-swap.service
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable zram-swap.service
|
||||
systemctl start zram-swap.service
|
||||
22
zram-swap-service
Normal file
22
zram-swap-service
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# portion of real ram to use as zram swap (expression: "1/2", "0.5", etc)
|
||||
_zram_fraction="1/2"
|
||||
|
||||
# compression algorithm to employ (lzo, lz4, zstd, lzo-rle)
|
||||
_zram_algorithm="lz4"
|
||||
|
||||
# set expected compression ratio based on algorithm; this is a rough estimate
|
||||
# set this by hand if you use an algorithm other than lzo/lz4/zstd
|
||||
#_comp_factor="2.5"
|
||||
#
|
||||
# defaults:
|
||||
#case $_zram_algorithm in
|
||||
# lzo*|zstd)
|
||||
# _comp_factor="3"
|
||||
# ;;
|
||||
# lz4)
|
||||
# _comp_factor="2.5"
|
||||
# ;;
|
||||
# *)
|
||||
# _comp_factor="2"
|
||||
# ;;
|
||||
#esac
|
||||
13
zram-swap.service
Normal file
13
zram-swap.service
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=zram swap service
|
||||
Requires=systemd-modules-load.service local-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/sbin/zram-swap.sh init
|
||||
ExecStop=/usr/local/sbin/zram-swap.sh end
|
||||
RemainAfterExit=True
|
||||
|
||||
[Install]
|
||||
WantedBy=sysinit.target
|
||||
#RequiredBy=
|
||||
125
zram-swap.sh
Executable file
125
zram-swap.sh
Executable file
|
|
@ -0,0 +1,125 @@
|
|||
#!/bin/bash
|
||||
# source: https://github.com/foundObjects/zram-swap
|
||||
|
||||
[[ "$EUID" == "0" ]] || { echo "This script requires root." && exit 1; }
|
||||
set -eo pipefail
|
||||
|
||||
# parse debug flag early so we can trace everything
|
||||
[[ "$1" == "-x" ]] && { shift && set -x; } >&/dev/null
|
||||
|
||||
# set sane defaults, see /etc/default/zram-swap-service for explanations
|
||||
_zram_fraction="1/2"
|
||||
_zram_algorithm="lz4"
|
||||
_comp_factor=''
|
||||
|
||||
# load user config
|
||||
[[ -f /etc/default/zram-swap-service ]] &&
|
||||
source /etc/default/zram-swap-service
|
||||
|
||||
# set expected compression ratio based on algorithm; this is a rough estimate
|
||||
# skip if already set in user config
|
||||
if [[ -z "$_comp_factor" ]]; then
|
||||
case $_zram_algorithm in
|
||||
lzo* | zstd) _comp_factor="3" ;;
|
||||
lz4) _comp_factor="2.5" ;;
|
||||
*) _comp_factor="2" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# main script:
|
||||
_main() {
|
||||
if ! modprobe zram; then
|
||||
err "Failed to load zram module, exiting"
|
||||
return 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
# a little magic to quietly set -u after testing our last expected empty variable
|
||||
# matches every case, runs set -u without logging to the trace and then continues matching
|
||||
*) { set -u; } 2>/dev/null ;;&
|
||||
"init" | "start")
|
||||
if grep -q zram /proc/swaps; then
|
||||
err "zram swap already in use, exiting"
|
||||
return 1
|
||||
fi
|
||||
_init
|
||||
;;
|
||||
"end" | "stop")
|
||||
if ! grep -q zram /proc/swaps; then
|
||||
err "no zram swaps to cleanup, exiting"
|
||||
return 1
|
||||
fi
|
||||
_end
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 (init|end)"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# initialize swap
|
||||
_init() {
|
||||
# Calculate memory to use for zram
|
||||
totalmem=$(LC_ALL=C free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/ *.*//')
|
||||
mem=$(calc "$totalmem * $_comp_factor * $_zram_fraction * 1024")
|
||||
|
||||
# NOTE: init is a little janky; zramctl sometimes fails if we don't wait after module
|
||||
# load so retry a couple of times with slightly increasing delay before giving up
|
||||
_device=''
|
||||
for i in $(seq 3); do
|
||||
sleep "$(calc "0.1 * $i")"
|
||||
_device=$(zramctl -f -s "$mem" -a "$_zram_algorithm") || true
|
||||
[[ -b "$_device" ]] && break
|
||||
done
|
||||
|
||||
if [[ -b "$_device" ]]; then
|
||||
# cleanup the device if swap setup fails
|
||||
trap "_rem_zdev $_device" EXIT
|
||||
mkswap "$_device"
|
||||
swapon -p 5 "$_device"
|
||||
trap - EXIT
|
||||
return 0
|
||||
else
|
||||
err "Failed to initialize zram device"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# end swapping and cleanup
|
||||
_end() {
|
||||
local ret="0"
|
||||
DEVICES=$(grep zram /proc/swaps | awk '{print $1}')
|
||||
for d in $DEVICES; do
|
||||
swapoff "$d"
|
||||
if ! _rem_zdev "$d"; then
|
||||
err "Failed to remove zram device $d"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
return "$ret"
|
||||
}
|
||||
|
||||
# Remove zram device with retry
|
||||
_rem_zdev() {
|
||||
if [[ ! -b "$1" ]]; then
|
||||
err "No zram device '$1' to remove"
|
||||
return 1
|
||||
fi
|
||||
for i in $(seq 3); do
|
||||
sleep "$(calc "0.1 * $i")"
|
||||
zramctl -r "$1" || true
|
||||
[[ -b "$1" ]] || break
|
||||
done
|
||||
if [[ -b "$1" ]]; then
|
||||
err "Couldn't remove zram device '$1' after 3 attempts"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
calc() { awk "BEGIN{print $*}"; }
|
||||
#crapout() { echo "$@" >&2 && exit 1; }
|
||||
err() { echo "Err '${FUNCNAME[1]}': $*" >&2; }
|
||||
|
||||
_main "$@"
|
||||
Loading…
Add table
Add a link
Reference in a new issue