Search code examples
clinuxdaemonrhel

Writing a linux daemon


What is the right way to write/configure application under Linux, that runs all the time and serves external requests (TCP, database, filesystem, any kind of them).

I specifically do not call this daemon, because it may mean something I do not want it to in Linux environment.

I already read multiple topics, including:

Linux daemonize

best way to write a linux daemon

Best practice to run Linux service as a different user

but none of them gives full comparison about which approach to use.

I see following options:

  • writing application which forks, calls setpid, umask, etc. but this requires application to perform many steps by itself; (with autostart by init.d?)
  • use daemon() init.d function which performs most of those steps for you (but is it portable to all/many linux distributions)
  • running application with & and trust it to run in background

But which of them is the way to go. Or if they all can be used, what constitutes daemon in Linux?

I am looking for an equivalent of running application as a service under windows (and any .exe can be automatically made for runs as a service with use of sc).


My requirements are as following:

  • start after boot (automatically)
  • runs as specific user (not root)
  • has access to entire filesystem (/) but creates/modifies files as user under which the application is run
  • can be controlled through service start, service stop
  • possibly automatically restart after crash or kill
  • can write to syslog
  • run under RHEL7

I am the author of the application, but would prefer not to alter it to handle daemonization.

My guess would be to write custom init.d script which in turn would call daemon() function from /etc/init.d/functions. Am I right?


Solution

  • 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.