Pre-2.0 release: Sync with HAMMER 64 - NFS and cross-device link fixes.
[dragonfly.git] / usr.sbin / rpc.lockd / procs.c
blob7245445a5eb855e20c79dc95097f8ba286a8b497
1 /*
2 * Copyright (c) 1995
3 * A.R. Gordon (andrew.gordon@net-tel.co.uk). All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed for the FreeBSD project
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY ANDREW GORDON AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
32 * $FreeBSD: src/usr.sbin/rpc.lockd/procs.c,v 1.4.2.2 2001/08/01 06:39:36 alfred Exp $
33 * $DragonFly: src/usr.sbin/rpc.lockd/procs.c,v 1.3 2005/11/25 00:32:49 swildner Exp $
36 #include <string.h>
37 #include "lockd.h"
39 #include <sys/param.h> /* for MAXHOSTNAMELEN */
40 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
43 #include <netdb.h>
46 #define CLIENT_CACHE_SIZE 64 /* No. of client sockets cached */
47 #define CLIENT_CACHE_LIFETIME 120 /* In seconds */
49 #if 0
50 #undef LOG_DEBUG
51 #undef LOG_ERR
52 #define LOG_DEBUG stderr
53 #define LOG_ERR stderr
54 #define syslog fprintf
55 #endif
57 /* log_from_addr ----------------------------------------------------------- */
59 Purpose: Log name of function called and source address
60 Returns: Nothing
61 Notes: Extracts the source address from the transport handle
62 passed in as part of the called procedure specification
65 static void
66 log_from_addr(char *fun_name, struct svc_req *req)
68 struct sockaddr_in *addr;
69 struct hostent *host;
70 char hostname_buf[40];
72 addr = svc_getcaller(req->rq_xprt);
73 host = gethostbyaddr((char *)&(addr->sin_addr), addr->sin_len, AF_INET);
74 if (host)
76 strncpy(hostname_buf, host->h_name, sizeof(hostname_buf));
77 hostname_buf[sizeof(hostname_buf) -1] = '\0';
79 else /* No hostname available - print raw address */
81 strcpy(hostname_buf, inet_ntoa(addr->sin_addr));
84 syslog(LOG_DEBUG, "%s from %s", fun_name, hostname_buf);
88 /* get_client -------------------------------------------------------------- */
90 Purpose: Get a CLIENT* for making RPC calls to lockd on given host
91 Returns: CLIENT* pointer, from clnt_udp_create, or NULL if error
92 Notes: Creating a CLIENT* is quite expensive, involving a
93 conversation with the remote portmapper to get the
94 port number. Since a given client is quite likely
95 to make several locking requests in succession, it is
96 desirable to cache the created CLIENT*.
98 Since we are using UDP rather than TCP, there is no cost
99 to the remote system in keeping these cached indefinitely.
100 Unfortunately there is a snag: if the remote system
101 reboots, the cached portmapper results will be invalid,
102 and we will never detect this since all of the xxx_msg()
103 calls return no result - we just fire off a udp packet
104 and hope for the best.
106 We solve this by discarding cached values after two
107 minutes, regardless of whether they have been used
108 in the meanwhile (since a bad one might have been used
109 plenty of times, as the host keeps retrying the request
110 and we keep sending the reply back to the wrong port).
112 Given that the entries will always expire in the order
113 that they were created, there is no point in a LRU
114 algorithm for when the cache gets full - entries are
115 always re-used in sequence.
118 static CLIENT *clnt_cache_ptr[CLIENT_CACHE_SIZE];
119 static long clnt_cache_time[CLIENT_CACHE_SIZE]; /* time entry created */
120 static struct in_addr clnt_cache_addr[CLIENT_CACHE_SIZE];
121 static int clnt_cache_next_to_use = 0;
123 static CLIENT *
124 get_client(struct sockaddr_in *host_addr)
126 CLIENT *client;
127 int sock_no;
128 struct timeval retry_time, time_now;
129 int i;
131 gettimeofday(&time_now, NULL);
133 /* Search for the given client in the cache, zapping any expired */
134 /* entries that we happen to notice in passing. */
135 for (i = 0; i < CLIENT_CACHE_SIZE; i++)
137 client = clnt_cache_ptr[i];
138 if (client &&
139 ((clnt_cache_time[i] + CLIENT_CACHE_LIFETIME) < time_now.tv_sec))
141 /* Cache entry has expired. */
142 if (debug_level > 3) syslog(LOG_DEBUG, "Expired CLIENT* in cache");
143 clnt_cache_time[i] = 0L;
144 clnt_destroy(client);
145 clnt_cache_ptr[i] = NULL;
146 client = NULL;
149 if (client && !memcmp(&clnt_cache_addr[i], &host_addr->sin_addr,
150 sizeof(struct in_addr)))
152 /* Found it! */
153 if (debug_level > 3) syslog(LOG_DEBUG, "Found CLIENT* in cache");
154 return (client);
158 /* Not found in cache. Free the next entry if it is in use */
159 if (clnt_cache_ptr[clnt_cache_next_to_use])
161 clnt_destroy(clnt_cache_ptr[clnt_cache_next_to_use]);
162 clnt_cache_ptr[clnt_cache_next_to_use] = NULL;
165 /* Create the new client handle */
167 sock_no = RPC_ANYSOCK;
168 retry_time.tv_sec = 5;
169 retry_time.tv_usec = 0;
170 host_addr->sin_port = 0; /* Force consultation with portmapper */
171 client = clntudp_create(host_addr, NLM_PROG, NLM_VERS, retry_time, &sock_no);
172 if (!client)
174 syslog(LOG_ERR, "%s", clnt_spcreateerror("clntudp_create"));
175 syslog(LOG_ERR, "Unable to return result to %s",
176 inet_ntoa(host_addr->sin_addr));
177 return NULL;
180 /* Success - update the cache entry */
181 clnt_cache_ptr[clnt_cache_next_to_use] = client;
182 clnt_cache_addr[clnt_cache_next_to_use] = host_addr->sin_addr;
183 clnt_cache_time[clnt_cache_next_to_use] = time_now.tv_sec;
184 if (++clnt_cache_next_to_use > CLIENT_CACHE_SIZE)
185 clnt_cache_next_to_use = 0;
187 /* Disable the default timeout, so we can specify our own in calls */
188 /* to clnt_call(). [note that the timeout is a different concept */
189 /* from the retry period set in clnt_udp_create() above.] */
190 retry_time.tv_sec = -1;
191 retry_time.tv_usec = -1;
192 clnt_control(client, CLSET_TIMEOUT, &retry_time);
194 if (debug_level > 3) syslog(LOG_DEBUG, "Created CLIENT* for %s",
195 inet_ntoa(host_addr->sin_addr));
196 return client;
200 /* transmit_result --------------------------------------------------------- */
202 Purpose: Transmit result for nlm_xxx_msg pseudo-RPCs
203 Returns: Nothing - we have no idea if the datagram got there
204 Notes: clnt_call() will always fail (with timeout) as we are
205 calling it with timeout 0 as a hack to just issue a datagram
206 without expecting a result
209 static void
210 transmit_result(int opcode, void *result, struct svc_req *req)
212 static char dummy;
213 struct sockaddr_in *addr;
214 CLIENT *cli;
215 int success;
216 struct timeval timeo;
218 addr = svc_getcaller(req->rq_xprt);
219 if ((cli = get_client(addr)))
221 timeo.tv_sec = 0; /* No timeout - not expecting response */
222 timeo.tv_usec = 0;
224 success = clnt_call(cli, opcode, xdr_nlm_res, result, xdr_void,
225 &dummy, timeo);
227 if (debug_level > 2) syslog(LOG_DEBUG, "clnt_call returns %d", success);
231 /* ------------------------------------------------------------------------- */
233 Functions for Unix<->Unix locking (ie. monitored locking, with rpc.statd
234 involved to ensure reclaim of locks after a crash of the "stateless"
235 server.
237 These all come in two flavours - nlm_xxx() and nlm_xxx_msg().
238 The first are standard RPCs with argument and result.
239 The nlm_xxx_msg() calls implement exactly the same functions, but
240 use two pseudo-RPCs (one in each direction). These calls are NOT
241 standard use of the RPC protocol in that they do not return a result
242 at all (NB. this is quite different from returning a void result).
243 The effect of this is to make the nlm_xxx_msg() calls simple unacknowledged
244 datagrams, requiring higher-level code to perform retries.
246 Despite the disadvantages of the nlm_xxx_msg() approach (some of which
247 are documented in the comments to get_client() above), this is the
248 interface used by all current commercial NFS implementations
249 [Solaris, SCO, AIX etc.]. This is presumed to be because these allow
250 implementations to continue using the standard RPC libraries, while
251 avoiding the block-until-result nature of the library interface.
253 No client implementations have been identified so far that make use
254 of the true RPC version (early SunOS releases would be a likely candidate
255 for testing).
259 /* nlm_test ---------------------------------------------------------------- */
261 Purpose: Test whether a specified lock would be granted if requested
262 Returns: nlm_granted (or error code)
263 Notes:
266 nlm_testres *
267 nlm_test_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
269 static nlm_testres res;
270 if (debug_level) log_from_addr("nlm_test", rqstp);
272 /* Copy the cookie from the argument into the result. Note that this */
273 /* is slightly hazardous, as the structure contains a pointer to a */
274 /* malloc()ed buffer that will get freed by the caller. However, the */
275 /* main function transmits the result before freeing the argument */
276 /* so it is in fact safe. */
277 res.cookie = arg->cookie;
278 res.stat.stat = nlm_granted;
279 return (&res);
282 nlm4_testres *
283 nlmproc4_test_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
285 static nlm4_testres res;
286 if (debug_level) log_from_addr("nlm_test", rqstp);
288 /* Copy the cookie from the argument into the result. Note that this */
289 /* is slightly hazardous, as the structure contains a pointer to a */
290 /* malloc()ed buffer that will get freed by the caller. However, the */
291 /* main function transmits the result before freeing the argument */
292 /* so it is in fact safe. */
293 res.cookie = arg->cookie;
294 res.stat.stat = nlm4_granted;
295 return (&res);
298 void *
299 nlm_test_msg_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
301 nlm_testres res;
302 static char dummy;
303 struct sockaddr_in *addr;
304 CLIENT *cli;
305 int success;
306 struct timeval timeo;
308 if (debug_level) log_from_addr("nlm_test_msg", rqstp);
310 res.cookie = arg->cookie;
311 res.stat.stat = nlm_granted;
313 /* nlm_test has different result type to the other operations, so */
314 /* can't use transmit_result() in this case */
315 addr = svc_getcaller(rqstp->rq_xprt);
316 if ((cli = get_client(addr)))
318 timeo.tv_sec = 0; /* No timeout - not expecting response */
319 timeo.tv_usec = 0;
321 success = clnt_call(cli, NLM_TEST_RES, xdr_nlm_testres, &res, xdr_void,
322 &dummy, timeo);
324 if (debug_level > 2) syslog(LOG_DEBUG, "clnt_call returns %d", success);
326 return (NULL);
329 void *
330 nlmproc4_test_msg_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
332 nlm4_testres res;
333 static char dummy;
334 struct sockaddr_in *addr;
335 CLIENT *cli;
336 int success;
337 struct timeval timeo;
339 if (debug_level) log_from_addr("nlm_test_msg", rqstp);
341 res.cookie = arg->cookie;
342 res.stat.stat = nlm4_granted;
344 /* nlm_test has different result type to the other operations, so */
345 /* can't use transmit_result() in this case */
346 addr = svc_getcaller(rqstp->rq_xprt);
347 if ((cli = get_client(addr)))
349 timeo.tv_sec = 0; /* No timeout - not expecting response */
350 timeo.tv_usec = 0;
352 success = clnt_call(cli, NLMPROC4_TEST_RES, xdr_nlm_testres, &res, xdr_void,
353 &dummy, timeo);
355 if (debug_level > 2) syslog(LOG_DEBUG, "clnt_call returns %d", success);
357 return (NULL);
362 /* nlm_lock ---------------------------------------------------------------- */
364 Purposes: Establish a lock
365 Returns: granted, denied or blocked
366 Notes: *** grace period support missing
369 nlm_res *
370 nlm_lock_1_svc(nlm_lockargs *arg, struct svc_req *rqstp)
372 static nlm_res res;
373 if (debug_level) log_from_addr("nlm_lock", rqstp);
375 /* copy cookie from arg to result. See comment in nlm_test_1() */
376 res.cookie = arg->cookie;
378 res.stat.stat = nlm_granted;
379 return (&res);
382 nlm4_res *
383 nlmproc4_lock_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
385 static nlm4_res res;
387 if (debug_level) log_from_addr("nlm_lock", rqstp);
389 /* copy cookie from arg to result. See comment in nlm_test_1() */
390 res.cookie = arg->cookie;
392 res.stat.stat = nlm4_granted;
393 return (&res);
396 void *
397 nlm_lock_msg_1_svc(nlm_lockargs *arg, struct svc_req *rqstp)
399 static nlm_res res;
401 if (debug_level) log_from_addr("nlm_lock_msg", rqstp);
403 res.cookie = arg->cookie;
404 res.stat.stat = nlm_granted;
405 transmit_result(NLM_LOCK_RES, &res, rqstp);
407 return (NULL);
410 void *
411 nlmproc4_lock_msg_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
413 static nlm4_res res;
415 if (debug_level) log_from_addr("nlm_lock_msg", rqstp);
417 res.cookie = arg->cookie;
418 res.stat.stat = nlm4_granted;
419 transmit_result(NLMPROC4_LOCK_RES, &res, rqstp);
421 return (NULL);
425 /* nlm_cancel -------------------------------------------------------------- */
427 Purpose: Cancel a blocked lock request
428 Returns: granted or denied
429 Notes:
432 nlm_res *
433 nlm_cancel_1_svc(nlm_cancargs *arg, struct svc_req *rqstp)
435 static nlm_res res;
436 if (debug_level) log_from_addr("nlm_cancel", rqstp);
438 /* copy cookie from arg to result. See comment in nlm_test_1() */
439 res.cookie = arg->cookie;
441 /* Since at present we never return 'nlm_blocked', there can never be */
442 /* a lock to cancel, so this call always fails. */
443 res.stat.stat = nlm_denied;
444 return (&res);
447 nlm4_res *
448 nlmproc4_cancel_4_svc(nlm4_cancargs *arg, struct svc_req *rqstp)
450 static nlm4_res res;
451 if (debug_level) log_from_addr("nlm_cancel", rqstp);
453 /* copy cookie from arg to result. See comment in nlm_test_1() */
454 res.cookie = arg->cookie;
456 /* Since at present we never return 'nlm_blocked', there can never be */
457 /* a lock to cancel, so this call always fails. */
458 res.stat.stat = nlm4_denied;
459 return (&res);
462 void *
463 nlm_cancel_msg_1_svc(nlm_cancargs *arg, struct svc_req *rqstp)
465 static nlm_res res;
466 if (debug_level) log_from_addr("nlm_cancel_msg", rqstp);
468 res.cookie = arg->cookie;
469 /* Since at present we never return 'nlm_blocked', there can never be */
470 /* a lock to cancel, so this call always fails. */
471 res.stat.stat = nlm_denied;
472 transmit_result(NLM_CANCEL_RES, &res, rqstp);
473 return (NULL);
476 void *
477 nlmproc4_cancel_msg_4_svc(nlm4_cancargs *arg, struct svc_req *rqstp)
479 static nlm4_res res;
480 if (debug_level) log_from_addr("nlm_cancel_msg", rqstp);
482 res.cookie = arg->cookie;
483 /* Since at present we never return 'nlm_blocked', there can never be */
484 /* a lock to cancel, so this call always fails. */
485 res.stat.stat = nlm4_denied;
486 transmit_result(NLMPROC4_CANCEL_RES, &res, rqstp);
487 return (NULL);
490 /* nlm_unlock -------------------------------------------------------------- */
492 Purpose: Release an existing lock
493 Returns: Always granted, unless during grace period
494 Notes: "no such lock" error condition is ignored, as the
495 protocol uses unreliable UDP datagrams, and may well
496 re-try an unlock that has already succeeded.
499 nlm_res *
500 nlm_unlock_1_svc(nlm_unlockargs *arg, struct svc_req *rqstp)
502 static nlm_res res;
503 if (debug_level) log_from_addr("nlm_unlock", rqstp);
505 res.stat.stat= nlm_granted;
506 res.cookie = arg->cookie;
508 return (&res);
511 nlm4_res *
512 nlmproc4_unlock_4_svc(nlm4_unlockargs *arg, struct svc_req *rqstp)
514 static nlm4_res res;
515 if (debug_level) log_from_addr("nlm_unlock", rqstp);
517 res.stat.stat= nlm4_granted;
518 res.cookie = arg->cookie;
520 return (&res);
523 void *
524 nlm_unlock_msg_1_svc(nlm_unlockargs *arg, struct svc_req *rqstp)
526 static nlm_res res;
527 if (debug_level) log_from_addr("nlm_unlock_msg", rqstp);
529 res.stat.stat = nlm_granted;
530 res.cookie = arg->cookie;
532 transmit_result(NLM_UNLOCK_RES, &res, rqstp);
533 return (NULL);
536 void *
537 nlmproc4_unlock_msg_4_svc(nlm4_unlockargs *arg, struct svc_req *rqstp)
539 static nlm4_res res;
540 if (debug_level) log_from_addr("nlm_unlock_msg", rqstp);
542 res.stat.stat = nlm4_granted;
543 res.cookie = arg->cookie;
545 transmit_result(NLMPROC4_UNLOCK_RES, &res, rqstp);
546 return (NULL);
549 /* ------------------------------------------------------------------------- */
551 Client-side pseudo-RPCs for results. Note that for the client there
552 are only nlm_xxx_msg() versions of each call, since the 'real RPC'
553 version returns the results in the RPC result, and so the client
554 does not normally receive incoming RPCs.
556 The exception to this is nlm_granted(), which is genuinely an RPC
557 call from the server to the client - a 'call-back' in normal procedure
558 call terms.
561 /* nlm_granted ------------------------------------------------------------- */
563 Purpose: Receive notification that formerly blocked lock now granted
564 Returns: always success ('granted')
565 Notes:
568 nlm_res *
569 nlm_granted_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
571 static nlm_res res;
572 if (debug_level) log_from_addr("nlm_granted", rqstp);
574 /* copy cookie from arg to result. See comment in nlm_test_1() */
575 res.cookie = arg->cookie;
577 res.stat.stat = nlm_granted;
578 return (&res);
581 nlm4_res *
582 nlmproc4_granted_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
584 static nlm4_res res;
585 if (debug_level) log_from_addr("nlm_granted", rqstp);
587 /* copy cookie from arg to result. See comment in nlm_test_1() */
588 res.cookie = arg->cookie;
590 res.stat.stat = nlm4_granted;
591 return (&res);
594 void *
595 nlm_granted_msg_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
597 nlm_res res;
598 if (debug_level) log_from_addr("nlm_granted_msg", rqstp);
600 res.cookie = arg->cookie;
601 res.stat.stat = nlm_granted;
602 transmit_result(NLM_GRANTED_RES, &res, rqstp);
603 return (NULL);
606 void *
607 nlmproc4_granted_msg_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
609 nlm4_res res;
610 if (debug_level) log_from_addr("nlm_granted_msg", rqstp);
612 res.cookie = arg->cookie;
613 res.stat.stat = nlm4_granted;
614 transmit_result(NLMPROC4_GRANTED_RES, &res, rqstp);
615 return (NULL);
618 /* nlm_test_res ------------------------------------------------------------ */
620 Purpose: Accept result from earlier nlm_test_msg() call
621 Returns: Nothing
624 void *
625 nlm_test_res_1_svc(nlm_testres *arg, struct svc_req *rqstp)
627 if (debug_level) log_from_addr("nlm_test_res", rqstp);
628 return (NULL);
631 void *
632 nlmproc4_test_res_4_svc(nlm4_testres *arg, struct svc_req *rqstp)
634 if (debug_level) log_from_addr("nlm_test_res", rqstp);
635 return (NULL);
638 /* nlm_lock_res ------------------------------------------------------------ */
640 Purpose: Accept result from earlier nlm_lock_msg() call
641 Returns: Nothing
644 void *
645 nlm_lock_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
647 if (debug_level) log_from_addr("nlm_lock_res", rqstp);
649 return (NULL);
652 void *
653 nlmproc4_lock_res_4_svc(nlm4_res *arg, struct svc_req *rqstp)
655 if (debug_level) log_from_addr("nlm_lock_res", rqstp);
657 return (NULL);
660 /* nlm_cancel_res ---------------------------------------------------------- */
662 Purpose: Accept result from earlier nlm_cancel_msg() call
663 Returns: Nothing
666 void *
667 nlm_cancel_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
669 if (debug_level) log_from_addr("nlm_cancel_res", rqstp);
670 return (NULL);
673 void *
674 nlmproc4_cancel_res_4_svc(nlm4_res *arg, struct svc_req *rqstp)
676 if (debug_level) log_from_addr("nlm_cancel_res", rqstp);
677 return (NULL);
680 /* nlm_unlock_res ---------------------------------------------------------- */
682 Purpose: Accept result from earlier nlm_unlock_msg() call
683 Returns: Nothing
686 void *
687 nlm_unlock_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
689 if (debug_level) log_from_addr("nlm_unlock_res", rqstp);
690 return (NULL);
693 void *
694 nlmproc4_unlock_res_4_svc(nlm4_res *arg, struct svc_req *rqstp)
696 if (debug_level) log_from_addr("nlm_unlock_res", rqstp);
697 return (NULL);
700 /* nlm_granted_res --------------------------------------------------------- */
702 Purpose: Accept result from earlier nlm_granted_msg() call
703 Returns: Nothing
706 void *
707 nlm_granted_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
709 if (debug_level) log_from_addr("nlm_granted_res", rqstp);
710 return (NULL);
713 void *
714 nlmproc4_granted_res_4_svc(nlm4_res *arg, struct svc_req *rqstp)
716 if (debug_level) log_from_addr("nlm_granted_res", rqstp);
717 return (NULL);
720 /* ------------------------------------------------------------------------- */
722 Calls for PCNFS locking (aka non-monitored locking, no involvement
723 of rpc.statd).
725 These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
729 /* nlm_share --------------------------------------------------------------- */
731 Purpose: Establish a DOS-style lock
732 Returns: success or failure
733 Notes: Blocking locks are not supported - client is expected
734 to retry if required.
737 nlm_shareres *
738 nlm_share_3_svc(nlm_shareargs *arg, struct svc_req *rqstp)
740 static nlm_shareres res;
741 if (debug_level) log_from_addr("nlm_share", rqstp);
743 res.cookie = arg->cookie;
744 res.stat = nlm_granted;
745 res.sequence = 1234356; /* X/Open says this field is ignored? */
746 return (&res);
749 nlm4_shareres *
750 nlmproc4_share_4_svc(nlm4_shareargs *arg, struct svc_req *rqstp)
752 static nlm4_shareres res;
753 if (debug_level) log_from_addr("nlm_share", rqstp);
755 res.cookie = arg->cookie;
756 res.stat = nlm4_granted;
757 res.sequence = 1234356; /* X/Open says this field is ignored? */
758 return (&res);
761 /* nlm_unshare ------------------------------------------------------------ */
763 Purpose: Release a DOS-style lock
764 Returns: nlm_granted, unless in grace period
765 Notes:
768 nlm_shareres *
769 nlm_unshare_3_svc(nlm_shareargs *arg, struct svc_req *rqstp)
771 static nlm_shareres res;
772 if (debug_level) log_from_addr("nlm_unshare", rqstp);
774 res.cookie = arg->cookie;
775 res.stat = nlm_granted;
776 res.sequence = 1234356; /* X/Open says this field is ignored? */
777 return (&res);
780 nlm4_shareres *
781 nlmproc4_unshare_4_svc(nlm4_shareargs *arg, struct svc_req *rqstp)
783 static nlm4_shareres res;
784 if (debug_level) log_from_addr("nlm_unshare", rqstp);
786 res.cookie = arg->cookie;
787 res.stat = nlm4_granted;
788 res.sequence = 1234356; /* X/Open says this field is ignored? */
789 return (&res);
792 /* nlm_nm_lock ------------------------------------------------------------ */
794 Purpose: non-monitored version of nlm_lock()
795 Returns: as for nlm_lock()
796 Notes: These locks are in the same style as the standard nlm_lock,
797 but the rpc.statd should not be called to establish a
798 monitor for the client machine, since that machine is
799 declared not to be running a rpc.statd, and so would not
800 respond to the statd protocol.
803 nlm_res *
804 nlm_nm_lock_3_svc(nlm_lockargs *arg, struct svc_req *rqstp)
806 static nlm_res res;
807 if (debug_level) log_from_addr("nlm_nm_lock", rqstp);
809 /* copy cookie from arg to result. See comment in nlm_test_1() */
810 res.cookie = arg->cookie;
811 res.stat.stat = nlm_granted;
812 return (&res);
815 nlm4_res *
816 nlmproc4_nm_lock_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
818 static nlm4_res res;
819 if (debug_level) log_from_addr("nlm_nm_lock", rqstp);
821 /* copy cookie from arg to result. See comment in nlm_test_1() */
822 res.cookie = arg->cookie;
823 res.stat.stat = nlm4_granted;
824 return (&res);
827 /* nlm_free_all ------------------------------------------------------------ */
829 Purpose: Release all locks held by a named client
830 Returns: Nothing
831 Notes: Potential denial of service security problem here - the
832 locks to be released are specified by a host name, independent
833 of the address from which the request has arrived.
834 Should probably be rejected if the named host has been
835 using monitored locks.
838 void *
839 nlm_free_all_3_svc(nlm_notify *arg, struct svc_req *rqstp)
841 static char dummy;
843 if (debug_level) log_from_addr("nlm_free_all", rqstp);
844 return (&dummy);
847 void *
848 nlmproc4_free_all_4_svc(nlm4_notify *arg, struct svc_req *rqstp)
850 static char dummy;
852 if (debug_level) log_from_addr("nlm_free_all", rqstp);
853 return (&dummy);
856 void *
857 nlmproc4_null_4_svc(void *arg, struct svc_req *rqstp)
859 static char dummy;
861 if (debug_level) log_from_addr("nlm_free_all", rqstp);
862 return (&dummy);