Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/rpc.lockd Implement file locking in lockd. All the ...



details:   https://anonhg.NetBSD.org/src/rev/12d36a3bd54a
branches:  trunk
changeset: 487418:12d36a3bd54a
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Wed Jun 07 14:34:40 2000 +0000

description:
Implement file locking in lockd. All the stuff is done in userland, using
fhopen() and flock(). This means that if you kill lockd, all locks will
be relased (but you're supposed to kill statd at the same time, so
remote hosts will know it and re-establish the lock).
Tested against solaris 2.7 and linux 2.2.14 clients.
Shared lock are not handled efficiently, they're serialised in lockd when they
could be granted.

diffstat:

 usr.sbin/rpc.lockd/Makefile     |    4 +-
 usr.sbin/rpc.lockd/lock_proc.c  |  225 ++++++++---
 usr.sbin/rpc.lockd/lockd.c      |   92 +++-
 usr.sbin/rpc.lockd/lockd.h      |    4 +-
 usr.sbin/rpc.lockd/lockd_lock.c |  756 ++++++++++++++++++++++++++++++++++++++++
 usr.sbin/rpc.lockd/lockd_lock.h |   20 +
 usr.sbin/rpc.lockd/rpc.lockd.8  |   16 +-
 7 files changed, 1018 insertions(+), 99 deletions(-)

diffs (truncated from 1577 to 300 lines):

diff -r 0fa803489afd -r 12d36a3bd54a usr.sbin/rpc.lockd/Makefile
--- a/usr.sbin/rpc.lockd/Makefile       Wed Jun 07 14:30:15 2000 +0000
+++ b/usr.sbin/rpc.lockd/Makefile       Wed Jun 07 14:34:40 2000 +0000
@@ -1,7 +1,7 @@
-#      $NetBSD: Makefile,v 1.7 1999/06/06 03:13:13 thorpej Exp $
+#      $NetBSD: Makefile,v 1.8 2000/06/07 14:34:40 bouyer Exp $
 
 PROG=  rpc.lockd
-SRCS=  nlm_prot_svc.c lockd.c lock_proc.c
+SRCS=  nlm_prot_svc.c lockd.c lock_proc.c lockd_lock.c
 MAN=   rpc.lockd.8
 MLINKS=        rpc.lockd.8 lockd.8
 
diff -r 0fa803489afd -r 12d36a3bd54a usr.sbin/rpc.lockd/lock_proc.c
--- a/usr.sbin/rpc.lockd/lock_proc.c    Wed Jun 07 14:30:15 2000 +0000
+++ b/usr.sbin/rpc.lockd/lock_proc.c    Wed Jun 07 14:34:40 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lock_proc.c,v 1.3 2000/02/02 18:17:42 bouyer Exp $     */
+/*     $NetBSD: lock_proc.c,v 1.4 2000/06/07 14:34:40 bouyer Exp $     */
 
 /*
  * Copyright (c) 1995
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: lock_proc.c,v 1.3 2000/02/02 18:17:42 bouyer Exp $");
+__RCSID("$NetBSD: lock_proc.c,v 1.4 2000/06/07 14:34:40 bouyer Exp $");
 #endif
 
 #include <sys/param.h>
@@ -54,15 +54,13 @@
 
 #include "lockd.h"
 #include "nlm_prot.h"
+#include "lockd_lock.h"
 
 
 #define        CLIENT_CACHE_SIZE       64      /* No. of client sockets cached */
 #define        CLIENT_CACHE_LIFETIME   120     /* In seconds */
 
-static CLIENT  *get_client __P((struct sockaddr_in *));
 static void    log_from_addr __P((char *, struct svc_req *));
-static void    transmit_result __P((int, nlm_res *, struct svc_req *));
-static void    transmit4_result __P((int, nlm4_res *, struct svc_req *));
 
 /* log_from_addr ----------------------------------------------------------- */
 /*
@@ -71,7 +69,7 @@
  * Notes:      Extracts the source address from the transport handle
  *             passed in as part of the called procedure specification
  */
-static void 
+static void
 log_from_addr(fun_name, req)
        char *fun_name;
        struct svc_req *req;
