Best Way to Write a Linux Daemon

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 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>

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:

  • Linux-UNIX-Programmierung - German
  • Unix Daemon Server Programming

best way to write a linux daemon

It depends on your application. Threads and forking can both be perfectly valid approaches, as well as the third option of a single-threaded event-driven model. If you can explain a bit more about exactly what you're writing, it would help when giving advice.

For what it's worth, here are a few general guidelines:

  • If you have no shared state, use forking.
  • If you have shared state, use threads or an event-driven system.
  • If you need high performance under very large numbers of connections, avoid forking as it has higher overhead (particularly memory use). Instead, use threads, an event loop, or several event loop threads (typically one per CPU).

Generally forking will be the easiest to implement, as you can essentially ignore all other connections once you fork; threads the next hardest due to the additional synchronization requirements; the event loop more difficult due to the need to turn your processing into a state machine; and multiple threads running event loops the most difficult of them all (due to combining other factors).

Writing a linux daemon

RHEL7 uses systemd as its init system, which will take care of most of your requirements. You should write a systemd unit file for your daemon (called a service in systemd parlance). It can then:

  • start automatically: Yes, with systemctl enable yourservice.
  • run as specific user: Yes, set a User key in your unit file.
  • has access to the entire filesystem: Yes, it will have all the permissions your configured user has, and create files as that user.
  • can be controlled through service start: Yes, or through systemctl start.
  • automatically restart after crash: Yes, set a Restart key in your unit file (for example, on-failure or always).
  • write to syslog: Any output your program writes to standard output is written to the systemd journal, where it can be viewed with journalctl and/or written to syslog, as needed.

Your application doesn't need to (and shouldn't) daemonize itself when run under a modern init system. This goes not only for systemd but also for upstart, as well as supervisors like runit, daemontools, supervisord and most everything else. Daemonizing is a bit finicky and easy to get wrong. Just write your application like you normally would, and let an init system do its thing.

What is the preferred way to write my linux daemons?

Perl and Python are default answers for writing such scripts. But it doesn't matter (much) what language you use if you write good code. The more importat thing is that how you handle your script on failure.

In the long run you may see your scripts are failing seldom for arbitrary reasons, and it may not worth for you to debug the script because it usually does a fair job and it would be difficult to find where it went wrong.

I have few perl scripts doing the same kind of thing that you are doing. to me the tricky part was to make sure that my scripts don't fail for long because I didn't want to miss a chunck of live streamed data.

And for that I used monit . A great tool.

Best way to make a shell script daemon?

Use your system's daemon facility, such as start-stop-daemon.

Otherwise, yes, there has to be a loop somewhere.

Need to write a daemon in linux, not sure what to use C++ or C

I can answer this one entirely in code. Writing a daemon roughly consists of doing this:

/*
* Daemon Initialisation:
* 1. Fork()
* 2. setsid()
* 3. Fork() do we need to do this twice?
* 4. Chdir /
* 5. Umask(0)
* 6. Close STDIN/OUT/ERR
* 7. Optionally re-open stuff.
*
* Refs:
* 1. http://www.faqs.org/faqs/unix-faq/programmer/faq/
* 2. http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html
* 3. http://www.enderunix.org/docs/eng/daemon.php
*/

/* Variables */
/* Our process ID and Session ID */

pid_t pid, sid;
int fd = 0;

