He creado un pequeño script que activa o desactiva el swap según la cantidad de memoria física libre.
Ahora mismo está pensado para tenerlo en autoarranque. Funciona mediante un bucle que, cada cierto tiempo, comprueba la memoria disponible y ejecuta las acciones correspondientes.
Se pueden configurar el tiempo y los estados de memoria libre editando unas variables dentro del propio script; no requiere archivos de configuración ni permite (aún) parámetros externos, y no está pensado para que sea interactivo (se supone que debe ejecutarse solo). Ahora mismo está configurado para repetirse cada 30 segundos, activar el swap cuando queden menos de 200MB libres y desactivarlo cuando queden más de 1000MB.
Para reactivar el swap, por defecto lee la configuración de fstab (es lo más sencillo y estándar, pues swapon tiene un parámetro para ello), pero también puede restablecer el estado en el que se encontraba antes de ejecutar el script descomentando algunas líneas, para entornos más… peculiares.
Requiere añadir permisos de ejecución sin contraseña para swapon y swapoff (instrucciones en los comentarios del script; también se puede hacer editando sudoers).
Aún no está terminado. Los comentarios los he escrito en inglés, pero no soy muy bueno en idiomas, así que aceptaría críticas también sobre eso.
¿Qué os parece? ¿Qué cambiaríais? ¿Qué se puede mejorar?
VERSIÓN 2:
Mostrar código
#!/bin/bash
# -*- ENCODING: UTF-8 -*-
# Permissions for swap:
# sudo chmod 4755 /usr/sbin/swapon
# sudo chmod 4755 /usr/sbin/swapoff
# Repeat each (s):
seconds=30
# Memory free (MB) limits:
tope=1000
critico=200
# On first execution, store the active swap locations (not needed mounting swap using fstab)
swapon_pre=$(swapon| tail -n +2)
# Then, disable the swap
swapoff -a
swaped=false
# state 1: normal, state 2: warning, state 3: critical. Initialised to "normal"
state=1
sleep 3
# Infinite loop:
while true
do
libre=$(free -m | awk '/Mem/{print $7}')
# Actions to do when RAM is critical low:
if [ $libre -lt $critico ] && [ $state != 3 ]; then
state=3
zenity --notification --text="Memoria crítca: "$libre"MB"
if [ $swaped == false ]; then
# If the swap partition is in fstab:
swapon -a
zenity --notification --text="Swap on";
# If not, this lines restore the previous swap partitions:
# cat <<<$swapon_pre | while read line ; do
# location=$(echo $line | cut -d " " -f 1);
# swapon $location;
# zenity --notification --text="Swap on "$location;
# done
swaped=true
fi
# Actions to do when RAM is warning:
elif [ $libre -gt $critico ] && [ $libre -lt $tope ] && [ $state != 2 ]; then
state=2
zenity --notification --text="Memoria baja: "$libre"MB"
# Actions to do when RAM normal:
elif [ $libre -gt $tope ] && [ $state != 1 ]; then
state=1
zenity --notification --text="Memoria normal: "$libre"MB"
if [ $swaped == true ]; then
swapoff -a
zenity --notification --text="Swap off";
swaped=false
fi
fi
sleep $seconds
done
VERSIÓN 3:
Mostrar código
#!/bin/bash
# -*- ENCODING: UTF-8 -*-
# Execution permissions for swapon:
# sudo chmod 4755 /usr/sbin/swapon
# Repeat each (s):
seconds=30
# Memory free (MB) limits:
tope=1000
critico=500
# Languages:
lang=$(locale | grep LANGUAGE= | cut -b 10-15)
echo $lang
case $lang in
"es_"*)
txt_normal='Memoria normal: '
txt_low='Memoria baja: '
txt_critic='Memoria crítica: '
txt_swapon_p='Swap activado'
txt_swapon_f='Swap activado en '
txt_swapoff='Swap desactivado'
;;
*)
txt_normal='Normal memory:'
txt_low='Low memory:'
txt_critic='Critic memory'
txt_swapon_p='Swap on'
txt_swapon_f='Swap on for'
txt_swapoff='Swap off'
;;
esac
# On first execution, check if swap is configured on fstab.
# If not, store the active swap locations before disabling the swap
fstabswap=$(cat /etc/fstab | grep swap | grep -v was | cut -d " " -f 1)
if [ -n "$fstabswap" ]
then
use_fstab=true
else
swapon_pre=$(swapon| tail -n +2)
use_fstab=false
fi
# Then, disable the swap
swapoff -a
swaped=false
# state 1: normal, state 2: warning, state 3: critical
state=1
# Infinite loop:
while true
do
libre=$(free -m | awk '/Mem/{print $7}')
#### For debug only ####
#echo "¿Memoria libre?"
#read libre
# Actions to do when RAM is critical low:
if [ $libre -lt $critico ] && [ $state != 3 ]; then
state=3
zenity --notification --text="$txt_critic $libre""MB" 2>/dev/null
if [ $swaped == false ] && [ $use_fstab == true ]; then
swapon -a
swaped=true
zenity --notification --text="$txt_swapon_p" 2>/dev/null;
elif [ $swaped == false ] && [ $use_fstab == false ]; then
cat <<<$swapon_pre | while read line
do
location=$(echo $line | cut -d " " -f 1);
swapon $location;
zenity --notification --text="$txt_swapon_f $location" 2>/dev/null;
done
swaped=true;
fi
# Actions to do when RAM is warning:
elif [ $libre -gt $critico ] && [ $libre -lt $tope ] && [ $state != 2 ]; then
state=2
zenity --notification --text="$txt_low $libre""MB" 2>/dev/null
# Actions to do when RAM normal:
elif [ $libre -gt $tope ] && [ $state != 1 ]; then
state=1
zenity --notification --text="$txt_normal $libre""MB" 2>/dev/null
if [ $swaped == true ]; then
swapoff -a
zenity --notification --text="$txt_swapoff" 2>/dev/null;
swaped=false
fi
fi
sleep $seconds
done
VERSIÓN 4
Mostrar código
#!/bin/bash
# -*- ENCODING: UTF-8 -*-
# Execution permissions for swapon:
# sudo chmod 4755 /usr/sbin/swapon
# sudo chmod 4755 /usr/sbin/swapoff
# Repeat each (s):
seconds=30
# Memory free (MB) limits:
t_warning=1000
t_critic=500
# Languages:
lang=$(locale | grep LANGUAGE= | cut -b 10-15)
echo $lang
case $lang in
"es_"*)
txt_normal='Memoria normal: '
txt_low='Memoria baja: '
txt_critic='Memoria crítica: '
txt_swapon_p='Swap activado'
txt_swapon_f='Swap activado en '
txt_swapoff='Swap desactivado'
;;
*)
txt_normal='Normal memory:'
txt_low='Low memory:'
txt_critic='Critic memory'
txt_swapon_p='Swap on'
txt_swapon_f='Swap on for'
txt_swapoff='Swap off'
;;
esac
# Variables assigned by parameters:
seconds=30
t_warning=1000
t_critic=500
if [[ $1 ]]; then
if [ $1 == "-h" ]; then
echo -e "List of valid parameters:\n -t <seconds> \t Time in seconds for check free memory\n -w <MB> \t Amount of free memory to activate the warning alarm\n -c <MB> \t Amount of free memory to activate the critical actions"
echo -e "Example: Check memory every 5 minutes (300 seconds) and activate swap when free memory is less than 100 MB:\n\t simpleswap -t 300 -c 100"
exit
fi
while getopts t:w:c: flag
do
case "${flag}" in
t) seconds=${OPTARG};;
w) t_warning=${OPTARG};;
c) t_critic=${OPTARG};;
*) echo -e "Valid arguments: -t <seconds> -w <MB> -c <MB> \nUse -h for help."
exit;;
esac
done
fi
#echo "Seconds: $seconds";
#echo "Warning: $t_warning";
#echo "Critic: $t_critic";
# On first execution, check if swap is configured on fstab.
# If not, store the active swap locations before disabling the swap
fstabswap=$(cat /etc/fstab | grep swap | grep -v was | cut -d " " -f 1)
if [ -n "$fstabswap" ]
then
use_fstab=true
else
swapon_pre=$(swapon| tail -n +2)
use_fstab=false
fi
# Then, disable the swap
swapoff -a
swaped=false
# state 1: normal, state 2: warning, state 3: critical
state=1
# Infinite loop:
while true
do
libre=$(free -m | awk '/Mem/{print $7}')
#### For debug only ####
#echo "¿Memoria libre?"
#read libre
# Actions to do when RAM is critical low:
if [ $libre -lt $t_critic ] && [ $state != 3 ]; then
state=3
zenity --notification --text="$txt_critic $libre""MB" 2>/dev/null
if [ $swaped == false ] && [ $use_fstab == true ]; then
swapon -a
swaped=true
zenity --notification --text="$txt_swapon_p" 2>/dev/null;
elif [ $swaped == false ] && [ $use_fstab == false ]; then
cat <<<$swapon_pre | while read line
do
location=$(echo $line | cut -d " " -f 1);
swapon $location;
zenity --notification --text="$txt_swapon_f $location" 2>/dev/null;
done
swaped=true;
fi
# Actions to do when RAM is warning:
elif [ $libre -gt $t_critic ] && [ $libre -lt $t_warning ] && [ $state != 2 ]; then
state=2
zenity --notification --text="$txt_low $libre""MB" 2>/dev/null
# Actions to do when RAM normal:
elif [ $libre -gt $t_warning ] && [ $state != 1 ]; then
state=1
zenity --notification --text="$txt_normal $libre""MB" 2>/dev/null
if [ $swaped == true ]; then
swapoff -a
zenity --notification --text="$txt_swapoff" 2>/dev/null;
swaped=false
fi
fi
sleep $seconds
done