I have the following code for a service that I'm trying to have automatically start on boot.
#!/bin/sh
# Source function library.
. /etc/rc.d/init.d/functions
RETVAL=0
prog='foo'
exec="/usr/sbin/$prog"
pidfile="/var/run/$prog.pid"
lock_file="/var/lock/subsys/$prog"
logfile="/var/log/$prog"
if [ -f /etc/default/foo ]; then
. /etc/default/foo
fi
if [ -z $QUEUE_TYPE ]; then
echo 'ENV variable QUEUE_TYPE has not been set, please set it in /etc/default/foo'
exit 1
fi
get_pid() {
cat "$pidfile"
}
is_running() {
[ -f "$pidfile" ] && ps `get_pid` > /dev/null 2>&1
}
case "$1" in
start)
echo -n "Starting Consul daemon: "
#
daemon --pidfile $pidfile --check foo --user my-user "my app stuff here"
echo
;;
stop)
echo -n 'Stopping Consul daemon: '
killproc foo
echo
;;
status)
status $pidfile
RETVAL=$?
#status -p $pidfile -l $prog
#[ $RETVAL -eq 0 ] && RETVAL=$?
#RETVAL=$?
#if is_running; then
# echo 'Running'
#else
# echo 'Not Running'
#fi
#status foo
#RETVAL=$?
;;
restart)
$0 stop
$0 start
RETVAL=$?
;;
*)
echo 'Usage: foo {start|stop|status|restart}'
exit 1
esac
exit $RETVAL
When I run sudo service foo status it says that it hasn't been started which is correct. After running sudo service foo start and then running the status command, it tells me that the service hasn't been started. I'm not sure what is causing this to happen. I looked at the configurations for other init.d scripts to see how they were handling this and tried to follow their lead. Is there something obvious here that I'm doing wrong or something else that I may be unaware of that's causing this problem?
Related
I found this initscript for launching nginx here: http://www.rackspace.com/knowledge_center/article/centos-adding-an-nginx-init-script. Im trying to modify it to work with a chroot environment and its proving more troublesome than I expected.
Here's what I have:
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemin
#
# chkconfig: - 85 15
. /etc/rc.d/init.d/functions
. /etc/sysconfig/network
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx"
prog="nginx"
chroot="/usr/sbin/chroot /nginx
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
lockfile=/var/lock/subsys/nginx
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $chroot $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killall $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killall $prog -HUP
retval=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
if rh_status_q; then
printf "$prog already running\n"
exit 0
fi
$1
;;
stop)
if ! rh_status_q; then
printf "$prog not running\n"
exit 0
fi
$1
;;
restart|configtest)
$1
;;
reload)
if ! rh_status_q; then
printf "$prog not running\n"
exit 7
fi
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
if ! rh_status_q; then
printf "$prog not running\n"
exit 0
fi
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac
The main thing not working right now is the status call.
[root#localhost ~]# /etc/init.d/nginx status
nginx dead but subsys locked
This error points to a lockfile being present but no pid file. This is true, however when I use the original nginx init script and launch it in a non-chroot environment, there is no pidfile, and the status call works just fine.
I put in some lines to retrieve the pid by launching the process in the background instead of using daemon:
PID=$chroot $nginx -c $NGINX_CONF_FILE > /dev/null 2>&1 $ echo $!
echo $PID > $pidfile
But this grabs the pid of chroot, which ends after nginx is launched. Nginx has both a master and a child pid. Might grabbing those and putting them to a pidfile be the way forward? Or is there something else I should try?
I think its because daemon launches a chroot process it gets the wrong pid.
Alright it was as easy as grepping for the pid
pidfile='/var/run/nginx.pid'
start(){
...
daemon $chroot $nginx -c $NGINX_CONF_FILE
PID=`ps -ef | grep $nginx | grep -v grep | awk '{print $2}'`
echo $PID > $pidfile
...
}
stop() {
...
[ $retval -eq 0 ] && rm -f $lockfile && rm -f $pidfile
return $retval
}
I am writing a init.d script for kibana
as of not script is running partially, but the issue is if I run run service kibana start even if service is running then second instance start which bothers me I want to add check before starting service, if service is running then dont start second instance. I tried to put if check on "/var/lock/subsys/kibana" but didn't work. Here is my script :
#!/bin/bash
KIBANA_PATH="/opt/kibana4"
DESC="Kibana Daemon"
NAME=kibana
DAEMON=bin/kibana
CONFIG_DIR=$KIBANA_PATH/config/kibana.yml
LOGFILE=/var/log/kibana/kibana.log
#ARGS="agent --config ${CONFIG_DIR} --log ${LOGFILE}"
SCRIPTNAME=/etc/init.d/kibana
PIDFILE=/var/run/kibana.pid
base=kibana
# Exit if the package is not installed
if [ ! -x "$KIBANA_PATH/$DAEMON" ]; then
{
echo "Couldn't find $DAEMON"
exit 99
}
fi
. /etc/init.d/functions
#
# Function that starts the daemon/service
#
do_start()
{
cd $KIBANA_PATH && \
($DAEMON >> $LOGFILE &) && \
success || failure;
}
set_pidfile()
{
pgrep -f "kibana.jar" > $PIDFILE
}
#
# Function that stops the daemon/service
#
do_stop()
{
pid=`cat $PIDFILE`
if checkpid $pid 2>&1; then
# TERM first, then KILL if not dead
kill -TERM $pid >/dev/null 2>&1
usleep 100000
if checkpid $pid && sleep 1 &&
checkpid $pid && sleep $delay &&
checkpid $pid ; then
kill -KILL $pid >/dev/null 2>&1
usleep 100000
fi
fi
checkpid $pid
RC=$?
[ "$RC" -eq 0 ] && failure $"$base shutdown" || success $"$base shutdown"
}
case "$1" in
start)
echo -n "Starting $DESC: "
do_start
touch /var/lock/subsys/$NAME
set_pidfile
;;
stop)
echo -n "Stopping $DESC: "
do_stop
rm /var/lock/subsys/$NAME
rm $PIDFILE
;;
restart|reload)
echo -n "Restarting $DESC: "
do_stop
do_start
touch /var/lock/subsys/$NAME
set_pidfile
;;
status)
echo $DESC
status -p $PIDFILE
echo $!
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
exit 3
;;
esac
echo
exit 0
any help here ?
Thanks
use lockfile -r0 /path/to/lock/file.lck when you start the service. every new access then will retry zero times to create the file. so if that command fails do nothing or start the service otherwise.
lockfile -r0 /path/to/lock/file.lck
if [ "$?" == "0" ]; then
echo "lock does not exist. enter devils land :)"
fi
The following is a pretty standard implementation of this feature used by most init.d scripts.
start () {
[ -d /var/run/nscd ] || mkdir /var/run/nscd
[ -d /var/db/nscd ] || mkdir /var/db/nscd
echo -n $"Starting $prog: "
daemon /usr/sbin/nscd $NSCD_OPTIONS
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/nscd
return $RETVAL
}
...
# See how we were called.
case "$1" in
start)
[ -e /var/lock/subsys/nscd ] || start
RETVAL=$?
;;
...
I have the standard unicorn_init.sh file sym-linked to my /etc/init.d
#!/bin/sh
set -e
# Example init script, this can be used with nginx, too,
# since nginx and unicorn accept the same signals
# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}
APP_ROOT=<APP HOME DIRECTORY>
PID=$APP_ROOT/tmp/pids/unicorn.pid
CMD="cd $APP_ROOT; $APP_ROOT/bin/unicorn -D -c $APP_ROOT/config/unicorn.rb -E production"
action="$1"
set -u
old_pid="$PID.oldbin"
cd $APP_ROOT || exit 1
sig () {
test -s "$PID" && kill -$1 `cat $PID`
}
oldsig () {
test -s $old_pid && kill -$1 `cat $old_pid`
}
case $action in
start)
sig 0 && echo >&2 "Already running" && exit 0
su -c "$CMD" - <USER>
;;
stop)
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig HUP && echo reloaded OK && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
su -c "$CMD" - <USER>
;;
upgrade)
if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
then
n=$TIMEOUT
while test -s $old_pid && test $n -ge 0
do
printf '.' && sleep 1 && n=$(( $n - 1 ))
done
echo
if test $n -lt 0 && test -s $old_pid
then
echo >&2 "$old_pid still exists after $TIMEOUT seconds"
exit 1
fi
exit 0
fi
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
su -c "$CMD" - <USER>
;;
reopen-logs)
sig USR1
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
exit 1
;;
esac
Saying
service unicorn_<APP NAME> start
app boots no problem and browser resolves all requests
but when I try to stop the service
service unicorn_<APP NAME> stop
I get the error from the file "Not running", I try to restart
service unicorn_<APP_NAME> restart
I get the error:
Couldn't reload, starting 'cd <APP_NAME>; <APP_NAME>/bin/unicorn -D -c <APP_NAME>/config/unicorn.rb -E production' instead
master failed to start, check stderr log for details
I think it is because it loses track of the pid for the worker processes and checking the /tmp/pid area unicorn.pid does not exist and if I create a blank one it makes no difference.
Any help appreciated.
I have this script which I would like to switch to the user "terraria" before starting the daemon. I can't figure out how to do it. My research brings me to bash scripts using su my_user -c, but I don't think that works in this case.
#!/bin/bash
# Terraria daemon
# chkconfig: 345 20 80
# description: Terraria Server
# processname: TerrariaServer.exe
DAEMON_PATH="/usr/Terraria"
DAEMON=TerrariaServer.exe
DAEMONOPTS="-world This_Land.wld -port 7777 "
NAME=TerrariaServer
DESC="Terraria Server"
PIDFILE=/var/run/TerrariaServer.pid
SCRIPTNAME=/etc/init.d/Terraria-Server
case "$1" in
start)
printf "%-50s" "Starting $NAME..."
cd $DAEMON_PATH
PID=`mono $DAEMON $DAEMONOPTS > /dev/null 2>&1 & echo $!`
#echo "Saving PID" $PID " to " $PIDFILE
if [ -z $PID ]; then
printf "%s\n" "Fail"
else
echo $PID > $PIDFILE
printf "%s\n" "Ok"
fi
;;
status)
printf "%-50s" "Checking $NAME..."
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then
printf "%s\n" "Process dead but pidfile exists"
else
echo "Running"
fi
else
printf "%s\n" "Service not running"
fi
;;
stop)
printf "%-50s" "Stopping $NAME"
PID=`cat $PIDFILE`
cd $DAEMON_PATH
if [ -f $PIDFILE ]; then
kill -HUP $PID
printf "%s\n" "Ok"
rm -f $PIDFILE
else
printf "%s\n" "pidfile not found"
fi
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {status|start|stop|restart}"
exit 1
esac
Check out the following link for the 'DJB' way of starting up processes as other users:
http://thedjbway.b0llix.net/daemontools/uidgid.html
Also, see:
How to run a command as a specific user in an init script?
I'd like to have an init.d daemon restart my node.js app if it crashes. This script starts/stops my node app. I've had no luck getting it to restart the app if it crashes.
I'm running under CentOS. What am I missing?
#!/bin/sh
. /etc/rc.d/init.d/functions
USER="rmlxadmin"
DAEMON="/usr/bin/nodejs"
ROOT_DIR="/home/rmlxadmin"
SERVER="$ROOT_DIR/my_node_app.js"
LOG_FILE="$ROOT_DIR/app.js.log"
LOCK_FILE="/var/lock/subsys/node-server"
do_start()
{
if [ ! -f "$LOCK_FILE" ] ; then
echo -n $"Starting $SERVER: "
runuser -l "$USER" -c "$DAEMON $SERVER >> $LOG_FILE &" && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
else
echo "$SERVER is locked."
RETVAL=1
fi
}
do_stop()
{
echo -n $"Stopping $SERVER: "
pid=`ps -aefw | grep "$DAEMON $SERVER" | grep -v " grep " | awk '{print $2}'`
kill -9 $pid > /dev/null 2>&1 && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
}
case "$1" in
start)
do_start
;;
stop)
do_stop
;;
restart)
do_stop
do_start
;;
*)
echo "Usage: $0 {start|stop|restart}"
RETVAL=1
esac
exit $RETVAL
You need to use additional tools like node-supervisor for this case.
Install node-supervisor with npm:
sudo npm install -g supervisor
Change DAEMON variable in your init.d script to node-supervisor executable: /usr/bin/supervisor. You can check this path using command 'whereis supervisor' in your system (after installation, of course).
Now supervisor will restart your application if it's crash.