/* Fork off the parent process */
pid = fork();
if (pid < 0)
{
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
* we can exit the parent process.
*/
if (pid > 0)
{
exit(EXIT_SUCCESS);
}

/* Create a new SID for the child process */
sid = setsid();

if (sid < 0)
{
/* Log the failure */
exit(EXIT_FAILURE);
}

/* Fork off the parent process, again */
pid = fork();
if (pid < 0)
{
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0)
{
exit(EXIT_SUCCESS);
}

/* Change the current working directory */
if ((chdir("/")) < 0)
{
/* Log the failure */
exit(EXIT_FAILURE);
}

/* Change the file mode mask */
umask(0);

/* Close all file descriptors */

for (fd = getdtablesize(); fd >= 0; --fd)
{
close(fd);
}

/* Open standard file descriptors from
* elsewhere.
* e.g. /dev/null -> stdin.
* /dev/console -> stderr?
* logfile as stdout?
*/
fd = open("/dev/null", O_RDWR); /* open stdin */
dup(fd); /* stdout */
dup(fd); /* stderr */

These are all C function calls, but of course, you can call them from C++.

The reason I have this code sat around is because it's actually a function I pass function pointers to which executes my "daemon body". Why do I do it this way? To work out where my errors are running the code directly as a process (if necessary with root privs) then I "daemonise". It's quite hard to debug a daemon process otherwise...

Edit: of course, using function pointers is a C way of thinking, but there's no reason you can't implement some form of class-based mechanism.

So, honestly, it really doesn't matter. Pick whichever you prefer.

How to write a Java daemon

How to write a Java daemon that has 24/7 uptime...

We run a number of 24/365 applications on our Linux servers that just call the Java like the following -- no need for any C wrappers:

nohup java -D... -X... -jar something.jar ... < /dev/null > output.log 2>&1 &

That will put the jar running in the background (nohup ... &) with no input (< /dev/null) and the output (stdout and stderr) redirected to a logfile (> output.log 2>&1). We have distributed logging infrastructure but some console output (such as thread dumps) is still expected. These applications can run for months until we upgrade them.

Can nagios be configured to monitor whether or not my daemon is running, and to alert me or the sys admin when it isn't?

In terms of monitoring, there is much you can do. Nagios looks to have a JMX plugin for testing the information that jconsole displays. There are also a lot of native JMX logging and monitoring utilities out there. We have internal green/yellow/red indicators that can be pulled up using JMX and easily checked. I also have exported a simple JMX/HTTP service from each application to provide status information making it easy for 3rd party monitoring tools to detect failures.

This will be an SMPP client app (or ESME app I guess) which is why I've chosen Java as it seems to be a very mature platform for SMPP.

I assume you mean SMPP? If so then I see no reason why Java couldn't do a good job. Our applications do a wide variety of HTTP, UDP, SMTP, JDBC, LDAP, and other protocols in real time. We use Jgroups at lot which accomplishes a complete authenticated, encrypted, network stack in Java.

What's the best way to manage deployment of new builds? Just stop the daemon and replace the binary as quickly as possible and restart?

In terms of replacing a running binary on the fly, that it more complicated. We have VIPs up front and replace the binaries at our leisure. Our internal protocols are designed to failover. If you do not have a VIP then one thing to consider would be an orderly handoff. You boot the new jar and it talks to the application running the old jar when it is ready to bind to the new port. Then the old application unbinds and the new one binds immediately afterwards. Something like that.

Hope this helps.

Installable Linux daemons, how to create them in C++?

Ok, the first thing, you need to know that writing services in Windows and Linux is very different. First of all, in Linux, "services" are not called "services", they're called "daemons". Knowing that, you can use google to find this extremely useful document.

As for starting/stopping/restarting, there is no universal premade solution here. In most cases, daemons create *.pid files in /var/run; those files contain their process identifiers "PIDs". Then a simple bash script is written that controls the daemon execution by reading the pid from the appropriate file and sending a kill signal to it.

For example, suppose your daemon name is foo. Then it will create the file /var/run/foo.pid and write its PID into it, using ASCII characters and appending a newline at the end. Your control script name would be fooctl, it should support the following commands: start, stop and restart. That is, when you run fooctl start, the script should first check if the corresponding pid file exists, if not, then do whatever is necessary to start the daemon; when you run fooctl stop, it should read the pid from /var/run/foo.pid and kill the process with that ID. In case of fooctl restart, your script will need to first stop the daemon, then start it again.

That all being said, it is just an agreement about how daemons should work. This is how it's usually done. But those rules are not enforced in any way. You are free to invent and use your own techniques for creating and controlling daemons.

As for the second part of your question (about apt-get), this is called package management. It has nothing to do with daemons, but since you asked: to do it with your custom application, you would need to publish it in the main repository, which might be impossible for a number of reasons; or you can create your own repo. Also you can assemble a *.deb package for your application and it will be just as easy to install. Search the web for more info on how to build packages for custom Linux applications.



Related Topics



Leave a reply



Submit