summaryrefslogtreecommitdiff
path: root/.html/devops/self-daemonization-sucks.html
blob: 14e2c011532d9dd9247158bb0450a7cbc616204e (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
<!DOCTYPE html>
<html>
<head>
	<title>
		The Codex » 
		Self-daemonizing code is awful
	</title>

	<link
		rel='stylesheet'
		type='text/css'
		href='http://fonts.googleapis.com/css?family=Buenard:400,700&amp;subset=latin,latin-ext'>
	<link
		rel="stylesheet"
		type="text/css"
		href="../media/css/reset.css">
	<link
		rel="stylesheet"
		type="text/css"
		href="../media/css/grimoire.css">
</head>
<body>

<div id="shell">
	
		<ol id="breadcrumbs">
			
				<li class="crumb-0 not-last">
					
						<a href="../">index</a>
					
				</li>
			
				<li class="crumb-1 not-last">
					
						<a href="./">devops</a>
					
				</li>
			
				<li class="crumb-2 last">
					
						self-daemonization-sucks
					
				</li>
			
		</ol>
	

	
	<div id="article">
		<h1 id="self-daemonizing-code-is-awful">Self-daemonizing code is awful</h1>
<p>The classical UNIX approach to services is to implement them as “daemons,”
programs that run without a terminal attached and provide some service. The
key feature of a classical daemon is that, when started, it carefully
detaches itself from its initial environment and terminal, then continues
running in the background.</p>
<p>This is awful and I'm glad modern init replacements discourage it.</p>
<h2 id="process-tracking">Process Tracking</h2>
<p>Daemons don't exist in a vacuum. Administrators and owners need to be able to
start and stop daemons reliably, and check their status. The classic
self-daemonization approach makes this impossible.</p>
<p>Traditionally, daemons run as children of <code>init</code> (pid 1), even if they start
out as children of some terminal or startup process. Posix only provides
deterministic APIs for processes to manage their children and their immediate
parents; the classic daemonisation protocol hands the newly-started daemon
process off from its original parent process, which knows how to start and
stop it, to an unsuspecting <code>init</code>, which has no idea how this specific
daemon is special.</p>
<p>The standard workaround has daemons write their own PIDs to a file, but a
file is “dead” data: it's not automatically updated if the daemon dies, and
can linger long enough to contain the PID of some later, unrelated program.
PID file validity checks generally suffer from subtle (or, sometimes, quite
gross) race conditions.</p>
<h2 id="complexity">Complexity</h2>
<p>The actual <em>code</em> to correctly daemonize a process is surprisingly complex,
given the individual interfaces' relative simplicity:</p>
<ul>
<li>
<p>The daemon must start its own process group</p>
</li>
<li>
<p>The daemon must detach from its controlling terminal</p>
</li>
<li>
<p>The daemon should close (and may reopen) file handles inherited from its
  parent process (generally, a shell)</p>
</li>
<li>
<p>The daemon should ensure its working directory is predictable and
  controllable</p>
</li>
<li>
<p>The daemon should ensure its umask is predictable and controllable</p>
</li>
<li>
<p>If the daemon uses privileged resources (such as low-numbered ports), it
  should carefully manage its effective, real, and session UID and GIDs</p>
</li>
<li>
<p>Daemons must ensure that all of the above steps happen in signal-safe ways,
  so that a daemon can be shut down sanely even if it's still starting up</p>
</li>
</ul>
<p>See <a href="http://www.freedesktop.org/software/systemd/man/daemon.html">this list</a>
for a longer version. It's worse than you think.</p>
<p>All of this gets even more complicated if the daemon has its own child
processes, a pattern common to network services. Naturally, a lot of daemons
in the real world get some of these steps wrong.</p>
<h2 id="the-future">The Future</h2>
<p><a href="http://supervisord.org">Supervisord</a>,
<a href="http://ddollar.github.io/foreman/">Foreman</a>,
<a href="http://upstart.ubuntu.com">Upstart</a>,
<a href="https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/launchctl.1.html">Launchd</a>,
<a href="http://www.freedesktop.org/wiki/Software/systemd/">systemd</a>, and <a href="http://cr.yp.to/daemontools.html">daemontools</a> all
encourage services <em>not</em> to self-daemonize by providing a sane system for
starting the daemon with the right parent process and the right environment
in the first place.</p>
<p>This is a great application of
<a href="http://c2.com/cgi/wiki?DontRepeatYourself">DRY</a>, as the daemon management
code only needs to be written once (in the daemon-managing daemon) rather
than many times over (in each individual daemon). It also makes daemon
execution more predictable, since daemons “in production” behave more like
they do when run attached to a developer's console during debugging or
development.</p>
	</div>


	
<div id="comments">
<div id="disqus_thread"></div>
<script type="text/javascript">
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
</div>


	
	<div id="footer">
		<p>
			
				The Codex —
			
			Powered by <a href="http://markdoc.org/">Markdoc</a>.
			
<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/devops/self-daemonization-sucks.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/devops/self-daemonization-sucks.md">history</a>).

		</p>
	</div>
	
</div>
</body>
</html>