Skip to content

Commit

Permalink
Full rewrite, simplify code & config
Browse files Browse the repository at this point in the history
Signed-off-by: Timofey Titovets <[email protected]>
  • Loading branch information
nefelim4ag committed Oct 26, 2016
1 parent e8fbcf3 commit 3631514
Show file tree
Hide file tree
Showing 8 changed files with 271 additions and 432 deletions.
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
## systemd-swap
Script for manage swap on:
* zswap - Enable/Configure
* zram - Autoconfigurating
* zswap - configure
* block devices - auto find and do swapon
* files - (sparse files for saving space, support btrfs)
* vram - EXPERIMENTAL: for creating swap on video memory
* block devices - auto find and do swapon

It is configurable in /etc/systemd-swap.conf.
It is configurable in /etc/systemd/swap.conf.

## Files placed:
```
/etc/systemd-swap.conf
/etc/systemd/swap.conf
/usr/lib/systemd/system/systemd-swap.service
/usr/lib/systemd/scripts/systemd-swap.sh
/usr/bin/systemd-swap
```

## Please not forget to enable by:
Expand All @@ -34,4 +33,3 @@ $ sudo dpkg -i ././systemd-swap/systemd-swap-*any.deb
```
options zram max_devices=32
```
* For vram as swap, you need open source drivers [Arch wiki](https://wiki.archlinux.org/index.php/Swap_on_video_ram)
19 changes: 9 additions & 10 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ERRO(){ echo -n "ERRO: "; echo -n "$@" ; echo " Abort!"; exit 1;}

PREFIX="/"
case $1 in
PREFIX=*) PREFIX=$(echo $1 | cut -d'=' -f2);;
PREFIX=*) PREFIX="${PREFIX//PREFIX=/}";;
esac

cd "$(dirname $0)"
Expand All @@ -20,19 +20,18 @@ if [ "$PREFIX" == "/" ]; then
fi
fi

if [ -f /etc/systemd-swap.conf ]; then
INFO "File $PREFIX/etc/systemd-swap.conf already exists"
if cmp -s ./systemd-swap.conf $PREFIX/etc/systemd-swap.conf; then
$SUDO mkdir -p $PREFIX/etc/systemd/
if [ -f $PREFIX/etc/systemd/swap.conf ]; then
INFO "File $PREFIX/etc/systemd/swap.conf already exists"
if cmp -s ./systemd/swap.conf $PREFIX/etc/systemd/swap.conf; then
:
else
INFO "New config saved as /etc/systemd-swap.conf.new"
$SUDO install -Dm 644 ./systemd-swap.conf $PREFIX/etc/systemd-swap.conf.new
INFO "New config saved as $PREFIX/etc/systemd/swap.conf.new"
$SUDO install -Dm 644 ./swap.conf $PREFIX/etc/systemd/swap.conf.new
fi
else
$SUDO install -Dm 644 ./systemd-swap.conf $PREFIX/etc/systemd-swap.conf
$SUDO install -Dm 644 ./swap.conf $PREFIX/etc/systemd/swap.conf
fi

$SUDO install -Dm755 ./systemd-swap.sh $PREFIX/usr/lib/systemd/scripts/systemd-swap.sh
$SUDO mkdir -p $PREFIX/etc/systemd/
$SUDO ln -svf /etc/systemd-swap.conf $PREFIX/etc/systemd/swap.conf
$SUDO install -Dm755 ./systemd-swap $PREFIX/usr/bin/systemd-swap
$SUDO install -Dm644 ./systemd-swap.service $PREFIX/usr/lib/systemd/system/systemd-swap.service
45 changes: 45 additions & 0 deletions swap.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
################################################################################
# Defaults are optimized for general usage
################################################################################

################################################################################
# Zswap
#
# Kernel >= 3.11
# Zswap create compress cache between swap and memory for reduce IO
# https://www.kernel.org/doc/Documentation/vm/zswap.txt

zswap_enabled=Y
zswap_compressor=lz4
zswap_max_pool_percent=25
zswap_zpool=z3fold

################################################################################
# ZRam
#
# Kernel >= 3.15
# Zram compression streams count for additional information see:
# https://www.kernel.org/doc/Documentation/blockdev/zram.txt

