Last active 1 month ago

OneWheelGeek's Avatar 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