freebsd-ports/sysutils/swapmon/files/swapmon.sh.in
Glen Barber cc7dcdd642 update sysutils/swapmon to version 1.5
Changes:
- clean up leftover swapfiles after unexpected reboots
- also works if no swap is configured

PR:		ports/169467
Submitted by:	freebsd@nagilum.org (maintainer)
Approved by:	crees (mentor)
2012-06-27 13:31:10 +00:00

234 lines
7.6 KiB
Bash

#!/bin/sh
#
# swapmon - add / remove swap as needed
#
# Copyright (C) 2010 Alexander Kuehn. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
CONFIG=%%PREFIX%%/etc/swapmonrc
VERSION="1.5"
if [ -r "${CONFIG}" ]
then . "${CONFIG}"
fi
# where to create swapfiles
: ${SM_HOME=/usr/.swap}
# if the swap usage is higher than that (percentage) new swap will be added
: ${SWAP_HIGH=75}
# if the swap usage is lower than that then a previously added swapfile will be removed
: ${SWAP_LOW=45}
# if swap is running low we will increase the swapspace by this many percent
: ${SWAP_STEP=$(( 100 - ${SWAP_HIGH} ))}
# if running as daemon how long to wait between checks
: ${DELAY=30}
# if running as daemon where to log messages
: ${LOGGER=/usr/bin/logger}
# if running as daemon where to put pidfile
: ${PIDFILE=/var/run/swapmon.pid}
# if no swap is configured create a swapfile with this size
: ${SWAP_MIN=256}
LOCKF=$SM_HOME/lock
SWAPFILE=$SM_HOME/swap.XXXX
SWAPLIST=$SM_HOME/swapfiles
SWAPDEF=$SM_HOME/swap.def
MKTEMP=/usr/bin/mktemp
TRUNCATE=/usr/bin/truncate
TOUCH=/usr/bin/touch
CHMOD=/bin/chmod
MDCONFIG=/sbin/mdconfig
SWAPON=/sbin/swapon
SWAPOFF=/sbin/swapoff
SWAPCTL=/sbin/swapctl
RM=/bin/rm
SED=/usr/bin/sed
PERM=600
UID=$(/usr/bin/id -u)
GID=$(/usr/bin/id -g)
umask 0077
# a few sanity checks to see if we can do our work
if [ $UID -gt 0 ]
then echo "I'm not running as root (uid=0) this probably wont work."
# exit 1
fi
if [ \! -d ${SM_HOME} ]
then /bin/mkdir -p ${SM_HOME} || { echo "Error creating ${SM_HOME}!" ; exit 1; }
fi
$TOUCH ${SWAPLIST} || { echo "Can't write to ${SWAPLIST} aborting." ; exit 1; }
# add a 1MB swapfile to check if we have the permissions to do so
NSWAP=$($MKTEMP ${SWAPFILE})
$TRUNCATE -s 1M "${NSWAP}" || { echo "Error creating swapfile ${NSWAP}, aborting." ; exit 1; }
$CHMOD ${PERM} "${NSWAP}"
MDEV=$($MDCONFIG -a -t vnode -f "${NSWAP}")
if [ -n "$MDEV" ]
then
$SWAPON /dev/${MDEV} || { echo "error activating swapdevice /dev/${MDEV}."; exit 1; }
$SWAPOFF "/dev/${MDEV}"
$MDCONFIG -d -u ${MDEV} >/dev/null
$RM -f "${NSWAP}"
else
echo "error configuring memory disk ($MDCONFIG -a -t vnode -f \"${NSWAP}\")"
$RM -f "${NSWAP}"
exit
fi
# delete leftover swapfiles
find $SM_HOME -maxdepth 1 -name $(echo ${SWAPFILE##*/}|tr X \?) -type f \
-perm ${PERM} -user $UID -group $GID -exec $RM -fv "{}" \;
if [ ${SWAP_LOW} -ge $(( $(($SWAP_HIGH * 100)) / $((100 + $SWAP_STEP)) )) ]
then echo "SWAP_LOW(${SWAP_LOW}) schould be lower than $(( $(($SWAP_HIGH * 100)) / $((100 + $SWAP_STEP)) )) to be useful."
echo "Swapmon $VERSION."
exit 1
fi
# if there is no swap configured, add some
add_def_swap()
{
SWAPCTLSK=$($SWAPCTL -sk)
SWAPTOTAL=${SWAPCTLSK#* }
SWAPTOTAL=${SWAPTOTAL% *}
if [ "$SWAPTOTAL" -eq 0 ]
then
if [ "${SWAP_MIN}" -gt 0 ]
then
if [ -e "${SWAPDEF}" ] # if the file already exists
then if [ -f "${SWAPDEF}" -a \! -h "${SWAPDEF}"] # is it a regular file and no symlink?
then $RM -f "${SWAPDEF}"
else echo "Error: swapfile ${SWAPDEF} is not a regular file, aborting." ; exit 1;
fi
fi
$TRUNCATE -s ${SWAP_MIN}M "${SWAPDEF}" || { echo "Error creating swapfile ${SWAPDEF}, aborting." ; exit 1; }
$CHMOD $PERM "${SWAPDEF}"
MDEV=$($MDCONFIG -a -t vnode -f "${SWAPDEF}")
if [ -n "$MDEV" ]
then
$SWAPON /dev/${MDEV} || { echo "error activating swapdevice /dev/${MDEV}."; exit 1; }
echo "swapmon$VERSION[$$] Activated swapfile ${SWAPDEF} as there was no swap configured!"|$LOGGER
else
echo "error configuring memory disk ($MDCONFIG -a -t vnode -f \"${SWAPDEF}\")"
$RM -f "${SWAPDEF}"
exit 1
fi
else
echo "No swap configured, SWAP_MIN set to $SWAP_MIN - aborting."
exit 1
fi
fi
}
check_swap()
{
SWAPCTLSK=$($SWAPCTL -sk)
SWAPTOTAL=${SWAPCTLSK#* }
SWAPTOTAL=${SWAPTOTAL% *}
SWAPUSAGE=$(( ${SWAPCTLSK##* } * 100 / $SWAPTOTAL ))
if [ ${SWAPUSAGE} -gt ${SWAP_HIGH} ]
then NSWAP=$($MKTEMP ${SWAPFILE})
BLOCKS=$(( $(( ${SWAPTOTAL} * ${SWAP_STEP} +1023)) / 102400 ))
# make sure we can write to the swaplist
$TOUCH "${SWAPLIST}" || { echo "swapmon$VERSION[$$] Error modifying ${SWAPLIST} exiting."|$LOGGER; exit 1; }
$TRUNCATE -s ${BLOCKS}M "${NSWAP}"
$CHMOD $PERM "${NSWAP}"
if [ -s "${NSWAP}" ]
then MDEV=$($MDCONFIG -a -t vnode -f "${NSWAP}")
printf "${MDEV} ${NSWAP}\n" >>"${SWAPLIST}"
echo "swapmon$VERSION[$$] Swapusage ${SWAPUSAGE}%($((${SWAPCTLSK##* }/1024))/$(($SWAPTOTAL/1024)) M), activated new swapdevice ${MDEV} backed by ${NSWAP}."|$LOGGER
$SWAPON /dev/${MDEV}
$SWAPCTL -lh|$SED -e "s/^/swapmon$VERSION[$$] /g"|$LOGGER
else echo "swapmon$VERSION[$$] Creating swapfile ${NSWAP} failed! :("|$LOGGER
fi
fi
while [ \( ${SWAPUSAGE} -lt ${SWAP_LOW} \) -a -s "${SWAPLIST}" ]
do MDEV=$(/usr/bin/tail -1 "${SWAPLIST}")
SWAPF=${MDEV#* }
MDEV=${MDEV%% *}
if [ -s "${SWAPF}" ]
then if [ "${SWAPF}" = "$($MDCONFIG -l -u ${MDEV}|/usr/bin/awk '{print $4}')" ]
then if [ -n "$($SWAPCTL -l|$SED -n '1!p'|/usr/bin/grep '/dev/'${MDEV})" ]
then echo "swapmon$VERSION[$$] Swapusage ${SWAPUSAGE}%($((${SWAPCTLSK##* }/1024))/$(($SWAPTOTAL/1024)) M), deactivating swapdevice ${MDEV}."|$LOGGER
$SWAPCTL -lh|$SED -e "s/^/swapmon$VERSION[$$] /g"|$LOGGER
$SWAPOFF "/dev/${MDEV}"
fi
echo "swapmon$VERSION[$$] Detaching vnode ${MDEV}."|$LOGGER
$MDCONFIG -d -u ${MDEV} >/dev/null
$RM -f "${SWAPF}"
else echo "swapmon$VERSION[$$] Swapfile ${SWAPF} is not attached to ${MDEV} as it should be!?"|$LOGGER
for MDEV in $($MDCONFIG -l)
do echo "swapmon$VERSION[$$] $($MDCONFIG -l -u ${MDEV})"|$LOGGER
done
fi
else echo "swapmon$VERSION[$$] ${SWAPF} is not a valid swapfile."|$LOGGER
fi
$SED -I '' -n '$!p' "${SWAPLIST}"
SWAPCTLSK=$($SWAPCTL -sk)
SWAPTOTAL=${SWAPCTLSK#* }
SWAPTOTAL=${SWAPTOTAL% *}
SWAPUSAGE=$(( ${SWAPCTLSK##* } * 100 / $SWAPTOTAL ))
done
}
add_def_swap # this will check if there is some swap configured
# we can't work without
case "$1" in
start)
$0 -F <&- 2>&1 >/dev/null &
;;
stop)
if [ -s "${PIDFILE}" ]
then
PID=$(/bin/cat ${PIDFILE})
if ( /bin/ps -p $PID|grep -q $0 )
then /bin/kill $PID
fi
$RM "${PIDFILE}"
fi
;;
-F)
echo $$ >"${PIDFILE}"
echo "swapmon$VERSION[$$] Writing pid $$ to pidfile ${PIDFILE}."|$LOGGER
cd / || exit 1
while [ -f "${PIDFILE}" ]
do check_swap
sleep ${DELAY}
done
;;
'')
if [ -r "${LOCKF}" ]
then
echo "${LOCKF} exists"
exit 1;
else
echo $$ >"${LOCKF}"
LOGGER="/bin/cat"
check_swap
fi
$RM -f "${LOCKF}"
;;
*)
echo "$* not supported"
;;
esac