|
Lines 217-222
u_int utmp_len = HOST_NAME_MAX+1;
Link Here
|
| 217 |
int *startup_pipes = NULL; |
217 |
int *startup_pipes = NULL; |
| 218 |
int startup_pipe; /* in child */ |
218 |
int startup_pipe; /* in child */ |
| 219 |
|
219 |
|
|
|
220 |
/* options.max_startup sized array of fd ints */ |
| 221 |
int *listener_pipes = NULL; |
| 222 |
|
| 220 |
/* variables used for privilege separation */ |
223 |
/* variables used for privilege separation */ |
| 221 |
int use_privsep = -1; |
224 |
int use_privsep = -1; |
| 222 |
struct monitor *pmonitor = NULL; |
225 |
struct monitor *pmonitor = NULL; |
|
Lines 257-263
close_listen_socks(void)
Link Here
|
| 257 |
} |
260 |
} |
| 258 |
|
261 |
|
| 259 |
static void |
262 |
static void |
| 260 |
close_startup_pipes(void) |
263 |
close_notification_pipes(void) |
| 261 |
{ |
264 |
{ |
| 262 |
int i; |
265 |
int i; |
| 263 |
|
266 |
|
|
Lines 265-270
close_startup_pipes(void)
Link Here
|
| 265 |
for (i = 0; i < options.max_startups; i++) |
268 |
for (i = 0; i < options.max_startups; i++) |
| 266 |
if (startup_pipes[i] != -1) |
269 |
if (startup_pipes[i] != -1) |
| 267 |
close(startup_pipes[i]); |
270 |
close(startup_pipes[i]); |
|
|
271 |
|
| 272 |
if (listener_pipes) |
| 273 |
for (i = 0; i < options.max_startups; i++) |
| 274 |
if (listener_pipes[i] != -1) |
| 275 |
close(listener_pipes[i]); |
| 268 |
} |
276 |
} |
| 269 |
|
277 |
|
| 270 |
/* |
278 |
/* |
|
Lines 295-301
sighup_restart(void)
Link Here
|
| 295 |
unlink(options.pid_file); |
303 |
unlink(options.pid_file); |
| 296 |
platform_pre_restart(); |
304 |
platform_pre_restart(); |
| 297 |
close_listen_socks(); |
305 |
close_listen_socks(); |
| 298 |
close_startup_pipes(); |
306 |
close_notification_pipes(); |
| 299 |
alarm(0); /* alarm timer persists across exec */ |
307 |
alarm(0); /* alarm timer persists across exec */ |
| 300 |
signal(SIGHUP, SIG_IGN); /* will be restored after exec */ |
308 |
signal(SIGHUP, SIG_IGN); /* will be restored after exec */ |
| 301 |
execv(saved_argv[0], saved_argv); |
309 |
execv(saved_argv[0], saved_argv); |
|
Lines 1022-1029
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1022 |
{ |
1030 |
{ |
| 1023 |
fd_set *fdset; |
1031 |
fd_set *fdset; |
| 1024 |
int i, j, ret, maxfd; |
1032 |
int i, j, ret, maxfd; |
| 1025 |
int startups = 0; |
1033 |
int startups = 0, listening_children = 0; |
| 1026 |
int startup_p[2] = { -1 , -1 }; |
1034 |
int startup_p[2] = { -1 , -1 }; |
|
|
1035 |
int listener_p[2] = { -1 , -1 }; |
| 1027 |
struct sockaddr_storage from; |
1036 |
struct sockaddr_storage from; |
| 1028 |
socklen_t fromlen; |
1037 |
socklen_t fromlen; |
| 1029 |
pid_t pid; |
1038 |
pid_t pid; |
|
Lines 1040-1051
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1040 |
for (i = 0; i < options.max_startups; i++) |
1049 |
for (i = 0; i < options.max_startups; i++) |
| 1041 |
startup_pipes[i] = -1; |
1050 |
startup_pipes[i] = -1; |
| 1042 |
|
1051 |
|
|
|
1052 |
/* pipes connected to listening childs */ |
| 1053 |
listener_pipes = xcalloc(options.max_startups, sizeof(int)); |
| 1054 |
for (i = 0; i < options.max_startups; i++) |
| 1055 |
listener_pipes[i] = -1; |
| 1056 |
|
| 1043 |
/* |
1057 |
/* |
| 1044 |
* Stay listening for connections until the system crashes or |
1058 |
* Stay listening for connections until the system crashes or |
| 1045 |
* the daemon is killed with a signal. |
1059 |
* the daemon is killed with a signal. |
| 1046 |
*/ |
1060 |
*/ |
| 1047 |
for (;;) { |
1061 |
for (;;) { |
| 1048 |
if (received_sighup) |
1062 |
if (received_sighup && |
|
|
1063 |
listening_children == 0) // TODO too heavy traffic may prevent us restarting forever |
| 1049 |
sighup_restart(); |
1064 |
sighup_restart(); |
| 1050 |
free(fdset); |
1065 |
free(fdset); |
| 1051 |
fdset = xcalloc(howmany(maxfd + 1, NFDBITS), |
1066 |
fdset = xcalloc(howmany(maxfd + 1, NFDBITS), |
|
Lines 1054-1061
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1054 |
for (i = 0; i < num_listen_socks; i++) |
1069 |
for (i = 0; i < num_listen_socks; i++) |
| 1055 |
FD_SET(listen_socks[i], fdset); |
1070 |
FD_SET(listen_socks[i], fdset); |
| 1056 |
for (i = 0; i < options.max_startups; i++) |
1071 |
for (i = 0; i < options.max_startups; i++) |
| 1057 |
if (startup_pipes[i] != -1) |
1072 |
if (startup_pipes[i] != -1) { |
| 1058 |
FD_SET(startup_pipes[i], fdset); |
1073 |
FD_SET(startup_pipes[i], fdset); |
|
|
1074 |
// assert(listener_pipes[i] != -1) |
| 1075 |
FD_SET(listener_pipes[i], fdset); |
| 1076 |
} |
| 1059 |
|
1077 |
|
| 1060 |
/* Wait in select until there is a connection. */ |
1078 |
/* Wait in select until there is a connection. */ |
| 1061 |
ret = select(maxfd+1, fdset, NULL, NULL, NULL); |
1079 |
ret = select(maxfd+1, fdset, NULL, NULL, NULL); |
|
Lines 1072-1077
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1072 |
if (ret < 0) |
1090 |
if (ret < 0) |
| 1073 |
continue; |
1091 |
continue; |
| 1074 |
|
1092 |
|
|
|
1093 |
for (i = 0; i < options.max_startups; i++) |
| 1094 |
if (listener_pipes[i] != -1 && |
| 1095 |
FD_ISSET(listener_pipes[i], fdset)) { |
| 1096 |
/* |
| 1097 |
* the read end of the pipe is ready |
| 1098 |
* if the child has closed the pipe |
| 1099 |
* after closing listen socket |
| 1100 |
* or if the child has died (that is handled |
| 1101 |
* via startup_pipes) |
| 1102 |
*/ |
| 1103 |
close(listener_pipes[i]); |
| 1104 |
listener_pipes[i] = -1; |
| 1105 |
listening_children--; |
| 1106 |
} |
| 1107 |
|
| 1075 |
for (i = 0; i < options.max_startups; i++) |
1108 |
for (i = 0; i < options.max_startups; i++) |
| 1076 |
if (startup_pipes[i] != -1 && |
1109 |
if (startup_pipes[i] != -1 && |
| 1077 |
FD_ISSET(startup_pipes[i], fdset)) { |
1110 |
FD_ISSET(startup_pipes[i], fdset)) { |
|
Lines 1085-1090
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1085 |
startup_pipes[i] = -1; |
1118 |
startup_pipes[i] = -1; |
| 1086 |
startups--; |
1119 |
startups--; |
| 1087 |
} |
1120 |
} |
|
|
1121 |
|
| 1122 |
/* Delay accepting new clients after we restart */ |
| 1123 |
if (received_sighup) |
| 1124 |
continue; |
| 1088 |
for (i = 0; i < num_listen_socks; i++) { |
1125 |
for (i = 0; i < num_listen_socks; i++) { |
| 1089 |
if (!FD_ISSET(listen_socks[i], fdset)) |
1126 |
if (!FD_ISSET(listen_socks[i], fdset)) |
| 1090 |
continue; |
1127 |
continue; |
|
Lines 1121-1126
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1121 |
close(*newsock); |
1158 |
close(*newsock); |
| 1122 |
continue; |
1159 |
continue; |
| 1123 |
} |
1160 |
} |
|
|
1161 |
if (pipe(listener_p) == -1) { |
| 1162 |
close(startup_p[0]); |
| 1163 |
close(startup_p[1]); |
| 1164 |
close(*newsock); |
| 1165 |
continue; |
| 1166 |
} |
| 1124 |
|
1167 |
|
| 1125 |
if (rexec_flag && socketpair(AF_UNIX, |
1168 |
if (rexec_flag && socketpair(AF_UNIX, |
| 1126 |
SOCK_STREAM, 0, config_s) == -1) { |
1169 |
SOCK_STREAM, 0, config_s) == -1) { |
|
Lines 1129-1134
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1129 |
close(*newsock); |
1172 |
close(*newsock); |
| 1130 |
close(startup_p[0]); |
1173 |
close(startup_p[0]); |
| 1131 |
close(startup_p[1]); |
1174 |
close(startup_p[1]); |
|
|
1175 |
close(listener_p[0]); |
| 1176 |
close(listener_p[1]); |
| 1132 |
continue; |
1177 |
continue; |
| 1133 |
} |
1178 |
} |
| 1134 |
|
1179 |
|
|
Lines 1138-1143
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1138 |
if (maxfd < startup_p[0]) |
1183 |
if (maxfd < startup_p[0]) |
| 1139 |
maxfd = startup_p[0]; |
1184 |
maxfd = startup_p[0]; |
| 1140 |
startups++; |
1185 |
startups++; |
|
|
1186 |
|
| 1187 |
listener_pipes[j] = listener_p[0]; |
| 1188 |
if (maxfd < listener_p[0]) |
| 1189 |
maxfd = listener_p[0]; |
| 1190 |
listening_children++; |
| 1141 |
break; |
1191 |
break; |
| 1142 |
} |
1192 |
} |
| 1143 |
|
1193 |
|
|
Lines 1157-1162
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1157 |
*sock_out = *newsock; |
1207 |
*sock_out = *newsock; |
| 1158 |
close(startup_p[0]); |
1208 |
close(startup_p[0]); |
| 1159 |
close(startup_p[1]); |
1209 |
close(startup_p[1]); |
|
|
1210 |
close(listener_p[0]); |
| 1211 |
close(listener_p[1]); |
| 1160 |
startup_pipe = -1; |
1212 |
startup_pipe = -1; |
| 1161 |
pid = getpid(); |
1213 |
pid = getpid(); |
| 1162 |
if (rexec_flag) { |
1214 |
if (rexec_flag) { |
|
Lines 1183-1190
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1183 |
*/ |
1235 |
*/ |
| 1184 |
platform_post_fork_child(); |
1236 |
platform_post_fork_child(); |
| 1185 |
startup_pipe = startup_p[1]; |
1237 |
startup_pipe = startup_p[1]; |
| 1186 |
close_startup_pipes(); |
1238 |
close_notification_pipes(); |
| 1187 |
close_listen_socks(); |
1239 |
close_listen_socks(); |
|
|
1240 |
/* Notify parent about free'd listen sock */ |
| 1241 |
close(listener_p[1]); |
| 1188 |
*sock_in = *newsock; |
1242 |
*sock_in = *newsock; |
| 1189 |
*sock_out = *newsock; |
1243 |
*sock_out = *newsock; |
| 1190 |
log_init(__progname, |
1244 |
log_init(__progname, |
|
Lines 1204-1209
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
Link Here
|
| 1204 |
debug("Forked child %ld.", (long)pid); |
1258 |
debug("Forked child %ld.", (long)pid); |
| 1205 |
|
1259 |
|
| 1206 |
close(startup_p[1]); |
1260 |
close(startup_p[1]); |
|
|
1261 |
close(listener_p[1]); |
| 1207 |
|
1262 |
|
| 1208 |
if (rexec_flag) { |
1263 |
if (rexec_flag) { |
| 1209 |
send_rexec_state(config_s[0], cfg); |
1264 |
send_rexec_state(config_s[0], cfg); |
| 1210 |
- |
|
|