6

My nginx unitfile is following,

[root@arif ~]# cat /usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Here, in the [Service] portion, the value of Type is equal to forking which means from here,

The process started with ExecStart spawns a child process that becomes the main process of the service. The parent process exits when the startup is complete.

My questions are,

  • Why a service does that?
  • What are the advantages for doing this?
  • What's wrong is Type=simple or other similar options?
arif
  • 1,459
  • 2
    It's a behavior due to historical reason, but it's not a recommended behavior in systemd world anymore. Systend simply provide this option to support old programs. – 炸鱼薯条德里克 Mar 04 '19 at 23:15

2 Answers2

8

Why a service does that?

Services generally do not do that, in fact. Aside from the fact that it isn't good practice, and the idea of "dæmonization" is indeed fallacious, what services do isn't what the forking protocol requires. They get the protocol wrong, because they are in fact doing something else, which is being shoehorned into the forking protocol, usually unnecessarily.

What are the advantages for doing this?

There aren't any. Better readiness notification protocols exist, and no-one actually speaks this protocol properly. This service unit is not doing this because it is advantageous.

What's wrong is Type=simple or other similar options?

Nothing. It is in fact generally the use of the forking readiness protocol that is wrong. This is not best practice, as claimed in other answers. Quite the reverse.

The simple fact is that this is the best of a bad job, a bodge to cope with a behaviour of nginx that still cannot be turned off. Most service softwares nowadays, thanks to a quarter of a century of encouragement from the IBM SRC, daemontools, and other serious service management worlds, have gained options for, or even changed their default behaviours to, not attempting to foolishly "dæmonize" something that is already in dæmon context.

This is still not the case for nginx, though. daemon off does not work, sadly. Just as many softwares used to erroneously conflate "non-dæmonize" mode with debug mode (but often no longer do, nowadays), nginx unfortunately conflates it with other things, such as not handling its control signals. People have been pushing for this for 5 years, so far.

Further reading

Elliott B
  • 565
JdeBP
  • 68,745
  • 1
    thanks for the bug link along with other link to help me understand dæmonization issue properly. – arif Mar 04 '19 at 23:17
  • This answer is wrong, at least if there are services depending on the service in question, because not forking causes the service in question to reach the running state before it is ready to be used. See my answer for an explanation. – Juergen Mar 18 '21 at 23:52
0

As long as the service in question does not specifically support messaging systemd when it has finished initializing (see man systemd-notify), the forking method is used as the traditional means of notifying: As long as the parent process lives, the service status as reported by systemctl status remains at start.
It changes to running only after the parent process has exited. The parent process of a traditional daemon service does exit only after the child process has finished its setup and is ready to be used.

This mechanism is needed if there are any dependent services waiting for the service in question to become ready to use. Would a service that not supports the systemd specific method of notification be started without using the traditional daemon forking mechanism, the service status changed to running immediately and any dependent services were started immediately after the service in question, before is ready to be used.

This reason is explained in more detail in Debian Bug #728015 which is already linked in JdeBP's answer.
This reason is also the reason why that bug had been closed as wontfix.

Juergen
  • 674