]>
git.saurik.com Git - apple/network_cmds.git/blob - rpc_lockd.tproj/kern.c
2 * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Berkeley Software Design Inc's name may not be used to endorse or
13 * promote products derived from this software without specific prior
16 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * from BSDI kern.c,v 1.2 1998/11/25 22:38:27 don Exp
29 * $FreeBSD: src/usr.sbin/rpc.lockd/kern.c,v 1.11 2002/08/15 21:52:21 alfred Exp $
32 #include <sys/param.h>
33 #include <sys/mount.h>
34 #include <sys/queue.h>
35 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
52 #include "rpcsvc/nlm_prot.h"
53 #include <nfs/rpcv2.h>
54 #include <nfs/nfsproto.h>
55 #include <nfs/nfs_lock.h>
59 #include "lockd_lock.h"
61 #define nfslockdans(_v, _ansp) \
62 ((_ansp)->la_version = (_v), \
63 nfsclnt(NFSCLNT_LOCKDANS, (_ansp)))
66 /* Lock request owner. */
67 typedef struct __owner
{
68 pid_t pid
; /* Process ID. */
69 time_t tod
; /* Time-of-day. */
73 static char hostname
[MAXHOSTNAMELEN
+ 1]; /* Hostname. */
75 static void client_cleanup(void);
76 static void set_auth(CLIENT
*cl
, struct xucred
*ucred
);
77 int lock_request(LOCKD_MSG
*);
78 int cancel_request(LOCKD_MSG
*);
79 int test_request(LOCKD_MSG
*);
80 void show(LOCKD_MSG
*);
81 int unlock_request(LOCKD_MSG
*);
83 #define d_calls (debug_level > 1)
84 #define d_args (debug_level > 2)
88 struct sockaddr
*saddr
;
90 static char inet_buf
[INET6_ADDRSTRLEN
];
92 if (getnameinfo(saddr
, saddr
->sa_len
, inet_buf
, sizeof(inet_buf
),
93 NULL
, 0, NI_NUMERICHOST
) == 0)
101 * wait for kernel to signal first lock request before starting
104 client_kern_wait(void)
106 if (nfsclnt(NFSCLNT_LOCKDWAIT
, NULL
))
107 warn("nfsclnt_lockdwait");
113 (void) nfsclnt(NFSCLNT_LOCKDFD
, (struct lockd_ans
*)-1);
119 * Loop around messages from the kernel, forwarding them off to
131 /* Recreate the NLM fifo. */
132 (void)unlink(_PATH_LCKFIFO
);
133 old_umask
= umask(S_IXGRP
|S_IXOTH
);
134 if (mkfifo(_PATH_LCKFIFO
, S_IWUSR
| S_IRUSR
)) {
135 syslog(LOG_ERR
, "mkfifo: %s: %m", _PATH_LCKFIFO
);
141 * Create a separate process, the client code is really a separate
142 * daemon that shares a lot of code.
144 switch (child
= fork()) {
153 signal(SIGHUP
, (sig_t
)client_cleanup
);
154 signal(SIGTERM
, (sig_t
)client_cleanup
);
157 (void)time(&owner
.tod
);
158 owner
.pid
= getpid();
159 (void)gethostname(hostname
, sizeof(hostname
) - 1);
161 /* Open the fifo for reading. */
162 if ((fd
= open(_PATH_LCKFIFO
, O_RDONLY
| O_NONBLOCK
)) == -1) {
163 syslog(LOG_ERR
, "open: %s: %m", _PATH_LCKFIFO
);
166 (void)unlink(_PATH_LCKFIFO
);
167 if (nfsclnt(NFSCLNT_LOCKDFD
, (struct lockd_ans
*)fd
)) {
168 syslog(LOG_ERR
, "nfsclnt_fd: %d: %m", fd
);
173 /* Wait for contact... fifo's return EAGAIN when read with
176 /* Set up the select. */
179 (void)select(fd
+ 1, &rdset
, NULL
, NULL
, NULL
);
181 /* Read the fixed length message. */
182 if ((nr
= read(fd
, &msg
, sizeof(msg
))) == sizeof(msg
)) {
186 if (msg
.lm_version
!= LOCKD_MSG_VERSION
) {
188 "unknown msg type: %d", msg
.lm_version
);
191 * Send it to the NLM server and don't grant the lock
192 * if we fail for any reason.
194 switch (msg
.lm_fl
.l_type
) {
197 if (msg
.lm_flags
& LOCKD_MSG_TEST
)
198 ret
= test_request(&msg
);
199 else if (msg
.lm_flags
& LOCKD_MSG_CANCEL
)
200 ret
= cancel_request(&msg
);
202 ret
= lock_request(&msg
);
205 ret
= unlock_request(&msg
);
210 "unknown lock type: %d", msg
.lm_fl
.l_type
);
214 struct lockd_ans ans
;
216 ans
.la_xid
= msg
.lm_xid
;
217 ans
.la_errno
= ENOTSUP
;
219 if (nfslockdans(LOCKD_ANS_VERSION
, &ans
)) {
220 syslog(LOG_DEBUG
, "process %lu: %m",
221 (u_long
)msg
.lm_fl
.l_pid
);
224 } else if (nr
== -1) {
225 if (errno
!= EAGAIN
) {
226 syslog(LOG_ERR
, "read: %s: %m", _PATH_LCKFIFO
);
229 } else if (nr
!= 0) {
231 "%s: discard %d bytes", _PATH_LCKFIFO
, nr
);
235 /* Reached only on error. */
237 (void) nfsclnt(NFSCLNT_LOCKDFD
, (struct lockd_ans
*)-1);
245 struct xucred
*xucred
;
247 if (cl
->cl_auth
!= NULL
)
248 cl
->cl_auth
->ah_ops
->ah_destroy(cl
->cl_auth
);
249 cl
->cl_auth
= authunix_create(hostname
,
251 xucred
->cr_groups
[0],
252 xucred
->cr_ngroups
- 1,
253 &xucred
->cr_groups
[1]);
259 * Convert a lock LOCKD_MSG into an NLM request, and send it off.
262 test_request(LOCKD_MSG
*msg
)
265 struct timeval timeout
= {0, 0}; /* No timeout, no response. */
269 syslog(LOG_DEBUG
, "test request: %s: %s to %s",
270 (msg
->lm_flags
& LOCKD_MSG_NFSV3
) ? "V4" : "V1/3",
271 msg
->lm_fl
.l_type
== F_WRLCK
? "write" : "read",
272 from_addr((struct sockaddr
*)&msg
->lm_addr
));
274 if (msg
->lm_flags
& LOCKD_MSG_NFSV3
) {
275 struct nlm4_testargs arg4
;
277 arg4
.cookie
.n_bytes
= (char *)&msg
->lm_xid
;
278 arg4
.cookie
.n_len
= sizeof(msg
->lm_xid
);
279 arg4
.exclusive
= msg
->lm_fl
.l_type
== F_WRLCK
? 1 : 0;
280 arg4
.alock
.caller_name
= hostname
;
281 arg4
.alock
.fh
.n_bytes
= (char *)&msg
->lm_fh
;
282 arg4
.alock
.fh
.n_len
= msg
->lm_fh_len
;
283 arg4
.alock
.oh
.n_bytes
= (char *)&owner
;
284 arg4
.alock
.oh
.n_len
= sizeof(owner
);
285 arg4
.alock
.svid
= msg
->lm_fl
.l_pid
;
286 arg4
.alock
.l_offset
= msg
->lm_fl
.l_start
;
287 arg4
.alock
.l_len
= msg
->lm_fl
.l_len
;
289 if ((cli
= get_client(
290 (struct sockaddr
*)&msg
->lm_addr
,
294 set_auth(cli
, &msg
->lm_cred
);
295 (void)clnt_call(cli
, NLM4_TEST_MSG
,
296 xdr_nlm4_testargs
, &arg4
, xdr_void
, &dummy
, timeout
);
298 struct nlm_testargs arg
;
300 arg
.cookie
.n_bytes
= (char *)&msg
->lm_xid
;
301 arg
.cookie
.n_len
= sizeof(msg
->lm_xid
);
302 arg
.exclusive
= msg
->lm_fl
.l_type
== F_WRLCK
? 1 : 0;
303 arg
.alock
.caller_name
= hostname
;
304 arg
.alock
.fh
.n_bytes
= (char *)&msg
->lm_fh
;
305 arg
.alock
.fh
.n_len
= msg
->lm_fh_len
;
306 arg
.alock
.oh
.n_bytes
= (char *)&owner
;
307 arg
.alock
.oh
.n_len
= sizeof(owner
);
308 arg
.alock
.svid
= msg
->lm_fl
.l_pid
;
309 arg
.alock
.l_offset
= msg
->lm_fl
.l_start
;
310 arg
.alock
.l_len
= msg
->lm_fl
.l_len
;
312 if ((cli
= get_client(
313 (struct sockaddr
*)&msg
->lm_addr
,
317 set_auth(cli
, &msg
->lm_cred
);
318 (void)clnt_call(cli
, NLM_TEST_MSG
,
319 xdr_nlm_testargs
, &arg
, xdr_void
, &dummy
, timeout
);
326 * Convert a lock LOCKD_MSG into an NLM request, and send it off.
329 lock_request(LOCKD_MSG
*msg
)
332 struct nlm4_lockargs arg4
;
333 struct nlm_lockargs arg
;
334 struct timeval timeout
= {0, 0}; /* No timeout, no response. */
338 syslog(LOG_DEBUG
, "lock request: %s: %s to %s",
339 (msg
->lm_flags
& LOCKD_MSG_NFSV3
) ? "V4" : "V1/3",
340 msg
->lm_fl
.l_type
== F_WRLCK
? "write" : "read",
341 from_addr((struct sockaddr
*)&msg
->lm_addr
));
343 monitor_lock_host_by_addr((struct sockaddr
*)&msg
->lm_addr
);
345 if (msg
->lm_flags
& LOCKD_MSG_NFSV3
) {
346 arg4
.cookie
.n_bytes
= (char *)&msg
->lm_xid
;
347 arg4
.cookie
.n_len
= sizeof(msg
->lm_xid
);
348 arg4
.block
= (msg
->lm_flags
& LOCKD_MSG_BLOCK
) ? 1 : 0;
349 arg4
.exclusive
= msg
->lm_fl
.l_type
== F_WRLCK
? 1 : 0;
350 arg4
.alock
.caller_name
= hostname
;
351 arg4
.alock
.fh
.n_bytes
= (char *)&msg
->lm_fh
;
352 arg4
.alock
.fh
.n_len
= msg
->lm_fh_len
;
353 arg4
.alock
.oh
.n_bytes
= (char *)&owner
;
354 arg4
.alock
.oh
.n_len
= sizeof(owner
);
355 arg4
.alock
.svid
= msg
->lm_fl
.l_pid
;
356 arg4
.alock
.l_offset
= msg
->lm_fl
.l_start
;
357 arg4
.alock
.l_len
= msg
->lm_fl
.l_len
;
359 arg4
.state
= nsm_state
;
361 if ((cli
= get_client(
362 (struct sockaddr
*)&msg
->lm_addr
,
366 set_auth(cli
, &msg
->lm_cred
);
367 (void)clnt_call(cli
, NLM4_LOCK_MSG
,
368 xdr_nlm4_lockargs
, &arg4
, xdr_void
, &dummy
, timeout
);
370 arg
.cookie
.n_bytes
= (char *)&msg
->lm_xid
;
371 arg
.cookie
.n_len
= sizeof(msg
->lm_xid
);
372 arg
.block
= (msg
->lm_flags
& LOCKD_MSG_BLOCK
) ? 1 : 0;
373 arg
.exclusive
= msg
->lm_fl
.l_type
== F_WRLCK
? 1 : 0;
374 arg
.alock
.caller_name
= hostname
;
375 arg
.alock
.fh
.n_bytes
= (char *)&msg
->lm_fh
;
376 arg
.alock
.fh
.n_len
= msg
->lm_fh_len
;
377 arg
.alock
.oh
.n_bytes
= (char *)&owner
;
378 arg
.alock
.oh
.n_len
= sizeof(owner
);
379 arg
.alock
.svid
= msg
->lm_fl
.l_pid
;
380 arg
.alock
.l_offset
= msg
->lm_fl
.l_start
;
381 arg
.alock
.l_len
= msg
->lm_fl
.l_len
;
383 arg
.state
= nsm_state
;
385 if ((cli
= get_client(
386 (struct sockaddr
*)&msg
->lm_addr
,
390 set_auth(cli
, &msg
->lm_cred
);
391 (void)clnt_call(cli
, NLM_LOCK_MSG
,
392 xdr_nlm_lockargs
, &arg
, xdr_void
, &dummy
, timeout
);
399 * Convert a lock LOCKD_MSG into an NLM request, and send it off.
402 cancel_request(LOCKD_MSG
*msg
)
405 struct nlm4_cancargs arg4
;
406 struct nlm_cancargs arg
;
407 struct timeval timeout
= {0, 0}; /* No timeout, no response. */
411 syslog(LOG_DEBUG
, "cancel request: %s: %s to %s",
412 (msg
->lm_flags
& LOCKD_MSG_NFSV3
) ? "V4" : "V1/3",
413 msg
->lm_fl
.l_type
== F_WRLCK
? "write" : "read",
414 from_addr((struct sockaddr
*)&msg
->lm_addr
));
416 if (msg
->lm_flags
& LOCKD_MSG_NFSV3
) {
417 arg4
.cookie
.n_bytes
= (char *)&msg
->lm_xid
;
418 arg4
.cookie
.n_len
= sizeof(msg
->lm_xid
);
419 arg4
.block
= (msg
->lm_flags
& LOCKD_MSG_BLOCK
) ? 1 : 0;
420 arg4
.exclusive
= msg
->lm_fl
.l_type
== F_WRLCK
? 1 : 0;
421 arg4
.alock
.caller_name
= hostname
;
422 arg4
.alock
.fh
.n_bytes
= (char *)&msg
->lm_fh
;
423 arg4
.alock
.fh
.n_len
= msg
->lm_fh_len
;
424 arg4
.alock
.oh
.n_bytes
= (char *)&owner
;
425 arg4
.alock
.oh
.n_len
= sizeof(owner
);
426 arg4
.alock
.svid
= msg
->lm_fl
.l_pid
;
427 arg4
.alock
.l_offset
= msg
->lm_fl
.l_start
;
428 arg4
.alock
.l_len
= msg
->lm_fl
.l_len
;
430 if ((cli
= get_client(
431 (struct sockaddr
*)&msg
->lm_addr
, NLM_VERS4
)) == NULL
)
434 set_auth(cli
, &msg
->lm_cred
);
435 (void)clnt_call(cli
, NLM4_CANCEL_MSG
,
436 xdr_nlm4_cancargs
, &arg4
, xdr_void
, &dummy
, timeout
);
438 arg
.cookie
.n_bytes
= (char *)&msg
->lm_xid
;
439 arg
.cookie
.n_len
= sizeof(msg
->lm_xid
);
440 arg
.block
= (msg
->lm_flags
& LOCKD_MSG_BLOCK
) ? 1 : 0;
441 arg
.exclusive
= msg
->lm_fl
.l_type
== F_WRLCK
? 1 : 0;
442 arg
.alock
.caller_name
= hostname
;
443 arg
.alock
.fh
.n_bytes
= (char *)&msg
->lm_fh
;
444 arg
.alock
.fh
.n_len
= msg
->lm_fh_len
;
445 arg
.alock
.oh
.n_bytes
= (char *)&owner
;
446 arg
.alock
.oh
.n_len
= sizeof(owner
);
447 arg
.alock
.svid
= msg
->lm_fl
.l_pid
;
448 arg
.alock
.l_offset
= msg
->lm_fl
.l_start
;
449 arg
.alock
.l_len
= msg
->lm_fl
.l_len
;
451 if ((cli
= get_client(
452 (struct sockaddr
*)&msg
->lm_addr
, NLM_VERS
)) == NULL
)
455 set_auth(cli
, &msg
->lm_cred
);
456 (void)clnt_call(cli
, NLM_CANCEL_MSG
,
457 xdr_nlm_cancargs
, &arg
, xdr_void
, &dummy
, timeout
);
464 * Convert an unlock LOCKD_MSG into an NLM request, and send it off.
467 unlock_request(LOCKD_MSG
*msg
)
470 struct nlm4_unlockargs arg4
;
471 struct nlm_unlockargs arg
;
472 struct timeval timeout
= {0, 0}; /* No timeout, no response. */
476 syslog(LOG_DEBUG
, "unlock request: %s: to %s",
477 (msg
->lm_flags
& LOCKD_MSG_NFSV3
) ? "V4" : "V1/3",
478 from_addr((struct sockaddr
*)&msg
->lm_addr
));
480 if (msg
->lm_flags
& LOCKD_MSG_NFSV3
) {
481 arg4
.cookie
.n_bytes
= (char *)&msg
->lm_xid
;
482 arg4
.cookie
.n_len
= sizeof(msg
->lm_xid
);
483 arg4
.alock
.caller_name
= hostname
;
484 arg4
.alock
.fh
.n_bytes
= (char *)&msg
->lm_fh
;
485 arg4
.alock
.fh
.n_len
= msg
->lm_fh_len
;
486 arg4
.alock
.oh
.n_bytes
= (char *)&owner
;
487 arg4
.alock
.oh
.n_len
= sizeof(owner
);
488 arg4
.alock
.svid
= msg
->lm_fl
.l_pid
;
489 arg4
.alock
.l_offset
= msg
->lm_fl
.l_start
;
490 arg4
.alock
.l_len
= msg
->lm_fl
.l_len
;
492 if ((cli
= get_client(
493 (struct sockaddr
*)&msg
->lm_addr
,
497 set_auth(cli
, &msg
->lm_cred
);
498 (void)clnt_call(cli
, NLM4_UNLOCK_MSG
,
499 xdr_nlm4_unlockargs
, &arg4
, xdr_void
, &dummy
, timeout
);
501 arg
.cookie
.n_bytes
= (char *)&msg
->lm_xid
;
502 arg
.cookie
.n_len
= sizeof(msg
->lm_xid
);
503 arg
.alock
.caller_name
= hostname
;
504 arg
.alock
.fh
.n_bytes
= (char *)&msg
->lm_fh
;
505 arg
.alock
.fh
.n_len
= msg
->lm_fh_len
;
506 arg
.alock
.oh
.n_bytes
= (char *)&owner
;
507 arg
.alock
.oh
.n_len
= sizeof(owner
);
508 arg
.alock
.svid
= msg
->lm_fl
.l_pid
;
509 arg
.alock
.l_offset
= msg
->lm_fl
.l_start
;
510 arg
.alock
.l_len
= msg
->lm_fl
.l_len
;
512 if ((cli
= get_client(
513 (struct sockaddr
*)&msg
->lm_addr
,
517 set_auth(cli
, &msg
->lm_cred
);
518 (void)clnt_call(cli
, NLM_UNLOCK_MSG
,
519 xdr_nlm_unlockargs
, &arg
, xdr_void
, &dummy
, timeout
);
526 lock_answer(int version
, netobj
*netcookie
, nlm4_lock
*lock
, int flags
, int result
)
528 struct lockd_ans ans
;
531 if (flags
& LOCK_ANSWER_GRANTED
)
532 ans
.la_flags
|= LOCKD_ANS_GRANTED
;
534 if (netcookie
->n_len
!= sizeof(ans
.la_xid
)) {
535 if (lock
== NULL
) { /* we're screwed */
536 syslog(LOG_ERR
, "inedible nlm cookie");
539 /* no/bad cookie - need to copy lock info to identify request */
542 ans
.la_fh_len
= lock
->fh
.n_len
;
543 if (!lock
->fh
.n_len
|| (lock
->fh
.n_len
> NFS_SMALLFH
)) {
544 syslog(LOG_ERR
, "bogus filehandle size %d in answer", lock
->fh
.n_len
);
547 memcpy(ans
.la_fh
, lock
->fh
.n_bytes
, ans
.la_fh_len
);
548 ans
.la_pid
= lock
->svid
;
549 ans
.la_start
= lock
->l_offset
;
550 ans
.la_len
= lock
->l_len
;
551 ans
.la_flags
|= LOCKD_ANS_LOCK_INFO
;
552 if (flags
& LOCK_ANSWER_LOCK_EXCL
)
553 ans
.la_flags
|= LOCKD_ANS_LOCK_EXCL
;
555 memcpy(&ans
.la_xid
, netcookie
->n_bytes
, sizeof(ans
.la_xid
));
560 syslog(LOG_DEBUG
, "lock answer: pid %lu: %s %d",
561 (unsigned long)ans
.la_pid
,
562 version
== NLM_VERS4
? "nlmv4" : "nlmv3",
565 if (version
== NLM_VERS4
)
569 if ((flags
& LOCK_ANSWER_GRANTED
) && lock
&&
570 !(ans
.la_flags
& LOCKD_ANS_LOCK_INFO
)) {
572 ans
.la_fh_len
= lock
->fh
.n_len
;
573 if (!lock
->fh
.n_len
|| (lock
->fh
.n_len
> NFS_SMALLFH
)) {
574 syslog(LOG_ERR
, "bogus filehandle size %d in answer", lock
->fh
.n_len
);
577 memcpy(ans
.la_fh
, lock
->fh
.n_bytes
, ans
.la_fh_len
);
578 ans
.la_pid
= lock
->svid
;
579 ans
.la_start
= lock
->l_offset
;
580 ans
.la_len
= lock
->l_len
;
581 ans
.la_flags
|= LOCKD_ANS_LOCK_INFO
;
582 if (flags
& LOCK_ANSWER_LOCK_EXCL
)
583 ans
.la_flags
|= LOCKD_ANS_LOCK_EXCL
;
587 ans
.la_errno
= EACCES
;
591 ans
.la_errno
= EACCES
;
593 /* this is an answer to a nlm_test msg */
594 ans
.la_pid
= lock
->svid
;
595 ans
.la_start
= lock
->l_offset
;
596 ans
.la_len
= lock
->l_len
;
597 ans
.la_flags
|= LOCKD_ANS_LOCK_INFO
;
598 if (flags
& LOCK_ANSWER_LOCK_EXCL
)
599 ans
.la_flags
|= LOCKD_ANS_LOCK_EXCL
;
603 case nlm4_denied_nolocks
:
604 ans
.la_errno
= ENOLCK
;
607 ans
.la_errno
= EINPROGRESS
;
609 case nlm4_denied_grace_period
:
610 ans
.la_errno
= EAGAIN
;
613 ans
.la_errno
= EDEADLK
;
616 ans
.la_errno
= EROFS
;
619 ans
.la_errno
= ESTALE
;
622 ans
.la_errno
= EFBIG
;
625 ans
.la_errno
= EACCES
;
632 if ((flags
& LOCK_ANSWER_GRANTED
) && lock
&&
633 !(ans
.la_flags
& LOCKD_ANS_LOCK_INFO
)) {
635 ans
.la_fh_len
= lock
->fh
.n_len
;
636 if (!lock
->fh
.n_len
|| (lock
->fh
.n_len
> NFS_SMALLFH
)) {
637 syslog(LOG_ERR
, "bogus filehandle size %d in answer", lock
->fh
.n_len
);
640 memcpy(ans
.la_fh
, lock
->fh
.n_bytes
, ans
.la_fh_len
);
641 ans
.la_pid
= lock
->svid
;
642 ans
.la_start
= lock
->l_offset
;
643 ans
.la_len
= lock
->l_len
;
644 ans
.la_flags
|= LOCKD_ANS_LOCK_INFO
;
645 if (flags
& LOCK_ANSWER_LOCK_EXCL
)
646 ans
.la_flags
|= LOCKD_ANS_LOCK_EXCL
;
650 ans
.la_errno
= EACCES
;
654 ans
.la_errno
= EACCES
;
656 /* this is an answer to a nlm_test msg */
657 ans
.la_pid
= lock
->svid
;
658 ans
.la_start
= lock
->l_offset
;
659 ans
.la_len
= lock
->l_len
;
660 ans
.la_flags
|= LOCKD_ANS_LOCK_INFO
;
661 if (flags
& LOCK_ANSWER_LOCK_EXCL
)
662 ans
.la_flags
|= LOCKD_ANS_LOCK_EXCL
;
666 case nlm_denied_nolocks
:
667 ans
.la_errno
= ENOLCK
;
670 ans
.la_errno
= EINPROGRESS
;
672 case nlm_denied_grace_period
:
673 ans
.la_errno
= EAGAIN
;
676 ans
.la_errno
= EDEADLK
;
680 if (nfslockdans(LOCKD_ANS_VERSION
, &ans
)) {
681 syslog(LOG_DEBUG
, "lock_answer(%d): process %lu: %m",
682 result
, (u_long
)ans
.la_pid
);
690 * Display the contents of a kernel LOCKD_MSG structure.
695 static char hex
[] = "0123456789abcdef";
697 u_int8_t
*p
, *t
, buf
[NFS_SMALLFH
*3+1];
699 syslog(LOG_DEBUG
, "process ID: %lu\n", (long)mp
->lm_fl
.l_pid
);
701 for (t
= buf
, p
= (u_int8_t
*)mp
->lm_fh
,
703 len
> 0; ++p
, --len
) {
705 *t
++ = hex
[(*p
& 0xf0) >> 4];
706 *t
++ = hex
[*p
& 0x0f];
710 syslog(LOG_DEBUG
, "fh_len %d, fh %s\n", mp
->lm_fh_len
, buf
);
712 /* Show flock structure. */
713 syslog(LOG_DEBUG
, "start %qu; len %qu; pid %lu; type %d; whence %d\n",
714 mp
->lm_fl
.l_start
, mp
->lm_fl
.l_len
, (u_long
)mp
->lm_fl
.l_pid
,
715 mp
->lm_fl
.l_type
, mp
->lm_fl
.l_whence
);
717 /* Show wait flag. */
718 syslog(LOG_DEBUG
, "wait was %s\n", (mp
->lm_flags
& LOCKD_MSG_BLOCK
) ? "set" : "not set");