Created
March 24, 2018 00:34
-
-
Save Trucido/7259d8f0f876fdb2e5512c7589fabeb0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# /etc/init.d/zswap || zswap.service || /usr/local/sbin/zswap || somethingsomething | |
# | |
### BEGIN INIT INFO | |
# Provides: zswap | |
# Required-Start: | |
# Required-Stop: | |
# Default-Start: 2 3 4 5 | |
# Default-Stop: 0 1 6 | |
# Short-Description: Zswap | |
# Description: Activate and tune Zswap compressed cache for swap pages | |
### END INIT INFO | |
# TODO: Optimize module detection instead of this utterly ridiculous trying to fail until we succeed strategy. | |
# TODO: Merge main init script with swap detection logic. | |
# : Also Merge Zram activation and optimization script -- use zram::foo() for zram stuff. | |
# TODO: Log to syslog or somewhere instead of nullifying output. | |
# : Any stdout breaks some init/startup scripts when called directly. | |
# TODO: Make this an actual lsb compliant service? Also test if works with systemd-sysv-generator | |
# TODO: More tunables. Compressor/Zpool/max_pool_percent etc. (external config file? upstart env style? or extra args?) | |
# Set upstart job for compatibility. | |
# Also useful to `logger -t "${JOB}" "foo"` | |
#JOB="ZSWAP" ##TODO | |
# Tunables | |
# max_pool_percent | |
[ -z "$ZSWAP_SIZE" ] && ZSWAP_SIZE="" | |
zswap::set_params() { | |
# Set zswap sysfs params | |
local max_pool_size | |
max_pool_size="${ZSWAP_SIZE}" | |
# TODO: add case for compressor, zpool, and max_pool_percent | |
# TODO: possibly add zswap_size_mb param with mb to percent math? | |
# Set Compressor | |
if [ -e "/sys/module/zswap/parameters/compressor" ]; then | |
# Try lz4 | |
if ! echo lz4 > "/sys/module/zswap/parameters/compressor"; then | |
# Fallback: lzo | |
echo lzo > "/sys/module/zswap/parameters/compressor" || : | |
fi | |
fi | |
# Set Zpool | |
if [ -e "/sys/module/zswap/parameters/zpool" ]; then | |
# Try z3fold | |
if ! echo z3fold > "/sys/module/zswap/parameters/zpool"; then | |
# Fallback: zbud | |
echo zbud > "/sys/module/zswap/parameters/zpool" || : | |
fi | |
fi | |
# Set max_pool_percent | |
if [ -e "/sys/module/zswap/parameters/max_pool_percent" ]; then | |
# Try $ZSWAP_SIZE if set | |
if [ ! -z "$max_pool_size" ]; then | |
if echo "$max_pool_size" > "/sys/module/zswap/parameters/max_pool_percent"; then | |
return | |
else | |
# Fallback: Default 20% | |
echo 20 > "/sys/module/zswap/parameters/max_pool_percent" || : | |
fi | |
fi | |
else | |
# Fallback: Default 20% if $ZSWAP_SIZE unset | |
echo 20 > "/sys/module/zswap/parameters/max_pool_percent" || : | |
fi | |
} | |
zswap::load_depmods() { | |
# Load optimal compressor and zpool modules if available and not already loaded | |
# Modprobe $COMPRESSOR | |
# Try lz4 | |
if ! grep -qE 'lz4|lz4_compress' "/proc/modules" || [ ! -e "/sys/module/lz4" ]; then | |
modprobe -q lz4 || : | |
fi | |
# Modprobe $ZPOOL | |
# Try z3fold | |
if ! grep -q "^z3fold " "/proc/modules" || [ ! -e "/sys/module/z3fold" ]; then | |
if modprobe -q z3fold 2>/dev/null; then | |
return | |
elif ! grep -q "^zbud " "/proc/modules" || [ ! -e "/sys/module/zbud" ]; then | |
if modprobe -q zbud 2>/dev/null; then | |
return | |
fi | |
fi | |
# Fallback: zbud | |
elif ! grep -q "^zbud " "/proc/modules" || [ ! -e "/sys/module/zbud" ]; then | |
modprobe -q zbud || : | |
fi | |
} | |
zswap::load_module() { | |
# Try and modprobe zswap with optimal zpool/compressor. | |
if ! grep -q "^zswap " "/proc/modules" || [ ! -e "/sys/module/zswap" ]; then | |
# Try z3fold/lz4 | |
if modprobe -q zswap zpool=z3fold compressor=lz4 enabled=Y 2>/dev/null; then | |
return | |
# Try zbud/lz4 | |
elif modprobe -q zswap zpool=zbud compressor=lz4 enabled=Y 2>/dev/null; then | |
return | |
# Try z3fold/lzo | |
elif modprobe -q zswap zpool=z3fold compressor=lzo enabled=Y 2>/dev/null; then | |
return | |
else | |
# Fallback: Default zbud/lzo | |
modprobe -q zswap zpool=zbud compressor=lzo enabled=Y 2>/dev/null || : | |
fi | |
fi | |
} | |
#zswap::start() | |
start() { | |
# Load or Reload Zswap modules. | |
if grep -q "^zswap " "/proc/modules" ; then | |
# Deactivate zswap module if loaded | |
if [ -e "/sys/module/zswap/parameters/enabled" ]; then | |
echo N > "/sys/module/zswap/parameters/enabled" || : | |
fi | |
# Remove zswap module before full reset | |
modprobe -rq zswap >/dev/null 2>&1 || :; | |
# Modprobe optimal compressor/zpool modules if available | |
zswap::load_depmods >/dev/null 2>&1 || :; | |
# Modprobe zswap with best available compressor/zpool | |
zswap::load_mod >/dev/null 2>&1 || : | |
elif [ -e /sys/module/zswap ]; then | |
# Else builtin? Then load any missing modules for optimal params | |
zswap::load_depmods >/dev/null 2>&1 || : | |
fi | |
# Reset Zswap state and tune params | |
if [ -e "/sys/module/zswap/parameters/enabled" ]; then | |
# Deactivate zswap | |
echo N > "/sys/module/zswap/parameters/enabled" || :; | |
# Set zswap sysfs parameters | |
zswap::set_params >/dev/null 2>&1 || :; | |
# Activate zswap | |
echo Y > "/sys/module/zswap/parameters/enabled" || : | |
fi | |
} | |
#zswap::stop() | |
stop() { | |
return | |
# Not really necessary to stop... but we could do: | |
#echo N > "/sys/module/zswap/parameters/enabled" | |
#local tries=0 | |
#while [ ${tries} -le 6 ]; do | |
# modprobe -rq zswap 2>/dev/null && break | |
# : $(( tries += 1 )) | |
# sleep 0.5 | |
#done | |
} | |
#zswap::status() | |
status() { | |
# Show general swap info first. | |
printf '\nswap block device(s):\n' | |
cat /proc/swaps | |
# Check if dir exists before we spam | |
local ddir="/sys/kernel/debug/zswap" | |
local mdir="/sys/module/zswap/parameters" | |
if [ ! -e "${mdir}" ] && [ ! -e "${ddir}" ]; then | |
printf "\nZswap module not loaded.\n" | |
return | |
else | |
# Spam various zswap settings. | |
# Spam Zswap module parameters | |
if [ -d "${mdir}" ]; then | |
printf '\nZswap parameters in %s:\n' "${mdir}" | |
cd "${mdir}" || return 1 | |
# shellcheck disable=SC2035 | |
grep -s '^' * || : | |
fi | |
# Spam Zswap debug stats | |
if [ -d "${ddir}" ]; then | |
printf '\nZswap debug stats in %s:\n' "${ddir}" | |
cd "${ddir}" || return 1 | |
# shellcheck disable=SC2035 | |
grep -s '^' * || : | |
fi | |
fi | |
} | |
#zswap::usage() | |
usage() { | |
cat <<EOF | |
Usage: $0 <start|stop|status> | |
Start, stop, or show the status of compressed swap cache. | |
EOF | |
exit "$1" | |
} | |
## MAIN ## | |
# TODO: set correct exit status after testing. For now return/exit 0. | |
main() { | |
set -e | |
# If we're called without any argument, just run it by default. #TODO | |
if [ $# -lt 1 ]; then | |
# Nullify any chatter (hopefully). | |
start >/dev/null 2>&1 || : | |
elif [ $# -gt 1 ]; then | |
usage 0 | |
else | |
# If given argument, ensure it's one we can handle. | |
local cmd="$1" | |
shift | |
case "${cmd}" in | |
start|stop|status) | |
if [ $# -ne 0 ]; then | |
usage 0 | |
fi | |
start >/dev/null 2>&1 || : | |
;; | |
*) | |
usage 0 | |
;; | |
esac | |
# Just call the func directly if valid. | |
${cmd} "$@" | |
fi | |
} | |
#logger -t "${JOB}" "Starting Zswap compressed swap cache" | |
main "$@" || : |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment