openwrt/package/system/zram-swap/files/zram.init
Rui Salvaterra 90853439a1 zram-swap: explicitly use mkswap/swapon/swapoff from /sbin
The required BusyBox applets are enabled by default, so we can rely on them
being present in the system. This way, we make sure there are no conflicts
with less featured variants of these same applets which might also be
present in the system.

Fixes: 0bd7dfa3ed ("zram-swap: enable swap discard")

Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
[wrap commit description]
Signed-off-by: David Bauer <mail@david-bauer.net>
2020-09-20 17:52:25 +02:00

219 lines
6.2 KiB
Bash
Executable File

#!/bin/sh /etc/rc.common
START=15
EXTRA_COMMANDS="compact status"
EXTRA_HELP=" compact trigger compaction for all Z-RAM swap dev's
status print out status information & statistics about Z-RAM swap devices"
ram_getsize()
{
local line
while read line; do case "$line" in MemTotal:*) set $line; echo "$2"; break ;; esac; done </proc/meminfo
}
zram_getsize() # in megabytes
{
local zram_size="$( uci -q get system.@system[0].zram_size_mb )"
local ram_size="$( ram_getsize )"
if [ -z "$zram_size" ]; then
# e.g. 6mb for 16mb-routers or 61mb for 128mb-routers
echo $(( ram_size / 2048 ))
else
echo "$zram_size"
fi
}
zram_applicable()
{
local zram_dev="$1"
[ -e "$zram_dev" ] || {
logger -s -t zram_applicable -p daemon.crit "[ERROR] device '$zram_dev' not found"
return 1
}
[ -x /sbin/mkswap ] || {
logger -s -t zram_applicable -p daemon.err "[ERROR] 'BusyBox mkswap' not installed"
return 1
}
[ -x /sbin/swapon ] || {
logger -s -t zram_applicable -p daemon.err "[ERROR] 'BusyBox swapon' not installed"
return 1
}
[ -x /sbin/swapoff ] || {
logger -s -t zram_applicable -p daemon.err "[ERROR] 'BusyBox swapoff' not installed"
return 1
}
}
zram_dev()
{
local idx="$1"
echo "/dev/zram${idx:-0}"
}
zram_reset()
{
local dev="$1"
local message="$2"
local proc_entry="/sys/block/$( basename "$dev" )/reset"
logger -s -t zram_reset -p daemon.debug "$message via $proc_entry"
echo "1" >"$proc_entry"
}
zram_getdev()
{
#get unallocated zram dev
local zdev=$( zram_dev )
if [ "$(mount | grep $zdev)" ]; then
local idx=$(cat /sys/class/zram-control/hot_add)
zdev="$( zram_dev $idx )"
fi
echo $zdev
}
zram_comp_algo()
{
local dev="$1"
local zram_comp_algo="$( uci -q get system.@system[0].zram_comp_algo )"
if [ -z "$zram_comp_algo" ]; then
# lzo-rle fails on small RAM devices, default to lzo, which is always available
zram_comp_algo="lzo"
fi
if [ $(grep -c "$zram_comp_algo" /sys/block/$( basename $dev )/comp_algorithm) -ne 0 ]; then
logger -s -t zram_comp_algo -p daemon.debug "Set compression algorithm '$zram_comp_algo' for zram '$dev'"
echo $zram_comp_algo > "/sys/block/$( basename $dev )/comp_algorithm"
else
logger -s -t zram_comp_algo -p daemon.debug "Compression algorithm '$zram_comp_algo' is not supported for '$dev'"
fi
}
zram_comp_streams()
{
local dev="$1"
local logical_cpus=$( grep -ci "^processor" /proc/cpuinfo )
[ $logical_cpus -gt 1 ] || return 1
local zram_comp_streams="$( uci -q get system.@system[0].zram_comp_streams )"
[ -n "$zram_comp_streams" ] && [ "$zram_comp_streams" -le "$logical_cpus" ] || zram_comp_streams=$logical_cpus
if [ -e /sys/block/$( basename $dev )/max_comp_streams ]; then
logger -s -t zram_comp_streams -p daemon.debug "Set max compression streams to '$zram_comp_streams' for zram '$dev'"
echo $zram_comp_streams > /sys/block/$( basename $dev )/max_comp_streams
fi
}
#print various stats info about zram swap device
zram_stats()
{
local zdev="/sys/block/$( basename "$1" )"
printf "\nGathering stats info for zram device \"$( basename "$1" )\"\n\n"
printf "Z-RAM\n-----\n"
printf "%-25s - %s\n" "Block device" $zdev
awk '{ printf "%-25s - %d MiB\n", "Device size", $1/1024/1024 }' <$zdev/disksize
printf "%-25s - %s\n" "Compression algo" "$(cat $zdev/comp_algorithm)"
printf "%-25s - %s\n" "Compression streams" "$( cat $zdev/max_comp_streams)"
awk 'BEGIN { fmt = "%-25s - %.2f %s\n"
fmt2 = "%-25s - %d\n"
print "\nDATA\n----" }
{ printf fmt, "Original data size", $1/1024/1024, "MiB"
printf fmt, "Compressed data size", $2/1024/1024, "MiB"
printf fmt, "Compress ratio", $1/$2, ""
print "\nMEMORY\n------"
printf fmt, "Memory used, total", $3/1024/1024, "MiB"
printf fmt, "Allocator overhead", ($3-$2)/1024/1024, "MiB"
printf fmt, "Allocator efficiency", $2/$3*100, "%"
printf fmt, "Maximum memory ever used", $5/1024/1024, "MiB"
printf fmt, "Memory limit", $4/1024/1024, "MiB"
print "\nPAGES\n-----"
printf fmt2, "Same pages count", $6
printf fmt2, "Pages compacted", $7 }' <$zdev/mm_stat
awk '{ printf "%-25s - %d\n", "Free pages discarded", $4 }' <$zdev/io_stat
}
zram_compact()
{
# compact zram device (reduce memory allocation overhead)
local zdev="/sys/block/$( basename "$1" )"
local old_mem_used=$(awk '{print $3}' <$zdev/mm_stat)
local old_overhead=$(awk '{print $3-$2}' <$zdev/mm_stat)
echo 1 > $zdev/compact
# If not running interactively, than just return
[ -z "$PS1" ] && return 0
echo ""
echo "Compacting zram device $zdev"
awk -v old_mem="$old_mem_used" -v ovr="$old_overhead" 'BEGIN { fmt = "%-25s - %.1f %s\n" }
{ printf fmt, "Memory usage reduced by ", (old_mem-$3)/1024/1024, "MiB"
printf fmt, "Overhead reduced by", (ovr-($3-$2))/ovr*100, "%" }' <$zdev/mm_stat
}
start()
{
if [ $( grep -cs zram /proc/swaps ) -ne 0 ]; then
logger -s -t zram_start -p daemon.notice "[OK] zram swap is already mounted"
return 1
fi
local zram_size="$( zram_getsize )"
local zram_dev="$( zram_getdev )"
zram_applicable "$zram_dev" || return 1
local zram_priority="$( uci -q get system.@system[0].zram_priority )"
zram_priority=${zram_priority:+-p $zram_priority}
logger -s -t zram_start -p daemon.debug "activating '$zram_dev' for swapping ($zram_size MegaBytes)"
zram_reset "$zram_dev" "enforcing defaults"
zram_comp_algo "$zram_dev"
zram_comp_streams "$zram_dev"
echo $(( $zram_size * 1024 * 1024 )) >"/sys/block/$( basename "$zram_dev" )/disksize"
/sbin/mkswap "$zram_dev"
/sbin/swapon -d $zram_priority "$zram_dev"
}
stop()
{
local zram_dev
for zram_dev in $( grep zram /proc/swaps |awk '{print $1}' ); do {
logger -s -t zram_stop -p daemon.debug "deactivate swap $zram_dev"
/sbin/swapoff "$zram_dev" && zram_reset "$zram_dev" "claiming memory back"
local dev_index="$( echo $zram_dev | grep -o "[0-9]*$" )"
if [ $dev_index -ne 0 ]; then
logger -s -t zram_stop -p daemon.debug "removing zram $zram_dev"
echo $dev_index > /sys/class/zram-control/hot_remove
fi
} done
}
# show memory stats for all zram swaps
status()
{
for zram_dev in $( grep zram /proc/swaps |awk '{print $1}' ); do {
zram_stats "$zram_dev"
} done
}
# trigger compaction for all zram swaps
compact()
{
for zram_dev in $( grep zram /proc/swaps |awk '{print $1}' ); do {
zram_compact "$zram_dev"
} done
}