18.01.2011 16:51, Lennart Poettering пишет:
On Tue, 18.01.11 16:41, Alexander E. Patrakov (patra...@gmail.com) wrote:

How is this implemented in detail? Sending SIGINT is async, so at the
time you start the new instance you cannot be sure that the old instance
has stopped listening?
Indeed, there is a race here. That's why "/bin/sleep 1" in my
initial service file.
Hmm, what's the lighthttp people's take on this? They came up with the
scheme, so how do they think this problem should be handled?

They usleep(5 * 1000) and, if the new copy of lighttpd still fails to start due to a race, sleep again and attempt to start it again, ad infinitum.

(One possible solution could be if the old and the new instance would
communicate and pass the listening sockets via some AF_UNIX
socket/SCM_RIGHTS or so. But that is not trivial.)

I came with a different (albeit systemd-specific) solution. The solution (implemented as an attached patch) is to fork() after we closed all the listening sockets and exit immediately in the parent. This way, the chlid continues to serve already-requested files, and systemd has a race-free indication that it can restart lighttpd via Restart=always. Please review the patch and the service file. One known problem: the patch is completely untested with server.max-worker > 0.

--
Alexander E. Patrakov
diff -ur lighttpd-1.4.28.orig/src/server.c lighttpd-1.4.28/src/server.c
--- lighttpd-1.4.28.orig/src/server.c	2010-08-17 15:04:38.000000000 +0600
+++ lighttpd-1.4.28/src/server.c	2011-01-18 17:28:31.000000000 +0500
@@ -1394,6 +1394,11 @@
 
 				if (graceful_shutdown) {
 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
+/* FIXME: list all other fdevent handlers that don't survive fork() */
+#if defined HAVE_FORK && !defined HAVE_KQUEUE
+					if (fork() > 0)
+						_exit(0);
+#endif
 				} else if (srv->conns->used >= srv->max_conns) {
 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
 				} else {
[Unit]
Description=Lighttpd Web Server
After=network.target

[Service]
ExecStart=/usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf -D
Restart=always
ExecReload=/bin/kill -INT $MAINPID
TimeoutSec=60
KillMode=process

[Install]
WantedBy=multi-user.target
WantedBy=http-daemon.target
_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to