Question

I have a service, say foo, written in C++, that runs as root. There is the usual scrip, /etc/init.d/foo start|stop|restart.

At certain times, foo needs to reload itself. Normally after an upgrade has finished. But doing things like:

system("/etc/init.d/foo restart")

doesn't work since as soon as restart kills foo, the system() call obviously gets killed as well, and the restart script never executes to completion.

Is there another call I can use instead of system() that runs asynchronously as a sibling to the calling process, instead of creating a synchronous child?

Thanks!

Was it helpful?

Solution

Have you considered the exec[*] family yet? Here's one -- execve.

OTHER TIPS

You could put it in inittab and let init worry about restarting the process when it exits for any reason. That would also take care of automatic restarts if your process happens to crash or assert() or otherwise exit unexpectedly.

Then, to handle your use case, the process would simply terminate itself.

how about fork() followed by exec()?

Consider implementing

/etc/init.d/foo reload

for your daemon (pretty standard judging by a grep of my Debian box).

This is typically done by sending the process a SIGHUP signal; the daemon should have a signal handler which catches this and reloads any configuration.

If the process knows it needs to reload it can just signal itself.

If you really do need to restart to pick up new libraries then go with exec*()

Combining the two answers so far, use a fork-exec.

To add to what Ori has already said, some Linux distros still use initab, but Ubuntu and possibly others have switched to /etc/event.d. You put a file in there (copy and edit one of the existing ones) then start the daemon with "sudo start ssh_tunnel" or whatever your file is called.

Then when you need it to restart, you can just kill it with a signal, and the system will restart it. Or it could decide on its own that it's time to restart, by calling "exit(0);" or whatever.

exec*() by itself on the original command line should do the trick. You can probably omit the fork, `cause then you have two copies running which you don't need, and the original copy then needs to exit.

But also look at inittab and event.d depending on your distro, to see if it will do what you need in a better way.

A third possibility to what Ori and Paul have suggested would be to use daemontools. It is more portable though less likely to be available. You create a script called /service/foo/run and daemontools will respawn your service whenever it exits.

http://cr.yp.to/daemontools.html

Look at the man page for inittab.

It describes how the system will auto restart your processes if it dies (respawn).

With this set up correctly all you service has to do is exit and the system will take care of the re-start (respawn) for you auto-magically.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top