@@ -125,9 +123,10 @@
 static struct in_addr clnt_cache_addr[CLIENT_CACHE_SIZE];
 static int clnt_cache_next_to_use = 0;
 
-static CLIENT *
-get_client(host_addr)
+CLIENT *
+get_client(host_addr, vers)
        struct sockaddr_in *host_addr;
+       u_long vers;
 {
        CLIENT *client;
        struct timeval retry_time, time_now;
@@ -171,8 +170,13 @@
        retry_time.tv_sec = 5;
        retry_time.tv_usec = 0;
        host_addr->sin_port = 0; /* Force consultation with portmapper */
-       client = clntudp_create(host_addr, NLM_PROG, NLM_VERS,
+#if 1
+       client = clntudp_create(host_addr, NLM_PROG, vers,
            retry_time, &sock_no);
+#else 
+       client = clnttcp_create(host_addr, NLM_PROG, vers,
+           &sock_no, 0, 0);
+#endif
        if (!client) {
                syslog(LOG_ERR, clnt_spcreateerror("clntudp_create"));
                syslog(LOG_ERR, "Unable to return result to %s",
@@ -211,20 +215,18 @@
  *             calling it with timeout 0 as a hack to just issue a datagram
  *             without expecting a result
  */
-static void 
-transmit_result(opcode, result, req)
+void
+transmit_result(opcode, result, addr)
        int opcode;
        nlm_res *result;
-       struct svc_req *req;
+       struct sockaddr *addr;
 {
        static char dummy;
-       struct sockaddr_in *addr;
        CLIENT *cli;
        struct timeval timeo;
        int success;
 
-       addr = svc_getcaller(req->rq_xprt);
-       if ((cli = get_client(addr)) != NULL) {
+       if ((cli = get_client((struct sockaddr_in *)addr, NLM_VERS)) != NULL) {
                timeo.tv_sec = 0; /* No timeout - not expecting response */
                timeo.tv_usec = 0;
 
@@ -232,7 +234,8 @@
                    &dummy, timeo);
 
                if (debug_level > 2)
-                       syslog(LOG_DEBUG, "clnt_call returns %d\n", success);
+                       syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
+                           success, clnt_sperrno(success));
        }
 }
 /* transmit4_result --------------------------------------------------------- */
@@ -243,20 +246,18 @@
  *             calling it with timeout 0 as a hack to just issue a datagram
  *             without expecting a result
  */
-static void 
-transmit4_result(opcode, result, req)
+void
+transmit4_result(opcode, result, addr)
        int opcode;
        nlm4_res *result;
-       struct svc_req *req;
+       struct sockaddr *addr;
 {
        static char dummy;
-       struct sockaddr_in *addr;
        CLIENT *cli;
        struct timeval timeo;
        int success;
 
-       addr = svc_getcaller(req->rq_xprt);
-       if ((cli = get_client(addr)) != NULL) {
+       if ((cli = get_client((struct sockaddr_in *)addr, NLM_VERS4)) != NULL) {
                timeo.tv_sec = 0; /* No timeout - not expecting response */
                timeo.tv_usec = 0;
 
@@ -264,9 +265,24 @@
                    &dummy, timeo);
 
                if (debug_level > 2)
-                       syslog(LOG_DEBUG, "clnt_call returns %d\n", success);
+                       syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
+                           success, clnt_sperrno(success));
        }
 }
+
+/*
+ * converts a struct nlm_lock to struct nlm4_lock
+ */
+static void nlmtonlm4 __P((struct nlm_lock *, struct nlm4_lock *));
+static void
+nlmtonlm4(arg, arg4)
+       struct nlm_lock *arg;
+       struct nlm4_lock *arg4;
+{
+       memcpy(arg4, arg, sizeof(nlm_lock));
+       arg4->l_offset = arg->l_offset;
+       arg4->l_len = arg->l_len;
+}
 /* ------------------------------------------------------------------------- */
 /*
  * Functions for Unix<->Unix locking (ie. monitored locking, with rpc.statd
@@ -306,10 +322,14 @@
        struct svc_req *rqstp;
 {
        static nlm_testres res;
+       struct nlm4_lock arg4;
+       struct nlm4_holder *holder;
+       nlmtonlm4(&arg->alock, &arg4);
 
        if (debug_level)
                log_from_addr("nlm_test", rqstp);
 
+       holder = testlock(&arg4, 0);
        /*
         * Copy the cookie from the argument into the result.  Note that this
         * is slightly hazardous, as the structure contains a pointer to a
@@ -318,7 +338,15 @@
         * so it is in fact safe.
         */
        res.cookie = arg->cookie;
-       res.stat.stat = nlm_granted;
+       if (holder == NULL) {
+               res.stat.stat = nlm_granted;
+       } else {
+               res.stat.stat = nlm_denied;
+               memcpy(&res.stat.nlm_testrply_u.holder, holder,
+                   sizeof(struct nlm_holder));
+               res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
+               res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
+       }
        return (&res);
 }
 
@@ -333,19 +361,33 @@
        CLIENT *cli;
        int success;
        struct timeval timeo;
+       struct nlm4_lock arg4;
+       struct nlm4_holder *holder;
+
+       nlmtonlm4(&arg->alock, &arg4);
 
        if (debug_level)
                log_from_addr("nlm_test_msg", rqstp);
 
+       holder = testlock(&arg4, 0);
+
        res.cookie = arg->cookie;
-       res.stat.stat = nlm_granted;
+       if (holder == NULL) {
+               res.stat.stat = nlm_granted;
+       } else {
+               res.stat.stat = nlm_denied;
+               memcpy(&res.stat.nlm_testrply_u.holder, holder,
+                   sizeof(struct nlm_holder));
+               res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
+               res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
+       }
 
        /*
         * nlm_test has different result type to the other operations, so
         * can't use transmit_result() in this case
         */
        addr = svc_getcaller(rqstp->rq_xprt);
-       if ((cli = get_client(addr)) != NULL) {
+       if ((cli = get_client(addr, NLM_VERS)) != NULL) {
                timeo.tv_sec = 0; /* No timeout - not expecting response */
                timeo.tv_usec = 0;
 
@@ -353,7 +395,7 @@
                    &res, xdr_void, &dummy, timeo);
 
                if (debug_level > 2)
-                       syslog(LOG_DEBUG, "clnt_call returns %d\n", success);
+                       syslog(LOG_DEBUG, "clnt_call returns %d", success);
        }
        return (NULL);
 }
