mdmn_commd.x revision 8452:89d32dfdae6e
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 (the "License").
6% * You may not use this file except in compliance with the License.
7% *
8% * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9% * or http://www.opensolaris.org/os/licensing.
10% * See the License for the specific language governing permissions
11% * and limitations under the License.
12% *
13% * When distributing Covered Code, include this CDDL HEADER in each
14% * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15% * If applicable, add the following below this CDDL HEADER, with the
16% * fields enclosed by brackets "[]" replaced with your own identifying
17% * information: Portions Copyright [yyyy] [name of copyright owner]
18% *
19% * CDDL HEADER END
20% */
21%
22%/*
23% * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24% * Use is subject to license terms.
25% */
26%
27
28%#include <sys/types.h>
29%#include <sys/types32.h>
30%#include <sys/lvm/md_basic.h>
31%#include <sys/lvm/mdio.h>
32%#ifndef _KERNEL
33%#include <mdiox.h>
34%#include <meta_basic.h>
35%extern  bool_t  xdr_md_set_params_t(XDR *xdrs, md_set_params_t *objp);
36%extern  bool_t  xdr_mp_unit_t(XDR *xdrs, mp_unit_t *objp);
37%extern  bool_t  xdr_diskaddr_t(XDR *xdrs, diskaddr_t *objp);
38%extern  bool_t  xdr_md_dev64_t(XDR *xdrs, md_dev64_t *objp);
39%extern  bool_t  xdr_daddr_t(XDR *xdrs, daddr_t *objp);
40%extern  bool_t  xdr_daddr32_t(XDR *xdrs, daddr32_t *objp);
41%#else
42%#include <sys/lvm/md_mdiox.h>
43%#endif /* ! _KERNEL */
44
45/* every message handler must have these parameters */
46%#define	HANDLER_PARMS md_mn_msg_t *msg, uint_t flag, md_mn_result_t *res
47
48
49/* every submessage generator must have these parameters */
50%#define	SMGEN_PARMS md_mn_msg_t *msg, md_mn_msg_t **msglist
51
52/* when ever a new message type is added, an entry for it must be made in the master msg_table (defined in mdmn_commd_server.c*/
53
54enum md_mn_msgtype_t {
55        MD_MN_MSG_NULL = 0,  /* special message type for internal use only */
56	MD_MN_MSG_TEST1,
57	MD_MN_MSG_TEST2,
58	MD_MN_MSG_TEST3,
59	MD_MN_MSG_TEST4,
60	MD_MN_MSG_TEST5,
61	MD_MN_MSG_TEST6,
62	MD_MN_MSG_BC_CMD,		/* Send metacommand */
63	MD_MN_MSG_BC_CMD_RETRY,		/* Send metacommand, retry on busy */
64	MD_MN_MSG_CLU_CHECK,
65	MD_MN_MSG_CLU_LOCK,
66	MD_MN_MSG_CLU_UNLOCK,
67	MD_MN_MSG_REQUIRE_OWNER,	/* Request to become Mirror owner */
68	MD_MN_MSG_CHOOSE_OWNER,		/* Request to allocate a resync owner */
69	MD_MN_MSG_CHANGE_OWNER,		/* Change owner to a specific node */
70	MD_MN_MSG_SUSPEND_WRITES,	/* Suspend writes to a mirror */
71	MD_MN_MSG_STATE_UPDATE_RESWR,	/* Ch state of comp & resume writes */
72	MD_MN_MSG_STATE_UPDATE,		/* Susp writes/Change state of comp */
73	MD_MN_MSG_ALLOCATE_HOTSPARE,	/* Allocate hotspare for mirror comp */
74	MD_MN_MSG_RESYNC_STARTING,	/* Resync thread starting */
75	MD_MN_MSG_RESYNC_NEXT,		/* Next resync region */
76	MD_MN_MSG_RESYNC_FINISH,	/* Resync thread finished */
77	MD_MN_MSG_RESYNC_PHASE_DONE,	/* End of resync phase */
78	MD_MN_MSG_SET_CAP,		/* Set capability, eg ABR */
79	MD_MN_MSG_VERBOSITY,		/* set various levels of debug */
80	MD_MN_MSG_MDDB_PARSE,		/* Slave to reparse portion of mddb */
81	MD_MN_MSG_MDDB_BLOCK,		/* Block parse/recs on master/slave */
82	MD_MN_MSG_META_DB_ATTACH,	/* Master message to add new mddb */
83	MD_MN_MSG_SM_MDDB_ATTACH,	/* Submessage to add new mddb */
84	MD_MN_MSG_META_DB_DETACH,	/* Master message to delete mddb */
85	MD_MN_MSG_SM_MDDB_DETACH,	/* Submessage to delete mddb */
86	MD_MN_MSG_META_DB_NEWSIDE,	/* Node adding mddb side info */
87	MD_MN_MSG_META_DB_DELSIDE,	/* Node deleting mddb side info */
88	MD_MN_MSG_META_MD_ADDSIDE,	/* Node adding md side info */
89	MD_MN_MSG_META_MD_DELSIDE,	/* Node deleting md side info */
90	MD_MN_MSG_MDDB_OPTRECERR,	/* Node detects opt rec error */
91	MD_MN_MSG_ABORT,		/* Stop sending messages to any node */
92	MD_MN_MSG_STATE_UPDATE_RESWR2,	/* UPDATE_RESWR for watermark updates */
93	MD_MN_MSG_STATE_UPDATE2,	/* STATE_UPDATE for watermark updates */
94	MD_MN_MSG_ALLOCATE_HOTSPARE2,	/* ALLOCATE_HOTSPARE for wm updates */
95	MD_MN_MSG_IOCSET,		/* Send IOCSET ioctl */
96	MD_MN_MSG_SP_SETSTAT,		/* Update status of softpart */
97	MD_MN_MSG_ADDKEYNAME,		/* Add key */
98	MD_MN_MSG_DELKEYNAME,		/* Delete key */
99	MD_MN_MSG_GET_TSTATE,		/* Get tstate from master */
100	MD_MN_MSG_GET_MIRROR_STATE,	/* Get submirror state from master */
101	MD_MN_MSG_SP_SETSTAT2,		/* Update softpart status on error */
102	MD_MN_MSG_SETSYNC,		/* Set resync status */
103	MD_MN_MSG_POKE_HOTSPARES,	/* Call poke_hotspares */
104	MD_MN_MSG_ADDMDNAME,		/* Add metadevice name */
105	MD_MN_MSG_RR_DIRTY,		/* Mark RR range as dirty */
106	MD_MN_MSG_RR_CLEAN,		/* Mark RR range as clean */
107	MD_MN_NMESSAGES /* insert elements before */
108};
109
110/*
111 * A message of class X may trigger only messages of classes higher than X
112 * Feel free to change the order here. As long as you leave MD_MSG_CL_NULL
113 * and NCLASSES, of course
114 */
115
116enum md_mn_msgclass_t {
117	MD_MSG_CLASS0 = 0,  /* special message class for internal use only */
118	MD_MSG_CLASS1,
119	MD_MSG_CLASS2,
120	MD_MSG_CLASS3,
121	MD_MSG_CLASS4,
122	MD_MSG_CLASS5,
123	MD_MSG_CLASS6,
124	MD_MSG_CLASS7,
125	MD_MN_NCLASSES /* insert elements before */
126};
127
128%/*
129% * The following are needed for things like suspend and resume when the
130% * operation is to be applied to all classes / all sets.
131% */
132%#define	MD_COMM_ALL_CLASSES MD_MSG_CLASS0
133%#define	MD_COMM_ALL_SETS 0
134
135/* This is for state changes of submirror components */
136struct md_mn_msg_stch_t {
137        minor_t		msg_stch_mnum;		/* minor number of dev */
138	int		msg_stch_sm;		/* submirror involved */
139	int		msg_stch_comp;		/* component */
140	int		msg_stch_new_state;	/* new state for comp */
141	mddb_recid_t	msg_stch_hs_id;		/* hs_id at time of call */
142};
143
144
145/* This is for suspending writes to a mirror */
146struct md_mn_msg_suspwr_t {
147        minor_t         msg_suspwr_mnum;        /* minor number of dev */
148};
149
150/* Message format for choosing a resync owner */
151struct md_mn_msg_chooseid_t {
152	minor_t	msg_chooseid_mnum;	/* minor num of dev */
153	int	msg_chooseid_rcnt;	/* resync count for set */
154	int	msg_chooseid_set_node;	/* 1 => use rcnt as nodeid for owner */
155};
156
157/* Message format for changing a resync owner */
158struct md_mn_msg_chowner_t {
159	minor_t	msg_chowner_mnum;	/* minor num of dev */
160	int	msg_chowner_nodeid;	/* node id of new owner */
161};
162
163/* Message format for setting metadevice capability */
164struct md_mn_msg_setcap_t {
165	char msg_setcap_driver[MD_DRIVERNAMELEN];	/* Driver name */
166	minor_t	msg_setcap_mnum;	/* minor num of dev */
167	u_int	msg_setcap_set;		/* new settings */
168};
169
170/* This is for setting the verbosity level (MD_MN_MSG_VERBOSITY) */
171struct md_mn_verbose_t {
172	set_t			mmv_setno;
173	md_mn_msgclass_t	mmv_class;
174	u_int			mmv_what;
175};
176
177/* What do we want to debug ? (mmv_what) */
178%/* turn off everything */
179%#define	MD_MMV_NULL 		0x00000000
180%/* initialization of nodes / rpc clients */
181%#define	MD_MMV_INIT		0x00000001
182%/* mdmn_send_svc_1 related / early stage */
183%#define	MD_MMV_SEND		0x00000002
184%/* mdmn_work_svc_1 stuff on master */
185%#define	MD_MMV_WORK		0x00000004
186%/* mdmn_master_process_msg stuff */
187%#define	MD_MMV_PROC_M		0x00000008
188%/* mdmn_slave_process_msg stuff */
189%#define	MD_MMV_PROC_S		0x00000010
190%/* wakeup_master  */
191%#define	MD_MMV_WAKE_M		0x00000020
192%/* wakeup_initiator */
193%#define	MD_MMV_WAKE_I		0x00000040
194%/* Misc stuff*/
195%#define	MD_MMV_MISC		0x00000080
196%/* turn on everything */
197%#define	MD_MMV_ALL		0x0000ffff
198%/* write to syslog instead of output file, for critical messages */
199%#define	MD_MMV_SYSLOG		0x10000000
200%/* enable timestamps */
201%#define	MD_MMV_TIMESTAMP	0x20000000
202
203
204/* Message format for allocating hotspares */
205struct md_mn_msg_allochsp_t {
206	minor_t msg_allochsp_mnum;		/* minor num of dev */
207	int msg_allochsp_sm;			/* submirror index */
208	int msg_allochsp_comp;			/* component index */
209	mddb_recid_t msg_allochsp_hs_id;	/* hotspare id */
210};
211
212/* Message format for resync messages */
213struct md_mn_msg_resync_t {
214	minor_t msg_resync_mnum;		/* minor num of dev */
215	int msg_resync_type;			/* resync type */
216	diskaddr_t msg_resync_start;		/* start of resync region */
217	diskaddr_t msg_resync_rsize;		/* size of resync region */
218	diskaddr_t msg_resync_done;		/* count of resync done */
219	diskaddr_t msg_resync_2_do;		/* total size of resync */
220	int msg_originator;			/* message originator */
221	int	msg_resync_flags;		/* resync flags */
222	sm_state_t	msg_sm_state[NMIRROR];	/* submirror state */
223	sm_flags_t	msg_sm_flags[NMIRROR];	/* submirror flags */
224};
225
226%#define	MD_MSGF_DEFAULT_FLAGS		0x00000000
227
228/* Message format for blocking/unblocking MDDB parsing and record changes  */
229struct md_mn_msg_mddb_block_t {
230	int	msg_block_flags;
231};
232
233/* Message format for MDDB re-parsing */
234struct md_mn_msg_mddb_parse_t {
235	int	msg_parse_flags;	/* flags describe part to reparse */
236	int	msg_lb_flags[50];
237};
238
239/* Message format for MDDB attach */
240struct md_mn_msg_meta_db_attach_t {
241	md_dev64_t	msg_l_dev;
242	int		msg_cnt;
243	int		msg_dbsize;
244	char		msg_dname[16];
245	md_splitname	msg_splitname;
246	u_int		msg_options;
247	char		msg_devid[1];	/* unused for now, for future */
248					/* must be last element */
249};
250
251/* Message format for MDDB detach */
252struct md_mn_msg_meta_db_detach_t {
253	md_splitname	msg_splitname;
254	char		msg_devid[1];	/* unused for now, for future */
255					/* must be last element */
256};
257
258/* Message format for MDDB newside */
259struct md_mn_msg_meta_db_newside_t {
260	md_dev64_t	msg_l_dev;
261	daddr_t		msg_blkno;
262	side_t		msg_sideno;
263	minor_t		msg_mnum;
264	char		msg_dname[16];
265	md_splitname	msg_splitname;
266	char		msg_devid[1];	/* unused for now, for future */
267					/* must be last element */
268};
269
270/* Message format for MDDB delside */
271struct md_mn_msg_meta_db_delside_t {
272	md_dev64_t	msg_l_dev;
273	daddr_t		msg_blkno;
274	side_t		msg_sideno;
275	char		msg_devid[1];	/* unused for now, for future */
276					/* must be last element */
277};
278
279/* Message format for MD addside */
280struct md_mn_msg_meta_md_addside_t {
281	side_t		msg_sideno;
282	side_t		msg_otherside;
283};
284
285/* Message format for MDDB delside */
286struct md_mn_msg_meta_md_delside_t {
287	side_t		msg_sideno;
288};
289
290/* Message format for optimized record error */
291struct md_mn_msg_mddb_optrecerr_t {
292	md_replica_recerr_t	msg_recerr[2];
293};
294
295/*
296 * Message format for IOCSET message
297 */
298
299struct md_mn_msg_iocset_t {
300	md_set_params_t	iocset_params;
301	mp_unit_t		unit;
302};
303
304/* Message format for SP_SETSTAT message */
305
306struct md_mn_msg_sp_setstat_t {
307	minor_t		sp_setstat_mnum;
308	int		sp_setstat_status;
309};
310
311/* Message format for ADDKEYNAME message */
312
313struct md_mn_msg_addkeyname_t {
314	set_t		addkeyname_setno;
315	char		addkeyname_name[1];	/* must be last element */
316};
317
318/*
319 * Add metadevice name into replica
320 */
321struct md_mn_msg_addmdname_t {
322	set_t		addmdname_setno;
323	char		addmdname_name[1];
324};
325
326/* Message format for DELKEYNAME message */
327
328struct md_mn_msg_delkeyname_t {
329	md_dev64_t	delkeyname_dev;
330	set_t		delkeyname_setno;
331	mdkey_t		delkeyname_key;
332};
333
334/* Message format for GET_TSTATE message */
335
336struct md_mn_msg_gettstate_t {
337	md_dev64_t	gettstate_dev;
338};
339
340/* Message format for GET_MIRROR_STATE message */
341
342struct md_mn_msg_mir_state_t {
343	minor_t		mir_state_mnum;
344};
345
346/* Results format for GET_SM_STATE message */
347struct md_mn_msg_mir_state_res_t {
348	sm_state_t	sm_state[NMIRROR];
349	sm_flags_t	sm_flags[NMIRROR];
350	u_int		mir_tstate;
351};
352
353/* Message format for MD_MN_MSG_SETSYNC message */
354struct md_mn_msg_setsync_t {
355	minor_t		setsync_mnum;
356	md_riflags_t	setsync_flags;
357	diskaddr_t	setsync_copysize;
358};
359
360/* Message format for MD_MN_MSG_POKE_HOTSPARES message */
361struct md_mn_msg_pokehsp_t {
362	minor_t		pokehsp_setno;
363};
364
365/* Message format for MD_MN_MSG_RR_DIRTY message */
366struct md_mn_msg_rr_dirty_t {
367	minor_t		rr_mnum;
368	int		rr_nodeid;
369	u_int		rr_range;	/* Start(16bits) | End(16bits) */
370};
371
372/* Message format for MD_MN_MSG_RR_CLEAN message */
373%#define	MDMN_MSG_RR_CLEAN_DATA_MAX_BYTES	\
374%		    ((MDMN_MAX_KMSG_DATA) - \
375%		    sizeof (struct md_mn_msg_rr_clean_t))
376%#define	MDMN_MSG_RR_CLEAN_SIZE_DATA(x)		\
377%		    (sizeof (struct md_mn_msg_rr_clean_t) + (x))
378%#define	MDMN_MSG_RR_CLEAN_MSG_SIZE(x)		\
379%		    (sizeof (struct md_mn_msg_rr_clean_t) \
380%		    + MDMN_MSG_RR_CLEAN_DATA_BYTES(x))
381%#define	MDMN_MSG_RR_CLEAN_DATA(x)		\
382%		    ((unsigned char *)(x) + \
383%		    sizeof (struct md_mn_msg_rr_clean_t))
384
385/* since we cannot use ushorts, some macros to extract the parts from an int */
386%#define	MDMN_MSG_RR_CLEAN_START_BIT(x)	((x)->rr_start_size >> 16)
387%#define	MDMN_MSG_RR_CLEAN_DATA_BYTES(x)	((x)->rr_start_size & 0xffff)
388%#define	MDMN_MSG_RR_CLEAN_START_SIZE_SET(x, start, size) \
389%			((x)->rr_start_size = (start << 16) | size)
390
391struct md_mn_msg_rr_clean_t {
392	md_mn_nodeid_t	rr_nodeid;
393	unsigned int	rr_mnum;
394	unsigned int	rr_start_size;	/* start_bit (16b) | data_bytes (16b) */
395	/* actual data goes here */
396};
397
398%#define	MD_MSGF_NO_LOG			0x00000001
399%#define	MD_MSGF_NO_BCAST		0x00000002
400%#define	MD_MSGF_STOP_ON_ERROR		0x00000004
401%#define	MD_MSGF_REPLAY_MSG		0x00000008
402%#define	MD_MSGF_OVERRIDE_SUSPEND	0x00000010
403%#define	MD_MSGF_ON_MASTER		0x00000020
404%#define	MD_MSGF_ON_SLAVE		0x00000040
405%#define	MD_MSGF_ON_INITIATOR		0x00000080
406%#define	MD_MSGF_LOCAL_ONLY		0x00000100
407%#define	MD_MSGF_FAIL_ON_SUSPEND		0x00000200
408%#define	MD_MSGF_NO_MCT			0x00000400
409%#define	MD_MSGF_PANIC_WHEN_INCONSISTENT	0x00000800
410%#define	MD_MSGF_BLK_SIGNAL		0x00001000
411%#define	MD_MSGF_KSEND_NORETRY		0x00002000
412%#define	MD_MSGF_DIRECTED		0x00004000
413%#define	MD_MSGF_VERBOSE			0x10000000
414%#define	MD_MSGF_VERBOSE_2		0x20000000
415
416%#define	MD_MSGF_INHERIT_BITS		\
417%			MD_MSGF_REPLAY_MSG | MD_MSGF_OVERRIDE_SUSPEND
418
419
420
421%/* maximum number of nodes in cluster (not in diskset) */
422%#define	NNODES MD_MNMAXSIDES
423
424
425/* if you add elements here, make sure, to add them to MSGID_COPY(), too */
426struct md_mn_msgid_t {
427	uint64_t	mid_time;	/* unique timestamp */
428	md_mn_nodeid_t	mid_nid;	/* node that created the message */
429	md_mn_msgclass_t mid_oclass;	/* for submessages original class */
430	uint8_t		mid_smid;	/* sub message number */
431	uint8_t		mid_spare[15];	/* Always good to have some spares */
432};
433
434%#define MD_NULL_MSGID (md_mn_msgid_t *)NULL
435%
436%/* macros to handle msgid's */
437%#define	MSGID_COPY(from, to) {				\
438%			(to)->mid_nid = (from)->mid_nid;	\
439%			(to)->mid_smid = (from)->mid_smid;	\
440%			(to)->mid_oclass = (from)->mid_oclass;	\
441%			(to)->mid_time = (from)->mid_time;	\
442%		}
443%
444%#define	MSGID_CMP(a, b) 				\
445%			(((a)->mid_nid == (b)->mid_nid) &&	\
446%			((a)->mid_smid == (b)->mid_smid) &&	\
447%			((a)->mid_time == (b)->mid_time))
448%
449%#define	MSGID_ELEMS(mid) (mid).mid_nid, (mid).mid_time, (mid).mid_smid
450
451/* if you add elements here, make sure, to add them to copy_msg(), too */
452struct md_mn_msg_t {
453        md_mn_msgid_t	msg_msgid;	/* Message id */
454	md_mn_nodeid_t	msg_sender;	/* who wants the results? */
455	u_int		msg_flags;	/* See MD_MSGF_* above */
456	set_t		msg_setno;	/* which set is involved */
457        md_mn_msgtype_t msg_type;       /* what type of message */
458	md_mn_nodeid_t	msg_recipient;	/* who to send DIRECTED message to */
459	char		msg_spare[28];	/* Always good to hav'em */
460	opaque		msg_event<>;	/* the actual event wrapped up */
461};
462%#define	msg_event_data	msg_event.msg_event_val
463%#define	msg_event_size	msg_event.msg_event_len
464%
465%#define	MD_MN_MSG_LEN(msg)	((msg)->msg_event_size +\
466%							sizeof (md_mn_msg_t))
467%#define	MD_MN_MSG_MAXDATALEN	1024
468
469/* ondisk version of the message */
470struct md_mn_msg_od_t {
471        md_mn_msgid_t	msg_msgid;	/* Message id */
472	md_mn_nodeid_t	msg_sender;	/* who wants the results? */
473	uint32_t	msg_flags;	/* See MD_MSGF_* above */
474	set_t		msg_setno;	/* which set is involved */
475        md_mn_msgtype_t msg_type;       /* what type of message */
476	md_mn_nodeid_t	msg_recipient;	/* who to send DIRECTED message to */
477	char		msg_spare[28];	/* Always good to hav'em */
478	uint32_t	msg_ev_len;
479	char		msg_ev_val[MD_MN_MSG_MAXDATALEN];
480};
481%
482%#define	msg_od_event_data	msg_ev_val
483%#define	msg_od_event_size	msg_ev_len
484%#define	MDMN_MAX_KMSG_DATA	256
485
486/* needed for mdmn_ksend_message to deliver the data into userland thru doors */
487struct md_mn_kmsg_t {
488	md_mn_msgid_t 	kmsg_msgid;
489	u_int		kmsg_flags;
490	set_t		kmsg_setno;
491	md_mn_msgtype_t	kmsg_type;
492	md_mn_nodeid_t	kmsg_recipient;	/* who to send DIRECTED message to */
493	int		kmsg_size;
494	char		kmsg_data[MDMN_MAX_KMSG_DATA];
495};
496
497/* if you add elements here, make sure, to add them to copy_result(), too */
498struct md_mn_result_t {
499	md_mn_msgid_t	mmr_msgid;
500	md_mn_msgtype_t	mmr_msgtype;
501	set_t		mmr_setno;
502	u_int		mmr_flags;
503	md_mn_nodeid_t	mmr_sender;   /* needed to check for unsolicited msgs */
504	md_mn_nodeid_t	mmr_failing_node; /* trouble maker */
505	int		mmr_comm_state;
506	int		mmr_exitval;
507	md_error_t	mmr_ep;
508	opaque		mmr_output<>; /* msg handler can store output here */
509	opaque		mmr_error<>;  /* ... and error output goes here */
510};
511
512%#define	MDMN_MAX_KRES_DATA	256
513/* kernel results don't provide something like stderr */
514struct md_mn_kresult_t {
515	md_mn_msgtype_t	kmmr_msgtype;
516	u_int		kmmr_flags;
517	int		kmmr_comm_state;
518	md_mn_nodeid_t	kmmr_failing_node; /* trouble maker */
519	int		kmmr_exitval;
520	int		kmmr_res_size;
521	char		kmmr_res_data[MDMN_MAX_KRES_DATA];
522};
523
524/* possible return values for the rpc services */
525enum md_mn_retval_t {
526	MDMNE_NULL = 0,
527	MDMNE_ACK,		/* this is the good one */
528	MDMNE_CLASS_BUSY,	/* try again */
529	MDMNE_RPC_FAIL,		/* some RPC error occurred */
530	MDMNE_THR_CREATE_FAIL,  /* cannot create working thread */
531	MDMNE_NO_HANDLER,	/* this message has no handler */
532	MDMNE_LOG_FAIL,		/* logging failed for some reason */
533	MDMNE_CANNOT_CONNECT,	/* rpc connection not possible */
534	MDMNE_NO_WAKEUP_ENTRY,	/* no entry in wakeup table for msgid */
535	MDMNE_NOT_JOINED,	/* this host hasn't joined yet */
536	MDMNE_HANDLER_FAILED,	/* could not run the handler for this message */
537	MDMNE_EINVAL,		/* bad argument specified for special message */
538	MDMNE_SUSPENDED,	/* commd doesn't accept new messgaes */
539	MDMNE_CLASS_LOCKED,	/* class has been locked (for testing only) */
540	MDMNE_TIMEOUT,		/* processing message took too long */
541	MDMNE_SET_NOT_DRAINED,	/* still outstandang messages for this set */
542	MDMNE_ABORT,		/* Contacted node is in abort state */
543	MDMNE_IGNORE_NODE	/* ignore current node, send msg to next one */
544};
545
546%
547%#define	MDMN_KSEND_MSG_OK(rv, kres)		\
548%	(((rv) == 0) && (((kres)->kmmr_exitval == 0) && \
549%	 (((kres)->kmmr_comm_state == MDMNE_ACK) || \
550%	  (!md_mn_is_commd_present() && \
551%	   ((kres)->kmmr_comm_state == MDMNE_RPC_FAIL)))))
552%
553
554%
555%#define	mmr_out		mmr_output.mmr_output_val
556%#define	mmr_out_size	mmr_output.mmr_output_len
557%#define	mmr_err		mmr_error.mmr_error_val
558%#define	mmr_err_size	mmr_error.mmr_error_len
559%
560%
561%extern void mdmn_master_process_msg(md_mn_msg_t *);
562%extern void mdmn_slave_process_msg(md_mn_msg_t *);
563
564
565struct md_mn_set_and_class_t {
566	set_t			msc_set;
567	md_mn_msgclass_t	msc_class;
568	u_int			msc_flags;
569};
570
571%/* possible values for msc_flags above */
572%#define	MD_MSCF_NO_FLAGS		0x0000
573%#define	MD_MSCF_DONT_RESUME_CLASS1	0x0001
574
575struct md_mn_type_and_lock_t {
576	md_mn_msgtype_t	mmtl_type;
577	u_int		mmtl_lock;
578};
579
580%/* possible values for mmtl_flags above */
581%#define	MMTL_UNLOCK		0x0000
582%#define	MMTL_LOCK		0x0001
583
584%/* Currently not used, but thinkable extensions */
585%#define	MMTL_LOCK_ON_INITIATOR	0x0002
586%#define	MMTL_LOCK_ON_MASTER	0x0004
587%#define	MMTL_LOCK_ON_SLAVE	0x0008
588%#define	MMTL_LOCK_ONE_TIME_ONLY	0x0010
589
590
591program MDMN_COMMD {
592	version TWO {
593		md_mn_result_t
594		mdmn_send(md_mn_msg_t) = 1;
595
596		int
597		mdmn_work(md_mn_msg_t msg) = 2;
598
599		int
600		mdmn_wakeup_initiator(md_mn_result_t) = 3;
601
602		int
603		mdmn_wakeup_master(md_mn_result_t) = 4;
604
605		int
606		mdmn_comm_lock(md_mn_set_and_class_t) = 5;
607
608		int
609		mdmn_comm_unlock(md_mn_set_and_class_t) = 6;
610
611		int
612		mdmn_comm_suspend(md_mn_set_and_class_t) = 7;
613
614		int
615		mdmn_comm_resume(md_mn_set_and_class_t) = 8;
616
617		int
618		mdmn_comm_reinit_set(set_t) = 9;
619
620		int
621		mdmn_comm_msglock(md_mn_type_and_lock_t) = 10;
622	} = 2;
623} = 100422;
624