]> git.saurik.com Git - apple/network_cmds.git/blobdiff - rpc_lockd.tproj/lockd.c
network_cmds-245.16.tar.gz
[apple/network_cmds.git] / rpc_lockd.tproj / lockd.c
index f8e46db5ef62334797bbba5118d03e98c419a8d2..07a1c90922cd8a24c1722312c046cb89dd82346b 100644 (file)
@@ -59,6 +59,8 @@ __RCSID("$NetBSD: lockd.c,v 1.7 2000/08/12 18:08:44 thorpej Exp $");
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/sysctl.h>
 
 #include <rpc/rpc.h>
 #include <rpc/pmap_clnt.h>
@@ -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 <debuglevel>] [-g <grace period>] [-w]");
+       errx(1, "usage: rpc.lockd [-d <debuglevel>] [-g <grace period>] "
+           " [-x <statd cache timeout>] [-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();
+       }
+}