OneWheelGeek revised this gist 1 month ago. Go to revision
1 file changed, 117 insertions
swapon.sh(file created)
| @@ -0,0 +1,117 @@ | |||
| 1 | + | #!/usr/bin/env bash | |
| 2 | + | set -euo pipefail | |
| 3 | + | ||
| 4 | + | SWAPFILE="/swapfile" | |
| 5 | + | FSTAB="/etc/fstab" | |
| 6 | + | ||
| 7 | + | die() { | |
| 8 | + | echo "ERROR: $*" >&2 | |
| 9 | + | exit 1 | |
| 10 | + | } | |
| 11 | + | ||
| 12 | + | need_cmd() { | |
| 13 | + | command -v "$1" >/dev/null 2>&1 || die "Required command not found: $1" | |
| 14 | + | } | |
| 15 | + | ||
| 16 | + | # Must be root | |
| 17 | + | if [[ "${EUID}" -ne 0 ]]; then | |
| 18 | + | die "Run this script as root (e.g. sudo bash script.sh)" | |
| 19 | + | fi | |
| 20 | + | ||
| 21 | + | need_cmd awk | |
| 22 | + | need_cmd grep | |
| 23 | + | need_cmd chmod | |
| 24 | + | need_cmd mkswap | |
| 25 | + | need_cmd swapon | |
| 26 | + | need_cmd free | |
| 27 | + | ||
| 28 | + | # Refuse if any swap is already active | |
| 29 | + | if swapon --noheadings --show | grep -q .; then | |
| 30 | + | echo "Swap is already active:" | |
| 31 | + | swapon --show | |
| 32 | + | die "Refusing to continue." | |
| 33 | + | fi | |
| 34 | + | ||
| 35 | + | # Refuse if fstab already has any non-comment swap entry | |
| 36 | + | if awk ' | |
| 37 | + | $0 !~ /^[[:space:]]*#/ && NF >= 3 && $3 == "swap" { found=1 } | |
| 38 | + | END { exit(found ? 0 : 1) } | |
| 39 | + | ' "$FSTAB"; then | |
| 40 | + | echo "Existing swap entry found in $FSTAB:" | |
| 41 | + | awk '$0 !~ /^[[:space:]]*#/ && NF >= 3 && $3 == "swap"' "$FSTAB" | |
| 42 | + | die "Refusing to continue." | |
| 43 | + | fi | |
| 44 | + | ||
| 45 | + | # Refuse if /swapfile already exists | |
| 46 | + | if [[ -e "$SWAPFILE" ]]; then | |
| 47 | + | die "$SWAPFILE already exists. Refusing to continue." | |
| 48 | + | fi | |
| 49 | + | ||
| 50 | + | # Read RAM from /proc/meminfo (kB) | |
| 51 | + | mem_kb="$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)" | |
| 52 | + | [[ -n "$mem_kb" ]] || die "Could not determine system RAM." | |
| 53 | + | ||
| 54 | + | mem_mb=$((mem_kb / 1024)) | |
| 55 | + | mem_gb=$(((mem_mb + 1023) / 1024)) # rounded up | |
| 56 | + | ||
| 57 | + | # Sizing policy: | |
| 58 | + | # <=2GB => 2x RAM | |
| 59 | + | # <=8GB => 1x RAM | |
| 60 | + | # <=64GB => 0.5x RAM | |
| 61 | + | # >64GB => 8GB cap | |
| 62 | + | if (( mem_mb <= 2048 )); then | |
| 63 | + | swap_mb=$((mem_mb * 2)) | |
| 64 | + | elif (( mem_mb <= 8192 )); then | |
| 65 | + | swap_mb=$mem_mb | |
| 66 | + | elif (( mem_mb <= 65536 )); then | |
| 67 | + | swap_mb=$((mem_mb / 2)) | |
| 68 | + | else | |
| 69 | + | swap_mb=8192 | |
| 70 | + | fi | |
| 71 | + | ||
| 72 | + | # Minimum 1GB | |
| 73 | + | if (( swap_mb < 1024 )); then | |
| 74 | + | swap_mb=1024 | |
| 75 | + | fi | |
| 76 | + | ||
| 77 | + | echo "Detected RAM: ${mem_mb} MB (~${mem_gb} GB)" | |
| 78 | + | echo "Will create swap: ${swap_mb} MB (~$(((swap_mb + 1023) / 1024)) GB)" | |
| 79 | + | echo | |
| 80 | + | ||
| 81 | + | # Ensure there is enough free disk space on / | |
| 82 | + | avail_kb="$(df --output=avail / | tail -n1 | tr -d ' ')" | |
| 83 | + | need_kb=$((swap_mb * 1024)) | |
| 84 | + | if (( avail_kb < need_kb + 262144 )); then | |
| 85 | + | die "Not enough free disk space on /. Need about ${swap_mb} MB plus some headroom." | |
| 86 | + | fi | |
| 87 | + | ||
| 88 | + | # Create swapfile | |
| 89 | + | if command -v fallocate >/dev/null 2>&1; then | |
| 90 | + | fallocate -l "${swap_mb}M" "$SWAPFILE" || { | |
| 91 | + | echo "fallocate failed, falling back to dd..." | |
| 92 | + | dd if=/dev/zero of="$SWAPFILE" bs=1M count="$swap_mb" status=progress | |
| 93 | + | } | |
| 94 | + | else | |
| 95 | + | dd if=/dev/zero of="$SWAPFILE" bs=1M count="$swap_mb" status=progress | |
| 96 | + | fi | |
| 97 | + | ||
| 98 | + | chmod 600 "$SWAPFILE" | |
| 99 | + | mkswap "$SWAPFILE" | |
| 100 | + | swapon "$SWAPFILE" | |
| 101 | + | ||
| 102 | + | # Backup fstab before editing | |
| 103 | + | cp "$FSTAB" "${FSTAB}.bak.$(date +%Y%m%d%H%M%S)" | |
| 104 | + | ||
| 105 | + | echo "$SWAPFILE none swap sw 0 0" >> "$FSTAB" | |
| 106 | + | ||
| 107 | + | echo | |
| 108 | + | echo "Swap successfully created and enabled." | |
| 109 | + | echo | |
| 110 | + | echo "Current memory/swap:" | |
| 111 | + | free -h | |
| 112 | + | echo | |
| 113 | + | echo "Active swap:" | |
| 114 | + | swapon --show | |
| 115 | + | echo | |
| 116 | + | echo "fstab entry added:" | |
| 117 | + | tail -n 5 "$FSTAB" | |
Newer
Older