1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright (C) 1986, 1992, 1993, 1997, 1999 by Sun Microsystems, Inc.
  24  * All rights reserved.
  25  *
  26  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  27  *
  28  * Protocol used between local lock manager and remote lock manager.
  29  *
  30  * There are currently 3 versions of the protocol in use.  Versions 1
  31  * and 3 are used with NFS version 2.  Version 4 is used with NFS
  32  * version 3.
  33  *
  34  * (Note: there is also a version 2, but it defines an orthogonal set of
  35  * procedures that the status monitor uses to notify the lock manager of
  36  * changes in monitored systems.)
  37  */
  38 
  39 #if RPC_HDR
  40 %
  41 %#include <rpc/rpc_sztypes.h>
  42 %
  43 #endif
  44 
  45 #ifdef RPC_HDR
  46 %#define LM_MAXSTRLEN   1024
  47 %#define LM_MAXNAMELEN  (LM_MAXSTRLEN + 1)
  48 #endif
  49 
  50 /*
  51  * Types for versions 1 and 3.
  52  */
  53 
  54 /*
  55  * Status of a call to the lock manager.  The lower case enums violate the
  56  * current style guide, but we're stuck with 'em.
  57  */
  58 
  59 enum nlm_stats {
  60         nlm_granted = 0,
  61         nlm_denied = 1,
  62         nlm_denied_nolocks = 2,
  63         nlm_blocked = 3,
  64         nlm_denied_grace_period = 4,
  65         nlm_deadlck = 5
  66 };
  67 
  68 /*
  69  * The holder of a conflicting lock.
  70  */
  71 
  72 struct nlm_holder {
  73         bool exclusive;
  74         int svid;
  75         netobj oh;
  76         unsigned l_offset;
  77         unsigned l_len;
  78 };
  79 
  80 union nlm_testrply switch (nlm_stats stat) {
  81         case nlm_denied:
  82                 struct nlm_holder holder;
  83         default:
  84                 void;
  85 };
  86 
  87 struct nlm_stat {
  88         nlm_stats stat;
  89 };
  90 
  91 struct nlm_res {
  92         netobj cookie;
  93         nlm_stat stat;
  94 };
  95 
  96 struct nlm_testres {
  97         netobj cookie;
  98         nlm_testrply stat;
  99 };
 100 
 101 struct nlm_lock {
 102         string caller_name<LM_MAXSTRLEN>;
 103         netobj fh;              /* identify a file */
 104         netobj oh;              /* identify owner of a lock */
 105         int svid;               /* generated from pid for svid */
 106         unsigned l_offset;
 107         unsigned l_len;
 108 };
 109 
 110 struct nlm_lockargs {
 111         netobj cookie;
 112         bool block;
 113         bool exclusive;
 114         struct nlm_lock alock;
 115         bool reclaim;           /* used for recovering locks */
 116         int state;              /* specify local status monitor state */
 117 };
 118 
 119 struct nlm_cancargs {
 120         netobj cookie;
 121         bool block;
 122         bool exclusive;
 123         struct nlm_lock alock;
 124 };
 125 
 126 struct nlm_testargs {
 127         netobj cookie;
 128         bool exclusive;
 129         struct nlm_lock alock;
 130 };
 131 
 132 struct nlm_unlockargs {
 133         netobj cookie;
 134         struct nlm_lock alock;
 135 };
 136 
 137 #ifdef RPC_HDR
 138 %/*
 139 % * The following enums are actually bit encoded for efficient
 140 % * boolean algebra.... DON'T change them.....
 141 % * The mixed-case enums violate the present style guide, but we're
 142 % * stuck with 'em.
 143 % */
 144 #endif
 145 
 146 enum    fsh_mode {
 147         fsm_DN  = 0,    /* deny none */
 148         fsm_DR  = 1,    /* deny read */
 149         fsm_DW  = 2,    /* deny write */
 150         fsm_DRW = 3     /* deny read/write */
 151 };
 152 
 153 enum    fsh_access {
 154         fsa_NONE = 0,   /* for completeness */
 155         fsa_R    = 1,   /* read only */
 156         fsa_W    = 2,   /* write only */
 157         fsa_RW   = 3    /* read/write */
 158 };
 159 
 160 struct  nlm_share {
 161         string caller_name<LM_MAXSTRLEN>;
 162         netobj  fh;
 163         netobj  oh;
 164         fsh_mode        mode;
 165         fsh_access      access;
 166 };
 167 
 168 struct  nlm_shareargs {
 169         netobj  cookie;
 170         nlm_share       share;
 171         bool    reclaim;
 172 };
 173 
 174 struct  nlm_shareres {
 175         netobj  cookie;
 176         nlm_stats       stat;
 177         int     sequence;
 178 };
 179 
 180 struct  nlm_notify {
 181         string name<LM_MAXNAMELEN>;
 182         int state;
 183 };
 184 
 185 /*
 186  * Types for version 4.
 187  *
 188  * This revision is designed to work with NFS V3.  The main changes from
 189  * NFS V2 to V3 that affect the NLM protocol are that all file offsets
 190  * and sizes are now unsigned 64-bit ints, and file handles are now
 191  * variable length.  In NLM V1 and V3, the fixed-length V2 file handle
 192  * was encoded as a 'netobj', which is a count followed by the data
 193  * bytes.  For NLM 4, the file handle is already a count followed by
 194  * data bytes, so the handle is copied directly into the netobj, rather
 195  * than being encoded with an additional byte count.
 196  */
 197 
 198 /*
 199  * Status of a call to the lock manager.
 200  */
 201 
 202 enum nlm4_stats {
 203         nlm4_granted = 0,               /* lock was granted */
 204         nlm4_denied = 1,                /* lock was not granted, usually */
 205                                         /* due to conflicting lock */
 206         nlm4_denied_nolocks = 2,        /* not granted: out of resources */
 207         nlm4_blocked = 3,               /* not granted: expect callback */
 208                                         /* when granted */
 209         nlm4_denied_grace_period = 4,   /* not granted: server is */
 210                                         /* reestablishing old locks */
 211         nlm4_deadlck = 5,               /* not granted: deadlock detected */
 212         nlm4_rofs = 6,                  /* not granted: read-only filesystem */
 213         nlm4_stale_fh = 7,              /* not granted: stale file handle */
 214         nlm4_fbig = 8,                  /* not granted: offset or length */
 215                                         /* too big */
 216         nlm4_failed = 9                 /* not granted: some other error */
 217 };
 218 
 219 /*
 220  * The holder of a conflicting lock.
 221  */
 222 
 223 struct nlm4_holder {
 224         bool exclusive;
 225         int32 svid;
 226         netobj oh;
 227         uint64 l_offset;
 228         uint64 l_len;
 229 };
 230 
 231 union nlm4_testrply switch (nlm4_stats stat) {
 232         case nlm4_denied:
 233                 struct nlm4_holder holder;
 234         default:
 235                 void;
 236 };
 237 
 238 struct nlm4_stat {
 239         nlm4_stats stat;
 240 };
 241 
 242 struct nlm4_res {
 243         netobj cookie;
 244         nlm4_stat stat;
 245 };
 246 
 247 struct nlm4_testres {
 248         netobj cookie;
 249         nlm4_testrply stat;
 250 };
 251 
 252 struct nlm4_lock {
 253         string caller_name<LM_MAXSTRLEN>;
 254         netobj fh;              /* identify a file */
 255         netobj oh;              /* identify owner of a lock */
 256         int32 svid;             /* generated from pid for svid */
 257         uint64 l_offset;
 258         uint64 l_len;
 259 };
 260 
 261 struct nlm4_lockargs {
 262         netobj cookie;
 263         bool block;
 264         bool exclusive;
 265         struct nlm4_lock alock;
 266         bool reclaim;           /* used for recovering locks */
 267         int32 state;            /* specify local status monitor state */
 268 };
 269 
 270 struct nlm4_cancargs {
 271         netobj cookie;
 272         bool block;
 273         bool exclusive;
 274         struct nlm4_lock alock;
 275 };
 276 
 277 struct nlm4_testargs {
 278         netobj cookie;
 279         bool exclusive;
 280         struct nlm4_lock alock;
 281 };
 282 
 283 struct nlm4_unlockargs {
 284         netobj cookie;
 285         struct nlm4_lock alock;
 286 };
 287 
 288 struct  nlm4_share {
 289         string caller_name<LM_MAXSTRLEN>;
 290         netobj  fh;
 291         netobj  oh;
 292         fsh_mode        mode;
 293         fsh_access      access;
 294 };
 295 
 296 struct  nlm4_shareargs {
 297         netobj  cookie;
 298         nlm4_share      share;
 299         bool    reclaim;
 300 };
 301 
 302 struct  nlm4_shareres {
 303         netobj  cookie;
 304         nlm4_stats      stat;
 305         int32   sequence;
 306 };
 307 
 308 struct  nlm4_notify {
 309         string name<LM_MAXNAMELEN>;
 310         int32 state;
 311 };
 312 
 313 /*
 314  * Argument for the NLM call-back procedure called by rpc.statd
 315  * when a monitored host status changes.  The statd calls the
 316  * NLM prog,vers,proc specified in the SM_MON call.
 317  * NB: This struct must exactly match sm_inter.x:sm_status
 318  * and requires LM_MAXSTRLEN == SM_MAXSTRLEN
 319  */
 320 struct nlm_sm_status {
 321         string mon_name<LM_MAXSTRLEN>; /* name of host */
 322         int32 state;                    /* new state */
 323         opaque priv[16];                /* private data */
 324 };
 325 
 326 /*
 327  * Over-the-wire protocol used between the network lock managers
 328  */
 329 
 330 program NLM_PROG {
 331 
 332         version NLM_VERS {
 333 
 334                 void
 335                         NLM_NULL(void) =                        0;
 336 
 337                 nlm_testres
 338                         NLM_TEST(nlm_testargs) =                1;
 339 
 340                 nlm_res
 341                         NLM_LOCK(nlm_lockargs) =                2;
 342 
 343                 nlm_res
 344                         NLM_CANCEL(nlm_cancargs) =              3;
 345 
 346                 nlm_res
 347                         NLM_UNLOCK(nlm_unlockargs) =            4;
 348                 /*
 349                  * remote lock manager call-back to grant lock
 350                  */
 351                 nlm_res
 352                         NLM_GRANTED(nlm_testargs) =             5;
 353 
 354                 /*
 355                  * message passing style of requesting lock
 356                  */
 357 
 358                 void
 359                         NLM_TEST_MSG(nlm_testargs) =            6;
 360                 void
 361                         NLM_LOCK_MSG(nlm_lockargs) =            7;
 362                 void
 363                         NLM_CANCEL_MSG(nlm_cancargs) =          8;
 364                 void
 365                         NLM_UNLOCK_MSG(nlm_unlockargs) =        9;
 366                 void
 367                         NLM_GRANTED_MSG(nlm_testargs) =         10;
 368                 void
 369                         NLM_TEST_RES(nlm_testres) =             11;
 370                 void
 371                         NLM_LOCK_RES(nlm_res) =                 12;
 372                 void
 373                         NLM_CANCEL_RES(nlm_res) =               13;
 374                 void
 375                         NLM_UNLOCK_RES(nlm_res) =               14;
 376                 void
 377                         NLM_GRANTED_RES(nlm_res) =              15;
 378         } = 1;
 379 
 380         /*
 381          * Private (loopback-only) call-backs from statd,
 382          * used to notify that some machine has restarted.
 383          * The meaning of these is up to the lock manager
 384          * implemenation.  (See the SM_MON calls.)
 385          */
 386         version NLM_SM {
 387                 void NLM_SM_NOTIFY1(struct nlm_sm_status) =     17;
 388                 void NLM_SM_NOTIFY2(struct nlm_sm_status) =     18;
 389         } = 2;
 390 
 391         version NLM_VERSX {
 392                 nlm_shareres
 393                         NLM_SHARE(nlm_shareargs) =              20;
 394                 nlm_shareres
 395                         NLM_UNSHARE(nlm_shareargs) =            21;
 396                 nlm_res
 397                         NLM_NM_LOCK(nlm_lockargs) =             22;
 398                 void
 399                         NLM_FREE_ALL(nlm_notify) =              23;
 400         } = 3;
 401 
 402         version NLM4_VERS {
 403                 void
 404                         NLM4_NULL(void) =                       0;
 405                 nlm4_testres
 406                         NLM4_TEST(nlm4_testargs) =              1;
 407                 nlm4_res
 408                         NLM4_LOCK(nlm4_lockargs) =              2;
 409                 nlm4_res
 410                         NLM4_CANCEL(nlm4_cancargs) =    3;
 411                 nlm4_res
 412                         NLM4_UNLOCK(nlm4_unlockargs) =  4;
 413                 /*
 414                  * remote lock manager call-back to grant lock
 415                  */
 416                 nlm4_res
 417                         NLM4_GRANTED(nlm4_testargs) =   5;
 418 
 419                 /*
 420                  * message passing style of requesting lock
 421                  */
 422 
 423                 void
 424                         NLM4_TEST_MSG(nlm4_testargs) =  6;
 425                 void
 426                         NLM4_LOCK_MSG(nlm4_lockargs) =  7;
 427                 void
 428                         NLM4_CANCEL_MSG(nlm4_cancargs) =        8;
 429                 void
 430                         NLM4_UNLOCK_MSG(nlm4_unlockargs) =      9;
 431                 void
 432                         NLM4_GRANTED_MSG(nlm4_testargs) =       10;
 433                 void
 434                         NLM4_TEST_RES(nlm4_testres) =   11;
 435                 void
 436                         NLM4_LOCK_RES(nlm4_res) =               12;
 437                 void
 438                         NLM4_CANCEL_RES(nlm4_res) =             13;
 439                 void
 440                         NLM4_UNLOCK_RES(nlm4_res) =             14;
 441                 void
 442                         NLM4_GRANTED_RES(nlm4_res) =    15;
 443 
 444                 /*
 445                  * DOS-style file sharing
 446                  */
 447 
 448                 nlm4_shareres
 449                         NLM4_SHARE(nlm4_shareargs) =    20;
 450                 nlm4_shareres
 451                         NLM4_UNSHARE(nlm4_shareargs) =  21;
 452                 nlm4_res
 453                         NLM4_NM_LOCK(nlm4_lockargs) =   22;
 454                 void
 455                         NLM4_FREE_ALL(nlm4_notify) =    23;
 456         } = 4;
 457 
 458 } = 100021;