1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * Just in case we're not in a build environment, make sure that
31*0Sstevel@tonic-gate  * TEXT_DOMAIN gets set to something.
32*0Sstevel@tonic-gate  */
33*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
34*0Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
35*0Sstevel@tonic-gate #endif
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate /*
38*0Sstevel@tonic-gate  * Mediator functions
39*0Sstevel@tonic-gate  */
40*0Sstevel@tonic-gate 
41*0Sstevel@tonic-gate #include <meta.h>
42*0Sstevel@tonic-gate #include <metamed.h>
43*0Sstevel@tonic-gate #include <dlfcn.h>
44*0Sstevel@tonic-gate #include <sdssc.h>
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate /*
47*0Sstevel@tonic-gate  * There are too many external factors that affect the timing of the
48*0Sstevel@tonic-gate  * operations, so we set the timeout to a very large value, in this
49*0Sstevel@tonic-gate  * case 1 day, which should handle HW timeouts, large configurations,
50*0Sstevel@tonic-gate  * and other potential delays.
51*0Sstevel@tonic-gate  */
52*0Sstevel@tonic-gate #define	CL_LONG_TMO	86400L			/* 1 day */
53*0Sstevel@tonic-gate #define	CL_MEDIUM_TMO	3600L			/* 1 hour */
54*0Sstevel@tonic-gate #define	CL_SHORT_TMO	600L			/* 10 minutes */
55*0Sstevel@tonic-gate #define	CL_DEF_TMO	10L			/* 10 seconds */
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate static	md_timeval32_t def_rpcb_timeout =  { MD_CLNT_CREATE_TOUT, 0 };
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate /*
60*0Sstevel@tonic-gate  * RPC handle
61*0Sstevel@tonic-gate  */
62*0Sstevel@tonic-gate typedef struct {
63*0Sstevel@tonic-gate 	char	*hostname;
64*0Sstevel@tonic-gate 	CLIENT	*clntp;
65*0Sstevel@tonic-gate } med_handle_t;
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate /*
68*0Sstevel@tonic-gate  * Data to be sent from med_clnt_create_timed to med_create_helper via
69*0Sstevel@tonic-gate  * meta_client_create_retry.
70*0Sstevel@tonic-gate  */
71*0Sstevel@tonic-gate typedef struct {
72*0Sstevel@tonic-gate 	rpcprog_t	mcd_program;	/* RPC program designation */
73*0Sstevel@tonic-gate 	rpcvers_t	mcd_version;	/* RPC version */
74*0Sstevel@tonic-gate 	char		*mcd_nettype;	/* Type of network to use for RPC */
75*0Sstevel@tonic-gate } med_create_data_t;
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate /*
78*0Sstevel@tonic-gate  * Perform the work of actually doing the clnt_create for
79*0Sstevel@tonic-gate  * meta_client_create_retry.
80*0Sstevel@tonic-gate  */
81*0Sstevel@tonic-gate static CLIENT *
82*0Sstevel@tonic-gate med_create_helper(char *hostname, void *private, struct timeval *time_out)
83*0Sstevel@tonic-gate {
84*0Sstevel@tonic-gate 	med_create_data_t	*cd = (med_create_data_t *)private;
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate 	return (clnt_create_timed(hostname, cd->mcd_program, cd->mcd_version,
87*0Sstevel@tonic-gate 		cd->mcd_nettype, time_out));
88*0Sstevel@tonic-gate }
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate static
91*0Sstevel@tonic-gate CLIENT *med_clnt_create_timed(
92*0Sstevel@tonic-gate 	char *hostname,
93*0Sstevel@tonic-gate 	const ulong_t prog,
94*0Sstevel@tonic-gate 	const ulong_t vers,
95*0Sstevel@tonic-gate 	char *nettype,
96*0Sstevel@tonic-gate 	const md_timeval32_t *tp
97*0Sstevel@tonic-gate )
98*0Sstevel@tonic-gate {
99*0Sstevel@tonic-gate 	med_create_data_t	cd;	/* Create data. */
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	cd.mcd_program = prog;
102*0Sstevel@tonic-gate 	cd.mcd_version = vers;
103*0Sstevel@tonic-gate 	cd.mcd_nettype = nettype;
104*0Sstevel@tonic-gate 	return (meta_client_create_retry(hostname, med_create_helper,
105*0Sstevel@tonic-gate 		(void *)&cd, (time_t)tp->tv_sec, NULL));
106*0Sstevel@tonic-gate }
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate /*
109*0Sstevel@tonic-gate  * Set the timeout value for this client handle.
110*0Sstevel@tonic-gate  */
111*0Sstevel@tonic-gate static int
112*0Sstevel@tonic-gate cl_sto_medd(
113*0Sstevel@tonic-gate 	CLIENT		*clntp,
114*0Sstevel@tonic-gate 	char		*hostname,
115*0Sstevel@tonic-gate 	long		time_out,
116*0Sstevel@tonic-gate 	md_error_t	*ep
117*0Sstevel@tonic-gate )
118*0Sstevel@tonic-gate {
119*0Sstevel@tonic-gate 	md_timeval32_t	nto;
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate 	(void) memset(&nto, '\0', sizeof (nto));
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate 	nto.tv_sec = time_out;
124*0Sstevel@tonic-gate 
125*0Sstevel@tonic-gate 	if (clnt_control(clntp, CLSET_TIMEOUT, (char *)&nto) != TRUE)
126*0Sstevel@tonic-gate 		return (mdrpcerror(ep, clntp, hostname,
127*0Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "metad client set timeout")));
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate 	return (0);
130*0Sstevel@tonic-gate }
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate /*
133*0Sstevel@tonic-gate  * close RPC connection
134*0Sstevel@tonic-gate  */
135*0Sstevel@tonic-gate static void
136*0Sstevel@tonic-gate close_medd(
137*0Sstevel@tonic-gate 	med_handle_t	*hp
138*0Sstevel@tonic-gate )
139*0Sstevel@tonic-gate {
140*0Sstevel@tonic-gate 	assert(hp != NULL);
141*0Sstevel@tonic-gate 	if (hp->hostname != NULL) {
142*0Sstevel@tonic-gate 		Free(hp->hostname);
143*0Sstevel@tonic-gate 	}
144*0Sstevel@tonic-gate 	if (hp->clntp != NULL) {
145*0Sstevel@tonic-gate 		auth_destroy(hp->clntp->cl_auth);
146*0Sstevel@tonic-gate 		clnt_destroy(hp->clntp);
147*0Sstevel@tonic-gate 	}
148*0Sstevel@tonic-gate 	Free(hp);
149*0Sstevel@tonic-gate }
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate /*
152*0Sstevel@tonic-gate  * open RPC connection to rpc.medd
153*0Sstevel@tonic-gate  */
154*0Sstevel@tonic-gate static med_handle_t *
155*0Sstevel@tonic-gate open_medd(
156*0Sstevel@tonic-gate 	char		*hostname,
157*0Sstevel@tonic-gate 	long		time_out,
158*0Sstevel@tonic-gate 	md_error_t	*ep
159*0Sstevel@tonic-gate )
160*0Sstevel@tonic-gate {
161*0Sstevel@tonic-gate 	CLIENT		*clntp;
162*0Sstevel@tonic-gate 	med_handle_t	*hp;
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	/* default to local host */
165*0Sstevel@tonic-gate 	if ((hostname == NULL) || (*hostname == '\0'))
166*0Sstevel@tonic-gate 		hostname = mynode();
167*0Sstevel@tonic-gate 
168*0Sstevel@tonic-gate 	/* open RPC connection */
169*0Sstevel@tonic-gate 	assert(hostname != NULL);
170*0Sstevel@tonic-gate 	if ((clntp = med_clnt_create_timed(hostname, MED_PROG, MED_VERS,
171*0Sstevel@tonic-gate 	    "tcp", &def_rpcb_timeout)) == NULL) {
172*0Sstevel@tonic-gate 		if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED)
173*0Sstevel@tonic-gate 			clnt_pcreateerror(hostname);
174*0Sstevel@tonic-gate 		(void) mdrpccreateerror(ep, hostname,
175*0Sstevel@tonic-gate 		    "medd med_clnt_create_timed");
176*0Sstevel@tonic-gate 		return (NULL);
177*0Sstevel@tonic-gate 	} else {
178*0Sstevel@tonic-gate 		auth_destroy(clntp->cl_auth);
179*0Sstevel@tonic-gate 		clntp->cl_auth = authsys_create_default();
180*0Sstevel@tonic-gate 		assert(clntp->cl_auth != NULL);
181*0Sstevel@tonic-gate 	}
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 	if (cl_sto_medd(clntp, hostname, time_out, ep) != 0)
184*0Sstevel@tonic-gate 		return (NULL);
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate 	/* return connection */
187*0Sstevel@tonic-gate 	hp = Zalloc(sizeof (*hp));
188*0Sstevel@tonic-gate 	hp->hostname = Strdup(hostname);
189*0Sstevel@tonic-gate 	hp->clntp = clntp;
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate 	return (hp);
192*0Sstevel@tonic-gate }
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate /*
195*0Sstevel@tonic-gate  * steal and convert med_err_t
196*0Sstevel@tonic-gate  */
197*0Sstevel@tonic-gate int
198*0Sstevel@tonic-gate meddstealerror(
199*0Sstevel@tonic-gate 	md_error_t	*ep,
200*0Sstevel@tonic-gate 	med_err_t	*medep
201*0Sstevel@tonic-gate )
202*0Sstevel@tonic-gate {
203*0Sstevel@tonic-gate 	char		buf[BUFSIZ];
204*0Sstevel@tonic-gate 	char		*p = buf;
205*0Sstevel@tonic-gate 	size_t		psize = BUFSIZ;
206*0Sstevel@tonic-gate 	char		*emsg;
207*0Sstevel@tonic-gate 	int		rval = -1;
208*0Sstevel@tonic-gate 
209*0Sstevel@tonic-gate 	/* no error */
210*0Sstevel@tonic-gate 	if (medep->med_errno == 0) {
211*0Sstevel@tonic-gate 		/* assert(medep->name == NULL); */
212*0Sstevel@tonic-gate 		rval = 0;
213*0Sstevel@tonic-gate 		goto out;
214*0Sstevel@tonic-gate 	}
215*0Sstevel@tonic-gate 
216*0Sstevel@tonic-gate 	/* steal error */
217*0Sstevel@tonic-gate 	if ((medep->med_node != NULL) && (medep->med_node[0] != '\0')) {
218*0Sstevel@tonic-gate 		(void) snprintf(p, psize, "%s: ", medep->med_node);
219*0Sstevel@tonic-gate 		p = &buf[strlen(buf)];
220*0Sstevel@tonic-gate 		psize = buf + BUFSIZ - p;
221*0Sstevel@tonic-gate 	}
222*0Sstevel@tonic-gate 
223*0Sstevel@tonic-gate 	if ((medep->med_misc != NULL) && (medep->med_misc[0] != '\0')) {
224*0Sstevel@tonic-gate 		(void) snprintf(p, psize, "%s: ", medep->med_misc);
225*0Sstevel@tonic-gate 		p = &buf[strlen(buf)];
226*0Sstevel@tonic-gate 		psize = buf + BUFSIZ - p;
227*0Sstevel@tonic-gate 	}
228*0Sstevel@tonic-gate 
229*0Sstevel@tonic-gate 	if (medep->med_errno < 0) {
230*0Sstevel@tonic-gate 		if ((emsg = med_errnum_to_str(medep->med_errno)) != NULL)
231*0Sstevel@tonic-gate 			(void) snprintf(p, psize, "%s", emsg);
232*0Sstevel@tonic-gate 		else
233*0Sstevel@tonic-gate 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
234*0Sstevel@tonic-gate 			    "unknown mediator errno %d\n"), medep->med_errno);
235*0Sstevel@tonic-gate 	} else {
236*0Sstevel@tonic-gate 		if ((emsg = strerror(medep->med_errno)) != NULL)
237*0Sstevel@tonic-gate 			(void) snprintf(p, psize, "%s", emsg);
238*0Sstevel@tonic-gate 		else
239*0Sstevel@tonic-gate 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
240*0Sstevel@tonic-gate 			    "errno %d out of range"), medep->med_errno);
241*0Sstevel@tonic-gate 	}
242*0Sstevel@tonic-gate 	(void) mderror(ep, MDE_MED_ERROR, buf);
243*0Sstevel@tonic-gate 
244*0Sstevel@tonic-gate 	/* cleanup, return success */
245*0Sstevel@tonic-gate out:
246*0Sstevel@tonic-gate 	if (medep->med_node != NULL)
247*0Sstevel@tonic-gate 		Free(medep->med_node);
248*0Sstevel@tonic-gate 	if (medep->med_misc != NULL)
249*0Sstevel@tonic-gate 		Free(medep->med_misc);
250*0Sstevel@tonic-gate 	(void) memset(medep, 0, sizeof (*medep));
251*0Sstevel@tonic-gate 	return (rval);
252*0Sstevel@tonic-gate }
253*0Sstevel@tonic-gate 
254*0Sstevel@tonic-gate static med_handle_t *
255*0Sstevel@tonic-gate open_medd_wrap(
256*0Sstevel@tonic-gate 	md_h_t		*mdhp,
257*0Sstevel@tonic-gate 	long		time_out,
258*0Sstevel@tonic-gate 	md_error_t	*ep
259*0Sstevel@tonic-gate )
260*0Sstevel@tonic-gate {
261*0Sstevel@tonic-gate 	med_handle_t		*hp = NULL;
262*0Sstevel@tonic-gate 	int			i;
263*0Sstevel@tonic-gate 	char    		*hnm;
264*0Sstevel@tonic-gate 
265*0Sstevel@tonic-gate 	assert(mdhp && mdhp->a_cnt > 0);
266*0Sstevel@tonic-gate 
267*0Sstevel@tonic-gate 	/* Loop through the hosts listed */
268*0Sstevel@tonic-gate 	i = min(mdhp->a_cnt, MAX_HOST_ADDRS) - 1;
269*0Sstevel@tonic-gate 	for (; i >= 0; i--) {
270*0Sstevel@tonic-gate 		hnm = mdhp->a_nm[i];
271*0Sstevel@tonic-gate 
272*0Sstevel@tonic-gate 		if ((hp = open_medd(hnm, time_out, ep)) == NULL) {
273*0Sstevel@tonic-gate 			if (mdanyrpcerror(ep) && i != 0) {
274*0Sstevel@tonic-gate 				mdclrerror(ep);
275*0Sstevel@tonic-gate 				continue;
276*0Sstevel@tonic-gate 			}
277*0Sstevel@tonic-gate 		}
278*0Sstevel@tonic-gate 		return (hp);
279*0Sstevel@tonic-gate 	}
280*0Sstevel@tonic-gate 
281*0Sstevel@tonic-gate 	rpc_createerr.cf_stat = RPC_CANTSEND;
282*0Sstevel@tonic-gate 	rpc_createerr.cf_error.re_status = 0;
283*0Sstevel@tonic-gate 	(void) mdrpccreateerror(ep, mdhp->a_nm[0],
284*0Sstevel@tonic-gate 	    dgettext(TEXT_DOMAIN, "medd open wrap"));
285*0Sstevel@tonic-gate 
286*0Sstevel@tonic-gate 	return (NULL);
287*0Sstevel@tonic-gate }
288*0Sstevel@tonic-gate 
289*0Sstevel@tonic-gate static int
290*0Sstevel@tonic-gate setup_med_transtab(md_error_t *ep)
291*0Sstevel@tonic-gate {
292*0Sstevel@tonic-gate 	mddb_med_t_parm_t	*tp = NULL;
293*0Sstevel@tonic-gate 	struct	stat		statb;
294*0Sstevel@tonic-gate 	int			i;
295*0Sstevel@tonic-gate 	size_t			alloc_size = 0;
296*0Sstevel@tonic-gate 	int			err = 0;
297*0Sstevel@tonic-gate 
298*0Sstevel@tonic-gate 
299*0Sstevel@tonic-gate 	if ((tp = Zalloc(sizeof (mddb_med_t_parm_t))) == NULL)
300*0Sstevel@tonic-gate 		return (mdsyserror(ep, ENOMEM, "setup_med_transtab"));
301*0Sstevel@tonic-gate 
302*0Sstevel@tonic-gate 	if (metaioctl(MD_MED_GET_TLEN, tp, &tp->med_tp_mde, NULL) != 0) {
303*0Sstevel@tonic-gate 		err = mdstealerror(ep, &tp->med_tp_mde);
304*0Sstevel@tonic-gate 		goto out;
305*0Sstevel@tonic-gate 	}
306*0Sstevel@tonic-gate 
307*0Sstevel@tonic-gate 	if (tp->med_tp_setup == 1)
308*0Sstevel@tonic-gate 		goto out;
309*0Sstevel@tonic-gate 
310*0Sstevel@tonic-gate 	alloc_size = (sizeof (mddb_med_t_parm_t) - sizeof (mddb_med_t_ent_t)) +
311*0Sstevel@tonic-gate 	    (sizeof (mddb_med_t_ent_t) * tp->med_tp_nents);
312*0Sstevel@tonic-gate 
313*0Sstevel@tonic-gate 	if ((tp = Realloc(tp, alloc_size)) == NULL) {
314*0Sstevel@tonic-gate 		err = mdsyserror(ep, ENOMEM, "setup_med_transtab");
315*0Sstevel@tonic-gate 		goto out;
316*0Sstevel@tonic-gate 	}
317*0Sstevel@tonic-gate 
318*0Sstevel@tonic-gate 	if (metaioctl(MD_MED_GET_T, tp, &tp->med_tp_mde, NULL) != 0) {
319*0Sstevel@tonic-gate 		err = mdstealerror(ep, &tp->med_tp_mde);
320*0Sstevel@tonic-gate 		goto out;
321*0Sstevel@tonic-gate 	}
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate 	for (i = 0; i < tp->med_tp_nents; i++) {
324*0Sstevel@tonic-gate 		if (meta_stat(tp->med_tp_ents[i].med_te_nm, &statb) == -1) {
325*0Sstevel@tonic-gate 			md_perror("setup_med_transtab(): stat():");
326*0Sstevel@tonic-gate 			tp->med_tp_ents[i].med_te_dev = NODEV64;
327*0Sstevel@tonic-gate 		} else {
328*0Sstevel@tonic-gate 			tp->med_tp_ents[i].med_te_dev =
329*0Sstevel@tonic-gate 				meta_expldev(statb.st_rdev);
330*0Sstevel@tonic-gate 		}
331*0Sstevel@tonic-gate 	}
332*0Sstevel@tonic-gate 
333*0Sstevel@tonic-gate 	if (metaioctl(MD_MED_SET_T, tp, &tp->med_tp_mde, NULL) != 0)
334*0Sstevel@tonic-gate 		err = mdstealerror(ep, &tp->med_tp_mde);
335*0Sstevel@tonic-gate 
336*0Sstevel@tonic-gate out:
337*0Sstevel@tonic-gate 	Free(tp);
338*0Sstevel@tonic-gate 	return (err);
339*0Sstevel@tonic-gate }
340*0Sstevel@tonic-gate 
341*0Sstevel@tonic-gate /*
342*0Sstevel@tonic-gate  * Externals
343*0Sstevel@tonic-gate  */
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate /*
346*0Sstevel@tonic-gate  * NULLPROC - just returns a response
347*0Sstevel@tonic-gate  */
348*0Sstevel@tonic-gate int
349*0Sstevel@tonic-gate clnt_med_null(
350*0Sstevel@tonic-gate 	char			*hostname,
351*0Sstevel@tonic-gate 	md_error_t		*ep
352*0Sstevel@tonic-gate )
353*0Sstevel@tonic-gate {
354*0Sstevel@tonic-gate 	med_handle_t		*hp;
355*0Sstevel@tonic-gate 	med_err_t		res;
356*0Sstevel@tonic-gate 
357*0Sstevel@tonic-gate 	/* initialize */
358*0Sstevel@tonic-gate 	mdclrerror(ep);
359*0Sstevel@tonic-gate 
360*0Sstevel@tonic-gate 	/* do it */
361*0Sstevel@tonic-gate 	if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL)
362*0Sstevel@tonic-gate 		return (-1);
363*0Sstevel@tonic-gate 
364*0Sstevel@tonic-gate 	if (med_null_1(NULL, &res, hp->clntp) != RPC_SUCCESS)
365*0Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hostname,
366*0Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd nullproc"));
367*0Sstevel@tonic-gate 
368*0Sstevel@tonic-gate 	close_medd(hp);
369*0Sstevel@tonic-gate 
370*0Sstevel@tonic-gate 	xdr_free(xdr_med_err_t, (char *)&res);
371*0Sstevel@tonic-gate 
372*0Sstevel@tonic-gate 	if (! mdisok(ep))
373*0Sstevel@tonic-gate 		return (-1);
374*0Sstevel@tonic-gate 
375*0Sstevel@tonic-gate 	return (0);
376*0Sstevel@tonic-gate }
377*0Sstevel@tonic-gate 
378*0Sstevel@tonic-gate /*
379*0Sstevel@tonic-gate  * Update the mediator information on the mediator.
380*0Sstevel@tonic-gate  * *** This is not normally called from user code, the kernel does this! ***
381*0Sstevel@tonic-gate  */
382*0Sstevel@tonic-gate int
383*0Sstevel@tonic-gate clnt_med_upd_data(
384*0Sstevel@tonic-gate 	md_h_t			*mdhp,
385*0Sstevel@tonic-gate 	mdsetname_t		*sp,
386*0Sstevel@tonic-gate 	med_data_t		*meddp,
387*0Sstevel@tonic-gate 	md_error_t		*ep
388*0Sstevel@tonic-gate )
389*0Sstevel@tonic-gate {
390*0Sstevel@tonic-gate 	med_handle_t		*hp;
391*0Sstevel@tonic-gate 	med_upd_data_args_t	args;
392*0Sstevel@tonic-gate 	med_err_t		res;
393*0Sstevel@tonic-gate 	md_set_desc		*sd;
394*0Sstevel@tonic-gate 
395*0Sstevel@tonic-gate 	/* initialize */
396*0Sstevel@tonic-gate 	mdclrerror(ep);
397*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
398*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
399*0Sstevel@tonic-gate 
400*0Sstevel@tonic-gate 	/* build args */
401*0Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
402*0Sstevel@tonic-gate 		return (-1);
403*0Sstevel@tonic-gate 
404*0Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
405*0Sstevel@tonic-gate 		/*
406*0Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
407*0Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
408*0Sstevel@tonic-gate 		 * any node to access mediator information.
409*0Sstevel@tonic-gate 		 *
410*0Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
411*0Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
412*0Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
413*0Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
414*0Sstevel@tonic-gate 		 *
415*0Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
416*0Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
417*0Sstevel@tonic-gate 		 * mediator data.
418*0Sstevel@tonic-gate 		 */
419*0Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
420*0Sstevel@tonic-gate 	else
421*0Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
422*0Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
423*0Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
424*0Sstevel@tonic-gate 	args.med_data = *meddp;
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate 	/* do it */
427*0Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
428*0Sstevel@tonic-gate 		return (-1);
429*0Sstevel@tonic-gate 
430*0Sstevel@tonic-gate 	if (med_upd_data_1(&args, &res, hp->clntp) != RPC_SUCCESS)
431*0Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
432*0Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd update data"));
433*0Sstevel@tonic-gate 	else
434*0Sstevel@tonic-gate 		(void) meddstealerror(ep, &res);
435*0Sstevel@tonic-gate 
436*0Sstevel@tonic-gate 	close_medd(hp);
437*0Sstevel@tonic-gate 
438*0Sstevel@tonic-gate 	xdr_free(xdr_med_upd_data_args_t, (char *)&args);
439*0Sstevel@tonic-gate 	xdr_free(xdr_med_err_t, (char *)&res);
440*0Sstevel@tonic-gate 
441*0Sstevel@tonic-gate 	if (! mdisok(ep))
442*0Sstevel@tonic-gate 		return (-1);
443*0Sstevel@tonic-gate 
444*0Sstevel@tonic-gate 	return (0);
445*0Sstevel@tonic-gate }
446*0Sstevel@tonic-gate 
447*0Sstevel@tonic-gate /*
448*0Sstevel@tonic-gate  * Get the mediator data for this client from the mediator
449*0Sstevel@tonic-gate  */
450*0Sstevel@tonic-gate int
451*0Sstevel@tonic-gate clnt_med_get_data(
452*0Sstevel@tonic-gate 	md_h_t			*mdhp,
453*0Sstevel@tonic-gate 	mdsetname_t		*sp,
454*0Sstevel@tonic-gate 	med_data_t		*meddp,
455*0Sstevel@tonic-gate 	md_error_t		*ep
456*0Sstevel@tonic-gate )
457*0Sstevel@tonic-gate {
458*0Sstevel@tonic-gate 	med_handle_t		*hp;
459*0Sstevel@tonic-gate 	med_args_t		args;
460*0Sstevel@tonic-gate 	med_get_data_res_t	res;
461*0Sstevel@tonic-gate 	int			rval = -1;
462*0Sstevel@tonic-gate 	md_set_desc		*sd;
463*0Sstevel@tonic-gate 
464*0Sstevel@tonic-gate 	/* initialize */
465*0Sstevel@tonic-gate 	mdclrerror(ep);
466*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
467*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
468*0Sstevel@tonic-gate 
469*0Sstevel@tonic-gate 	/* build args */
470*0Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
471*0Sstevel@tonic-gate 		return (-1);
472*0Sstevel@tonic-gate 
473*0Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
474*0Sstevel@tonic-gate 		/*
475*0Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
476*0Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
477*0Sstevel@tonic-gate 		 * any node to access mediator information.
478*0Sstevel@tonic-gate 		 *
479*0Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
480*0Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
481*0Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
482*0Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
483*0Sstevel@tonic-gate 		 *
484*0Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
485*0Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
486*0Sstevel@tonic-gate 		 * mediator data.
487*0Sstevel@tonic-gate 		 */
488*0Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
489*0Sstevel@tonic-gate 	else
490*0Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
491*0Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
492*0Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
493*0Sstevel@tonic-gate 
494*0Sstevel@tonic-gate 	/* do it */
495*0Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
496*0Sstevel@tonic-gate 		return (-1);
497*0Sstevel@tonic-gate 
498*0Sstevel@tonic-gate 	if (med_get_data_1(&args, &res, hp->clntp) != RPC_SUCCESS)
499*0Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
500*0Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd get data"));
501*0Sstevel@tonic-gate 	else
502*0Sstevel@tonic-gate 		(void) meddstealerror(ep, &res.med_status);
503*0Sstevel@tonic-gate 
504*0Sstevel@tonic-gate 	close_medd(hp);
505*0Sstevel@tonic-gate 
506*0Sstevel@tonic-gate 	if (mdisok(ep)) {
507*0Sstevel@tonic-gate 		/* do something with the results */
508*0Sstevel@tonic-gate 		(void) memmove(meddp, &res.med_data, sizeof (med_data_t));
509*0Sstevel@tonic-gate 		rval = 0;
510*0Sstevel@tonic-gate 	}
511*0Sstevel@tonic-gate 
512*0Sstevel@tonic-gate 	xdr_free(xdr_med_args_t, (char *)&args);
513*0Sstevel@tonic-gate 	xdr_free(xdr_med_get_data_res_t, (char *)&res);
514*0Sstevel@tonic-gate 
515*0Sstevel@tonic-gate 	return (rval);
516*0Sstevel@tonic-gate }
517*0Sstevel@tonic-gate 
518*0Sstevel@tonic-gate /*
519*0Sstevel@tonic-gate  * Update the mediator record on the mediator.
520*0Sstevel@tonic-gate  */
521*0Sstevel@tonic-gate int
522*0Sstevel@tonic-gate clnt_med_upd_rec(
523*0Sstevel@tonic-gate 	md_h_t			*mdhp,
524*0Sstevel@tonic-gate 	mdsetname_t		*sp,
525*0Sstevel@tonic-gate 	med_rec_t		*medrp,
526*0Sstevel@tonic-gate 	md_error_t		*ep
527*0Sstevel@tonic-gate )
528*0Sstevel@tonic-gate {
529*0Sstevel@tonic-gate 	med_handle_t		*hp;
530*0Sstevel@tonic-gate 	med_upd_rec_args_t	args;
531*0Sstevel@tonic-gate 	med_err_t		res;
532*0Sstevel@tonic-gate 	md_set_desc		*sd;
533*0Sstevel@tonic-gate 
534*0Sstevel@tonic-gate 	/* initialize */
535*0Sstevel@tonic-gate 	mdclrerror(ep);
536*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
537*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
538*0Sstevel@tonic-gate 
539*0Sstevel@tonic-gate 	/* build args */
540*0Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
541*0Sstevel@tonic-gate 		return (-1);
542*0Sstevel@tonic-gate 
543*0Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
544*0Sstevel@tonic-gate 		/*
545*0Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
546*0Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
547*0Sstevel@tonic-gate 		 * any node to access mediator information.
548*0Sstevel@tonic-gate 		 *
549*0Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
550*0Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
551*0Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
552*0Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
553*0Sstevel@tonic-gate 		 *
554*0Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
555*0Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
556*0Sstevel@tonic-gate 		 * mediator data.
557*0Sstevel@tonic-gate 		 */
558*0Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
559*0Sstevel@tonic-gate 	else
560*0Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
561*0Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
562*0Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
563*0Sstevel@tonic-gate 	args.med_flags = 0;
564*0Sstevel@tonic-gate 	args.med_rec = *medrp;			/* structure assignment */
565*0Sstevel@tonic-gate 
566*0Sstevel@tonic-gate 	/* do it */
567*0Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
568*0Sstevel@tonic-gate 		return (-1);
569*0Sstevel@tonic-gate 
570*0Sstevel@tonic-gate 	if (med_upd_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS)
571*0Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
572*0Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd update record"));
573*0Sstevel@tonic-gate 	else
574*0Sstevel@tonic-gate 		(void) meddstealerror(ep, &res);
575*0Sstevel@tonic-gate 
576*0Sstevel@tonic-gate 	close_medd(hp);
577*0Sstevel@tonic-gate 
578*0Sstevel@tonic-gate 	xdr_free(xdr_med_upd_rec_args_t, (char *)&args);
579*0Sstevel@tonic-gate 	xdr_free(xdr_med_err_t, (char *)&res);
580*0Sstevel@tonic-gate 
581*0Sstevel@tonic-gate 	if (! mdisok(ep))
582*0Sstevel@tonic-gate 		return (-1);
583*0Sstevel@tonic-gate 
584*0Sstevel@tonic-gate 	return (0);
585*0Sstevel@tonic-gate }
586*0Sstevel@tonic-gate 
587*0Sstevel@tonic-gate /*
588*0Sstevel@tonic-gate  * Get the mediator record for this client from the mediator
589*0Sstevel@tonic-gate  */
590*0Sstevel@tonic-gate int
591*0Sstevel@tonic-gate clnt_med_get_rec(
592*0Sstevel@tonic-gate 	md_h_t			*mdhp,
593*0Sstevel@tonic-gate 	mdsetname_t		*sp,
594*0Sstevel@tonic-gate 	med_rec_t		*medrp,
595*0Sstevel@tonic-gate 	md_error_t		*ep
596*0Sstevel@tonic-gate )
597*0Sstevel@tonic-gate {
598*0Sstevel@tonic-gate 	med_handle_t		*hp;
599*0Sstevel@tonic-gate 	med_args_t		args;
600*0Sstevel@tonic-gate 	med_get_rec_res_t	res;
601*0Sstevel@tonic-gate 	int			rval = -1;
602*0Sstevel@tonic-gate 	md_set_desc		*sd;
603*0Sstevel@tonic-gate 
604*0Sstevel@tonic-gate 	/* initialize */
605*0Sstevel@tonic-gate 	mdclrerror(ep);
606*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
607*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
608*0Sstevel@tonic-gate 
609*0Sstevel@tonic-gate 	/* build args */
610*0Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
611*0Sstevel@tonic-gate 		return (-1);
612*0Sstevel@tonic-gate 
613*0Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
614*0Sstevel@tonic-gate 		/*
615*0Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
616*0Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
617*0Sstevel@tonic-gate 		 * any node to access mediator information.
618*0Sstevel@tonic-gate 		 *
619*0Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
620*0Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
621*0Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
622*0Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
623*0Sstevel@tonic-gate 		 *
624*0Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
625*0Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
626*0Sstevel@tonic-gate 		 * mediator data.
627*0Sstevel@tonic-gate 		 */
628*0Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
629*0Sstevel@tonic-gate 	else
630*0Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
631*0Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
632*0Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
633*0Sstevel@tonic-gate 
634*0Sstevel@tonic-gate 	/* do it */
635*0Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
636*0Sstevel@tonic-gate 		return (-1);
637*0Sstevel@tonic-gate 
638*0Sstevel@tonic-gate 	if (med_get_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS)
639*0Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
640*0Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd get record"));
641*0Sstevel@tonic-gate 	else
642*0Sstevel@tonic-gate 		(void) meddstealerror(ep, &res.med_status);
643*0Sstevel@tonic-gate 
644*0Sstevel@tonic-gate 	close_medd(hp);
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate 	if (mdisok(ep)) {
647*0Sstevel@tonic-gate 		/* do something with the results */
648*0Sstevel@tonic-gate 		(void) memmove(medrp, &res.med_rec, sizeof (med_rec_t));
649*0Sstevel@tonic-gate 		rval = 0;
650*0Sstevel@tonic-gate 	}
651*0Sstevel@tonic-gate 
652*0Sstevel@tonic-gate 	xdr_free(xdr_med_args_t, (char *)&args);
653*0Sstevel@tonic-gate 	xdr_free(xdr_med_get_rec_res_t, (char *)&res);
654*0Sstevel@tonic-gate 
655*0Sstevel@tonic-gate 	return (rval);
656*0Sstevel@tonic-gate }
657*0Sstevel@tonic-gate 
658*0Sstevel@tonic-gate /*
659*0Sstevel@tonic-gate  * Get the name of the host from the mediator daemon.
660*0Sstevel@tonic-gate  */
661*0Sstevel@tonic-gate int
662*0Sstevel@tonic-gate clnt_med_hostname(
663*0Sstevel@tonic-gate 	char			*hostname,
664*0Sstevel@tonic-gate 	char			**ret_hostname,
665*0Sstevel@tonic-gate 	md_error_t		*ep
666*0Sstevel@tonic-gate )
667*0Sstevel@tonic-gate {
668*0Sstevel@tonic-gate 	med_handle_t		*hp;
669*0Sstevel@tonic-gate 	med_hnm_res_t		res;
670*0Sstevel@tonic-gate 	int			rval = -1;
671*0Sstevel@tonic-gate 
672*0Sstevel@tonic-gate 	/* initialize */
673*0Sstevel@tonic-gate 	mdclrerror(ep);
674*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
675*0Sstevel@tonic-gate 
676*0Sstevel@tonic-gate 	/* No args */
677*0Sstevel@tonic-gate 
678*0Sstevel@tonic-gate 	/* do it */
679*0Sstevel@tonic-gate 	if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL)
680*0Sstevel@tonic-gate 		return (-1);
681*0Sstevel@tonic-gate 
682*0Sstevel@tonic-gate 	if (med_hostname_1(NULL, &res, hp->clntp) != RPC_SUCCESS)
683*0Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hostname,
684*0Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd hostname"));
685*0Sstevel@tonic-gate 	else
686*0Sstevel@tonic-gate 		(void) meddstealerror(ep, &res.med_status);
687*0Sstevel@tonic-gate 
688*0Sstevel@tonic-gate 	close_medd(hp);
689*0Sstevel@tonic-gate 
690*0Sstevel@tonic-gate 	if (mdisok(ep)) {
691*0Sstevel@tonic-gate 		/* do something with the results */
692*0Sstevel@tonic-gate 		rval = 0;
693*0Sstevel@tonic-gate 
694*0Sstevel@tonic-gate 		if (ret_hostname != NULL)
695*0Sstevel@tonic-gate 			*ret_hostname = Strdup(res.med_hnm);
696*0Sstevel@tonic-gate 	}
697*0Sstevel@tonic-gate 
698*0Sstevel@tonic-gate 	xdr_free(xdr_med_hnm_res_t, (char *)&res);
699*0Sstevel@tonic-gate 
700*0Sstevel@tonic-gate 	return (rval);
701*0Sstevel@tonic-gate }
702*0Sstevel@tonic-gate 
703*0Sstevel@tonic-gate int
704*0Sstevel@tonic-gate meta_med_hnm2ip(md_hi_arr_t *mp, md_error_t *ep)
705*0Sstevel@tonic-gate {
706*0Sstevel@tonic-gate 	int		i, j;
707*0Sstevel@tonic-gate 	int		max_meds;
708*0Sstevel@tonic-gate 
709*0Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
710*0Sstevel@tonic-gate 		return (-1);
711*0Sstevel@tonic-gate 
712*0Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
713*0Sstevel@tonic-gate 		mp->n_lst[i].a_flg = 0;
714*0Sstevel@tonic-gate 		/* See if this is the local host */
715*0Sstevel@tonic-gate 		if (mp->n_lst[i].a_cnt > 0 &&
716*0Sstevel@tonic-gate 		    strcmp(mp->n_lst[i].a_nm[0], mynode()) == NULL)
717*0Sstevel@tonic-gate 			mp->n_lst[i].a_flg |= NMIP_F_LOCAL;
718*0Sstevel@tonic-gate 
719*0Sstevel@tonic-gate 		for (j = 0; j < mp->n_lst[i].a_cnt; j++) {
720*0Sstevel@tonic-gate 			struct hostent	*hp;
721*0Sstevel@tonic-gate 			char		*hnm = mp->n_lst[i].a_nm[j];
722*0Sstevel@tonic-gate 
723*0Sstevel@tonic-gate 			/*
724*0Sstevel@tonic-gate 			 * Cluster nodename support
725*0Sstevel@tonic-gate 			 *
726*0Sstevel@tonic-gate 			 * See if the clustering code can give us an IP addr
727*0Sstevel@tonic-gate 			 * for the stored name. If not, find it the old way
728*0Sstevel@tonic-gate 			 * which will use the public interface.
729*0Sstevel@tonic-gate 			 */
730*0Sstevel@tonic-gate 			if (sdssc_get_priv_ipaddr(mp->n_lst[i].a_nm[j],
731*0Sstevel@tonic-gate 			    (struct in_addr *)&mp->n_lst[i].a_ip[j]) !=
732*0Sstevel@tonic-gate 					SDSSC_OKAY) {
733*0Sstevel@tonic-gate 				if ((hp = gethostbyname(hnm)) == NULL)
734*0Sstevel@tonic-gate 					return (mdsyserror(ep, EADDRNOTAVAIL,
735*0Sstevel@tonic-gate 					    hnm));
736*0Sstevel@tonic-gate 
737*0Sstevel@tonic-gate 				/* We only do INET addresses */
738*0Sstevel@tonic-gate 				if (hp->h_addrtype != AF_INET)
739*0Sstevel@tonic-gate 					return (mdsyserror(ep, EPFNOSUPPORT,
740*0Sstevel@tonic-gate 					    hnm));
741*0Sstevel@tonic-gate 
742*0Sstevel@tonic-gate 				/* We take the first address only */
743*0Sstevel@tonic-gate 				if (*hp->h_addr_list) {
744*0Sstevel@tonic-gate 					(void) memmove(&mp->n_lst[i].a_ip[j],
745*0Sstevel@tonic-gate 					    *hp->h_addr_list,
746*0Sstevel@tonic-gate 					    sizeof (struct in_addr));
747*0Sstevel@tonic-gate 				} else
748*0Sstevel@tonic-gate 					return (mdsyserror(ep, EADDRNOTAVAIL,
749*0Sstevel@tonic-gate 					    hnm));
750*0Sstevel@tonic-gate 			}
751*0Sstevel@tonic-gate 
752*0Sstevel@tonic-gate 		}
753*0Sstevel@tonic-gate 	}
754*0Sstevel@tonic-gate 	return (0);
755*0Sstevel@tonic-gate }
756*0Sstevel@tonic-gate 
757*0Sstevel@tonic-gate int
758*0Sstevel@tonic-gate meta_h2hi(md_h_arr_t *mdhp, md_hi_arr_t *mdhip, md_error_t *ep)
759*0Sstevel@tonic-gate {
760*0Sstevel@tonic-gate 	int			i, j;
761*0Sstevel@tonic-gate 	int			max_meds;
762*0Sstevel@tonic-gate 
763*0Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
764*0Sstevel@tonic-gate 		return (-1);
765*0Sstevel@tonic-gate 
766*0Sstevel@tonic-gate 	mdhip->n_cnt = mdhp->n_cnt;
767*0Sstevel@tonic-gate 
768*0Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
769*0Sstevel@tonic-gate 		mdhip->n_lst[i].a_flg = 0;
770*0Sstevel@tonic-gate 		mdhip->n_lst[i].a_cnt = mdhp->n_lst[i].a_cnt;
771*0Sstevel@tonic-gate 		if (mdhp->n_lst[i].a_cnt == 0)
772*0Sstevel@tonic-gate 			continue;
773*0Sstevel@tonic-gate 		for (j = 0; j < mdhp->n_lst[i].a_cnt; j++)
774*0Sstevel@tonic-gate 			(void) strcpy(mdhip->n_lst[i].a_nm[j],
775*0Sstevel@tonic-gate 			    mdhp->n_lst[i].a_nm[j]);
776*0Sstevel@tonic-gate 	}
777*0Sstevel@tonic-gate 	return (0);
778*0Sstevel@tonic-gate }
779*0Sstevel@tonic-gate 
780*0Sstevel@tonic-gate int
781*0Sstevel@tonic-gate meta_hi2h(md_hi_arr_t *mdhip, md_h_arr_t *mdhp, md_error_t *ep)
782*0Sstevel@tonic-gate {
783*0Sstevel@tonic-gate 	int			i, j;
784*0Sstevel@tonic-gate 	int			max_meds;
785*0Sstevel@tonic-gate 
786*0Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
787*0Sstevel@tonic-gate 		return (-1);
788*0Sstevel@tonic-gate 
789*0Sstevel@tonic-gate 	mdhp->n_cnt = mdhip->n_cnt;
790*0Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
791*0Sstevel@tonic-gate 		mdhp->n_lst[i].a_cnt = mdhip->n_lst[i].a_cnt;
792*0Sstevel@tonic-gate 		if (mdhip->n_lst[i].a_cnt == 0)
793*0Sstevel@tonic-gate 			continue;
794*0Sstevel@tonic-gate 		for (j = 0; j < mdhip->n_lst[i].a_cnt; j++)
795*0Sstevel@tonic-gate 			(void) strcpy(mdhp->n_lst[i].a_nm[j],
796*0Sstevel@tonic-gate 			    mdhip->n_lst[i].a_nm[j]);
797*0Sstevel@tonic-gate 	}
798*0Sstevel@tonic-gate 	return (0);
799*0Sstevel@tonic-gate }
800*0Sstevel@tonic-gate 
801*0Sstevel@tonic-gate int
802*0Sstevel@tonic-gate setup_med_cfg(
803*0Sstevel@tonic-gate 	mdsetname_t		*sp,
804*0Sstevel@tonic-gate 	mddb_config_t		*cp,
805*0Sstevel@tonic-gate 	int			force,
806*0Sstevel@tonic-gate 	md_error_t		*ep
807*0Sstevel@tonic-gate )
808*0Sstevel@tonic-gate {
809*0Sstevel@tonic-gate 	md_set_desc		*sd;
810*0Sstevel@tonic-gate 	int			i;
811*0Sstevel@tonic-gate 	int			max_meds;
812*0Sstevel@tonic-gate 
813*0Sstevel@tonic-gate 	if (metaislocalset(sp))
814*0Sstevel@tonic-gate 		return (0);
815*0Sstevel@tonic-gate 
816*0Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
817*0Sstevel@tonic-gate 		return (-1);
818*0Sstevel@tonic-gate 
819*0Sstevel@tonic-gate 	if (setup_med_transtab(ep))
820*0Sstevel@tonic-gate 		return (-1);
821*0Sstevel@tonic-gate 
822*0Sstevel@tonic-gate 	if (meta_h2hi(&sd->sd_med, &cp->c_med, ep))
823*0Sstevel@tonic-gate 		return (-1);
824*0Sstevel@tonic-gate 
825*0Sstevel@tonic-gate 	/* Make sure the ip addresses are current */
826*0Sstevel@tonic-gate 	if (meta_med_hnm2ip(&cp->c_med, ep))
827*0Sstevel@tonic-gate 		return (-1);
828*0Sstevel@tonic-gate 
829*0Sstevel@tonic-gate 	if (force)
830*0Sstevel@tonic-gate 		return (0);
831*0Sstevel@tonic-gate 
832*0Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
833*0Sstevel@tonic-gate 		return (-1);
834*0Sstevel@tonic-gate 
835*0Sstevel@tonic-gate 	/* Make sure metamedd still running on host - only chk nodename */
836*0Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
837*0Sstevel@tonic-gate 		char		*hostname;
838*0Sstevel@tonic-gate 		char		*hnm;
839*0Sstevel@tonic-gate 
840*0Sstevel@tonic-gate 		if (sd->sd_med.n_lst[i].a_cnt == 0)
841*0Sstevel@tonic-gate 			continue;
842*0Sstevel@tonic-gate 
843*0Sstevel@tonic-gate 		hnm = sd->sd_med.n_lst[i].a_nm[0];
844*0Sstevel@tonic-gate 
845*0Sstevel@tonic-gate 		if (clnt_med_hostname(hnm, &hostname, ep))
846*0Sstevel@tonic-gate 			return (mddserror(ep, MDE_DS_NOMEDONHOST, sp->setno,
847*0Sstevel@tonic-gate 			    hnm, NULL, sp->setname));
848*0Sstevel@tonic-gate 		Free(hostname);
849*0Sstevel@tonic-gate 	}
850*0Sstevel@tonic-gate 	return (0);
851*0Sstevel@tonic-gate }
852