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