Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/ctld/ctld.cc
| Show First 20 Lines • Show All 2,289 Lines • ▼ Show 20 Lines | start_timer(int timeout, bool fatal) | ||||
| bzero(&itv, sizeof(itv)); | bzero(&itv, sizeof(itv)); | ||||
| itv.it_interval.tv_sec = 1; | itv.it_interval.tv_sec = 1; | ||||
| itv.it_value.tv_sec = timeout; | itv.it_value.tv_sec = timeout; | ||||
| error = setitimer(ITIMER_REAL, &itv, NULL); | error = setitimer(ITIMER_REAL, &itv, NULL); | ||||
| if (error != 0) | if (error != 0) | ||||
| log_err(1, "setitimer"); | log_err(1, "setitimer"); | ||||
| } | } | ||||
| static int | static void | ||||
| wait_for_children(bool block) | wait_for_children(bool block) | ||||
| { | { | ||||
| pid_t pid; | pid_t pid; | ||||
| int status; | int status; | ||||
| int num = 0; | |||||
| for (;;) { | |||||
| /* | /* | ||||
| * If "block" is true, wait for at least one process. | * If "block" is true, wait for at least one process. | ||||
| */ | */ | ||||
| if (block && num == 0) | while (nchildren > 0) { | ||||
| if (block) | |||||
| pid = wait4(-1, &status, 0, NULL); | pid = wait4(-1, &status, 0, NULL); | ||||
| else | else | ||||
| pid = wait4(-1, &status, WNOHANG, NULL); | pid = wait4(-1, &status, WNOHANG, NULL); | ||||
| if (pid <= 0) | if (pid <= 0) | ||||
| break; | break; | ||||
| if (WIFSIGNALED(status)) { | if (WIFSIGNALED(status)) { | ||||
| log_warnx("child process %d terminated with signal %d", | log_warnx("child process %d terminated with signal %d", | ||||
| pid, WTERMSIG(status)); | pid, WTERMSIG(status)); | ||||
| } else if (WEXITSTATUS(status) != 0) { | } else if (WEXITSTATUS(status) != 0) { | ||||
| log_warnx("child process %d terminated with exit status %d", | log_warnx("child process %d terminated with exit status %d", | ||||
| pid, WEXITSTATUS(status)); | pid, WEXITSTATUS(status)); | ||||
| } else { | } else { | ||||
| log_debugx("child process %d terminated gracefully", pid); | log_debugx("child process %d terminated gracefully", pid); | ||||
| } | } | ||||
| num++; | nchildren--; | ||||
| } | |||||
| return (num); | block = false; | ||||
| } | } | ||||
| } | |||||
| static void | static void | ||||
| handle_connection(struct portal *portal, freebsd::fd_up fd, | handle_connection(struct portal *portal, freebsd::fd_up fd, | ||||
| const struct sockaddr *client_sa, bool dont_fork) | const struct sockaddr *client_sa, bool dont_fork) | ||||
| { | { | ||||
| struct portal_group *pg; | struct portal_group *pg; | ||||
| int error; | int error; | ||||
| pid_t pid; | pid_t pid; | ||||
| char host[NI_MAXHOST + 1]; | char host[NI_MAXHOST + 1]; | ||||
| struct conf *conf; | struct conf *conf; | ||||
| pg = portal->portal_group(); | pg = portal->portal_group(); | ||||
| conf = pg->conf(); | conf = pg->conf(); | ||||
| if (dont_fork) { | if (dont_fork) { | ||||
| log_debugx("incoming connection; not forking due to -d flag"); | log_debugx("incoming connection; not forking due to -d flag"); | ||||
| } else { | } else { | ||||
| nchildren -= wait_for_children(false); | wait_for_children(false); | ||||
| assert(nchildren >= 0); | |||||
| while (conf->maxproc() > 0 && nchildren >= conf->maxproc()) { | while (conf->maxproc() > 0 && nchildren >= conf->maxproc()) { | ||||
| log_debugx("maxproc limit of %d child processes hit; " | log_debugx("maxproc limit of %d child processes hit; " | ||||
| "waiting for child process to exit", | "waiting for child process to exit", | ||||
| conf->maxproc()); | conf->maxproc()); | ||||
| nchildren -= wait_for_children(true); | wait_for_children(true); | ||||
| assert(nchildren >= 0); | |||||
| } | } | ||||
| log_debugx("incoming connection; forking child process #%d", | log_debugx("incoming connection; forking child process #%d", | ||||
| nchildren); | nchildren); | ||||
| nchildren++; | nchildren++; | ||||
| pid = fork(); | pid = fork(); | ||||
| if (pid < 0) | if (pid < 0) | ||||
| log_err(1, "fork"); | log_err(1, "fork"); | ||||
| if (pid > 0) | if (pid > 0) | ||||
| ▲ Show 20 Lines • Show All 423 Lines • ▼ Show 20 Lines | if (sighup_received) { | ||||
| error = newconf->apply(oldconf.get()); | error = newconf->apply(oldconf.get()); | ||||
| if (error != 0) | if (error != 0) | ||||
| log_warnx("failed to apply configuration"); | log_warnx("failed to apply configuration"); | ||||
| oldconf.reset(); | oldconf.reset(); | ||||
| log_warnx("exiting on signal"); | log_warnx("exiting on signal"); | ||||
| return (0); | return (0); | ||||
| } else { | } else { | ||||
| nchildren -= wait_for_children(false); | wait_for_children(false); | ||||
| assert(nchildren >= 0); | |||||
| if (timed_out()) { | if (timed_out()) { | ||||
| newconf->isns_update(); | newconf->isns_update(); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* NOTREACHED */ | /* NOTREACHED */ | ||||
| } | } | ||||