X-Git-Url: https://git.saurik.com/apple/network_cmds.git/blobdiff_plain/ac2f15b3eadabcc5cceb4bb7f642395e9616a902..44d75bbf245e7a9e4b9d47cda6a7696ef781e19f:/rpc_lockd.tproj/lockd.c diff --git a/rpc_lockd.tproj/lockd.c b/rpc_lockd.tproj/lockd.c index f8e46db..07a1c90 100644 --- a/rpc_lockd.tproj/lockd.c +++ b/rpc_lockd.tproj/lockd.c @@ -59,6 +59,8 @@ __RCSID("$NetBSD: lockd.c,v 1.7 2000/08/12 18:08:44 thorpej Exp $"); #include #include #include +#include +#include #include #include @@ -90,6 +92,7 @@ void cleanup_pid_file(void); void handle_sig_cleanup(int); void sigalarm_handler(void); +void my_svc_run(void); const char *transports[] = { "udp", "tcp", "udp6", "tcp6" }; @@ -102,8 +105,13 @@ main(argc, argv) int ch; struct sigaction sigalarm; int grace_period = 30; + struct rlimit rlp; + int mib[6]; + int oldstate; + int oldsize; + int newstate; - while ((ch = getopt(argc, argv, "d:g:w")) != (-1)) { + while ((ch = getopt(argc, argv, "d:g:wx:")) != (-1)) { switch (ch) { case 'd': debug_level = atoi(optarg); @@ -122,6 +130,9 @@ main(argc, argv) case 'w': waitkern = 1; break; + case 'x': + host_expire = atoi(optarg); + break; default: case '?': usage(); @@ -137,7 +148,7 @@ main(argc, argv) * Note that it is NOT sensible to run this program from inetd - the * protocol assumes that it will run immediately at boot time. */ - if (debug_level != 99 && daemon(0, 0)) { + if (debug_level != 99 && daemon(0, debug_level > 0)) { err(1, "cannot fork"); /* NOTREACHED */ } @@ -148,8 +159,25 @@ main(argc, argv) signal(SIGHUP, handle_sig_cleanup); signal(SIGQUIT, handle_sig_cleanup); - if (claim_pid_file("/var/run/lockd.pid", 0) < 0) - errx(1, "cannot claim pid file"); + + + openlog("rpc.lockd", debug_level == 99 ? LOG_PERROR : 0, LOG_DAEMON); + + mib[0] = CTL_KERN; + mib[1] = KERN_PROCDELAYTERM; + + oldstate = 0; + oldsize = 4; + newstate = 1; + + if (sysctl(mib, 2, &oldstate, &oldsize, &newstate, 4) < 0) { + syslog(LOG_INFO, "cannot mark pid for delayed termination"); + } + + if (claim_pid_file("/var/run/lockd.pid", 0) < 0) { + syslog(LOG_ERR, "cannot claim pid file"); + exit(1); + } if (waitkern) { struct timespec ts; @@ -164,7 +192,6 @@ main(argc, argv) nanosleep(&ts, NULL); } - openlog("rpc.lockd", 0, LOG_DAEMON); if (debug_level) syslog(LOG_INFO, "Starting, debug level %d", debug_level); else @@ -176,24 +203,48 @@ main(argc, argv) (void)pmap_unset(NLM_PROG, NLM_VERS4); transp = svcudp_create(RPC_ANYSOCK); - if (transp == NULL) - errx(1, "cannot create udp service"); - if (!svc_register(transp, NLM_PROG, NLM_VERS, nlm_prog_1, IPPROTO_UDP)) - errx(1, "unable to register (NLM_PROG, NLM_VERS, udp)"); - if (!svc_register(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, IPPROTO_UDP)) - errx(1, "unable to register (NLM_PROG, NLM_VERSX, udp)"); - if (!svc_register(transp, NLM_PROG, NLM_VERS4, nlm_prog_4, IPPROTO_UDP)) - errx(1, "unable to register (NLM_PROG, NLM_VERS4, udp)"); + if (transp == NULL) { + syslog(LOG_ERR, "cannot create udp service"); + exit(1); + } + if (!svc_register(transp, NLM_PROG, NLM_SM, nlm_prog_0, IPPROTO_UDP)) { + syslog(LOG_ERR, "unable to register (NLM_PROG, NLM_SM, udp)"); + exit(1); + } + if (!svc_register(transp, NLM_PROG, NLM_VERS, nlm_prog_1, IPPROTO_UDP)) { + syslog(LOG_ERR, "unable to register (NLM_PROG, NLM_VERS, udp)"); + exit(1); + } + if (!svc_register(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, IPPROTO_UDP)) { + syslog(LOG_ERR, "unable to register (NLM_PROG, NLM_VERSX, udp)"); + exit(1); + } + if (!svc_register(transp, NLM_PROG, NLM_VERS4, nlm_prog_4, IPPROTO_UDP)) { + syslog(LOG_ERR, "unable to register (NLM_PROG, NLM_VERS4, udp)"); + exit(1); + } transp = svctcp_create(RPC_ANYSOCK, 0, 0); - if (transp == NULL) - errx(1, "cannot create tcp service"); - if (!svc_register(transp, NLM_PROG, NLM_VERS, nlm_prog_1, IPPROTO_TCP)) - errx(1, "unable to register (NLM_PROG, NLM_VERS, tcp)"); - if (!svc_register(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, IPPROTO_TCP)) - errx(1, "unable to register (NLM_PROG, NLM_VERSX, tcp)"); - if (!svc_register(transp, NLM_PROG, NLM_VERS4, nlm_prog_4, IPPROTO_TCP)) - errx(1, "unable to register (NLM_PROG, NLM_VERS4, tcp)"); + if (transp == NULL) { + syslog(LOG_ERR, "cannot create tcp service"); + exit(1); + } + if (!svc_register(transp, NLM_PROG, NLM_SM, nlm_prog_0, IPPROTO_TCP)) { + syslog(LOG_ERR, "unable to register (NLM_PROG, NLM_SM, tcp)"); + exit(1); + } + if (!svc_register(transp, NLM_PROG, NLM_VERS, nlm_prog_1, IPPROTO_TCP)) { + syslog(LOG_ERR, "unable to register (NLM_PROG, NLM_VERS, tcp)"); + exit(1); + } + if (!svc_register(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, IPPROTO_TCP)) { + syslog(LOG_ERR, "unable to register (NLM_PROG, NLM_VERSX, tcp)"); + exit(1); + } + if (!svc_register(transp, NLM_PROG, NLM_VERS4, nlm_prog_4, IPPROTO_TCP)) { + syslog(LOG_ERR, "unable to register (NLM_PROG, NLM_VERS4, tcp)"); + exit(1); + } sigalarm.sa_handler = (sig_t) sigalarm_handler; sigemptyset(&sigalarm.sa_mask); @@ -211,7 +262,19 @@ main(argc, argv) client_pid = client_request(); - svc_run(); /* Should never return */ + /* raise our resource limits as far as they can go */ + if (getrlimit(RLIMIT_NOFILE, &rlp)) { + syslog(LOG_WARNING, "getrlimit(RLIMIT_NOFILE) failed: %s", + strerror(errno)); + } else { + rlp.rlim_cur = rlp.rlim_max; + if (setrlimit(RLIMIT_NOFILE, &rlp)) { + syslog(LOG_WARNING, "setrlimit(RLIMIT_NOFILE) failed: %s", + strerror(errno)); + } + } + + my_svc_run(); /* Should never return */ exit(1); } @@ -225,7 +288,8 @@ sigalarm_handler(void) void usage() { - errx(1, "usage: rpc.lockd [-d ] [-g ] [-w]"); + errx(1, "usage: rpc.lockd [-d ] [-g ] " + " [-x ] [-w]"); } /* @@ -260,7 +324,7 @@ init_nsm(void) ret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON_ALL, xdr_my_id, &id, xdr_sm_stat, &stat); if (ret) { - warnx("%lu %s", SM_PROG, clnt_sperrno(ret)); + syslog(LOG_WARNING, "%lu %s", SM_PROG, clnt_sperrno(ret)); if (++attempt < 20) { sleep(attempt); continue; @@ -270,7 +334,8 @@ init_nsm(void) } while (1); if (ret != 0) { - errx(1, "%lu %s", SM_PROG, clnt_sperrno(ret)); + syslog(LOG_ERR, "%lu %s", SM_PROG, clnt_sperrno(ret)); + exit(1); } nsm_state = stat.state; @@ -369,3 +434,45 @@ handle_sig_cleanup(int sig __unused) exit(1); } +void +my_svc_run(void) +{ + fd_set readfds; + struct timeval timeout; + struct timeval now; + int error; + int hashosts = 0; + int tsize = 0; + struct timeval *top; + + + for( ;; ) { + timeout.tv_sec = host_expire + 1; + timeout.tv_usec = 0; + + tsize = getdtablesize(); + bcopy(&svc_fdset, &readfds, sizeof(svc_fdset)); + /* + * If there are any expired hosts then sleep with a + * timeout to expire them. + */ + if (hashosts && (timeout.tv_sec >= 0)) + top = &timeout; + else + top = NULL; + error = select(tsize, &readfds, NULL, NULL, top); + if (error == -1) { + if (errno == EINTR) + continue; + perror("rpc.lockd: my_svc_run: select failed"); + return; + } + gettimeofday(&now, NULL); + currsec = now.tv_sec; + if (error > 0) + svc_getreqset(&readfds); + if (debug_level > 3 && error == 0) + fprintf(stderr, "my_svc_run: select timeout\n"); + hashosts = expire_lock_hosts(); + } +}