summaryrefslogtreecommitdiff
path: root/man/daemon.xml
blob: 853b3bb814790d6b3a35ad4c449b78ad7ee3e87f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">

<!--
  This file is part of systemd.

  Copyright 2010 Lennart Poettering

  systemd is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  systemd is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->

<refentry id="daemon">

        <refentryinfo>
                <title>daemon</title>
                <productname>systemd</productname>

                <authorgroup>
                        <author>
                                <contrib>Developer</contrib>
                                <firstname>Lennart</firstname>
                                <surname>Poettering</surname>
                                <email>lennart@poettering.net</email>
                        </author>
                </authorgroup>
        </refentryinfo>

        <refmeta>
                <refentrytitle>daemon</refentrytitle>
                <manvolnum>7</manvolnum>
        </refmeta>

        <refnamediv>
                <refname>daemon</refname>
                <refpurpose>Writing and Packaging System Daemons</refpurpose>
        </refnamediv>

        <refsect1>
                <title>Description</title>

                <para>A daemon is a service process that runs in the
                background and supervises the system or provides
                functionality to other processes. Traditionally,
                daemons are implemented following a scheme originating
                in SysV Unix. Modern daemons should follow a simpler
                yet more powerful scheme (here called "new-style"
                daemons), as implemented by
                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>. </para>

                <refsect2>
                        <title>SysV Daemons</title>

                        <para>When a traditional SysV daemon
                        starts, it should execute the following steps
                        as part of the initialization. Note that these
                        steps are unnecessary for new-style daemons (see below),
                        and should only be implemented if compatibility
                        with SysV is essential.</para>

                        <orderedlist>
                                <listitem><para>Close all open file
                                descriptors except STDIN, STDOUT,
                                STDERR (i.e. the first three file
                                descriptors 0, 1, 2). This ensures
                                that no accidentally passed file
                                descriptor stays around in the daemon
                                process. On Linux this is best
                                implemented by iterating through
                                <filename>/proc/self/fd</filename>,
                                with a fallback of iterating from file
                                descriptor 3 to the value returned by
                                <function>getrlimit()</function> for
                                RLIMIT_NOFILE.</para></listitem>

                                <listitem><para>Reset all signal
                                handlers to their default. This is
                                best done by iterating through the
                                available signals up to the limit of
                                _NSIG and resetting them to
                                SIG_DFL.</para></listitem>

                                <listitem><para>Reset the signal mask
                                using
                                <function>sigprocmask()</function>.</para></listitem>

                                <listitem><para>Sanitize the
                                environment block, removing or
                                resetting environment variables that
                                might negatively impact daemon
                                runtime.</para></listitem>

                                <listitem><para>Call <function>fork()</function>,
                                to create a background
                                process.</para></listitem>

                                <listitem><para>In the child, call
                                <function>setsid()</function> to
                                detach from any terminal and create an
                                independent session.</para></listitem>

                                <listitem><para>In the child, call
                                <function>fork()</function> again, to
                                ensure the daemon can never re-aquire
                                a terminal again.</para></listitem>

                                <listitem><para>Call <function>exit()</function> in the
                                first child, so that only the second
                                child (the actual daemon process)
                                stays around. This ensures that the
                                daemon process is reparented to
                                init/PID 1, as all daemons should
                                be.</para></listitem>

                                <listitem><para>In the daemon process,
                                connect <filename>/dev/null</filename>
                                to STDIN, STDOUT,
                                STDERR.</para></listitem>

                                <listitem><para>In the daemon process,
                                reset the umask to 0, so that the file
                                modes passed to <function>open()</function>, <function>mkdir()</function> and
                                suchlike directly control the access
                                mode of the created files and
                                directories.</para></listitem>

                                <listitem><para>In the daemon process,
                                change the current directory to the
                                root directory (/), in order to avoid
                                that the daemon involuntarily
                                blocks mount points from being
                                unmounted.</para></listitem>

                                <listitem><para>In the daemon process,
                                write the daemon PID (as returned by
                                <function>getpid()</function>) to a
                                PID file, for example
                                <filename>/var/run/foobar.pid</filename>
                                (for a hypothetical daemon "foobar"),
                                to ensure that the daemon cannot be
                                started more than once. This must be
                                implemented in race-free fashion so
                                that the PID file is only updated when
                                at the same time it is verified that
                                the PID previously stored in the PID
                                file no longer exists or belongs to a
                                foreign process. Commonly some kind of
                                file locking is employed to implement
                                this logic.</para></listitem>

                                <listitem><para>In the daemon process,
                                drop privileges, if possible and
                                applicable.</para></listitem>

                                <listitem><para>From the daemon
                                process notify the original process
                                started that initialization is
                                complete. This can be implemented via
                                an unnamed pipe or similar
                                communication channel that is created
                                before the first
                                <function>fork()</function> and hence
                                available in both the original and the
                                daemon process.</para></listitem>

                                <listitem><para>Call
                                <function>exit()</function> in the
                                original process. The process that
                                invoked the daemon must be able to
                                rely that this
                                <function>exit()</function> happens
                                after initialization is complete and
                                all external communication channels
                                established and
                                accessible.</para></listitem>
                        </orderedlist>

                        <para>The BSD <function>daemon()</function> function should not be
                        used, as it implements only a subset of these steps.</para>

                        <para>A daemon that needs to provide
                        compatibility with SysV systems should
                        implement the scheme pointed out
                        above. However, it is recommended to make this
                        behaviour optional and configurable via a
                        command line argument, to ease debugging as
                        well as to simplify integration into systems
                        using systemd.</para>
                </refsect2>

                <refsect2>
                        <title>New-Style Daemons</title>

                        <para>Modern services for Linux should be
                        implemented as new-style daemons. This makes it
                        easier to supervise and control them at
                        runtime and simplifies their
                        implementation.</para>

                        <para>For developing a new-style daemon none
                        of the initialization steps recommended for
                        SysV daemons need to be implemented. New-style
                        init systems such as systemd make all of them
                        redundant. Moreover, since some of these steps
                        interfere with process monitoring, file
                        descriptor passing and other functionality of
                        the init system it is recommended not to
                        execute them when run as new-style
                        service.</para>

                        <para>Note that new-style init systems
                        guarantee execution of daemon processes in
                        clean process contexts: it is guaranteed that
                        the environment block is sanitized, that the
                        signal handlers and mask is reset and that no
                        left-over file descriptors are passed. Daemons
                        will be executed in their own session, and
                        STDIN/STDOUT/STDERR connected to
                        <filename>/dev/null</filename> unless
                        otherwise configured. The umask is reset.</para>

                        <para>It is recommended for new-style daemons
                        to implement the following:</para>

                        <orderedlist>
                                <listitem><para>If SIGTERM is
                                received, shut down the daemon and
                                exit cleanly.</para></listitem>

                                <listitem><para>If SIGHUP is received,
                                reload the configuration files, if
                                this applies.</para></listitem>

                                <listitem><para>Provide a correct exit
                                code from the main daemon process, as
                                this is used by the init system to
                                detect service errors and problems. It
                                is recommended to follow the exit code
                                scheme as defined in the <ulink
                                url="http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB
                                recommendations for SysV init
                                scripts</ulink>.</para></listitem>

                                <listitem><para>As much as possible,
                                rely on systemd's functionality to
                                limit the access of the daemon to
                                files, services and other
                                resources. i.e. rely on systemd's
                                resource limit control instead of
                                implementing your own, rely on
                                systemd's privilege dropping code
                                instead of implementing it in the
                                daemon, and similar. See
                                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                                for the available
                                controls.</para></listitem>

                                <listitem><para>If possible and
                                applicable expose the daemon's control
                                interface via the D-Bus IPC system and
                                grab a bus name as last step of
                                initialization.</para></listitem>

                                <listitem><para>If D-Bus is used, make
                                your daemon bus-activatable, via
                                supplying a D-Bus service activation
                                configuration file. This has multiple
                                advantages: your daemon may be started
                                lazily on-demand; it may be started in
                                parallel to other daemons requiring it
                                -- which maximizes parallelization and
                                boot-up speed; your daemon can be
                                restarted on failure, without losing
                                any bus requests, as the bus queues
                                requests for activatable services. See
                                below for details.</para></listitem>

                                <listitem><para>If your daemon
                                provides services to other local
                                processes or remote clients via a
                                socket, it should be made
                                socket-activatable following the
                                scheme pointed out below. Like D-Bus
                                activation this enables on-demand
                                starting of services as well as it
                                allows improved parallelization of
                                service start-up. Also, for state-less
                                protocols (such as syslog, DNS) a
                                daemon implementing socket-based
                                activation can be restarted without
                                losing a single request. See below for
                                details.</para></listitem>

                                <listitem><para>If applicable a daemon
                                should notify the init system about
                                startup completion or status updates
                                via the
                                <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                                interface.</para></listitem>

                                <listitem><para>Instead of using the
                                <function>syslog()</function> call to log directly to the
                                system logger, a new-style daemon may
                                choose to simply log to STDERR via
                                <function>fprintf()</function>, which is then forwarded to
                                syslog by the init system. If log
                                priorities are necessary these can be
                                encoded by prefixing individual log
                                lines with strings like "&lt;4&gt;"
                                (for log priority 4 "WARNING" in the
                                syslog priority scheme), following a
                                similar style as the Linux kernel's
                                <function>printk()</function> priority system. In fact,
                                using this style of logging also
                                enables the init system to optionally
                                direct all application logging to the
                                kernel log buffer (kmsg), as
                                accessible via
                                <citerefentry><refentrytitle>dmesg</refentrytitle><manvolnum>1</manvolnum></citerefentry>. This
                                kind of logging may be enabled by
                                setting
                                <varname>StandardError=syslog</varname>
                                in the service unit file. For details
                                see
                                <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                                and
                                <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>

                        </orderedlist>

                        <para>These recommendations are similar but
                        not identical to the <ulink
                        url="http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/LaunchOnDemandDaemons.html#//apple_ref/doc/uid/TP40001762-104738">Apple
                        MacOS X Daemon Requirements</ulink>.</para>
                </refsect2>

                <refsect2>
                        <title>Socket-Based Activation</title>
                </refsect2>

                <refsect2>
                        <title>Bus-Based Activation</title>
                </refsect2>

                <refsect2>
                        <title>Path-Based Activation</title>
                </refsect2>

                <refsect2>
                        <title>Writing Systemd Unit Files</title>

                        <para>When writing systemd unit files, it is
                        recommended to consider the following
                        suggestions:</para>

                        <orderedlist>
                                <listitem><para>If possible do not use
                                the <varname>Type=forking</varname>
                                setting in service files. But if you
                                do, make sure to set the PID file path
                                using <varname>PIDFile=</varname>. See
                                <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                                for details.</para></listitem>

                                <listitem><para>If your daemon
                                registers a D-Bus name on the bus,
                                make sure to use
                                <varname>Type=dbus</varname> if
                                possible.</para></listitem>

                                <listitem><para>Make sure to set a
                                good human-readable description string
                                with
                                <varname>Description=</varname>.</para></listitem>

                                <listitem><para>Do not disable
                                <varname>DefaultDependencies=</varname>,
                                unless you really know what you do and
                                your unit is involved in early boot or
                                late system shutdown.</para></listitem>

                                <listitem><para>Normally, little if
                                any dependencies should need to
                                be defined explicitly. However, if you
                                do configure explicit dependencies, only refer to
                                unit names listed on
                                <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                                or names introduced by your own
                                package to keep the unit file
                                operating
                                system-independent.</para></listitem>

                                <listitem><para>Make sure to include
                                an <literal>[Install]</literal> section including
                                installation information for the unit
                                file. See
                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                                for details. To activate your service
                                on boot make sure to add a
                                <varname>WantedBy=multi-user.target</varname>
                                or
                                <varname>WantedBy=graphical.target</varname> directive.</para></listitem>

                        </orderedlist>
                </refsect2>

                <refsect2>
                        <title>Installing Service Files</title>

                        <para>At the build installation time
                        (e.g. <command>make install</command> during
                        package build) packages are recommended to
                        install their systemd unit files in the
                        directory returned by <command>pkg-config
                        systemd
                        --variable=systemdsystemnunitdir</command>
                        (for system services),
                        resp. <command>pkg-config systemd
                        --variable=systemdsessionunitdir</command>
                        (for session services). This will make the
                        services available in the system on explicit
                        request but not activate them automatically
                        during boot. Optionally, during package
                        installation (e.g. <command>rpm -i</command>
                        by the administrator) symlinks should be
                        created in the systemd configuration
                        directories via the
                        <citerefentry><refentrytitle>systemd-install</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                        tool, to activate them automatically on
                        boot.</para>

                        <para>Packages using
                        <citerefentry><refentrytitle>autoconf</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                        are recommended to use a configure script
                        excerpt like the following to determine the
                        unit installation path during source
                        configuration:</para>

                        <programlisting>PKG_PROG_PKG_CONFIG
