1
0
mirror of https://github.com/home-assistant/operating-system.git synced 2026-05-03 23:18:02 +01:00
Files
operating-system/buildroot-external/rootfs-overlay/usr/libexec/haos-swapfile
Jan Čermák 57445099f7 Allow for fluctuation of MemTotal for automatic swapfile size (#4016)
As the reported MemTotal can fluctuate a bit on some systems, e.g. because the
reserved memory changes between kernel version or other factors affect it like
VRAM, the swap file can be recreated unnecessarily between boots. Allow for
some fluctuation (up to +-32MB) before the swapfile is recreated.

This was a problem already before the recent haos-swapfile changes, however,
before it checked if the existing swapfile isn't smaller than the desired
value. If the MemTotal fluctuated there, the swapfile size eventually settled
on the highest value seen and it wasn't recreated anymore. With this change,
things should be stable even more.
2025-04-10 17:18:07 +02:00

67 lines
2.1 KiB
Bash
Executable File

#!/bin/sh
set -e
size2kilobytes() {
bytes="$(echo "$1" | awk \
'BEGIN{IGNORECASE = 1}
function tobytes(n,b,p) {printf "%u\n", n*b^p/1024}
/[0-9]B?$/{tobytes($1, 1, 0); next};
/K(i?B)?$/{tobytes($1, 2, 10); next};
/M(i?B)?$/{tobytes($1, 2, 20); next};
/G(i?B)?$/{tobytes($1, 2, 30); next};
{print -1}')"
echo "$bytes"
}
if [ -f /etc/default/haos-swapfile ]; then
# shellcheck disable=SC1091
. /etc/default/haos-swapfile
fi
SWAPFILE="/mnt/data/swapfile"
# Swap size in kilobytes (as it's also what meminfo shows)
SWAPSIZE="$(size2kilobytes "${SWAPSIZE}")"
SWAPSIZE_TOLERANCE=0
if [ -z "${SWAPSIZE}" ] || [ "${SWAPSIZE}" = "-1" ]; then
# Default to 33% of total memory
SWAPSIZE="$(awk '/MemTotal/{ print int($2 * 0.33) }' /proc/meminfo)"
echo "[INFO] Using default swapsize of 33% RAM (${SWAPSIZE} kB)"
SWAPSIZE_TOLERANCE=$((32*1024)) # allow for 32MB fluctuations
fi
# Swap space in 4k blocks
SWAPSIZE_BLOCKS=$((SWAPSIZE / 4))
if [ "${SWAPSIZE_BLOCKS}" -lt 10 ]; then
echo "[INFO] Requested swap size smaller than 40kB, disabling swap"
if [ -f "${SWAPFILE}" ]; then
echo "[INFO] Removing existing swapfile"
rm -f "${SWAPFILE}"
fi
exit 0
fi
CURRENT_SIZE="$([ -f "${SWAPFILE}" ] && stat "${SWAPFILE}" -c '%s' || echo 0)"
if [ -s "${SWAPFILE}" ] && [ "${CURRENT_SIZE}" -ge $(((SWAPSIZE - SWAPSIZE_TOLERANCE) * 1024)) ] \
&& [ "${CURRENT_SIZE}" -le $(((SWAPSIZE + SWAPSIZE_TOLERANCE) * 1024)) ]; then
echo "[INFO] Swapfile already exists with size ${CURRENT_SIZE} bytes"
elif [ ! -s "${SWAPFILE}" ] || [ "${CURRENT_SIZE}" -ne $((SWAPSIZE_BLOCKS * 4096)) ]; then
# Check free space (in 4k blocks)
if [ "$(stat -f /mnt/data -c '%f')" -lt "${SWAPSIZE_BLOCKS}" ]; then
echo "[ERROR] Not enough space to allocate swapfile"
exit 1
fi
echo "[INFO] Creating swapfile of size ${SWAPSIZE} kB (rounded to ${SWAPSIZE_BLOCKS} blocks)"
umask 0077
dd if=/dev/zero of="${SWAPFILE}" bs=4k count="${SWAPSIZE_BLOCKS}"
fi
if ! swaplabel "${SWAPFILE}" > /dev/null 2>&1; then
/usr/lib/systemd/systemd-makefs swap "${SWAPFILE}"
fi