zram_enabled=0
zram_size=$(($ram_size/4))K # This is 1/4 of ram size by default.
zram_streams=$cpu_count
zram_alg=lz4 # lzo lz4 deflate lz4hc 842 - for Linux 4.8.4
zram_prio=32767

################################################################################
# Swap file Universal
# loop + swapfile = support any fs (also btrfs)
swapfu_enabled=0
# File is sparse and dynamically allocated.
swapfu_size=${ram_size}K # Size of swap file.
# File will not be available in fs after script start
# Make sure what script can access to this path during the boot process.
# Full path to swapfile
swapfu_path=/var/swap
swapfu_prio=-1024

################################################################################
# Swap devices
# Find and auto swapon all available swap devices
swapd_auto_swapon=1
202 changes: 202 additions & 0 deletions systemd-swap
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
#!/bin/bash
################################################################################
# echo wrappers
INFO(){ echo -n "INFO: "; echo "$@" ;}
WARN(){ echo -n "WARN: "; echo "$@" ;}
ERRO(){ echo -n "ERRO: "; echo -n "$@" ; echo " Abort!"; exit 1;}

################################################################################
# Helpers
YN(){
case "$1" in
Yes|Y|1|true) return 0 ;;
*) return 1 ;;
esac
}

write(){
DATA="$1" FILE="$2"
[ -z "$DATA" ] && return
[ -z "$FILE" ] && return
echo "$DATA" > "$FILE"
}

help(){
echo "$0 start|stop"
}
################################################################################
# Initialization
check_root_rights(){ [ "$UID" == "0" ] || ERRO "Script must be runned as root!"; }

# get cpu count from cpuinfo
cpu_count=$(nproc)
# get total ram size for meminfo
ram_size=$(awk '/MemTotal:/ { print $2 }' /proc/meminfo)

WORK_DIR=/run/systemd/swap
TMPDIR=$WORK_DIR
CONF=/etc/systemd/swap.conf
B_CONF=$WORK_DIR/swap.conf

case "$1" in
start)
INFO "Check config"
[ ! -f $CONF ] && ERRO "Missing config: /etc/systemd/swap.conf - try reinstall package"
check_root_rights
mkdir -p $WORK_DIR
[ -f $B_CONF ] && ERRO "systemd-swap already started!"
INFO "Backup config"
cp $CONF $B_CONF
INFO "Load config"
. $B_CONF