AC_ARG_WITH([systemdsystemunitdir],
        AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
        [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir"])</programlisting>

                        <para>This snippet allows automatic
                        installation of the unit files on systemd
                        machines, and optionally allows their
                        installation even on machines lacking
                        systemd. (Modification of this snippet for the
                        session unit directory is left as excercise to the
                        reader.)</para>

                        <para>Additionally, to ensure that
                        <command>make distcheck</command> continues to
                        work, it is recommended to add the following
                        to the top-level <filename>Makefile.am</filename>
                        file in
                        <citerefentry><refentrytitle>automake</refentrytitle><manvolnum>1</manvolnum></citerefentry>-based
                        projects:</para>

                        <programlisting>DISTCHECK_CONFIGURE_FLAGS = \
        --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)</programlisting>

                        <para>Finally, unit files should be installed in the system with an automake excerpt like the following:</para>

                        <programlisting>if HAVE_SYSTEMD
systemdsystemunit_DATA = \
        foobar.socket \
        foobar.service
endif</programlisting>

                        <para>In the
                        <citerefentry><refentrytitle>rpm</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                        <filename>.spec</filename> file use a snippet like
                        the following to enable/disable the service
                        during installation/deinstallation. Consult
                        the packaging guidelines of your distribution
                        for details and the equivalent for other
                        packaging managers:</para>

                        <programlisting>%post
/usr/bin/systemd-install enable foobar.service foobar.socket >/dev/null 2>&amp;1 || :

%preun
if [ "$1" -eq 0 ]; then
        /usr/bin/systemd-install disable foobar.service foobar.socket >/dev/null 2>&amp;1 || :
fi</programlisting>

                </refsect2>

                <refsect2>
                        <title>Porting Existing Daemons</title>

                        <para>Since new-style init systems such as
                        systemd are compatible with traditional SysV
                        init systems it is not strictly necessary to
                        port existing daemons to the new
                        style. However doing this offers additional
                        functionality to the daemons as well as it
                        simplifies integration into new-style init
                        systems.</para>

                        <para>To port an existing SysV compatible
                        daemon the following steps are
                        recommended:</para>

                        <orderedlist>
                                <listitem><para>If not already
                                implemented, add an optional command
                                line switch to the daemon to disable
                                daemonization. This is useful not only
                                for using the daemon in new-style init
                                systems, but also to ease debugging.</para></listitem>

                                <listitem><para>If the daemon offers
                                interfaces to other software running
                                on the local system via local AF_UNIX
                                sockets, consider implementing
                                socket-based activation (see
                                above). Usually a minimal patch is
                                sufficient to implement this: Extend
                                the socket creation in the daemon code
                                so that
                                <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                                is checked for already passed sockets
                                first. If sockets are passed
                                (i.e. when
                                <function>sd_listen_fds()</function>
                                returns a positive value), skip the
                                socket createn step and use the passed
                                sockets. Secondly, ensure that the
                                file-system socket nodes for local
                                AF_UNIX sockets used in the
                                socket-based activation are not
                                removed when the daemon shuts down, if
                                sockets have been passed. Third, if
                                the daemon normally closes all
                                remaining open file descriptors as
                                part of its initialization, the
                                sockets passed from the init system
                                must be spared. Since new-style init
                                systems guarantee that no left-over
                                file descriptors are passed to
                                executed processes, it might be a good
                                choice to simply skip the closing of
                                all remaining open file descriptors if
                                file descriptors are
                                passed.</para></listitem>

                                <listitem><para>Write and install a
                                systemd unit file for the service (and
                                the sockets if socket-based activation
                                is used, as well as a path unit file,
                                if the daemon processes a spool
                                directory), see above for
                                details.</para></listitem>

                                <listitem><para>If the daemon exposes
                                interfaces via D-Bus, write and
                                install a D-Bus activation file for
                                the service, see above for
                                details.</para></listitem>
                        </orderedlist>

                </refsect2>

        </refsect1>


        <refsect1>
                <title>See Also</title>
                <para>
                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                        <citerefentry><refentrytitle>systemd-install</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                        <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                        <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                        <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                </para>
        </refsect1>

</refentry>