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