diff options
Diffstat (limited to 'sys/nlm')
| -rw-r--r-- | sys/nlm/nlm.h | 5 | ||||
| -rw-r--r-- | sys/nlm/nlm_advlock.c | 7 | ||||
| -rw-r--r-- | sys/nlm/nlm_prot_impl.c | 178 |
3 files changed, 104 insertions, 86 deletions
diff --git a/sys/nlm/nlm.h b/sys/nlm/nlm.h index 27b921fa5cec..d2c5ee1610a5 100644 --- a/sys/nlm/nlm.h +++ b/sys/nlm/nlm.h @@ -210,6 +210,11 @@ struct vop_reclaim_args; extern int nlm_advlock(struct vop_advlock_args *ap); extern int nlm_reclaim(struct vop_reclaim_args *ap); +/* + * Acquire the next sysid for remote locks not handled by the NLM. + */ +extern uint32_t nlm_acquire_next_sysid(void); + #endif #endif diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c index 2c1f1a6f385b..761ed73ad7e5 100644 --- a/sys/nlm/nlm_advlock.c +++ b/sys/nlm/nlm_advlock.c @@ -35,15 +35,16 @@ __FBSDID("$FreeBSD$"); #include <sys/lock.h> #include <sys/lockf.h> #include <sys/malloc.h> +#include <sys/mbuf.h> #include <sys/mount.h> #include <sys/mutex.h> #include <sys/proc.h> #include <sys/syslog.h> #include <sys/systm.h> #include <sys/unistd.h> +#include <sys/vimage.h> #include <sys/vnode.h> -#include <rpc/rpcclnt.h> #include <nfs/nfsproto.h> #include <nfsclient/nfs.h> #include <nfsclient/nfsnode.h> @@ -1222,12 +1223,12 @@ nlm_init_lock(struct flock *fl, int flags, int svid, } mtx_lock(&hostname_mtx); - snprintf(oh_space, 32, "%d@%s", svid, hostname); + snprintf(oh_space, 32, "%d@%s", svid, G_hostname); mtx_unlock(&hostname_mtx); oh_len = strlen(oh_space); memset(lock, 0, sizeof(*lock)); - lock->caller_name = hostname; + lock->caller_name = G_hostname; lock->fh.n_len = fhlen; lock->fh.n_bytes = fh; lock->oh.n_len = oh_len; diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index 1add718a2c34..6ee6baa282ac 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include <sys/syscall.h> #include <sys/sysctl.h> #include <sys/sysent.h> +#include <sys/syslog.h> #include <sys/sysproto.h> #include <sys/systm.h> #include <sys/taskqueue.h> @@ -104,6 +105,16 @@ static bool_t nlm_syscall_registered = FALSE; static int nlm_debug_level; SYSCTL_INT(_debug, OID_AUTO, nlm_debug, CTLFLAG_RW, &nlm_debug_level, 0, ""); +#define NLM_DEBUG(_level, args...) \ + do { \ + if (nlm_debug_level >= (_level)) \ + log(LOG_DEBUG, args); \ + } while(0) +#define NLM_ERR(args...) \ + do { \ + log(LOG_ERR, args); \ + } while(0) + /* * Grace period handling. The value of nlm_grace_threshold is the * value of time_uptime after which we are serving requests normally. @@ -254,7 +265,7 @@ nlm_init(void *dummy) error = syscall_register(&nlm_syscall_offset, &nlm_syscall_sysent, &nlm_syscall_prev_sysent); if (error) - printf("Can't register NLM syscall\n"); + NLM_ERR("Can't register NLM syscall\n"); else nlm_syscall_registered = TRUE; } @@ -301,6 +312,7 @@ nlm_get_rpc(struct sockaddr *sa, rpcprog_t prog, rpcvers_t vers) enum clnt_stat stat = RPC_SUCCESS; int rpcvers = RPCBVERS4; bool_t do_tcp = FALSE; + bool_t tryagain = FALSE; struct portmap mapping; u_short port = 0; @@ -362,14 +374,7 @@ again: stat = CLNT_CALL(rpcb, (rpcprog_t) RPCBPROC_GETADDR, (xdrproc_t) xdr_rpcb, &parms, (xdrproc_t) xdr_wrapstring, &uaddr, timo); - if (stat == RPC_PROGVERSMISMATCH) { - if (rpcvers == RPCBVERS4) - rpcvers = RPCBVERS; - else if (rpcvers == RPCBVERS) - rpcvers = PMAPVERS; - CLNT_CONTROL(rpcb, CLSET_VERS, &rpcvers); - goto again; - } else if (stat == RPC_SUCCESS) { + if (stat == RPC_SUCCESS) { /* * We have a reply from the remote RPCBIND - turn it * into an appropriate address and make a new client @@ -380,13 +385,22 @@ again: struct netbuf *a; a = __rpc_uaddr2taddr_af(ss.ss_family, uaddr); if (!a) { - CLNT_DESTROY(rpcb); - return (NULL); + tryagain = TRUE; + } else { + tryagain = FALSE; + memcpy(&ss, a->buf, a->len); + free(a->buf, M_RPC); + free(a, M_RPC); + xdr_free((xdrproc_t) xdr_wrapstring, &uaddr); } - memcpy(&ss, a->buf, a->len); - free(a->buf, M_RPC); - free(a, M_RPC); - xdr_free((xdrproc_t) xdr_wrapstring, &uaddr); + } + if (tryagain || stat == RPC_PROGVERSMISMATCH) { + if (rpcvers == RPCBVERS4) + rpcvers = RPCBVERS; + else if (rpcvers == RPCBVERS) + rpcvers = PMAPVERS; + CLNT_CONTROL(rpcb, CLSET_VERS, &rpcvers); + goto again; } break; case PMAPVERS: @@ -450,9 +464,8 @@ again: } /* Otherwise, bad news. */ - printf("NLM: failed to contact remote rpcbind, " - "stat = %d, port = %d\n", - (int) stat, port); + NLM_ERR("NLM: failed to contact remote rpcbind, " + "stat = %d, port = %d\n", (int) stat, port); CLNT_DESTROY(rpcb); return (NULL); } @@ -506,10 +519,8 @@ nlm_lock_callback(void *arg, int pending) struct nlm_async_lock *af = (struct nlm_async_lock *) arg; struct rpc_callextra ext; - if (nlm_debug_level >= 2) - printf("NLM: async lock %p for %s (sysid %d) granted\n", - af, af->af_host->nh_caller_name, - af->af_host->nh_sysid); + NLM_DEBUG(2, "NLM: async lock %p for %s (sysid %d) granted\n", + af, af->af_host->nh_caller_name, af->af_host->nh_sysid); /* * Send the results back to the host. @@ -608,10 +619,8 @@ nlm_cancel_async_lock(struct nlm_async_lock *af) mtx_lock(&host->nh_lock); if (!error) { - if (nlm_debug_level >= 2) - printf("NLM: async lock %p for %s (sysid %d) " - "cancelled\n", - af, host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(2, "NLM: async lock %p for %s (sysid %d) " + "cancelled\n", af, host->nh_caller_name, host->nh_sysid); /* * Remove from the nh_pending list and free now that @@ -672,15 +681,13 @@ nlm_client_recovery_start(void *arg) { struct nlm_host *host = (struct nlm_host *) arg; - if (nlm_debug_level >= 1) - printf("NLM: client lock recovery for %s started\n", - host->nh_caller_name); + NLM_DEBUG(1, "NLM: client lock recovery for %s started\n", + host->nh_caller_name); nlm_client_recovery(host); - if (nlm_debug_level >= 1) - printf("NLM: client lock recovery for %s completed\n", - host->nh_caller_name); + NLM_DEBUG(1, "NLM: client lock recovery for %s completed\n", + host->nh_caller_name); host->nh_monstate = NLM_MONITORED; nlm_host_release(host); @@ -703,10 +710,9 @@ nlm_host_notify(struct nlm_host *host, int newstate) struct nlm_async_lock *af; if (newstate) { - if (nlm_debug_level >= 1) - printf("NLM: host %s (sysid %d) rebooted, new " - "state is %d\n", - host->nh_caller_name, host->nh_sysid, newstate); + NLM_DEBUG(1, "NLM: host %s (sysid %d) rebooted, new " + "state is %d\n", host->nh_caller_name, + host->nh_sysid, newstate); } /* @@ -786,9 +792,8 @@ nlm_create_host(const char* caller_name) mtx_assert(&nlm_global_lock, MA_OWNED); - if (nlm_debug_level >= 1) - printf("NLM: new host %s (sysid %d)\n", - caller_name, nlm_next_sysid); + NLM_DEBUG(1, "NLM: new host %s (sysid %d)\n", + caller_name, nlm_next_sysid); host = malloc(sizeof(struct nlm_host), M_NLM, M_NOWAIT|M_ZERO); if (!host) return (NULL); @@ -830,6 +835,20 @@ nlm_create_host(const char* caller_name) } /* + * Acquire the next sysid for remote locks not handled by the NLM. + */ +uint32_t +nlm_acquire_next_sysid(void) +{ + uint32_t next_sysid; + + mtx_lock(&nlm_global_lock); + next_sysid = nlm_next_sysid++; + mtx_unlock(&nlm_global_lock); + return (next_sysid); +} + +/* * Return non-zero if the address parts of the two sockaddrs are the * same. */ @@ -1078,9 +1097,8 @@ nlm_host_unmonitor(struct nlm_host *host) struct timeval timo; enum clnt_stat stat; - if (nlm_debug_level >= 1) - printf("NLM: unmonitoring %s (sysid %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(1, "NLM: unmonitoring %s (sysid %d)\n", + host->nh_caller_name, host->nh_sysid); /* * We put our assigned system ID value in the priv field to @@ -1100,11 +1118,11 @@ nlm_host_unmonitor(struct nlm_host *host) (xdrproc_t) xdr_sm_stat, &smstat, timo); if (stat != RPC_SUCCESS) { - printf("Failed to contact local NSM - rpc error %d\n", stat); + NLM_ERR("Failed to contact local NSM - rpc error %d\n", stat); return; } if (smstat.res_stat == stat_fail) { - printf("Local NSM refuses to unmonitor %s\n", + NLM_ERR("Local NSM refuses to unmonitor %s\n", host->nh_caller_name); return; } @@ -1131,9 +1149,8 @@ nlm_host_monitor(struct nlm_host *host, int state) * detect host reboots. */ host->nh_state = state; - if (nlm_debug_level >= 1) - printf("NLM: host %s (sysid %d) has NSM state %d\n", - host->nh_caller_name, host->nh_sysid, state); + NLM_DEBUG(1, "NLM: host %s (sysid %d) has NSM state %d\n", + host->nh_caller_name, host->nh_sysid, state); } mtx_lock(&host->nh_lock); @@ -1144,9 +1161,8 @@ nlm_host_monitor(struct nlm_host *host, int state) host->nh_monstate = NLM_MONITORED; mtx_unlock(&host->nh_lock); - if (nlm_debug_level >= 1) - printf("NLM: monitoring %s (sysid %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(1, "NLM: monitoring %s (sysid %d)\n", + host->nh_caller_name, host->nh_sysid); /* * We put our assigned system ID value in the priv field to @@ -1167,11 +1183,11 @@ nlm_host_monitor(struct nlm_host *host, int state) (xdrproc_t) xdr_sm_stat, &smstat, timo); if (stat != RPC_SUCCESS) { - printf("Failed to contact local NSM - rpc error %d\n", stat); + NLM_ERR("Failed to contact local NSM - rpc error %d\n", stat); return; } if (smstat.res_stat == stat_fail) { - printf("Local NSM refuses to monitor %s\n", + NLM_ERR("Local NSM refuses to monitor %s\n", host->nh_caller_name); mtx_lock(&host->nh_lock); host->nh_monstate = NLM_MONITOR_FAILED; @@ -1369,7 +1385,7 @@ nlm_register_services(SVCPOOL *pool, int addr_count, char **addrs) int i, j, error; if (!addr_count) { - printf("NLM: no service addresses given - can't start server"); + NLM_ERR("NLM: no service addresses given - can't start server"); return (EINVAL); } @@ -1402,7 +1418,7 @@ nlm_register_services(SVCPOOL *pool, int addr_count, char **addrs) goto out; nconf = getnetconfigent(netid); if (!nconf) { - printf("Can't lookup netid %s\n", + NLM_ERR("Can't lookup netid %s\n", netid); error = EINVAL; goto out; @@ -1410,7 +1426,7 @@ nlm_register_services(SVCPOOL *pool, int addr_count, char **addrs) xprts[j] = svc_tp_create(pool, dispatchers[i], NLM_PROG, versions[i], uaddr, nconf); if (!xprts[j]) { - printf("NLM: unable to create " + NLM_ERR("NLM: unable to create " "(NLM_PROG, %d).\n", versions[i]); error = EINVAL; goto out; @@ -1421,7 +1437,7 @@ nlm_register_services(SVCPOOL *pool, int addr_count, char **addrs) rpcb_unset(NLM_PROG, versions[i], nconf); if (!svc_reg(xprts[j], NLM_PROG, versions[i], dispatchers[i], nconf)) { - printf("NLM: can't register " + NLM_ERR("NLM: can't register " "(NLM_PROG, %d)\n", versions[i]); error = EINVAL; goto out; @@ -1469,7 +1485,8 @@ nlm_server_main(int addr_count, char **addrs) #endif if (nlm_socket) { - printf("NLM: can't start server - it appears to be running already\n"); + NLM_ERR("NLM: can't start server - " + "it appears to be running already\n"); return (EPERM); } @@ -1479,7 +1496,7 @@ nlm_server_main(int addr_count, char **addrs) error = socreate(AF_INET, &nlm_socket, SOCK_DGRAM, 0, td->td_ucred, td); if (error) { - printf("NLM: can't create IPv4 socket - error %d\n", error); + NLM_ERR("NLM: can't create IPv4 socket - error %d\n", error); return (error); } opt.sopt_dir = SOPT_SET; @@ -1495,7 +1512,7 @@ nlm_server_main(int addr_count, char **addrs) error = socreate(AF_INET6, &nlm_socket6, SOCK_DGRAM, 0, td->td_ucred, td); if (error) { - printf("NLM: can't create IPv6 socket - error %d\n", error); + NLM_ERR("NLM: can't create IPv6 socket - error %d\n", error); goto out; return (error); } @@ -1529,7 +1546,7 @@ nlm_server_main(int addr_count, char **addrs) #endif if (!nlm_nsm) { - printf("Can't start NLM - unable to contact NSM\n"); + NLM_ERR("Can't start NLM - unable to contact NSM\n"); error = EINVAL; goto out; } @@ -1553,14 +1570,13 @@ nlm_server_main(int addr_count, char **addrs) struct rpc_err err; CLNT_GETERR(nlm_nsm, &err); - printf("NLM: unexpected error contacting NSM, stat=%d, errno=%d\n", - stat, err.re_errno); + NLM_ERR("NLM: unexpected error contacting NSM, " + "stat=%d, errno=%d\n", stat, err.re_errno); error = EINVAL; goto out; } - if (nlm_debug_level >= 1) - printf("NLM: local NSM state is %d\n", smstat.state); + NLM_DEBUG(1, "NLM: local NSM state is %d\n", smstat.state); nlm_nsm_state = smstat.state; #ifdef NFSCLIENT @@ -1692,8 +1708,7 @@ nlm_sm_notify(struct nlm_sm_status *argp) uint32_t sysid; struct nlm_host *host; - if (nlm_debug_level >= 3) - printf("nlm_sm_notify(): mon_name = %s\n", argp->mon_name); + NLM_DEBUG(3, "nlm_sm_notify(): mon_name = %s\n", argp->mon_name); memcpy(&sysid, &argp->priv, sizeof(sysid)); host = nlm_find_host_by_sysid(sysid); if (host) { @@ -1751,7 +1766,8 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp, } if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) { crfree(cred); - cred = crhold(credanon); + cred = credanon; + credanon = NULL; } /* @@ -1771,6 +1787,8 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp, out: if (cred) crfree(cred); + if (credanon) + crfree(credanon); return (error); } @@ -1822,9 +1840,8 @@ nlm_do_test(nlm4_testargs *argp, nlm4_testres *result, struct svc_req *rqstp, return (ENOMEM); } - if (nlm_debug_level >= 3) - printf("nlm_do_test(): caller_name = %s (sysid = %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(3, "nlm_do_test(): caller_name = %s (sysid = %d)\n", + host->nh_caller_name, host->nh_sysid); nlm_free_finished_locks(host); sysid = host->nh_sysid; @@ -1919,9 +1936,8 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, return (ENOMEM); } - if (nlm_debug_level >= 3) - printf("nlm_do_lock(): caller_name = %s (sysid = %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(3, "nlm_do_lock(): caller_name = %s (sysid = %d)\n", + host->nh_caller_name, host->nh_sysid); if (monitor && host->nh_state && argp->state && host->nh_state != argp->state) { @@ -2043,10 +2059,8 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, &af->af_granted); free(af, M_NLM); } else { - if (nlm_debug_level >= 2) - printf("NLM: pending async lock %p for %s " - "(sysid %d)\n", - af, host->nh_caller_name, sysid); + NLM_DEBUG(2, "NLM: pending async lock %p for %s " + "(sysid %d)\n", af, host->nh_caller_name, sysid); /* * Don't vrele the vnode just yet - this must * wait until either the async callback @@ -2103,9 +2117,8 @@ nlm_do_cancel(nlm4_cancargs *argp, nlm4_res *result, struct svc_req *rqstp, return (ENOMEM); } - if (nlm_debug_level >= 3) - printf("nlm_do_cancel(): caller_name = %s (sysid = %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(3, "nlm_do_cancel(): caller_name = %s (sysid = %d)\n", + host->nh_caller_name, host->nh_sysid); nlm_free_finished_locks(host); sysid = host->nh_sysid; @@ -2193,9 +2206,8 @@ nlm_do_unlock(nlm4_unlockargs *argp, nlm4_res *result, struct svc_req *rqstp, return (ENOMEM); } - if (nlm_debug_level >= 3) - printf("nlm_do_unlock(): caller_name = %s (sysid = %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(3, "nlm_do_unlock(): caller_name = %s (sysid = %d)\n", + host->nh_caller_name, host->nh_sysid); nlm_free_finished_locks(host); sysid = host->nh_sysid; |
