[systemd-devel] How to run forking daemon with systemd in correct way, without errors?
Lennart Poettering
lennart at poettering.net
Thu Nov 23 14:55:12 UTC 2017
On Do, 23.11.17 11:32, Gena Makhomed (gmm at csdoc.com) wrote:
> On 23.11.2017 7:45, Mantas Mikulėnas wrote:
>
> > > This is bug in nginx code? And this bug should be fixed in nginx?
> > >
> > > But "daemon(); write_pidfile();" is common pattern
> > > used by many services and even in library functions.
>
> > It may be common, but not necessarily correct. The parent process should
> > only exit *after* finishing all the preparations (i.e. something like
> > "fork(); write_pidfile(); exit()"), since systemd uses the exit as a signal
> > that the daemon is now "ready".
>
> You are joking? Why you think that this pattern is not correct?
It doesn't work on SysV init either: "/etc/init.d/ngnx start ;
/etc/init.d/ngnx stop" is racy as it will leave ngnx running if it the
PID file isn't written by the time the stop command is used.
> Is any systemd documentations exists, which requires from daemons
> write pidfile of daemon process before exiting the parent process?
Yes:
https://www.freedesktop.org/software/systemd/man/daemon.html
> Does you see daemon() function from The GNU C Library (glibc)?
> It exits from parent process immediately, without writing pid file.
> Probably you should first fix function daemon() from glibc to meet systemd
> requirements? And after this - rewrite all existing daemons?
daemon() is hard to use properly, but it's possible: create a pipe()
first, then invoke daemon(). Then write the PID file in the daemon
process. Then close both sides of the pipe in the daemon process. In
the parent close the writing side, and read() from the reading
side. It will block until the daemon side closed its fds, and then get
EOF. And there, you got your synchronization done properly.
> Or may be it will be simpler to fix root cause of problem in
> systemd?
Well, I wish you good luck fixing SysV init scripts too. Before we
talk about "fixing systemd", let's talk how do you intend to make
"/etc/init.d/ngnx start ; /etc/init.d/ngnx stop" work correctly,
without races, without sometimes leaving ngnx running, if you don't
wait for the PID file to be written safely before exiting.
Lennart
--
Lennart Poettering, Red Hat
More information about the systemd-devel
mailing list