Creating daemon process in linux

Creating a daemon in Linux

In Linux I want to add a daemon that cannot be stopped and which monitors filesystem changes. If any changes are detected, it should write the path to the console where it was started plus a newline. I already have the filesystem changing code almost ready but I cannot figure out how to create a daemon. My code is from here: http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html What to do after the fork?

int main (int argc, char **argv) < pid_t pID = fork(); if (pID == 0) < // child // Code only executed by child process sIdentifier = "Child Process: "; >else if (pID < 0) < cerr else // parent < // Code only executed by parent process sIdentifier = "Parent Process:"; >return 0; > 

possible duplicate of: stackoverflow.com/questions/5384168/… for the daemonize part, stackoverflow.com/questions/931093/… for the filesystem watch

If you don’t need POSIX compliance you may be interested in inotify API. See: inotify_init , inotify_add_watch , inotify_rm_watch .

9 Answers 9

In Linux i want to add a daemon that cannot be stopped and which monitors filesystem changes. If any changes would be detected it should write the path to the console where it was started + a newline.

Daemons work in the background and (usually. ) don’t belong to a TTY that’s why you can’t use stdout/stderr in the way you probably want. Usually a syslog daemon (syslogd) is used for logging messages to files (debug, error. ).

Besides that, there are a few required steps to daemonize a process.

If I remember correctly these steps are:

  • fork off the parent process & let it terminate if forking was successful. -> Because the parent process has terminated, the child process now runs in the background.
  • setsid — Create a new session. The calling process becomes the leader of the new session and the process group leader of the new process group. The process is now detached from its controlling terminal (CTTY).
  • Catch signals — Ignore and/or handle signals.
  • fork again & let the parent process terminate to ensure that you get rid of the session leading process. (Only session leaders may get a TTY again.)
  • chdir — Change the working directory of the daemon.
  • umask — Change the file mode mask according to the needs of the daemon.
  • close — Close all open file descriptors that may be inherited from the parent process.
Читайте также:  Connect to vpn pptp linux

To give you a starting point: Look at this skeleton code that shows the basic steps. This code can now also be forked on GitHub: Basic skeleton of a linux daemon

/* * daemonize.c * This example daemonizes a process, writes a few log messages, * sleeps 20 seconds and terminates afterwards. */ #include #include #include #include #include #include #include static void skeleton_daemon() < pid_t pid; /* Fork off the parent process */ pid = fork(); /* An error occurred */ if (pid < 0) exit(EXIT_FAILURE); /* Success: Let the parent terminate */ if (pid >0) exit(EXIT_SUCCESS); /* On success: The child process becomes session leader */ if (setsid() < 0) exit(EXIT_FAILURE); /* Catch, ignore and handle signals */ //TODO: Implement a working signal handler */ signal(SIGCHLD, SIG_IGN); signal(SIGHUP, SIG_IGN); /* Fork off for the second time*/ pid = fork(); /* An error occurred */ if (pid < 0) exit(EXIT_FAILURE); /* Success: Let the parent terminate */ if (pid >0) exit(EXIT_SUCCESS); /* Set new file permissions */ umask(0); /* Change the working directory to the root directory */ /* or another appropriated directory */ chdir("/"); /* Close all open file descriptors */ int x; for (x = sysconf(_SC_OPEN_MAX); x>=0; x--) < close (x); >/* Open the log file */ openlog ("firstdaemon", LOG_PID, LOG_DAEMON); > 
int main() < skeleton_daemon(); while (1) < //TODO: Insert daemon code here. syslog (LOG_NOTICE, "First daemon started."); sleep (20); break; >syslog (LOG_NOTICE, "First daemon terminated."); closelog(); return EXIT_SUCCESS; > 
  • Compile the code: gcc -o firstdaemon daemonize.c
  • Start the daemon: ./firstdaemon
  • Check if everything is working properly: ps -xj | grep firstdaemon
  • The output should be similar to this one:
+------+------+------+------+-----+-------+------+------+------+-----+ | PPID | PID | PGID | SID | TTY | TPGID | STAT | UID | TIME | CMD | +------+------+------+------+-----+-------+------+------+------+-----+ | 1 | 3387 | 3386 | 3386 | ? | -1 | S | 1000 | 0:00 | ./ | +------+------+------+------+-----+-------+------+------+------+-----+

What you should see here is:

  • The daemon has no controlling terminal (TTY = ?)
  • The parent process ID (PPID) is 1 (The init process)
  • The PID != SID which means that our process is NOT the session leader
    (because of the second fork())
  • Because PID != SID our process can’t take control of a TTY again

Reading the syslog:

  • Locate your syslog file. Mine is here: /var/log/syslog
  • Do a: grep firstdaemon /var/log/syslog
  • The output should be similar to this one:
firstdaemon[3387]: First daemon started. firstdaemon[3387]: First daemon terminated.

A note: In reality you would also want to implement a signal handler and set up the logging properly (Files, log levels. ).

Читайте также:  Linux iptables rules save

Further reading:

Источник

Daemonizing a Process in Linux

Most of the times when we need to run some Java, Node.js or python program in background, so it could stay running even after you leave console all we do is put “&” in the end of the command.