if YN $zswap_enabled; then
[ ! -d /sys/module/zswap ] && ERRO "Zswap - not supported on current kernel"
ZSWAP_P=/sys/module/zswap/parameters/
INFO "Zswap: backup current configuration: start"
mkdir -p $WORK_DIR/zswap/
for file in $ZSWAP_P/*; do
cp $file $WORK_DIR/zswap/$(basename $file)
done
INFO "Zswap: backup current configuration: complete"
INFO "Zswap: set new parameters: start"
write $zswap_enabled $ZSWAP_P/enabled
write $zswap_compressor $ZSWAP_P/compressor
write $zswap_max_pool_percent $ZSWAP_P/max_pool_percent
write $zswap_zpool $ZSWAP_P/zpool
INFO "Zswap: set new parameters: complete"
fi

if YN $zram_enabled; then
[ -z "$zram_size" ] && zram_size=$((ram_size/4))K
zram_streams=${zram_streams:-$cpu_count}
zram_alg=${zram_alg:-"lz4"}
zram_prio=${zram_prio:-"32767"}
zram_dev=""
INFO "Zram: check availability"
if [ ! -d /sys/module/zram ]; then
INFO "Zram: not part of kernel, so try find zram module"
modprobe -n zram || ERRO "Zram: can't find zram module!"
# Wrapper, for handling zram initialization problems
for (( i = 0; i < 10; i++ )); do
if [ ! -d /sys/module/zram ]; then
modprobe zram
sleep 1
fi
done
INFO "Zram: module a successful loaded"
fi
INFO "Zram: module already loaded"
for (( i = 0; i < 10; i++ )); do
INFO "Zram: try initialize free device"
# zramctl is a external program -> return name of first free device
TMP=$(mktemp)
zramctl -f -a $zram_alg -t $zram_streams -s $zram_size &> $TMP
read -r OUTPUT < $TMP
rm $TMP
case "$OUTPUT" in
*"failed to reset: Device or resource busy"*) sleep 1 ;;
*"zramctl: no free zram device found"*)
WARN "Zram: zramctl can't find free device"
INFO "Zram: use workaround hook for hot add"
[ ! -f /sys/class/zram-control/hot_add ] && \
ERRO "Zram: this kernel not support hot add zram device, please use 4.2+ kernels or see modinfo zram and make modprobe rule"
NEW_ZRAM=$(cat /sys/class/zram-control/hot_add)
INFO "Zram: success: new device /dev/zram$NEW_ZRAM"
;;
/dev/zram*)
[ -b "$OUTPUT" ] || continue
zram_dev="$OUTPUT"
break
;;
esac
done
INFO "Zram: initialized: $zram_dev"
mkdir -p $WORK_DIR/zram/
mkswap "$zram_dev" &> /dev/null && \
swapon -d -p $zram_prio "$zram_dev" && \
ln -s $zram_dev $WORK_DIR/zram/
fi

if YN $swapf_enabled; then
swapf_size=${swapf_size:-"${ram_size}K"}
swapf_path=${swapf_path:-"/var/swap"}
swapf_prio=${swapf_prio:-"-1024"}
truncate -s $swapf_size $swapf_path
INFO "swapF: search free loop"
swapf_loop=$(losetup -f --show $swapf_path)
INFO "swapF: use $swapf_loop"
# loop use file descriptor, file still exist, but no have path
# When loop deatach file, file will be deleted.
rm $swapf_path
mkswap $swapf_loop &> /dev/null
swapon -p $swapf_prio -d $swapf_loop
# set autoclear flag
losetup -d $swapf_loop
mkdir -p $WORK_DIR/swapf
ln -s $swapf_loop $WORK_DIR/swapf/
fi

if YN $swapd_auto_swapon; then
INFO "swapD: search swap devices"
mkdir -p $WORK_DIR/swapd/
for device in $(blkid -t TYPE=swap -o device | grep -vE '(zram|loop)'); do
for used_device in $(swapon --show=NAME --noheadings); do
[ "$device" == "$used_device" ] && unset device
done
[ ! -b "$device" ] && continue
swapon -d $device &> /dev/null && \
ln -s $device $WORK_DIR/swapd/ && \
INFO "swapD: enable device: $device"
done
fi
;;
stop)
check_root_rights
[ ! -f $B_CONF ] && ERRO "systemd-swap not started!"
INFO "Load config"
. $B_CONF
if YN $zswap_enabled; then
[ ! -d /sys/module/zswap ] && ERRO "Zswap - not supported on current kernel"
ZSWAP_P=/sys/module/zswap/parameters/
INFO "Zswap: restore configuration: start"
mkdir -p $WORK_DIR/zswap/
for file in $WORK_DIR/zswap/*; do
cp $file $ZSWAP_P/$(basename $file)
done
INFO "Zswap: restore configuration: complete"
fi

if YN $zram_enabled; then
for zram in $WORK_DIR/zram/*; do
[ ! -b $zram ] && continue
INFO "Zram: remove: /dev/$(basename $zram)"
swapoff $zram && \
zramctl -r $(basename $zram) && \
rm $zram && \
INFO "Zram: removed: /dev/$(basename $zram)"
done
fi

if YN $swapf_enabled; then
for device in $WORK_DIR/swapf/*; do
[ ! -b "$device" ] && continue
swapoff $device && \
rm $device && \
INFO "swapF: stopped /dev/$(basename $device)"
done
fi

if YN $swapd_auto_swapon; then
for device in $WORK_DIR/swapd/*; do
[ ! -b "$device" ] && continue
swapoff $device && \
rm $device && \
INFO "swapD: disable device: $device"
done
fi
[ -d $WORK_DIR ] && rm -rf $WORK_DIR
;;

*) help ;;
esac
84 changes: 0 additions & 84 deletions systemd-swap.conf

This file was deleted.

Loading

0 comments on commit 3631514

Please sign in to comment.