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;
459