|
From c63a20c1fe9c34af08c24d141e8bb81bcf2e40b6 Mon Sep 17 00:00:00 2001
|
|
From: "Kyle J. McKay" <mackyle@gmail.com>
|
|
Date: Fri, 4 Dec 2015 18:10:45 -0800
|
|
Subject: [PATCH] server.c: call ftruncate on pid file
|
|
|
|
If the server has changed its uid or is running in a chroot
|
|
it may be unable to remove the pid file when it exits.
|
|
|
|
However, if it holds on to an open handle to the pid file
|
|
that has write permission, it will be able to truncate the
|
|
pid file to 0 bytes in length.
|
|
|
|
Most monitoring software recognizes a 0-length pid file
|
|
as indicating there is no process running.
|
|
|
|
Therefore always attempt to truncate the pid file before
|
|
trying to remove it so that it's not left containing the
|
|
pid of a process that is no longer running.
|
|
|
|
Signed-off-by: Kyle J. McKay <mackyle@gmail.com>
|
|
---
|
|
src/server.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
|
|
1 file changed, 76 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/src/server.c b/src/server.c
|
|
index c5845e2c..f0bcb0a0 100644
|
|
--- a/src/server.c
|
|
+++ b/src/server.c
|
|
@@ -718,6 +718,7 @@ int main (int argc, char **argv) {
|
|
return -1;
|
|
}
|
|
}
|
|
+ fd_close_on_exec(pid_fd);
|
|
}
|
|
|
|
if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
|
|
@@ -1012,8 +1013,6 @@ int main (int argc, char **argv) {
|
|
close(pid_fd);
|
|
return -1;
|
|
}
|
|
- close(pid_fd);
|
|
- pid_fd = -1;
|
|
}
|
|
|
|
/* Close stderr ASAP in the child process to make sure that nothing
|
|
@@ -1146,6 +1145,32 @@ int main (int argc, char **argv) {
|
|
kill(0, SIGTERM);
|
|
}
|
|
|
|
+ if (!buffer_string_is_empty(srv->srvconf.pid_file) && 0 <= pid_fd) {
|
|
+ if (0 != ftruncate(pid_fd, 0)) {
|
|
+ log_error_write(srv, __FILE__, __LINE__, "sbds",
|
|
+ "ftruncate failed for:",
|
|
+ srv->srvconf.pid_file,
|
|
+ errno,
|
|
+ strerror(errno));
|
|
+ }
|
|
+ }
|
|
+ if (0 <= pid_fd) {
|
|
+ close(pid_fd);
|
|
+ pid_fd = -1;
|
|
+ }
|
|
+ if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
|
+ buffer_string_is_empty(srv->srvconf.changeroot)) {
|
|
+ if (0 != unlink(srv->srvconf.pid_file->ptr)) {
|
|
+ if (errno != EACCES && errno != EPERM) {
|
|
+ log_error_write(srv, __FILE__, __LINE__, "sbds",
|
|
+ "unlink failed for:",
|
|
+ srv->srvconf.pid_file,
|
|
+ errno,
|
|
+ strerror(errno));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
log_error_close(srv);
|
|
network_close(srv);
|
|
connections_free(srv);
|
|
@@ -1153,6 +1178,15 @@ int main (int argc, char **argv) {
|
|
server_free(srv);
|
|
return 0;
|
|
}
|
|
+
|
|
+ /**
|
|
+ * make sure workers do not muck with pid-file
|
|
+ */
|
|
+ if (0 <= pid_fd) {
|
|
+ close(pid_fd);
|
|
+ pid_fd = -1;
|
|
+ }
|
|
+ buffer_reset(srv->srvconf.pid_file);
|
|
}
|
|
#endif
|
|
|
|
@@ -1437,23 +1471,36 @@ int main (int argc, char **argv) {
|
|
srv_socket->fd = -1;
|
|
|
|
/* network_close() will cleanup after us */
|
|
-
|
|
- if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
|
- buffer_string_is_empty(srv->srvconf.changeroot)) {
|
|
- if (0 != unlink(srv->srvconf.pid_file->ptr)) {
|
|
- if (errno != EACCES && errno != EPERM) {
|
|
- log_error_write(srv, __FILE__, __LINE__, "sbds",
|
|
- "unlink failed for:",
|
|
- srv->srvconf.pid_file,
|
|
- errno,
|
|
- strerror(errno));
|
|
- }
|
|
- }
|
|
- }
|
|
}
|
|
}
|
|
|
|
if (graceful_shutdown) {
|
|
+ if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
|
+ 0 <= pid_fd) {
|
|
+ if (0 != ftruncate(pid_fd, 0)) {
|
|
+ log_error_write(srv, __FILE__, __LINE__, "sbds",
|
|
+ "ftruncate failed for:",
|
|
+ srv->srvconf.pid_file,
|
|
+ errno,
|
|
+ strerror(errno));
|
|
+ }
|
|
+ }
|
|
+ if (0 <= pid_fd) {
|
|
+ close(pid_fd);
|
|
+ pid_fd = -1;
|
|
+ }
|
|
+ if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
|
+ buffer_string_is_empty(srv->srvconf.changeroot)) {
|
|
+ if (0 != unlink(srv->srvconf.pid_file->ptr)) {
|
|
+ if (errno != EACCES && errno != EPERM) {
|
|
+ log_error_write(srv, __FILE__, __LINE__, "sbds",
|
|
+ "unlink failed for:",
|
|
+ srv->srvconf.pid_file,
|
|
+ errno,
|
|
+ strerror(errno));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
|
|
} else if (srv->conns->used >= srv->max_conns) {
|
|
log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
|
|
@@ -1556,6 +1603,20 @@ int main (int argc, char **argv) {
|
|
}
|
|
|
|
if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
|
+ 0 == graceful_shutdown && 0 <= pid_fd) {
|
|
+ if (0 != ftruncate(pid_fd, 0)) {
|
|
+ log_error_write(srv, __FILE__, __LINE__, "sbds",
|
|
+ "ftruncate failed for:",
|
|
+ srv->srvconf.pid_file,
|
|
+ errno,
|
|
+ strerror(errno));
|
|
+ }
|
|
+ }
|
|
+ if (0 <= pid_fd) {
|
|
+ close(pid_fd);
|
|
+ pid_fd = -1;
|
|
+ }
|
|
+ if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
|
buffer_string_is_empty(srv->srvconf.changeroot) &&
|
|
0 == graceful_shutdown) {
|
|
if (0 != unlink(srv->srvconf.pid_file->ptr)) {
|
|
--
|
|
2.4.10
|
|
|