static void up_calibratedelay(void) { int i; swarn("Beginning 100s delay\n"); for (i = 0; i < 100; i++) { up_mdelay(1000); } swarn("End 100s delay\n"); }
static int rew_sub(enum mdoc_type t, struct mdoc *m, enum mdoct tok, int line, int ppos) { struct mdoc_node *n; enum rew c; /* LINTED */ for (n = m->last; n; n = n->parent) { c = rew_dohalt(tok, t, n); if (REWIND_HALT == c) { if (MDOC_BLOCK != t) return(1); if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) return(1); /* FIXME: shouldn't raise an error */ mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTNOSCOPE); return(0); } if (REWIND_REWIND == c) break; else if (rew_dobreak(tok, n)) continue; if ( ! swarn(m, t, line, ppos, n)) return(0); } assert(n); if ( ! rew_last(m, n)) return(0); #ifdef UGLY /* * The current block extends an enclosing block beyond a line * break. Now that the current block ends, close the enclosing * block, too. */ if (NULL != (n = n->pending)) { assert(MDOC_HEAD == n->type); if ( ! rew_last(m, n)) return(0); if ( ! mdoc_body_alloc(m, n->line, n->pos, n->tok)) return(0); } #endif return(1); }
void mother_envsetup(void) { const char *function = "mother_envsetup()"; const int exitsignalv[] = { SIGINT, SIGQUIT, SIGBUS, SIGSEGV, SIGTERM, SIGILL, SIGFPE #ifdef SIGSYS , SIGSYS #endif /* SIGSYS */ }; const size_t pipetomotherfds = 2; /* fds needed for pipe to mother. */ const size_t exitsignalc = ELEMENTS(exitsignalv); const int ignoresignalv[] = { SIGPIPE }; const size_t ignoresignalc = ELEMENTS(ignoresignalv); struct sigaction sigact; struct rlimit rlimit; #ifdef RLIMIT_NPROC struct rlimit maxproc; #endif /* RLIMIT_NPROC */ rlim_t maxopenfd, minfd_neg, minfd_req, minfd_io, minfd; size_t i, fdreserved; for (fdreserved = 0; fdreserved < ELEMENTS(sockscf.state.reservedfdv); ++fdreserved) if ((sockscf.state.reservedfdv[fdreserved] = makedummyfd(0, 0)) == -1) serr("%s: could not reserve fd #%lu for later use", function, (unsigned long)fdreserved + 1); /* * close any descriptor we don't need, both in case of chroot(2) * and for needing every descriptor we can get. */ /* assume syslog uses one */ fdreserved += sockscf.log.type & LOGTYPE_SYSLOG ? 0 : 1; /* * shmem-segments we may need to attach to temporarily in relation * to doing rulespermit() and similar for a client. */ fdreserved += 1 /* bw fd */ + 1 /* session fd */ + 1; /* monitor fd */ for (i = 0, maxopenfd = getmaxofiles(softlimit); (rlim_t)i < maxopenfd; ++i) { size_t j; if (descriptorisreserved((int)i)) { ++fdreserved; continue; } /* sockets we listen on. */ for (j = 0; j < sockscf.internal.addrc; ++j) { if ((int)i == sockscf.internal.addrv[j].s) break; } if (j < sockscf.internal.addrc) /* listening on this socket. */ continue; close((int)i); } errno = 0; newprocinit(); /* just in case the above closed a syslog(3) fd. */ /* * Check system limits against what we need. * Enough descriptors for each child process? + 2 for the pipes from * the child to mother. */ minfd_neg = (SOCKD_NEGOTIATEMAX * 1) + pipetomotherfds + fdreserved; minfd_req = (SOCKD_REQUESTMAX * FDPASS_MAX) + pipetomotherfds + fdreserved; minfd_io = (SOCKD_IOMAX * FDPASS_MAX) + pipetomotherfds + fdreserved; /* i/o process stays attached to bw and monitor shmem all the time. */ minfd_io += SOCKD_IOMAX * (1 + 1); #if BAREFOOTD minfd_io += MIN(10, MIN_UDPCLIENTS); #endif slog(LOG_DEBUG, "%s: minfd_negotiate: %lu, minfd_request: %lu, minfd_io: %lu", function, (unsigned long)minfd_neg, (unsigned long)minfd_req, (unsigned long)minfd_io); /* * need to know max number of open files so we can allocate correctly * sized fd_sets. Also, try to set both it and the max number of * processes to the hard limit. */ sockscf.state.maxopenfiles = getmaxofiles(hardlimit); slog(LOG_DEBUG, "hard limit for max number of open files is %lu, soft limit is %lu", (unsigned long)sockscf.state.maxopenfiles, (unsigned long)getmaxofiles(softlimit)); if (sockscf.state.maxopenfiles == RLIM_INFINITY) { sockscf.state.maxopenfiles = getmaxofiles(softlimit); SASSERTX(sockscf.state.maxopenfiles != RLIM_INFINITY); } minfd = MAX(minfd_neg, MAX(minfd_req, minfd_io)); if (sockscf.state.maxopenfiles < minfd) { slog(LOG_INFO, "have only %lu file descriptors available, but need at least %lu " "according to the configuration. Trying to increase it ...", (unsigned long)sockscf.state.maxopenfiles, (unsigned long)minfd); sockscf.state.maxopenfiles = minfd; } rlimit.rlim_cur = rlimit.rlim_max = sockscf.state.maxopenfiles; if (setrlimit(RLIMIT_OFILE, &rlimit) == 0) slog(LOG_DEBUG, "max number of file descriptors is now %lu", (unsigned long)sockscf.state.maxopenfiles); else { const char *problem; sockscf.state.maxopenfiles = getmaxofiles(hardlimit); if (sockscf.state.maxopenfiles < minfd_neg) problem = "SOCKD_NEGOTIATEMAX"; else if (sockscf.state.maxopenfiles < minfd_req) problem = "SOCKD_REQUESTMAX"; else if (sockscf.state.maxopenfiles < minfd_io) problem = "SOCKD_IOMAX"; else SERRX(sockscf.state.maxopenfiles); serrx("%s: failed to increase the max number of open file descriptors " "for ourselves via setrlimit(RLIMIT_OFILE) to %lu: %s. " "Increase the kernel/shell's max open files limit, or reduce " "the %s value in %s's include/config.h, or we will be unable to " "start up", function, (unsigned long)rlimit.rlim_max, strerror(errno), problem, PRODUCT); } #ifdef RLIMIT_NPROC if (getrlimit(RLIMIT_NPROC, &maxproc) != 0) swarn("getrlimit(RLIMIT_NPROC) failed"); else { maxproc.rlim_cur = maxproc.rlim_max; if (setrlimit(RLIMIT_NPROC, &maxproc) != 0) swarn("setrlimit(RLIMIT_NPROC, { %lu, %lu }) failed", (unsigned long)rlimit.rlim_cur, (unsigned long)rlimit.rlim_max); } #endif /* !RLIMIT_NPROC */ /* * set up signal handlers. */ bzero(&sigact, sizeof(sigact)); sigact.sa_flags = SA_RESTART | SA_NOCLDSTOP | SA_SIGINFO; sigact.sa_sigaction = siginfo; #if HAVE_SIGNAL_SIGINFO if (sigaction(SIGINFO, &sigact, NULL) != 0) serr("sigaction(SIGINFO)"); #endif /* HAVE_SIGNAL_SIGINFO */ /* * same handler, for systems without SIGINFO, as well as systems with * broken ("more secure") signal semantics. */ if (sigaction(SIGUSR1, &sigact, NULL) != 0) serr("sigaction(SIGUSR1)"); sigact.sa_sigaction = sighup; if (sigaction(SIGHUP, &sigact, NULL) != 0) serr("sigaction(SIGHUP)"); sigact.sa_sigaction = sigchld; if (sigaction(SIGCHLD, &sigact, NULL) != 0) serr("sigaction(SIGCHLD)"); sigact.sa_sigaction = sigterm; for (i = 0; (size_t)i < exitsignalc; ++i) if (sigaction(exitsignalv[i], &sigact, NULL) != 0) serr("sigaction(%d)", exitsignalv[i]); sigact.sa_handler = SIG_IGN; for (i = 0; (size_t)i < ignoresignalc; ++i) if (sigaction(ignoresignalv[i], &sigact, NULL) != 0) serr("sigaction(%d)", ignoresignalv[i]); sigact.sa_flags = SA_SIGINFO; /* want to be interrupted. */ sigact.sa_sigaction = sigalrm; if (sigaction(SIGALRM, &sigact, NULL) != 0) serr("sigaction(SIGALRM)"); if (sockscf.option.daemon) { if (daemon(1, 0) != 0) serr("daemon()"); newprocinit(); /* for daemon(). */ close(STDIN_FILENO); /* leave stdout/stderr, but close stdin. */ *sockscf.state.motherpidv = getpid(); /* we are the main mother. */ } if (HAVE_ENABLED_PIDFILE) { FILE *fp; sockd_priv(SOCKD_PRIV_PRIVILEGED, PRIV_ON); if ((fp = fopen(sockscf.option.pidfile, "w")) == NULL) { swarn("open(%s)", sockscf.option.pidfile); errno = 0; } sockd_priv(SOCKD_PRIV_PRIVILEGED, PRIV_OFF); if (fp != NULL) { if (fprintf(fp, "%lu\n", (unsigned long)sockscf.state.pid) == EOF) swarn("failed writing pid to pidfile %s", sockscf.option.pidfile); else sockscf.option.pidfilewritten = 1; fclose(fp); } } enable_childcreate(); freedescriptors(NULL, &sockscf.state.highestfdinuse); }
char * mother_getlimitinfo(void) { const char *function = "mother_getlimitinfo()"; static char buf[2048]; const int fds_per_proc = 2; /* two pipes */ const char *limiter, *prefix = "max clients calculation will not be done"; struct rlimit maxfd, maxproc; char maxprocstr[64], maxfdstr[64]; unsigned long negc_proc, negc_fd, reqc_proc, reqc_fd, ioc_proc, ioc_fd, negc_limit, reqc_limit, ioc_limit, proc_free, proc_used, procs, fds_free; if (getrlimit(RLIMIT_NOFILE, &maxfd) != 0) { swarn("%s: getrlimit(RLIMIT_NOFILE) failed", function); return ""; } #ifdef RLIMIT_NPROC if (getrlimit(RLIMIT_NPROC, &maxproc) != 0) { swarn("%s: %s: getrlimit(RLIMIT_NPROC) failed", function, prefix); return ""; } #else /* !RLIMIT_NPROC */ if ((maxproc.rlim_cur = (rlim_t)sysconf(_SC_CHILD_MAX)) == (rlim_t)-1) { swarn("%s: %s: sysconf(_SC_CHILD_MAX) failed", function, prefix); return ""; } maxproc.rlim_max = maxproc.rlim_cur; #endif /* !RLIMIT_NPROC */ if (maxfd.rlim_cur == RLIM_INFINITY && maxproc.rlim_cur == RLIM_INFINITY) return "no applicable environment resource limits configured"; proc_used = sockscf.option.serverc + childcheck(-PROC_NEGOTIATE) / SOCKD_NEGOTIATEMAX + childcheck(-PROC_REQUEST) / SOCKD_REQUESTMAX + childcheck(-PROC_IO) / SOCKD_IOMAX; proc_free = maxproc.rlim_cur - proc_used; if (maxproc.rlim_cur == RLIM_INFINITY) snprintf(maxprocstr, sizeof(maxprocstr), "no limit"); else snprintf(maxprocstr, sizeof(maxprocstr), "%lu (%lu free)", (unsigned long)maxproc.rlim_cur, proc_free); fds_free = freedescriptors(NULL, NULL) - FDPASS_MAX; if (maxfd.rlim_cur == RLIM_INFINITY) snprintf(maxfdstr, sizeof(maxfdstr), "no limit"); else snprintf(maxfdstr, sizeof(maxfdstr), "%lu (%lu free)", (unsigned long)maxfd.rlim_cur, fds_free); /* * Calculate the max number of new clients we can handle based on both * the process resource limit and the fd limit. */ /* * Process-based limit, disregarding any other limits. * Each process can handle SOCKD_{NEGOTIATE,REQUEST,IO}MAX clients. * We can create a max number of proc_free additional processes, so * the number of additional clients we can handle is the number * of additional clients multiplied by the number of clients each * process can handle. */ negc_proc = proc_free * SOCKD_NEGOTIATEMAX; reqc_proc = proc_free * SOCKD_REQUESTMAX; ioc_proc = proc_free * SOCKD_IOMAX; /* * FD-based limit, disregarding any other limits. * With the fds we have, we can create a given number of additional * processes (procs). * Each process needs fds_per_proc, and an additional * SOCKD_{NEGOTIATE,REQUEST,IO}MAX * <number of fds per client in this * phase> fds to handle the max number of clients, meaning we can handle * the following number of additional clients: */ procs = fds_free / fds_per_proc; negc_fd = MIN(((fds_free - fds_per_proc) / 1), SOCKD_NEGOTIATEMAX) * procs; reqc_fd = MIN(((fds_free - fds_per_proc) / FDPASS_MAX), SOCKD_REQUESTMAX) * procs; ioc_fd = MIN(((fds_free - fds_per_proc) / FDPASS_MAX), SOCKD_IOMAX) * procs; /* * Different process-types could be limited by different things, but * ignore that here. */ if (negc_proc < negc_fd || reqc_proc < reqc_fd || ioc_proc < ioc_fd) { limiter = "process"; negc_limit = negc_proc; reqc_limit = reqc_proc; ioc_limit = ioc_proc; } else { limiter = "open file"; negc_limit = negc_fd; reqc_limit = reqc_fd; ioc_limit = ioc_fd; } snprintf(buf, sizeof(buf), "max limits: processes: %s, files: %s, " "%s-slots: %lu, %s-slots: %lu, %s-slots: %lu " "(max clients limited by %s limit)", maxprocstr, maxfdstr, childtype2string(PROC_NEGOTIATE), negc_limit, childtype2string(PROC_REQUEST), reqc_limit, childtype2string(PROC_IO), ioc_limit, limiter); return buf; }