systemd kill my processes before ExecStop completed - linux

I'm trying to update my application to use it with systemd.
When I have used Upstart, I've just create a /etc/init.d/myService script:
#!/bin/bash
#chkconfig: 2345 90 10
#description: myDescription
### BEGIN INIT INFO
# Provides: myService
# Required-Start: sshd
# Required-Stop: sshd
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start myService
# Description:
### END INIT INFO
SCRIPT=$(readlink -f $0)
lockfile="/var/lock/subsys/myService"
do_start() {
if [ -d "/var/lock/subsys" ]; then
touch $lockfile
fi
...
}
do_stop() {
...
if [ -d "/var/lock/subsys" ]; then
if [ -f "$lockfile" ]; then
rm -f $lockfile
fi
fi
}
do_status() {
...
}
case "$1" in
start)
do_start
exit 0
;;
stop)
do_stop
exit 0
;;
status)
do_status
exit 0
;;
restart)
do_stop
do_start
exit 0
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
exit 3
;;
esac
And all were fine.
Notice, this script generate some subprocesses which will executing in background.
To use it with systemd, I made the follow service file (myService.service):
[Unit]
Description=My Description
Requires=sshd.service
After=sshd.service
Before=shutdown.target reboot.target halt.target
[Service]
Type=oneshot
ExecStart=/etc/init.d/myService start
ExecStop=/etc/init.d/myService stop
RemainAfterExit=yes
KillMode=none
[Install]
WantedBy=multi-user.target
If I run
systemctl stop myService.service
All work fine. My application stop successfully by /etc/init.d/myService stop command.
But I've got the follow issue:
When I reboot the system, and /etc/init.d/myService stop is executing, process which I should stop by myService script already killed. There are many processes which I should control ( around 7 processes ), and system should not terminated it itself.
I've tried to use Type=forking and specify the PIDFile as a pidfile of process, which has the longest life-time ( it should started first end stopped last ), however all my process were terminated again.
Is any simple way to avoid killing my subprocess?

Solution was found.
I ran hadoop & hbase, some of their components was starting by ssh-connection to localhost, and processes, which was started by this way, was unable to be controlled by systemd.
It was the design for distributed system, but in my case the work is going on the one machine. So I have replaced in hadoop/bin/slaves.sh
for slave in `cat "$HOSTLIST"|sed "s/#.*$//;/^$/d"`; do
ssh $HADOOP_SSH_OPTS $slave $"${#// /\\ }" \
2>&1 | sed "s/^/$slave: /" &
if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
sleep $HADOOP_SLAVE_SLEEP
fi
done
to
for slave in `cat "$HOSTLIST"|sed "s/#.*$//;/^$/d"`; do
eval "$#"
if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
sleep $HADOOP_SLAVE_SLEEP
fi
done
The problem was resolved and now processes are showing in service process tree.
Hbase probably has the same solution, but now it start with distributed=false and don't start any process by ssh.

Related

Start an Electron app at boot on Raspberry Pi 3 with yocto

