]> mj.ucw.cz Git - libucw.git/blob - ucw/doc/daemon.txt
Configure: Turned off -fgnu89-inline
[libucw.git] / ucw / doc / daemon.txt
1 Daemon helpers
2 ==============
3
4 Daemonization
5 -------------
6
7 When programs run as daemons, they frequently forget to detach themselves
8 from the parent environment. LibUCW therefore offers a simple daemonization
9 helper which performs the necessary actions. Namely:
10
11 * Establishing a new session via a call to `setsid()`.
12 * Switching the user and group ID if needed. The user and group can be specified
13   by either a name or `#uid`. If only the user is given, the relevant groups are
14   set according to `/etc/passwd` and `/etc/group`.
15 * Redirecting standard input and output from `/dev/null`. Standard error
16   output is left open, so that error messages can be printed before you
17   set up proper <<log:,logging>>.
18 * Setting the `umask()` to a fixed value (022).
19 * Switching from the current directory to `/`, so that it is not kept busy.
20 * Writing a PID file. While the daemon is running, the PID file is kept locked
21   by `flock()`, so we can easily detect stale PID files.
22
23 Example
24 -------
25
26         #include <ucw/lib.h>
27         #include <ucw/daemon.h>
28
29         void daemon_body(struct daemon_params *dp)
30         {
31                 // ... daemon's code ...
32                 // When we are done, release the PID file and exit:
33                 daemon_exit(dp);
34         }
35
36         int main(int argc, char **argv)
37         {
38                 struct daemon_params dp = { .pid_file = "/var/run/example.pid" };
39                 // ... parse arguments ...
40                 daemon_init(&dp);
41                 // ... initialize everything ...
42                 // Let us fork off the daemon:
43                 daemon_run(daemon_body);
44                 // Here continues the parent process
45                 return 0;
46         }
47
48 Daemon control
49 --------------
50
51 Daemons using the LibUCW helpers can be controlled by traditional mechanisms present
52 in most UNIX-like operating systems. These are usually based on PID files, but they
53 are inherently racy, since they do not perform any locking. For example, attempts to
54 start the daemon, while another process is trying to stop it often lead to undefined
55 states. Also, detection of running daemons fails when the daemon dies and its PID
56 is recycled. Checking of process name and similar tricks do not avoid the problem,
57 since there can be multiple instances of the daemon running simultaneously.
58
59 We therefore recommend the following daemon control protocol, which prevents all such
60 race conditions. Its implementation is available in form of the daemon_control() library
61 function or the `daemon-control` stand-alone utility.
62
63 * There exist two files:
64 ** PID file (usually `/var/run/daemon.pid`), which contains the PID of the daemon
65    process and when the daemon runs, it keeps the file locked by `flock()`.
66 ** Guard file (usually `/var/run/daemon.lock`), which is locked (again by `flock()`)
67    whenever we want to perform an action on the daemon.
68 * When we want to start the daemon:
69 ** Lock the guard file, creating it if it did not exist.
70 ** Try to lock the PID file. If it fails, the daemon is already running, so we are done.
71 ** Unlock the PID file.
72 ** Run the daemon. The daemon locks the PID file and when it has everything initialized,
73    it forks and the parent process writes the child's PID and exits.
74 ** Unlock the guard file.
75 * When we want to stop it:
76 ** Lock the guard file, creating it if it did not exist.
77 ** Try to lock the PID file. If it succeeds, the daemon is not running, so we are done.
78 ** Read the PID from the PID file.
79 ** Send a signal to the process. [This is the only place when we can race. The daemon could
80    have exited in the meantime and its PID could have been recycled. Hopefully, the time window
81    between checking the lock and sending the signal will be short enough. Using 32-bit PIDs
82    is advisable anyway.]
83 ** Lock the PID file. This will wait until the daemon finishes and releases the lock.
84 ** Unlock the guard file.
85 * When we want to query the daemon's status:
86 ** Lock the guard file, creating it if it did not exist.
87 ** Try to lock the PID file. If it succeeds, the daemon was not running.
88 ** Unlock everything.
89
90 ucw/daemon.h
91 ------------
92
93 !!ucw/daemon.h