99 lines
3.2 KiB
Bash
Executable File
99 lines
3.2 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# swapon — create, enable and persist an 8GB swap file.
|
|
#
|
|
# Runs on each managed server (Alpine/OpenRC). Deploy with ./update_sbin, then:
|
|
#
|
|
# rex doas /4server/sbin/swapon
|
|
#
|
|
# The script aborts if any swap is already active or if /swapfile already
|
|
# exists, so it is safe to run against the whole fleet.
|
|
#
|
|
# Optional first argument: swap size in MiB (default 8192 = 8GB).
|
|
|
|
set -euo pipefail
|
|
|
|
SWAPFILE="/swapfile"
|
|
SWAP_SIZE_MB="${1:-8192}"
|
|
FSTAB="/etc/fstab"
|
|
|
|
log() {
|
|
echo "[$(hostname)] $*"
|
|
}
|
|
|
|
die() {
|
|
echo "[$(hostname)] ERROR: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
case "$SWAP_SIZE_MB" in
|
|
''|*[!0-9]*) die "swap size must be a positive integer in MiB" ;;
|
|
esac
|
|
[ "$SWAP_SIZE_MB" -gt 0 ] || die "swap size must be greater than zero"
|
|
|
|
# Remove a partially created swap file if anything fails before it is enabled.
|
|
CREATED=0
|
|
cleanup() {
|
|
[ "$CREATED" -eq 1 ] || return 0
|
|
[ -e "$SWAPFILE" ] || return 0
|
|
if grep -q "^${SWAPFILE}[[:space:]]" /proc/swaps; then
|
|
return 0
|
|
fi
|
|
log "removing incomplete ${SWAPFILE}"
|
|
rm -f "$SWAPFILE"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# --- must run as root ---------------------------------------------------
|
|
[ "$(id -u)" -eq 0 ] || die "must be run as root (use: rex doas /4server/sbin/swapon)"
|
|
|
|
# --- abort if swap is already active ------------------------------------
|
|
# /proc/swaps always has a header line; anything more means swap is in use.
|
|
if [ "$(wc -l < /proc/swaps)" -gt 1 ]; then
|
|
echo "[$(hostname)] ERROR: swap is already active:" >&2
|
|
cat /proc/swaps >&2
|
|
exit 1
|
|
fi
|
|
|
|
# --- abort if the swap file already exists ------------------------------
|
|
if [ -e "$SWAPFILE" ]; then
|
|
die "$SWAPFILE already exists; remove it manually before recreating swap"
|
|
fi
|
|
|
|
# --- persistence requires OpenRC's swap service --------------------------
|
|
[ -x /etc/init.d/swap ] || \
|
|
die "/etc/init.d/swap not found; cannot persist swap across reboots"
|
|
|
|
# --- make sure there is enough room on / ---------------------------------
|
|
AVAIL_KB=$(df -Pk / | awk 'NR==2 {print $4}')
|
|
# Leave a 100MiB margin for filesystem metadata.
|
|
REQUIRED_KB=$((SWAP_SIZE_MB * 1024 + 102400))
|
|
[ "$AVAIL_KB" -ge "$REQUIRED_KB" ] || \
|
|
die "not enough free space on / (need ${SWAP_SIZE_MB}MiB, have $((AVAIL_KB / 1024))MiB)"
|
|
|
|
# --- create the swap file -----------------------------------------------
|
|
log "creating ${SWAP_SIZE_MB}MiB swap file at ${SWAPFILE}"
|
|
CREATED=1
|
|
dd if=/dev/zero of="$SWAPFILE" bs=1M count="$SWAP_SIZE_MB"
|
|
chmod 600 "$SWAPFILE"
|
|
/sbin/mkswap "$SWAPFILE"
|
|
|
|
# --- persist across reboots ---------------------------------------------
|
|
# OpenRC's swap service runs `swapon -a`, which reads /etc/fstab.
|
|
if ! grep -qE "^[[:space:]]*${SWAPFILE}[[:space:]]" "$FSTAB"; then
|
|
# Terminate the last line first in case fstab has no trailing newline.
|
|
[ -z "$(tail -c 1 "$FSTAB")" ] || echo >> "$FSTAB"
|
|
echo "${SWAPFILE} none swap sw 0 0" >> "$FSTAB"
|
|
log "added ${SWAPFILE} to ${FSTAB}"
|
|
fi
|
|
|
|
rc-update add swap boot >/dev/null 2>&1 || \
|
|
die "could not add the swap service to the boot runlevel"
|
|
|
|
# --- enable it now -------------------------------------------------------
|
|
# Absolute path avoids recursing into this script if /4server/sbin is on PATH.
|
|
/sbin/swapon "$SWAPFILE"
|
|
|
|
log "swap enabled:"
|
|
cat /proc/swaps
|