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