aboutsummaryrefslogtreecommitdiffstats
path: root/sysutils/swapmon
diff options
context:
space:
mode:
authorjsa <jsa@FreeBSD.org>2010-08-23 10:40:15 +0800
committerjsa <jsa@FreeBSD.org>2010-08-23 10:40:15 +0800
commit1e5628a5658d022eaf6426412b291352314a2760 (patch)
treed66afd148f0b10f4541787791122453beff2448a /sysutils/swapmon
parent71b8c0ba2b44c8b075b72edf69f2a55e9473a59b (diff)
downloadfreebsd-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/Makefile40
-rw-r--r--sysutils/swapmon/files/swapmon.188
-rw-r--r--sysutils/swapmon/files/swapmon.in33
-rw-r--r--sysutils/swapmon/files/swapmon.sh.in187
-rw-r--r--sysutils/swapmon/pkg-descr9
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