summaryrefslogtreecommitdiff
path: root/ejabberdctl.template
diff options
context:
space:
mode:
authorChristophe Romain <christophe.romain@process-one.net>2013-06-18 15:56:28 +0200
committerChristophe Romain <christophe.romain@process-one.net>2013-06-18 15:56:28 +0200
commit55fb85107e880e47cb63e65f09721e3af089ec9d (patch)
tree6242b2d5bd140fb8ba447bc7292a49147b707c5e /ejabberdctl.template
parentSome deps have their DLLs in "priv" directory (not "priv/lib"). (diff)
improve ejabberdctl, and support different node names (thanks to Zach Calvert)(EJAB-1611)
Diffstat (limited to 'ejabberdctl.template')
-rwxr-xr-xejabberdctl.template293
1 files changed, 148 insertions, 145 deletions
diff --git a/ejabberdctl.template b/ejabberdctl.template
index a98e73ef..035918be 100755
--- a/ejabberdctl.template
+++ b/ejabberdctl.template
@@ -6,24 +6,45 @@ SMP=auto
ERL_MAX_PORTS=32000
ERL_PROCESSES=250000
ERL_MAX_ETS_TABLES=1400
-
-SCRIPT_DIR=$(cd ${0%/*} && pwd)
+FIREWALL_WINDOW=""
+INET_DIST_INTERFACE="127.0.0.1"
+ERLANG_NODE=ejabberd@localhost
# define default environment variables
-NODE=ejabberd
-HOST=localhost
-ERLANG_NODE=$NODE@$HOST
+SCRIPT_DIR=`cd ${0%/*} && pwd`
ERL={{erl}}
INSTALLUSER={{installuser}}
+# Compatibility in ZSH
+#setopt shwordsplit 2>/dev/null
+
+# check the proper system user is used if defined
+if [ "$INSTALLUSER" != "" ] ; then
+ EXEC_CMD="false"
+ for GID in `id -G`; do
+ if [ $GID -eq 0 ] ; then
+ EXEC_CMD="su $INSTALLUSER -p -c"
+ fi
+ done
+ if [ `id -g` -eq `id -g $INSTALLUSER` ] ; then
+ EXEC_CMD="sh -c"
+ fi
+ if [ "$EXEC_CMD" = "false" ] ; then
+ echo "This command can only be run by root or the user $INSTALLUSER" >&2
+ exit 4
+ fi
+else
+ EXEC_CMD="sh -c"
+fi
+
# parse command line parameters
-ARGS=
+ARGS=""
while [ $# -ne 0 ] ; do
PARAM=$1
shift
case $PARAM in
--) break ;;
- --node) ERLANG_NODE_ARG=$1; shift ;;
+ --node) ERLANG_NODE_ARG=$1 ; shift ;;
--config-dir) ETCDIR=$1 ; shift ;;
--config) EJABBERD_CONFIG_PATH=$1 ; shift ;;
--ctl-config) EJABBERDCTL_CONFIG_PATH=$1 ; shift ;;
@@ -37,13 +58,15 @@ done
if [ "$ETCDIR" = "" ] ; then
ETCDIR={{sysconfdir}}/ejabberd
fi
-if [ "$EJABBERD_CONFIG_PATH" = "" ] ; then
- EJABBERD_CONFIG_PATH=$ETCDIR/ejabberd.cfg
-fi
if [ "$EJABBERDCTL_CONFIG_PATH" = "" ] ; then
EJABBERDCTL_CONFIG_PATH=$ETCDIR/ejabberdctl.cfg
fi
-[ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
+if [ -f "$EJABBERDCTL_CONFIG_PATH" ] ; then
+ . "$EJABBERDCTL_CONFIG_PATH"
+fi
+if [ "$EJABBERD_CONFIG_PATH" = "" ] ; then
+ EJABBERD_CONFIG_PATH=$ETCDIR/ejabberd.cfg
+fi
if [ "$LOGS_DIR" = "" ] ; then
LOGS_DIR={{localstatedir}}/log/ejabberd
fi
@@ -57,60 +80,26 @@ if [ "$ERLANG_NODE_ARG" != "" ] ; then
ERLANG_NODE=$ERLANG_NODE_ARG
NODE=${ERLANG_NODE%@*}
fi
-
-# check the proper system user is used
-ID=`id -g`
-GIDS=`id -G`
-EJID=`id -g $INSTALLUSER`
-EXEC_CMD="false"
-for GID in $GIDS; do
- if [ $GID -eq 0 ] ; then
- EXEC_CMD="su ${INSTALLUSER} -p -c"
- fi
-done
-if [ "$ID" -eq "$EJID" ] ; then
- EXEC_CMD="sh -c"
-fi
-if [ "$EXEC_CMD" = "false" ] ; then
- echo "This command can only be run by root or the user $INSTALLUSER" >&2
- exit 4
-fi
-
-NAME=-name
-[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && NAME=-sname
-
-KERNEL_OPTS=""
-if [ "$FIREWALL_WINDOW" != "" ] ; then
- KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
-fi
-if [ "$INET_DIST_INTERFACE" != "" ] ; then
- KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_use_interface \"${INET_DIST_INTERFACE}\""
-fi
-
-ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
-
-# define additional environment variables
if [ "{{release}}" != "true" ] ; then
if [ "$EJABBERDDIR" = "" ] ; then
- EJABBERDDIR={{libdir}}/ejabberd
+ EJABBERDDIR={{libdir}}/ejabberd
fi
if [ "$EJABBERD_EBIN_PATH" = "" ] ; then
- EJABBERD_EBIN_PATH=$EJABBERDDIR/ebin
+ EJABBERD_EBIN_PATH=$EJABBERDDIR/ebin
fi
if [ "$EJABBERD_PRIV_PATH" = "" ] ; then
- EJABBERD_PRIV_PATH=$EJABBERDDIR/priv
+ EJABBERD_PRIV_PATH=$EJABBERDDIR/priv
fi
if [ "$EJABBERD_BIN_PATH" = "" ] ; then
- EJABBERD_BIN_PATH=$EJABBERD_PRIV_PATH/bin
+ EJABBERD_BIN_PATH=$EJABBERD_PRIV_PATH/bin
fi
if [ "$EJABBERD_SO_PATH" = "" ] ; then
- EJABBERD_SO_PATH=$EJABBERD_PRIV_PATH/lib
+ EJABBERD_SO_PATH=$EJABBERD_PRIV_PATH/lib
fi
if [ "$EJABBERD_MSGS_PATH" = "" ] ; then
- EJABBERD_MSGS_PATH=$EJABBERD_PRIV_PATH/msgs
+ EJABBERD_MSGS_PATH=$EJABBERD_PRIV_PATH/msgs
fi
fi
-
EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
SASL_LOG_PATH=$LOGS_DIR/erlang.log
DATETIME=`date "+%Y%m%d-%H%M%S"`
@@ -118,11 +107,25 @@ ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump
ERL_INETRC=$ETCDIR/inetrc
HOME=$SPOOLDIR
-# create the home dir with the proper user if doesn't exist, because it stores cookie file
-[ -d $HOME ] || $EXEC_CMD "mkdir -p $HOME"
+# define erl parameters
+ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
+KERNEL_OPTS=""
+if [ "$FIREWALL_WINDOW" != "" ] ; then
+ KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
+fi
+if [ "$INET_DIST_INTERFACE" != "" ] ; then
+ KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_use_interface \"{${INET_DIST_INTERFACE//./,}}\""
+fi
+if [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] ; then
+ NAME="-sname"
+else
+ NAME="-name"
+fi
-# Change to a directory readable by INSTALLUSER to
+# create the ejabberd home dir with the proper user if doesn't exist
+# then change to that directory readable by INSTALLUSER to
# prevent "File operation error: eacces." messages
+[ -d $HOME ] || $EXEC_CMD "mkdir -p $HOME"
cd $HOME
# export global variables
@@ -141,16 +144,10 @@ export ERL_MAX_ETS_TABLES
export HOME
export EXEC_CMD
-
-# Compatibility in ZSH
-#setopt shwordsplit 2>/dev/null
-
# start server
-start ()
+start()
{
- checknodenameusage
- [ "$?" -eq 0 ] && echo "\nERROR: The node '$ERLANG_NODE' is already running." && return 1
-
+ check_start
$EXEC_CMD "$ERL \
$NAME $ERLANG_NODE \
-noinput -detached \
@@ -163,7 +160,7 @@ start ()
}
# attach to server
-debug ()
+debug()
{
echo "--------------------------------------------------------------------"
echo ""
@@ -182,7 +179,7 @@ debug ()
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press any key to continue"
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
- read foo
+ read foo
fi
echo ""
TTY=`tty | sed -e 's/.*\///g'`
@@ -195,11 +192,9 @@ debug ()
}
# start interactive server
-live ()
+live()
{
- checknodenameusage
- [ "$?" -eq 0 ] && echo "\nERROR: The node '$ERLANG_NODE' is already running." && return 1
-
+ check_start
echo "--------------------------------------------------------------------"
echo ""
echo "IMPORTANT: ejabberd is going to start in LIVE (interactive) mode."
@@ -216,7 +211,7 @@ live ()
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press any key to continue"
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
- read foo
+ read foo
fi
echo ""
$EXEC_CMD "$ERL \
@@ -228,7 +223,14 @@ live ()
$ERLANG_OPTS $ARGS \"$@\""
}
-help ()
+etop()
+{
+ $EXEC_CMD "$ERL \
+ $NAME debug-${TTY}-${ERLANG_NODE} \
+ -hidden -s etop -s erlang halt -output text -node $ERLANG_NODE"
+}
+
+help()
{
echo ""
echo "Commands to start an ejabberd node:"
@@ -247,7 +249,7 @@ help ()
}
# common control function
-ctl ()
+ctl()
{
COMMAND=$@
@@ -258,71 +260,71 @@ ctl ()
CONNLOCKDIR={{localstatedir}}/lock/ejabberdctl
FLOCK='/usr/bin/flock'
if [ ! -x "$FLOCK" ] || [ ! -d "$CONNLOCKDIR" ] ; then
- JOT='/usr/bin/jot'
- if [ ! -x "$JOT" ] ; then
- # no flock or jot, simply invoke ctlexec()
- CTL_CONN="ctl-${ERLANG_NODE}"
- ctlexec $CTL_CONN $COMMAND
- result=$?
- else
- # no flock, but at least there is jot
- RAND=`jot -r 1 0 $MAXCONNID`
- CTL_CONN="ctl-${RAND}-${ERLANG_NODE}"
- ctlexec $CTL_CONN $COMMAND
- result=$?
- fi
+ JOT='/usr/bin/jot'
+ if [ ! -x "$JOT" ] ; then
+ # no flock or jot, simply invoke ctlexec()
+ CTL_CONN="ctl-${ERLANG_NODE}"
+ ctlexec $CTL_CONN $COMMAND
+ result=$?
+ else
+ # no flock, but at least there is jot
+ RAND=`jot -r 1 0 $MAXCONNID`
+ CTL_CONN="ctl-${RAND}-${ERLANG_NODE}"
+ ctlexec $CTL_CONN $COMMAND
+ result=$?
+ fi
else
- # we have flock so we get a lock
- # on one of a limited number of
- # conn names -- this allows
- # concurrent invocations using a bound
- # number of atoms
- for N in $(seq 1 $MAXCONNID); do
- CTL_CONN="ejabberdctl-$N"
- CTL_LOCKFILE="$CONNLOCKDIR/$CTL_CONN"
- (
- exec 8>"$CTL_LOCKFILE"
- if flock --nb 8; then
- ctlexec $CTL_CONN $COMMAND
+ # we have flock so we get a lock
+ # on one of a limited number of
+ # conn names -- this allows
+ # concurrent invocations using a bound
+ # number of atoms
+ for N in `seq 1 $MAXCONNID`; do
+ CTL_CONN="ejabberdctl-$N"
+ CTL_LOCKFILE="$CONNLOCKDIR/$CTL_CONN"
+ (
+ exec 8>"$CTL_LOCKFILE"
+ if flock --nb 8; then
+ ctlexec $CTL_CONN $COMMAND
ssresult=$?
# segregate from possible flock exit(1)
- ssresult=$(expr $ssresult \* 10)
- exit $ssresult
- else
- exit 1
- fi
+ ssresult=`expr $ssresult \* 10`
+ exit $ssresult
+ else
+ exit 1
+ fi
)
- result=$?
- if [ $result -eq 1 ]; then
+ result=$?
+ if [ $result -eq 1 ] ; then
# means we errored out in flock
# rather than in the exec - stay in the loop
# trying other conn names...
- badlock=1
- else
- badlock=""
- break;
- fi
- done
- result=$(expr $result / 10)
+ badlock=1
+ else
+ badlock=""
+ break;
+ fi
+ done
+ result=`expr $result / 10`
fi
- if [ "$badlock" ];then
- echo "Ran out of connections to try. Your ejabberd processes" >&2
- echo "may be stuck or this is a very busy server. For very" >&2
- echo "busy servers, consider raising MAXCONNID in ejabberdctl">&2
- exit 1;
+ if [ "$badlock" ] ;then
+ echo "Ran out of connections to try. Your ejabberd processes" >&2
+ echo "may be stuck or this is a very busy server. For very" >&2
+ echo "busy servers, consider raising MAXCONNID in ejabberdctl">&2
+ exit 1;
fi
case $result in
- 0) :;;
- 1) :;;
- 2) help;;
- 3) help;;
+ 0) :;;
+ 1) :;;
+ 2) help;;
+ 3) help;;
esac
return $result
}
-ctlexec ()
+ctlexec()
{
CONN_NAME=$1; shift
COMMAND=$@
@@ -335,17 +337,30 @@ ctlexec ()
-s ejabberd_ctl -extra $ERLANG_NODE $COMMAND"
}
-# display ctl usage
-usage ()
+# stop epmd if there is no other running node
+stop_epmd()
{
- ctl
- exit
+ epmd -names 2>/dev/null | grep -q name || epmd -kill >/dev/null
}
-# stop epmd if there is no other running node
-stop_epmd()
+# make sure node not already running and node name unregistered
+check_start()
{
- epmd -names | grep -q name || epmd -kill
+ epmd -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && {
+ ps ux | grep -v grep | grep -q " $ERLANG_NODE " && {
+ echo "ERROR: The ejabberd node '$ERLANG_NODE' is already running."
+ exit 4
+ } || {
+ ps ux | grep -v grep | grep -q beam && {
+ echo "ERROR: The ejabberd node '$ERLANG_NODE' is registered,"
+ echo " but no related beam process has been found."
+ echo "Shutdown all other erlang nodes, and call 'epmd -kill'."
+ exit 5
+ } || {
+ epmd -kill >/dev/null
+ }
+ }
+ }
}
# allow sync calls
@@ -355,9 +370,9 @@ wait_for_status()
# return: 0 OK, 1 KO
timeout=$2
status=4
- while [ $status -ne $1 ]; do
+ while [ $status -ne $1 ] ; do
sleep $3
- timeout=$(($timeout - 1))
+ timeout=`expr $timeout - 1`
[ $timeout -eq 0 ] && {
status=$1
} || {
@@ -365,28 +380,16 @@ wait_for_status()
status=$?
}
done
- [ $timeout -eq 0 ] && {
- status=1
- } || {
- status=0
- }
- return $status
-}
-
-# check node name is used or not
-# $? --> 0=alreadyused 1=available
-checknodenameusage ()
-{
- $EXEC_CMD "$ERL \
- $NAME $ERLANG_NODE \
- -s erlang halt | grep -c duplicate_name > /dev/null "
+ [ $timeout -eq 0 ] && return 1 || return 0
}
+# main handler
case $ARGS in
' start') start;;
' debug') debug;;
' live') live;;
+ ' etop') etop;;
' started') wait_for_status 0 30 2;; # wait 30x2s before timeout
- ' stopped') wait_for_status 3 15 2; stop_epmd;; # wait 15x2s before timeout
+ ' stopped') wait_for_status 3 15 2 && stop_epmd;; # wait 15x2s before timeout
*) ctl $ARGS;;
esac