@@ -370,6 +412,13 @@
        struct svc_req *rqstp;
 {
        static nlm_res res;
+       struct nlm4_lockargs arg4;
+       nlmtonlm4(&arg->alock, &arg4.alock);
+       arg4.cookie = arg->cookie;
+       arg4.block = arg->block;
+       arg4.exclusive = arg->exclusive;
+       arg4.reclaim = arg->reclaim;
+       arg4.state = arg->state;
 
        if (debug_level)
                log_from_addr("nlm_lock", rqstp);
@@ -377,7 +426,7 @@
        /* copy cookie from arg to result.  See comment in nlm_test_1() */
        res.cookie = arg->cookie;
 
-       res.stat.stat = nlm_granted;
+       res.stat.stat = getlock(&arg4, rqstp, LOCK_MON);
        return (&res);
 }
 
@@ -387,13 +436,22 @@
        struct svc_req *rqstp;
 {
        static nlm_res res;
+       struct nlm4_lockargs arg4;
+
+       nlmtonlm4(&arg->alock, &arg4.alock);
+       arg4.cookie = arg->cookie;
+       arg4.block = arg->block;
+       arg4.exclusive = arg->exclusive;
+       arg4.reclaim = arg->reclaim;
+       arg4.state = arg->state;
 
        if (debug_level)
                log_from_addr("nlm_lock_msg", rqstp);
 
        res.cookie = arg->cookie;
-       res.stat.stat = nlm_granted;
-       transmit_result(NLM_LOCK_RES, &res, rqstp);
+       res.stat.stat = getlock(&arg4, rqstp, LOCK_ASYNC | LOCK_MON);
+       transmit_result(NLM_LOCK_RES, &res,
+           (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
 
        return (NULL);
 }
@@ -410,6 +468,9 @@
        struct svc_req *rqstp;
 {
        static nlm_res res;



Home | Main Index | Thread Index | Old Index