I built an image with X11 using yocto for a Raspberry Pi 3 and a touchscreen. I can start my app built with Electron (chromium) by running commands manually in a serial session:
export DISPLAY=:0
/usr/lib/node/electron/dist/electron --no-sandbox /home/root/app
I though to use an init.d script to do it automatically at startup but I'd like to do it the proper way. I tried to create an .Xsession file in my user directory with the commands above but it doesn't work and I don't know if I can get logs of what happened.
According to this wiki, there is a lot of steps at X11 startup. Currently, I only see a Terminal (from Matchbox I guess) and a mouse cursor.
What's the "standard" way to start an app with the system and is there a way to remove the cursor for a touchscreen?
Edit
Here is the content of my /etc/X11 directory:
Xsession
Xsession.d/
xinit/
xorg.conf
Xsession:
#!/bin/sh
if [ -x /usr/bin/dbus-launch ]; then
# As this is the X session script, always start a new DBus session.
eval `dbus-launch --sh-syntax --exit-with-session </dev/null`
echo "D-BUS per-session daemon address is: $DBUS_SESSION_BUS_ADDRESS"
fi
. /etc/profile
if [ -f $HOME/.profile ]; then
. $HOME/.profile
fi
SYSSESSIONDIR=/etc/X11/Xsession.d
export CLUTTER_DISABLE_MIPMAPPED_TEXT=1
for SESSIONFILE in $SYSSESSIONDIR/*; do
set +e
case "$SESSIONFILE" in
*.sh)
. "$SESSIONFILE"
;;
*.shbg)
"$SESSIONFILE" &
;;
*~)
# Ignore backup files
;;
*)
"$SESSIONFILE"
;;
esac
set -e
done
exit 0
xorg.conf: empty.
Xsession.d/:
13xdgbasedirs.sh
30xinput_calibrate.sh
89xdgautostart.sh
90XWindowManager.sh
89xdgautostart.sh:
XDGAUTOSTART=/etc/xdg/autostart
if [ -d $XDGAUTOSTART ]; then
for SCRIPT in $XDGAUTOSTART/*; do
CMD=`grep ^Exec= $SCRIPT | cut -d '=' -f 2`
$CMD &
done
fi
90XWindowManager.sh:
if [ -x $HOME/.Xsession ]; then
exec $HOME/.Xsession
elif [ -x /usr/bin/x-session-manager ]; then
exec /usr/bin/x-session-manager
else
exec /usr/bin/x-window-manager
fi
There is also a file /etc/xserver-nodm/Xserver:
#!/bin/sh
# This script is only needed to make sure /etc/X11/xserver-common
# can affect XSERVER, ARGS & DPI: otherwise systemd could just use
# /etc/default/xserver-nodm as EnvironmentFile and sysvinit could just
# source the same file
. /etc/profile
# load default values for XSERVER, ARGS, DISPLAY...
. /etc/default/xserver-nodm
# Allow xserver-common to override ARGS, XSERVER, DPI
if [ -e /etc/X11/xserver-common ] ; then
. /etc/X11/xserver-common
if [ ! -e $XSERVER ] ; then
XSERVER=$(which $XSERVER)
fi
fi
if [ -n "$DPI" ] ; then
ARGS="$ARGS -dpi $DPI"
fi
exec xinit /etc/X11/Xsession -- $XSERVER $DISPLAY $ARGS $*
and a file /etc/rc5.d/S09xserver-nodm:
#!/bin/sh
#
### BEGIN INIT INFO
# Provides: xserver
# Required-Start: $local_fs $remote_fs dbus
# Required-Stop: $local_fs $remote_fs
# Default-Start: 5
# Default-Stop: 0 1 2 3 6
### END INIT INFO
killproc() { # kill the named process(es)
pid=`/bin/pidof $1`
[ "$pid" != "" ] && kill $pid
}
read CMDLINE < /proc/cmdline
for x in $CMDLINE; do
case $x in
x11=false)
echo "X Server disabled"
exit 0;
;;
esac
done
case "$1" in
start)
. /etc/profile
#default for USER
. /etc/default/xserver-nodm
echo "Starting Xserver"
if [ "$USER" != "root" ]; then
# setting for rootless X
chmod o+w /var/log
chmod g+r /dev/tty[0-3]
# hidraw device is probably needed
if [ -e /dev/hidraw0 ]; then
chmod o+rw /dev/hidraw*
fi
fi
# Using su rather than sudo as latest 1.8.1 cause failure [YOCTO #1211]
su -l -c '/etc/xserver-nodm/Xserver &' $USER
# Wait for the desktop to say its finished loading
# before loading the rest of the system
# dbus-wait org.matchbox_project.desktop Loaded
;;
stop)
echo "Stopping XServer"
killproc xinit
sleep 1
chvt 1 &
;;
restart)
$0 stop
$0 start
;;
*)
echo "usage: $0 { start | stop | restart }"
;;
esac
exit 0
The correct way to define a complete X session depends on your session manager: on Yocto that is often matchbox-session or mini-x-session. From your description I'd guess you're using mini-x-session (it happens to start a terminal and a window-manager if session file is not found).
Quoting mini-x-session:
if [ -e $HOME/.mini_x/session ]
then
exec $HOME/.mini_x/session
fi
if [ -e /etc/mini_x/session ]
then
exec /etc/mini_x/session
fi
So adding a /etc/mini_x/session script should work.
By the way, in your session file you may also want to start a window manager (X can do weird things without one):
your-app-here &
exec matchbox-window-manager

run jar-file on startup linux

I've used a standard bash-startup script for autostarting my Teamspeak Server - which works perfectly. Now I've done the same for the JTS3 Server Mod, problem: It's a .jar-file and doesn't start. If I run the .jar/startscript manually it works just fine.
Here's the script in /etc/init.d/
#!/bin/bash
### BEGIN INIT INFO
# Provides: jts3servermod
# Required-Start: $local_fs $network
# Required-Stop: $local_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: JTS3 Server Mod
### END INIT INFO
# INIT Script by www.SysADMINsLife.com
######################################
# Customize values for your needs: "User"; "DIR"
USER="ts"
DIR="/home/ts/JTS3ServerMod"
###### Teamspeak 3 server start/stop script ######
case "$1" in
start)
su $USER -c "${DIR}/jts3servermod_startscript.sh start"
;;
stop)
su $USER -c "${DIR}/jts3servermod_startscript.sh stop"
;;
restart)
su $USER -c "${DIR}/jts3servermod_startscript.sh restart"
;;
status)
su $USER -c "${DIR}/jts3servermod_startscript.sh status"
;;
*)
echo "Usage: {start|stop|restart|status}" >&2
exit 1
;;
esac
exit 0
of course it is linked in the runlevel-folders with update-rc.d jts3servermod defaults.
the servermod startscript (jts3servermod_startscript.sh) is:
#!/bin/sh
# JTS3ServerMod Linux start script
# Created by Stefan "Stefan1200" Martens
# The author of this script is not responsible for any damage or data loss!
JAVA_COMMANDLINE_PARAMETERS="-mx30M" # You can add java arguments here, like the -mx30M argument!
JTS3SERVERMOD_COMMANDLINE_PARAMETERS="" # You can add JTS3ServerMod arguments here, like the -config and -log argument!
BINARYPATH="$(pwd)" # This have to point to the JTS3ServerMod directory!
# Don't change the lines below, if you are not a sh script expert!
cd "${BINARYPATH}"
BINARYNAME="JTS3ServerMod.jar"
ROOTUID="0"
case "$1" in
java)
if which java >/dev/null 2>&1 ; then
echo "Java is already installed:"
java -version
else
if [ "$(id -u)" -ne "$ROOTUID" ] ; then
echo "Start this script as root to start the automatic installation of the Java runtime environment."
echo "You can also read the system requirements of the JTS3ServerMod in the readme.txt file for a manual installation of the Java runtime environment."
exit 6
else
read -p "Do you wish to install the Java runtime environment? (y/n) " yn
case $yn in
[Yy]* ) installJava; break;;
* ) echo "Aborted!"; exit 6;;
esac
fi
fi
;;
start)
if ! which java >/dev/null 2>&1 ; then
echo "The JTS3ServerMod needs the Java runtime environment installed to run!"
echo "Start this script with the java argument as root to start the automatic installation of the Java runtime environment:"
echo "$0 java"
echo "You can also read the system requirements of the JTS3ServerMod in the readme.txt file for a manual installation of the Java runtime environment."
exit 6
fi
if [ "$(id -u)" -eq "$ROOTUID" ] ; then
echo "For security reasons it is prefered not to run the JTS3ServerMod as root!"
fi
if [ -e jts3servermod.pid ]; then
if ( kill -0 $(cat jts3servermod.pid) 2> /dev/null ); then
echo "The JTS3ServerMod is already running, try restart or stop!"
exit 1
else
echo "jts3servermod.pid found, but no JTS3ServerMod running. Possibly your previously started JTS3ServerMod crashed!"
echo "Please view the logfile for details."
rm -f jts3servermod.pid
fi
fi
echo "Starting the JTS3ServerMod..."
if [ -e "$BINARYNAME" ]; then
java ${JAVA_COMMANDLINE_PARAMETERS} -jar ${BINARYNAME} ${JTS3SERVERMOD_COMMANDLINE_PARAMETERS} > /dev/null &
PID=$!
ps -p ${PID} > /dev/null 2>&1
if [ "$?" -ne "0" ]; then
echo "JTS3ServerMod could not start!"
else
echo $PID > jts3servermod.pid
echo "JTS3ServerMod started, for details please view the log file!"
fi
else
echo "Could not find the file $BINARYNAME, aborting!"
exit 5
fi
;;
stop)
if [ -e jts3servermod.pid ]; then
echo -n "Stopping the JTS3ServerMod.."
if ( kill -TERM $(cat jts3servermod.pid) 2> /dev/null ); then
c=1
while [ "$c" -le 120 ]; do
if ( kill -0 $(cat jts3servermod.pid) 2> /dev/null ); then
echo -n "."
sleep 1
else
break
fi
c=$(($c+1))
done
fi
if ( kill -0 $(cat jts3servermod.pid) 2> /dev/null ); then
echo "JTS3ServerMod is not shutting down cleanly - killing!"
kill -KILL $(cat jts3servermod.pid)
else
echo "done"
fi
rm -f jts3servermod.pid
else
echo "No JTS3ServerMod running (jts3servermod.pid is missing)!"
exit 7
fi
;;
restart)
$0 stop && $0 start || exit 1
;;
status)
if [ -e jts3servermod.pid ]; then
if ( kill -0 $(cat jts3servermod.pid) 2> /dev/null ); then
echo "JTS3ServerMod is running!"
else
echo "JTS3ServerMod seems to have died!"
fi
else
echo "No JTS3ServerMod running (jts3servermod.pid is missing)!"
fi
;;
*)
echo "Usage: ${0} {start|stop|restart|status|java}"
exit 2
esac
exit 0
I also tried to write an own simple script for only starting the jar and catching the pid and writing it into a file.
None of these scripts wanted to start my .jar file during the startup.
As you can see, the first script is a template for starting Teamspeak Servers during boot. I only replaced some stuff with my Server Mod paths and scripts and put into /etc/init.d/ (chmod 755 was executed of course).
Maybe some of you have other approaches to solve that strange circumstances.
I don't know if the problem was solved in the meantime, but while experimenting with the same issue. I figured out that the script could not find the jar file. So I added:
#!/bin/sh
# JTS3ServerMod Linux start script
# Created by Stefan "Stefan1200" Martens
# The author of this script is not responsible for any damage or data loss!
cd "$(dirname "$0")"
...
At the beginning of the jts3servermod_startscript.sh to ensure that the "working directory" is correct.
BTW - My init script:
jts-bot
#!/bin/sh
### BEGIN INIT INFO
# Provides: jts-bot
# Required-Start: $local_fs $network
# Required-Stop: $local_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: JTS3-Bot for TeamSpeak
### END INIT INFO
USER="teamspeak"
DIR="/home/teamspeak/JTS3ServerMod"
###### JTS3ServerMod start/stop script ######
case "$1" in
start)
su $USER -c "${DIR}/jts3servermod_startscript.sh start"
;;
stop)
su $USER -c "${DIR}/jts3servermod_startscript.sh stop"
;;
restart)
su $USER -c "${DIR}/jts3servermod_startscript.sh restart"
;;
status)
su $USER -c "${DIR}/jts3servermod_startscript.sh status"
;;
*)
echo "Usage: -bash {start|stop|restart|status}" >&2
exit 1
;;
esac
exit 0

init.d scripts works perfectly in console, bad poorly in systemd's service call

i have following init.d script.
#!/bin/sh
### BEGIN INIT INFO
# Provides: teamcity
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
start_cmd="start-stop-daemon --start -c root --chdir /srv/teamcity/TeamCity-9.1/bin --exec /srv/teamcity/TeamCity-9.1/bin/runAll.sh start"
stop_cmd="start-stop-daemon --start -c root --chdir /srv/teamcity/TeamCity-9.1/bin --exec /srv/teamcity/TeamCity-9.1/bin/runAll.sh stop"
user="root"
export TEAMCITY_DATA_PATH="/srv/teamcity/TeamCity-9.1/.BuildServer"
export TEAMCITY_PID_FILE_PATH="/var/run/teamcity.pid"
export TEAMCITY_SERVER_OPTS=-Djava.awt.headless=true
export TEAMCITY_SERVER_MEM_OPTS="-Xmx750m -XX:MaxPermSize=270m"
/etc/profile.d/java.sh
name="teamcity"
pid_file="/var/run/$name.pid"
stdout_log="/var/log/$name.log"
stderr_log="/var/log/$name.err"
get_pid() {
cat "$pid_file"
}
is_running() {
[ -f "$pid_file" ] && ps `get_pid` > /dev/null 2>&1
}
case "$1" in
start)
if is_running; then
echo "Already started"
else
echo "Starting $name"
$start_cmd >> "$stdout_log" 2>> "$stderr_log" &
sleep 1
if ! is_running; then
echo "Unable to start, see $stdout_log and $stderr_log"
exit 1
fi
fi
;;
stop)
if is_running; then
echo -n "Stopping $name.."
$stop_cmd >> "$stdout_log" 2>> "$stderr_log" &
for i in {1..20}
do
if ! is_running; then
break
fi
echo -n "."
sleep 1
done
if is_running; then
echo "Not stopped; may still be shutting down or shutdown may have failed"
exit 1
else
echo "Stopped"
if [ -f "$pid_file" ]; then
rm "$pid_file"
fi
fi
else
echo "Not running"
fi
;;
restart)
$0 stop
if is_running; then
echo "Unable to stop, will not attempt to start"
exit 1
fi
$0 start
;;
status)
if is_running; then
echo "Running"
else
echo "Stopped"
exit 1
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
If you using it directly from console like this
/etc/init.d/teamcity start
,it works very well. But with system'd "service" command not works.
Systemd is not be able to start Teamcity properly.
Systemd writes only one line on service teamcity start:
Started LSB: Start daemon at boot time.
Stopping service fails with:
teamcity.service: control process exited, code=exited status=1
Stopped LSB: Start daemon at boot time.
Unit teamcity.service entered failed state.
I spend three days googling and changing init file, but no suitable solution.
Any suggestions to fix that?
Leave SYSV init.d scripts and start using new systemd services notation is my last solution.
Thanks a lot
Here's a simple systemd service file that I stitched together that works for my installed version of TeamCity: v10.0.4 (build 42538):
[Unit]
Description=TeamCity Build Agent
After=network.target
[Service]
Type=simple
Environment="JAVA_HOME=/usr/java/jdk1.8.0_121"
ExecStart=/opt/teamcity/bin/startup.sh
ExecStop=/opt/teamcity/bin/shutdown.sh
[Install]
WantedBy=multi-user.target
You'll need to customize the Environment, ExecStart, and ExecStop variables to suit your installation of Java and TeamCity.

Linux: process into a service

I am trying to make a linux executable as a service
I execute my program like this below
java -jar mytestprogram.jar
creates a process that runs continuously and serves REST requests. But I want to run it as a service where I can do
service mytestprogram start
service mytestprogram stop
service mytestprogram status
chkconfig mytestprogram on
etc. What is the most simple way of doing it?
That depends on your system manager
the most common way to do that on debian/ubuntu is to build an initscript and place it in /etc/init.d or /etc/rc/init.d and place a script named mytestprogram in that.
this is an example initscript:
#!/bin/sh
### BEGIN INIT INFO
# Provides: testone
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: false
# Short-Description: Example init script
# Description: Start/stop an example script
### END INIT INFO
DESC="test script"
NAME=testone
#DAEMON=
do_start()
{
echo "starting!";
}
do_stop()
{
echo "stopping!"
}
case "$1" in
start)
do_start
;;
stop)
do_stop
;;
esac
exit 0
I suggest you to look some scripts in that directory, It's simple if you know bash a little ;)
Here is a sample shell script (make sure you replace the MAT name with the name of the your application):
I create one GitHubGist with the latest version of my script and a brief explanation to help those who need it. GitHub Gist link
#!/bin/bash
### BEGIN INIT INFO
# Provides: MATH
# Required-Start: $java
# Required-Stop: $java
# Short-Description: Start and stop MATH service.
# Description: -
# Date-Creation: -
# Date-Last-Modification: -
# Author: -
### END INIT INFO
# Variables
PGREP=/usr/bin/pgrep
JAVA=/usr/bin/java
ZERO=0
# Start the MATH
start() {
echo "Starting MATH..."
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "The service is already running"
else
#Run the jar file MATH service
$JAVA -jar /opt/MATH/MATH.jar > /dev/null 2>&1 &
#sleep time before the service verification
sleep 10
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "Service was successfully started"
else
echo "Failed to start service"
fi
fi
echo
}
# Stop the MATH
stop() {
echo "Stopping MATH..."
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
#Kill the pid of java with the service name
kill -9 $($PGREP -f MATH)
#Sleep time before the service verification
sleep 10
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "Failed to stop service"
else
echo "Service was successfully stopped"
fi
else
echo "The service is already stopped"
fi
echo
}
# Verify the status of MATH
status() {
echo "Checking status of MATH..."
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "Service is running"
else
echo "Service is stopped"
fi
echo
}
# Main logic
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart|reload)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|status|restart|reload}"
exit 1
esac
exit 0
In Ubuntu you can create the file as explained above with few lines, play around and see if it works for you.
description "My prog"
start on (net-device-up
and local-filesystems
and runlevel [2345])
stop on runlevel [!2345]
respawn
respawn limit 10 5
setuid root
setgid shnmon
script
/usr/local/bin/my_script -config.path /etc/myprog/yourconfig.xyz -children false >> /var/log/myprog.log 2>&1
end script
The "-config.path /etc/myprog/yourconfig.xyz" is optional incase you have a config file.
You can just edit the script part and test it and keep others default and edit the rest along the way

Call to daemon in a /etc/init.d script is blocking, not running in background

I have a Perl script that I want to daemonize. Basically this perl script will read a directory every 30 seconds, read the files that it finds and then process the data. To keep it simple here consider the following Perl script (called synpipe_server, there is a symbolic link of this script in /usr/sbin/) :
#!/usr/bin/perl
use strict;
use warnings;
my $continue = 1;
$SIG{'TERM'} = sub { $continue = 0; print "Caught TERM signal\n"; };
$SIG{'INT'} = sub { $continue = 0; print "Caught INT signal\n"; };
my $i = 0;
while ($continue) {
#do stuff
print "Hello, I am running " . ++$i . "\n";
sleep 3;
}
So this script basically prints something every 3 seconds.
Then, as I want to daemonize this script, I've also put this bash script (also called synpipe_server) in /etc/init.d/ :
#!/bin/bash
# synpipe_server : This starts and stops synpipe_server
#
# chkconfig: 12345 12 88
# description: Monitors all production pipelines
# processname: synpipe_server
# pidfile: /var/run/synpipe_server.pid
# Source function library.
. /etc/rc.d/init.d/functions
pname="synpipe_server"
exe="/usr/sbin/synpipe_server"
pidfile="/var/run/${pname}.pid"
lockfile="/var/lock/subsys/${pname}"
[ -x $exe ] || exit 0
RETVAL=0
start() {
echo -n "Starting $pname : "
daemon ${exe}
RETVAL=$?
PID=$!
echo
[ $RETVAL -eq 0 ] && touch ${lockfile}
echo $PID > ${pidfile}
}
stop() {
echo -n "Shutting down $pname : "
killproc ${exe}
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
rm -f ${lockfile}
rm -f ${pidfile}
fi
}
restart() {
echo -n "Restarting $pname : "
stop
sleep 2
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status ${pname}
;;
restart)
restart
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
;; esac
exit 0
So, (if I have well understood the doc for daemon) the Perl script should run in the background and the output should be redirected to /dev/null if I execute :
service synpipe_server start
But here is what I get instead :
[root#master init.d]# service synpipe_server start
Starting synpipe_server : Hello, I am running 1
Hello, I am running 2
Hello, I am running 3
Hello, I am running 4
Caught INT signal
[ OK ]
[root#master init.d]#
So it starts the Perl script but runs it without detaching it from the current terminal session, and I can see the output printed in my console ... which is not really what I was expecting. Moreover, the PID file is empty (or with a line feed only, no pid returned by daemon).
Does anyone have any idea of what I am doing wrong ?
EDIT : maybe I should say that I am on a Red Hat machine.
Scientific Linux SL release 5.4 (Boron)
Thanks,
Tony
I finally re-wrote the start function in the bash init script, and I am not using daemon anymore.
start() {
echo -n "Starting $pname : "
#daemon ${exe} # Not working ...
if [ -s ${pidfile} ]; then
RETVAL=1
echo -n "Already running !" && warning
echo
else
nohup ${exe} >/dev/null 2>&1 &
RETVAL=$?
PID=$!
[ $RETVAL -eq 0 ] && touch ${lockfile} && success || failure
echo
echo $PID > ${pidfile}
fi
}
I check that the pid file is not existing already (if so, just write a warning). If not, I use
nohup ${exe} >/dev/null 2>&1 &
to start the script.
I don't know if it is safe this way (?) but it works.
The proper way to daemonize a process is have it detach from the terminal by itself. This is how most larger software suites do it, for instance, apache.
The rationale behind daemon not doing what you would expect from its name, and how to make a unix process detach into the background, can be found here in section 1.7 How do I get my program to act like a daemon?
Simply invoking a program in the background isn't really adequate for
these long-running programs; that does not correctly detach the
process from the terminal session that started it. Also, the
conventional way of starting daemons is simply to issue the command
manually or from an rc script; the daemon is expected to put itself
into the background.
For further reading on this topic: What's the difference between nohup and a daemon?
According to man daemon correct syntax is
daemon [options] -- [command] [command args]
Your init script startup should run something like:
daemon --pidfile ${pidfile} -- ${exe}
As said here, it seems that the process needs to be sent to the background using &.
Daemon don’t do it for you.

Resources