Introducing sysutils/swapmon.
This port attempts to monitor swap usage and dynamically add a swapfile as neccessary. PR: ports/148711 Submitted by: Alexander Kuehn <freebsd@nagilum.org> Approved by: wxs (mentor)
This commit is contained in:
parent
bfdbff9375
commit
93ee365402
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=259788
6 changed files with 358 additions and 0 deletions
|
@ -809,6 +809,7 @@
|
|||
SUBDIR += su2
|
||||
SUBDIR += superiotool
|
||||
SUBDIR += swapd
|
||||
SUBDIR += swapmon
|
||||
SUBDIR += symlinks
|
||||
SUBDIR += symon
|
||||
SUBDIR += synergy
|
||||
|
|
40
sysutils/swapmon/Makefile
Normal file
40
sysutils/swapmon/Makefile
Normal file
|
@ -0,0 +1,40 @@
|
|||
# ports collection makefile for: swapmon
|
||||
# Date Created: 27 July 2010
|
||||
# Whom: Alexander Kuehn <freebsd@nagilum.org>
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
PORTNAME= swapmon
|
||||
PORTVERSION= 1.4
|
||||
CATEGORIES= sysutils
|
||||
MASTER_SITES= # none
|
||||
DISTFILES= # none
|
||||
|
||||
MAINTAINER= freebsd@nagilum.org
|
||||
COMMENT= Add/remove swapspace as needed
|
||||
|
||||
LICENSE= BSD
|
||||
|
||||
NO_BUILD= yes
|
||||
MAN1= ${PORTNAME}.1
|
||||
|
||||
USE_RC_SUBR= ${PORTNAME}
|
||||
|
||||
PLIST_FILES= sbin/${PORTNAME}
|
||||
|
||||
do-install:
|
||||
@${SED} -e 's|%%PREFIX%%|${PREFIX}|g' ${FILESDIR}/${PORTNAME}.sh.in \
|
||||
> ${WRKDIR}/${PORTNAME}.sh
|
||||
${INSTALL_SCRIPT} ${WRKDIR}/${PORTNAME}.sh ${PREFIX}/sbin/${PORTNAME}
|
||||
${INSTALL_MAN} ${FILESDIR}/${PORTNAME}.1 ${PREFIX}/man/man1
|
||||
|
||||
post-install:
|
||||
@${ECHO_MSG} ""
|
||||
@${ECHO_MSG} "To have swapmon run automatically after each boot"
|
||||
@${ECHO_MSG} "execute the following command as root:"
|
||||
@${ECHO_MSG} ""
|
||||
@${ECHO_MSG} " echo '${PORTNAME}_enable=\"YES\"' >>/etc/rc.conf"
|
||||
@${ECHO_MSG} ""
|
||||
|
||||
.include <bsd.port.mk>
|
88
sysutils/swapmon/files/swapmon.1
Normal file
88
sysutils/swapmon/files/swapmon.1
Normal file
|
@ -0,0 +1,88 @@
|
|||
.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
|
||||
.\"See Also:
|
||||
.\"man mdoc.samples for a complete listing of options
|
||||
.\"man mdoc for the short list of editing options
|
||||
.\"/usr/share/misc/mdoc.template
|
||||
.Dd Wed Jul 20 2010 \" DATE
|
||||
.Dt swapmon 1 \" Program name and manual section number
|
||||
.Os FreeBSD
|
||||
.Sh NAME \" Section Header - required - don't modify
|
||||
.Nm swapmon
|
||||
.\" The following lines are read in generating the apropos(man -k) database. Use only key
|
||||
.\" words here as the database is built based on the words here and in the .ND line.
|
||||
.Nd monitor swapusage, add swapspace as needed
|
||||
.Sh SYNOPSIS \" Section Header - required - don't modify
|
||||
.Nm
|
||||
.Op Ar start|stop|-F
|
||||
add/remove swapspace automatically as needed
|
||||
.Sh DESCRIPTION \" Section Header - required - don't modify
|
||||
.Nm
|
||||
will check the current swapusage and if more than SWAP_HIGH percent of swapspace is in use it will create a new swapfile with a size of size of SWAP_STEP percent of the current swapspace and activate it.
|
||||
If less than SWAP_LOW percent of swapspace is in use it will deactivate a previously added swapspace file and remove it.
|
||||
.Pp \" Inserts a space
|
||||
If called with
|
||||
.Ar start
|
||||
it will fork into the background and run as a daemon. It will check and then sleep for DELAY seconds before checking again. Messages about the operation will be piped to LOGGER. The pid of the daemon will be written to PIDFILE.
|
||||
.Pp \" Inserts a space
|
||||
If called with
|
||||
.Ar stop
|
||||
it stop a previously forked swapmon daemon.
|
||||
.Pp \" Inserts a space
|
||||
If called with
|
||||
.Ar -F
|
||||
it will run as a daemon but not detach from the terminal. Messages will still be piped to LOGGGER and not to the terminal by default. You may specify "/bin/cat" as LOGGER to get the messages on the terminal.
|
||||
.Pp \" Inserts a space
|
||||
Default values:
|
||||
.Bl -tag -width -indent \" Begins a tagged list
|
||||
.It SWAP_HIGH \" Each item preceded by .It macro
|
||||
75
|
||||
.It SWAP_LOW \" Each item preceded by .It macro
|
||||
45
|
||||
.It SWAP_STEP \" Each item preceded by .It macro
|
||||
100-SWAP_HIGH (=25)
|
||||
.It SM_HOME
|
||||
"/usr/.swap/"
|
||||
.It DELAY \" Each item preceded by .It macro
|
||||
30
|
||||
.It LOGGER \" Each item preceded by .It macro
|
||||
/usr/bin/logger
|
||||
.It PIDFILE \" Each item preceded by .It macro
|
||||
/var/run/swapmon.pid
|
||||
.El \" Ends the list
|
||||
.Pp
|
||||
swapmon can be called via cron(5). In that case you would receive messages about the swapspace being adjusted via e-mail. To use it that way add a crontab entry to the root crontab similar to this:
|
||||
.Bl -tag -width -indent \" Differs from above in tag removed
|
||||
.It * * * * * /usr/local/sbin/swapmon
|
||||
.El \" Ends the list
|
||||
.Pp
|
||||
.\" .Sh ENVIRONMENT \" May not be needed
|
||||
.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
|
||||
.\" .It Ev ENV_VAR_1
|
||||
.\" Description of ENV_VAR_1
|
||||
.\" .It Ev ENV_VAR_2
|
||||
.\" Description of ENV_VAR_2
|
||||
.\" .El
|
||||
.Sh FILES \" File used or created by the topic of the man page
|
||||
.Bl -tag -width "/usr/local/etc/swapmonrc" -compact
|
||||
.It Pa /usr/local/etc/swapmonrc
|
||||
optional configuration file for overwriting the defaults above
|
||||
.It Pa $SM_HOME
|
||||
The "homedirectory" of swapmon. In here the swapfiles as well as a lockfile and the swapfile list will be created.
|
||||
.\" .Sh DIAGNOSTICS \" May not be needed
|
||||
.\" .Bl -diag
|
||||
.\" .It Diagnostic Tag
|
||||
.\" Diagnostic informtion here.
|
||||
.\" .It Diagnostic Tag
|
||||
.\" Diagnostic informtion here.
|
||||
.\" .El
|
||||
.Sh SEE ALSO
|
||||
.\" List links in ascending order by section, alphabetically within a section.
|
||||
.\" Please do not reference files that do not exist without filing a bug report
|
||||
.Xr swapctl 8 ,
|
||||
.Xr mdconfig 8 ,
|
||||
.Xr truncate 8 ,
|
||||
.Xr logger 1 ,
|
||||
.Xr crontab 5
|
||||
.\" .Sh BUGS \" Document known, unremedied bugs
|
||||
.\" .Sh HISTORY \" Document history if command behaves in a unique manner
|
||||
|
33
sysutils/swapmon/files/swapmon.in
Normal file
33
sysutils/swapmon/files/swapmon.in
Normal file
|
@ -0,0 +1,33 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# swapmon - add / remove swap as needed
|
||||
#
|
||||
# PROVIDE: swapmon
|
||||
# REQUIRE: LOGIN
|
||||
# KEYWORD: shutdown
|
||||
#
|
||||
# Add the following lines to /etc/rc.conf to enable swapmon:
|
||||
#
|
||||
#swapmon_enable="YES"
|
||||
#
|
||||
. /etc/rc.subr
|
||||
|
||||
name=swapmon
|
||||
rcvar=`set_rcvar`
|
||||
|
||||
command="%%PREFIX%%/sbin/${name}"
|
||||
command_interpreter="/bin/sh"
|
||||
|
||||
CONFIG=%%PREFIX%%/etc/${name}rc
|
||||
if [ -r "${CONFIG}" ]
|
||||
then . "${CONFIG}"
|
||||
fi
|
||||
pidfile=${PIDFILE:-"/var/run/${name}.pid"}
|
||||
swapmon_enable=${swapmon_enable:-"NO"}
|
||||
|
||||
load_rc_config ${name}
|
||||
start_precmd='command_args="-F <&- 2>&1 >/dev/null &"'
|
||||
stop_postcmd='rm $pidfile'
|
||||
|
||||
run_rc_command "$1"
|
||||
|
187
sysutils/swapmon/files/swapmon.sh.in
Normal file
187
sysutils/swapmon/files/swapmon.sh.in
Normal file
|
@ -0,0 +1,187 @@
|
|||
#!/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.4"
|
||||
|
||||
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}
|
||||
|
||||
LOCKF=$SM_HOME/lock
|
||||
SWAPFILE=$SM_HOME/swap.XXXX
|
||||
SWAPLIST=$SM_HOME/swapfiles
|
||||
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
|
||||
umask 0077
|
||||
|
||||
if [ $(/usr/bin/id -u) -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 600 "${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
|
||||
|
||||
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
|
||||
|
||||
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 0600 "${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
|
||||
}
|
||||
|
||||
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
|
9
sysutils/swapmon/pkg-descr
Normal file
9
sysutils/swapmon/pkg-descr
Normal file
|
@ -0,0 +1,9 @@
|
|||
swapmon will check the current swapusage and if more than SWAP_HIGH per-
|
||||
cent of swapspace is in use it will create a new swapfile with a size of
|
||||
size of SWAP_STEP percent of the current swapspace and activate it. If
|
||||
less than SWAP_LOW percent of swapspace is in use it will deactivate a
|
||||
previously added swapspace file and remove it.
|
||||
|
||||
WWW: http://www.nagilum.net/swapmon/
|
||||
|
||||
freebsd@nagilum.org
|
Loading…
Reference in a new issue