diff options
author | jsa <jsa@FreeBSD.org> | 2010-08-23 10:40:15 +0800 |
---|---|---|
committer | jsa <jsa@FreeBSD.org> | 2010-08-23 10:40:15 +0800 |
commit | 1e5628a5658d022eaf6426412b291352314a2760 (patch) | |
tree | d66afd148f0b10f4541787791122453beff2448a /sysutils/swapmon | |
parent | 71b8c0ba2b44c8b075b72edf69f2a55e9473a59b (diff) | |
download | freebsd-ports-graphics-1e5628a5658d022eaf6426412b291352314a2760.tar.gz freebsd-ports-graphics-1e5628a5658d022eaf6426412b291352314a2760.tar.zst freebsd-ports-graphics-1e5628a5658d022eaf6426412b291352314a2760.zip |
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)
Diffstat (limited to 'sysutils/swapmon')
-rw-r--r-- | sysutils/swapmon/Makefile | 40 | ||||
-rw-r--r-- | sysutils/swapmon/files/swapmon.1 | 88 | ||||
-rw-r--r-- | sysutils/swapmon/files/swapmon.in | 33 | ||||
-rw-r--r-- | sysutils/swapmon/files/swapmon.sh.in | 187 | ||||
-rw-r--r-- | sysutils/swapmon/pkg-descr | 9 |
5 files changed, 357 insertions, 0 deletions
diff --git a/sysutils/swapmon/Makefile b/sysutils/swapmon/Makefile new file mode 100644 index 00000000000..deb1bf5d4e9 --- /dev/null +++ b/sysutils/swapmon/Makefile @@ -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> diff --git a/sysutils/swapmon/files/swapmon.1 b/sysutils/swapmon/files/swapmon.1 new file mode 100644 index 00000000000..0b2377cd131 --- /dev/null +++ b/sysutils/swapmon/files/swapmon.1 @@ -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 + diff --git a/sysutils/swapmon/files/swapmon.in b/sysutils/swapmon/files/swapmon.in new file mode 100644 index 00000000000..7d1da4b5f11 --- /dev/null +++ b/sysutils/swapmon/files/swapmon.in @@ -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" + diff --git a/sysutils/swapmon/files/swapmon.sh.in b/sysutils/swapmon/files/swapmon.sh.in new file mode 100644 index 00000000000..7e135d0f6aa --- /dev/null +++ b/sysutils/swapmon/files/swapmon.sh.in @@ -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 diff --git a/sysutils/swapmon/pkg-descr b/sysutils/swapmon/pkg-descr new file mode 100644 index 00000000000..9d28ee66b09 --- /dev/null +++ b/sysutils/swapmon/pkg-descr @@ -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 |