Home | History | Annotate | Line # | Download | only in rpc.lockd
lock_proc.c revision 1.5
      1 /*	$NetBSD: lock_proc.c,v 1.5 2000/06/09 14:00:52 fvdl Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1995
      5  *	A.R. Gordon (andrew.gordon (at) net-tel.co.uk).  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed for the FreeBSD project
     18  * 4. Neither the name of the author nor the names of any co-contributors
     19  *    may be used to endorse or promote products derived from this software
     20  *    without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY ANDREW GORDON AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  *
     34  */
     35 
     36 #include <sys/cdefs.h>
     37 #ifndef lint
     38 __RCSID("$NetBSD: lock_proc.c,v 1.5 2000/06/09 14:00:52 fvdl Exp $");
     39 #endif
     40 
     41 #include <sys/param.h>
     42 #include <sys/socket.h>
     43 
     44 #include <netinet/in.h>
     45 #include <arpa/inet.h>
     46 
     47 #include <netdb.h>
     48 #include <stdio.h>
     49 #include <string.h>
     50 #include <syslog.h>
     51 #include <netconfig.h>
     52 
     53 #include <rpc/rpc.h>
     54 #include <rpcsvc/sm_inter.h>
     55 
     56 #include "lockd.h"
     57 #include "nlm_prot.h"
     58 #include "lockd_lock.h"
     59 
     60 
     61 #define	CLIENT_CACHE_SIZE	64	/* No. of client sockets cached */
     62 #define	CLIENT_CACHE_LIFETIME	120	/* In seconds */
     63 
     64 static void	log_from_addr __P((char *, struct svc_req *));
     65 static int	addrcmp __P((struct sockaddr *, struct sockaddr *));
     66 
     67 /* log_from_addr ----------------------------------------------------------- */
     68 /*
     69  * Purpose:	Log name of function called and source address
     70  * Returns:	Nothing
     71  * Notes:	Extracts the source address from the transport handle
     72  *		passed in as part of the called procedure specification
     73  */
     74 static void
     75 log_from_addr(fun_name, req)
     76 	char *fun_name;
     77 	struct svc_req *req;
     78 {
     79 	struct sockaddr *addr;
     80 	char hostname_buf[NI_MAXHOST];
     81 
     82 	addr = svc_getrpccaller(req->rq_xprt)->buf;
     83 	if (getnameinfo(addr , addr->sa_len, hostname_buf, sizeof hostname_buf,
     84 	    NULL, 0, 0) != 0)
     85 		return;
     86 
     87 	syslog(LOG_DEBUG, "%s from %s", fun_name, hostname_buf);
     88 }
     89 
     90 /* get_client -------------------------------------------------------------- */
     91 /*
     92  * Purpose:	Get a CLIENT* for making RPC calls to lockd on given host
     93  * Returns:	CLIENT* pointer, from clnt_udp_create, or NULL if error
     94  * Notes:	Creating a CLIENT* is quite expensive, involving a
     95  *		conversation with the remote portmapper to get the
     96  *		port number.  Since a given client is quite likely
     97  *		to make several locking requests in succession, it is
     98  *		desirable to cache the created CLIENT*.
     99  *
    100  *		Since we are using UDP rather than TCP, there is no cost
    101  *		to the remote system in keeping these cached indefinitely.
    102  *		Unfortunately there is a snag: if the remote system
    103  *		reboots, the cached portmapper results will be invalid,
    104  *		and we will never detect this since all of the xxx_msg()
    105  *		calls return no result - we just fire off a udp packet
    106  *		and hope for the best.
    107  *
    108  *		We solve this by discarding cached values after two
    109  *		minutes, regardless of whether they have been used
    110  *		in the meanwhile (since a bad one might have been used
    111  *		plenty of times, as the host keeps retrying the request
    112  *		and we keep sending the reply back to the wrong port).
    113  *
    114  *		Given that the entries will always expire in the order
    115  *		that they were created, there is no point in a LRU
    116  *		algorithm for when the cache gets full - entries are
    117  *		always re-used in sequence.
    118  */
    119 static CLIENT *clnt_cache_ptr[CLIENT_CACHE_SIZE];
    120 static long clnt_cache_time[CLIENT_CACHE_SIZE];	/* time entry created */
    121 static struct sockaddr_storage clnt_cache_addr[CLIENT_CACHE_SIZE];
    122 static int clnt_cache_next_to_use = 0;
    123 
    124 static int
    125 addrcmp(sa1, sa2)
    126 	struct sockaddr *sa1;
    127 	struct sockaddr *sa2;
    128 {
    129 	int len;
    130 	void *p1, *p2;
    131 
    132 	if (sa1->sa_family != sa2->sa_family)
    133 		return -1;
    134 
    135 	switch (sa1->sa_family) {
    136 	case AF_INET:
    137 		p1 = &((struct sockaddr_in *)sa1)->sin_addr;
    138 		p2 = &((struct sockaddr_in *)sa2)->sin_addr;
    139 		len = 4;
    140 		break;
    141 	case AF_INET6:
    142 		p1 = &((struct sockaddr_in6 *)sa1)->sin6_addr;
    143 		p2 = &((struct sockaddr_in6 *)sa2)->sin6_addr;
    144 		len = 16;
    145 		break;
    146 	default:
    147 		return -1;
    148 	}
    149 
    150 	return memcmp(p1, p2, len);
    151 }
    152 
    153 CLIENT *
    154 get_client(host_addr, vers)
    155 	struct sockaddr *host_addr;
    156 	rpcvers_t vers;
    157 {
    158 	CLIENT *client;
    159 	struct timeval retry_time, time_now;
    160 	int i;
    161 	char *netid;
    162 	struct netconfig *nconf;
    163 	char host[NI_MAXHOST];
    164 
    165 	gettimeofday(&time_now, NULL);
    166 
    167 	/*
    168 	 * Search for the given client in the cache, zapping any expired
    169 	 * entries that we happen to notice in passing.
    170 	 */
    171 	for (i = 0; i < CLIENT_CACHE_SIZE; i++) {
    172 		client = clnt_cache_ptr[i];
    173 		if (client && ((clnt_cache_time[i] + CLIENT_CACHE_LIFETIME)
    174 		    < time_now.tv_sec)) {
    175 			/* Cache entry has expired. */
    176 			if (debug_level > 3)
    177 				syslog(LOG_DEBUG, "Expired CLIENT* in cache");
    178 			clnt_cache_time[i] = 0L;
    179 			clnt_destroy(client);
    180 			clnt_cache_ptr[i] = NULL;
    181 			client = NULL;
    182 		}
    183 		if (client && !addrcmp((struct sockaddr *)&clnt_cache_addr[i],
    184 		    host_addr)) {
    185 			/* Found it! */
    186 			if (debug_level > 3)
    187 				syslog(LOG_DEBUG, "Found CLIENT* in cache");
    188 			return (client);
    189 		}
    190 	}
    191 
    192 	/* Not found in cache.  Free the next entry if it is in use. */
    193 	if (clnt_cache_ptr[clnt_cache_next_to_use]) {
    194 		clnt_destroy(clnt_cache_ptr[clnt_cache_next_to_use]);
    195 		clnt_cache_ptr[clnt_cache_next_to_use] = NULL;
    196 	}
    197 
    198 	/*
    199 	 * Need a host string for clnt_tp_create. Use NI_NUMERICHOST
    200 	 * to avoid DNS lookups.
    201 	 */
    202 	if (getnameinfo(host_addr, host_addr->sa_len, host, sizeof host,
    203 	    NULL, 0, NI_NUMERICHOST) != 0) {
    204 		syslog(LOG_ERR, "unable to get name string for caller");
    205 		return NULL;
    206 	}
    207 
    208 #if 1
    209 	if (host_addr->sa_family == AF_INET6)
    210 		netid = "udp6";
    211 	else
    212 		netid = "udp";
    213 #else
    214 	if (host_addr->sa_family == AF_INET6)
    215 		netid = "tcp6";
    216 	else
    217 		netid = "tcp";
    218 #endif
    219 	nconf = getnetconfigent(netid);
    220 	if (nconf == NULL) {
    221 		syslog(LOG_ERR, "could not get netconfig info for '%s': "
    222 				"no /etc/netconfig file?", netid);
    223 		return NULL;
    224 	}
    225 
    226 	client = clnt_tp_create(host, NLM_PROG, vers, nconf);
    227 	freenetconfigent(nconf);
    228 
    229 	if (!client) {
    230 		syslog(LOG_ERR, clnt_spcreateerror("clntudp_create"));
    231 		syslog(LOG_ERR, "Unable to return result to %s", host);
    232 		return NULL;
    233 	}
    234 
    235 	/* Success - update the cache entry */
    236 	clnt_cache_ptr[clnt_cache_next_to_use] = client;
    237 	memcpy(&clnt_cache_addr[clnt_cache_next_to_use], host_addr,
    238 	    host_addr->sa_len);
    239 	clnt_cache_time[clnt_cache_next_to_use] = time_now.tv_sec;
    240 	if (++clnt_cache_next_to_use > CLIENT_CACHE_SIZE)
    241 		clnt_cache_next_to_use = 0;
    242 
    243 	/*
    244 	 * Disable the default timeout, so we can specify our own in calls
    245 	 * to clnt_call().  (Note that the timeout is a different concept
    246 	 * from the retry period set in clnt_udp_create() above.)
    247 	 */
    248 	retry_time.tv_sec = -1;
    249 	retry_time.tv_usec = -1;
    250 	clnt_control(client, CLSET_TIMEOUT, (char *)&retry_time);
    251 
    252 	if (debug_level > 3)
    253 		syslog(LOG_DEBUG, "Created CLIENT* for %s", host);
    254 	return client;
    255 }
    256 
    257 
    258 /* transmit_result --------------------------------------------------------- */
    259 /*
    260  * Purpose:	Transmit result for nlm_xxx_msg pseudo-RPCs
    261  * Returns:	Nothing - we have no idea if the datagram got there
    262  * Notes:	clnt_call() will always fail (with timeout) as we are
    263  *		calling it with timeout 0 as a hack to just issue a datagram
    264  *		without expecting a result
    265  */
    266 void
    267 transmit_result(opcode, result, addr)
    268 	int opcode;
    269 	nlm_res *result;
    270 	struct sockaddr *addr;
    271 {
    272 	static char dummy;
    273 	CLIENT *cli;
    274 	struct timeval timeo;
    275 	int success;
    276 
    277 	if ((cli = get_client(addr, NLM_VERS)) != NULL) {
    278 		timeo.tv_sec = 0; /* No timeout - not expecting response */
    279 		timeo.tv_usec = 0;
    280 
    281 		success = clnt_call(cli, opcode, xdr_nlm_res, result, xdr_void,
    282 		    &dummy, timeo);
    283 
    284 		if (debug_level > 2)
    285 			syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
    286 			    success, clnt_sperrno(success));
    287 	}
    288 }
    289 /* transmit4_result --------------------------------------------------------- */
    290 /*
    291  * Purpose:	Transmit result for nlm4_xxx_msg pseudo-RPCs
    292  * Returns:	Nothing - we have no idea if the datagram got there
    293  * Notes:	clnt_call() will always fail (with timeout) as we are
    294  *		calling it with timeout 0 as a hack to just issue a datagram
    295  *		without expecting a result
    296  */
    297 void
    298 transmit4_result(opcode, result, addr)
    299 	int opcode;
    300 	nlm4_res *result;
    301 	struct sockaddr *addr;
    302 {
    303 	static char dummy;
    304 	CLIENT *cli;
    305 	struct timeval timeo;
    306 	int success;
    307 
    308 	if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
    309 		timeo.tv_sec = 0; /* No timeout - not expecting response */
    310 		timeo.tv_usec = 0;
    311 
    312 		success = clnt_call(cli, opcode, xdr_nlm4_res, result, xdr_void,
    313 		    &dummy, timeo);
    314 
    315 		if (debug_level > 2)
    316 			syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
    317 			    success, clnt_sperrno(success));
    318 	}
    319 }
    320 
    321 /*
    322  * converts a struct nlm_lock to struct nlm4_lock
    323  */
    324 static void nlmtonlm4 __P((struct nlm_lock *, struct nlm4_lock *));
    325 static void
    326 nlmtonlm4(arg, arg4)
    327 	struct nlm_lock *arg;
    328 	struct nlm4_lock *arg4;
    329 {
    330 	memcpy(arg4, arg, sizeof(nlm_lock));
    331 	arg4->l_offset = arg->l_offset;
    332 	arg4->l_len = arg->l_len;
    333 }
    334 /* ------------------------------------------------------------------------- */
    335 /*
    336  * Functions for Unix<->Unix locking (ie. monitored locking, with rpc.statd
    337  * involved to ensure reclaim of locks after a crash of the "stateless"
    338  * server.
    339  *
    340  * These all come in two flavours - nlm_xxx() and nlm_xxx_msg().
    341  * The first are standard RPCs with argument and result.
    342  * The nlm_xxx_msg() calls implement exactly the same functions, but
    343  * use two pseudo-RPCs (one in each direction).  These calls are NOT
    344  * standard use of the RPC protocol in that they do not return a result
    345  * at all (NB. this is quite different from returning a void result).
    346  * The effect of this is to make the nlm_xxx_msg() calls simple unacknowledged
    347  * datagrams, requiring higher-level code to perform retries.
    348  *
    349  * Despite the disadvantages of the nlm_xxx_msg() approach (some of which
    350  * are documented in the comments to get_client() above), this is the
    351  * interface used by all current commercial NFS implementations
    352  * [Solaris, SCO, AIX etc.].  This is presumed to be because these allow
    353  * implementations to continue using the standard RPC libraries, while
    354  * avoiding the block-until-result nature of the library interface.
    355  *
    356  * No client implementations have been identified so far that make use
    357  * of the true RPC version (early SunOS releases would be a likely candidate
    358  * for testing).
    359  */
    360 
    361 /* nlm_test ---------------------------------------------------------------- */
    362 /*
    363  * Purpose:	Test whether a specified lock would be granted if requested
    364  * Returns:	nlm_granted (or error code)
    365  * Notes:
    366  */
    367 nlm_testres *
    368 nlm_test_1_svc(arg, rqstp)
    369 	nlm_testargs *arg;
    370 	struct svc_req *rqstp;
    371 {
    372 	static nlm_testres res;
    373 	struct nlm4_lock arg4;
    374 	struct nlm4_holder *holder;
    375 	nlmtonlm4(&arg->alock, &arg4);
    376 
    377 	if (debug_level)
    378 		log_from_addr("nlm_test", rqstp);
    379 
    380 	holder = testlock(&arg4, 0);
    381 	/*
    382 	 * Copy the cookie from the argument into the result.  Note that this
    383 	 * is slightly hazardous, as the structure contains a pointer to a
    384 	 * malloc()ed buffer that will get freed by the caller.  However, the
    385 	 * main function transmits the result before freeing the argument
    386 	 * so it is in fact safe.
    387 	 */
    388 	res.cookie = arg->cookie;
    389 	if (holder == NULL) {
    390 		res.stat.stat = nlm_granted;
    391 	} else {
    392 		res.stat.stat = nlm_denied;
    393 		memcpy(&res.stat.nlm_testrply_u.holder, holder,
    394 		    sizeof(struct nlm_holder));
    395 		res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
    396 		res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
    397 	}
    398 	return (&res);
    399 }
    400 
    401 void *
    402 nlm_test_msg_1_svc(arg, rqstp)
    403 	nlm_testargs *arg;
    404 	struct svc_req *rqstp;
    405 {
    406 	nlm_testres res;
    407 	static char dummy;
    408 	struct sockaddr *addr;
    409 	CLIENT *cli;
    410 	int success;
    411 	struct timeval timeo;
    412 	struct nlm4_lock arg4;
    413 	struct nlm4_holder *holder;
    414 
    415 	nlmtonlm4(&arg->alock, &arg4);
    416 
    417 	if (debug_level)
    418 		log_from_addr("nlm_test_msg", rqstp);
    419 
    420 	holder = testlock(&arg4, 0);
    421 
    422 	res.cookie = arg->cookie;
    423 	if (holder == NULL) {
    424 		res.stat.stat = nlm_granted;
    425 	} else {
    426 		res.stat.stat = nlm_denied;
    427 		memcpy(&res.stat.nlm_testrply_u.holder, holder,
    428 		    sizeof(struct nlm_holder));
    429 		res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
    430 		res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
    431 	}
    432 
    433 	/*
    434 	 * nlm_test has different result type to the other operations, so
    435 	 * can't use transmit_result() in this case
    436 	 */
    437 	addr = svc_getrpccaller(rqstp->rq_xprt)->buf;
    438 	if ((cli = get_client(addr, NLM_VERS)) != NULL) {
    439 		timeo.tv_sec = 0; /* No timeout - not expecting response */
    440 		timeo.tv_usec = 0;
    441 
    442 		success = clnt_call(cli, NLM_TEST_RES, xdr_nlm_testres,
    443 		    &res, xdr_void, &dummy, timeo);
    444 
    445 		if (debug_level > 2)
    446 			syslog(LOG_DEBUG, "clnt_call returns %d", success);
    447 	}
    448 	return (NULL);
    449 }
    450 
    451 /* nlm_lock ---------------------------------------------------------------- */
    452 /*
    453  * Purposes:	Establish a lock
    454  * Returns:	granted, denied or blocked
    455  * Notes:	*** grace period support missing
    456  */
    457 nlm_res *
    458 nlm_lock_1_svc(arg, rqstp)
    459 	nlm_lockargs *arg;
    460 	struct svc_req *rqstp;
    461 {
    462 	static nlm_res res;
    463 	struct nlm4_lockargs arg4;
    464 	nlmtonlm4(&arg->alock, &arg4.alock);
    465 	arg4.cookie = arg->cookie;
    466 	arg4.block = arg->block;
    467 	arg4.exclusive = arg->exclusive;
    468 	arg4.reclaim = arg->reclaim;
    469 	arg4.state = arg->state;
    470 
    471 	if (debug_level)
    472 		log_from_addr("nlm_lock", rqstp);
    473 
    474 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
    475 	res.cookie = arg->cookie;
    476 
    477 	res.stat.stat = getlock(&arg4, rqstp, LOCK_MON);
    478 	return (&res);
    479 }
    480 
    481 void *
    482 nlm_lock_msg_1_svc(arg, rqstp)
    483 	nlm_lockargs *arg;
    484 	struct svc_req *rqstp;
    485 {
    486 	static nlm_res res;
    487 	struct nlm4_lockargs arg4;
    488 
    489 	nlmtonlm4(&arg->alock, &arg4.alock);
    490 	arg4.cookie = arg->cookie;
    491 	arg4.block = arg->block;
    492 	arg4.exclusive = arg->exclusive;
    493 	arg4.reclaim = arg->reclaim;
    494 	arg4.state = arg->state;
    495 
    496 	if (debug_level)
    497 		log_from_addr("nlm_lock_msg", rqstp);
    498 
    499 	res.cookie = arg->cookie;
    500 	res.stat.stat = getlock(&arg4, rqstp, LOCK_ASYNC | LOCK_MON);
    501 	transmit_result(NLM_LOCK_RES, &res,
    502 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
    503 
    504 	return (NULL);
    505 }
    506 
    507 /* nlm_cancel -------------------------------------------------------------- */
    508 /*
    509  * Purpose:	Cancel a blocked lock request
    510  * Returns:	granted or denied
    511  * Notes:
    512  */
    513 nlm_res *
    514 nlm_cancel_1_svc(arg, rqstp)
    515 	nlm_cancargs *arg;
    516 	struct svc_req *rqstp;
    517 {
    518 	static nlm_res res;
    519 	struct nlm4_lock arg4;
    520 
    521 	nlmtonlm4(&arg->alock, &arg4);
    522 
    523 	if (debug_level)
    524 		log_from_addr("nlm_cancel", rqstp);
    525 
    526 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
    527 	res.cookie = arg->cookie;
    528 
    529 	/*
    530 	 * Since at present we never return 'nlm_blocked', there can never be
    531 	 * a lock to cancel, so this call always fails.
    532 	 */
    533 	res.stat.stat = unlock(&arg4, LOCK_CANCEL);
    534 	return (&res);
    535 }
    536 
    537 void *
    538 nlm_cancel_msg_1_svc(arg, rqstp)
    539 	nlm_cancargs *arg;
    540 	struct svc_req *rqstp;
    541 {
    542 	static nlm_res res;
    543 	struct nlm4_lock arg4;
    544 
    545 	nlmtonlm4(&arg->alock, &arg4);
    546 
    547 	if (debug_level)
    548 		log_from_addr("nlm_cancel_msg", rqstp);
    549 
    550 	res.cookie = arg->cookie;
    551 	/*
    552 	 * Since at present we never return 'nlm_blocked', there can never be
    553 	 * a lock to cancel, so this call always fails.
    554 	 */
    555 	res.stat.stat = unlock(&arg4, LOCK_CANCEL);
    556 	transmit_result(NLM_CANCEL_RES, &res,
    557 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
    558 	return (NULL);
    559 }
    560 
    561 /* nlm_unlock -------------------------------------------------------------- */
    562 /*
    563  * Purpose:	Release an existing lock
    564  * Returns:	Always granted, unless during grace period
    565  * Notes:	"no such lock" error condition is ignored, as the
    566  *		protocol uses unreliable UDP datagrams, and may well
    567  *		re-try an unlock that has already succeeded.
    568  */
    569 nlm_res *
    570 nlm_unlock_1_svc(arg, rqstp)
    571 	nlm_unlockargs *arg;
    572 	struct svc_req *rqstp;
    573 {
    574 	static nlm_res res;
    575 	struct nlm4_lock arg4;
    576 
    577 	nlmtonlm4(&arg->alock, &arg4);
    578 
    579 	if (debug_level)
    580 		log_from_addr("nlm_unlock", rqstp);
    581 
    582 	res.stat.stat = unlock(&arg4, 0);
    583 	res.cookie = arg->cookie;
    584 
    585 	return (&res);
    586 }
    587 
    588 void *
    589 nlm_unlock_msg_1_svc(arg, rqstp)
    590 	nlm_unlockargs *arg;
    591 	struct svc_req *rqstp;
    592 {
    593 	static nlm_res res;
    594 	struct nlm4_lock arg4;
    595 
    596 	nlmtonlm4(&arg->alock, &arg4);
    597 
    598 	if (debug_level)
    599 		log_from_addr("nlm_unlock_msg", rqstp);
    600 
    601 	res.stat.stat = unlock(&arg4, 0);
    602 	res.cookie = arg->cookie;
    603 
    604 	transmit_result(NLM_UNLOCK_RES, &res,
    605 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
    606 	return (NULL);
    607 }
    608 
    609 /* ------------------------------------------------------------------------- */
    610 /*
    611  * Client-side pseudo-RPCs for results.  Note that for the client there
    612  * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
    613  * version returns the results in the RPC result, and so the client
    614  * does not normally receive incoming RPCs.
    615  *
    616  * The exception to this is nlm_granted(), which is genuinely an RPC
    617  * call from the server to the client - a 'call-back' in normal procedure
    618  * call terms.
    619  */
    620 
    621 /* nlm_granted ------------------------------------------------------------- */
    622 /*
    623  * Purpose:	Receive notification that formerly blocked lock now granted
    624  * Returns:	always success ('granted')
    625  * Notes:
    626  */
    627 nlm_res *
    628 nlm_granted_1_svc(arg, rqstp)
    629 	nlm_testargs *arg;
    630 	struct svc_req *rqstp;
    631 {
    632 	static nlm_res res;
    633 
    634 	if (debug_level)
    635 		log_from_addr("nlm_granted", rqstp);
    636 
    637 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
    638 	res.cookie = arg->cookie;
    639 
    640 	res.stat.stat = nlm_granted;
    641 	return (&res);
    642 }
    643 
    644 void *
    645 nlm_granted_msg_1_svc(arg, rqstp)
    646 	nlm_testargs *arg;
    647 	struct svc_req *rqstp;
    648 {
    649 	static nlm_res res;
    650 
    651 	if (debug_level)
    652 		log_from_addr("nlm_granted_msg", rqstp);
    653 
    654 	res.cookie = arg->cookie;
    655 	res.stat.stat = nlm_granted;
    656 	transmit_result(NLM_GRANTED_RES, &res,
    657 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
    658 	return (NULL);
    659 }
    660 
    661 /* nlm_test_res ------------------------------------------------------------ */
    662 /*
    663  * Purpose:	Accept result from earlier nlm_test_msg() call
    664  * Returns:	Nothing
    665  */
    666 void *
    667 nlm_test_res_1_svc(arg, rqstp)
    668 	nlm_testres *arg;
    669 	struct svc_req *rqstp;
    670 {
    671 	if (debug_level)
    672 		log_from_addr("nlm_test_res", rqstp);
    673 	return (NULL);
    674 }
    675 
    676 /* nlm_lock_res ------------------------------------------------------------ */
    677 /*
    678  * Purpose:	Accept result from earlier nlm_lock_msg() call
    679  * Returns:	Nothing
    680  */
    681 void *
    682 nlm_lock_res_1_svc(arg, rqstp)
    683 	nlm_res *arg;
    684 	struct svc_req *rqstp;
    685 {
    686 	if (debug_level)
    687 		log_from_addr("nlm_lock_res", rqstp);
    688 
    689 	return (NULL);
    690 }
    691 
    692 /* nlm_cancel_res ---------------------------------------------------------- */
    693 /*
    694  * Purpose:	Accept result from earlier nlm_cancel_msg() call
    695  * Returns:	Nothing
    696  */
    697 void *
    698 nlm_cancel_res_1_svc(arg, rqstp)
    699 	nlm_res *arg;
    700 	struct svc_req *rqstp;
    701 {
    702 	if (debug_level)
    703 		log_from_addr("nlm_cancel_res", rqstp);
    704 	return (NULL);
    705 }
    706 
    707 /* nlm_unlock_res ---------------------------------------------------------- */
    708 /*
    709  * Purpose:	Accept result from earlier nlm_unlock_msg() call
    710  * Returns:	Nothing
    711  */
    712 void *
    713 nlm_unlock_res_1_svc(arg, rqstp)
    714 	nlm_res *arg;
    715 	struct svc_req *rqstp;
    716 {
    717 	if (debug_level)
    718 		log_from_addr("nlm_unlock_res", rqstp);
    719 	return (NULL);
    720 }
    721 
    722 /* nlm_granted_res --------------------------------------------------------- */
    723 /*
    724  * Purpose:	Accept result from earlier nlm_granted_msg() call
    725  * Returns:	Nothing
    726  */
    727 void *
    728 nlm_granted_res_1_svc(arg, rqstp)
    729 	nlm_res *arg;
    730 	struct svc_req *rqstp;
    731 {
    732 	if (debug_level)
    733 		log_from_addr("nlm_granted_res", rqstp);
    734 	return (NULL);
    735 }
    736 
    737 /* ------------------------------------------------------------------------- */
    738 /*
    739  * Calls for PCNFS locking (aka non-monitored locking, no involvement
    740  * of rpc.statd).
    741  *
    742  * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
    743  */
    744 
    745 /* nlm_share --------------------------------------------------------------- */
    746 /*
    747  * Purpose:	Establish a DOS-style lock
    748  * Returns:	success or failure
    749  * Notes:	Blocking locks are not supported - client is expected
    750  *		to retry if required.
    751  */
    752 nlm_shareres *
    753 nlm_share_3_svc(arg, rqstp)
    754 	nlm_shareargs *arg;
    755 	struct svc_req *rqstp;
    756 {
    757 	static nlm_shareres res;
    758 
    759 	if (debug_level)
    760 		log_from_addr("nlm_share", rqstp);
    761 
    762 	res.cookie = arg->cookie;
    763 	res.stat = nlm_granted;
    764 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
    765 	return (&res);
    766 }
    767 
    768 /* nlm_unshare ------------------------------------------------------------ */
    769 /*
    770  * Purpose:	Release a DOS-style lock
    771  * Returns:	nlm_granted, unless in grace period
    772  * Notes:
    773  */
    774 nlm_shareres *
    775 nlm_unshare_3_svc(arg, rqstp)
    776 	nlm_shareargs *arg;
    777 	struct svc_req *rqstp;
    778 {
    779 	static nlm_shareres res;
    780 
    781 	if (debug_level)
    782 		log_from_addr("nlm_unshare", rqstp);
    783 
    784 	res.cookie = arg->cookie;
    785 	res.stat = nlm_granted;
    786 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
    787 	return (&res);
    788 }
    789 
    790 /* nlm_nm_lock ------------------------------------------------------------ */
    791 /*
    792  * Purpose:	non-monitored version of nlm_lock()
    793  * Returns:	as for nlm_lock()
    794  * Notes:	These locks are in the same style as the standard nlm_lock,
    795  *		but the rpc.statd should not be called to establish a
    796  *		monitor for the client machine, since that machine is
    797  *		declared not to be running a rpc.statd, and so would not
    798  *		respond to the statd protocol.
    799  */
    800 nlm_res *
    801 nlm_nm_lock_3_svc(arg, rqstp)
    802 	nlm_lockargs *arg;
    803 	struct svc_req *rqstp;
    804 {
    805 	static nlm_res res;
    806 
    807 	if (debug_level)
    808 		log_from_addr("nlm_nm_lock", rqstp);
    809 
    810 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
    811 	res.cookie = arg->cookie;
    812 	res.stat.stat = nlm_granted;
    813 	return (&res);
    814 }
    815 
    816 /* nlm_free_all ------------------------------------------------------------ */
    817 /*
    818  * Purpose:	Release all locks held by a named client
    819  * Returns:	Nothing
    820  * Notes:	Potential denial of service security problem here - the
    821  *		locks to be released are specified by a host name, independent
    822  *		of the address from which the request has arrived.
    823  *		Should probably be rejected if the named host has been
    824  *		using monitored locks.
    825  */
    826 void *
    827 nlm_free_all_3_svc(arg, rqstp)
    828 	nlm_notify *arg;
    829 	struct svc_req *rqstp;
    830 {
    831 	static char dummy;
    832 
    833 	if (debug_level)
    834 		log_from_addr("nlm_free_all", rqstp);
    835 	return (&dummy);
    836 }
    837 
    838 /* calls for nlm version 4 (NFSv3) */
    839 /* nlm_test ---------------------------------------------------------------- */
    840 /*
    841  * Purpose:	Test whether a specified lock would be granted if requested
    842  * Returns:	nlm_granted (or error code)
    843  * Notes:
    844  */
    845 nlm4_testres *
    846 nlm4_test_4_svc(arg, rqstp)
    847 	nlm4_testargs *arg;
    848 	struct svc_req *rqstp;
    849 {
    850 	static nlm4_testres res;
    851 	struct nlm4_holder *holder;
    852 
    853 	if (debug_level)
    854 		log_from_addr("nlm4_test", rqstp);
    855 
    856 	holder = testlock(&arg->alock, LOCK_V4);
    857 
    858 	/*
    859 	 * Copy the cookie from the argument into the result.  Note that this
    860 	 * is slightly hazardous, as the structure contains a pointer to a
    861 	 * malloc()ed buffer that will get freed by the caller.  However, the
    862 	 * main function transmits the result before freeing the argument
    863 	 * so it is in fact safe.
    864 	 */
    865 	res.cookie = arg->cookie;
    866 	if (holder == NULL) {
    867 		res.stat.stat = nlm4_granted;
    868 	} else {
    869 		res.stat.stat = nlm4_denied;
    870 		memcpy(&res.stat.nlm4_testrply_u.holder, holder,
    871 		    sizeof(struct nlm4_holder));
    872 	}
    873 	return (&res);
    874 }
    875 
    876 void *
    877 nlm4_test_msg_4_svc(arg, rqstp)
    878 	nlm4_testargs *arg;
    879 	struct svc_req *rqstp;
    880 {
    881 	nlm4_testres res;
    882 	static char dummy;
    883 	struct sockaddr *addr;
    884 	CLIENT *cli;
    885 	int success;
    886 	struct timeval timeo;
    887 	struct nlm4_holder *holder;
    888 
    889 	if (debug_level)
    890 		log_from_addr("nlm4_test_msg", rqstp);
    891 
    892 	holder = testlock(&arg->alock, LOCK_V4);
    893 
    894 	res.cookie = arg->cookie;
    895 	if (holder == NULL) {
    896 		res.stat.stat = nlm4_granted;
    897 	} else {
    898 		res.stat.stat = nlm4_denied;
    899 		memcpy(&res.stat.nlm4_testrply_u.holder, holder,
    900 		    sizeof(struct nlm4_holder));
    901 	}
    902 
    903 	/*
    904 	 * nlm_test has different result type to the other operations, so
    905 	 * can't use transmit4_result() in this case
    906 	 */
    907 	addr = svc_getrpccaller(rqstp->rq_xprt)->buf;
    908 	if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
    909 		timeo.tv_sec = 0; /* No timeout - not expecting response */
    910 		timeo.tv_usec = 0;
    911 
    912 		success = clnt_call(cli, NLM4_TEST_RES, xdr_nlm4_testres,
    913 		    &res, xdr_void, &dummy, timeo);
    914 
    915 		if (debug_level > 2)
    916 			syslog(LOG_DEBUG, "clnt_call returns %d", success);
    917 	}
    918 	return (NULL);
    919 }
    920 
    921 /* nlm_lock ---------------------------------------------------------------- */
    922 /*
    923  * Purposes:	Establish a lock
    924  * Returns:	granted, denied or blocked
    925  * Notes:	*** grace period support missing
    926  */
    927 nlm4_res *
    928 nlm4_lock_4_svc(arg, rqstp)
    929 	nlm4_lockargs *arg;
    930 	struct svc_req *rqstp;
    931 {
    932 	static nlm4_res res;
    933 
    934 	if (debug_level)
    935 		log_from_addr("nlm4_lock", rqstp);
    936 
    937 	/* copy cookie from arg to result.  See comment in nlm_test_4() */
    938 	res.cookie = arg->cookie;
    939 
    940 	res.stat.stat = getlock(arg, rqstp, LOCK_MON | LOCK_V4);
    941 	return (&res);
    942 }
    943 
    944 void *
    945 nlm4_lock_msg_4_svc(arg, rqstp)
    946 	nlm4_lockargs *arg;
    947 	struct svc_req *rqstp;
    948 {
    949 	static nlm4_res res;
    950 
    951 	if (debug_level)
    952 		log_from_addr("nlm4_lock_msg", rqstp);
    953 
    954 	res.cookie = arg->cookie;
    955 	res.stat.stat = getlock(arg, rqstp, LOCK_MON | LOCK_ASYNC | LOCK_V4);
    956 	transmit4_result(NLM4_LOCK_RES, &res,
    957 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
    958 
    959 	return (NULL);
    960 }
    961 
    962 /* nlm_cancel -------------------------------------------------------------- */
    963 /*
    964  * Purpose:	Cancel a blocked lock request
    965  * Returns:	granted or denied
    966  * Notes:
    967  */
    968 nlm4_res *
    969 nlm4_cancel_4_svc(arg, rqstp)
    970 	nlm4_cancargs *arg;
    971 	struct svc_req *rqstp;
    972 {
    973 	static nlm4_res res;
    974 
    975 	if (debug_level)
    976 		log_from_addr("nlm4_cancel", rqstp);
    977 
    978 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
    979 	res.cookie = arg->cookie;
    980 
    981 	/*
    982 	 * Since at present we never return 'nlm_blocked', there can never be
    983 	 * a lock to cancel, so this call always fails.
    984 	 */
    985 	res.stat.stat = unlock(&arg->alock, LOCK_CANCEL);
    986 	return (&res);
    987 }
    988 
    989 void *
    990 nlm4_cancel_msg_4_svc(arg, rqstp)
    991 	nlm4_cancargs *arg;
    992 	struct svc_req *rqstp;
    993 {
    994 	static nlm4_res res;
    995 
    996 	if (debug_level)
    997 		log_from_addr("nlm4_cancel_msg", rqstp);
    998 
    999 	res.cookie = arg->cookie;
   1000 	/*
   1001 	 * Since at present we never return 'nlm_blocked', there can never be
   1002 	 * a lock to cancel, so this call always fails.
   1003 	 */
   1004 	res.stat.stat = unlock(&arg->alock, LOCK_CANCEL | LOCK_V4);
   1005 	transmit4_result(NLM4_CANCEL_RES, &res,
   1006 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
   1007 	return (NULL);
   1008 }
   1009 
   1010 /* nlm_unlock -------------------------------------------------------------- */
   1011 /*
   1012  * Purpose:	Release an existing lock
   1013  * Returns:	Always granted, unless during grace period
   1014  * Notes:	"no such lock" error condition is ignored, as the
   1015  *		protocol uses unreliable UDP datagrams, and may well
   1016  *		re-try an unlock that has already succeeded.
   1017  */
   1018 nlm4_res *
   1019 nlm4_unlock_4_svc(arg, rqstp)
   1020 	nlm4_unlockargs *arg;
   1021 	struct svc_req *rqstp;
   1022 {
   1023 	static nlm4_res res;
   1024 
   1025 	if (debug_level)
   1026 		log_from_addr("nlm4_unlock", rqstp);
   1027 
   1028 	res.stat.stat = unlock(&arg->alock, LOCK_V4);
   1029 	res.cookie = arg->cookie;
   1030 
   1031 	return (&res);
   1032 }
   1033 
   1034 void *
   1035 nlm4_unlock_msg_4_svc(arg, rqstp)
   1036 	nlm4_unlockargs *arg;
   1037 	struct svc_req *rqstp;
   1038 {
   1039 	static nlm4_res res;
   1040 
   1041 	if (debug_level)
   1042 		log_from_addr("nlm4_unlock_msg", rqstp);
   1043 
   1044 	res.stat.stat = unlock(&arg->alock, LOCK_V4);
   1045 	res.cookie = arg->cookie;
   1046 
   1047 	transmit4_result(NLM4_UNLOCK_RES, &res,
   1048 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
   1049 	return (NULL);
   1050 }
   1051 
   1052 /* ------------------------------------------------------------------------- */
   1053 /*
   1054  * Client-side pseudo-RPCs for results.  Note that for the client there
   1055  * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
   1056  * version returns the results in the RPC result, and so the client
   1057  * does not normally receive incoming RPCs.
   1058  *
   1059  * The exception to this is nlm_granted(), which is genuinely an RPC
   1060  * call from the server to the client - a 'call-back' in normal procedure
   1061  * call terms.
   1062  */
   1063 
   1064 /* nlm_granted ------------------------------------------------------------- */
   1065 /*
   1066  * Purpose:	Receive notification that formerly blocked lock now granted
   1067  * Returns:	always success ('granted')
   1068  * Notes:
   1069  */
   1070 nlm4_res *
   1071 nlm4_granted_4_svc(arg, rqstp)
   1072 	nlm4_testargs *arg;
   1073 	struct svc_req *rqstp;
   1074 {
   1075 	static nlm4_res res;
   1076 
   1077 	if (debug_level)
   1078 		log_from_addr("nlm4_granted", rqstp);
   1079 
   1080 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
   1081 	res.cookie = arg->cookie;
   1082 
   1083 	res.stat.stat = nlm4_granted;
   1084 	return (&res);
   1085 }
   1086 
   1087 void *
   1088 nlm4_granted_msg_4_svc(arg, rqstp)
   1089 	nlm4_testargs *arg;
   1090 	struct svc_req *rqstp;
   1091 {
   1092 	static nlm4_res res;
   1093 
   1094 	if (debug_level)
   1095 		log_from_addr("nlm4_granted_msg", rqstp);
   1096 
   1097 	res.cookie = arg->cookie;
   1098 	res.stat.stat = nlm4_granted;
   1099 	transmit4_result(NLM4_GRANTED_RES, &res,
   1100 	    (struct sockaddr *)svc_getrpccaller(rqstp->rq_xprt)->buf);
   1101 	return (NULL);
   1102 }
   1103 
   1104 /* nlm_test_res ------------------------------------------------------------ */
   1105 /*
   1106  * Purpose:	Accept result from earlier nlm_test_msg() call
   1107  * Returns:	Nothing
   1108  */
   1109 void *
   1110 nlm4_test_res_4_svc(arg, rqstp)
   1111 	nlm4_testres *arg;
   1112 	struct svc_req *rqstp;
   1113 {
   1114 	if (debug_level)
   1115 		log_from_addr("nlm4_test_res", rqstp);
   1116 	return (NULL);
   1117 }
   1118 
   1119 /* nlm_lock_res ------------------------------------------------------------ */
   1120 /*
   1121  * Purpose:	Accept result from earlier nlm_lock_msg() call
   1122  * Returns:	Nothing
   1123  */
   1124 void *
   1125 nlm4_lock_res_4_svc(arg, rqstp)
   1126 	nlm4_res *arg;
   1127 	struct svc_req *rqstp;
   1128 {
   1129 	if (debug_level)
   1130 		log_from_addr("nlm4_lock_res", rqstp);
   1131 
   1132 	return (NULL);
   1133 }
   1134 
   1135 /* nlm_cancel_res ---------------------------------------------------------- */
   1136 /*
   1137  * Purpose:	Accept result from earlier nlm_cancel_msg() call
   1138  * Returns:	Nothing
   1139  */
   1140 void *
   1141 nlm4_cancel_res_4_svc(arg, rqstp)
   1142 	nlm4_res *arg;
   1143 	struct svc_req *rqstp;
   1144 {
   1145 	if (debug_level)
   1146 		log_from_addr("nlm4_cancel_res", rqstp);
   1147 	return (NULL);
   1148 }
   1149 
   1150 /* nlm_unlock_res ---------------------------------------------------------- */
   1151 /*
   1152  * Purpose:	Accept result from earlier nlm_unlock_msg() call
   1153  * Returns:	Nothing
   1154  */
   1155 void *
   1156 nlm4_unlock_res_4_svc(arg, rqstp)
   1157 	nlm4_res *arg;
   1158 	struct svc_req *rqstp;
   1159 {
   1160 	if (debug_level)
   1161 		log_from_addr("nlm4_unlock_res", rqstp);
   1162 	return (NULL);
   1163 }
   1164 
   1165 /* nlm_granted_res --------------------------------------------------------- */
   1166 /*
   1167  * Purpose:	Accept result from earlier nlm_granted_msg() call
   1168  * Returns:	Nothing
   1169  */
   1170 void *
   1171 nlm4_granted_res_4_svc(arg, rqstp)
   1172 	nlm4_res *arg;
   1173 	struct svc_req *rqstp;
   1174 {
   1175 	if (debug_level)
   1176 		log_from_addr("nlm4_granted_res", rqstp);
   1177 	return (NULL);
   1178 }
   1179 
   1180 /* ------------------------------------------------------------------------- */
   1181 /*
   1182  * Calls for PCNFS locking (aka non-monitored locking, no involvement
   1183  * of rpc.statd).
   1184  *
   1185  * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
   1186  */
   1187 
   1188 /* nlm_share --------------------------------------------------------------- */
   1189 /*
   1190  * Purpose:	Establish a DOS-style lock
   1191  * Returns:	success or failure
   1192  * Notes:	Blocking locks are not supported - client is expected
   1193  *		to retry if required.
   1194  */
   1195 nlm4_shareres *
   1196 nlm4_share_4_svc(arg, rqstp)
   1197 	nlm4_shareargs *arg;
   1198 	struct svc_req *rqstp;
   1199 {
   1200 	static nlm4_shareres res;
   1201 
   1202 	if (debug_level)
   1203 		log_from_addr("nlm4_share", rqstp);
   1204 
   1205 	res.cookie = arg->cookie;
   1206 	res.stat = nlm4_granted;
   1207 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
   1208 	return (&res);
   1209 }
   1210 
   1211 /* nlm4_unshare ------------------------------------------------------------ */
   1212 /*
   1213  * Purpose:	Release a DOS-style lock
   1214  * Returns:	nlm_granted, unless in grace period
   1215  * Notes:
   1216  */
   1217 nlm4_shareres *
   1218 nlm4_unshare_4_svc(arg, rqstp)
   1219 	nlm4_shareargs *arg;
   1220 	struct svc_req *rqstp;
   1221 {
   1222 	static nlm4_shareres res;
   1223 
   1224 	if (debug_level)
   1225 		log_from_addr("nlm_unshare", rqstp);
   1226 
   1227 	res.cookie = arg->cookie;
   1228 	res.stat = nlm4_granted;
   1229 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
   1230 	return (&res);
   1231 }
   1232 
   1233 /* nlm4_nm_lock ------------------------------------------------------------ */
   1234 /*
   1235  * Purpose:	non-monitored version of nlm4_lock()
   1236  * Returns:	as for nlm4_lock()
   1237  * Notes:	These locks are in the same style as the standard nlm4_lock,
   1238  *		but the rpc.statd should not be called to establish a
   1239  *		monitor for the client machine, since that machine is
   1240  *		declared not to be running a rpc.statd, and so would not
   1241  *		respond to the statd protocol.
   1242  */
   1243 nlm4_res *
   1244 nlm4_nm_lock_4_svc(arg, rqstp)
   1245 	nlm4_lockargs *arg;
   1246 	struct svc_req *rqstp;
   1247 {
   1248 	static nlm4_res res;
   1249 
   1250 	if (debug_level)
   1251 		log_from_addr("nlm4_nm_lock", rqstp);
   1252 
   1253 	/* copy cookie from arg to result.  See comment in nlm4_test_1() */
   1254 	res.cookie = arg->cookie;
   1255 	res.stat.stat = nlm4_granted;
   1256 	return (&res);
   1257 }
   1258 
   1259 /* nlm4_free_all ------------------------------------------------------------ */
   1260 /*
   1261  * Purpose:	Release all locks held by a named client
   1262  * Returns:	Nothing
   1263  * Notes:	Potential denial of service security problem here - the
   1264  *		locks to be released are specified by a host name, independent
   1265  *		of the address from which the request has arrived.
   1266  *		Should probably be rejected if the named host has been
   1267  *		using monitored locks.
   1268  */
   1269 void *
   1270 nlm4_free_all_4_svc(arg, rqstp)
   1271 	nlm_notify *arg;
   1272 	struct svc_req *rqstp;
   1273 {
   1274 	static char dummy;
   1275 
   1276 	if (debug_level)
   1277 		log_from_addr("nlm4_free_all", rqstp);
   1278 	return (&dummy);
   1279 }
   1280 
   1281 /* nlm_sm_notify --------------------------------------------------------- */
   1282 /*
   1283  * Purpose:	called by rpc.statd when a monitored host state changes.
   1284  * Returns:	Nothing
   1285  */
   1286 void *
   1287 nlm_sm_notify_0_svc(arg, rqstp)
   1288 	struct nlm_sm_status *arg;
   1289 	struct svc_req *rqstp;
   1290 {
   1291 	static char dummy;
   1292 	notify(arg->mon_name, arg->state);
   1293 	return (&dummy);
   1294 }
   1295