xref: /onnv-gate/usr/src/lib/lvm/libmeta/common/meta_med.c (revision 8979:eba3282e25c3)
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
58451SRameshkumar.Ramasamy@Sun.COM  * Common Development and Distribution License (the "License").
68451SRameshkumar.Ramasamy@Sun.COM  * 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  */
217044Smk117520 
220Sstevel@tonic-gate /*
23*8979SRameshkumar.Ramasamy@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*
280Sstevel@tonic-gate  * Just in case we're not in a build environment, make sure that
290Sstevel@tonic-gate  * TEXT_DOMAIN gets set to something.
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
320Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
330Sstevel@tonic-gate #endif
340Sstevel@tonic-gate 
350Sstevel@tonic-gate /*
360Sstevel@tonic-gate  * Mediator functions
370Sstevel@tonic-gate  */
380Sstevel@tonic-gate 
390Sstevel@tonic-gate #include <meta.h>
400Sstevel@tonic-gate #include <metamed.h>
410Sstevel@tonic-gate #include <dlfcn.h>
420Sstevel@tonic-gate #include <sdssc.h>
430Sstevel@tonic-gate 
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate  * There are too many external factors that affect the timing of the
460Sstevel@tonic-gate  * operations, so we set the timeout to a very large value, in this
470Sstevel@tonic-gate  * case 1 day, which should handle HW timeouts, large configurations,
480Sstevel@tonic-gate  * and other potential delays.
490Sstevel@tonic-gate  */
500Sstevel@tonic-gate #define	CL_LONG_TMO	86400L			/* 1 day */
510Sstevel@tonic-gate #define	CL_MEDIUM_TMO	3600L			/* 1 hour */
520Sstevel@tonic-gate #define	CL_SHORT_TMO	600L			/* 10 minutes */
530Sstevel@tonic-gate #define	CL_DEF_TMO	10L			/* 10 seconds */
540Sstevel@tonic-gate 
550Sstevel@tonic-gate static	md_timeval32_t def_rpcb_timeout =  { MD_CLNT_CREATE_TOUT, 0 };
560Sstevel@tonic-gate 
570Sstevel@tonic-gate /*
580Sstevel@tonic-gate  * RPC handle
590Sstevel@tonic-gate  */
600Sstevel@tonic-gate typedef struct {
610Sstevel@tonic-gate 	char	*hostname;
620Sstevel@tonic-gate 	CLIENT	*clntp;
630Sstevel@tonic-gate } med_handle_t;
640Sstevel@tonic-gate 
650Sstevel@tonic-gate /*
660Sstevel@tonic-gate  * Data to be sent from med_clnt_create_timed to med_create_helper via
670Sstevel@tonic-gate  * meta_client_create_retry.
680Sstevel@tonic-gate  */
690Sstevel@tonic-gate typedef struct {
700Sstevel@tonic-gate 	rpcprog_t	mcd_program;	/* RPC program designation */
710Sstevel@tonic-gate 	rpcvers_t	mcd_version;	/* RPC version */
720Sstevel@tonic-gate 	char		*mcd_nettype;	/* Type of network to use for RPC */
730Sstevel@tonic-gate } med_create_data_t;
740Sstevel@tonic-gate 
750Sstevel@tonic-gate /*
760Sstevel@tonic-gate  * Perform the work of actually doing the clnt_create for
770Sstevel@tonic-gate  * meta_client_create_retry.
780Sstevel@tonic-gate  */
790Sstevel@tonic-gate static CLIENT *
med_create_helper(char * hostname,void * private,struct timeval * time_out)800Sstevel@tonic-gate med_create_helper(char *hostname, void *private, struct timeval *time_out)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate 	med_create_data_t	*cd = (med_create_data_t *)private;
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	return (clnt_create_timed(hostname, cd->mcd_program, cd->mcd_version,
858451SRameshkumar.Ramasamy@Sun.COM 	    cd->mcd_nettype, time_out));
860Sstevel@tonic-gate }
870Sstevel@tonic-gate 
880Sstevel@tonic-gate static
med_clnt_create_timed(char * hostname,const ulong_t prog,const ulong_t vers,char * nettype,const md_timeval32_t * tp)890Sstevel@tonic-gate CLIENT *med_clnt_create_timed(
900Sstevel@tonic-gate 	char *hostname,
910Sstevel@tonic-gate 	const ulong_t prog,
920Sstevel@tonic-gate 	const ulong_t vers,
930Sstevel@tonic-gate 	char *nettype,
940Sstevel@tonic-gate 	const md_timeval32_t *tp
950Sstevel@tonic-gate )
960Sstevel@tonic-gate {
970Sstevel@tonic-gate 	med_create_data_t	cd;	/* Create data. */
980Sstevel@tonic-gate 
990Sstevel@tonic-gate 	cd.mcd_program = prog;
1000Sstevel@tonic-gate 	cd.mcd_version = vers;
1010Sstevel@tonic-gate 	cd.mcd_nettype = nettype;
1020Sstevel@tonic-gate 	return (meta_client_create_retry(hostname, med_create_helper,
1038451SRameshkumar.Ramasamy@Sun.COM 	    (void *)&cd, (time_t)tp->tv_sec, NULL));
1040Sstevel@tonic-gate }
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate /*
1070Sstevel@tonic-gate  * Set the timeout value for this client handle.
1080Sstevel@tonic-gate  */
1090Sstevel@tonic-gate static int
cl_sto_medd(CLIENT * clntp,char * hostname,long time_out,md_error_t * ep)1100Sstevel@tonic-gate cl_sto_medd(
1110Sstevel@tonic-gate 	CLIENT		*clntp,
1120Sstevel@tonic-gate 	char		*hostname,
1130Sstevel@tonic-gate 	long		time_out,
1140Sstevel@tonic-gate 	md_error_t	*ep
1150Sstevel@tonic-gate )
1160Sstevel@tonic-gate {
1170Sstevel@tonic-gate 	md_timeval32_t	nto;
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	(void) memset(&nto, '\0', sizeof (nto));
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 	nto.tv_sec = time_out;
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	if (clnt_control(clntp, CLSET_TIMEOUT, (char *)&nto) != TRUE)
1240Sstevel@tonic-gate 		return (mdrpcerror(ep, clntp, hostname,
1250Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "metad client set timeout")));
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 	return (0);
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate /*
1310Sstevel@tonic-gate  * close RPC connection
1320Sstevel@tonic-gate  */
1330Sstevel@tonic-gate static void
close_medd(med_handle_t * hp)1340Sstevel@tonic-gate close_medd(
1350Sstevel@tonic-gate 	med_handle_t	*hp
1360Sstevel@tonic-gate )
1370Sstevel@tonic-gate {
1380Sstevel@tonic-gate 	assert(hp != NULL);
1390Sstevel@tonic-gate 	if (hp->hostname != NULL) {
1400Sstevel@tonic-gate 		Free(hp->hostname);
1410Sstevel@tonic-gate 	}
1420Sstevel@tonic-gate 	if (hp->clntp != NULL) {
1430Sstevel@tonic-gate 		auth_destroy(hp->clntp->cl_auth);
1440Sstevel@tonic-gate 		clnt_destroy(hp->clntp);
1450Sstevel@tonic-gate 	}
1460Sstevel@tonic-gate 	Free(hp);
1470Sstevel@tonic-gate }
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate /*
1500Sstevel@tonic-gate  * open RPC connection to rpc.medd
1510Sstevel@tonic-gate  */
1520Sstevel@tonic-gate static med_handle_t *
open_medd(char * hostname,long time_out,md_error_t * ep)1530Sstevel@tonic-gate open_medd(
1540Sstevel@tonic-gate 	char		*hostname,
1550Sstevel@tonic-gate 	long		time_out,
1560Sstevel@tonic-gate 	md_error_t	*ep
1570Sstevel@tonic-gate )
1580Sstevel@tonic-gate {
1590Sstevel@tonic-gate 	CLIENT		*clntp;
1600Sstevel@tonic-gate 	med_handle_t	*hp;
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 	/* default to local host */
1630Sstevel@tonic-gate 	if ((hostname == NULL) || (*hostname == '\0'))
1640Sstevel@tonic-gate 		hostname = mynode();
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate 	/* open RPC connection */
1670Sstevel@tonic-gate 	assert(hostname != NULL);
1680Sstevel@tonic-gate 	if ((clntp = med_clnt_create_timed(hostname, MED_PROG, MED_VERS,
1690Sstevel@tonic-gate 	    "tcp", &def_rpcb_timeout)) == NULL) {
1700Sstevel@tonic-gate 		if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED)
1710Sstevel@tonic-gate 			clnt_pcreateerror(hostname);
1720Sstevel@tonic-gate 		(void) mdrpccreateerror(ep, hostname,
1730Sstevel@tonic-gate 		    "medd med_clnt_create_timed");
1740Sstevel@tonic-gate 		return (NULL);
1750Sstevel@tonic-gate 	} else {
1760Sstevel@tonic-gate 		auth_destroy(clntp->cl_auth);
1770Sstevel@tonic-gate 		clntp->cl_auth = authsys_create_default();
1780Sstevel@tonic-gate 		assert(clntp->cl_auth != NULL);
1790Sstevel@tonic-gate 	}
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 	if (cl_sto_medd(clntp, hostname, time_out, ep) != 0)
1820Sstevel@tonic-gate 		return (NULL);
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 	/* return connection */
1850Sstevel@tonic-gate 	hp = Zalloc(sizeof (*hp));
1860Sstevel@tonic-gate 	hp->hostname = Strdup(hostname);
1870Sstevel@tonic-gate 	hp->clntp = clntp;
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 	return (hp);
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate /*
1930Sstevel@tonic-gate  * steal and convert med_err_t
1940Sstevel@tonic-gate  */
1950Sstevel@tonic-gate int
meddstealerror(md_error_t * ep,med_err_t * medep)1960Sstevel@tonic-gate meddstealerror(
1970Sstevel@tonic-gate 	md_error_t	*ep,
1980Sstevel@tonic-gate 	med_err_t	*medep
1990Sstevel@tonic-gate )
2000Sstevel@tonic-gate {
2010Sstevel@tonic-gate 	char		buf[BUFSIZ];
2020Sstevel@tonic-gate 	char		*p = buf;
2030Sstevel@tonic-gate 	size_t		psize = BUFSIZ;
2040Sstevel@tonic-gate 	char		*emsg;
2050Sstevel@tonic-gate 	int		rval = -1;
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate 	/* no error */
2080Sstevel@tonic-gate 	if (medep->med_errno == 0) {
2090Sstevel@tonic-gate 		/* assert(medep->name == NULL); */
2100Sstevel@tonic-gate 		rval = 0;
2110Sstevel@tonic-gate 		goto out;
2120Sstevel@tonic-gate 	}
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 	/* steal error */
2150Sstevel@tonic-gate 	if ((medep->med_node != NULL) && (medep->med_node[0] != '\0')) {
2160Sstevel@tonic-gate 		(void) snprintf(p, psize, "%s: ", medep->med_node);
2170Sstevel@tonic-gate 		p = &buf[strlen(buf)];
2180Sstevel@tonic-gate 		psize = buf + BUFSIZ - p;
2190Sstevel@tonic-gate 	}
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate 	if ((medep->med_misc != NULL) && (medep->med_misc[0] != '\0')) {
2220Sstevel@tonic-gate 		(void) snprintf(p, psize, "%s: ", medep->med_misc);
2230Sstevel@tonic-gate 		p = &buf[strlen(buf)];
2240Sstevel@tonic-gate 		psize = buf + BUFSIZ - p;
2250Sstevel@tonic-gate 	}
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 	if (medep->med_errno < 0) {
2280Sstevel@tonic-gate 		if ((emsg = med_errnum_to_str(medep->med_errno)) != NULL)
2290Sstevel@tonic-gate 			(void) snprintf(p, psize, "%s", emsg);
2300Sstevel@tonic-gate 		else
2310Sstevel@tonic-gate 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
2320Sstevel@tonic-gate 			    "unknown mediator errno %d\n"), medep->med_errno);
2330Sstevel@tonic-gate 	} else {
2340Sstevel@tonic-gate 		if ((emsg = strerror(medep->med_errno)) != NULL)
2350Sstevel@tonic-gate 			(void) snprintf(p, psize, "%s", emsg);
2360Sstevel@tonic-gate 		else
2370Sstevel@tonic-gate 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
2380Sstevel@tonic-gate 			    "errno %d out of range"), medep->med_errno);
2390Sstevel@tonic-gate 	}
2400Sstevel@tonic-gate 	(void) mderror(ep, MDE_MED_ERROR, buf);
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 	/* cleanup, return success */
2430Sstevel@tonic-gate out:
2440Sstevel@tonic-gate 	if (medep->med_node != NULL)
2450Sstevel@tonic-gate 		Free(medep->med_node);
2460Sstevel@tonic-gate 	if (medep->med_misc != NULL)
2470Sstevel@tonic-gate 		Free(medep->med_misc);
2480Sstevel@tonic-gate 	(void) memset(medep, 0, sizeof (*medep));
2490Sstevel@tonic-gate 	return (rval);
2500Sstevel@tonic-gate }
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate static med_handle_t *
open_medd_wrap(md_h_t * mdhp,long time_out,md_error_t * ep)2530Sstevel@tonic-gate open_medd_wrap(
2540Sstevel@tonic-gate 	md_h_t		*mdhp,
2550Sstevel@tonic-gate 	long		time_out,
2560Sstevel@tonic-gate 	md_error_t	*ep
2570Sstevel@tonic-gate )
2580Sstevel@tonic-gate {
2590Sstevel@tonic-gate 	med_handle_t		*hp = NULL;
2600Sstevel@tonic-gate 	int			i;
2610Sstevel@tonic-gate 	char    		*hnm;
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate 	assert(mdhp && mdhp->a_cnt > 0);
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 	/* Loop through the hosts listed */
2660Sstevel@tonic-gate 	i = min(mdhp->a_cnt, MAX_HOST_ADDRS) - 1;
2670Sstevel@tonic-gate 	for (; i >= 0; i--) {
2680Sstevel@tonic-gate 		hnm = mdhp->a_nm[i];
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate 		if ((hp = open_medd(hnm, time_out, ep)) == NULL) {
2710Sstevel@tonic-gate 			if (mdanyrpcerror(ep) && i != 0) {
2720Sstevel@tonic-gate 				mdclrerror(ep);
2730Sstevel@tonic-gate 				continue;
2740Sstevel@tonic-gate 			}
2750Sstevel@tonic-gate 		}
2760Sstevel@tonic-gate 		return (hp);
2770Sstevel@tonic-gate 	}
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate 	rpc_createerr.cf_stat = RPC_CANTSEND;
2800Sstevel@tonic-gate 	rpc_createerr.cf_error.re_status = 0;
2810Sstevel@tonic-gate 	(void) mdrpccreateerror(ep, mdhp->a_nm[0],
2820Sstevel@tonic-gate 	    dgettext(TEXT_DOMAIN, "medd open wrap"));
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	return (NULL);
2850Sstevel@tonic-gate }
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate static int
setup_med_transtab(md_error_t * ep)2880Sstevel@tonic-gate setup_med_transtab(md_error_t *ep)
2890Sstevel@tonic-gate {
2900Sstevel@tonic-gate 	mddb_med_t_parm_t	*tp = NULL;
2910Sstevel@tonic-gate 	struct	stat		statb;
2920Sstevel@tonic-gate 	int			i;
2930Sstevel@tonic-gate 	size_t			alloc_size = 0;
2940Sstevel@tonic-gate 	int			err = 0;
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 	if ((tp = Zalloc(sizeof (mddb_med_t_parm_t))) == NULL)
2980Sstevel@tonic-gate 		return (mdsyserror(ep, ENOMEM, "setup_med_transtab"));
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate 	if (metaioctl(MD_MED_GET_TLEN, tp, &tp->med_tp_mde, NULL) != 0) {
3010Sstevel@tonic-gate 		err = mdstealerror(ep, &tp->med_tp_mde);
3020Sstevel@tonic-gate 		goto out;
3030Sstevel@tonic-gate 	}
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate 	if (tp->med_tp_setup == 1)
3060Sstevel@tonic-gate 		goto out;
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	alloc_size = (sizeof (mddb_med_t_parm_t) - sizeof (mddb_med_t_ent_t)) +
3090Sstevel@tonic-gate 	    (sizeof (mddb_med_t_ent_t) * tp->med_tp_nents);
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate 	if ((tp = Realloc(tp, alloc_size)) == NULL) {
3120Sstevel@tonic-gate 		err = mdsyserror(ep, ENOMEM, "setup_med_transtab");
3130Sstevel@tonic-gate 		goto out;
3140Sstevel@tonic-gate 	}
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 	if (metaioctl(MD_MED_GET_T, tp, &tp->med_tp_mde, NULL) != 0) {
3170Sstevel@tonic-gate 		err = mdstealerror(ep, &tp->med_tp_mde);
3180Sstevel@tonic-gate 		goto out;
3190Sstevel@tonic-gate 	}
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate 	for (i = 0; i < tp->med_tp_nents; i++) {
3220Sstevel@tonic-gate 		if (meta_stat(tp->med_tp_ents[i].med_te_nm, &statb) == -1) {
3230Sstevel@tonic-gate 			md_perror("setup_med_transtab(): stat():");
3240Sstevel@tonic-gate 			tp->med_tp_ents[i].med_te_dev = NODEV64;
3250Sstevel@tonic-gate 		} else {
3260Sstevel@tonic-gate 			tp->med_tp_ents[i].med_te_dev =
3278451SRameshkumar.Ramasamy@Sun.COM 			    meta_expldev(statb.st_rdev);
3280Sstevel@tonic-gate 		}
3290Sstevel@tonic-gate 	}
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate 	if (metaioctl(MD_MED_SET_T, tp, &tp->med_tp_mde, NULL) != 0)
3320Sstevel@tonic-gate 		err = mdstealerror(ep, &tp->med_tp_mde);
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate out:
3350Sstevel@tonic-gate 	Free(tp);
3360Sstevel@tonic-gate 	return (err);
3370Sstevel@tonic-gate }
3380Sstevel@tonic-gate 
3390Sstevel@tonic-gate /*
3400Sstevel@tonic-gate  * Externals
3410Sstevel@tonic-gate  */
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate /*
3440Sstevel@tonic-gate  * NULLPROC - just returns a response
3450Sstevel@tonic-gate  */
3460Sstevel@tonic-gate int
clnt_med_null(char * hostname,md_error_t * ep)3470Sstevel@tonic-gate clnt_med_null(
3480Sstevel@tonic-gate 	char			*hostname,
3490Sstevel@tonic-gate 	md_error_t		*ep
3500Sstevel@tonic-gate )
3510Sstevel@tonic-gate {
3520Sstevel@tonic-gate 	med_handle_t		*hp;
3530Sstevel@tonic-gate 	med_err_t		res;
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate 	/* initialize */
3560Sstevel@tonic-gate 	mdclrerror(ep);
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	/* do it */
3590Sstevel@tonic-gate 	if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL)
3600Sstevel@tonic-gate 		return (-1);
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 	if (med_null_1(NULL, &res, hp->clntp) != RPC_SUCCESS)
3630Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hostname,
3640Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd nullproc"));
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 	close_medd(hp);
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate 	xdr_free(xdr_med_err_t, (char *)&res);
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate 	if (! mdisok(ep))
3710Sstevel@tonic-gate 		return (-1);
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 	return (0);
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate /*
3770Sstevel@tonic-gate  * Update the mediator information on the mediator.
3787044Smk117520  * This function does the same functionality as
3797044Smk117520  * clnt_med_upd_data() except that it takes different
3807044Smk117520  * argument so that host which is just a mediator, can
3817044Smk117520  * still update its mediator record.
3827044Smk117520  */
3837044Smk117520 int
clnt_user_med_upd_data(md_h_t * mdhp,bool_t obandiskset,char * setname,uint_t setnum,med_data_t * meddp,md_error_t * ep)3847044Smk117520 clnt_user_med_upd_data(
3857044Smk117520 	md_h_t	*mdhp,
3867044Smk117520 	bool_t	obandiskset,
3877044Smk117520 	char	*setname,
3887044Smk117520 	uint_t	setnum,
3897044Smk117520 	med_data_t	*meddp,
3907044Smk117520 	md_error_t	*ep
3917044Smk117520 )
3927044Smk117520 {
3937044Smk117520 	med_handle_t    	*hp;
3947044Smk117520 	med_upd_data_args_t	args;
3957044Smk117520 	med_err_t		res;
3967044Smk117520 
3977044Smk117520 	/* Initialize */
3987044Smk117520 	mdclrerror(ep);
3997044Smk117520 	(void) memset(&args, 0, sizeof (args));
4007044Smk117520 	(void) memset(&res, 0, sizeof (res));
4017044Smk117520 
4027044Smk117520 	/* Build args */
4037044Smk117520 	if (obandiskset)
4047044Smk117520 		args.med.med_caller = Strdup(MED_MN_CALLER);
4057044Smk117520 	else
4067044Smk117520 		args.med.med_caller = Strdup(mynode());
4077044Smk117520 
4087044Smk117520 	args.med.med_setname = Strdup(setname);
4097044Smk117520 	args.med.med_setno = setnum;
4107044Smk117520 	args.med_data = *meddp;
4117044Smk117520 
4127044Smk117520 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
4137044Smk117520 		return (-1);
4147044Smk117520 
4157044Smk117520 	if (med_upd_data_1(&args, &res, hp->clntp) != RPC_SUCCESS)
4167044Smk117520 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
4177044Smk117520 		    dgettext(TEXT_DOMAIN, "medd get record"));
4187044Smk117520 	else
4197044Smk117520 		(void) meddstealerror(ep, &res);
4207044Smk117520 
4217044Smk117520 	close_medd(hp);
4227044Smk117520 
4237044Smk117520 	xdr_free(xdr_med_upd_data_args_t, (char *)&args);
4247044Smk117520 	xdr_free(xdr_med_err_t, (char *)&res);
4257044Smk117520 
4267044Smk117520 	if (! mdisok(ep))
4277044Smk117520 		return (-1);
4287044Smk117520 
4297044Smk117520 	return (0);
4307044Smk117520 }
4317044Smk117520 
4327044Smk117520 /*
4337044Smk117520  * Get the mediator information from the client.
4347044Smk117520  * The code does same functinality as clnt_med_get_data()
4357044Smk117520  * except that it takes different arguments so that
4367044Smk117520  * host which doesn't have set information, can still
4377044Smk117520  * get access to mediator information
4387044Smk117520  */
4397044Smk117520 int
clnt_user_med_get_data(md_h_t * mdhp,bool_t obandiskset,char * setname,uint_t setnum,med_data_t * meddp,md_error_t * ep)4407044Smk117520 clnt_user_med_get_data(
4417044Smk117520 	md_h_t	*mdhp,
4427044Smk117520 	bool_t	obandiskset,
4437044Smk117520 	char	*setname,
4447044Smk117520 	uint_t	setnum,
4457044Smk117520 	med_data_t	*meddp,
4467044Smk117520 	md_error_t	*ep
4477044Smk117520 )
4487044Smk117520 {
4497044Smk117520 	int			rval = -1;
4507044Smk117520 	med_handle_t		*hp;
4517044Smk117520 	med_args_t		args;
4527044Smk117520 	med_get_data_res_t	res;
4537044Smk117520 
4547044Smk117520 	/* Initialize */
4557044Smk117520 	mdclrerror(ep);
4567044Smk117520 	(void) memset(&args, 0, sizeof (args));
4577044Smk117520 	(void) memset(&res, 0, sizeof (res));
4587044Smk117520 
4597044Smk117520 	/* Build args */
4607044Smk117520 	if (obandiskset)
4617044Smk117520 		args.med.med_caller = Strdup(MED_MN_CALLER);
4627044Smk117520 	else
4637044Smk117520 		args.med.med_caller = Strdup(mynode());
4647044Smk117520 
4657044Smk117520 	args.med.med_setname = Strdup(setname);
4667044Smk117520 	args.med.med_setno = setnum;
4677044Smk117520 
4687044Smk117520 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
4697044Smk117520 		return (-1);
4707044Smk117520 
4717044Smk117520 	if (med_get_data_1(&args, &res, hp->clntp) != RPC_SUCCESS)
4727044Smk117520 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
4737044Smk117520 		    dgettext(TEXT_DOMAIN, "medd get record"));
4747044Smk117520 	else
4757044Smk117520 		(void) meddstealerror(ep, &res.med_status);
4767044Smk117520 
4777044Smk117520 	close_medd(hp);
4787044Smk117520 
4797044Smk117520 	if (mdisok(ep)) {
4807044Smk117520 		/* copy the mediator data in meddp */
4817044Smk117520 		(void) memmove(meddp, &res.med_data, sizeof (med_data_t));
4827044Smk117520 		rval = 0;
4837044Smk117520 	}
4847044Smk117520 
4857044Smk117520 	xdr_free(xdr_med_args_t, (char *)&args);
4867044Smk117520 	xdr_free(xdr_med_get_data_res_t, (char *)&res);
4877044Smk117520 
4887044Smk117520 	return (rval);
4897044Smk117520 }
4907044Smk117520 
4917044Smk117520 
4927044Smk117520 /*
4937044Smk117520  * Update the mediator information on the mediator.
4940Sstevel@tonic-gate  * *** This is not normally called from user code, the kernel does this! ***
4950Sstevel@tonic-gate  */
4960Sstevel@tonic-gate int
clnt_med_upd_data(md_h_t * mdhp,mdsetname_t * sp,med_data_t * meddp,md_error_t * ep)4970Sstevel@tonic-gate clnt_med_upd_data(
4980Sstevel@tonic-gate 	md_h_t			*mdhp,
4990Sstevel@tonic-gate 	mdsetname_t		*sp,
5000Sstevel@tonic-gate 	med_data_t		*meddp,
5010Sstevel@tonic-gate 	md_error_t		*ep
5020Sstevel@tonic-gate )
5030Sstevel@tonic-gate {
5040Sstevel@tonic-gate 	med_handle_t		*hp;
5050Sstevel@tonic-gate 	med_upd_data_args_t	args;
5060Sstevel@tonic-gate 	med_err_t		res;
5070Sstevel@tonic-gate 	md_set_desc		*sd;
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate 	/* initialize */
5100Sstevel@tonic-gate 	mdclrerror(ep);
5110Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
5120Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate 	/* build args */
5150Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
5160Sstevel@tonic-gate 		return (-1);
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
5190Sstevel@tonic-gate 		/*
5200Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
5210Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
5220Sstevel@tonic-gate 		 * any node to access mediator information.
5230Sstevel@tonic-gate 		 *
5240Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
5250Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
5260Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
5270Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
5280Sstevel@tonic-gate 		 *
5290Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
5300Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
5310Sstevel@tonic-gate 		 * mediator data.
5320Sstevel@tonic-gate 		 */
5330Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
5340Sstevel@tonic-gate 	else
5350Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
5360Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
5370Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
5380Sstevel@tonic-gate 	args.med_data = *meddp;
5390Sstevel@tonic-gate 
5400Sstevel@tonic-gate 	/* do it */
5410Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
5420Sstevel@tonic-gate 		return (-1);
5430Sstevel@tonic-gate 
5440Sstevel@tonic-gate 	if (med_upd_data_1(&args, &res, hp->clntp) != RPC_SUCCESS)
5450Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
5460Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd update data"));
5470Sstevel@tonic-gate 	else
5480Sstevel@tonic-gate 		(void) meddstealerror(ep, &res);
5490Sstevel@tonic-gate 
5500Sstevel@tonic-gate 	close_medd(hp);
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate 	xdr_free(xdr_med_upd_data_args_t, (char *)&args);
5530Sstevel@tonic-gate 	xdr_free(xdr_med_err_t, (char *)&res);
5540Sstevel@tonic-gate 
5550Sstevel@tonic-gate 	if (! mdisok(ep))
5560Sstevel@tonic-gate 		return (-1);
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate 	return (0);
5590Sstevel@tonic-gate }
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate /*
5620Sstevel@tonic-gate  * Get the mediator data for this client from the mediator
5630Sstevel@tonic-gate  */
5640Sstevel@tonic-gate int
clnt_med_get_data(md_h_t * mdhp,mdsetname_t * sp,med_data_t * meddp,md_error_t * ep)5650Sstevel@tonic-gate clnt_med_get_data(
5660Sstevel@tonic-gate 	md_h_t			*mdhp,
5670Sstevel@tonic-gate 	mdsetname_t		*sp,
5680Sstevel@tonic-gate 	med_data_t		*meddp,
5690Sstevel@tonic-gate 	md_error_t		*ep
5700Sstevel@tonic-gate )
5710Sstevel@tonic-gate {
5720Sstevel@tonic-gate 	med_handle_t		*hp;
5730Sstevel@tonic-gate 	med_args_t		args;
5740Sstevel@tonic-gate 	med_get_data_res_t	res;
5750Sstevel@tonic-gate 	int			rval = -1;
5760Sstevel@tonic-gate 	md_set_desc		*sd;
5770Sstevel@tonic-gate 
5780Sstevel@tonic-gate 	/* initialize */
5790Sstevel@tonic-gate 	mdclrerror(ep);
5800Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
5810Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate 	/* build args */
5840Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
5850Sstevel@tonic-gate 		return (-1);
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
5880Sstevel@tonic-gate 		/*
5890Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
5900Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
5910Sstevel@tonic-gate 		 * any node to access mediator information.
5920Sstevel@tonic-gate 		 *
5930Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
5940Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
5950Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
5960Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
5970Sstevel@tonic-gate 		 *
5980Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
5990Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
6000Sstevel@tonic-gate 		 * mediator data.
6010Sstevel@tonic-gate 		 */
6020Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
6030Sstevel@tonic-gate 	else
6040Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
6050Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
6060Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
6070Sstevel@tonic-gate 
6080Sstevel@tonic-gate 	/* do it */
6090Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
6100Sstevel@tonic-gate 		return (-1);
6110Sstevel@tonic-gate 
6120Sstevel@tonic-gate 	if (med_get_data_1(&args, &res, hp->clntp) != RPC_SUCCESS)
6130Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
6140Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd get data"));
6150Sstevel@tonic-gate 	else
6160Sstevel@tonic-gate 		(void) meddstealerror(ep, &res.med_status);
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate 	close_medd(hp);
6190Sstevel@tonic-gate 
6200Sstevel@tonic-gate 	if (mdisok(ep)) {
6210Sstevel@tonic-gate 		/* do something with the results */
6220Sstevel@tonic-gate 		(void) memmove(meddp, &res.med_data, sizeof (med_data_t));
6230Sstevel@tonic-gate 		rval = 0;
6240Sstevel@tonic-gate 	}
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate 	xdr_free(xdr_med_args_t, (char *)&args);
6270Sstevel@tonic-gate 	xdr_free(xdr_med_get_data_res_t, (char *)&res);
6280Sstevel@tonic-gate 
6290Sstevel@tonic-gate 	return (rval);
6300Sstevel@tonic-gate }
6310Sstevel@tonic-gate 
6320Sstevel@tonic-gate /*
6330Sstevel@tonic-gate  * Update the mediator record on the mediator.
6340Sstevel@tonic-gate  */
6350Sstevel@tonic-gate int
clnt_med_upd_rec(md_h_t * mdhp,mdsetname_t * sp,med_rec_t * medrp,md_error_t * ep)6360Sstevel@tonic-gate clnt_med_upd_rec(
6370Sstevel@tonic-gate 	md_h_t			*mdhp,
6380Sstevel@tonic-gate 	mdsetname_t		*sp,
6390Sstevel@tonic-gate 	med_rec_t		*medrp,
6400Sstevel@tonic-gate 	md_error_t		*ep
6410Sstevel@tonic-gate )
6420Sstevel@tonic-gate {
6430Sstevel@tonic-gate 	med_handle_t		*hp;
6440Sstevel@tonic-gate 	med_upd_rec_args_t	args;
6450Sstevel@tonic-gate 	med_err_t		res;
6460Sstevel@tonic-gate 	md_set_desc		*sd;
6470Sstevel@tonic-gate 
6480Sstevel@tonic-gate 	/* initialize */
6490Sstevel@tonic-gate 	mdclrerror(ep);
6500Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
6510Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate 	/* build args */
6540Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
6550Sstevel@tonic-gate 		return (-1);
6560Sstevel@tonic-gate 
6570Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
6580Sstevel@tonic-gate 		/*
6590Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
6600Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
6610Sstevel@tonic-gate 		 * any node to access mediator information.
6620Sstevel@tonic-gate 		 *
6630Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
6640Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
6650Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
6660Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
6670Sstevel@tonic-gate 		 *
6680Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
6690Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
6700Sstevel@tonic-gate 		 * mediator data.
6710Sstevel@tonic-gate 		 */
6720Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
6730Sstevel@tonic-gate 	else
6740Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
6750Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
6760Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
6770Sstevel@tonic-gate 	args.med_flags = 0;
6780Sstevel@tonic-gate 	args.med_rec = *medrp;			/* structure assignment */
6790Sstevel@tonic-gate 
6800Sstevel@tonic-gate 	/* do it */
6810Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
6820Sstevel@tonic-gate 		return (-1);
6830Sstevel@tonic-gate 
6840Sstevel@tonic-gate 	if (med_upd_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS)
6850Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
6860Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd update record"));
6870Sstevel@tonic-gate 	else
6880Sstevel@tonic-gate 		(void) meddstealerror(ep, &res);
6890Sstevel@tonic-gate 
6900Sstevel@tonic-gate 	close_medd(hp);
6910Sstevel@tonic-gate 
6920Sstevel@tonic-gate 	xdr_free(xdr_med_upd_rec_args_t, (char *)&args);
6930Sstevel@tonic-gate 	xdr_free(xdr_med_err_t, (char *)&res);
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 	if (! mdisok(ep))
6960Sstevel@tonic-gate 		return (-1);
6970Sstevel@tonic-gate 
6980Sstevel@tonic-gate 	return (0);
6990Sstevel@tonic-gate }
7000Sstevel@tonic-gate 
7010Sstevel@tonic-gate /*
7020Sstevel@tonic-gate  * Get the mediator record for this client from the mediator
7030Sstevel@tonic-gate  */
7040Sstevel@tonic-gate int
clnt_med_get_rec(md_h_t * mdhp,mdsetname_t * sp,med_rec_t * medrp,md_error_t * ep)7050Sstevel@tonic-gate clnt_med_get_rec(
7060Sstevel@tonic-gate 	md_h_t			*mdhp,
7070Sstevel@tonic-gate 	mdsetname_t		*sp,
7080Sstevel@tonic-gate 	med_rec_t		*medrp,
7090Sstevel@tonic-gate 	md_error_t		*ep
7100Sstevel@tonic-gate )
7110Sstevel@tonic-gate {
7120Sstevel@tonic-gate 	med_handle_t		*hp;
7130Sstevel@tonic-gate 	med_args_t		args;
7140Sstevel@tonic-gate 	med_get_rec_res_t	res;
7150Sstevel@tonic-gate 	int			rval = -1;
7160Sstevel@tonic-gate 	md_set_desc		*sd;
7170Sstevel@tonic-gate 
7180Sstevel@tonic-gate 	/* initialize */
7190Sstevel@tonic-gate 	mdclrerror(ep);
7200Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
7210Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate 	/* build args */
7240Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
7250Sstevel@tonic-gate 		return (-1);
7260Sstevel@tonic-gate 
7270Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
7280Sstevel@tonic-gate 		/*
7290Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
7300Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
7310Sstevel@tonic-gate 		 * any node to access mediator information.
7320Sstevel@tonic-gate 		 *
7330Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
7340Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
7350Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
7360Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
7370Sstevel@tonic-gate 		 *
7380Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
7390Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
7400Sstevel@tonic-gate 		 * mediator data.
7410Sstevel@tonic-gate 		 */
7420Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
7430Sstevel@tonic-gate 	else
7440Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
7450Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
7460Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
7470Sstevel@tonic-gate 
7480Sstevel@tonic-gate 	/* do it */
7490Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
7500Sstevel@tonic-gate 		return (-1);
7510Sstevel@tonic-gate 
7520Sstevel@tonic-gate 	if (med_get_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS)
7530Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
7540Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd get record"));
7550Sstevel@tonic-gate 	else
7560Sstevel@tonic-gate 		(void) meddstealerror(ep, &res.med_status);
7570Sstevel@tonic-gate 
7580Sstevel@tonic-gate 	close_medd(hp);
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate 	if (mdisok(ep)) {
7610Sstevel@tonic-gate 		/* do something with the results */
7620Sstevel@tonic-gate 		(void) memmove(medrp, &res.med_rec, sizeof (med_rec_t));
7630Sstevel@tonic-gate 		rval = 0;
7640Sstevel@tonic-gate 	}
7650Sstevel@tonic-gate 
7660Sstevel@tonic-gate 	xdr_free(xdr_med_args_t, (char *)&args);
7670Sstevel@tonic-gate 	xdr_free(xdr_med_get_rec_res_t, (char *)&res);
7680Sstevel@tonic-gate 
7690Sstevel@tonic-gate 	return (rval);
7700Sstevel@tonic-gate }
7710Sstevel@tonic-gate 
7720Sstevel@tonic-gate /*
7730Sstevel@tonic-gate  * Get the name of the host from the mediator daemon.
7740Sstevel@tonic-gate  */
7750Sstevel@tonic-gate int
clnt_med_hostname(char * hostname,char ** ret_hostname,md_error_t * ep)7760Sstevel@tonic-gate clnt_med_hostname(
7770Sstevel@tonic-gate 	char			*hostname,
7780Sstevel@tonic-gate 	char			**ret_hostname,
7790Sstevel@tonic-gate 	md_error_t		*ep
7800Sstevel@tonic-gate )
7810Sstevel@tonic-gate {
7820Sstevel@tonic-gate 	med_handle_t		*hp;
7830Sstevel@tonic-gate 	med_hnm_res_t		res;
7840Sstevel@tonic-gate 	int			rval = -1;
7850Sstevel@tonic-gate 
7860Sstevel@tonic-gate 	/* initialize */
7870Sstevel@tonic-gate 	mdclrerror(ep);
7880Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
7890Sstevel@tonic-gate 
7900Sstevel@tonic-gate 	/* No args */
7910Sstevel@tonic-gate 
7920Sstevel@tonic-gate 	/* do it */
7930Sstevel@tonic-gate 	if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL)
7940Sstevel@tonic-gate 		return (-1);
7950Sstevel@tonic-gate 
7960Sstevel@tonic-gate 	if (med_hostname_1(NULL, &res, hp->clntp) != RPC_SUCCESS)
7970Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hostname,
7980Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd hostname"));
7990Sstevel@tonic-gate 	else
8000Sstevel@tonic-gate 		(void) meddstealerror(ep, &res.med_status);
8010Sstevel@tonic-gate 
8020Sstevel@tonic-gate 	close_medd(hp);
8030Sstevel@tonic-gate 
8040Sstevel@tonic-gate 	if (mdisok(ep)) {
8050Sstevel@tonic-gate 		/* do something with the results */
8060Sstevel@tonic-gate 		rval = 0;
8070Sstevel@tonic-gate 
8080Sstevel@tonic-gate 		if (ret_hostname != NULL)
8090Sstevel@tonic-gate 			*ret_hostname = Strdup(res.med_hnm);
8100Sstevel@tonic-gate 	}
8110Sstevel@tonic-gate 
8120Sstevel@tonic-gate 	xdr_free(xdr_med_hnm_res_t, (char *)&res);
8130Sstevel@tonic-gate 
8140Sstevel@tonic-gate 	return (rval);
8150Sstevel@tonic-gate }
8160Sstevel@tonic-gate 
8170Sstevel@tonic-gate int
meta_med_hnm2ip(md_hi_arr_t * mp,md_error_t * ep)8180Sstevel@tonic-gate meta_med_hnm2ip(md_hi_arr_t *mp, md_error_t *ep)
8190Sstevel@tonic-gate {
8200Sstevel@tonic-gate 	int		i, j;
8210Sstevel@tonic-gate 	int		max_meds;
8220Sstevel@tonic-gate 
8230Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
8240Sstevel@tonic-gate 		return (-1);
8250Sstevel@tonic-gate 
8260Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
8270Sstevel@tonic-gate 		mp->n_lst[i].a_flg = 0;
8280Sstevel@tonic-gate 		/* See if this is the local host */
8290Sstevel@tonic-gate 		if (mp->n_lst[i].a_cnt > 0 &&
8300Sstevel@tonic-gate 		    strcmp(mp->n_lst[i].a_nm[0], mynode()) == NULL)
8310Sstevel@tonic-gate 			mp->n_lst[i].a_flg |= NMIP_F_LOCAL;
8320Sstevel@tonic-gate 
8330Sstevel@tonic-gate 		for (j = 0; j < mp->n_lst[i].a_cnt; j++) {
8340Sstevel@tonic-gate 			struct hostent	*hp;
8350Sstevel@tonic-gate 			char		*hnm = mp->n_lst[i].a_nm[j];
8360Sstevel@tonic-gate 
8370Sstevel@tonic-gate 			/*
8380Sstevel@tonic-gate 			 * Cluster nodename support
8390Sstevel@tonic-gate 			 *
8400Sstevel@tonic-gate 			 * See if the clustering code can give us an IP addr
8410Sstevel@tonic-gate 			 * for the stored name. If not, find it the old way
8420Sstevel@tonic-gate 			 * which will use the public interface.
8430Sstevel@tonic-gate 			 */
8440Sstevel@tonic-gate 			if (sdssc_get_priv_ipaddr(mp->n_lst[i].a_nm[j],
8450Sstevel@tonic-gate 			    (struct in_addr *)&mp->n_lst[i].a_ip[j]) !=
8468451SRameshkumar.Ramasamy@Sun.COM 			    SDSSC_OKAY) {
8470Sstevel@tonic-gate 				if ((hp = gethostbyname(hnm)) == NULL)
8480Sstevel@tonic-gate 					return (mdsyserror(ep, EADDRNOTAVAIL,
8490Sstevel@tonic-gate 					    hnm));
8500Sstevel@tonic-gate 
8510Sstevel@tonic-gate 				/* We only do INET addresses */
8520Sstevel@tonic-gate 				if (hp->h_addrtype != AF_INET)
8530Sstevel@tonic-gate 					return (mdsyserror(ep, EPFNOSUPPORT,
8540Sstevel@tonic-gate 					    hnm));
8550Sstevel@tonic-gate 
8560Sstevel@tonic-gate 				/* We take the first address only */
8570Sstevel@tonic-gate 				if (*hp->h_addr_list) {
8580Sstevel@tonic-gate 					(void) memmove(&mp->n_lst[i].a_ip[j],
8590Sstevel@tonic-gate 					    *hp->h_addr_list,
8600Sstevel@tonic-gate 					    sizeof (struct in_addr));
8610Sstevel@tonic-gate 				} else
8620Sstevel@tonic-gate 					return (mdsyserror(ep, EADDRNOTAVAIL,
8630Sstevel@tonic-gate 					    hnm));
8640Sstevel@tonic-gate 			}
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate 		}
8670Sstevel@tonic-gate 	}
8680Sstevel@tonic-gate 	return (0);
8690Sstevel@tonic-gate }
8700Sstevel@tonic-gate 
8710Sstevel@tonic-gate int
meta_h2hi(md_h_arr_t * mdhp,md_hi_arr_t * mdhip,md_error_t * ep)8720Sstevel@tonic-gate meta_h2hi(md_h_arr_t *mdhp, md_hi_arr_t *mdhip, md_error_t *ep)
8730Sstevel@tonic-gate {
8740Sstevel@tonic-gate 	int			i, j;
8750Sstevel@tonic-gate 	int			max_meds;
8760Sstevel@tonic-gate 
8770Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
8780Sstevel@tonic-gate 		return (-1);
8790Sstevel@tonic-gate 
8800Sstevel@tonic-gate 	mdhip->n_cnt = mdhp->n_cnt;
8810Sstevel@tonic-gate 
8820Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
8830Sstevel@tonic-gate 		mdhip->n_lst[i].a_flg = 0;
8840Sstevel@tonic-gate 		mdhip->n_lst[i].a_cnt = mdhp->n_lst[i].a_cnt;
8850Sstevel@tonic-gate 		if (mdhp->n_lst[i].a_cnt == 0)
8860Sstevel@tonic-gate 			continue;
8870Sstevel@tonic-gate 		for (j = 0; j < mdhp->n_lst[i].a_cnt; j++)
8880Sstevel@tonic-gate 			(void) strcpy(mdhip->n_lst[i].a_nm[j],
8890Sstevel@tonic-gate 			    mdhp->n_lst[i].a_nm[j]);
8900Sstevel@tonic-gate 	}
8910Sstevel@tonic-gate 	return (0);
8920Sstevel@tonic-gate }
8930Sstevel@tonic-gate 
8940Sstevel@tonic-gate int
meta_hi2h(md_hi_arr_t * mdhip,md_h_arr_t * mdhp,md_error_t * ep)8950Sstevel@tonic-gate meta_hi2h(md_hi_arr_t *mdhip, md_h_arr_t *mdhp, md_error_t *ep)
8960Sstevel@tonic-gate {
8970Sstevel@tonic-gate 	int			i, j;
8980Sstevel@tonic-gate 	int			max_meds;
8990Sstevel@tonic-gate 
9000Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
9010Sstevel@tonic-gate 		return (-1);
9020Sstevel@tonic-gate 
9030Sstevel@tonic-gate 	mdhp->n_cnt = mdhip->n_cnt;
9040Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
9050Sstevel@tonic-gate 		mdhp->n_lst[i].a_cnt = mdhip->n_lst[i].a_cnt;
9060Sstevel@tonic-gate 		if (mdhip->n_lst[i].a_cnt == 0)
9070Sstevel@tonic-gate 			continue;
9080Sstevel@tonic-gate 		for (j = 0; j < mdhip->n_lst[i].a_cnt; j++)
9090Sstevel@tonic-gate 			(void) strcpy(mdhp->n_lst[i].a_nm[j],
9100Sstevel@tonic-gate 			    mdhip->n_lst[i].a_nm[j]);
9110Sstevel@tonic-gate 	}
9120Sstevel@tonic-gate 	return (0);
9130Sstevel@tonic-gate }
9140Sstevel@tonic-gate 
9150Sstevel@tonic-gate int
setup_med_cfg(mdsetname_t * sp,mddb_config_t * cp,int force,md_error_t * ep)9160Sstevel@tonic-gate setup_med_cfg(
9170Sstevel@tonic-gate 	mdsetname_t		*sp,
9180Sstevel@tonic-gate 	mddb_config_t		*cp,
9190Sstevel@tonic-gate 	int			force,
9200Sstevel@tonic-gate 	md_error_t		*ep
9210Sstevel@tonic-gate )
9220Sstevel@tonic-gate {
9230Sstevel@tonic-gate 	md_set_desc		*sd;
9240Sstevel@tonic-gate 	int			i;
9250Sstevel@tonic-gate 	int			max_meds;
9260Sstevel@tonic-gate 
9270Sstevel@tonic-gate 	if (metaislocalset(sp))
9280Sstevel@tonic-gate 		return (0);
9290Sstevel@tonic-gate 
9300Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
9310Sstevel@tonic-gate 		return (-1);
9320Sstevel@tonic-gate 
9330Sstevel@tonic-gate 	if (setup_med_transtab(ep))
9340Sstevel@tonic-gate 		return (-1);
9350Sstevel@tonic-gate 
9360Sstevel@tonic-gate 	if (meta_h2hi(&sd->sd_med, &cp->c_med, ep))
9370Sstevel@tonic-gate 		return (-1);
9380Sstevel@tonic-gate 
9390Sstevel@tonic-gate 	/* Make sure the ip addresses are current */
9400Sstevel@tonic-gate 	if (meta_med_hnm2ip(&cp->c_med, ep))
9410Sstevel@tonic-gate 		return (-1);
9420Sstevel@tonic-gate 
9430Sstevel@tonic-gate 	if (force)
9440Sstevel@tonic-gate 		return (0);
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
9470Sstevel@tonic-gate 		return (-1);
9480Sstevel@tonic-gate 
9490Sstevel@tonic-gate 	/* Make sure metamedd still running on host - only chk nodename */
9500Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
9510Sstevel@tonic-gate 		char		*hostname;
9520Sstevel@tonic-gate 		char		*hnm;
9530Sstevel@tonic-gate 
9540Sstevel@tonic-gate 		if (sd->sd_med.n_lst[i].a_cnt == 0)
9550Sstevel@tonic-gate 			continue;
9560Sstevel@tonic-gate 
9570Sstevel@tonic-gate 		hnm = sd->sd_med.n_lst[i].a_nm[0];
9580Sstevel@tonic-gate 
9590Sstevel@tonic-gate 		if (clnt_med_hostname(hnm, &hostname, ep))
9600Sstevel@tonic-gate 			return (mddserror(ep, MDE_DS_NOMEDONHOST, sp->setno,
9610Sstevel@tonic-gate 			    hnm, NULL, sp->setname));
9620Sstevel@tonic-gate 		Free(hostname);
9630Sstevel@tonic-gate 	}
9640Sstevel@tonic-gate 	return (0);
9650Sstevel@tonic-gate }
9667044Smk117520 
9677044Smk117520 /*
9687044Smk117520  * This is a general routine to get mediator information from
9697044Smk117520  * file /etc/lvm/meddb. Commands medstat and metainit use this
9707044Smk117520  * routine to get mediator information from all mediator hosts or update
9717044Smk117520  * its mediator record respectively.
9727044Smk117520  */
9737044Smk117520 int
meta_mediator_info_from_file(char * sname,int verbose,md_error_t * ep)9747044Smk117520 meta_mediator_info_from_file(char *sname, int verbose, md_error_t *ep)
9757044Smk117520 {
9767044Smk117520 	uint_t		c;
9777044Smk117520 	int		i;
9787044Smk117520 	int		j;
9797044Smk117520 	int		fd;
9807044Smk117520 	int		rec_size;
9817044Smk117520 	char		*setname;
9827044Smk117520 	uint_t		setnum;
9837044Smk117520 	med_rec_t	*rec_buf = NULL;
9847044Smk117520 	med_db_hdr_t	*dbhbr;
9857044Smk117520 	med_rec_t	*medrecp;
9867044Smk117520 	med_data_t	medd;
987*8979SRameshkumar.Ramasamy@Sun.COM 	med_data_t	save_medd;
9887044Smk117520 	md_h_t		mdh;
9897044Smk117520 	uint_t		latest_med_dat_cc = 0;
9908451SRameshkumar.Ramasamy@Sun.COM 	int		retval = 0;
9917044Smk117520 	int		medok = 0;
9927044Smk117520 	int		golden = 0;
9937044Smk117520 	bool_t		obandiskset;
994*8979SRameshkumar.Ramasamy@Sun.COM 	int		isSetFound = 0;
9957044Smk117520 
9967044Smk117520 	/* Open the meddb file */
9977044Smk117520 	if ((fd = open(MED_DB_FILE, O_RDONLY, 0)) == -1) {
9988451SRameshkumar.Ramasamy@Sun.COM 
9998451SRameshkumar.Ramasamy@Sun.COM 		/*
10008451SRameshkumar.Ramasamy@Sun.COM 		 * During the start up of the SVM services, this function
10018451SRameshkumar.Ramasamy@Sun.COM 		 * will be called with an empty sname. In that case it is
10028451SRameshkumar.Ramasamy@Sun.COM 		 * entirely possible for the MED_DB_FILE not to exist.
10038451SRameshkumar.Ramasamy@Sun.COM 		 * If so, then no need to report an error.
10048451SRameshkumar.Ramasamy@Sun.COM 		 */
10058451SRameshkumar.Ramasamy@Sun.COM 		if (sname != NULL) {
10068451SRameshkumar.Ramasamy@Sun.COM 			(void) mdsyserror(ep, errno, MED_DB_FILE);
10078451SRameshkumar.Ramasamy@Sun.COM 			mde_perror(ep, dgettext(TEXT_DOMAIN,
10088451SRameshkumar.Ramasamy@Sun.COM 			    "Error in opening meddb file"));
10098451SRameshkumar.Ramasamy@Sun.COM 			return (1);
10108451SRameshkumar.Ramasamy@Sun.COM 		}
10118451SRameshkumar.Ramasamy@Sun.COM 		return (0);
10127044Smk117520 	}
10137044Smk117520 
10147044Smk117520 	/* Initialize rec_size */
10157044Smk117520 	rec_size = roundup(sizeof (med_rec_t), DEV_BSIZE);
10167044Smk117520 
10177044Smk117520 	/* Allocate a record buffer */
10187044Smk117520 	if ((rec_buf = malloc(rec_size)) == NULL) {
10198451SRameshkumar.Ramasamy@Sun.COM 		(void) mdsyserror(ep, errno, MED_DB_FILE);
10208451SRameshkumar.Ramasamy@Sun.COM 		mde_perror(ep, dgettext(TEXT_DOMAIN,
10218451SRameshkumar.Ramasamy@Sun.COM 		    "Error in allocating memory"));
10227044Smk117520 		goto out;
10237044Smk117520 	}
10247044Smk117520 
10257044Smk117520 	/* read the file header */
10267044Smk117520 	if ((read(fd, rec_buf, rec_size)) != rec_size) {
10278451SRameshkumar.Ramasamy@Sun.COM 		(void) mdsyserror(ep, EINVAL, MED_DB_FILE);
10288451SRameshkumar.Ramasamy@Sun.COM 		mde_perror(ep, dgettext(TEXT_DOMAIN,
10298451SRameshkumar.Ramasamy@Sun.COM 		    "Error in reading mediator record"));
10307044Smk117520 		goto out;
10317044Smk117520 	}
10327044Smk117520 
10337044Smk117520 	dbhbr = (med_db_hdr_t *)rec_buf;
10347044Smk117520 
10357044Smk117520 	/* Number of records in the mediator file */
10367044Smk117520 	c = dbhbr->med_dbh_nm;
10377044Smk117520 
10387044Smk117520 	for (i = 0; i < c; i++) {
10397044Smk117520 		(void) memset(rec_buf, 0, rec_size);
10407044Smk117520 
10417044Smk117520 		if (read(fd, rec_buf, rec_size) == -1) {
10428451SRameshkumar.Ramasamy@Sun.COM 			(void) mdsyserror(ep, errno, MED_DB_FILE);
10438451SRameshkumar.Ramasamy@Sun.COM 			mde_perror(ep, dgettext(TEXT_DOMAIN,
10448451SRameshkumar.Ramasamy@Sun.COM 			    "Error in reading mediator record"));
10457044Smk117520 			goto out;
10467044Smk117520 		}
10477044Smk117520 
10487044Smk117520 		medrecp = (med_rec_t *)rec_buf;
10497044Smk117520 
10507044Smk117520 		/*
10517044Smk117520 		 * For oban diskset first entry in the rec_nodes field is
1052*8979SRameshkumar.Ramasamy@Sun.COM 		 * "multiowner" and all other entries are empty.
10537044Smk117520 		 * Check if this is really multiowner diskset.
10547044Smk117520 		 */
10557044Smk117520 
10567044Smk117520 		if ((strcmp(medrecp->med_rec_nodes[0], MED_MN_CALLER) == 0) &&
1057*8979SRameshkumar.Ramasamy@Sun.COM 		    (medrecp->med_rec_nodes[1][0] == '\0'))
10587044Smk117520 			obandiskset = TRUE;
10597044Smk117520 		else
10607044Smk117520 			obandiskset = FALSE;
10617044Smk117520 
10627044Smk117520 		if (sname != NULL) {
10637044Smk117520 			/*
10647044Smk117520 			 * Continue if the set name is not in our interest.
10657044Smk117520 			 * This is required when this routine is called
10667044Smk117520 			 * from medstat
10677044Smk117520 			 */
10687044Smk117520 
10697044Smk117520 			if (strcmp(sname, medrecp->med_rec_snm) != 0) {
10707044Smk117520 				continue;
10717044Smk117520 			}
10727044Smk117520 
10737044Smk117520 			if (verbose)
10747044Smk117520 				(void) printf("%8.8s\t\t%6.6s\t%6.6s\n",
10757044Smk117520 				    gettext("Mediator"), gettext("Status"),
10767044Smk117520 				    gettext("Golden"));
10777044Smk117520 
1078*8979SRameshkumar.Ramasamy@Sun.COM 			isSetFound = 1;
10797044Smk117520 			setname = sname;
10807044Smk117520 		} else {
10817044Smk117520 			setname = medrecp->med_rec_snm;
10827044Smk117520 		}
10837044Smk117520 		setnum = medrecp->med_rec_sn;
1084*8979SRameshkumar.Ramasamy@Sun.COM 		(void) memset(&medd, '\0', sizeof (medd));
1085*8979SRameshkumar.Ramasamy@Sun.COM 		(void) memset(&mdh, '\0', sizeof (mdh));
1086*8979SRameshkumar.Ramasamy@Sun.COM 		(void) memset(&save_medd, '\0', sizeof (save_medd));
1087*8979SRameshkumar.Ramasamy@Sun.COM 		latest_med_dat_cc = 0;
10887044Smk117520 
1089*8979SRameshkumar.Ramasamy@Sun.COM 		for (j = 0; j < MED_MAX_HOSTS; j++) {
1090*8979SRameshkumar.Ramasamy@Sun.COM 			/*
1091*8979SRameshkumar.Ramasamy@Sun.COM 			 * It is possible for the n_lst[j] slot to be empty
1092*8979SRameshkumar.Ramasamy@Sun.COM 			 * if the mediator node has already been removed so
1093*8979SRameshkumar.Ramasamy@Sun.COM 			 * go to the next slot.
1094*8979SRameshkumar.Ramasamy@Sun.COM 			 */
1095*8979SRameshkumar.Ramasamy@Sun.COM 			if (medrecp->med_rec_meds.n_lst[j].a_cnt == 0)
1096*8979SRameshkumar.Ramasamy@Sun.COM 				continue;
10977044Smk117520 			mdh = medrecp->med_rec_meds.n_lst[j];
10987044Smk117520 
10997044Smk117520 			if ((sname != NULL) && (verbose))
11007044Smk117520 				(void) printf("%-17.17s\t",
11018451SRameshkumar.Ramasamy@Sun.COM 				    medrecp->med_rec_meds.n_lst[j].a_nm[0]);
11027044Smk117520 
11037044Smk117520 			if (clnt_user_med_get_data(&mdh, obandiskset,
11047044Smk117520 			    setname, setnum, &medd, ep) == -1) {
11057044Smk117520 				if (sname == NULL) {
11067044Smk117520 					continue;
11077044Smk117520 				} else {
11087044Smk117520 					if (mdanyrpcerror(ep)) {
11097044Smk117520 						if (verbose)
11107044Smk117520 							(void) printf("%s\n",
11117044Smk117520 							    gettext("Unreach"
11127044Smk117520 							    "able"));
11137044Smk117520 						continue;
11147044Smk117520 					} else if (mdiserror(ep,
11158451SRameshkumar.Ramasamy@Sun.COM 					    MDE_MED_ERROR)) {
11167044Smk117520 						if (verbose)
11177044Smk117520 							(void) printf("%s\n",
11187044Smk117520 							    gettext("Bad"));
11197044Smk117520 					} else {
11207044Smk117520 						if (verbose)
11217044Smk117520 							(void) printf("%s\n",
11227044Smk117520 							    gettext("Fatal"));
11237044Smk117520 					}
11247044Smk117520 					mde_perror(ep, "");
11257044Smk117520 					if (mdiserror(ep, MDE_MED_ERROR))
11267044Smk117520 						continue;
11277044Smk117520 					goto out;
11287044Smk117520 				}
11297044Smk117520 			} else {
1130*8979SRameshkumar.Ramasamy@Sun.COM 				/*
1131*8979SRameshkumar.Ramasamy@Sun.COM 				 * Make sure this node has the correct value
1132*8979SRameshkumar.Ramasamy@Sun.COM 				 * for the mediator record. If not we want the
1133*8979SRameshkumar.Ramasamy@Sun.COM 				 * highest value from the other nodes. Save it
1134*8979SRameshkumar.Ramasamy@Sun.COM 				 * for updating once the loop through all the
1135*8979SRameshkumar.Ramasamy@Sun.COM 				 * mediator nodes has completed.
1136*8979SRameshkumar.Ramasamy@Sun.COM 				 */
11377044Smk117520 				if (sname == NULL) {
11387044Smk117520 					if (latest_med_dat_cc <
11397044Smk117520 					    medd.med_dat_cc) {
11407044Smk117520 						latest_med_dat_cc =
11417044Smk117520 						    medd.med_dat_cc;
1142*8979SRameshkumar.Ramasamy@Sun.COM 						(void) memcpy(&save_medd, &medd,
1143*8979SRameshkumar.Ramasamy@Sun.COM 						    sizeof (medd));
11447044Smk117520 					}
11457044Smk117520 				} else {
11467044Smk117520 					if (verbose)
11477044Smk117520 						(void) printf("%s",
11487044Smk117520 						    gettext("Ok"));
11497044Smk117520 					if (medd.med_dat_fl & MED_DFL_GOLDEN) {
11507044Smk117520 						if (verbose)
11517044Smk117520 							(void) printf("\t%s",
11527044Smk117520 							    gettext("Yes"));
11537044Smk117520 						golden++;
11547044Smk117520 					} else {
11557044Smk117520 						if (verbose)
11567044Smk117520 							(void) printf("\t%s",
11577044Smk117520 							    gettext("No"));
11587044Smk117520 					}
11597044Smk117520 					if (verbose)
11607044Smk117520 						(void) printf("\n");
11617044Smk117520 						medok++;
11627044Smk117520 				}
11637044Smk117520 			}
11647044Smk117520 		}
11657044Smk117520 		if (sname == NULL) {
1166*8979SRameshkumar.Ramasamy@Sun.COM 
1167*8979SRameshkumar.Ramasamy@Sun.COM 			/*
1168*8979SRameshkumar.Ramasamy@Sun.COM 			 * Mediators only become active when there are
1169*8979SRameshkumar.Ramasamy@Sun.COM 			 * replica updates to the sets and this can only
1170*8979SRameshkumar.Ramasamy@Sun.COM 			 * occur when there is a disk in the set.
1171*8979SRameshkumar.Ramasamy@Sun.COM 			 * If there are no disks found then the save_medd
1172*8979SRameshkumar.Ramasamy@Sun.COM 			 * structure will be empty. If save_medd is empty,
1173*8979SRameshkumar.Ramasamy@Sun.COM 			 * do not update the set.
1174*8979SRameshkumar.Ramasamy@Sun.COM 			 */
1175*8979SRameshkumar.Ramasamy@Sun.COM 			if (save_medd.med_dat_sn == 0)
1176*8979SRameshkumar.Ramasamy@Sun.COM 				continue;
11777044Smk117520 			/*
11787044Smk117520 			 * Update the latest mediator information
11797044Smk117520 			 * on this node
11807044Smk117520 			 */
11817044Smk117520 			(void) strlcpy(mdh.a_nm[0], mynode(),
11827044Smk117520 			    sizeof (mdh.a_nm[0]));
1183*8979SRameshkumar.Ramasamy@Sun.COM 			mdh.a_cnt = 1;
11847044Smk117520 			if (clnt_user_med_upd_data(&mdh, obandiskset,
1185*8979SRameshkumar.Ramasamy@Sun.COM 			    setname, setnum, &save_medd, ep) == -1) {
11867044Smk117520 				/*
11877044Smk117520 				 * We had some errors while updaing the
11887044Smk117520 				 * record. This means this metaset is
11897044Smk117520 				 * not updated with latest mediator
11907044Smk117520 				 * information.
11917044Smk117520 				 */
11927044Smk117520 				mde_perror(ep, "");
11937044Smk117520 			}
1194*8979SRameshkumar.Ramasamy@Sun.COM 
11957044Smk117520 		} else {
11967044Smk117520 			if (golden) {
11977044Smk117520 				retval = 0;
11987044Smk117520 				goto out;
11997044Smk117520 			}
12007044Smk117520 			if (medok < ((medrecp->med_rec_meds.n_cnt / 2) + 1))
12017044Smk117520 				retval = 1;
12027044Smk117520 		}
12037044Smk117520 	}
12047044Smk117520 
12057044Smk117520 out:
1206*8979SRameshkumar.Ramasamy@Sun.COM 	if ((sname != NULL) && (isSetFound == 0)) {
1207*8979SRameshkumar.Ramasamy@Sun.COM 		(void) mderror(ep, MDE_NO_SET, sname);
1208*8979SRameshkumar.Ramasamy@Sun.COM 		mde_perror(ep, "");
1209*8979SRameshkumar.Ramasamy@Sun.COM 		retval = 1;
1210*8979SRameshkumar.Ramasamy@Sun.COM 	}
12117044Smk117520 	if (rec_buf != NULL)
12127044Smk117520 		Free(rec_buf);
12137044Smk117520 	if (close(fd) < 0) {
12148451SRameshkumar.Ramasamy@Sun.COM 		(void) mdsyserror(ep, errno, MED_DB_FILE);
12158451SRameshkumar.Ramasamy@Sun.COM 		mde_perror(ep, dgettext(TEXT_DOMAIN,
12168451SRameshkumar.Ramasamy@Sun.COM 		    "Error in closing meddb file"));
12177044Smk117520 		return (1);
12187044Smk117520 	}
12197044Smk117520 	return (retval);
12207044Smk117520 }
1221