$java -jar SimpleService.jar &

The problem here is that when you leave the bash shell your process will become “Orphan” and it’s up to the OS if INIT should adopt the process or kill the process.

To fix this we can force the process to be detached from your shell and become child process of INIT by putting nohup in front of command.

$nohup java -jar SimpleService.jar &

It’s all good for testing purposes, but services are supposed to run as “daemons” under some service supervisor. You can find many service supervisors with which you manage your services on Linux and we will cover few of the defaults that come with Linux.

Why do you need it ?

a. auto start/stop the service on startup/shutdown
b. controlling which service should start first
c. controlling which service should stop first is equally important
d. INIT controlled processes directly which provides more options like respawn, post-start, etc..

Ubuntu services using Upstart

Modify the script according to your setup:

$sudo vi /etc/init/java-app.conf

[js]author «nitin»
description «start and stop java-app for Ubuntu (upstart)»
version «1.0»

start on started networking
stop on runlevel [!2345]

# Automatically Respawn a process if fails, try max 5 times in 60 sec then give up
respawn
respawn limit 5 60

# Open files Limit
limit nofile 32768 32768

env APPUSER=»admin»
env APPBIN=»/usr/bin/java»
env APPARGS=»-jar /opt/app/SimpleService.jar»

script
exec su – $APPUSER -c «$APPBIN $APPARGS»
end script

post-stop script
sleep 2
end script[/js]

Check the configuration:
$init-checkconf /etc/init/java-app.conf

Reload New configuration:
$sudo initctl reload-configuration

Check is service is known to Upstart:
$sudo initctl list |grep java

Start the service with:
$sudo start java-app

Note: For any errors look into /var/log/syslog and /var/log/upstart/*

Читайте также:  Проброс usb linux windows

Debian and Ubuntu services using SysVinit

Modify the script according to your setup.

### BEGIN INIT INFO
# Provides: daemon
# Required-Start: $local_fs $network $syslog
# Required-Stop: $local_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Java-app
# Description: Java-app start-stop-daemon – Debian
### END INIT INFO

NAME=»java-app»
PATH=»/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin»
APPDIR=»/opt/app»
APPBIN=»/usr/bin/java»
APPARGS=»-jar /opt/app/SimpleService.jar»
USER=»admin»
GROUP=»admin»

# Include functions
set -e
. /lib/lsb/init-functions

start() printf «Starting ‘$NAME’… »
start-stop-daemon –start –chuid «$USER:$GROUP» –background –make-pidfile –pidfile /var/run/$NAME.pid –chdir «$APPDIR» –exec «$APPBIN» — $APPARGS || true
printf «done\n»
>

#We need this function to ensure the whole process tree will be killed
killtree() local _pid=$1
local _sig=$
for _child in $(ps -o pid –no-headers –ppid $); do
killtree $ $
done
kill -$ $
>

stop() printf «Stopping ‘$NAME’… »
[ -z `cat /var/run/$NAME.pid 2>/dev/null` ] || \
while test -d /proc/$(cat /var/run/$NAME.pid); do
killtree $(cat /var/run/$NAME.pid) 15
sleep 0.5
done
[ -z `cat /var/run/$NAME.pid 2>/dev/null` ] || rm /var/run/$NAME.pid
printf «done\n»
>

status() status_of_proc -p /var/run/$NAME.pid «» $NAME && exit 0 || exit $?
>

Make sure the script is executable:
$chmod +x /etc/init.d/java-app

Enable the service to auto start in runlevel 2345:
$update-rc.d java-app defaults

Start the service with:
$service java-app start

CentOS/Redhat services using SysVinit

Modify the parameter according to your setup:
$sudo vi /etc/init.d/example

[js]#!/bin/sh
#
# example start stop daemon for CentOS (sysvinit)
#
# chkconfig: – 64 36
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 2 3 4 6
# Required-Start:
# description: java-app start stop daemon for CentOS
# processname: java-app
# pidfile: none
# lockfile: /var/lock/subsys/java-app

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ «$NETWORKING» = «no» ] && exit 0

USER=»admin»
APPNAME=»java-app»
APPBIN=»/usr/bin/java»
APPARGS=»-jar /opt/app/SimpleService.jar»
LOGFILE=»/var/log/$APPNAME/error.log»
LOCKFILE=»/var/lock/subsys/$APPNAME»

start() [ -x $prog ] || exit 5
[ -d $LOGPATH ] || mkdir $LOGPATH
[ -f $LOGFILE ] || touch $LOGFILE

echo -n $»Starting $APPNAME: »
daemon –user=$USER «$APPBIN $APPARGS >>$LOGFILE &»
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch $LOCKFILE
return $RETVAL
>

stop() echo -n $»Stopping $APPNAME: »
killproc $APPBIN
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f $LOCKFILE
return $RETVAL
>

Make sure the script is marked as executable:
$sudo chmod +x /etc/init.d/java-app

Enable the service to auto start at runlevels 2345:
$sudo chkconfig java-app on

Start the service with:
$sudo service java-app start

This is how simple it is to daemonize a process. In my next blog, I will talk about more interesting features available in Linux OS.

Источник

Оцените статью
Adblock
detector