6

I have a C program which I want to run as a daemon. How do I install it so it will run as a daemon on CentOS? Someone said to use @reboot, and some said to put it in /etc/rc.d/rc.local. Which is the right way?

migrated from serverfault.com Dec 12 '11 at 6:42

This question came from our site for system and network administrators.

  • 2
    Note that daemon has a special meaning, daemon listens for input for the program control data over the network listener interface is said to be daemon, generally. However, any program which runs in background interface silently doing its work without any bother is also said to be interpreted to be in the leagues of daemon. – Nikhil Mulley Dec 12 '11 at 7:40
7

Neither. If you want to have it behave properly like a real daemon you should place it using the init system - /etc/init.d ( and make appropriate runlevel links in the appropriate /etc/rc.X folders )

Run a search or have a look at something like this: https://serverfault.com/questions/204695/comprehensive-guide-to-init-d-scripts

  • dear thinice,according to the link it say look for the skeletion file under the /etc/init.d I do not find under my centos? So what should I do next? – newbie14 Dec 12 '11 at 8:49
  • just start it from /etc/rc.local like this: /path/to/my/binary & e.g. /usr/local/bin/newbie14program & running it from cron will also work: @reboot /usr/local/bin/newbie14program – Folkert van Heusden Dec 12 '11 at 9:12
  • but according to thinice it wont behave well with cron? Ok I want to learn further from you regarding the /etc/rc.local? What must I do must I edit this file? What must I add. When I compile my C I get a an executable file as output? So what should I do next? – newbie14 Dec 12 '11 at 12:46
  • 1
    ... For starters, does your C program run as a daemon at all? IE, does it fork into the background so it can keep running even after you close the shell? – Shadur Dec 12 '11 at 13:30
  • @Shadur 's question is important- if it is a daemon as you say, you should look in /etc/init.d - ls the directory, there should always be some sort of README-like file in there for setting up an init script. If it's not a daemon, then /etc/rc.local / crontab @reboot should work fine, you'll need to set your path in these files in most cases. – thinice Dec 12 '11 at 14:58
1

Assuming that you're writing a network daemon, the easiest way would be to write your C program to interface to xinetd/inetd and leave the daemon-ing to the xinetd/inetd tool.

  • @sybreaon what this inetd? how better is this xinetd compare to daemontool because I am kind of confuse here too many methods? – newbie14 Dec 20 '11 at 16:36
  • daemontools is designed to complement something like SysV init to start up services. inetd is a daemon itself and can be configured to execute external applications when something connects to it from the network. inetd can be found on all distros while daemontools less so. – sybreon Dec 21 '11 at 1:38
  • @sybereon actually i am newbie into both this tools. Yes I have read about inetd is more link towards network stuff. So any good tutorial for me to start my daemon properly via it? Cause I google and found many confusing things. – newbie14 Dec 21 '11 at 3:06
  • This is not a good place for a detailed guide. It might be better for you to ask specific questions that confuse you as individual questions. – sybreon Dec 21 '11 at 14:37
0

If the user is wanting to write something to listen to a network service that you do not want running all the time, but only as needed you would probably be best to run it under inetd/xinetd, associate it with the proper port and run it that way.

The init.d also known as "services" on various flavors of *NIX are for running programs that are intended to be operational at different run levels (e.g., startup, shut down, single-user, multi-user, with a network, without, with a graphic interface, etc.). These services are intended to run continuously whether they are being accessed or not (e.g., like a database).

For example, a database would be started/stopped with init.d/services/systemctl and so it would have scripts that would start it up during multi-user+network startup and it would have a corresponding script that would shut it down properly during a shutdown process before the network get's shut off. These scripts get placed in /etc/init.d/ and are symlinked to the correct run-level (/etc/init.d/rc2.d = runlevel2, rc3.d = runlevel 3, etc.). You can identify what your various possible run-levels are by looking at the "/etc/inittab" file. You can see what runlevel you are at by typing "runlevel" or "uptime" depending on your flavor of *NIX. The database would run even when nobody was connected to it from the network or locally.

But if you have something small like a telnet daemon, finger daemon, whois daemon, etc., that are more closely coupled with OS behavior and you do not want it in memory all the time, only when it is needed you would run that under inetd/xinetd. Essentially inetd/xinetd is the "super server" and when it sees a connection of a specific type on a specific port it launches a daemon to process that message and then re-spawn on a separate port and when done, exit. This way you can have hundreds, thousands of processes spawn to handle connections based on available system resources.

If you want to run your c program as a "service" with an init run-level then you would write your program to do it's function, then you would write a script that supports a stop argument and a stop argument. You would then put that script in /etc/init.d/. Then you would make a symlink to that script in the appropriate run-level directories (e.g., rc3.d) and that symlink for startup would either start with a capital 'S' meaning it is both active and should be run at start time, followed immediately a number such as '01' if you want it to run ahead of anything else in that runlevel or '99' if you want it to run last in that run-level. The reason this is important is you would not want to start a service that depends on another service such as DNS, or NFS or even networking and those not be available. You would want to give it a number AFTER those processes get started. When the system calls your script S99domything it passes the word "start" as argument #1 and inside your script you should have a switch-case that at the "start" choice launches your process. If you want to disable your script but not delete it, rename it so it starts with a lowercase 's' (e.g., "s99domything").

Likewise, to have an orderly shutdown of your process you would put a 'K' in front of the symlink to the /etc/init.d/domything script such as K01domything. Now, if you need your script to start AFTER some other process, when you want it to get shut down it should probably shutdown BEFORE that other process. So if your startup is S99domything, then your shutdown might well be K01domything. And when the init process finds a script starting with a K it sends the first argument as "stop" when it calls the script. You need to have a "stop" case in your script that shuts your service down properly.

Pretty clever.

This is also why using /sbin/shutdown is important because it causes init to go through the proper startup/shutdown sequence so that everything gets handled in an "orderly" fashion, reducing data loss or corruption.

Some examples:

/etc/rc3.d/S25mysql is a symlink to /etc/init.d/mysql.sh
/etc/rc5.d/K01mysql is a symlink to /etc/init.d/mysql.sh

In both cases the symlinks point back to the same /etc/init.d file, but when the init process launches them it passes a "start" or "stop" basedon whether the first character was a "S" or a "K".

Hope this helps explain a few things that are consistent with minor variations across almost every flavor of *NIX.

In more modern versions of *NIX inetd/xinetd has fallen out of favor in lieu of using systemctl/services. That's a shame because it had it's place and was reliable and easy to use. You can see what all the various ports were assigned to over the years by looking at /etc/services. Any port 1024 or below must be serviced by a root-owned process.

Cheers! -D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.