xref: /onnv-gate/usr/src/lib/lvm/libmeta/common/meta_mn_comm.c (revision 8452:89d32dfdae6e)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
53073Sjkennedy  * Common Development and Distribution License (the "License").
63073Sjkennedy  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate 
220Sstevel@tonic-gate /*
23*8452SJohn.Wren.Kennedy@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #include <stdlib.h>
280Sstevel@tonic-gate #include <unistd.h>
290Sstevel@tonic-gate #include <wait.h>
300Sstevel@tonic-gate #include <sys/time.h>
310Sstevel@tonic-gate #include <strings.h>
320Sstevel@tonic-gate #include <meta.h>
330Sstevel@tonic-gate #include <syslog.h>
340Sstevel@tonic-gate 
350Sstevel@tonic-gate extern md_mn_msg_tbl_entry_t  msg_table[];
360Sstevel@tonic-gate 
370Sstevel@tonic-gate /*
380Sstevel@tonic-gate  * When contacting the local rpc.mdcommd we always want to do that using
390Sstevel@tonic-gate  * the IPv4 version of localhost.
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate #define	LOCALHOST_IPv4	"127.0.0.1"
420Sstevel@tonic-gate 
430Sstevel@tonic-gate md_mn_msgclass_t
mdmn_get_message_class(md_mn_msgtype_t msgtype)440Sstevel@tonic-gate mdmn_get_message_class(md_mn_msgtype_t msgtype)
450Sstevel@tonic-gate {
460Sstevel@tonic-gate 	return (msg_table[msgtype].mte_class);
470Sstevel@tonic-gate }
480Sstevel@tonic-gate 
490Sstevel@tonic-gate void (*
mdmn_get_handler(md_mn_msgtype_t msgtype)500Sstevel@tonic-gate mdmn_get_handler(md_mn_msgtype_t msgtype))
510Sstevel@tonic-gate 	(md_mn_msg_t *msg, uint_t flags, md_mn_result_t *res)
520Sstevel@tonic-gate {
530Sstevel@tonic-gate 	return (msg_table[msgtype].mte_handler);
540Sstevel@tonic-gate }
550Sstevel@tonic-gate 
560Sstevel@tonic-gate int (*
mdmn_get_submessage_generator(md_mn_msgtype_t msgtype)570Sstevel@tonic-gate mdmn_get_submessage_generator(md_mn_msgtype_t msgtype))
580Sstevel@tonic-gate 	(md_mn_msg_t *msg, md_mn_msg_t **msglist)
590Sstevel@tonic-gate {
600Sstevel@tonic-gate 	return (msg_table[msgtype].mte_smgen);
610Sstevel@tonic-gate }
620Sstevel@tonic-gate 
630Sstevel@tonic-gate time_t
mdmn_get_timeout(md_mn_msgtype_t msgtype)640Sstevel@tonic-gate mdmn_get_timeout(md_mn_msgtype_t msgtype)
650Sstevel@tonic-gate {
660Sstevel@tonic-gate 	return (msg_table[msgtype].mte_timeout);
670Sstevel@tonic-gate }
680Sstevel@tonic-gate 
690Sstevel@tonic-gate 
700Sstevel@tonic-gate void
ldump_msg(char * prefix,md_mn_msg_t * msg)710Sstevel@tonic-gate ldump_msg(char *prefix, md_mn_msg_t *msg)
720Sstevel@tonic-gate {
73*8452SJohn.Wren.Kennedy@Sun.COM 	(void) fprintf(stderr, "%s &msg       = 0x%x\n", prefix, (uint_t)msg);
74*8452SJohn.Wren.Kennedy@Sun.COM 	(void) fprintf(stderr, "%s ID         = (%d, 0x%llx-%d)\n", prefix,
750Sstevel@tonic-gate 	    MSGID_ELEMS(msg->msg_msgid));
76*8452SJohn.Wren.Kennedy@Sun.COM 	(void) fprintf(stderr, "%s sender     = %d\n", prefix, msg->msg_sender);
77*8452SJohn.Wren.Kennedy@Sun.COM 	(void) fprintf(stderr, "%s flags      = 0x%x\n",
78*8452SJohn.Wren.Kennedy@Sun.COM 	    prefix, msg->msg_flags);
79*8452SJohn.Wren.Kennedy@Sun.COM 	(void) fprintf(stderr, "%s setno      = %d\n", prefix, msg->msg_setno);
80*8452SJohn.Wren.Kennedy@Sun.COM 	(void) fprintf(stderr, "%s recipient  = %d\n",
81*8452SJohn.Wren.Kennedy@Sun.COM 	    prefix, msg->msg_recipient);
82*8452SJohn.Wren.Kennedy@Sun.COM 	(void) fprintf(stderr, "%s type       = %d\n", prefix, msg->msg_type);
83*8452SJohn.Wren.Kennedy@Sun.COM 	(void) fprintf(stderr, "%s size       = %d\n",
84*8452SJohn.Wren.Kennedy@Sun.COM 	    prefix, msg->msg_event_size);
850Sstevel@tonic-gate }
860Sstevel@tonic-gate 
87*8452SJohn.Wren.Kennedy@Sun.COM #define	COMMD_PROGNAME	"rpc.mdcommd"
88*8452SJohn.Wren.Kennedy@Sun.COM 
89*8452SJohn.Wren.Kennedy@Sun.COM extern uint_t meta_rpc_err_mask(void);
90*8452SJohn.Wren.Kennedy@Sun.COM 
91*8452SJohn.Wren.Kennedy@Sun.COM /*
92*8452SJohn.Wren.Kennedy@Sun.COM  * If a clnt_call gets an RPC error, force the message out here with details.
93*8452SJohn.Wren.Kennedy@Sun.COM  * This would be nice to send to commd_debug(), but we can't call rpc.mdcommd
94*8452SJohn.Wren.Kennedy@Sun.COM  * code from libmeta.
95*8452SJohn.Wren.Kennedy@Sun.COM  */
96*8452SJohn.Wren.Kennedy@Sun.COM static void
mdmn_handle_RPC_error(CLIENT * clnt,char * ident,md_mn_nodeid_t nid)97*8452SJohn.Wren.Kennedy@Sun.COM mdmn_handle_RPC_error(CLIENT *clnt, char *ident, md_mn_nodeid_t nid)
98*8452SJohn.Wren.Kennedy@Sun.COM {
99*8452SJohn.Wren.Kennedy@Sun.COM 	/*
100*8452SJohn.Wren.Kennedy@Sun.COM 	 * This is sized for a max message which would look like this:
101*8452SJohn.Wren.Kennedy@Sun.COM 	 * "mdmn_wakeup_initiator: rpc.mdcommd node 4294967295"
102*8452SJohn.Wren.Kennedy@Sun.COM 	 */
103*8452SJohn.Wren.Kennedy@Sun.COM 	char errstr[51];
104*8452SJohn.Wren.Kennedy@Sun.COM 	struct rpc_err e;
105*8452SJohn.Wren.Kennedy@Sun.COM 
106*8452SJohn.Wren.Kennedy@Sun.COM 	CLNT_GETERR((CLIENT *) clnt, &e);
107*8452SJohn.Wren.Kennedy@Sun.COM 	if (meta_rpc_err_mask() & (1 << e.re_status)) {
108*8452SJohn.Wren.Kennedy@Sun.COM 		if (nid == 0) {
109*8452SJohn.Wren.Kennedy@Sun.COM 			(void) snprintf(errstr, sizeof (errstr),
110*8452SJohn.Wren.Kennedy@Sun.COM 			    "%s: %s node (local)", ident, COMMD_PROGNAME);
111*8452SJohn.Wren.Kennedy@Sun.COM 		} else {
112*8452SJohn.Wren.Kennedy@Sun.COM 			(void) snprintf(errstr, sizeof (errstr),
113*8452SJohn.Wren.Kennedy@Sun.COM 			    "%s: %s node %d", ident, COMMD_PROGNAME, nid);
114*8452SJohn.Wren.Kennedy@Sun.COM 		}
115*8452SJohn.Wren.Kennedy@Sun.COM 		syslog(LOG_WARNING, "mdmn_handle_RPC_error: %s",
116*8452SJohn.Wren.Kennedy@Sun.COM 		    clnt_sperror(clnt, errstr));
117*8452SJohn.Wren.Kennedy@Sun.COM 	}
118*8452SJohn.Wren.Kennedy@Sun.COM }
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate /* Default timeout can be changed using clnt_control() */
1210Sstevel@tonic-gate static struct timeval TIMEOUT = { 25, 0 };
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate md_mn_result_t *
mdmn_send_2(argp,clnt,nid)124*8452SJohn.Wren.Kennedy@Sun.COM mdmn_send_2(argp, clnt, nid)
1250Sstevel@tonic-gate 	md_mn_msg_t *argp;
1260Sstevel@tonic-gate 	CLIENT *clnt;
127*8452SJohn.Wren.Kennedy@Sun.COM 	md_mn_nodeid_t nid;
1280Sstevel@tonic-gate {
129*8452SJohn.Wren.Kennedy@Sun.COM 	enum clnt_stat	res;
1300Sstevel@tonic-gate 	md_mn_result_t *clnt_res = Zalloc(sizeof (md_mn_result_t));
1310Sstevel@tonic-gate 
132*8452SJohn.Wren.Kennedy@Sun.COM 	res = clnt_call(clnt, mdmn_send,
1330Sstevel@tonic-gate 		(xdrproc_t)xdr_md_mn_msg_t, (caddr_t)argp,
134*8452SJohn.Wren.Kennedy@Sun.COM 		(xdrproc_t)xdr_md_mn_result_t, (caddr_t)clnt_res, TIMEOUT);
135*8452SJohn.Wren.Kennedy@Sun.COM 
136*8452SJohn.Wren.Kennedy@Sun.COM 	if (res == RPC_SUCCESS) {
137*8452SJohn.Wren.Kennedy@Sun.COM 		return (clnt_res);
1380Sstevel@tonic-gate 	}
139*8452SJohn.Wren.Kennedy@Sun.COM 	mdmn_handle_RPC_error(clnt, "mdmn_send", nid);
140*8452SJohn.Wren.Kennedy@Sun.COM 	Free(clnt_res);
141*8452SJohn.Wren.Kennedy@Sun.COM 	return (NULL);
1420Sstevel@tonic-gate }
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate int *
mdmn_work_2(argp,clnt,nid)145*8452SJohn.Wren.Kennedy@Sun.COM mdmn_work_2(argp, clnt, nid)
1460Sstevel@tonic-gate 	md_mn_msg_t *argp;
1470Sstevel@tonic-gate 	CLIENT *clnt;
148*8452SJohn.Wren.Kennedy@Sun.COM 	md_mn_nodeid_t nid;
1490Sstevel@tonic-gate {
150*8452SJohn.Wren.Kennedy@Sun.COM 	enum clnt_stat	res;
1510Sstevel@tonic-gate 	int *clnt_res = Zalloc(sizeof (int));
1520Sstevel@tonic-gate 
153*8452SJohn.Wren.Kennedy@Sun.COM 	res = clnt_call(clnt, mdmn_work,
1540Sstevel@tonic-gate 		(xdrproc_t)xdr_md_mn_msg_t, (caddr_t)argp,
155*8452SJohn.Wren.Kennedy@Sun.COM 		(xdrproc_t)xdr_int, (caddr_t)clnt_res, TIMEOUT);
156*8452SJohn.Wren.Kennedy@Sun.COM 
157*8452SJohn.Wren.Kennedy@Sun.COM 	if (res == RPC_SUCCESS) {
158*8452SJohn.Wren.Kennedy@Sun.COM 		return (clnt_res);
1590Sstevel@tonic-gate 	}
160*8452SJohn.Wren.Kennedy@Sun.COM 	mdmn_handle_RPC_error(clnt, "mdmn_work", nid);
161*8452SJohn.Wren.Kennedy@Sun.COM 	Free(clnt_res);
162*8452SJohn.Wren.Kennedy@Sun.COM 	return (NULL);
1630Sstevel@tonic-gate }
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate int *
mdmn_wakeup_initiator_2(argp,clnt,nid)166*8452SJohn.Wren.Kennedy@Sun.COM mdmn_wakeup_initiator_2(argp, clnt, nid)
1670Sstevel@tonic-gate 	md_mn_result_t *argp;
1680Sstevel@tonic-gate 	CLIENT *clnt;
169*8452SJohn.Wren.Kennedy@Sun.COM 	md_mn_nodeid_t nid;
1700Sstevel@tonic-gate {
171*8452SJohn.Wren.Kennedy@Sun.COM 	enum clnt_stat	res;
1720Sstevel@tonic-gate 	int *clnt_res = Zalloc(sizeof (int));
1730Sstevel@tonic-gate 
174*8452SJohn.Wren.Kennedy@Sun.COM 	res = clnt_call(clnt, mdmn_wakeup_initiator,
1750Sstevel@tonic-gate 		(xdrproc_t)xdr_md_mn_result_t, (caddr_t)argp,
176*8452SJohn.Wren.Kennedy@Sun.COM 		(xdrproc_t)xdr_int, (caddr_t)clnt_res, TIMEOUT);
177*8452SJohn.Wren.Kennedy@Sun.COM 
178*8452SJohn.Wren.Kennedy@Sun.COM 	if (res == RPC_SUCCESS) {
179*8452SJohn.Wren.Kennedy@Sun.COM 		return (clnt_res);
1800Sstevel@tonic-gate 	}
181*8452SJohn.Wren.Kennedy@Sun.COM 	mdmn_handle_RPC_error(clnt, "mdmn_wakeup_initiator", nid);
182*8452SJohn.Wren.Kennedy@Sun.COM 	Free(clnt_res);
183*8452SJohn.Wren.Kennedy@Sun.COM 	return (NULL);
1840Sstevel@tonic-gate }
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate int *
mdmn_wakeup_master_2(argp,clnt,nid)187*8452SJohn.Wren.Kennedy@Sun.COM mdmn_wakeup_master_2(argp, clnt, nid)
1880Sstevel@tonic-gate 	md_mn_result_t *argp;
1890Sstevel@tonic-gate 	CLIENT *clnt;
190*8452SJohn.Wren.Kennedy@Sun.COM 	md_mn_nodeid_t nid;
1910Sstevel@tonic-gate {
192*8452SJohn.Wren.Kennedy@Sun.COM 	enum clnt_stat	res;
1930Sstevel@tonic-gate 	int *clnt_res = Zalloc(sizeof (int));
1940Sstevel@tonic-gate 
195*8452SJohn.Wren.Kennedy@Sun.COM 	res = clnt_call(clnt, mdmn_wakeup_master,
1960Sstevel@tonic-gate 		(xdrproc_t)xdr_md_mn_result_t, (caddr_t)argp,
197*8452SJohn.Wren.Kennedy@Sun.COM 		(xdrproc_t)xdr_int, (caddr_t)clnt_res, TIMEOUT);
198*8452SJohn.Wren.Kennedy@Sun.COM 
199*8452SJohn.Wren.Kennedy@Sun.COM 	if (res == RPC_SUCCESS) {
200*8452SJohn.Wren.Kennedy@Sun.COM 		return (clnt_res);
2010Sstevel@tonic-gate 	}
202*8452SJohn.Wren.Kennedy@Sun.COM 	mdmn_handle_RPC_error(clnt, "mdmn_wakeup_master", nid);
203*8452SJohn.Wren.Kennedy@Sun.COM 	Free(clnt_res);
204*8452SJohn.Wren.Kennedy@Sun.COM 	return (NULL);
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate int *
mdmn_comm_lock_2(argp,clnt,nid)208*8452SJohn.Wren.Kennedy@Sun.COM mdmn_comm_lock_2(argp, clnt, nid)
2090Sstevel@tonic-gate 	md_mn_set_and_class_t *argp;
2100Sstevel@tonic-gate 	CLIENT *clnt;
211*8452SJohn.Wren.Kennedy@Sun.COM 	md_mn_nodeid_t nid;
2120Sstevel@tonic-gate {
213*8452SJohn.Wren.Kennedy@Sun.COM 	enum clnt_stat	res;
2140Sstevel@tonic-gate 	int *clnt_res = Zalloc(sizeof (int));
2150Sstevel@tonic-gate 
216*8452SJohn.Wren.Kennedy@Sun.COM 	res = clnt_call(clnt, mdmn_comm_lock,
2170Sstevel@tonic-gate 		(xdrproc_t)xdr_md_mn_set_and_class_t, (caddr_t)argp,
218*8452SJohn.Wren.Kennedy@Sun.COM 		(xdrproc_t)xdr_int, (caddr_t)clnt_res, TIMEOUT);
219*8452SJohn.Wren.Kennedy@Sun.COM 
220*8452SJohn.Wren.Kennedy@Sun.COM 	if (res == RPC_SUCCESS) {
221*8452SJohn.Wren.Kennedy@Sun.COM 		return (clnt_res);
2220Sstevel@tonic-gate 	}
223*8452SJohn.Wren.Kennedy@Sun.COM 	mdmn_handle_RPC_error(clnt, "mdmn_comm_lock", nid);
224*8452SJohn.Wren.Kennedy@Sun.COM 	Free(clnt_res);
225*8452SJohn.Wren.Kennedy@Sun.COM 	return (NULL);
2260Sstevel@tonic-gate }
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate int *
mdmn_comm_unlock_2(argp,clnt,nid)229*8452SJohn.Wren.Kennedy@Sun.COM mdmn_comm_unlock_2(argp, clnt, nid)
2300Sstevel@tonic-gate 	md_mn_set_and_class_t *argp;
2310Sstevel@tonic-gate 	CLIENT *clnt;
232*8452SJohn.Wren.Kennedy@Sun.COM 	md_mn_nodeid_t nid;
2330Sstevel@tonic-gate {
234*8452SJohn.Wren.Kennedy@Sun.COM 	enum clnt_stat	res;
2350Sstevel@tonic-gate 	int *clnt_res = Zalloc(sizeof (int));
2360Sstevel@tonic-gate 
237*8452SJohn.Wren.Kennedy@Sun.COM 	res = clnt_call(clnt, mdmn_comm_unlock,
2380Sstevel@tonic-gate 		(xdrproc_t)xdr_md_mn_set_and_class_t, (caddr_t)argp,
239*8452SJohn.Wren.Kennedy@Sun.COM 		(xdrproc_t)xdr_int, (caddr_t)clnt_res, TIMEOUT);
240*8452SJohn.Wren.Kennedy@Sun.COM 
241*8452SJohn.Wren.Kennedy@Sun.COM 	if (res == RPC_SUCCESS) {
242*8452SJohn.Wren.Kennedy@Sun.COM 		return (clnt_res);
2430Sstevel@tonic-gate 	}
244*8452SJohn.Wren.Kennedy@Sun.COM 	mdmn_handle_RPC_error(clnt, "mdmn_comm_unlock", nid);
245*8452SJohn.Wren.Kennedy@Sun.COM 	Free(clnt_res);
246*8452SJohn.Wren.Kennedy@Sun.COM 	return (NULL);
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate int *
mdmn_comm_suspend_2(argp,clnt,nid)250*8452SJohn.Wren.Kennedy@Sun.COM mdmn_comm_suspend_2(argp, clnt, nid)
2510Sstevel@tonic-gate 	md_mn_set_and_class_t *argp;
2520Sstevel@tonic-gate 	CLIENT *clnt;
253*8452SJohn.Wren.Kennedy@Sun.COM 	md_mn_nodeid_t nid;
2540Sstevel@tonic-gate {
255*8452SJohn.Wren.Kennedy@Sun.COM 	enum clnt_stat	res;
2560Sstevel@tonic-gate 	int *clnt_res = Zalloc(sizeof (int));
2570Sstevel@tonic-gate 
258*8452SJohn.Wren.Kennedy@Sun.COM 	res = clnt_call(clnt, mdmn_comm_suspend,
2590Sstevel@tonic-gate 		(xdrproc_t)xdr_md_mn_set_and_class_t, (caddr_t)argp,
260*8452SJohn.Wren.Kennedy@Sun.COM 		(xdrproc_t)xdr_int, (caddr_t)clnt_res, TIMEOUT);
261*8452SJohn.Wren.Kennedy@Sun.COM 
262*8452SJohn.Wren.Kennedy@Sun.COM 	if (res == RPC_SUCCESS) {
263*8452SJohn.Wren.Kennedy@Sun.COM 		return (clnt_res);
2640Sstevel@tonic-gate 	}
265*8452SJohn.Wren.Kennedy@Sun.COM 	mdmn_handle_RPC_error(clnt, "mdmn_comm_suspend", nid);
266*8452SJohn.Wren.Kennedy@Sun.COM 	Free(clnt_res);
267*8452SJohn.Wren.Kennedy@Sun.COM 	return (NULL);
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate int *
mdmn_comm_resume_2(argp,clnt,nid)271*8452SJohn.Wren.Kennedy@Sun.COM mdmn_comm_resume_2(argp, clnt, nid)
2720Sstevel@tonic-gate 	md_mn_set_and_class_t *argp;
2730Sstevel@tonic-gate 	CLIENT *clnt;
274*8452SJohn.Wren.Kennedy@Sun.COM 	md_mn_nodeid_t nid;
2750Sstevel@tonic-gate {
276*8452SJohn.Wren.Kennedy@Sun.COM 	enum clnt_stat	res;
2770Sstevel@tonic-gate 	int *clnt_res = Zalloc(sizeof (int));
2780Sstevel@tonic-gate 
279*8452SJohn.Wren.Kennedy@Sun.COM 	res = clnt_call(clnt, mdmn_comm_resume,
2800Sstevel@tonic-gate 		(xdrproc_t)xdr_md_mn_set_and_class_t, (caddr_t)argp,
281*8452SJohn.Wren.Kennedy@Sun.COM 		(xdrproc_t)xdr_int, (caddr_t)clnt_res, TIMEOUT);
282*8452SJohn.Wren.Kennedy@Sun.COM 
283*8452SJohn.Wren.Kennedy@Sun.COM 	if (res == RPC_SUCCESS) {
284*8452SJohn.Wren.Kennedy@Sun.COM 		return (clnt_res);
2850Sstevel@tonic-gate 	}
286*8452SJohn.Wren.Kennedy@Sun.COM 	mdmn_handle_RPC_error(clnt, "mdmn_comm_resume", nid);
287*8452SJohn.Wren.Kennedy@Sun.COM 	Free(clnt_res);
288*8452SJohn.Wren.Kennedy@Sun.COM 	return (NULL);
2890Sstevel@tonic-gate }
2900Sstevel@tonic-gate 
2910Sstevel@tonic-gate int *
mdmn_comm_reinit_set_2(argp,clnt,nid)292*8452SJohn.Wren.Kennedy@Sun.COM mdmn_comm_reinit_set_2(argp, clnt, nid)
2930Sstevel@tonic-gate 	set_t *argp;
2940Sstevel@tonic-gate 	CLIENT *clnt;
295*8452SJohn.Wren.Kennedy@Sun.COM 	md_mn_nodeid_t nid;
2960Sstevel@tonic-gate {
297*8452SJohn.Wren.Kennedy@Sun.COM 	enum clnt_stat	res;
2980Sstevel@tonic-gate 	int *clnt_res = Zalloc(sizeof (int));
2990Sstevel@tonic-gate 
300*8452SJohn.Wren.Kennedy@Sun.COM 	res = clnt_call(clnt, mdmn_comm_reinit_set,
3010Sstevel@tonic-gate 		(xdrproc_t)xdr_set_t, (caddr_t)argp,
302*8452SJohn.Wren.Kennedy@Sun.COM 		(xdrproc_t)xdr_int, (caddr_t)clnt_res, TIMEOUT);
303*8452SJohn.Wren.Kennedy@Sun.COM 
304*8452SJohn.Wren.Kennedy@Sun.COM 	if (res == RPC_SUCCESS) {
305*8452SJohn.Wren.Kennedy@Sun.COM 		return (clnt_res);
3060Sstevel@tonic-gate 	}
307*8452SJohn.Wren.Kennedy@Sun.COM 	mdmn_handle_RPC_error(clnt, "mdmn_comm_reinit_set", nid);
308*8452SJohn.Wren.Kennedy@Sun.COM 	Free(clnt_res);
309*8452SJohn.Wren.Kennedy@Sun.COM 	return (NULL);
3100Sstevel@tonic-gate }
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate int *
mdmn_comm_msglock_2(argp,clnt,nid)313*8452SJohn.Wren.Kennedy@Sun.COM mdmn_comm_msglock_2(argp, clnt, nid)
3140Sstevel@tonic-gate 	md_mn_type_and_lock_t *argp;
3150Sstevel@tonic-gate 	CLIENT *clnt;
316*8452SJohn.Wren.Kennedy@Sun.COM 	md_mn_nodeid_t nid;
3170Sstevel@tonic-gate {
318*8452SJohn.Wren.Kennedy@Sun.COM 	enum clnt_stat	res;
3190Sstevel@tonic-gate 	int *clnt_res = Zalloc(sizeof (int));
3200Sstevel@tonic-gate 
321*8452SJohn.Wren.Kennedy@Sun.COM 	res = clnt_call(clnt, mdmn_comm_msglock,
3220Sstevel@tonic-gate 		(xdrproc_t)xdr_md_mn_type_and_lock_t, (caddr_t)argp,
323*8452SJohn.Wren.Kennedy@Sun.COM 		(xdrproc_t)xdr_int, (caddr_t)clnt_res, TIMEOUT);
324*8452SJohn.Wren.Kennedy@Sun.COM 
325*8452SJohn.Wren.Kennedy@Sun.COM 	if (res == RPC_SUCCESS) {
326*8452SJohn.Wren.Kennedy@Sun.COM 		return (clnt_res);
3270Sstevel@tonic-gate 	}
328*8452SJohn.Wren.Kennedy@Sun.COM 	mdmn_handle_RPC_error(clnt, "mdmn_comm_msglock", nid);
329*8452SJohn.Wren.Kennedy@Sun.COM 	Free(clnt_res);
330*8452SJohn.Wren.Kennedy@Sun.COM 	return (NULL);
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate 
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate #define	USECS_PER_TICK	10000
3350Sstevel@tonic-gate 
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate /*
3380Sstevel@tonic-gate  * Let the kernel create a clusterwide unique message ID
3390Sstevel@tonic-gate  *
3400Sstevel@tonic-gate  * returns 0 on success
3410Sstevel@tonic-gate  *	   1 on failure
3420Sstevel@tonic-gate  */
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate int
mdmn_create_msgid(md_mn_msgid_t * msgid)3450Sstevel@tonic-gate mdmn_create_msgid(md_mn_msgid_t *msgid)
3460Sstevel@tonic-gate {
3470Sstevel@tonic-gate 	md_error_t	mde = mdnullerror;
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate 	if (msgid == NULL) {
3500Sstevel@tonic-gate 		return (1); /* failure */
3510Sstevel@tonic-gate 	}
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 	if (metaioctl(MD_IOCGUNIQMSGID, msgid, &mde, NULL) != 0) {
3540Sstevel@tonic-gate 		msgid->mid_nid = ~0u;
3550Sstevel@tonic-gate 		msgid->mid_time = 0LL;
3560Sstevel@tonic-gate 		return (1); /* failure */
3570Sstevel@tonic-gate 	}
3580Sstevel@tonic-gate 
3590Sstevel@tonic-gate 	/*
3600Sstevel@tonic-gate 	 * mid_smid and mid_oclass are only used for submessages.
3610Sstevel@tonic-gate 	 * mdmn_create_msgid is never called for submessages, as they inherit
3620Sstevel@tonic-gate 	 * the message ID from their parent.
3630Sstevel@tonic-gate 	 * Thus we can safely null out the following fields.
3640Sstevel@tonic-gate 	 */
3650Sstevel@tonic-gate 	msgid->mid_smid = 0;
3660Sstevel@tonic-gate 	msgid->mid_oclass = 0;
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate 	/* if the node_id is not set yet, somethings seems to be wrong */
3690Sstevel@tonic-gate 	if (msgid->mid_nid == ~0u) {
3700Sstevel@tonic-gate 		return (1); /* failure */
3710Sstevel@tonic-gate 	}
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 	return (0); /* success */
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate md_mn_result_t *
copy_result(md_mn_result_t * res)3770Sstevel@tonic-gate copy_result(md_mn_result_t *res)
3780Sstevel@tonic-gate {
3790Sstevel@tonic-gate 	md_mn_result_t *nres;
3800Sstevel@tonic-gate 	nres = Zalloc(sizeof (md_mn_result_t));
3810Sstevel@tonic-gate 	/* It's MSGID_COPY(from, to); */
3820Sstevel@tonic-gate 	MSGID_COPY(&(res->mmr_msgid), &(nres->mmr_msgid));
3830Sstevel@tonic-gate 	nres->mmr_msgtype	= res->mmr_msgtype;
3840Sstevel@tonic-gate 	nres->mmr_setno		= res->mmr_setno;
3850Sstevel@tonic-gate 	nres->mmr_flags		= res->mmr_flags;
3860Sstevel@tonic-gate 	nres->mmr_sender	= res->mmr_sender;
3870Sstevel@tonic-gate 	nres->mmr_failing_node	= res->mmr_failing_node;
3880Sstevel@tonic-gate 	nres->mmr_comm_state	= res->mmr_comm_state;
3890Sstevel@tonic-gate 	nres->mmr_exitval	= res->mmr_exitval;
3900Sstevel@tonic-gate 	nres->mmr_out_size	= res->mmr_out_size;
3910Sstevel@tonic-gate 	nres->mmr_err_size	= res->mmr_err_size;
3920Sstevel@tonic-gate 	if (res->mmr_out_size > 0) {
3930Sstevel@tonic-gate 		nres->mmr_out = Zalloc(res->mmr_out_size);
3940Sstevel@tonic-gate 		bcopy(res->mmr_out, nres->mmr_out, res->mmr_out_size);
3950Sstevel@tonic-gate 	}
3960Sstevel@tonic-gate 	if (res->mmr_err_size > 0) {
3970Sstevel@tonic-gate 		nres->mmr_err = Zalloc(res->mmr_err_size);
3980Sstevel@tonic-gate 		bcopy(res->mmr_err, nres->mmr_err, res->mmr_err_size);
3990Sstevel@tonic-gate 	}
4000Sstevel@tonic-gate 	if (res->mmr_ep.host != '\0') {
4010Sstevel@tonic-gate 		nres->mmr_ep.host = strdup(res->mmr_ep.host);
4020Sstevel@tonic-gate 	}
4030Sstevel@tonic-gate 	if (res->mmr_ep.extra != '\0') {
4040Sstevel@tonic-gate 		nres->mmr_ep.extra = strdup(res->mmr_ep.extra);
4050Sstevel@tonic-gate 	}
4060Sstevel@tonic-gate 	if (res->mmr_ep.name != '\0') {
4070Sstevel@tonic-gate 		nres->mmr_ep.name = strdup(res->mmr_ep.name);
4080Sstevel@tonic-gate 	}
4090Sstevel@tonic-gate 	return (nres);
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate void
free_result(md_mn_result_t * res)4130Sstevel@tonic-gate free_result(md_mn_result_t *res)
4140Sstevel@tonic-gate {
4150Sstevel@tonic-gate 	if (res->mmr_out_size > 0) {
4160Sstevel@tonic-gate 		Free(res->mmr_out);
4170Sstevel@tonic-gate 	}
4180Sstevel@tonic-gate 	if (res->mmr_err_size > 0) {
4190Sstevel@tonic-gate 		Free(res->mmr_err);
4200Sstevel@tonic-gate 	}
4210Sstevel@tonic-gate 	if (res->mmr_ep.host != '\0') {
4220Sstevel@tonic-gate 		Free(res->mmr_ep.host);
4230Sstevel@tonic-gate 	}
4240Sstevel@tonic-gate 	if (res->mmr_ep.extra != '\0') {
4250Sstevel@tonic-gate 		Free(res->mmr_ep.extra);
4260Sstevel@tonic-gate 	}
4270Sstevel@tonic-gate 	if (res->mmr_ep.name != '\0') {
4280Sstevel@tonic-gate 		Free(res->mmr_ep.name);
4290Sstevel@tonic-gate 	}
4300Sstevel@tonic-gate 	Free(res);
4310Sstevel@tonic-gate }
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate 
4340Sstevel@tonic-gate /* allocate a new message and copy a given message into it */
4350Sstevel@tonic-gate md_mn_msg_t *
copy_msg(md_mn_msg_t * msg,md_mn_msg_t * dest)4360Sstevel@tonic-gate copy_msg(md_mn_msg_t *msg, md_mn_msg_t *dest)
4370Sstevel@tonic-gate {
4380Sstevel@tonic-gate 	md_mn_msg_t *nmsg;
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 	nmsg = dest;
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 	if (nmsg == NULL) {
4430Sstevel@tonic-gate 		nmsg = Zalloc(sizeof (md_mn_msg_t));
4440Sstevel@tonic-gate 	}
4450Sstevel@tonic-gate 	if (nmsg->msg_event_data == NULL) {
4460Sstevel@tonic-gate 		nmsg->msg_event_data = Zalloc(msg->msg_event_size);
4470Sstevel@tonic-gate 	}
4480Sstevel@tonic-gate 	/* It's MSGID_COPY(from, to); */
4490Sstevel@tonic-gate 	MSGID_COPY(&(msg->msg_msgid), &(nmsg->msg_msgid));
4500Sstevel@tonic-gate 	nmsg->msg_sender	= msg->msg_sender;
4510Sstevel@tonic-gate 	nmsg->msg_flags		= msg->msg_flags;
4520Sstevel@tonic-gate 	nmsg->msg_setno		= msg->msg_setno;
4530Sstevel@tonic-gate 	nmsg->msg_type		= msg->msg_type;
454*8452SJohn.Wren.Kennedy@Sun.COM 	nmsg->msg_recipient	= msg->msg_recipient;
4550Sstevel@tonic-gate 	nmsg->msg_event_size	= msg->msg_event_size;
4560Sstevel@tonic-gate 	if (msg->msg_event_size > 0) {
4570Sstevel@tonic-gate 		bcopy(msg->msg_event_data, nmsg->msg_event_data,
4580Sstevel@tonic-gate 		    msg->msg_event_size);
4590Sstevel@tonic-gate 	}
4600Sstevel@tonic-gate 	return (nmsg);
4610Sstevel@tonic-gate }
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate void
copy_msg_2(md_mn_msg_t * msg,md_mn_msg_od_t * msgod,int direction)464*8452SJohn.Wren.Kennedy@Sun.COM copy_msg_2(md_mn_msg_t *msg, md_mn_msg_od_t *msgod, int direction)
4650Sstevel@tonic-gate {
4660Sstevel@tonic-gate 	assert((direction == MD_MN_COPY_TO_ONDISK) ||
4670Sstevel@tonic-gate 	    (direction == MD_MN_COPY_TO_INCORE));
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate 	if (direction == MD_MN_COPY_TO_ONDISK) {
4700Sstevel@tonic-gate 		MSGID_COPY(&(msg->msg_msgid), &(msgod->msg_msgid));
4710Sstevel@tonic-gate 		msgod->msg_sender	= msg->msg_sender;
4720Sstevel@tonic-gate 		msgod->msg_flags	= msg->msg_flags;
4730Sstevel@tonic-gate 		msgod->msg_setno	= msg->msg_setno;
4740Sstevel@tonic-gate 		msgod->msg_type		= msg->msg_type;
475*8452SJohn.Wren.Kennedy@Sun.COM 		msgod->msg_recipient	= msg->msg_recipient;
4760Sstevel@tonic-gate 		msgod->msg_od_event_size = msg->msg_event_size;
4770Sstevel@tonic-gate 		/* paranoid checks */
4780Sstevel@tonic-gate 		if (msg->msg_event_size != 0 && msg->msg_event_data != NULL)
4790Sstevel@tonic-gate 			bcopy(msg->msg_event_data,
4800Sstevel@tonic-gate 			    &msgod->msg_od_event_data[0], msg->msg_event_size);
4810Sstevel@tonic-gate 	} else {
4820Sstevel@tonic-gate 		MSGID_COPY(&(msgod->msg_msgid), &(msg->msg_msgid));
4830Sstevel@tonic-gate 		msg->msg_sender	= msgod->msg_sender;
4840Sstevel@tonic-gate 		msg->msg_flags		= msgod->msg_flags;
4850Sstevel@tonic-gate 		msg->msg_setno		= msgod->msg_setno;
4860Sstevel@tonic-gate 		msg->msg_type		= msgod->msg_type;
487*8452SJohn.Wren.Kennedy@Sun.COM 		msg->msg_recipient	= msgod->msg_recipient;
4880Sstevel@tonic-gate 		msg->msg_event_size	= msgod->msg_od_event_size;
4890Sstevel@tonic-gate 		if (msg->msg_event_data == NULL)
4900Sstevel@tonic-gate 			msg->msg_event_data = Zalloc(msg->msg_event_size);
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate 		bcopy(&msgod->msg_od_event_data[0],
4930Sstevel@tonic-gate 		    msg->msg_event_data, msgod->msg_od_event_size);
4940Sstevel@tonic-gate 	}
4950Sstevel@tonic-gate }
4960Sstevel@tonic-gate 
4970Sstevel@tonic-gate /* Free a message */
4980Sstevel@tonic-gate void
free_msg(md_mn_msg_t * msg)4990Sstevel@tonic-gate free_msg(md_mn_msg_t *msg)
5000Sstevel@tonic-gate {
5010Sstevel@tonic-gate 	if (msg->msg_event_size > 0) {
5020Sstevel@tonic-gate 		Free(msg->msg_event_data);
5030Sstevel@tonic-gate 	}
5040Sstevel@tonic-gate 	Free(msg);
5050Sstevel@tonic-gate }
5060Sstevel@tonic-gate 
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate /* The following declarations are only for the next two routines */
5090Sstevel@tonic-gate 
5100Sstevel@tonic-gate md_mn_client_list_t *mdmn_clients;
5110Sstevel@tonic-gate 
5120Sstevel@tonic-gate mutex_t	mcl_mutex;
5130Sstevel@tonic-gate #define	MNGLC_INIT_ONLY	0x0001
5140Sstevel@tonic-gate #define	MNGLC_FOR_REAL	0x0002
5150Sstevel@tonic-gate /*
5160Sstevel@tonic-gate  * mdmn_get_local_clnt(flag)
5170Sstevel@tonic-gate  * If there is a client in the free pool, get one,
5180Sstevel@tonic-gate  * If no client is available, create one.
5190Sstevel@tonic-gate  * Every multithreaded application that uses mdmn_send_message must call it
5200Sstevel@tonic-gate  * single threaded first with special flags so we do the initialization
5210Sstevel@tonic-gate  * stuff in a safe environment.
5220Sstevel@tonic-gate  *
5230Sstevel@tonic-gate  * Input: MNGLC_INIT_ONLY: just initializes the mutex
5240Sstevel@tonic-gate  *        MNGLC_FOR_REAL : do real work
5250Sstevel@tonic-gate  * Output:
5260Sstevel@tonic-gate  *	An rpc client for sending rpc requests to the local commd
5270Sstevel@tonic-gate  *	NULL in case of an error
5280Sstevel@tonic-gate  *
5290Sstevel@tonic-gate  */
5300Sstevel@tonic-gate static CLIENT *
mdmn_get_local_clnt(uint_t flag)5310Sstevel@tonic-gate mdmn_get_local_clnt(uint_t flag)
5320Sstevel@tonic-gate {
5330Sstevel@tonic-gate 	CLIENT *local_daemon;
5340Sstevel@tonic-gate 	static int inited = 0;
5350Sstevel@tonic-gate 	md_mn_client_list_t *tmp;
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate 	if (inited == 0) {
5380Sstevel@tonic-gate 		(void) mutex_init(&mcl_mutex, USYNC_THREAD, NULL);
5390Sstevel@tonic-gate 		inited = 1;
5400Sstevel@tonic-gate 	}
5410Sstevel@tonic-gate 
5420Sstevel@tonic-gate 	if (flag == MNGLC_INIT_ONLY)
5430Sstevel@tonic-gate 		return ((CLIENT *)NULL);
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate 	(void) mutex_lock(&mcl_mutex);
5460Sstevel@tonic-gate 	if (mdmn_clients == (md_mn_client_list_t *)NULL) {
5470Sstevel@tonic-gate 		/* if there is no entry, create a client and return a it */
5480Sstevel@tonic-gate 		local_daemon = meta_client_create(LOCALHOST_IPv4, MDMN_COMMD,
549*8452SJohn.Wren.Kennedy@Sun.COM 		    TWO, "tcp");
5500Sstevel@tonic-gate 	} else {
5510Sstevel@tonic-gate 		/*
5520Sstevel@tonic-gate 		 * If there is an entry from a previous put operation,
5530Sstevel@tonic-gate 		 * remove it from the head of the list and free the list stuff
5540Sstevel@tonic-gate 		 * around it. Then return the client
5550Sstevel@tonic-gate 		 */
5560Sstevel@tonic-gate 		local_daemon = mdmn_clients->mcl_clnt;
5570Sstevel@tonic-gate 		tmp = mdmn_clients;
5580Sstevel@tonic-gate 		mdmn_clients = mdmn_clients->mcl_next;
5590Sstevel@tonic-gate 		Free(tmp);
5600Sstevel@tonic-gate 	}
5610Sstevel@tonic-gate 	(void) mutex_unlock(&mcl_mutex);
5620Sstevel@tonic-gate 
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate 	if (local_daemon == (CLIENT *)NULL) {
5650Sstevel@tonic-gate 		clnt_pcreateerror("local_daemon");
5660Sstevel@tonic-gate 	}
5670Sstevel@tonic-gate 
5680Sstevel@tonic-gate 	return (local_daemon);
5690Sstevel@tonic-gate }
5700Sstevel@tonic-gate 
5710Sstevel@tonic-gate /*
5720Sstevel@tonic-gate  * mdmn_put_local_clnt()
5730Sstevel@tonic-gate  * returns a no longer used client to the pool
5740Sstevel@tonic-gate  *
5750Sstevel@tonic-gate  * Input: an RPC client
5760Sstevel@tonic-gate  * Output: void
5770Sstevel@tonic-gate  */
5780Sstevel@tonic-gate static void
mdmn_put_local_clnt(CLIENT * local_daemon)5790Sstevel@tonic-gate mdmn_put_local_clnt(CLIENT *local_daemon)
5800Sstevel@tonic-gate {
5810Sstevel@tonic-gate 	md_mn_client_list_t *tmp;
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate 	(void) mutex_lock(&mcl_mutex);
5840Sstevel@tonic-gate 
5850Sstevel@tonic-gate 	tmp =  mdmn_clients;
5860Sstevel@tonic-gate 	mdmn_clients = (md_mn_client_list_t *)
5870Sstevel@tonic-gate 	    malloc(sizeof (md_mn_client_list_t));
5880Sstevel@tonic-gate 	mdmn_clients->mcl_clnt = local_daemon;
5890Sstevel@tonic-gate 	mdmn_clients->mcl_next = tmp;
5900Sstevel@tonic-gate 
5910Sstevel@tonic-gate 	(void) mutex_unlock(&mcl_mutex);
5920Sstevel@tonic-gate }
5930Sstevel@tonic-gate 
5940Sstevel@tonic-gate /*
5950Sstevel@tonic-gate  * This is the regular interface for sending a message.
5960Sstevel@tonic-gate  * This function only passes through all arguments to
5970Sstevel@tonic-gate  * mdmn_send_message_with_msgid() and adds a NULL for the message ID.
5980Sstevel@tonic-gate  *
5990Sstevel@tonic-gate  * Normally, you don't have already a message ID for the message you want
6000Sstevel@tonic-gate  * to send.  Only in case of replaying a previously logged message,
6010Sstevel@tonic-gate  * a msgid is already attached to it.
6020Sstevel@tonic-gate  * In that case mdmn_send_message_with_msgid() has to be called directly.
6030Sstevel@tonic-gate  *
604*8452SJohn.Wren.Kennedy@Sun.COM  * The recipient argument is almost always unused, and is therefore typically
605*8452SJohn.Wren.Kennedy@Sun.COM  * set to zero, as zero is an invalid cluster nodeid.  The exceptions are the
606*8452SJohn.Wren.Kennedy@Sun.COM  * marking and clearing of the DRL from a node that is not currently the
607*8452SJohn.Wren.Kennedy@Sun.COM  * owner.  In these cases, the recipient argument will be the nodeid of the
608*8452SJohn.Wren.Kennedy@Sun.COM  * mirror owner, and MD_MSGF_DIRECTED will be set in the flags.  Non-owner
609*8452SJohn.Wren.Kennedy@Sun.COM  * nodes will not receive these messages.
610*8452SJohn.Wren.Kennedy@Sun.COM  *
6110Sstevel@tonic-gate  * Return values / CAVEAT EMPTOR: see mdmn_send_message_with_msgid()
6120Sstevel@tonic-gate  */
6130Sstevel@tonic-gate 
6140Sstevel@tonic-gate int
mdmn_send_message(set_t setno,md_mn_msgtype_t type,uint_t flags,md_mn_nodeid_t recipient,char * data,int size,md_mn_result_t ** result,md_error_t * ep)6150Sstevel@tonic-gate mdmn_send_message(
6160Sstevel@tonic-gate 		set_t setno,
6170Sstevel@tonic-gate 		md_mn_msgtype_t type,
6180Sstevel@tonic-gate 		uint_t flags,
619*8452SJohn.Wren.Kennedy@Sun.COM 		md_mn_nodeid_t recipient,
6200Sstevel@tonic-gate 		char *data,
6210Sstevel@tonic-gate 		int size,
6220Sstevel@tonic-gate 		md_mn_result_t **result,
6230Sstevel@tonic-gate 		md_error_t *ep)
6240Sstevel@tonic-gate {
625*8452SJohn.Wren.Kennedy@Sun.COM 	return (mdmn_send_message_with_msgid(setno, type, flags,
626*8452SJohn.Wren.Kennedy@Sun.COM 	    recipient, data, size, result, MD_NULL_MSGID, ep));
6270Sstevel@tonic-gate }
6280Sstevel@tonic-gate /*
6290Sstevel@tonic-gate  * mdmn_send_message_with_msgid()
6300Sstevel@tonic-gate  * Create a message from the given pieces of data and hand it over
6310Sstevel@tonic-gate  * to the local commd.
6320Sstevel@tonic-gate  * This may fail for various reasons (rpc error / class busy / class locked ...)
6330Sstevel@tonic-gate  * Some error types are immediately deadly, others will cause retries
6340Sstevel@tonic-gate  * until the request is fulfilled or until the retries are ecxceeded.
6350Sstevel@tonic-gate  *
6360Sstevel@tonic-gate  * In case an error is returned it is up to the user to decide what to do.
6370Sstevel@tonic-gate  *
6380Sstevel@tonic-gate  * Returns:
6390Sstevel@tonic-gate  *	0 on success
6400Sstevel@tonic-gate  *	1 if retries1 exceeded
6410Sstevel@tonic-gate  *	2 if retries2 exceeded
6420Sstevel@tonic-gate  *	-1 if connecting to the local daemon failed
6430Sstevel@tonic-gate  *	-2 if the RPC call to the local daemon failed
6440Sstevel@tonic-gate  *	-3 if this node hasn't yet joined the set
6450Sstevel@tonic-gate  *	-4 if any other problem occured
6460Sstevel@tonic-gate  *
6470Sstevel@tonic-gate  * CAVEAT EMPTOR:
6480Sstevel@tonic-gate  *	The caller is responsible for calling free_result() when finished with
6490Sstevel@tonic-gate  *	the results!
6500Sstevel@tonic-gate  */
6510Sstevel@tonic-gate int
mdmn_send_message_with_msgid(set_t setno,md_mn_msgtype_t type,uint_t flags,md_mn_nodeid_t recipient,char * data,int size,md_mn_result_t ** result,md_mn_msgid_t * msgid,md_error_t * ep)6520Sstevel@tonic-gate mdmn_send_message_with_msgid(
6530Sstevel@tonic-gate 		set_t setno,
6540Sstevel@tonic-gate 		md_mn_msgtype_t type,
6550Sstevel@tonic-gate 		uint_t flags,
656*8452SJohn.Wren.Kennedy@Sun.COM 		md_mn_nodeid_t recipient,
6570Sstevel@tonic-gate 		char *data,
6580Sstevel@tonic-gate 		int size,
6590Sstevel@tonic-gate 		md_mn_result_t **result,
6600Sstevel@tonic-gate 		md_mn_msgid_t *msgid,
6610Sstevel@tonic-gate 		md_error_t *ep)
6620Sstevel@tonic-gate {
6630Sstevel@tonic-gate 	uint_t retry1, ticks1, retry2, ticks2;
6640Sstevel@tonic-gate 	int retval;
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate 	CLIENT *local_daemon;
6670Sstevel@tonic-gate 	struct timeval timeout;
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 	md_mn_msg_t msg;
6700Sstevel@tonic-gate 	md_mn_result_t *resp;
6710Sstevel@tonic-gate 
6720Sstevel@tonic-gate 	/*
6730Sstevel@tonic-gate 	 * Special case for multithreaded applications:
6740Sstevel@tonic-gate 	 * When starting up, the application should call mdmn_send_message
6750Sstevel@tonic-gate 	 * single threaded with all parameters set to NULL.
6760Sstevel@tonic-gate 	 * When we detect this we know, we safely can do initialization
6770Sstevel@tonic-gate 	 * stuff here.
6780Sstevel@tonic-gate 	 * We only check for set and type being zero
6790Sstevel@tonic-gate 	 */
6800Sstevel@tonic-gate 	if ((setno == 0) && (type == 0)) {
6810Sstevel@tonic-gate 		/* do all needed initializations here */
6820Sstevel@tonic-gate 		(void) mdmn_get_local_clnt(MNGLC_INIT_ONLY);
6830Sstevel@tonic-gate 		return (0); /* success */
6840Sstevel@tonic-gate 	}
6850Sstevel@tonic-gate 
6860Sstevel@tonic-gate 
6870Sstevel@tonic-gate 	/* did the caller specify space to store the result pointer? */
6880Sstevel@tonic-gate 	if (result == (md_mn_result_t **)NULL) {
6890Sstevel@tonic-gate 		syslog(LOG_INFO, dgettext(TEXT_DOMAIN,
6900Sstevel@tonic-gate 		    "FATAL, can not allocate result structure\n"));
6910Sstevel@tonic-gate 		return (-4);
6920Sstevel@tonic-gate 	}
6930Sstevel@tonic-gate 	*result = NULL;
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 	/* Replay messages already have their msgID */
6960Sstevel@tonic-gate 	if ((flags & MD_MSGF_REPLAY_MSG) == 0) {
6970Sstevel@tonic-gate 		if (mdmn_create_msgid(&msg.msg_msgid) != 0) {
6980Sstevel@tonic-gate 			syslog(LOG_INFO, dgettext(TEXT_DOMAIN,
6990Sstevel@tonic-gate 			    "FATAL, can not create message ID\n"));
7000Sstevel@tonic-gate 			return (-4);
7010Sstevel@tonic-gate 		}
7020Sstevel@tonic-gate 	} else {
7030Sstevel@tonic-gate 		/* in this case a message ID must be specified */
7040Sstevel@tonic-gate 		assert(msgid != MD_NULL_MSGID);
7050Sstevel@tonic-gate 		MSGID_COPY(msgid, &msg.msg_msgid);
7060Sstevel@tonic-gate 	}
7070Sstevel@tonic-gate 
7080Sstevel@tonic-gate 
7090Sstevel@tonic-gate 	/*
7100Sstevel@tonic-gate 	 * When setting the flags, additionally apply the
7110Sstevel@tonic-gate 	 * default flags for this message type.
7120Sstevel@tonic-gate 	 */
7130Sstevel@tonic-gate 	msg.msg_flags		= flags;
7140Sstevel@tonic-gate 	msg.msg_setno		= setno;
715*8452SJohn.Wren.Kennedy@Sun.COM 	msg.msg_recipient	= recipient;
7160Sstevel@tonic-gate 	msg.msg_type		= type;
7170Sstevel@tonic-gate 	msg.msg_event_size	= size;
7180Sstevel@tonic-gate 	msg.msg_event_data	= data;
7190Sstevel@tonic-gate 
7200Sstevel@tonic-gate 	/*
7210Sstevel@tonic-gate 	 * For the timeout pick the specific timeout for the message times the
7220Sstevel@tonic-gate 	 * the maximum number of nodes.
7230Sstevel@tonic-gate 	 * This is a better estimate than 1 hour or 3 days or never.
7240Sstevel@tonic-gate 	 */
7250Sstevel@tonic-gate 	timeout.tv_sec = mdmn_get_timeout(type) * NNODES;
7260Sstevel@tonic-gate 	timeout.tv_usec = 0;
7270Sstevel@tonic-gate 
7280Sstevel@tonic-gate 	if (flags & MD_MSGF_VERBOSE) {
7290Sstevel@tonic-gate 		syslog(LOG_INFO, "send_message: ID=(%d, 0x%llx-%d)\n",
7300Sstevel@tonic-gate 		    MSGID_ELEMS(msg.msg_msgid));
7310Sstevel@tonic-gate 	}
7320Sstevel@tonic-gate 
7330Sstevel@tonic-gate 	/* get an RPC client to the local commd */
7340Sstevel@tonic-gate 	local_daemon = mdmn_get_local_clnt(MNGLC_FOR_REAL);
7350Sstevel@tonic-gate 	if (local_daemon == (CLIENT *)NULL) {
7360Sstevel@tonic-gate 		return (-1);
7370Sstevel@tonic-gate 	}
7380Sstevel@tonic-gate 	clnt_control(local_daemon, CLSET_TIMEOUT, (char *)&timeout);
7390Sstevel@tonic-gate 
7400Sstevel@tonic-gate 	retry1 = msg_table[type].mte_retry1;
7410Sstevel@tonic-gate 	ticks1 = msg_table[type].mte_ticks1;
7420Sstevel@tonic-gate 	retry2 = msg_table[type].mte_retry2;
7430Sstevel@tonic-gate 	ticks2 = msg_table[type].mte_ticks2;
7440Sstevel@tonic-gate 
7450Sstevel@tonic-gate 	/*
7460Sstevel@tonic-gate 	 * run that loop until:
7470Sstevel@tonic-gate 	 * - commstate is Ok
7480Sstevel@tonic-gate 	 * - deadly commstate occured
7490Sstevel@tonic-gate 	 * - retries1 or retries2 exceeded
7500Sstevel@tonic-gate 	 */
7510Sstevel@tonic-gate 	for (; ; ) {
752*8452SJohn.Wren.Kennedy@Sun.COM 		*result = mdmn_send_2(&msg, local_daemon, 0);
7530Sstevel@tonic-gate 		resp = *result;
7540Sstevel@tonic-gate 		if (resp != (md_mn_result_t *)NULL) {
7550Sstevel@tonic-gate 			/* Bingo! */
7560Sstevel@tonic-gate 			if (resp->mmr_comm_state == MDMNE_ACK) {
7570Sstevel@tonic-gate 				retval = 0;
7580Sstevel@tonic-gate 				goto out;
7590Sstevel@tonic-gate 			}
7600Sstevel@tonic-gate 			/* Hmm... what if there's no handler? */
7610Sstevel@tonic-gate 			if (resp->mmr_comm_state == MDMNE_NO_HANDLER) {
7620Sstevel@tonic-gate 				retval = 0;
7630Sstevel@tonic-gate 				goto out;
7640Sstevel@tonic-gate 
7650Sstevel@tonic-gate 			}
7660Sstevel@tonic-gate 			/*
7670Sstevel@tonic-gate 			 * This node didn't yet join the disk set. It is not
7680Sstevel@tonic-gate 			 * supposed to send any messages then.
7690Sstevel@tonic-gate 			 * This is deadly (no retries)
7700Sstevel@tonic-gate 			 */
7710Sstevel@tonic-gate 			if (resp->mmr_comm_state == MDMNE_NOT_JOINED) {
7720Sstevel@tonic-gate 				retval = -3;
7730Sstevel@tonic-gate 				goto out;
7740Sstevel@tonic-gate 
7750Sstevel@tonic-gate 			}
7760Sstevel@tonic-gate 			/* these two are deadly too (no retries) */
7770Sstevel@tonic-gate 			if ((resp->mmr_comm_state == MDMNE_NO_WAKEUP_ENTRY) ||
7780Sstevel@tonic-gate 			    (resp->mmr_comm_state == MDMNE_LOG_FAIL)) {
7790Sstevel@tonic-gate 				retval = -4;
7800Sstevel@tonic-gate 				goto out;
7810Sstevel@tonic-gate 
7820Sstevel@tonic-gate 			}
7830Sstevel@tonic-gate 			/* Class busy? Use retry1 */
7840Sstevel@tonic-gate 			if (resp->mmr_comm_state == MDMNE_CLASS_BUSY) {
7850Sstevel@tonic-gate 				if (retry1-- == 0) {
7860Sstevel@tonic-gate 					retval = 1; /* retry1 exceeded */
7870Sstevel@tonic-gate 					goto out;
7880Sstevel@tonic-gate 				}
7890Sstevel@tonic-gate 				(void) usleep(ticks1 * USECS_PER_TICK);
7900Sstevel@tonic-gate 				free_result(resp);
7910Sstevel@tonic-gate 
7920Sstevel@tonic-gate 				if (flags & MD_MSGF_VERBOSE)
7930Sstevel@tonic-gate 					(void) printf("#Resend1 ID=(%d, "
7940Sstevel@tonic-gate 					    "0x%llx-%d)\n",
7950Sstevel@tonic-gate 					    MSGID_ELEMS(msg.msg_msgid));
7960Sstevel@tonic-gate 				continue;
7970Sstevel@tonic-gate 			}
7980Sstevel@tonic-gate 			if ((resp->mmr_comm_state == MDMNE_CLASS_LOCKED) ||
7990Sstevel@tonic-gate 			    (resp->mmr_comm_state == MDMNE_ABORT)) {
8000Sstevel@tonic-gate 				/*
8010Sstevel@tonic-gate 				 * Be patient, wait for 1 secs and try again.
8020Sstevel@tonic-gate 				 * It's not likely that the ABORT condition ever
8030Sstevel@tonic-gate 				 * goes away, but it won't hurt to retry
8040Sstevel@tonic-gate 				 */
8050Sstevel@tonic-gate 				free_result(resp);
8060Sstevel@tonic-gate 				(void) sleep(1);
8070Sstevel@tonic-gate 				continue;
8080Sstevel@tonic-gate 			}
8090Sstevel@tonic-gate 			if (resp->mmr_comm_state == MDMNE_SUSPENDED) {
8100Sstevel@tonic-gate 				if (flags & MD_MSGF_FAIL_ON_SUSPEND) {
8110Sstevel@tonic-gate 					/* caller wants us to fail here */
8120Sstevel@tonic-gate 					(void) mddserror(ep,
8130Sstevel@tonic-gate 					    MDE_DS_NOTNOW_RECONFIG, setno,
8140Sstevel@tonic-gate 					    mynode(), mynode(), NULL);
8150Sstevel@tonic-gate 					retval = -4;
8160Sstevel@tonic-gate 					goto out;
8170Sstevel@tonic-gate 				} else {
8180Sstevel@tonic-gate 					/* wait for 1 secs and try again. */
8190Sstevel@tonic-gate 					free_result(resp);
8200Sstevel@tonic-gate 					(void) sleep(1);
8210Sstevel@tonic-gate 					continue;
8220Sstevel@tonic-gate 				}
8230Sstevel@tonic-gate 			}
8240Sstevel@tonic-gate 		} else {
8250Sstevel@tonic-gate 			/*
8260Sstevel@tonic-gate 			 * If we get a NULL back from the rpc call, try to
8270Sstevel@tonic-gate 			 * reinitialize the client.
8280Sstevel@tonic-gate 			 * Depending on retries2 we try again, or not.
8290Sstevel@tonic-gate 			 */
8300Sstevel@tonic-gate 			syslog(LOG_INFO,
8310Sstevel@tonic-gate 			    "send_message: ID=(%d, 0x%llx-%d) resp = NULL\n",
8320Sstevel@tonic-gate 			    MSGID_ELEMS(msg.msg_msgid));
8330Sstevel@tonic-gate 
8340Sstevel@tonic-gate 			clnt_destroy(local_daemon);
8350Sstevel@tonic-gate 			local_daemon = mdmn_get_local_clnt(MNGLC_FOR_REAL);
8360Sstevel@tonic-gate 
8370Sstevel@tonic-gate 			if (local_daemon == (CLIENT *)NULL) {
8380Sstevel@tonic-gate 				return (-1);
8390Sstevel@tonic-gate 			}
8400Sstevel@tonic-gate 			clnt_control(local_daemon, CLSET_TIMEOUT,
8410Sstevel@tonic-gate 			    (char *)&timeout);
8420Sstevel@tonic-gate 		}
8430Sstevel@tonic-gate 
8440Sstevel@tonic-gate 		/*
8450Sstevel@tonic-gate 		 * If we are here, either resp is zero or resp is non-zero
8460Sstevel@tonic-gate 		 * but some commstate not mentioned above occured.
8470Sstevel@tonic-gate 		 * In either case we use retry2
8480Sstevel@tonic-gate 		 */
8490Sstevel@tonic-gate 		if (retry2-- == 0) {
8500Sstevel@tonic-gate 			syslog(LOG_INFO, dgettext(TEXT_DOMAIN,
8510Sstevel@tonic-gate 			    "send_message: (%d, 0x%llx-%d) retry2 exceeded\n"),
8520Sstevel@tonic-gate 			    MSGID_ELEMS(msg.msg_msgid));
8530Sstevel@tonic-gate 
8540Sstevel@tonic-gate 			retval = 2; /* retry2 exceeded */
8550Sstevel@tonic-gate 			goto out;
8560Sstevel@tonic-gate 		}
8570Sstevel@tonic-gate 		if (flags & MD_MSGF_VERBOSE) {
8580Sstevel@tonic-gate 			syslog(LOG_DEBUG, dgettext(TEXT_DOMAIN,
8590Sstevel@tonic-gate 			    "send_message: (%d, 0x%llx-%d) resend on retry2\n"),
8600Sstevel@tonic-gate 			    MSGID_ELEMS(msg.msg_msgid));
8610Sstevel@tonic-gate 		}
8620Sstevel@tonic-gate 
8630Sstevel@tonic-gate 		(void) usleep(ticks2 * USECS_PER_TICK);
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate 		if (resp != (md_mn_result_t *)NULL) {
8660Sstevel@tonic-gate 			free_result(resp);
8670Sstevel@tonic-gate 		}
8680Sstevel@tonic-gate 	}
8690Sstevel@tonic-gate out:
8700Sstevel@tonic-gate 	mdmn_put_local_clnt(local_daemon);
8710Sstevel@tonic-gate 	return (retval);
8720Sstevel@tonic-gate }
8730Sstevel@tonic-gate 
8740Sstevel@tonic-gate /*
8750Sstevel@tonic-gate  * suspend the commd for a given set/class combination.
8760Sstevel@tonic-gate  *
8770Sstevel@tonic-gate  * Parameter:
8780Sstevel@tonic-gate  *	set number or 0 (meaning all sets)
8790Sstevel@tonic-gate  *	class number or 0 (meaning all classes)
8800Sstevel@tonic-gate  *
8810Sstevel@tonic-gate  * Returns:
8820Sstevel@tonic-gate  *	0 on success (set is suspended and all messages drained)
8830Sstevel@tonic-gate  *	MDE_DS_COMMDCTL_SUSPEND_NYD if set is not yet drained
8840Sstevel@tonic-gate  *	MDE_DS_COMMDCTL_SUSPEND_FAIL if any failure occurred
8850Sstevel@tonic-gate  */
8860Sstevel@tonic-gate int
mdmn_suspend(set_t setno,md_mn_msgclass_t class,long timeout)8873073Sjkennedy mdmn_suspend(set_t setno, md_mn_msgclass_t class, long timeout)
8880Sstevel@tonic-gate {
8893073Sjkennedy 	int			*resp;
8903073Sjkennedy 	CLIENT			*local_daemon;
8913073Sjkennedy 	md_mn_set_and_class_t	msc;
8923073Sjkennedy 	md_error_t		xep = mdnullerror;
8930Sstevel@tonic-gate 
8940Sstevel@tonic-gate 	if ((setno >= MD_MAXSETS) || (class >= MD_MN_NCLASSES)) {
8950Sstevel@tonic-gate 		return (MDE_DS_COMMDCTL_SUSPEND_FAIL);
8960Sstevel@tonic-gate 	}
897*8452SJohn.Wren.Kennedy@Sun.COM 	local_daemon = meta_client_create(LOCALHOST_IPv4, MDMN_COMMD, TWO,
898*8452SJohn.Wren.Kennedy@Sun.COM 	    "tcp");
8990Sstevel@tonic-gate 	if (local_daemon == (CLIENT *)NULL) {
9000Sstevel@tonic-gate 		clnt_pcreateerror("local_daemon");
9010Sstevel@tonic-gate 		return (MDE_DS_COMMDCTL_SUSPEND_FAIL);
9020Sstevel@tonic-gate 	}
9033073Sjkennedy 
9043073Sjkennedy 	if (timeout != 0) {
9053073Sjkennedy 		if (cl_sto(local_daemon, LOCALHOST_IPv4, timeout, &xep) != 0) {
9063073Sjkennedy 			clnt_destroy(local_daemon);
9073073Sjkennedy 			return (1);
9083073Sjkennedy 		}
9093073Sjkennedy 	}
9103073Sjkennedy 
9110Sstevel@tonic-gate 	msc.msc_set = setno;
9120Sstevel@tonic-gate 	msc.msc_class = class;
9130Sstevel@tonic-gate 	msc.msc_flags = 0;
9140Sstevel@tonic-gate 
915*8452SJohn.Wren.Kennedy@Sun.COM 	resp = mdmn_comm_suspend_2(&msc, local_daemon, 0);
9160Sstevel@tonic-gate 	clnt_destroy(local_daemon);
9170Sstevel@tonic-gate 
9180Sstevel@tonic-gate 	if (resp == NULL) {
9190Sstevel@tonic-gate 		return (MDE_DS_COMMDCTL_SUSPEND_FAIL);
9200Sstevel@tonic-gate 	}
9210Sstevel@tonic-gate 
9220Sstevel@tonic-gate 	if (*resp == MDMNE_ACK) {
9230Sstevel@tonic-gate 		/* set successfully drained, no outstanding messages */
9240Sstevel@tonic-gate 		return (0);
9250Sstevel@tonic-gate 	}
9260Sstevel@tonic-gate 	if (*resp != MDMNE_SET_NOT_DRAINED) {
9270Sstevel@tonic-gate 		/* some error occurred */
9280Sstevel@tonic-gate 		return (MDE_DS_COMMDCTL_SUSPEND_FAIL);
9290Sstevel@tonic-gate 	}
9300Sstevel@tonic-gate 
9310Sstevel@tonic-gate 	/* still outstanding messages, return not yet drained failure */
9320Sstevel@tonic-gate 	return (MDE_DS_COMMDCTL_SUSPEND_NYD);
9330Sstevel@tonic-gate }
9340Sstevel@tonic-gate 
9350Sstevel@tonic-gate /*
9360Sstevel@tonic-gate  * resume the commd for a given set/class combination.
9370Sstevel@tonic-gate  *
9380Sstevel@tonic-gate  * Parameter:
9390Sstevel@tonic-gate  *	set number or 0 (meaning all sets)
9400Sstevel@tonic-gate  *	class number or 0 (meaning all classes)
9410Sstevel@tonic-gate  *
9420Sstevel@tonic-gate  * Returns:
9430Sstevel@tonic-gate  *	0 on success
9440Sstevel@tonic-gate  *	MDE_DS_COMMDCTL_RESUME_FAIL on failure
9450Sstevel@tonic-gate  */
9460Sstevel@tonic-gate int
mdmn_resume(set_t setno,md_mn_msgclass_t class,uint_t flags,long timeout)9473073Sjkennedy mdmn_resume(set_t setno, md_mn_msgclass_t class, uint_t flags, long timeout)
9480Sstevel@tonic-gate {
9493073Sjkennedy 	md_mn_set_and_class_t	msc;
9503073Sjkennedy 	int			ret = MDE_DS_COMMDCTL_RESUME_FAIL;
9513073Sjkennedy 	int			*resp;
9523073Sjkennedy 	CLIENT			*local_daemon;
9533073Sjkennedy 	md_error_t		xep = mdnullerror;
9540Sstevel@tonic-gate 
9550Sstevel@tonic-gate 	if ((setno >= MD_MAXSETS) || (class >= MD_MN_NCLASSES)) {
9560Sstevel@tonic-gate 		return (MDE_DS_COMMDCTL_RESUME_FAIL);
9570Sstevel@tonic-gate 	}
958*8452SJohn.Wren.Kennedy@Sun.COM 	local_daemon = meta_client_create(LOCALHOST_IPv4, MDMN_COMMD, TWO,
959*8452SJohn.Wren.Kennedy@Sun.COM 	    "tcp");
9600Sstevel@tonic-gate 	if (local_daemon == (CLIENT *)NULL) {
9610Sstevel@tonic-gate 		clnt_pcreateerror("local_daemon");
9620Sstevel@tonic-gate 		return (MDE_DS_COMMDCTL_RESUME_FAIL);
9630Sstevel@tonic-gate 	}
9640Sstevel@tonic-gate 
9653073Sjkennedy 	if (timeout != 0) {
9663073Sjkennedy 		if (cl_sto(local_daemon, LOCALHOST_IPv4, timeout, &xep) != 0) {
9673073Sjkennedy 			clnt_destroy(local_daemon);
9683073Sjkennedy 			return (1);
9693073Sjkennedy 		}
9703073Sjkennedy 	}
9713073Sjkennedy 
9720Sstevel@tonic-gate 	msc.msc_set = setno;
9730Sstevel@tonic-gate 	msc.msc_class = class;
9740Sstevel@tonic-gate 	msc.msc_flags = flags;
9750Sstevel@tonic-gate 
976*8452SJohn.Wren.Kennedy@Sun.COM 	resp = mdmn_comm_resume_2(&msc, local_daemon, 0);
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate 	if (resp != NULL) {
9790Sstevel@tonic-gate 		if (*resp == MDMNE_ACK) {
9800Sstevel@tonic-gate 			ret = 0;
9810Sstevel@tonic-gate 		}
9820Sstevel@tonic-gate 		Free(resp);
9830Sstevel@tonic-gate 	}
9840Sstevel@tonic-gate 
9850Sstevel@tonic-gate 	clnt_destroy(local_daemon);
9860Sstevel@tonic-gate 	return (ret);
9870Sstevel@tonic-gate }
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate /*
9900Sstevel@tonic-gate  * abort all communication
9910Sstevel@tonic-gate  *
9920Sstevel@tonic-gate  * returns void, because: if *this* get's an error what do you want to do?
9930Sstevel@tonic-gate  */
9940Sstevel@tonic-gate void
mdmn_abort(void)9950Sstevel@tonic-gate mdmn_abort(void)
9960Sstevel@tonic-gate {
9970Sstevel@tonic-gate 	char *dummy = "abort";
9980Sstevel@tonic-gate 	md_mn_result_t	*resultp = NULL;
9990Sstevel@tonic-gate 	md_error_t	mdne = mdnullerror;
10000Sstevel@tonic-gate 
10010Sstevel@tonic-gate 	(void) mdmn_send_message(0, /* No set is needed for this message */
1002*8452SJohn.Wren.Kennedy@Sun.COM 	    MD_MN_MSG_ABORT, MD_MSGF_LOCAL_ONLY, 0,
1003*8452SJohn.Wren.Kennedy@Sun.COM 	    dummy, sizeof (dummy), &resultp, &mdne);
10040Sstevel@tonic-gate 
10050Sstevel@tonic-gate 	if (resultp != NULL) {
10060Sstevel@tonic-gate 		Free(resultp);
10070Sstevel@tonic-gate 	}
10080Sstevel@tonic-gate }
10090Sstevel@tonic-gate 
10100Sstevel@tonic-gate /*
10110Sstevel@tonic-gate  * trigger the reinitialization for a given set.
10120Sstevel@tonic-gate  *
10130Sstevel@tonic-gate  * Parameter: set number
10140Sstevel@tonic-gate  *
10150Sstevel@tonic-gate  * Returns:
10160Sstevel@tonic-gate  *	0 on success
10170Sstevel@tonic-gate  *	1 on failure
10180Sstevel@tonic-gate  */
10190Sstevel@tonic-gate int
mdmn_reinit_set(set_t setno,long timeout)10203073Sjkennedy mdmn_reinit_set(set_t setno, long timeout)
10210Sstevel@tonic-gate {
10223073Sjkennedy 	int		ret = 1;
10233073Sjkennedy 	int		*resp;
10243073Sjkennedy 	CLIENT 		*local_daemon;
10253073Sjkennedy 	md_error_t	xep = mdnullerror;
10260Sstevel@tonic-gate 
10270Sstevel@tonic-gate 	if ((setno == 0) || (setno >= MD_MAXSETS)) {
10280Sstevel@tonic-gate 		return (1);
10290Sstevel@tonic-gate 	}
1030*8452SJohn.Wren.Kennedy@Sun.COM 	local_daemon = meta_client_create(LOCALHOST_IPv4, MDMN_COMMD, TWO,
1031*8452SJohn.Wren.Kennedy@Sun.COM 	    "tcp");
10320Sstevel@tonic-gate 	if (local_daemon == (CLIENT *)NULL) {
10330Sstevel@tonic-gate 		clnt_pcreateerror("local_daemon");
10340Sstevel@tonic-gate 		return (1);
10350Sstevel@tonic-gate 	}
10360Sstevel@tonic-gate 
10373073Sjkennedy 	if (timeout != 0) {
10383073Sjkennedy 		if (cl_sto(local_daemon, LOCALHOST_IPv4, timeout, &xep) != 0) {
10393073Sjkennedy 			clnt_destroy(local_daemon);
10403073Sjkennedy 			return (1);
10413073Sjkennedy 		}
10423073Sjkennedy 	}
10433073Sjkennedy 
1044*8452SJohn.Wren.Kennedy@Sun.COM 	resp = mdmn_comm_reinit_set_2(&setno, local_daemon, 0);
10450Sstevel@tonic-gate 
10460Sstevel@tonic-gate 	if (resp != NULL) {
10470Sstevel@tonic-gate 		if (*resp == MDMNE_ACK) {
10480Sstevel@tonic-gate 			ret = 0;
10490Sstevel@tonic-gate 		}
10500Sstevel@tonic-gate 		Free(resp);
10510Sstevel@tonic-gate 	}
10520Sstevel@tonic-gate 
10530Sstevel@tonic-gate 	clnt_destroy(local_daemon);
10540Sstevel@tonic-gate 	return (ret);
10550Sstevel@tonic-gate }
10560Sstevel@tonic-gate 
10570Sstevel@tonic-gate 
10580Sstevel@tonic-gate /*
10590Sstevel@tonic-gate  * Lock a single message type from being processed on this node
10600Sstevel@tonic-gate  *
10610Sstevel@tonic-gate  * Parameter: md_mn_msgtype_t msgtype, uint_t locktype
10620Sstevel@tonic-gate  *
10630Sstevel@tonic-gate  * Returns:
10640Sstevel@tonic-gate  *	0 on success
10650Sstevel@tonic-gate  *	1 on failure
10660Sstevel@tonic-gate  */
10670Sstevel@tonic-gate int
mdmn_msgtype_lock(md_mn_msgtype_t msgtype,uint_t locktype)10680Sstevel@tonic-gate mdmn_msgtype_lock(md_mn_msgtype_t msgtype, uint_t locktype)
10690Sstevel@tonic-gate {
10700Sstevel@tonic-gate 	int			ret = 1;
10710Sstevel@tonic-gate 	int			*resp;
10720Sstevel@tonic-gate 	CLIENT			*local_daemon;
10730Sstevel@tonic-gate 	md_mn_type_and_lock_t	mmtl;
10740Sstevel@tonic-gate 
10750Sstevel@tonic-gate 
10760Sstevel@tonic-gate 	if ((msgtype == 0) || (msgtype >= MD_MN_NMESSAGES)) {
10770Sstevel@tonic-gate 		return (1);
10780Sstevel@tonic-gate 	}
1079*8452SJohn.Wren.Kennedy@Sun.COM 	local_daemon = meta_client_create(LOCALHOST_IPv4, MDMN_COMMD, TWO,
1080*8452SJohn.Wren.Kennedy@Sun.COM 	    "tcp");
10810Sstevel@tonic-gate 	if (local_daemon == (CLIENT *)NULL) {
10820Sstevel@tonic-gate 		clnt_pcreateerror("local_daemon");
10830Sstevel@tonic-gate 		return (1);
10840Sstevel@tonic-gate 	}
10850Sstevel@tonic-gate 	mmtl.mmtl_type = msgtype;
10860Sstevel@tonic-gate 	mmtl.mmtl_lock = locktype;
10870Sstevel@tonic-gate 
1088*8452SJohn.Wren.Kennedy@Sun.COM 	resp = mdmn_comm_msglock_2(&mmtl, local_daemon, 0);
10890Sstevel@tonic-gate 
10900Sstevel@tonic-gate 	if (resp != NULL) {
10910Sstevel@tonic-gate 		if (*resp == MDMNE_ACK) {
10920Sstevel@tonic-gate 			ret = 0;
10930Sstevel@tonic-gate 		}
10940Sstevel@tonic-gate 		Free(resp);
10950Sstevel@tonic-gate 	}
10960Sstevel@tonic-gate 
10970Sstevel@tonic-gate 	clnt_destroy(local_daemon);
10980Sstevel@tonic-gate 	return (ret);
10990Sstevel@tonic-gate }
1100