Create a systemd daemon
Like it or hate it, you’ll find systemd on any modern linux system these days. This management subsystem is the newer replacement for the older init scripts-based systems.
In today’s article, I’m going to show you how to create a daemon that will sit under the management of systemd.
.service file
A service file instructs systemd how to interact with the deployed application. It’s referred to as the service unit configuration. The following is an example:
[Unit] Description=My Service After=network.target [Service] ExecStart=/usr/bin/my-service Restart=on-failure [Install] WantedBy=multi-user.target
Installation
This file, once you’ve created it gets deployed to systemd with a cp . You also need to notify systemd.
sudo cp my-service.service /lib/systemd/system sudo systemctl daemon-reload sudo systemctl enable my-service
Interacting with the service
Once the service is in place, you can start to interact with the daemon using systemctl .
sudo systemctl start my-service sudo systemctl status my-service
You can also get a hold of any log pushed out to the standard system file descriptors:
journalctl --unit my-service --follow
Removal
Once you no longer need your service, you can remove it simply my rm ‘ing the .service file. Of course, you’ll need to disable your service first.
That’s it for creating a systemd service.
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.
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. ).
Further reading:
How To Create A Daemon In Linux?
Recently we struck up with a problem. The problem is to run a script continuously in background and continuously check for a folder content changes. If any modifications are done in that folder, the script once again should start one more script. We thought of doing this by using crontab. But the problem with crontab is we have to wait at least one minute to run our script. One minute is too long for my requirement. We require a solution which runs continuously in background at every micro second, it should be similar to a normal Linux daemon such as httpd, ssh, ftp etc. I have searched in Google for creating daemons in Linux. But most of the people suggested to write a daemon in C language, which is alien to me(I have learnt C language some 9 years back but now totally forgot it 🙁 ). Here is one such link which will describe you how to create a daemon in Linux using C programming.
I went through many documentations and other stuff but come to a conclusion to go with Shell script. Which will work same as daemon. Here is the code for the daemon which we accomplish using while loop
This while loop continuously runs because we give condition as true for this while loop and then written a if statement what to do. Once you create above script there are other points to mention, such as below once to make above script as a daemon..
So how to run the above script?
Ans : Use nohup when running the script. For those people who don’t know nohup command here is the explnation.
nohup is a command to run a program thought you logout from the machine. For example here is my script with nohup.
nohup sh daemon.sh
But some times this will not work. At that time run this script from crontab once and then remove the entry from crontab.
So how to make this permanent?
Ans : Its simple. keep your script in /etc/init.d with execute permissions
cp /path/to/script/daemon.sh /etc/init.d/
chmod +x /etc/init.d/daemon.sh
Then create a link file to this script to the corresponding run-level. This is required at the time of booting.
ln -s /etc/init.d/daemon.sh /etc/rc.d/rc3.d/S43daemon.sh
ln -s /etc/init.d/daemon.sh /etc/rc.d/rc3.d/K43daemon.sh
What are those above two command will do?
Ans : The S43 will tell the system to start the script as 43 script when it boots up.
The K43 will tell the system to shutdown cleanly when you do a shut down.
Please share your thoughts if you have better idea to do it:-)
Surendra Anne
Mr Surendra Anne is from Vijayawada, Andhra Pradesh, India. He is a Linux/Open source supporter who believes in Hard work, A down to earth person, Likes to share knowledge with others, Loves dogs, Likes photography. He works as Devops Engineer with Taggle systems, an IOT automatic water metering company, Sydney . You can contact him at surendra (@) linuxnix dot com.
Latest posts by Surendra Anne (see all)
- Docker: How to copy files to/from docker container — June 30, 2020
- Anisble: ERROR! unexpected parameter type in action: Fix — June 29, 2020
- FREE: JOIN OUR DEVOPS TELEGRAM GROUPS — August 2, 2019
- Review: Whizlabs Practice Tests for AWS Certified Solutions Architect Professional (CSAP) — August 27, 2018
- How to use ohai/chef-shell to get node attributes — July 19, 2018