#!/bin/bash ## autoswap.sh ## version 1.0 ## Automatically add and remove SWAP files based on system load. ## Author: Ze'ev Schurmann ## License: GPL3.0 or later ## Git Repo: https://git.zaks.web.za/thisiszeev/linux-server-tools ## Usage: ## ## 1. Copy the file autoswap.conf to /etc/autoswap/autoswap.conf ## 2. Set owner and group to root and edit the contents of the file to fit your ## your use case. ## 3. Copy the file autoswap.service to /etc/systemd/system/autoswap.service ## 4. Set owner and group to root ## 5. Copy autoswap.sh, addswap.sh and remswap.sh to the / folder. ## 6. Set owner and group to root and make executable for root only (744) ## ## (as root) ## systemctl daemon-reload ## systemctl start autoswap.service ## systemctl enable autoswap.service ## ## (with sudo) ## sudo systemctl daemon-reload ## sudo systemctl start autoswap.service ## sudo systemctl enable autoswap.service ## ## The script will monitor your available memory and SWAP resources and use ## addswap.sh and remswap.sh to add and remove SWAP fles depending on your ## requirements and settings in /etc/autoswap/autoswap.conf. ## ## If you make changes to /etc/autoswap/autoswap.conf then you need to restart the ## autoswap.service using: ## ## (as root) ## systemctl restart autoswap.service ## ## (with sudo) ## sudo systemctl restart autoswap.service ## ## A log file can be found at /var/log/swapmanagement.log ## Why did I make these two scripts? ## ## I use Debian as my daily driver (I've been using Linux in some for or the other ## as my daily driver since 2006). I also us Debian for all my servers. I also ## running a webhosting business (https://www.zaks.web.za) and in my 20+ years in ## the game, I have learned that... 1. VPS's do not come with SWAP, but sometimes ## you need a bit of SWAP to handle heavy load. 2. SWAP files can be added and ## removed on the fly (no reboot required), however a SWAP partition, not so simple. ## ## On my daily driver machine, I also create a lot of digital artwork. I recently ## found myself rendering a finished artfile that was 9.5GB (24000px by 13700px) ## in Gimp, and half way through I started running out of RAM and SWAP. So I ## quickly created the needed SWAP file, and Gimp was able to finish the render ## without crashing. ## Plans for the future: ## ## I am planning to make a configurable service file that can be run in the ## background to automatically create more SWAP files when your server/computer is ## under load, and remove excess SWAP files when the server/computer is no longer ## under load. ## Do you have a script idea? ## If you have an idea for a useful server script for selfhost/homelab environments, ## please start a chat with me on Reddit /u/thisiszeev and share your idea. I might ## just make it a reality, and give you credit in the relevant README.md file. ## Donations ## ## Please consider making me small donation. Even though my scripts are open source ## and free to use, I still need to eat. And the occasional bottle of wine also goes ## down well. ## ## $5 buys me a cup of coffee ## $10 buys me a nice burger ## $20 buys me a bottle of wine ## Anything above that will be awesome as well. ## ## You can send me a donation via Paypal https://www.paypal.com/paypalme/thisiszeev ## ## Drop me a message on Reddit if you do make a donation. u/thisiszeev ## ## Support is only offered freely to those who donate $20 or more. ## ## Your donation contributes to further development. ## ## If you need a custom script, contact me on Reddit for pricing. function echolog { echo "$1" echo "$(date) > autoswap > $1" >> /var/log/swapmanagement.log if [[ $(wc -l < /var/log/swapmanagement.log) -gt 300 ]]; then cat /var/log/swapmanagement.log | tail -n 250 > /var/log/swapmanagement.temp && mv /var/log/swapmanagement.temp /var/log/swapmanagement.log fi } echolog "Initializing..." threshold_minimum=512 swap_file_size=2048 required_swap_files=1 minimum_free_storage=4096 check_interval=30 if [[ -f /etc/autoswap/autoswap.conf ]]; then source /etc/autoswap/autoswap.conf echolog "/etc/autoswap/autoswap.conf found... settings applied." else echolog "/etc/autoswap/autoswap.conf not found... default settings applied." fi swap_file_size_gb=$(($swap_file_size/1024)) if [[ $(($swap_file_size%1024)) -eq 0 ]]; then echolog "Converting {swap_file_size} from MB to GB, rounding up..." ((swap_file_size_gb++)) swap_file_size=$(($swap_file_size_gb*1014)) fi echolog "{threshold_minimum} = ${threshold_minimum}MB" echolog "{swap_file_size} = ${swap_file_size}MB" echolog "{required_swap_files} = ${required_swap_files}" echolog "{minimum_free_storage} = ${minimum_free_storage}MB" echolog "{check_interval} = ${check_interval}s" swap_file_size_gb=$(($swap_file_size/1024)) interval=$check_interval while true; do #echo "Doing checks..." ram_array=($(free | grep "^Mem:")) swap_array=($(free | grep "^Swap:")) root_drive_array=($(df | grep "/$")) free_ram=$((${ram_array[6]}/1024)) free_swap=$((${swap_array[3]}/1024)) free_combined=$(($free_ram+$free_swap)) free_root_drive=$((${root_drive_array[3]}/1024)) total_ram=${ram_array[1]} total_swap=${swap_array[1]} required_free_root_drive=$(($swap_file_size+$minimum_free_storage)) swap_files=$(swapon --show | grep "file" | wc -l) #echo "Root Drive Free Space : ${free_root_drive}MB" #echo "Req. Space for more SWAP : ${required_free_root_drive}MB" #echo "RAM Memory Free Space : ${free_ram}MB" #echo "SWAP Memory Free Space : ${free_swap}MB" #echo "Total Combined Free Mem : ${free_combined}MB" #echo "No. of Active SWAP Files : $swap_files" #echo "Threshold Minimum Space : ${threshold_minimum}MB" #echo "SWAP File Allocation Size : ${swap_file_size}MB" if [[ $swap_files -lt $required_swap_files ]]; then echolog "Number of active SWAP files is less than required minimum..." bash addswap.sh $swap_file_size_gb interval=1 elif [[ $free_combined -lt $threshold_minimum ]] && [[ $free_root_drive -gt $required_free_root_drive ]] && [[ $swap_files -ge $required_swap_files ]]; then echolog "System Memory and SWAP resources running below ${threshold_minimum}MB..." bash addswap.sh $swap_file_size_gb interval=$check_interval elif [[ $free_combined -lt $threshold_minimum ]] && [[ $free_root_drive -le $required_free_root_drive ]] && [[ $swap_files -ge $required_swap_files ]]; then echolog "CRITICAL > System Memory and SWAP resources running below ${threshold_minimum}MB but insufficient free space on root drive. [${free_root_drive}MB - requires $(($swap_file_size+$minimum_free_storage))MB]" interval=$(($check_interval*10)) elif [[ $free_combined -gt $(($threshold_minimum+$swap_file_size)) ]] && [[ $swap_files -gt $required_swap_files ]]; then echolog "System Memory and SWAP resource have improved." bash remswap.sh interval=1 else interval=$check_interval fi #echo "Check Interval : ${interval}s" sleep ${interval}s done