xref: /titanic_52/usr/src/uts/common/klm/klmmod.c (revision bbaa8b60dd95d714741fc474adad3cf710ef4efd)
1*bbaa8b60SDan Kruchinin /*
2*bbaa8b60SDan Kruchinin  * This file and its contents are supplied under the terms of the
3*bbaa8b60SDan Kruchinin  * Common Development and Distribution License ("CDDL"), version 1.0.
4*bbaa8b60SDan Kruchinin  * You may only use this file in accordance with the terms of version
5*bbaa8b60SDan Kruchinin  * 1.0 of the CDDL.
6*bbaa8b60SDan Kruchinin  *
7*bbaa8b60SDan Kruchinin  * A full copy of the text of the CDDL should have accompanied this
8*bbaa8b60SDan Kruchinin  * source.  A copy is of the CDDL is also available via the Internet
9*bbaa8b60SDan Kruchinin  * at http://www.illumos.org/license/CDDL.
10*bbaa8b60SDan Kruchinin  */
11*bbaa8b60SDan Kruchinin 
12*bbaa8b60SDan Kruchinin /*
13*bbaa8b60SDan Kruchinin  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
14*bbaa8b60SDan Kruchinin  * Copyright (c) 2012 by Delphix. All rights reserved.
15*bbaa8b60SDan Kruchinin  */
16*bbaa8b60SDan Kruchinin 
17*bbaa8b60SDan Kruchinin /*
18*bbaa8b60SDan Kruchinin  * NFS Lock Manager, server-side and common.
19*bbaa8b60SDan Kruchinin  *
20*bbaa8b60SDan Kruchinin  * This file contains all the external entry points of klmmod.
21*bbaa8b60SDan Kruchinin  * Basically, this is the "glue" to the BSD nlm code.
22*bbaa8b60SDan Kruchinin  */
23*bbaa8b60SDan Kruchinin 
24*bbaa8b60SDan Kruchinin #include <sys/types.h>
25*bbaa8b60SDan Kruchinin #include <sys/errno.h>
26*bbaa8b60SDan Kruchinin #include <sys/modctl.h>
27*bbaa8b60SDan Kruchinin #include <sys/flock.h>
28*bbaa8b60SDan Kruchinin 
29*bbaa8b60SDan Kruchinin #include <nfs/nfs.h>
30*bbaa8b60SDan Kruchinin #include <nfs/nfssys.h>
31*bbaa8b60SDan Kruchinin #include <nfs/lm.h>
32*bbaa8b60SDan Kruchinin #include <rpcsvc/nlm_prot.h>
33*bbaa8b60SDan Kruchinin #include "nlm_impl.h"
34*bbaa8b60SDan Kruchinin 
35*bbaa8b60SDan Kruchinin static struct modlmisc modlmisc = {
36*bbaa8b60SDan Kruchinin 	&mod_miscops, "lock mgr common module"
37*bbaa8b60SDan Kruchinin };
38*bbaa8b60SDan Kruchinin 
39*bbaa8b60SDan Kruchinin static struct modlinkage modlinkage = {
40*bbaa8b60SDan Kruchinin 	MODREV_1, &modlmisc, NULL
41*bbaa8b60SDan Kruchinin };
42*bbaa8b60SDan Kruchinin 
43*bbaa8b60SDan Kruchinin /*
44*bbaa8b60SDan Kruchinin  * Cluster node ID.  Zero unless we're part of a cluster.
45*bbaa8b60SDan Kruchinin  * Set by lm_set_nlmid_flk.  Pass to lm_set_nlm_status.
46*bbaa8b60SDan Kruchinin  * We're not yet doing "clustered" NLM stuff.
47*bbaa8b60SDan Kruchinin  */
48*bbaa8b60SDan Kruchinin int lm_global_nlmid = 0;
49*bbaa8b60SDan Kruchinin 
50*bbaa8b60SDan Kruchinin /*
51*bbaa8b60SDan Kruchinin  * Call-back hook for clusters: Set lock manager status.
52*bbaa8b60SDan Kruchinin  * If this hook is set, call this instead of the ususal
53*bbaa8b60SDan Kruchinin  * flk_set_lockmgr_status(FLK_LOCKMGR_UP / DOWN);
54*bbaa8b60SDan Kruchinin  */
55*bbaa8b60SDan Kruchinin void (*lm_set_nlm_status)(int nlm_id, flk_nlm_status_t) = NULL;
56*bbaa8b60SDan Kruchinin 
57*bbaa8b60SDan Kruchinin /*
58*bbaa8b60SDan Kruchinin  * Call-back hook for clusters: Delete all locks held by sysid.
59*bbaa8b60SDan Kruchinin  * Call from code that drops all client locks (for which we're
60*bbaa8b60SDan Kruchinin  * the server) i.e. after the SM tells us a client has crashed.
61*bbaa8b60SDan Kruchinin  */
62*bbaa8b60SDan Kruchinin void (*lm_remove_file_locks)(int) = NULL;
63*bbaa8b60SDan Kruchinin 
64*bbaa8b60SDan Kruchinin krwlock_t		lm_lck;
65*bbaa8b60SDan Kruchinin zone_key_t		nlm_zone_key;
66*bbaa8b60SDan Kruchinin 
67*bbaa8b60SDan Kruchinin /*
68*bbaa8b60SDan Kruchinin  * Init/fini per-zone stuff for klm
69*bbaa8b60SDan Kruchinin  */
70*bbaa8b60SDan Kruchinin /* ARGSUSED */
71*bbaa8b60SDan Kruchinin void *
72*bbaa8b60SDan Kruchinin lm_zone_init(zoneid_t zoneid)
73*bbaa8b60SDan Kruchinin {
74*bbaa8b60SDan Kruchinin 	struct nlm_globals *g;
75*bbaa8b60SDan Kruchinin 
76*bbaa8b60SDan Kruchinin 	g = kmem_zalloc(sizeof (*g), KM_SLEEP);
77*bbaa8b60SDan Kruchinin 
78*bbaa8b60SDan Kruchinin 	avl_create(&g->nlm_hosts_tree, nlm_host_cmp,
79*bbaa8b60SDan Kruchinin 	    sizeof (struct nlm_host),
80*bbaa8b60SDan Kruchinin 	    offsetof(struct nlm_host, nh_by_addr));
81*bbaa8b60SDan Kruchinin 
82*bbaa8b60SDan Kruchinin 	g->nlm_hosts_hash = mod_hash_create_idhash("nlm_host_by_sysid",
83*bbaa8b60SDan Kruchinin 	    64, mod_hash_null_valdtor);
84*bbaa8b60SDan Kruchinin 
85*bbaa8b60SDan Kruchinin 	TAILQ_INIT(&g->nlm_idle_hosts);
86*bbaa8b60SDan Kruchinin 	TAILQ_INIT(&g->nlm_slocks);
87*bbaa8b60SDan Kruchinin 
88*bbaa8b60SDan Kruchinin 	mutex_init(&g->lock, NULL, MUTEX_DEFAULT, NULL);
89*bbaa8b60SDan Kruchinin 	cv_init(&g->nlm_gc_sched_cv, NULL, CV_DEFAULT, NULL);
90*bbaa8b60SDan Kruchinin 	cv_init(&g->nlm_gc_finish_cv, NULL, CV_DEFAULT, NULL);
91*bbaa8b60SDan Kruchinin 	mutex_init(&g->clean_lock, NULL, MUTEX_DEFAULT, NULL);
92*bbaa8b60SDan Kruchinin 
93*bbaa8b60SDan Kruchinin 	g->lockd_pid = 0;
94*bbaa8b60SDan Kruchinin 	g->run_status = NLM_ST_DOWN;
95*bbaa8b60SDan Kruchinin 
96*bbaa8b60SDan Kruchinin 	nlm_globals_register(g);
97*bbaa8b60SDan Kruchinin 	return (g);
98*bbaa8b60SDan Kruchinin }
99*bbaa8b60SDan Kruchinin 
100*bbaa8b60SDan Kruchinin /* ARGSUSED */
101*bbaa8b60SDan Kruchinin void
102*bbaa8b60SDan Kruchinin lm_zone_fini(zoneid_t zoneid, void *data)
103*bbaa8b60SDan Kruchinin {
104*bbaa8b60SDan Kruchinin 	struct nlm_globals *g = data;
105*bbaa8b60SDan Kruchinin 
106*bbaa8b60SDan Kruchinin 	ASSERT(avl_is_empty(&g->nlm_hosts_tree));
107*bbaa8b60SDan Kruchinin 	avl_destroy(&g->nlm_hosts_tree);
108*bbaa8b60SDan Kruchinin 	mod_hash_destroy_idhash(g->nlm_hosts_hash);
109*bbaa8b60SDan Kruchinin 
110*bbaa8b60SDan Kruchinin 	ASSERT(g->nlm_gc_thread == NULL);
111*bbaa8b60SDan Kruchinin 	mutex_destroy(&g->lock);
112*bbaa8b60SDan Kruchinin 	cv_destroy(&g->nlm_gc_sched_cv);
113*bbaa8b60SDan Kruchinin 	cv_destroy(&g->nlm_gc_finish_cv);
114*bbaa8b60SDan Kruchinin 	mutex_destroy(&g->clean_lock);
115*bbaa8b60SDan Kruchinin 
116*bbaa8b60SDan Kruchinin 	nlm_globals_unregister(g);
117*bbaa8b60SDan Kruchinin 	kmem_free(g, sizeof (*g));
118*bbaa8b60SDan Kruchinin }
119*bbaa8b60SDan Kruchinin 
120*bbaa8b60SDan Kruchinin 
121*bbaa8b60SDan Kruchinin 
122*bbaa8b60SDan Kruchinin /*
123*bbaa8b60SDan Kruchinin  * ****************************************************************
124*bbaa8b60SDan Kruchinin  * module init, fini, info
125*bbaa8b60SDan Kruchinin  */
126*bbaa8b60SDan Kruchinin int
127*bbaa8b60SDan Kruchinin _init()
128*bbaa8b60SDan Kruchinin {
129*bbaa8b60SDan Kruchinin 	int retval;
130*bbaa8b60SDan Kruchinin 
131*bbaa8b60SDan Kruchinin 	rw_init(&lm_lck, NULL, RW_DEFAULT, NULL);
132*bbaa8b60SDan Kruchinin 	nlm_init();
133*bbaa8b60SDan Kruchinin 
134*bbaa8b60SDan Kruchinin 	zone_key_create(&nlm_zone_key, lm_zone_init, NULL, lm_zone_fini);
135*bbaa8b60SDan Kruchinin 	/* Per-zone lockmgr data.  See: os/flock.c */
136*bbaa8b60SDan Kruchinin 	zone_key_create(&flock_zone_key, flk_zone_init, NULL, flk_zone_fini);
137*bbaa8b60SDan Kruchinin 
138*bbaa8b60SDan Kruchinin 	retval = mod_install(&modlinkage);
139*bbaa8b60SDan Kruchinin 	if (retval == 0)
140*bbaa8b60SDan Kruchinin 		return (0);
141*bbaa8b60SDan Kruchinin 
142*bbaa8b60SDan Kruchinin 	/*
143*bbaa8b60SDan Kruchinin 	 * mod_install failed! undo above, reverse order
144*bbaa8b60SDan Kruchinin 	 */
145*bbaa8b60SDan Kruchinin 
146*bbaa8b60SDan Kruchinin 	(void) zone_key_delete(flock_zone_key);
147*bbaa8b60SDan Kruchinin 	flock_zone_key = ZONE_KEY_UNINITIALIZED;
148*bbaa8b60SDan Kruchinin 	(void) zone_key_delete(nlm_zone_key);
149*bbaa8b60SDan Kruchinin 	rw_destroy(&lm_lck);
150*bbaa8b60SDan Kruchinin 
151*bbaa8b60SDan Kruchinin 	return (retval);
152*bbaa8b60SDan Kruchinin }
153*bbaa8b60SDan Kruchinin 
154*bbaa8b60SDan Kruchinin int
155*bbaa8b60SDan Kruchinin _fini()
156*bbaa8b60SDan Kruchinin {
157*bbaa8b60SDan Kruchinin 	/* Don't unload. */
158*bbaa8b60SDan Kruchinin 	return (EBUSY);
159*bbaa8b60SDan Kruchinin }
160*bbaa8b60SDan Kruchinin 
161*bbaa8b60SDan Kruchinin int
162*bbaa8b60SDan Kruchinin _info(struct modinfo *modinfop)
163*bbaa8b60SDan Kruchinin {
164*bbaa8b60SDan Kruchinin 	return (mod_info(&modlinkage, modinfop));
165*bbaa8b60SDan Kruchinin }
166*bbaa8b60SDan Kruchinin 
167*bbaa8b60SDan Kruchinin 
168*bbaa8b60SDan Kruchinin 
169*bbaa8b60SDan Kruchinin /*
170*bbaa8b60SDan Kruchinin  * ****************************************************************
171*bbaa8b60SDan Kruchinin  * Stubs listed in modstubs.s
172*bbaa8b60SDan Kruchinin  */
173*bbaa8b60SDan Kruchinin 
174*bbaa8b60SDan Kruchinin /*
175*bbaa8b60SDan Kruchinin  * klm system calls.  Start service on some endpoint.
176*bbaa8b60SDan Kruchinin  * Called by nfssys() LM_SVC, from lockd.
177*bbaa8b60SDan Kruchinin  */
178*bbaa8b60SDan Kruchinin int
179*bbaa8b60SDan Kruchinin lm_svc(struct lm_svc_args *args)
180*bbaa8b60SDan Kruchinin {
181*bbaa8b60SDan Kruchinin 	struct knetconfig knc;
182*bbaa8b60SDan Kruchinin 	const char *netid;
183*bbaa8b60SDan Kruchinin 	struct nlm_globals *g;
184*bbaa8b60SDan Kruchinin 	struct file *fp = NULL;
185*bbaa8b60SDan Kruchinin 	int err = 0;
186*bbaa8b60SDan Kruchinin 
187*bbaa8b60SDan Kruchinin 	/* Get our "globals" */
188*bbaa8b60SDan Kruchinin 	g = zone_getspecific(nlm_zone_key, curzone);
189*bbaa8b60SDan Kruchinin 
190*bbaa8b60SDan Kruchinin 	/*
191*bbaa8b60SDan Kruchinin 	 * Check version of lockd calling.
192*bbaa8b60SDan Kruchinin 	 */
193*bbaa8b60SDan Kruchinin 	if (args->version != LM_SVC_CUR_VERS) {
194*bbaa8b60SDan Kruchinin 		NLM_ERR("lm_svc: Version mismatch "
195*bbaa8b60SDan Kruchinin 		    "(given 0x%x, expected 0x%x)\n",
196*bbaa8b60SDan Kruchinin 		    args->version, LM_SVC_CUR_VERS);
197*bbaa8b60SDan Kruchinin 		return (EINVAL);
198*bbaa8b60SDan Kruchinin 	}
199*bbaa8b60SDan Kruchinin 
200*bbaa8b60SDan Kruchinin 	/*
201*bbaa8b60SDan Kruchinin 	 * Build knetconfig, checking arg values.
202*bbaa8b60SDan Kruchinin 	 * Also come up with the "netid" string.
203*bbaa8b60SDan Kruchinin 	 * (With some knowledge of /etc/netconfig)
204*bbaa8b60SDan Kruchinin 	 */
205*bbaa8b60SDan Kruchinin 	bzero(&knc, sizeof (knc));
206*bbaa8b60SDan Kruchinin 	switch (args->n_proto) {
207*bbaa8b60SDan Kruchinin 	case LM_TCP:
208*bbaa8b60SDan Kruchinin 		knc.knc_semantics = NC_TPI_COTS_ORD;
209*bbaa8b60SDan Kruchinin 		knc.knc_proto = NC_TCP;
210*bbaa8b60SDan Kruchinin 		break;
211*bbaa8b60SDan Kruchinin 	case LM_UDP:
212*bbaa8b60SDan Kruchinin 		knc.knc_semantics = NC_TPI_CLTS;
213*bbaa8b60SDan Kruchinin 		knc.knc_proto = NC_UDP;
214*bbaa8b60SDan Kruchinin 		break;
215*bbaa8b60SDan Kruchinin 	default:
216*bbaa8b60SDan Kruchinin 		NLM_ERR("nlm_build_knetconfig: Unknown "
217*bbaa8b60SDan Kruchinin 		    "lm_proto=0x%x\n", args->n_proto);
218*bbaa8b60SDan Kruchinin 		return (EINVAL);
219*bbaa8b60SDan Kruchinin 	}
220*bbaa8b60SDan Kruchinin 
221*bbaa8b60SDan Kruchinin 	switch (args->n_fmly) {
222*bbaa8b60SDan Kruchinin 	case LM_INET:
223*bbaa8b60SDan Kruchinin 		knc.knc_protofmly = NC_INET;
224*bbaa8b60SDan Kruchinin 		break;
225*bbaa8b60SDan Kruchinin 	case LM_INET6:
226*bbaa8b60SDan Kruchinin 		knc.knc_protofmly = NC_INET6;
227*bbaa8b60SDan Kruchinin 		break;
228*bbaa8b60SDan Kruchinin 	case LM_LOOPBACK:
229*bbaa8b60SDan Kruchinin 		knc.knc_protofmly = NC_LOOPBACK;
230*bbaa8b60SDan Kruchinin 		/* Override what we set above. */
231*bbaa8b60SDan Kruchinin 		knc.knc_proto = NC_NOPROTO;
232*bbaa8b60SDan Kruchinin 		break;
233*bbaa8b60SDan Kruchinin 	default:
234*bbaa8b60SDan Kruchinin 		NLM_ERR("nlm_build_knetconfig: Unknown "
235*bbaa8b60SDan Kruchinin 		    "lm_fmly=0x%x\n", args->n_fmly);
236*bbaa8b60SDan Kruchinin 		return (EINVAL);
237*bbaa8b60SDan Kruchinin 	}
238*bbaa8b60SDan Kruchinin 
239*bbaa8b60SDan Kruchinin 	knc.knc_rdev = args->n_rdev;
240*bbaa8b60SDan Kruchinin 	netid = nlm_knc_to_netid(&knc);
241*bbaa8b60SDan Kruchinin 	if (!netid)
242*bbaa8b60SDan Kruchinin 		return (EINVAL);
243*bbaa8b60SDan Kruchinin 
244*bbaa8b60SDan Kruchinin 	/*
245*bbaa8b60SDan Kruchinin 	 * Setup service on the passed transport.
246*bbaa8b60SDan Kruchinin 	 * NB: must releasef(fp) after this.
247*bbaa8b60SDan Kruchinin 	 */
248*bbaa8b60SDan Kruchinin 	if ((fp = getf(args->fd)) == NULL)
249*bbaa8b60SDan Kruchinin 		return (EBADF);
250*bbaa8b60SDan Kruchinin 
251*bbaa8b60SDan Kruchinin 	mutex_enter(&g->lock);
252*bbaa8b60SDan Kruchinin 	/*
253*bbaa8b60SDan Kruchinin 	 * Don't try to start while still shutting down,
254*bbaa8b60SDan Kruchinin 	 * or lots of things will fail...
255*bbaa8b60SDan Kruchinin 	 */
256*bbaa8b60SDan Kruchinin 	if (g->run_status == NLM_ST_STOPPING) {
257*bbaa8b60SDan Kruchinin 		err = EAGAIN;
258*bbaa8b60SDan Kruchinin 		goto out;
259*bbaa8b60SDan Kruchinin 	}
260*bbaa8b60SDan Kruchinin 
261*bbaa8b60SDan Kruchinin 	/*
262*bbaa8b60SDan Kruchinin 	 * There is no separate "initialize" sub-call for nfssys,
263*bbaa8b60SDan Kruchinin 	 * and we want to do some one-time work when the first
264*bbaa8b60SDan Kruchinin 	 * binding comes in from lockd.
265*bbaa8b60SDan Kruchinin 	 */
266*bbaa8b60SDan Kruchinin 	if (g->run_status == NLM_ST_DOWN) {
267*bbaa8b60SDan Kruchinin 		g->run_status = NLM_ST_STARTING;
268*bbaa8b60SDan Kruchinin 		g->lockd_pid = curproc->p_pid;
269*bbaa8b60SDan Kruchinin 
270*bbaa8b60SDan Kruchinin 		/* Save the options. */
271*bbaa8b60SDan Kruchinin 		g->cn_idle_tmo = args->timout;
272*bbaa8b60SDan Kruchinin 		g->grace_period = args->grace;
273*bbaa8b60SDan Kruchinin 		g->retrans_tmo = args->retransmittimeout;
274*bbaa8b60SDan Kruchinin 
275*bbaa8b60SDan Kruchinin 		/* See nfs_sys.c (not yet per-zone) */
276*bbaa8b60SDan Kruchinin 		if (INGLOBALZONE(curproc)) {
277*bbaa8b60SDan Kruchinin 			rfs4_grace_period = args->grace;
278*bbaa8b60SDan Kruchinin 			rfs4_lease_time   = args->grace;
279*bbaa8b60SDan Kruchinin 		}
280*bbaa8b60SDan Kruchinin 
281*bbaa8b60SDan Kruchinin 		mutex_exit(&g->lock);
282*bbaa8b60SDan Kruchinin 		err = nlm_svc_starting(g, fp, netid, &knc);
283*bbaa8b60SDan Kruchinin 		mutex_enter(&g->lock);
284*bbaa8b60SDan Kruchinin 	} else {
285*bbaa8b60SDan Kruchinin 		/*
286*bbaa8b60SDan Kruchinin 		 * If KLM is not started and the very first endpoint lockd
287*bbaa8b60SDan Kruchinin 		 * tries to add is not a loopback device, report an error.
288*bbaa8b60SDan Kruchinin 		 */
289*bbaa8b60SDan Kruchinin 		if (g->run_status != NLM_ST_UP) {
290*bbaa8b60SDan Kruchinin 			err = ENOTACTIVE;
291*bbaa8b60SDan Kruchinin 			goto out;
292*bbaa8b60SDan Kruchinin 		}
293*bbaa8b60SDan Kruchinin 		if (g->lockd_pid != curproc->p_pid) {
294*bbaa8b60SDan Kruchinin 			/* Check if caller has the same PID lockd does */
295*bbaa8b60SDan Kruchinin 			err = EPERM;
296*bbaa8b60SDan Kruchinin 			goto out;
297*bbaa8b60SDan Kruchinin 		}
298*bbaa8b60SDan Kruchinin 
299*bbaa8b60SDan Kruchinin 		err = nlm_svc_add_ep(fp, netid, &knc);
300*bbaa8b60SDan Kruchinin 	}
301*bbaa8b60SDan Kruchinin 
302*bbaa8b60SDan Kruchinin out:
303*bbaa8b60SDan Kruchinin 	mutex_exit(&g->lock);
304*bbaa8b60SDan Kruchinin 	if (fp != NULL)
305*bbaa8b60SDan Kruchinin 		releasef(args->fd);
306*bbaa8b60SDan Kruchinin 
307*bbaa8b60SDan Kruchinin 	return (err);
308*bbaa8b60SDan Kruchinin }
309*bbaa8b60SDan Kruchinin 
310*bbaa8b60SDan Kruchinin /*
311*bbaa8b60SDan Kruchinin  * klm system calls.  Kill the lock manager.
312*bbaa8b60SDan Kruchinin  * Called by nfssys() KILL_LOCKMGR,
313*bbaa8b60SDan Kruchinin  * liblm:lm_shutdown() <- unused?
314*bbaa8b60SDan Kruchinin  */
315*bbaa8b60SDan Kruchinin int
316*bbaa8b60SDan Kruchinin lm_shutdown(void)
317*bbaa8b60SDan Kruchinin {
318*bbaa8b60SDan Kruchinin 	struct nlm_globals *g;
319*bbaa8b60SDan Kruchinin 	proc_t *p;
320*bbaa8b60SDan Kruchinin 	pid_t pid;
321*bbaa8b60SDan Kruchinin 
322*bbaa8b60SDan Kruchinin 	/* Get our "globals" */
323*bbaa8b60SDan Kruchinin 	g = zone_getspecific(nlm_zone_key, curzone);
324*bbaa8b60SDan Kruchinin 
325*bbaa8b60SDan Kruchinin 	mutex_enter(&g->lock);
326*bbaa8b60SDan Kruchinin 	if (g->run_status != NLM_ST_UP) {
327*bbaa8b60SDan Kruchinin 		mutex_exit(&g->lock);
328*bbaa8b60SDan Kruchinin 		return (EBUSY);
329*bbaa8b60SDan Kruchinin 	}
330*bbaa8b60SDan Kruchinin 
331*bbaa8b60SDan Kruchinin 	g->run_status = NLM_ST_STOPPING;
332*bbaa8b60SDan Kruchinin 	pid = g->lockd_pid;
333*bbaa8b60SDan Kruchinin 	mutex_exit(&g->lock);
334*bbaa8b60SDan Kruchinin 	nlm_svc_stopping(g);
335*bbaa8b60SDan Kruchinin 
336*bbaa8b60SDan Kruchinin 	mutex_enter(&pidlock);
337*bbaa8b60SDan Kruchinin 	p = prfind(pid);
338*bbaa8b60SDan Kruchinin 	if (p != NULL)
339*bbaa8b60SDan Kruchinin 		psignal(p, SIGTERM);
340*bbaa8b60SDan Kruchinin 
341*bbaa8b60SDan Kruchinin 	mutex_exit(&pidlock);
342*bbaa8b60SDan Kruchinin 	return (0);
343*bbaa8b60SDan Kruchinin }
344*bbaa8b60SDan Kruchinin 
345*bbaa8b60SDan Kruchinin /*
346*bbaa8b60SDan Kruchinin  * Cleanup remote locks on FS un-export.
347*bbaa8b60SDan Kruchinin  *
348*bbaa8b60SDan Kruchinin  * NOTE: called from nfs_export.c:unexport()
349*bbaa8b60SDan Kruchinin  * right before the share is going to
350*bbaa8b60SDan Kruchinin  * be unexported.
351*bbaa8b60SDan Kruchinin  */
352*bbaa8b60SDan Kruchinin void
353*bbaa8b60SDan Kruchinin lm_unexport(struct exportinfo *exi)
354*bbaa8b60SDan Kruchinin {
355*bbaa8b60SDan Kruchinin 	nlm_unexport(exi);
356*bbaa8b60SDan Kruchinin }
357*bbaa8b60SDan Kruchinin 
358*bbaa8b60SDan Kruchinin /*
359*bbaa8b60SDan Kruchinin  * CPR suspend/resume hooks.
360*bbaa8b60SDan Kruchinin  * See:cpr_suspend, cpr_resume
361*bbaa8b60SDan Kruchinin  *
362*bbaa8b60SDan Kruchinin  * Before suspend, get current state from "statd" on
363*bbaa8b60SDan Kruchinin  * all remote systems for which we have locks.
364*bbaa8b60SDan Kruchinin  *
365*bbaa8b60SDan Kruchinin  * After resume, check with those systems again,
366*bbaa8b60SDan Kruchinin  * and either reclaim locks, or do SIGLOST.
367*bbaa8b60SDan Kruchinin  */
368*bbaa8b60SDan Kruchinin void
369*bbaa8b60SDan Kruchinin lm_cprsuspend(void)
370*bbaa8b60SDan Kruchinin {
371*bbaa8b60SDan Kruchinin 	nlm_cprsuspend();
372*bbaa8b60SDan Kruchinin }
373*bbaa8b60SDan Kruchinin 
374*bbaa8b60SDan Kruchinin void
375*bbaa8b60SDan Kruchinin lm_cprresume(void)
376*bbaa8b60SDan Kruchinin {
377*bbaa8b60SDan Kruchinin 	nlm_cprresume();
378*bbaa8b60SDan Kruchinin }
379*bbaa8b60SDan Kruchinin 
380*bbaa8b60SDan Kruchinin /*
381*bbaa8b60SDan Kruchinin  * Add the nlm_id bits to the sysid (by ref).
382*bbaa8b60SDan Kruchinin  */
383*bbaa8b60SDan Kruchinin void
384*bbaa8b60SDan Kruchinin lm_set_nlmid_flk(int *new_sysid)
385*bbaa8b60SDan Kruchinin {
386*bbaa8b60SDan Kruchinin 	if (lm_global_nlmid != 0)
387*bbaa8b60SDan Kruchinin 		*new_sysid |= (lm_global_nlmid << BITS_IN_SYSID);
388*bbaa8b60SDan Kruchinin }
389*bbaa8b60SDan Kruchinin 
390*bbaa8b60SDan Kruchinin /*
391*bbaa8b60SDan Kruchinin  * It seems that closed source klmmod used
392*bbaa8b60SDan Kruchinin  * this function to release knetconfig stored
393*bbaa8b60SDan Kruchinin  * in mntinfo structure (see mntinfo's mi_klmconfig
394*bbaa8b60SDan Kruchinin  * field).
395*bbaa8b60SDan Kruchinin  * We store knetconfigs differently, thus we don't
396*bbaa8b60SDan Kruchinin  * need this function.
397*bbaa8b60SDan Kruchinin  */
398*bbaa8b60SDan Kruchinin void
399*bbaa8b60SDan Kruchinin lm_free_config(struct knetconfig *knc)
400*bbaa8b60SDan Kruchinin {
401*bbaa8b60SDan Kruchinin 	_NOTE(ARGUNUSED(knc));
402*bbaa8b60SDan Kruchinin }
403*bbaa8b60SDan Kruchinin 
404*bbaa8b60SDan Kruchinin /*
405*bbaa8b60SDan Kruchinin  * Called by NFS4 delegation code to check if there are any
406*bbaa8b60SDan Kruchinin  * NFSv2/v3 locks for the file, so it should not delegate.
407*bbaa8b60SDan Kruchinin  *
408*bbaa8b60SDan Kruchinin  * NOTE: called from NFSv4 code
409*bbaa8b60SDan Kruchinin  * (see nfs4_srv_deleg.c:rfs4_bgrant_delegation())
410*bbaa8b60SDan Kruchinin  */
411*bbaa8b60SDan Kruchinin int
412*bbaa8b60SDan Kruchinin lm_vp_active(const vnode_t *vp)
413*bbaa8b60SDan Kruchinin {
414*bbaa8b60SDan Kruchinin 	return (nlm_vp_active(vp));
415*bbaa8b60SDan Kruchinin }
416*bbaa8b60SDan Kruchinin 
417*bbaa8b60SDan Kruchinin /*
418*bbaa8b60SDan Kruchinin  * Find or create a "sysid" for given knc+addr.
419*bbaa8b60SDan Kruchinin  * name is optional.  Sets nc_changed if the
420*bbaa8b60SDan Kruchinin  * found knc_proto is different from passed.
421*bbaa8b60SDan Kruchinin  * Increments the reference count.
422*bbaa8b60SDan Kruchinin  *
423*bbaa8b60SDan Kruchinin  * Called internally, and in nfs4_find_sysid()
424*bbaa8b60SDan Kruchinin  */
425*bbaa8b60SDan Kruchinin struct lm_sysid *
426*bbaa8b60SDan Kruchinin lm_get_sysid(struct knetconfig *knc, struct netbuf *addr,
427*bbaa8b60SDan Kruchinin     char *name, bool_t *nc_changed)
428*bbaa8b60SDan Kruchinin {
429*bbaa8b60SDan Kruchinin 	struct nlm_globals *g;
430*bbaa8b60SDan Kruchinin 	const char *netid;
431*bbaa8b60SDan Kruchinin 	struct nlm_host *hostp;
432*bbaa8b60SDan Kruchinin 
433*bbaa8b60SDan Kruchinin 	_NOTE(ARGUNUSED(nc_changed));
434*bbaa8b60SDan Kruchinin 	netid = nlm_knc_to_netid(knc);
435*bbaa8b60SDan Kruchinin 	if (netid == NULL)
436*bbaa8b60SDan Kruchinin 		return (NULL);
437*bbaa8b60SDan Kruchinin 
438*bbaa8b60SDan Kruchinin 	g = zone_getspecific(nlm_zone_key, curzone);
439*bbaa8b60SDan Kruchinin 
440*bbaa8b60SDan Kruchinin 	hostp = nlm_host_findcreate(g, name, netid, addr);
441*bbaa8b60SDan Kruchinin 	if (hostp == NULL)
442*bbaa8b60SDan Kruchinin 		return (NULL);
443*bbaa8b60SDan Kruchinin 
444*bbaa8b60SDan Kruchinin 	return ((struct lm_sysid *)hostp);
445*bbaa8b60SDan Kruchinin }
446*bbaa8b60SDan Kruchinin 
447*bbaa8b60SDan Kruchinin /*
448*bbaa8b60SDan Kruchinin  * Release a reference on a "sysid".
449*bbaa8b60SDan Kruchinin  */
450*bbaa8b60SDan Kruchinin void
451*bbaa8b60SDan Kruchinin lm_rel_sysid(struct lm_sysid *sysid)
452*bbaa8b60SDan Kruchinin {
453*bbaa8b60SDan Kruchinin 	struct nlm_globals *g;
454*bbaa8b60SDan Kruchinin 
455*bbaa8b60SDan Kruchinin 	g = zone_getspecific(nlm_zone_key, curzone);
456*bbaa8b60SDan Kruchinin 	nlm_host_release(g, (struct nlm_host *)sysid);
457*bbaa8b60SDan Kruchinin }
458*bbaa8b60SDan Kruchinin 
459*bbaa8b60SDan Kruchinin /*
460*bbaa8b60SDan Kruchinin  * Alloc/free a sysid_t (a unique number between
461*bbaa8b60SDan Kruchinin  * LM_SYSID and LM_SYSID_MAX).
462*bbaa8b60SDan Kruchinin  *
463*bbaa8b60SDan Kruchinin  * Used by NFSv4 rfs4_op_lockt and smbsrv/smb_fsop_frlock,
464*bbaa8b60SDan Kruchinin  * both to represent non-local locks outside of klm.
465*bbaa8b60SDan Kruchinin  *
466*bbaa8b60SDan Kruchinin  * NOTE: called from NFSv4 and SMBFS to allocate unique
467*bbaa8b60SDan Kruchinin  * sysid.
468*bbaa8b60SDan Kruchinin  */
469*bbaa8b60SDan Kruchinin sysid_t
470*bbaa8b60SDan Kruchinin lm_alloc_sysidt(void)
471*bbaa8b60SDan Kruchinin {
472*bbaa8b60SDan Kruchinin 	return (nlm_sysid_alloc());
473*bbaa8b60SDan Kruchinin }
474*bbaa8b60SDan Kruchinin 
475*bbaa8b60SDan Kruchinin void
476*bbaa8b60SDan Kruchinin lm_free_sysidt(sysid_t sysid)
477*bbaa8b60SDan Kruchinin {
478*bbaa8b60SDan Kruchinin 	nlm_sysid_free(sysid);
479*bbaa8b60SDan Kruchinin }
480*bbaa8b60SDan Kruchinin 
481*bbaa8b60SDan Kruchinin /* Access private member lms->sysid */
482*bbaa8b60SDan Kruchinin sysid_t
483*bbaa8b60SDan Kruchinin lm_sysidt(struct lm_sysid *lms)
484*bbaa8b60SDan Kruchinin {
485*bbaa8b60SDan Kruchinin 	return (((struct nlm_host *)lms)->nh_sysid);
486*bbaa8b60SDan Kruchinin }
487*bbaa8b60SDan Kruchinin 
488*bbaa8b60SDan Kruchinin /*
489*bbaa8b60SDan Kruchinin  * Called by nfs_frlock to check lock constraints.
490*bbaa8b60SDan Kruchinin  * Return non-zero if the lock request is "safe", i.e.
491*bbaa8b60SDan Kruchinin  * the range is not mapped, not MANDLOCK, etc.
492*bbaa8b60SDan Kruchinin  *
493*bbaa8b60SDan Kruchinin  * NOTE: callde from NFSv3/NFSv2 frlock() functions to
494*bbaa8b60SDan Kruchinin  * determine whether it's safe to add new lock.
495*bbaa8b60SDan Kruchinin  */
496*bbaa8b60SDan Kruchinin int
497*bbaa8b60SDan Kruchinin lm_safelock(vnode_t *vp, const struct flock64 *fl, cred_t *cr)
498*bbaa8b60SDan Kruchinin {
499*bbaa8b60SDan Kruchinin 	return (nlm_safelock(vp, fl, cr));
500*bbaa8b60SDan Kruchinin }
501*bbaa8b60SDan Kruchinin 
502*bbaa8b60SDan Kruchinin /*
503*bbaa8b60SDan Kruchinin  * Called by nfs_lockcompletion to check whether it's "safe"
504*bbaa8b60SDan Kruchinin  * to map the file (and cache it's data).  Walks the list of
505*bbaa8b60SDan Kruchinin  * file locks looking for any that are not "whole file".
506*bbaa8b60SDan Kruchinin  *
507*bbaa8b60SDan Kruchinin  * NOTE: called from nfs_client.c:nfs_lockcompletion()
508*bbaa8b60SDan Kruchinin  */
509*bbaa8b60SDan Kruchinin int
510*bbaa8b60SDan Kruchinin lm_safemap(const vnode_t *vp)
511*bbaa8b60SDan Kruchinin {
512*bbaa8b60SDan Kruchinin 	return (nlm_safemap(vp));
513*bbaa8b60SDan Kruchinin }
514*bbaa8b60SDan Kruchinin 
515*bbaa8b60SDan Kruchinin /*
516*bbaa8b60SDan Kruchinin  * Called by nfs_map() for the MANDLOCK case.
517*bbaa8b60SDan Kruchinin  * Return non-zero if the file has any locks with a
518*bbaa8b60SDan Kruchinin  * blocked request (sleep).
519*bbaa8b60SDan Kruchinin  *
520*bbaa8b60SDan Kruchinin  * NOTE: called from NFSv3/NFSv2 map() functions in
521*bbaa8b60SDan Kruchinin  * order to determine whether it's safe to add new
522*bbaa8b60SDan Kruchinin  * mapping.
523*bbaa8b60SDan Kruchinin  */
524*bbaa8b60SDan Kruchinin int
525*bbaa8b60SDan Kruchinin lm_has_sleep(const vnode_t *vp)
526*bbaa8b60SDan Kruchinin {
527*bbaa8b60SDan Kruchinin 	return (nlm_has_sleep(vp));
528*bbaa8b60SDan Kruchinin }
529*bbaa8b60SDan Kruchinin 
530*bbaa8b60SDan Kruchinin /*
531*bbaa8b60SDan Kruchinin  * ****************************************************************
532*bbaa8b60SDan Kruchinin  * Stuff needed by klmops?
533*bbaa8b60SDan Kruchinin  */
534