kern.c revision 138431
175631Salfred/*- 275631Salfred * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. 375631Salfred * 475631Salfred * Redistribution and use in source and binary forms, with or without 575631Salfred * modification, are permitted provided that the following conditions 675631Salfred * are met: 775631Salfred * 1. Redistributions of source code must retain the above copyright 875631Salfred * notice, this list of conditions and the following disclaimer. 975631Salfred * 2. Redistributions in binary form must reproduce the above copyright 1075631Salfred * notice, this list of conditions and the following disclaimer in the 1175631Salfred * documentation and/or other materials provided with the distribution. 1275631Salfred * 3. Berkeley Software Design Inc's name may not be used to endorse or 1375631Salfred * promote products derived from this software without specific prior 1475631Salfred * written permission. 1575631Salfred * 1675631Salfred * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND 1775631Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1875631Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1975631Salfred * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE 2075631Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2175631Salfred * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2275631Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2375631Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2475631Salfred * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2575631Salfred * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2675631Salfred * SUCH DAMAGE. 2775631Salfred * 2875631Salfred * from BSDI kern.c,v 1.2 1998/11/25 22:38:27 don Exp 2975631Salfred * $FreeBSD: head/usr.sbin/rpc.lockd/kern.c 138431 2004-12-06 08:32:09Z phk $ 3075631Salfred */ 3175631Salfred 3275631Salfred#include <sys/param.h> 3375631Salfred#include <sys/mount.h> 3475631Salfred#include <sys/queue.h> 3575631Salfred#include <sys/socket.h> 3675631Salfred#include <sys/stat.h> 3775631Salfred 3886299Salfred#include <netinet/in.h> 3986299Salfred#include <arpa/inet.h> 4086299Salfred 4175631Salfred#include <err.h> 4275631Salfred#include <errno.h> 4375631Salfred#include <fcntl.h> 44138431Sphk#include <paths.h> 4586279Salfred#include <pwd.h> 4675631Salfred#include <stdio.h> 4775631Salfred#include <stdlib.h> 4875631Salfred#include <string.h> 4975631Salfred#include <syslog.h> 5075631Salfred#include <unistd.h> 51100134Salfred#include <netdb.h> 5275631Salfred 5375631Salfred#include "nlm_prot.h" 5483653Speter#include <nfs/rpcv2.h> 5583653Speter#include <nfs/nfsproto.h> 5683653Speter#include <nfsclient/nfs_lock.h> 5775631Salfred 5875631Salfred#include "lockd.h" 5975631Salfred#include "lockd_lock.h" 6083653Speter#include <nfsclient/nfs.h> 6175631Salfred 6286279Salfred#define DAEMON_USERNAME "daemon" 6386279Salfred 6475631Salfred/* Lock request owner. */ 6575631Salfredtypedef struct __owner { 6675631Salfred pid_t pid; /* Process ID. */ 6775631Salfred time_t tod; /* Time-of-day. */ 6875631Salfred} OWNER; 6975631Salfredstatic OWNER owner; 7075631Salfred 7175631Salfredstatic char hostname[MAXHOSTNAMELEN + 1]; /* Hostname. */ 7275631Salfred 7386299Salfredstatic void client_cleanup(void); 74101947Salfredstatic void set_auth(CLIENT *cl, struct xucred *ucred); 7575631Salfredint lock_request(LOCKD_MSG *); 7675631Salfredint test_request(LOCKD_MSG *); 7775631Salfredvoid show(LOCKD_MSG *); 7875631Salfredint unlock_request(LOCKD_MSG *); 79138431Sphkstatic int devfd; 8075631Salfred 81138431Sphkstatic int 82138431Sphknfslockdans(int vers, struct lockd_ans *ansp) 83138431Sphk{ 84138431Sphk 85138431Sphk ansp->la_vers = vers; 86138431Sphk return (write(devfd, ansp, sizeof *ansp)); 87138431Sphk} 88138431Sphk 8975631Salfred/* 9075631Salfred * will break because fifo needs to be repopened when EOF'd 9175631Salfred */ 9275631Salfred#define lockd_seteuid(uid) seteuid(uid) 9375631Salfred 9475979Salfred#define d_calls (debug_level > 1) 9575979Salfred#define d_args (debug_level > 2) 9675631Salfred 97100134Salfredstatic const char * 98100134Salfredfrom_addr(saddr) 99100134Salfred struct sockaddr *saddr; 100100134Salfred{ 101100134Salfred static char inet_buf[INET6_ADDRSTRLEN]; 10275979Salfred 103100134Salfred if (getnameinfo(saddr, saddr->sa_len, inet_buf, sizeof(inet_buf), 104100134Salfred NULL, 0, NI_NUMERICHOST) == 0) 105100134Salfred return inet_buf; 106100134Salfred return "???"; 107100134Salfred} 108100134Salfred 10975631Salfredvoid 11086299Salfredclient_cleanup(void) 11175631Salfred{ 11275631Salfred (void)lockd_seteuid(0); 11375631Salfred exit(-1); 11475631Salfred} 11575631Salfred 11675631Salfred/* 11775631Salfred * client_request -- 11875631Salfred * Loop around messages from the kernel, forwarding them off to 11975631Salfred * NLM servers. 12075631Salfred */ 12175631Salfredpid_t 12275631Salfredclient_request(void) 12375631Salfred{ 12475631Salfred LOCKD_MSG msg; 12575631Salfred fd_set rdset; 126138431Sphk int nr, ret; 12775631Salfred pid_t child; 12886279Salfred uid_t daemon_uid; 12986279Salfred mode_t old_umask; 13086279Salfred struct passwd *pw; 13175631Salfred 132138431Sphk /* Open the dev . */ 133138431Sphk devfd = open(_PATH_DEV _PATH_NFSLCKDEV, O_RDWR | O_NONBLOCK); 134138431Sphk if (devfd < 0) { 135138431Sphk syslog(LOG_ERR, "open: %s: %m", _PATH_NFSLCKDEV); 136138431Sphk goto err; 13775631Salfred } 13875631Salfred /* 13975631Salfred * Create a separate process, the client code is really a separate 14075631Salfred * daemon that shares a lot of code. 14175631Salfred */ 14275631Salfred switch (child = fork()) { 14375631Salfred case -1: 14475631Salfred err(1, "fork"); 14575631Salfred case 0: 14675631Salfred break; 14775631Salfred default: 14875631Salfred return (child); 14975631Salfred } 15075631Salfred 15186299Salfred signal(SIGHUP, (sig_t)client_cleanup); 15286299Salfred signal(SIGTERM, (sig_t)client_cleanup); 15375631Salfred 15475631Salfred /* Setup. */ 15575631Salfred (void)time(&owner.tod); 15675631Salfred owner.pid = getpid(); 15775631Salfred (void)gethostname(hostname, sizeof(hostname) - 1); 15875631Salfred 15986279Salfred pw = getpwnam(DAEMON_USERNAME); 16086279Salfred if (pw == NULL) { 16186279Salfred syslog(LOG_ERR, "getpwnam: %s: %m", DAEMON_USERNAME); 16286279Salfred goto err; 16386279Salfred } 16486279Salfred daemon_uid = pw->pw_uid; 16575631Salfred /* drop our root priviledges */ 16675631Salfred (void)lockd_seteuid(daemon_uid); 16775631Salfred 16875631Salfred for (;;) { 16975631Salfred /* Read the fixed length message. */ 170138431Sphk if ((nr = read(devfd, &msg, sizeof(msg))) == sizeof(msg)) { 17175631Salfred if (d_args) 17275631Salfred show(&msg); 17375631Salfred 17475631Salfred if (msg.lm_version != LOCKD_MSG_VERSION) { 17575631Salfred syslog(LOG_ERR, 17675631Salfred "unknown msg type: %d", msg.lm_version); 17775631Salfred } 17875631Salfred /* 17975631Salfred * Send it to the NLM server and don't grant the lock 18075631Salfred * if we fail for any reason. 18175631Salfred */ 18275631Salfred switch (msg.lm_fl.l_type) { 18375631Salfred case F_RDLCK: 18475631Salfred case F_WRLCK: 18575631Salfred if (msg.lm_getlk) 18675631Salfred ret = test_request(&msg); 18775631Salfred else 18875631Salfred ret = lock_request(&msg); 18975631Salfred break; 19075631Salfred case F_UNLCK: 19175631Salfred ret = unlock_request(&msg); 19275631Salfred break; 19375631Salfred default: 19475631Salfred ret = 1; 19575631Salfred syslog(LOG_ERR, 19675631Salfred "unknown lock type: %d", msg.lm_fl.l_type); 19775631Salfred break; 19875631Salfred } 19975631Salfred if (ret) { 20075631Salfred struct lockd_ans ans; 20175631Salfred 20275631Salfred ans.la_msg_ident = msg.lm_msg_ident; 20375631Salfred ans.la_errno = EHOSTUNREACH; 20475631Salfred 20575631Salfred if (nfslockdans(LOCKD_ANS_VERSION, &ans)) { 20675631Salfred syslog((errno == EPIPE ? LOG_INFO : 20775631Salfred LOG_ERR), "process %lu: %m", 20875631Salfred (u_long)msg.lm_msg_ident.pid); 20975631Salfred } 21075631Salfred } 21175631Salfred } else if (nr == -1) { 21275631Salfred if (errno != EAGAIN) { 213138431Sphk syslog(LOG_ERR, "read: %s: %m", _PATH_NFSLCKDEV); 21475631Salfred goto err; 21575631Salfred } 21675631Salfred } else if (nr != 0) { 21775631Salfred syslog(LOG_ERR, 218138431Sphk "%s: discard %d bytes", _PATH_NFSLCKDEV, nr); 21975631Salfred } 22075631Salfred } 22175631Salfred 22275631Salfred /* Reached only on error. */ 22375631Salfrederr: 22475631Salfred (void)lockd_seteuid(0); 22575631Salfred _exit (1); 22675631Salfred} 22775631Salfred 22875631Salfredvoid 229101947Salfredset_auth(cl, xucred) 23086186Salfred CLIENT *cl; 231101947Salfred struct xucred *xucred; 23275631Salfred{ 23375631Salfred if (cl->cl_auth != NULL) 23475631Salfred cl->cl_auth->ah_ops->ah_destroy(cl->cl_auth); 23575631Salfred cl->cl_auth = authunix_create(hostname, 236101947Salfred xucred->cr_uid, 237101947Salfred xucred->cr_groups[0], 238101947Salfred xucred->cr_ngroups - 1, 239101947Salfred &xucred->cr_groups[1]); 24075631Salfred} 24175631Salfred 24275631Salfred 24375631Salfred/* 24475631Salfred * test_request -- 24575631Salfred * Convert a lock LOCKD_MSG into an NLM request, and send it off. 24675631Salfred */ 24775631Salfredint 24875631Salfredtest_request(LOCKD_MSG *msg) 24975631Salfred{ 25075631Salfred CLIENT *cli; 25175631Salfred struct timeval timeout = {0, 0}; /* No timeout, no response. */ 25275631Salfred char dummy; 25375631Salfred 25475631Salfred if (d_calls) 25575631Salfred syslog(LOG_DEBUG, "test request: %s: %s to %s", 25675631Salfred msg->lm_nfsv3 ? "V4" : "V1/3", 25775631Salfred msg->lm_fl.l_type == F_WRLCK ? "write" : "read", 258100134Salfred from_addr((struct sockaddr *)&msg->lm_addr)); 25975631Salfred 26075631Salfred if (msg->lm_nfsv3) { 26175631Salfred struct nlm4_testargs arg4; 26275631Salfred 26375631Salfred arg4.cookie.n_bytes = (char *)&msg->lm_msg_ident; 26475631Salfred arg4.cookie.n_len = sizeof(msg->lm_msg_ident); 26575631Salfred arg4.exclusive = msg->lm_fl.l_type == F_WRLCK ? 1 : 0; 26675631Salfred arg4.alock.caller_name = hostname; 26775631Salfred arg4.alock.fh.n_bytes = (char *)&msg->lm_fh; 26875631Salfred arg4.alock.fh.n_len = msg->lm_fh_len; 26975631Salfred arg4.alock.oh.n_bytes = (char *)&owner; 27075631Salfred arg4.alock.oh.n_len = sizeof(owner); 27175631Salfred arg4.alock.svid = msg->lm_msg_ident.pid; 27275631Salfred arg4.alock.l_offset = msg->lm_fl.l_start; 27375631Salfred arg4.alock.l_len = msg->lm_fl.l_len; 27475631Salfred 27575631Salfred if ((cli = get_client( 27675631Salfred (struct sockaddr *)&msg->lm_addr, 27775631Salfred NLM_VERS4)) == NULL) 27875631Salfred return (1); 27975631Salfred 28075631Salfred set_auth(cli, &msg->lm_cred); 28175631Salfred (void)clnt_call(cli, NLM_TEST_MSG, 282121558Speter (xdrproc_t)xdr_nlm4_testargs, &arg4, 283121558Speter (xdrproc_t)xdr_void, &dummy, timeout); 28475631Salfred } else { 28575631Salfred struct nlm_testargs arg; 28675631Salfred 28775631Salfred arg.cookie.n_bytes = (char *)&msg->lm_msg_ident; 28875631Salfred arg.cookie.n_len = sizeof(msg->lm_msg_ident); 28975631Salfred arg.exclusive = msg->lm_fl.l_type == F_WRLCK ? 1 : 0; 29075631Salfred arg.alock.caller_name = hostname; 29175631Salfred arg.alock.fh.n_bytes = (char *)&msg->lm_fh; 29275631Salfred arg.alock.fh.n_len = msg->lm_fh_len; 29375631Salfred arg.alock.oh.n_bytes = (char *)&owner; 29475631Salfred arg.alock.oh.n_len = sizeof(owner); 29575631Salfred arg.alock.svid = msg->lm_msg_ident.pid; 29675631Salfred arg.alock.l_offset = msg->lm_fl.l_start; 29775631Salfred arg.alock.l_len = msg->lm_fl.l_len; 29875631Salfred 29975631Salfred if ((cli = get_client( 30075631Salfred (struct sockaddr *)&msg->lm_addr, 30175631Salfred NLM_VERS)) == NULL) 30275631Salfred return (1); 30375631Salfred 30475631Salfred set_auth(cli, &msg->lm_cred); 30575631Salfred (void)clnt_call(cli, NLM_TEST_MSG, 306121558Speter (xdrproc_t)xdr_nlm_testargs, &arg, 307121558Speter (xdrproc_t)xdr_void, &dummy, timeout); 30875631Salfred } 30975631Salfred return (0); 31075631Salfred} 31175631Salfred 31275631Salfred/* 31375631Salfred * lock_request -- 31475631Salfred * Convert a lock LOCKD_MSG into an NLM request, and send it off. 31575631Salfred */ 31675631Salfredint 31775631Salfredlock_request(LOCKD_MSG *msg) 31875631Salfred{ 31975631Salfred CLIENT *cli; 32075631Salfred struct nlm4_lockargs arg4; 32175631Salfred struct nlm_lockargs arg; 32275631Salfred struct timeval timeout = {0, 0}; /* No timeout, no response. */ 32375631Salfred char dummy; 32475631Salfred 32575631Salfred if (d_calls) 32675631Salfred syslog(LOG_DEBUG, "lock request: %s: %s to %s", 32775631Salfred msg->lm_nfsv3 ? "V4" : "V1/3", 32875631Salfred msg->lm_fl.l_type == F_WRLCK ? "write" : "read", 329100134Salfred from_addr((struct sockaddr *)&msg->lm_addr)); 33075631Salfred 33175631Salfred if (msg->lm_nfsv3) { 33275631Salfred arg4.cookie.n_bytes = (char *)&msg->lm_msg_ident; 33375631Salfred arg4.cookie.n_len = sizeof(msg->lm_msg_ident); 33475631Salfred arg4.block = msg->lm_wait ? 1 : 0; 33575631Salfred arg4.exclusive = msg->lm_fl.l_type == F_WRLCK ? 1 : 0; 33675631Salfred arg4.alock.caller_name = hostname; 33775631Salfred arg4.alock.fh.n_bytes = (char *)&msg->lm_fh; 33875631Salfred arg4.alock.fh.n_len = msg->lm_fh_len; 33975631Salfred arg4.alock.oh.n_bytes = (char *)&owner; 34075631Salfred arg4.alock.oh.n_len = sizeof(owner); 34175631Salfred arg4.alock.svid = msg->lm_msg_ident.pid; 34275631Salfred arg4.alock.l_offset = msg->lm_fl.l_start; 34375631Salfred arg4.alock.l_len = msg->lm_fl.l_len; 34475631Salfred arg4.reclaim = 0; 34575631Salfred arg4.state = nsm_state; 34675631Salfred 34775631Salfred if ((cli = get_client( 34875631Salfred (struct sockaddr *)&msg->lm_addr, 34975631Salfred NLM_VERS4)) == NULL) 35075631Salfred return (1); 35175631Salfred 35275631Salfred set_auth(cli, &msg->lm_cred); 35375631Salfred (void)clnt_call(cli, NLM_LOCK_MSG, 354121558Speter (xdrproc_t)xdr_nlm4_lockargs, &arg4, 355121558Speter (xdrproc_t)xdr_void, &dummy, timeout); 35675631Salfred } else { 35775631Salfred arg.cookie.n_bytes = (char *)&msg->lm_msg_ident; 35875631Salfred arg.cookie.n_len = sizeof(msg->lm_msg_ident); 35975631Salfred arg.block = msg->lm_wait ? 1 : 0; 36075631Salfred arg.exclusive = msg->lm_fl.l_type == F_WRLCK ? 1 : 0; 36175631Salfred arg.alock.caller_name = hostname; 36275631Salfred arg.alock.fh.n_bytes = (char *)&msg->lm_fh; 36375631Salfred arg.alock.fh.n_len = msg->lm_fh_len; 36475631Salfred arg.alock.oh.n_bytes = (char *)&owner; 36575631Salfred arg.alock.oh.n_len = sizeof(owner); 36675631Salfred arg.alock.svid = msg->lm_msg_ident.pid; 36775631Salfred arg.alock.l_offset = msg->lm_fl.l_start; 36875631Salfred arg.alock.l_len = msg->lm_fl.l_len; 36975631Salfred arg.reclaim = 0; 37075631Salfred arg.state = nsm_state; 37175631Salfred 37275631Salfred if ((cli = get_client( 37375631Salfred (struct sockaddr *)&msg->lm_addr, 37475631Salfred NLM_VERS)) == NULL) 37575631Salfred return (1); 37675631Salfred 37775631Salfred set_auth(cli, &msg->lm_cred); 37875631Salfred (void)clnt_call(cli, NLM_LOCK_MSG, 379121558Speter (xdrproc_t)xdr_nlm_lockargs, &arg, 380121558Speter (xdrproc_t)xdr_void, &dummy, timeout); 38175631Salfred } 38275631Salfred return (0); 38375631Salfred} 38475631Salfred 38575631Salfred/* 38675631Salfred * unlock_request -- 38775631Salfred * Convert an unlock LOCKD_MSG into an NLM request, and send it off. 38875631Salfred */ 38975631Salfredint 39075631Salfredunlock_request(LOCKD_MSG *msg) 39175631Salfred{ 39275631Salfred CLIENT *cli; 39375631Salfred struct nlm4_unlockargs arg4; 39475631Salfred struct nlm_unlockargs arg; 39575631Salfred struct timeval timeout = {0, 0}; /* No timeout, no response. */ 39675631Salfred char dummy; 39775631Salfred 39875631Salfred if (d_calls) 39975631Salfred syslog(LOG_DEBUG, "unlock request: %s: to %s", 40075631Salfred msg->lm_nfsv3 ? "V4" : "V1/3", 401100134Salfred from_addr((struct sockaddr *)&msg->lm_addr)); 40275631Salfred 40375631Salfred if (msg->lm_nfsv3) { 40475631Salfred arg4.cookie.n_bytes = (char *)&msg->lm_msg_ident; 40575631Salfred arg4.cookie.n_len = sizeof(msg->lm_msg_ident); 40675631Salfred arg4.alock.caller_name = hostname; 40775631Salfred arg4.alock.fh.n_bytes = (char *)&msg->lm_fh; 40875631Salfred arg4.alock.fh.n_len = msg->lm_fh_len; 40975631Salfred arg4.alock.oh.n_bytes = (char *)&owner; 41075631Salfred arg4.alock.oh.n_len = sizeof(owner); 41175631Salfred arg4.alock.svid = msg->lm_msg_ident.pid; 41275631Salfred arg4.alock.l_offset = msg->lm_fl.l_start; 41375631Salfred arg4.alock.l_len = msg->lm_fl.l_len; 41475631Salfred 41575631Salfred if ((cli = get_client( 41675631Salfred (struct sockaddr *)&msg->lm_addr, 41775631Salfred NLM_VERS4)) == NULL) 41875631Salfred return (1); 41975631Salfred 42075631Salfred set_auth(cli, &msg->lm_cred); 42175631Salfred (void)clnt_call(cli, NLM_UNLOCK_MSG, 422121558Speter (xdrproc_t)xdr_nlm4_unlockargs, &arg4, 423121558Speter (xdrproc_t)xdr_void, &dummy, timeout); 42475631Salfred } else { 42575631Salfred arg.cookie.n_bytes = (char *)&msg->lm_msg_ident; 42675631Salfred arg.cookie.n_len = sizeof(msg->lm_msg_ident); 42775631Salfred arg.alock.caller_name = hostname; 42875631Salfred arg.alock.fh.n_bytes = (char *)&msg->lm_fh; 42975631Salfred arg.alock.fh.n_len = msg->lm_fh_len; 43075631Salfred arg.alock.oh.n_bytes = (char *)&owner; 43175631Salfred arg.alock.oh.n_len = sizeof(owner); 43275631Salfred arg.alock.svid = msg->lm_msg_ident.pid; 43375631Salfred arg.alock.l_offset = msg->lm_fl.l_start; 43475631Salfred arg.alock.l_len = msg->lm_fl.l_len; 43575631Salfred 43675631Salfred if ((cli = get_client( 43775631Salfred (struct sockaddr *)&msg->lm_addr, 43875631Salfred NLM_VERS)) == NULL) 43975631Salfred return (1); 44075631Salfred 44175631Salfred set_auth(cli, &msg->lm_cred); 44275631Salfred (void)clnt_call(cli, NLM_UNLOCK_MSG, 443121558Speter (xdrproc_t)xdr_nlm_unlockargs, &arg, 444121558Speter (xdrproc_t)xdr_void, &dummy, timeout); 44575631Salfred } 44675631Salfred 44775631Salfred return (0); 44875631Salfred} 44975631Salfred 45075631Salfredint 45175631Salfredlock_answer(int pid, netobj *netcookie, int result, int *pid_p, int version) 45275631Salfred{ 45375631Salfred struct lockd_ans ans; 45475631Salfred 45575631Salfred if (netcookie->n_len != sizeof(ans.la_msg_ident)) { 45675631Salfred if (pid == -1) { /* we're screwed */ 45775631Salfred syslog(LOG_ERR, "inedible nlm cookie"); 45875631Salfred return -1; 45975631Salfred } 46075631Salfred ans.la_msg_ident.pid = pid; 46175631Salfred ans.la_msg_ident.msg_seq = -1; 46275631Salfred } else { 46386186Salfred memcpy(&ans.la_msg_ident, netcookie->n_bytes, 46486186Salfred sizeof(ans.la_msg_ident)); 46575631Salfred } 46675631Salfred 46775631Salfred if (d_calls) 46875979Salfred syslog(LOG_DEBUG, "lock answer: pid %lu: %s %d", 46986299Salfred (unsigned long)ans.la_msg_ident.pid, 47075979Salfred version == NLM_VERS4 ? "nlmv4" : "nlmv3", 47175979Salfred result); 47275631Salfred 47375631Salfred ans.la_set_getlk_pid = 0; 47475631Salfred if (version == NLM_VERS4) 47575631Salfred switch (result) { 47675631Salfred case nlm4_granted: 47775631Salfred ans.la_errno = 0; 47875631Salfred break; 47975631Salfred default: 48075631Salfred ans.la_errno = EACCES; 48175631Salfred break; 48275631Salfred case nlm4_denied: 48375631Salfred if (pid_p == NULL) 484115012Srwatson ans.la_errno = EAGAIN; 48575631Salfred else { 48675631Salfred /* this is an answer to a nlm_test msg */ 48775631Salfred ans.la_set_getlk_pid = 1; 48875631Salfred ans.la_getlk_pid = *pid_p; 48975631Salfred ans.la_errno = 0; 49075631Salfred } 49175631Salfred break; 49275631Salfred case nlm4_denied_nolocks: 49375631Salfred ans.la_errno = EAGAIN; 49475631Salfred break; 49575631Salfred case nlm4_blocked: 49675631Salfred return -1; 49775631Salfred /* NOTREACHED */ 49875631Salfred case nlm4_denied_grace_period: 49975631Salfred ans.la_errno = EAGAIN; 50075631Salfred break; 50175631Salfred case nlm4_deadlck: 50275631Salfred ans.la_errno = EDEADLK; 50375631Salfred break; 50475631Salfred case nlm4_rofs: 50575631Salfred ans.la_errno = EROFS; 50675631Salfred break; 50775631Salfred case nlm4_stale_fh: 50875631Salfred ans.la_errno = ESTALE; 50975631Salfred break; 51075631Salfred case nlm4_fbig: 51175631Salfred ans.la_errno = EFBIG; 51275631Salfred break; 51375631Salfred case nlm4_failed: 51475631Salfred ans.la_errno = EACCES; 51575631Salfred break; 51675631Salfred } 51775631Salfred else 51875631Salfred switch (result) { 51975631Salfred case nlm_granted: 52075631Salfred ans.la_errno = 0; 52175631Salfred break; 52275631Salfred default: 52375631Salfred ans.la_errno = EACCES; 52475631Salfred break; 52575631Salfred case nlm_denied: 52675631Salfred if (pid_p == NULL) 527115012Srwatson ans.la_errno = EAGAIN; 52875631Salfred else { 52975631Salfred /* this is an answer to a nlm_test msg */ 53075631Salfred ans.la_set_getlk_pid = 1; 53175631Salfred ans.la_getlk_pid = *pid_p; 53275631Salfred ans.la_errno = 0; 53375631Salfred } 53475631Salfred break; 53575631Salfred case nlm_denied_nolocks: 53675631Salfred ans.la_errno = EAGAIN; 53775631Salfred break; 53875631Salfred case nlm_blocked: 53975631Salfred return -1; 54075631Salfred /* NOTREACHED */ 54175631Salfred case nlm_denied_grace_period: 54275631Salfred ans.la_errno = EAGAIN; 54375631Salfred break; 54475631Salfred case nlm_deadlck: 54575631Salfred ans.la_errno = EDEADLK; 54675631Salfred break; 54775631Salfred } 54875631Salfred 54975631Salfred if (nfslockdans(LOCKD_ANS_VERSION, &ans)) { 55075631Salfred syslog(((errno == EPIPE || errno == ESRCH) ? 55175631Salfred LOG_INFO : LOG_ERR), 55275631Salfred "process %lu: %m", (u_long)ans.la_msg_ident.pid); 55375631Salfred return -1; 55475631Salfred } 55575631Salfred return 0; 55675631Salfred} 55775631Salfred 55875631Salfred/* 55975631Salfred * show -- 56075631Salfred * Display the contents of a kernel LOCKD_MSG structure. 56175631Salfred */ 56275631Salfredvoid 56375631Salfredshow(LOCKD_MSG *mp) 56475631Salfred{ 56575631Salfred static char hex[] = "0123456789abcdef"; 56675631Salfred struct fid *fidp; 56775631Salfred fsid_t *fsidp; 56875631Salfred size_t len; 56975631Salfred u_int8_t *p, *t, buf[NFS_SMALLFH*3+1]; 57075631Salfred 57186187Salfred syslog(LOG_DEBUG, "process ID: %lu\n", (long)mp->lm_msg_ident.pid); 57275631Salfred 57375631Salfred fsidp = (fsid_t *)&mp->lm_fh; 57475631Salfred fidp = (struct fid *)((u_int8_t *)&mp->lm_fh + sizeof(fsid_t)); 57575631Salfred 57675631Salfred for (t = buf, p = (u_int8_t *)mp->lm_fh, 57775631Salfred len = mp->lm_fh_len; 57875631Salfred len > 0; ++p, --len) { 57975631Salfred *t++ = '\\'; 58075631Salfred *t++ = hex[(*p & 0xf0) >> 4]; 58175631Salfred *t++ = hex[*p & 0x0f]; 58275631Salfred } 58375631Salfred *t = '\0'; 58475631Salfred 585121558Speter syslog(LOG_DEBUG, "fh_len %d, fh %s\n", (int)mp->lm_fh_len, buf); 58675631Salfred 58775631Salfred /* Show flock structure. */ 58886187Salfred syslog(LOG_DEBUG, "start %qu; len %qu; pid %lu; type %d; whence %d\n", 589121558Speter (unsigned long long)mp->lm_fl.l_start, 590121558Speter (unsigned long long)mp->lm_fl.l_len, (u_long)mp->lm_fl.l_pid, 59175631Salfred mp->lm_fl.l_type, mp->lm_fl.l_whence); 59275631Salfred 59375631Salfred /* Show wait flag. */ 59486187Salfred syslog(LOG_DEBUG, "wait was %s\n", mp->lm_wait ? "set" : "not set"); 59575631Salfred} 596