1
|
From c63a20c1fe9c34af08c24d141e8bb81bcf2e40b6 Mon Sep 17 00:00:00 2001
|
2
|
From: "Kyle J. McKay" <mackyle@gmail.com>
|
3
|
Date: Fri, 4 Dec 2015 18:10:45 -0800
|
4
|
Subject: [PATCH] server.c: call ftruncate on pid file
|
5
|
|
6
|
If the server has changed its uid or is running in a chroot
|
7
|
it may be unable to remove the pid file when it exits.
|
8
|
|
9
|
However, if it holds on to an open handle to the pid file
|
10
|
that has write permission, it will be able to truncate the
|
11
|
pid file to 0 bytes in length.
|
12
|
|
13
|
Most monitoring software recognizes a 0-length pid file
|
14
|
as indicating there is no process running.
|
15
|
|
16
|
Therefore always attempt to truncate the pid file before
|
17
|
trying to remove it so that it's not left containing the
|
18
|
pid of a process that is no longer running.
|
19
|
|
20
|
Signed-off-by: Kyle J. McKay <mackyle@gmail.com>
|
21
|
---
|
22
|
src/server.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
|
23
|
1 file changed, 76 insertions(+), 15 deletions(-)
|
24
|
|
25
|
diff --git a/src/server.c b/src/server.c
|
26
|
index c5845e2c..f0bcb0a0 100644
|
27
|
--- a/src/server.c
|
28
|
+++ b/src/server.c
|
29
|
@@ -718,6 +718,7 @@ int main (int argc, char **argv) {
|
30
|
return -1;
|
31
|
}
|
32
|
}
|
33
|
+ fd_close_on_exec(pid_fd);
|
34
|
}
|
35
|
|
36
|
if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
|
37
|
@@ -1012,8 +1013,6 @@ int main (int argc, char **argv) {
|
38
|
close(pid_fd);
|
39
|
return -1;
|
40
|
}
|
41
|
- close(pid_fd);
|
42
|
- pid_fd = -1;
|
43
|
}
|
44
|
|
45
|
/* Close stderr ASAP in the child process to make sure that nothing
|
46
|
@@ -1146,6 +1145,32 @@ int main (int argc, char **argv) {
|
47
|
kill(0, SIGTERM);
|
48
|
}
|
49
|
|
50
|
+ if (!buffer_string_is_empty(srv->srvconf.pid_file) && 0 <= pid_fd) {
|
51
|
+ if (0 != ftruncate(pid_fd, 0)) {
|
52
|
+ log_error_write(srv, __FILE__, __LINE__, "sbds",
|
53
|
+ "ftruncate failed for:",
|
54
|
+ srv->srvconf.pid_file,
|
55
|
+ errno,
|
56
|
+ strerror(errno));
|
57
|
+ }
|
58
|
+ }
|
59
|
+ if (0 <= pid_fd) {
|
60
|
+ close(pid_fd);
|
61
|
+ pid_fd = -1;
|
62
|
+ }
|
63
|
+ if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
64
|
+ buffer_string_is_empty(srv->srvconf.changeroot)) {
|
65
|
+ if (0 != unlink(srv->srvconf.pid_file->ptr)) {
|
66
|
+ if (errno != EACCES && errno != EPERM) {
|
67
|
+ log_error_write(srv, __FILE__, __LINE__, "sbds",
|
68
|
+ "unlink failed for:",
|
69
|
+ srv->srvconf.pid_file,
|
70
|
+ errno,
|
71
|
+ strerror(errno));
|
72
|
+ }
|
73
|
+ }
|
74
|
+ }
|
75
|
+
|
76
|
log_error_close(srv);
|
77
|
network_close(srv);
|
78
|
connections_free(srv);
|
79
|
@@ -1153,6 +1178,15 @@ int main (int argc, char **argv) {
|
80
|
server_free(srv);
|
81
|
return 0;
|
82
|
}
|
83
|
+
|
84
|
+ /**
|
85
|
+ * make sure workers do not muck with pid-file
|
86
|
+ */
|
87
|
+ if (0 <= pid_fd) {
|
88
|
+ close(pid_fd);
|
89
|
+ pid_fd = -1;
|
90
|
+ }
|
91
|
+ buffer_reset(srv->srvconf.pid_file);
|
92
|
}
|
93
|
#endif
|
94
|
|
95
|
@@ -1437,23 +1471,36 @@ int main (int argc, char **argv) {
|
96
|
srv_socket->fd = -1;
|
97
|
|
98
|
/* network_close() will cleanup after us */
|
99
|
-
|
100
|
- if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
101
|
- buffer_string_is_empty(srv->srvconf.changeroot)) {
|
102
|
- if (0 != unlink(srv->srvconf.pid_file->ptr)) {
|
103
|
- if (errno != EACCES && errno != EPERM) {
|
104
|
- log_error_write(srv, __FILE__, __LINE__, "sbds",
|
105
|
- "unlink failed for:",
|
106
|
- srv->srvconf.pid_file,
|
107
|
- errno,
|
108
|
- strerror(errno));
|
109
|
- }
|
110
|
- }
|
111
|
- }
|
112
|
}
|
113
|
}
|
114
|
|
115
|
if (graceful_shutdown) {
|
116
|
+ if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
117
|
+ 0 <= pid_fd) {
|
118
|
+ if (0 != ftruncate(pid_fd, 0)) {
|
119
|
+ log_error_write(srv, __FILE__, __LINE__, "sbds",
|
120
|
+ "ftruncate failed for:",
|
121
|
+ srv->srvconf.pid_file,
|
122
|
+ errno,
|
123
|
+ strerror(errno));
|
124
|
+ }
|
125
|
+ }
|
126
|
+ if (0 <= pid_fd) {
|
127
|
+ close(pid_fd);
|
128
|
+ pid_fd = -1;
|
129
|
+ }
|
130
|
+ if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
131
|
+ buffer_string_is_empty(srv->srvconf.changeroot)) {
|
132
|
+ if (0 != unlink(srv->srvconf.pid_file->ptr)) {
|
133
|
+ if (errno != EACCES && errno != EPERM) {
|
134
|
+ log_error_write(srv, __FILE__, __LINE__, "sbds",
|
135
|
+ "unlink failed for:",
|
136
|
+ srv->srvconf.pid_file,
|
137
|
+ errno,
|
138
|
+ strerror(errno));
|
139
|
+ }
|
140
|
+ }
|
141
|
+ }
|
142
|
log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
|
143
|
} else if (srv->conns->used >= srv->max_conns) {
|
144
|
log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
|
145
|
@@ -1556,6 +1603,20 @@ int main (int argc, char **argv) {
|
146
|
}
|
147
|
|
148
|
if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
149
|
+ 0 == graceful_shutdown && 0 <= pid_fd) {
|
150
|
+ if (0 != ftruncate(pid_fd, 0)) {
|
151
|
+ log_error_write(srv, __FILE__, __LINE__, "sbds",
|
152
|
+ "ftruncate failed for:",
|
153
|
+ srv->srvconf.pid_file,
|
154
|
+ errno,
|
155
|
+ strerror(errno));
|
156
|
+ }
|
157
|
+ }
|
158
|
+ if (0 <= pid_fd) {
|
159
|
+ close(pid_fd);
|
160
|
+ pid_fd = -1;
|
161
|
+ }
|
162
|
+ if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
163
|
buffer_string_is_empty(srv->srvconf.changeroot) &&
|
164
|
0 == graceful_shutdown) {
|
165
|
if (0 != unlink(srv->srvconf.pid_file->ptr)) {
|
166
|
--
|
167
|
2.4.10
|
168
|
|