xref: /onnv-gate/usr/src/lib/lvm/libmeta/common/meta_med.c (revision 7044:33050d853d04)
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
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
22*7044Smk117520 
230Sstevel@tonic-gate /*
24*7044Smk117520  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
250Sstevel@tonic-gate  * Use is subject to license terms.
260Sstevel@tonic-gate  */
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
290Sstevel@tonic-gate 
300Sstevel@tonic-gate /*
310Sstevel@tonic-gate  * Just in case we're not in a build environment, make sure that
320Sstevel@tonic-gate  * TEXT_DOMAIN gets set to something.
330Sstevel@tonic-gate  */
340Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
350Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
360Sstevel@tonic-gate #endif
370Sstevel@tonic-gate 
380Sstevel@tonic-gate /*
390Sstevel@tonic-gate  * Mediator functions
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #include <meta.h>
430Sstevel@tonic-gate #include <metamed.h>
440Sstevel@tonic-gate #include <dlfcn.h>
450Sstevel@tonic-gate #include <sdssc.h>
460Sstevel@tonic-gate 
470Sstevel@tonic-gate /*
480Sstevel@tonic-gate  * There are too many external factors that affect the timing of the
490Sstevel@tonic-gate  * operations, so we set the timeout to a very large value, in this
500Sstevel@tonic-gate  * case 1 day, which should handle HW timeouts, large configurations,
510Sstevel@tonic-gate  * and other potential delays.
520Sstevel@tonic-gate  */
530Sstevel@tonic-gate #define	CL_LONG_TMO	86400L			/* 1 day */
540Sstevel@tonic-gate #define	CL_MEDIUM_TMO	3600L			/* 1 hour */
550Sstevel@tonic-gate #define	CL_SHORT_TMO	600L			/* 10 minutes */
560Sstevel@tonic-gate #define	CL_DEF_TMO	10L			/* 10 seconds */
570Sstevel@tonic-gate 
580Sstevel@tonic-gate static	md_timeval32_t def_rpcb_timeout =  { MD_CLNT_CREATE_TOUT, 0 };
590Sstevel@tonic-gate 
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate  * RPC handle
620Sstevel@tonic-gate  */
630Sstevel@tonic-gate typedef struct {
640Sstevel@tonic-gate 	char	*hostname;
650Sstevel@tonic-gate 	CLIENT	*clntp;
660Sstevel@tonic-gate } med_handle_t;
670Sstevel@tonic-gate 
680Sstevel@tonic-gate /*
690Sstevel@tonic-gate  * Data to be sent from med_clnt_create_timed to med_create_helper via
700Sstevel@tonic-gate  * meta_client_create_retry.
710Sstevel@tonic-gate  */
720Sstevel@tonic-gate typedef struct {
730Sstevel@tonic-gate 	rpcprog_t	mcd_program;	/* RPC program designation */
740Sstevel@tonic-gate 	rpcvers_t	mcd_version;	/* RPC version */
750Sstevel@tonic-gate 	char		*mcd_nettype;	/* Type of network to use for RPC */
760Sstevel@tonic-gate } med_create_data_t;
770Sstevel@tonic-gate 
780Sstevel@tonic-gate /*
790Sstevel@tonic-gate  * Perform the work of actually doing the clnt_create for
800Sstevel@tonic-gate  * meta_client_create_retry.
810Sstevel@tonic-gate  */
820Sstevel@tonic-gate static CLIENT *
830Sstevel@tonic-gate med_create_helper(char *hostname, void *private, struct timeval *time_out)
840Sstevel@tonic-gate {
850Sstevel@tonic-gate 	med_create_data_t	*cd = (med_create_data_t *)private;
860Sstevel@tonic-gate 
870Sstevel@tonic-gate 	return (clnt_create_timed(hostname, cd->mcd_program, cd->mcd_version,
880Sstevel@tonic-gate 		cd->mcd_nettype, time_out));
890Sstevel@tonic-gate }
900Sstevel@tonic-gate 
910Sstevel@tonic-gate static
920Sstevel@tonic-gate CLIENT *med_clnt_create_timed(
930Sstevel@tonic-gate 	char *hostname,
940Sstevel@tonic-gate 	const ulong_t prog,
950Sstevel@tonic-gate 	const ulong_t vers,
960Sstevel@tonic-gate 	char *nettype,
970Sstevel@tonic-gate 	const md_timeval32_t *tp
980Sstevel@tonic-gate )
990Sstevel@tonic-gate {
1000Sstevel@tonic-gate 	med_create_data_t	cd;	/* Create data. */
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	cd.mcd_program = prog;
1030Sstevel@tonic-gate 	cd.mcd_version = vers;
1040Sstevel@tonic-gate 	cd.mcd_nettype = nettype;
1050Sstevel@tonic-gate 	return (meta_client_create_retry(hostname, med_create_helper,
1060Sstevel@tonic-gate 		(void *)&cd, (time_t)tp->tv_sec, NULL));
1070Sstevel@tonic-gate }
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate /*
1100Sstevel@tonic-gate  * Set the timeout value for this client handle.
1110Sstevel@tonic-gate  */
1120Sstevel@tonic-gate static int
1130Sstevel@tonic-gate cl_sto_medd(
1140Sstevel@tonic-gate 	CLIENT		*clntp,
1150Sstevel@tonic-gate 	char		*hostname,
1160Sstevel@tonic-gate 	long		time_out,
1170Sstevel@tonic-gate 	md_error_t	*ep
1180Sstevel@tonic-gate )
1190Sstevel@tonic-gate {
1200Sstevel@tonic-gate 	md_timeval32_t	nto;
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate 	(void) memset(&nto, '\0', sizeof (nto));
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate 	nto.tv_sec = time_out;
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 	if (clnt_control(clntp, CLSET_TIMEOUT, (char *)&nto) != TRUE)
1270Sstevel@tonic-gate 		return (mdrpcerror(ep, clntp, hostname,
1280Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "metad client set timeout")));
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 	return (0);
1310Sstevel@tonic-gate }
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate /*
1340Sstevel@tonic-gate  * close RPC connection
1350Sstevel@tonic-gate  */
1360Sstevel@tonic-gate static void
1370Sstevel@tonic-gate close_medd(
1380Sstevel@tonic-gate 	med_handle_t	*hp
1390Sstevel@tonic-gate )
1400Sstevel@tonic-gate {
1410Sstevel@tonic-gate 	assert(hp != NULL);
1420Sstevel@tonic-gate 	if (hp->hostname != NULL) {
1430Sstevel@tonic-gate 		Free(hp->hostname);
1440Sstevel@tonic-gate 	}
1450Sstevel@tonic-gate 	if (hp->clntp != NULL) {
1460Sstevel@tonic-gate 		auth_destroy(hp->clntp->cl_auth);
1470Sstevel@tonic-gate 		clnt_destroy(hp->clntp);
1480Sstevel@tonic-gate 	}
1490Sstevel@tonic-gate 	Free(hp);
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate /*
1530Sstevel@tonic-gate  * open RPC connection to rpc.medd
1540Sstevel@tonic-gate  */
1550Sstevel@tonic-gate static med_handle_t *
1560Sstevel@tonic-gate open_medd(
1570Sstevel@tonic-gate 	char		*hostname,
1580Sstevel@tonic-gate 	long		time_out,
1590Sstevel@tonic-gate 	md_error_t	*ep
1600Sstevel@tonic-gate )
1610Sstevel@tonic-gate {
1620Sstevel@tonic-gate 	CLIENT		*clntp;
1630Sstevel@tonic-gate 	med_handle_t	*hp;
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	/* default to local host */
1660Sstevel@tonic-gate 	if ((hostname == NULL) || (*hostname == '\0'))
1670Sstevel@tonic-gate 		hostname = mynode();
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	/* open RPC connection */
1700Sstevel@tonic-gate 	assert(hostname != NULL);
1710Sstevel@tonic-gate 	if ((clntp = med_clnt_create_timed(hostname, MED_PROG, MED_VERS,
1720Sstevel@tonic-gate 	    "tcp", &def_rpcb_timeout)) == NULL) {
1730Sstevel@tonic-gate 		if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED)
1740Sstevel@tonic-gate 			clnt_pcreateerror(hostname);
1750Sstevel@tonic-gate 		(void) mdrpccreateerror(ep, hostname,
1760Sstevel@tonic-gate 		    "medd med_clnt_create_timed");
1770Sstevel@tonic-gate 		return (NULL);
1780Sstevel@tonic-gate 	} else {
1790Sstevel@tonic-gate 		auth_destroy(clntp->cl_auth);
1800Sstevel@tonic-gate 		clntp->cl_auth = authsys_create_default();
1810Sstevel@tonic-gate 		assert(clntp->cl_auth != NULL);
1820Sstevel@tonic-gate 	}
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 	if (cl_sto_medd(clntp, hostname, time_out, ep) != 0)
1850Sstevel@tonic-gate 		return (NULL);
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 	/* return connection */
1880Sstevel@tonic-gate 	hp = Zalloc(sizeof (*hp));
1890Sstevel@tonic-gate 	hp->hostname = Strdup(hostname);
1900Sstevel@tonic-gate 	hp->clntp = clntp;
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate 	return (hp);
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate /*
1960Sstevel@tonic-gate  * steal and convert med_err_t
1970Sstevel@tonic-gate  */
1980Sstevel@tonic-gate int
1990Sstevel@tonic-gate meddstealerror(
2000Sstevel@tonic-gate 	md_error_t	*ep,
2010Sstevel@tonic-gate 	med_err_t	*medep
2020Sstevel@tonic-gate )
2030Sstevel@tonic-gate {
2040Sstevel@tonic-gate 	char		buf[BUFSIZ];
2050Sstevel@tonic-gate 	char		*p = buf;
2060Sstevel@tonic-gate 	size_t		psize = BUFSIZ;
2070Sstevel@tonic-gate 	char		*emsg;
2080Sstevel@tonic-gate 	int		rval = -1;
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate 	/* no error */
2110Sstevel@tonic-gate 	if (medep->med_errno == 0) {
2120Sstevel@tonic-gate 		/* assert(medep->name == NULL); */
2130Sstevel@tonic-gate 		rval = 0;
2140Sstevel@tonic-gate 		goto out;
2150Sstevel@tonic-gate 	}
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate 	/* steal error */
2180Sstevel@tonic-gate 	if ((medep->med_node != NULL) && (medep->med_node[0] != '\0')) {
2190Sstevel@tonic-gate 		(void) snprintf(p, psize, "%s: ", medep->med_node);
2200Sstevel@tonic-gate 		p = &buf[strlen(buf)];
2210Sstevel@tonic-gate 		psize = buf + BUFSIZ - p;
2220Sstevel@tonic-gate 	}
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 	if ((medep->med_misc != NULL) && (medep->med_misc[0] != '\0')) {
2250Sstevel@tonic-gate 		(void) snprintf(p, psize, "%s: ", medep->med_misc);
2260Sstevel@tonic-gate 		p = &buf[strlen(buf)];
2270Sstevel@tonic-gate 		psize = buf + BUFSIZ - p;
2280Sstevel@tonic-gate 	}
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate 	if (medep->med_errno < 0) {
2310Sstevel@tonic-gate 		if ((emsg = med_errnum_to_str(medep->med_errno)) != NULL)
2320Sstevel@tonic-gate 			(void) snprintf(p, psize, "%s", emsg);
2330Sstevel@tonic-gate 		else
2340Sstevel@tonic-gate 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
2350Sstevel@tonic-gate 			    "unknown mediator errno %d\n"), medep->med_errno);
2360Sstevel@tonic-gate 	} else {
2370Sstevel@tonic-gate 		if ((emsg = strerror(medep->med_errno)) != NULL)
2380Sstevel@tonic-gate 			(void) snprintf(p, psize, "%s", emsg);
2390Sstevel@tonic-gate 		else
2400Sstevel@tonic-gate 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
2410Sstevel@tonic-gate 			    "errno %d out of range"), medep->med_errno);
2420Sstevel@tonic-gate 	}
2430Sstevel@tonic-gate 	(void) mderror(ep, MDE_MED_ERROR, buf);
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate 	/* cleanup, return success */
2460Sstevel@tonic-gate out:
2470Sstevel@tonic-gate 	if (medep->med_node != NULL)
2480Sstevel@tonic-gate 		Free(medep->med_node);
2490Sstevel@tonic-gate 	if (medep->med_misc != NULL)
2500Sstevel@tonic-gate 		Free(medep->med_misc);
2510Sstevel@tonic-gate 	(void) memset(medep, 0, sizeof (*medep));
2520Sstevel@tonic-gate 	return (rval);
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate static med_handle_t *
2560Sstevel@tonic-gate open_medd_wrap(
2570Sstevel@tonic-gate 	md_h_t		*mdhp,
2580Sstevel@tonic-gate 	long		time_out,
2590Sstevel@tonic-gate 	md_error_t	*ep
2600Sstevel@tonic-gate )
2610Sstevel@tonic-gate {
2620Sstevel@tonic-gate 	med_handle_t		*hp = NULL;
2630Sstevel@tonic-gate 	int			i;
2640Sstevel@tonic-gate 	char    		*hnm;
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate 	assert(mdhp && mdhp->a_cnt > 0);
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	/* Loop through the hosts listed */
2690Sstevel@tonic-gate 	i = min(mdhp->a_cnt, MAX_HOST_ADDRS) - 1;
2700Sstevel@tonic-gate 	for (; i >= 0; i--) {
2710Sstevel@tonic-gate 		hnm = mdhp->a_nm[i];
2720Sstevel@tonic-gate 
2730Sstevel@tonic-gate 		if ((hp = open_medd(hnm, time_out, ep)) == NULL) {
2740Sstevel@tonic-gate 			if (mdanyrpcerror(ep) && i != 0) {
2750Sstevel@tonic-gate 				mdclrerror(ep);
2760Sstevel@tonic-gate 				continue;
2770Sstevel@tonic-gate 			}
2780Sstevel@tonic-gate 		}
2790Sstevel@tonic-gate 		return (hp);
2800Sstevel@tonic-gate 	}
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 	rpc_createerr.cf_stat = RPC_CANTSEND;
2830Sstevel@tonic-gate 	rpc_createerr.cf_error.re_status = 0;
2840Sstevel@tonic-gate 	(void) mdrpccreateerror(ep, mdhp->a_nm[0],
2850Sstevel@tonic-gate 	    dgettext(TEXT_DOMAIN, "medd open wrap"));
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate 	return (NULL);
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate static int
2910Sstevel@tonic-gate setup_med_transtab(md_error_t *ep)
2920Sstevel@tonic-gate {
2930Sstevel@tonic-gate 	mddb_med_t_parm_t	*tp = NULL;
2940Sstevel@tonic-gate 	struct	stat		statb;
2950Sstevel@tonic-gate 	int			i;
2960Sstevel@tonic-gate 	size_t			alloc_size = 0;
2970Sstevel@tonic-gate 	int			err = 0;
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate 	if ((tp = Zalloc(sizeof (mddb_med_t_parm_t))) == NULL)
3010Sstevel@tonic-gate 		return (mdsyserror(ep, ENOMEM, "setup_med_transtab"));
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate 	if (metaioctl(MD_MED_GET_TLEN, tp, &tp->med_tp_mde, NULL) != 0) {
3040Sstevel@tonic-gate 		err = mdstealerror(ep, &tp->med_tp_mde);
3050Sstevel@tonic-gate 		goto out;
3060Sstevel@tonic-gate 	}
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	if (tp->med_tp_setup == 1)
3090Sstevel@tonic-gate 		goto out;
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate 	alloc_size = (sizeof (mddb_med_t_parm_t) - sizeof (mddb_med_t_ent_t)) +
3120Sstevel@tonic-gate 	    (sizeof (mddb_med_t_ent_t) * tp->med_tp_nents);
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate 	if ((tp = Realloc(tp, alloc_size)) == NULL) {
3150Sstevel@tonic-gate 		err = mdsyserror(ep, ENOMEM, "setup_med_transtab");
3160Sstevel@tonic-gate 		goto out;
3170Sstevel@tonic-gate 	}
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 	if (metaioctl(MD_MED_GET_T, tp, &tp->med_tp_mde, NULL) != 0) {
3200Sstevel@tonic-gate 		err = mdstealerror(ep, &tp->med_tp_mde);
3210Sstevel@tonic-gate 		goto out;
3220Sstevel@tonic-gate 	}
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 	for (i = 0; i < tp->med_tp_nents; i++) {
3250Sstevel@tonic-gate 		if (meta_stat(tp->med_tp_ents[i].med_te_nm, &statb) == -1) {
3260Sstevel@tonic-gate 			md_perror("setup_med_transtab(): stat():");
3270Sstevel@tonic-gate 			tp->med_tp_ents[i].med_te_dev = NODEV64;
3280Sstevel@tonic-gate 		} else {
3290Sstevel@tonic-gate 			tp->med_tp_ents[i].med_te_dev =
3300Sstevel@tonic-gate 				meta_expldev(statb.st_rdev);
3310Sstevel@tonic-gate 		}
3320Sstevel@tonic-gate 	}
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate 	if (metaioctl(MD_MED_SET_T, tp, &tp->med_tp_mde, NULL) != 0)
3350Sstevel@tonic-gate 		err = mdstealerror(ep, &tp->med_tp_mde);
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate out:
3380Sstevel@tonic-gate 	Free(tp);
3390Sstevel@tonic-gate 	return (err);
3400Sstevel@tonic-gate }
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate /*
3430Sstevel@tonic-gate  * Externals
3440Sstevel@tonic-gate  */
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate /*
3470Sstevel@tonic-gate  * NULLPROC - just returns a response
3480Sstevel@tonic-gate  */
3490Sstevel@tonic-gate int
3500Sstevel@tonic-gate clnt_med_null(
3510Sstevel@tonic-gate 	char			*hostname,
3520Sstevel@tonic-gate 	md_error_t		*ep
3530Sstevel@tonic-gate )
3540Sstevel@tonic-gate {
3550Sstevel@tonic-gate 	med_handle_t		*hp;
3560Sstevel@tonic-gate 	med_err_t		res;
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	/* initialize */
3590Sstevel@tonic-gate 	mdclrerror(ep);
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 	/* do it */
3620Sstevel@tonic-gate 	if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL)
3630Sstevel@tonic-gate 		return (-1);
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate 	if (med_null_1(NULL, &res, hp->clntp) != RPC_SUCCESS)
3660Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hostname,
3670Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd nullproc"));
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate 	close_medd(hp);
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate 	xdr_free(xdr_med_err_t, (char *)&res);
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 	if (! mdisok(ep))
3740Sstevel@tonic-gate 		return (-1);
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate 	return (0);
3770Sstevel@tonic-gate }
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate /*
3800Sstevel@tonic-gate  * Update the mediator information on the mediator.
381*7044Smk117520  * This function does the same functionality as
382*7044Smk117520  * clnt_med_upd_data() except that it takes different
383*7044Smk117520  * argument so that host which is just a mediator, can
384*7044Smk117520  * still update its mediator record.
385*7044Smk117520  */
386*7044Smk117520 int
387*7044Smk117520 clnt_user_med_upd_data(
388*7044Smk117520 	md_h_t	*mdhp,
389*7044Smk117520 	bool_t	obandiskset,
390*7044Smk117520 	char	*setname,
391*7044Smk117520 	uint_t	setnum,
392*7044Smk117520 	med_data_t	*meddp,
393*7044Smk117520 	md_error_t	*ep
394*7044Smk117520 )
395*7044Smk117520 {
396*7044Smk117520 	med_handle_t    	*hp;
397*7044Smk117520 	med_upd_data_args_t	args;
398*7044Smk117520 	med_err_t		res;
399*7044Smk117520 
400*7044Smk117520 	/* Initialize */
401*7044Smk117520 	mdclrerror(ep);
402*7044Smk117520 	(void) memset(&args, 0, sizeof (args));
403*7044Smk117520 	(void) memset(&res, 0, sizeof (res));
404*7044Smk117520 
405*7044Smk117520 	/* Build args */
406*7044Smk117520 	if (obandiskset)
407*7044Smk117520 		args.med.med_caller = Strdup(MED_MN_CALLER);
408*7044Smk117520 	else
409*7044Smk117520 		args.med.med_caller = Strdup(mynode());
410*7044Smk117520 
411*7044Smk117520 	args.med.med_setname = Strdup(setname);
412*7044Smk117520 	args.med.med_setno = setnum;
413*7044Smk117520 	args.med_data = *meddp;
414*7044Smk117520 
415*7044Smk117520 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
416*7044Smk117520 		return (-1);
417*7044Smk117520 
418*7044Smk117520 	if (med_upd_data_1(&args, &res, hp->clntp) != RPC_SUCCESS)
419*7044Smk117520 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
420*7044Smk117520 		    dgettext(TEXT_DOMAIN, "medd get record"));
421*7044Smk117520 	else
422*7044Smk117520 		(void) meddstealerror(ep, &res);
423*7044Smk117520 
424*7044Smk117520 	close_medd(hp);
425*7044Smk117520 
426*7044Smk117520 	xdr_free(xdr_med_upd_data_args_t, (char *)&args);
427*7044Smk117520 	xdr_free(xdr_med_err_t, (char *)&res);
428*7044Smk117520 
429*7044Smk117520 	if (! mdisok(ep))
430*7044Smk117520 		return (-1);
431*7044Smk117520 
432*7044Smk117520 	return (0);
433*7044Smk117520 }
434*7044Smk117520 
435*7044Smk117520 /*
436*7044Smk117520  * Get the mediator information from the client.
437*7044Smk117520  * The code does same functinality as clnt_med_get_data()
438*7044Smk117520  * except that it takes different arguments so that
439*7044Smk117520  * host which doesn't have set information, can still
440*7044Smk117520  * get access to mediator information
441*7044Smk117520  */
442*7044Smk117520 int
443*7044Smk117520 clnt_user_med_get_data(
444*7044Smk117520 	md_h_t	*mdhp,
445*7044Smk117520 	bool_t	obandiskset,
446*7044Smk117520 	char	*setname,
447*7044Smk117520 	uint_t	setnum,
448*7044Smk117520 	med_data_t	*meddp,
449*7044Smk117520 	md_error_t	*ep
450*7044Smk117520 )
451*7044Smk117520 {
452*7044Smk117520 	int			rval = -1;
453*7044Smk117520 	med_handle_t		*hp;
454*7044Smk117520 	med_args_t		args;
455*7044Smk117520 	med_get_data_res_t	res;
456*7044Smk117520 
457*7044Smk117520 	/* Initialize */
458*7044Smk117520 	mdclrerror(ep);
459*7044Smk117520 	(void) memset(&args, 0, sizeof (args));
460*7044Smk117520 	(void) memset(&res, 0, sizeof (res));
461*7044Smk117520 
462*7044Smk117520 	/* Build args */
463*7044Smk117520 	if (obandiskset)
464*7044Smk117520 		args.med.med_caller = Strdup(MED_MN_CALLER);
465*7044Smk117520 	else
466*7044Smk117520 		args.med.med_caller = Strdup(mynode());
467*7044Smk117520 
468*7044Smk117520 	args.med.med_setname = Strdup(setname);
469*7044Smk117520 	args.med.med_setno = setnum;
470*7044Smk117520 
471*7044Smk117520 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
472*7044Smk117520 		return (-1);
473*7044Smk117520 
474*7044Smk117520 	if (med_get_data_1(&args, &res, hp->clntp) != RPC_SUCCESS)
475*7044Smk117520 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
476*7044Smk117520 		    dgettext(TEXT_DOMAIN, "medd get record"));
477*7044Smk117520 	else
478*7044Smk117520 		(void) meddstealerror(ep, &res.med_status);
479*7044Smk117520 
480*7044Smk117520 	close_medd(hp);
481*7044Smk117520 
482*7044Smk117520 	if (mdisok(ep)) {
483*7044Smk117520 		/* copy the mediator data in meddp */
484*7044Smk117520 		(void) memmove(meddp, &res.med_data, sizeof (med_data_t));
485*7044Smk117520 		rval = 0;
486*7044Smk117520 	}
487*7044Smk117520 
488*7044Smk117520 	xdr_free(xdr_med_args_t, (char *)&args);
489*7044Smk117520 	xdr_free(xdr_med_get_data_res_t, (char *)&res);
490*7044Smk117520 
491*7044Smk117520 	return (rval);
492*7044Smk117520 }
493*7044Smk117520 
494*7044Smk117520 
495*7044Smk117520 /*
496*7044Smk117520  * Update the mediator information on the mediator.
4970Sstevel@tonic-gate  * *** This is not normally called from user code, the kernel does this! ***
4980Sstevel@tonic-gate  */
4990Sstevel@tonic-gate int
5000Sstevel@tonic-gate clnt_med_upd_data(
5010Sstevel@tonic-gate 	md_h_t			*mdhp,
5020Sstevel@tonic-gate 	mdsetname_t		*sp,
5030Sstevel@tonic-gate 	med_data_t		*meddp,
5040Sstevel@tonic-gate 	md_error_t		*ep
5050Sstevel@tonic-gate )
5060Sstevel@tonic-gate {
5070Sstevel@tonic-gate 	med_handle_t		*hp;
5080Sstevel@tonic-gate 	med_upd_data_args_t	args;
5090Sstevel@tonic-gate 	med_err_t		res;
5100Sstevel@tonic-gate 	md_set_desc		*sd;
5110Sstevel@tonic-gate 
5120Sstevel@tonic-gate 	/* initialize */
5130Sstevel@tonic-gate 	mdclrerror(ep);
5140Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
5150Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
5160Sstevel@tonic-gate 
5170Sstevel@tonic-gate 	/* build args */
5180Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
5190Sstevel@tonic-gate 		return (-1);
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
5220Sstevel@tonic-gate 		/*
5230Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
5240Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
5250Sstevel@tonic-gate 		 * any node to access mediator information.
5260Sstevel@tonic-gate 		 *
5270Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
5280Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
5290Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
5300Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
5310Sstevel@tonic-gate 		 *
5320Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
5330Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
5340Sstevel@tonic-gate 		 * mediator data.
5350Sstevel@tonic-gate 		 */
5360Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
5370Sstevel@tonic-gate 	else
5380Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
5390Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
5400Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
5410Sstevel@tonic-gate 	args.med_data = *meddp;
5420Sstevel@tonic-gate 
5430Sstevel@tonic-gate 	/* do it */
5440Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
5450Sstevel@tonic-gate 		return (-1);
5460Sstevel@tonic-gate 
5470Sstevel@tonic-gate 	if (med_upd_data_1(&args, &res, hp->clntp) != RPC_SUCCESS)
5480Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
5490Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd update data"));
5500Sstevel@tonic-gate 	else
5510Sstevel@tonic-gate 		(void) meddstealerror(ep, &res);
5520Sstevel@tonic-gate 
5530Sstevel@tonic-gate 	close_medd(hp);
5540Sstevel@tonic-gate 
5550Sstevel@tonic-gate 	xdr_free(xdr_med_upd_data_args_t, (char *)&args);
5560Sstevel@tonic-gate 	xdr_free(xdr_med_err_t, (char *)&res);
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate 	if (! mdisok(ep))
5590Sstevel@tonic-gate 		return (-1);
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate 	return (0);
5620Sstevel@tonic-gate }
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate /*
5650Sstevel@tonic-gate  * Get the mediator data for this client from the mediator
5660Sstevel@tonic-gate  */
5670Sstevel@tonic-gate int
5680Sstevel@tonic-gate clnt_med_get_data(
5690Sstevel@tonic-gate 	md_h_t			*mdhp,
5700Sstevel@tonic-gate 	mdsetname_t		*sp,
5710Sstevel@tonic-gate 	med_data_t		*meddp,
5720Sstevel@tonic-gate 	md_error_t		*ep
5730Sstevel@tonic-gate )
5740Sstevel@tonic-gate {
5750Sstevel@tonic-gate 	med_handle_t		*hp;
5760Sstevel@tonic-gate 	med_args_t		args;
5770Sstevel@tonic-gate 	med_get_data_res_t	res;
5780Sstevel@tonic-gate 	int			rval = -1;
5790Sstevel@tonic-gate 	md_set_desc		*sd;
5800Sstevel@tonic-gate 
5810Sstevel@tonic-gate 	/* initialize */
5820Sstevel@tonic-gate 	mdclrerror(ep);
5830Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
5840Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
5850Sstevel@tonic-gate 
5860Sstevel@tonic-gate 	/* build args */
5870Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
5880Sstevel@tonic-gate 		return (-1);
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
5910Sstevel@tonic-gate 		/*
5920Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
5930Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
5940Sstevel@tonic-gate 		 * any node to access mediator information.
5950Sstevel@tonic-gate 		 *
5960Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
5970Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
5980Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
5990Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
6000Sstevel@tonic-gate 		 *
6010Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
6020Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
6030Sstevel@tonic-gate 		 * mediator data.
6040Sstevel@tonic-gate 		 */
6050Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
6060Sstevel@tonic-gate 	else
6070Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
6080Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
6090Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
6100Sstevel@tonic-gate 
6110Sstevel@tonic-gate 	/* do it */
6120Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
6130Sstevel@tonic-gate 		return (-1);
6140Sstevel@tonic-gate 
6150Sstevel@tonic-gate 	if (med_get_data_1(&args, &res, hp->clntp) != RPC_SUCCESS)
6160Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
6170Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd get data"));
6180Sstevel@tonic-gate 	else
6190Sstevel@tonic-gate 		(void) meddstealerror(ep, &res.med_status);
6200Sstevel@tonic-gate 
6210Sstevel@tonic-gate 	close_medd(hp);
6220Sstevel@tonic-gate 
6230Sstevel@tonic-gate 	if (mdisok(ep)) {
6240Sstevel@tonic-gate 		/* do something with the results */
6250Sstevel@tonic-gate 		(void) memmove(meddp, &res.med_data, sizeof (med_data_t));
6260Sstevel@tonic-gate 		rval = 0;
6270Sstevel@tonic-gate 	}
6280Sstevel@tonic-gate 
6290Sstevel@tonic-gate 	xdr_free(xdr_med_args_t, (char *)&args);
6300Sstevel@tonic-gate 	xdr_free(xdr_med_get_data_res_t, (char *)&res);
6310Sstevel@tonic-gate 
6320Sstevel@tonic-gate 	return (rval);
6330Sstevel@tonic-gate }
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate /*
6360Sstevel@tonic-gate  * Update the mediator record on the mediator.
6370Sstevel@tonic-gate  */
6380Sstevel@tonic-gate int
6390Sstevel@tonic-gate clnt_med_upd_rec(
6400Sstevel@tonic-gate 	md_h_t			*mdhp,
6410Sstevel@tonic-gate 	mdsetname_t		*sp,
6420Sstevel@tonic-gate 	med_rec_t		*medrp,
6430Sstevel@tonic-gate 	md_error_t		*ep
6440Sstevel@tonic-gate )
6450Sstevel@tonic-gate {
6460Sstevel@tonic-gate 	med_handle_t		*hp;
6470Sstevel@tonic-gate 	med_upd_rec_args_t	args;
6480Sstevel@tonic-gate 	med_err_t		res;
6490Sstevel@tonic-gate 	md_set_desc		*sd;
6500Sstevel@tonic-gate 
6510Sstevel@tonic-gate 	/* initialize */
6520Sstevel@tonic-gate 	mdclrerror(ep);
6530Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
6540Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
6550Sstevel@tonic-gate 
6560Sstevel@tonic-gate 	/* build args */
6570Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
6580Sstevel@tonic-gate 		return (-1);
6590Sstevel@tonic-gate 
6600Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
6610Sstevel@tonic-gate 		/*
6620Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
6630Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
6640Sstevel@tonic-gate 		 * any node to access mediator information.
6650Sstevel@tonic-gate 		 *
6660Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
6670Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
6680Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
6690Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
6700Sstevel@tonic-gate 		 *
6710Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
6720Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
6730Sstevel@tonic-gate 		 * mediator data.
6740Sstevel@tonic-gate 		 */
6750Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
6760Sstevel@tonic-gate 	else
6770Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
6780Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
6790Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
6800Sstevel@tonic-gate 	args.med_flags = 0;
6810Sstevel@tonic-gate 	args.med_rec = *medrp;			/* structure assignment */
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate 	/* do it */
6840Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
6850Sstevel@tonic-gate 		return (-1);
6860Sstevel@tonic-gate 
6870Sstevel@tonic-gate 	if (med_upd_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS)
6880Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
6890Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd update record"));
6900Sstevel@tonic-gate 	else
6910Sstevel@tonic-gate 		(void) meddstealerror(ep, &res);
6920Sstevel@tonic-gate 
6930Sstevel@tonic-gate 	close_medd(hp);
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 	xdr_free(xdr_med_upd_rec_args_t, (char *)&args);
6960Sstevel@tonic-gate 	xdr_free(xdr_med_err_t, (char *)&res);
6970Sstevel@tonic-gate 
6980Sstevel@tonic-gate 	if (! mdisok(ep))
6990Sstevel@tonic-gate 		return (-1);
7000Sstevel@tonic-gate 
7010Sstevel@tonic-gate 	return (0);
7020Sstevel@tonic-gate }
7030Sstevel@tonic-gate 
7040Sstevel@tonic-gate /*
7050Sstevel@tonic-gate  * Get the mediator record for this client from the mediator
7060Sstevel@tonic-gate  */
7070Sstevel@tonic-gate int
7080Sstevel@tonic-gate clnt_med_get_rec(
7090Sstevel@tonic-gate 	md_h_t			*mdhp,
7100Sstevel@tonic-gate 	mdsetname_t		*sp,
7110Sstevel@tonic-gate 	med_rec_t		*medrp,
7120Sstevel@tonic-gate 	md_error_t		*ep
7130Sstevel@tonic-gate )
7140Sstevel@tonic-gate {
7150Sstevel@tonic-gate 	med_handle_t		*hp;
7160Sstevel@tonic-gate 	med_args_t		args;
7170Sstevel@tonic-gate 	med_get_rec_res_t	res;
7180Sstevel@tonic-gate 	int			rval = -1;
7190Sstevel@tonic-gate 	md_set_desc		*sd;
7200Sstevel@tonic-gate 
7210Sstevel@tonic-gate 	/* initialize */
7220Sstevel@tonic-gate 	mdclrerror(ep);
7230Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
7240Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 	/* build args */
7270Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
7280Sstevel@tonic-gate 		return (-1);
7290Sstevel@tonic-gate 
7300Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd))
7310Sstevel@tonic-gate 		/*
7320Sstevel@tonic-gate 		 * In the MN diskset, use a generic nodename, multiowner, as
7330Sstevel@tonic-gate 		 * the node initiating the RPC request.  This allows
7340Sstevel@tonic-gate 		 * any node to access mediator information.
7350Sstevel@tonic-gate 		 *
7360Sstevel@tonic-gate 		 * MN diskset reconfig cycle forces consistent
7370Sstevel@tonic-gate 		 * view of set/node/drive/mediator information across all nodes
7380Sstevel@tonic-gate 		 * in the MN diskset.  This allows the relaxation of
7390Sstevel@tonic-gate 		 * node name checking in rpc.metamedd for MN disksets.
7400Sstevel@tonic-gate 		 *
7410Sstevel@tonic-gate 		 * In the traditional diskset, only a calling node that is
7420Sstevel@tonic-gate 		 * in the mediator record's diskset nodelist can access
7430Sstevel@tonic-gate 		 * mediator data.
7440Sstevel@tonic-gate 		 */
7450Sstevel@tonic-gate 		args.med.med_caller = Strdup(MED_MN_CALLER);
7460Sstevel@tonic-gate 	else
7470Sstevel@tonic-gate 		args.med.med_caller = Strdup(mynode());
7480Sstevel@tonic-gate 	args.med.med_setname = Strdup(sp->setname);
7490Sstevel@tonic-gate 	args.med.med_setno = sp->setno;
7500Sstevel@tonic-gate 
7510Sstevel@tonic-gate 	/* do it */
7520Sstevel@tonic-gate 	if ((hp = open_medd_wrap(mdhp, CL_DEF_TMO, ep)) == NULL)
7530Sstevel@tonic-gate 		return (-1);
7540Sstevel@tonic-gate 
7550Sstevel@tonic-gate 	if (med_get_rec_1(&args, &res, hp->clntp) != RPC_SUCCESS)
7560Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hp->hostname,
7570Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd get record"));
7580Sstevel@tonic-gate 	else
7590Sstevel@tonic-gate 		(void) meddstealerror(ep, &res.med_status);
7600Sstevel@tonic-gate 
7610Sstevel@tonic-gate 	close_medd(hp);
7620Sstevel@tonic-gate 
7630Sstevel@tonic-gate 	if (mdisok(ep)) {
7640Sstevel@tonic-gate 		/* do something with the results */
7650Sstevel@tonic-gate 		(void) memmove(medrp, &res.med_rec, sizeof (med_rec_t));
7660Sstevel@tonic-gate 		rval = 0;
7670Sstevel@tonic-gate 	}
7680Sstevel@tonic-gate 
7690Sstevel@tonic-gate 	xdr_free(xdr_med_args_t, (char *)&args);
7700Sstevel@tonic-gate 	xdr_free(xdr_med_get_rec_res_t, (char *)&res);
7710Sstevel@tonic-gate 
7720Sstevel@tonic-gate 	return (rval);
7730Sstevel@tonic-gate }
7740Sstevel@tonic-gate 
7750Sstevel@tonic-gate /*
7760Sstevel@tonic-gate  * Get the name of the host from the mediator daemon.
7770Sstevel@tonic-gate  */
7780Sstevel@tonic-gate int
7790Sstevel@tonic-gate clnt_med_hostname(
7800Sstevel@tonic-gate 	char			*hostname,
7810Sstevel@tonic-gate 	char			**ret_hostname,
7820Sstevel@tonic-gate 	md_error_t		*ep
7830Sstevel@tonic-gate )
7840Sstevel@tonic-gate {
7850Sstevel@tonic-gate 	med_handle_t		*hp;
7860Sstevel@tonic-gate 	med_hnm_res_t		res;
7870Sstevel@tonic-gate 	int			rval = -1;
7880Sstevel@tonic-gate 
7890Sstevel@tonic-gate 	/* initialize */
7900Sstevel@tonic-gate 	mdclrerror(ep);
7910Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
7920Sstevel@tonic-gate 
7930Sstevel@tonic-gate 	/* No args */
7940Sstevel@tonic-gate 
7950Sstevel@tonic-gate 	/* do it */
7960Sstevel@tonic-gate 	if ((hp = open_medd(hostname, CL_DEF_TMO, ep)) == NULL)
7970Sstevel@tonic-gate 		return (-1);
7980Sstevel@tonic-gate 
7990Sstevel@tonic-gate 	if (med_hostname_1(NULL, &res, hp->clntp) != RPC_SUCCESS)
8000Sstevel@tonic-gate 		(void) mdrpcerror(ep, hp->clntp, hostname,
8010Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "medd hostname"));
8020Sstevel@tonic-gate 	else
8030Sstevel@tonic-gate 		(void) meddstealerror(ep, &res.med_status);
8040Sstevel@tonic-gate 
8050Sstevel@tonic-gate 	close_medd(hp);
8060Sstevel@tonic-gate 
8070Sstevel@tonic-gate 	if (mdisok(ep)) {
8080Sstevel@tonic-gate 		/* do something with the results */
8090Sstevel@tonic-gate 		rval = 0;
8100Sstevel@tonic-gate 
8110Sstevel@tonic-gate 		if (ret_hostname != NULL)
8120Sstevel@tonic-gate 			*ret_hostname = Strdup(res.med_hnm);
8130Sstevel@tonic-gate 	}
8140Sstevel@tonic-gate 
8150Sstevel@tonic-gate 	xdr_free(xdr_med_hnm_res_t, (char *)&res);
8160Sstevel@tonic-gate 
8170Sstevel@tonic-gate 	return (rval);
8180Sstevel@tonic-gate }
8190Sstevel@tonic-gate 
8200Sstevel@tonic-gate int
8210Sstevel@tonic-gate meta_med_hnm2ip(md_hi_arr_t *mp, md_error_t *ep)
8220Sstevel@tonic-gate {
8230Sstevel@tonic-gate 	int		i, j;
8240Sstevel@tonic-gate 	int		max_meds;
8250Sstevel@tonic-gate 
8260Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
8270Sstevel@tonic-gate 		return (-1);
8280Sstevel@tonic-gate 
8290Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
8300Sstevel@tonic-gate 		mp->n_lst[i].a_flg = 0;
8310Sstevel@tonic-gate 		/* See if this is the local host */
8320Sstevel@tonic-gate 		if (mp->n_lst[i].a_cnt > 0 &&
8330Sstevel@tonic-gate 		    strcmp(mp->n_lst[i].a_nm[0], mynode()) == NULL)
8340Sstevel@tonic-gate 			mp->n_lst[i].a_flg |= NMIP_F_LOCAL;
8350Sstevel@tonic-gate 
8360Sstevel@tonic-gate 		for (j = 0; j < mp->n_lst[i].a_cnt; j++) {
8370Sstevel@tonic-gate 			struct hostent	*hp;
8380Sstevel@tonic-gate 			char		*hnm = mp->n_lst[i].a_nm[j];
8390Sstevel@tonic-gate 
8400Sstevel@tonic-gate 			/*
8410Sstevel@tonic-gate 			 * Cluster nodename support
8420Sstevel@tonic-gate 			 *
8430Sstevel@tonic-gate 			 * See if the clustering code can give us an IP addr
8440Sstevel@tonic-gate 			 * for the stored name. If not, find it the old way
8450Sstevel@tonic-gate 			 * which will use the public interface.
8460Sstevel@tonic-gate 			 */
8470Sstevel@tonic-gate 			if (sdssc_get_priv_ipaddr(mp->n_lst[i].a_nm[j],
8480Sstevel@tonic-gate 			    (struct in_addr *)&mp->n_lst[i].a_ip[j]) !=
8490Sstevel@tonic-gate 					SDSSC_OKAY) {
8500Sstevel@tonic-gate 				if ((hp = gethostbyname(hnm)) == NULL)
8510Sstevel@tonic-gate 					return (mdsyserror(ep, EADDRNOTAVAIL,
8520Sstevel@tonic-gate 					    hnm));
8530Sstevel@tonic-gate 
8540Sstevel@tonic-gate 				/* We only do INET addresses */
8550Sstevel@tonic-gate 				if (hp->h_addrtype != AF_INET)
8560Sstevel@tonic-gate 					return (mdsyserror(ep, EPFNOSUPPORT,
8570Sstevel@tonic-gate 					    hnm));
8580Sstevel@tonic-gate 
8590Sstevel@tonic-gate 				/* We take the first address only */
8600Sstevel@tonic-gate 				if (*hp->h_addr_list) {
8610Sstevel@tonic-gate 					(void) memmove(&mp->n_lst[i].a_ip[j],
8620Sstevel@tonic-gate 					    *hp->h_addr_list,
8630Sstevel@tonic-gate 					    sizeof (struct in_addr));
8640Sstevel@tonic-gate 				} else
8650Sstevel@tonic-gate 					return (mdsyserror(ep, EADDRNOTAVAIL,
8660Sstevel@tonic-gate 					    hnm));
8670Sstevel@tonic-gate 			}
8680Sstevel@tonic-gate 
8690Sstevel@tonic-gate 		}
8700Sstevel@tonic-gate 	}
8710Sstevel@tonic-gate 	return (0);
8720Sstevel@tonic-gate }
8730Sstevel@tonic-gate 
8740Sstevel@tonic-gate int
8750Sstevel@tonic-gate meta_h2hi(md_h_arr_t *mdhp, md_hi_arr_t *mdhip, md_error_t *ep)
8760Sstevel@tonic-gate {
8770Sstevel@tonic-gate 	int			i, j;
8780Sstevel@tonic-gate 	int			max_meds;
8790Sstevel@tonic-gate 
8800Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
8810Sstevel@tonic-gate 		return (-1);
8820Sstevel@tonic-gate 
8830Sstevel@tonic-gate 	mdhip->n_cnt = mdhp->n_cnt;
8840Sstevel@tonic-gate 
8850Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
8860Sstevel@tonic-gate 		mdhip->n_lst[i].a_flg = 0;
8870Sstevel@tonic-gate 		mdhip->n_lst[i].a_cnt = mdhp->n_lst[i].a_cnt;
8880Sstevel@tonic-gate 		if (mdhp->n_lst[i].a_cnt == 0)
8890Sstevel@tonic-gate 			continue;
8900Sstevel@tonic-gate 		for (j = 0; j < mdhp->n_lst[i].a_cnt; j++)
8910Sstevel@tonic-gate 			(void) strcpy(mdhip->n_lst[i].a_nm[j],
8920Sstevel@tonic-gate 			    mdhp->n_lst[i].a_nm[j]);
8930Sstevel@tonic-gate 	}
8940Sstevel@tonic-gate 	return (0);
8950Sstevel@tonic-gate }
8960Sstevel@tonic-gate 
8970Sstevel@tonic-gate int
8980Sstevel@tonic-gate meta_hi2h(md_hi_arr_t *mdhip, md_h_arr_t *mdhp, md_error_t *ep)
8990Sstevel@tonic-gate {
9000Sstevel@tonic-gate 	int			i, j;
9010Sstevel@tonic-gate 	int			max_meds;
9020Sstevel@tonic-gate 
9030Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
9040Sstevel@tonic-gate 		return (-1);
9050Sstevel@tonic-gate 
9060Sstevel@tonic-gate 	mdhp->n_cnt = mdhip->n_cnt;
9070Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
9080Sstevel@tonic-gate 		mdhp->n_lst[i].a_cnt = mdhip->n_lst[i].a_cnt;
9090Sstevel@tonic-gate 		if (mdhip->n_lst[i].a_cnt == 0)
9100Sstevel@tonic-gate 			continue;
9110Sstevel@tonic-gate 		for (j = 0; j < mdhip->n_lst[i].a_cnt; j++)
9120Sstevel@tonic-gate 			(void) strcpy(mdhp->n_lst[i].a_nm[j],
9130Sstevel@tonic-gate 			    mdhip->n_lst[i].a_nm[j]);
9140Sstevel@tonic-gate 	}
9150Sstevel@tonic-gate 	return (0);
9160Sstevel@tonic-gate }
9170Sstevel@tonic-gate 
9180Sstevel@tonic-gate int
9190Sstevel@tonic-gate setup_med_cfg(
9200Sstevel@tonic-gate 	mdsetname_t		*sp,
9210Sstevel@tonic-gate 	mddb_config_t		*cp,
9220Sstevel@tonic-gate 	int			force,
9230Sstevel@tonic-gate 	md_error_t		*ep
9240Sstevel@tonic-gate )
9250Sstevel@tonic-gate {
9260Sstevel@tonic-gate 	md_set_desc		*sd;
9270Sstevel@tonic-gate 	int			i;
9280Sstevel@tonic-gate 	int			max_meds;
9290Sstevel@tonic-gate 
9300Sstevel@tonic-gate 	if (metaislocalset(sp))
9310Sstevel@tonic-gate 		return (0);
9320Sstevel@tonic-gate 
9330Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
9340Sstevel@tonic-gate 		return (-1);
9350Sstevel@tonic-gate 
9360Sstevel@tonic-gate 	if (setup_med_transtab(ep))
9370Sstevel@tonic-gate 		return (-1);
9380Sstevel@tonic-gate 
9390Sstevel@tonic-gate 	if (meta_h2hi(&sd->sd_med, &cp->c_med, ep))
9400Sstevel@tonic-gate 		return (-1);
9410Sstevel@tonic-gate 
9420Sstevel@tonic-gate 	/* Make sure the ip addresses are current */
9430Sstevel@tonic-gate 	if (meta_med_hnm2ip(&cp->c_med, ep))
9440Sstevel@tonic-gate 		return (-1);
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate 	if (force)
9470Sstevel@tonic-gate 		return (0);
9480Sstevel@tonic-gate 
9490Sstevel@tonic-gate 	if ((max_meds = get_max_meds(ep)) == 0)
9500Sstevel@tonic-gate 		return (-1);
9510Sstevel@tonic-gate 
9520Sstevel@tonic-gate 	/* Make sure metamedd still running on host - only chk nodename */
9530Sstevel@tonic-gate 	for (i = 0; i < max_meds; i++) {
9540Sstevel@tonic-gate 		char		*hostname;
9550Sstevel@tonic-gate 		char		*hnm;
9560Sstevel@tonic-gate 
9570Sstevel@tonic-gate 		if (sd->sd_med.n_lst[i].a_cnt == 0)
9580Sstevel@tonic-gate 			continue;
9590Sstevel@tonic-gate 
9600Sstevel@tonic-gate 		hnm = sd->sd_med.n_lst[i].a_nm[0];
9610Sstevel@tonic-gate 
9620Sstevel@tonic-gate 		if (clnt_med_hostname(hnm, &hostname, ep))
9630Sstevel@tonic-gate 			return (mddserror(ep, MDE_DS_NOMEDONHOST, sp->setno,
9640Sstevel@tonic-gate 			    hnm, NULL, sp->setname));
9650Sstevel@tonic-gate 		Free(hostname);
9660Sstevel@tonic-gate 	}
9670Sstevel@tonic-gate 	return (0);
9680Sstevel@tonic-gate }
969*7044Smk117520 
970*7044Smk117520 /*
971*7044Smk117520  * This is a general routine to get mediator information from
972*7044Smk117520  * file /etc/lvm/meddb. Commands medstat and metainit use this
973*7044Smk117520  * routine to get mediator information from all mediator hosts or update
974*7044Smk117520  * its mediator record respectively.
975*7044Smk117520  */
976*7044Smk117520 int
977*7044Smk117520 meta_mediator_info_from_file(char *sname, int verbose, md_error_t *ep)
978*7044Smk117520 {
979*7044Smk117520 	uint_t		c;
980*7044Smk117520 	int		i;
981*7044Smk117520 	int		j;
982*7044Smk117520 	int		fd;
983*7044Smk117520 	int		rec_size;
984*7044Smk117520 	char		*setname;
985*7044Smk117520 	uint_t		setnum;
986*7044Smk117520 	med_rec_t	*rec_buf = NULL;
987*7044Smk117520 	med_db_hdr_t	*dbhbr;
988*7044Smk117520 	med_rec_t	*medrecp;
989*7044Smk117520 	med_data_t	medd;
990*7044Smk117520 	med_data_t	*save_medd;
991*7044Smk117520 	md_h_t		mdh;
992*7044Smk117520 	uint_t		latest_med_dat_cc = 0;
993*7044Smk117520 	int		retval;
994*7044Smk117520 	int		medok = 0;
995*7044Smk117520 	int		golden = 0;
996*7044Smk117520 	bool_t		obandiskset;
997*7044Smk117520 
998*7044Smk117520 	/* Open the meddb file */
999*7044Smk117520 	if ((fd = open(MED_DB_FILE, O_RDONLY, 0)) == -1) {
1000*7044Smk117520 		mde_perror(ep, "Error in opening meddb file");
1001*7044Smk117520 		return (1);
1002*7044Smk117520 	}
1003*7044Smk117520 
1004*7044Smk117520 	/* Initialize rec_size */
1005*7044Smk117520 	rec_size = roundup(sizeof (med_rec_t), DEV_BSIZE);
1006*7044Smk117520 
1007*7044Smk117520 	/* Allocate a record buffer */
1008*7044Smk117520 	if ((rec_buf = malloc(rec_size)) == NULL) {
1009*7044Smk117520 		mde_perror(ep, "Error in allocating memory");
1010*7044Smk117520 		goto out;
1011*7044Smk117520 	}
1012*7044Smk117520 
1013*7044Smk117520 	/* read the file header */
1014*7044Smk117520 	if ((read(fd, rec_buf, rec_size)) != rec_size) {
1015*7044Smk117520 		mde_perror(ep, "Error in reading mediator record");
1016*7044Smk117520 		goto out;
1017*7044Smk117520 	}
1018*7044Smk117520 
1019*7044Smk117520 	dbhbr = (med_db_hdr_t *)rec_buf;
1020*7044Smk117520 
1021*7044Smk117520 	/* Number of records in the mediator file */
1022*7044Smk117520 	c = dbhbr->med_dbh_nm;
1023*7044Smk117520 
1024*7044Smk117520 	for (i = 0; i < c; i++) {
1025*7044Smk117520 		(void) memset(rec_buf, 0, rec_size);
1026*7044Smk117520 
1027*7044Smk117520 		if (read(fd, rec_buf, rec_size) == -1) {
1028*7044Smk117520 			mde_perror(ep, "Error in reading mediator record");
1029*7044Smk117520 			goto out;
1030*7044Smk117520 		}
1031*7044Smk117520 
1032*7044Smk117520 		medrecp = (med_rec_t *)rec_buf;
1033*7044Smk117520 
1034*7044Smk117520 		/*
1035*7044Smk117520 		 * For oban diskset first entry in the rec_nodes field is
1036*7044Smk117520 		 * "multiowner" and all other entries are null
1037*7044Smk117520 		 * Check if this is really multiowner diskset.
1038*7044Smk117520 		 */
1039*7044Smk117520 
1040*7044Smk117520 		if ((strcmp(medrecp->med_rec_nodes[0], MED_MN_CALLER) == 0) &&
1041*7044Smk117520 		    (medrecp->med_rec_nodes[1] == NULL))
1042*7044Smk117520 			obandiskset = TRUE;
1043*7044Smk117520 		else
1044*7044Smk117520 			obandiskset = FALSE;
1045*7044Smk117520 
1046*7044Smk117520 		if (sname != NULL) {
1047*7044Smk117520 			/*
1048*7044Smk117520 			 * Continue if the set name is not in our interest.
1049*7044Smk117520 			 * This is required when this routine is called
1050*7044Smk117520 			 * from medstat
1051*7044Smk117520 			 */
1052*7044Smk117520 
1053*7044Smk117520 			if (strcmp(sname, medrecp->med_rec_snm) != 0) {
1054*7044Smk117520 				continue;
1055*7044Smk117520 			}
1056*7044Smk117520 
1057*7044Smk117520 			if (verbose)
1058*7044Smk117520 				(void) printf("%8.8s\t\t%6.6s\t%6.6s\n",
1059*7044Smk117520 				    gettext("Mediator"), gettext("Status"),
1060*7044Smk117520 				    gettext("Golden"));
1061*7044Smk117520 
1062*7044Smk117520 			if (medrecp->med_rec_meds.n_cnt == 0) {
1063*7044Smk117520 				if (verbose)
1064*7044Smk117520 					(void) printf(gettext(
1065*7044Smk117520 					    "No mediator hosts configured for"
1066*7044Smk117520 					    " set \"%s\".\n"),
1067*7044Smk117520 					    sname);
1068*7044Smk117520 				goto out;
1069*7044Smk117520 			}
1070*7044Smk117520 			setname = sname;
1071*7044Smk117520 		} else {
1072*7044Smk117520 			setname = medrecp->med_rec_snm;
1073*7044Smk117520 		}
1074*7044Smk117520 		setnum = medrecp->med_rec_sn;
1075*7044Smk117520 
1076*7044Smk117520 		for (j = 0; j < medrecp->med_rec_meds.n_cnt; j ++) {
1077*7044Smk117520 			(void) memset(&medd, 0, sizeof (medd));
1078*7044Smk117520 			(void) memset(&mdh, 0, sizeof (mdh));
1079*7044Smk117520 			mdh = medrecp->med_rec_meds.n_lst[j];
1080*7044Smk117520 
1081*7044Smk117520 			if ((sname != NULL) && (verbose))
1082*7044Smk117520 				(void) printf("%-17.17s\t",
1083*7044Smk117520 					medrecp->med_rec_meds.n_lst[j].a_nm[0]);
1084*7044Smk117520 
1085*7044Smk117520 			if (clnt_user_med_get_data(&mdh, obandiskset,
1086*7044Smk117520 			    setname, setnum, &medd, ep) == -1) {
1087*7044Smk117520 				if (sname == NULL) {
1088*7044Smk117520 					continue;
1089*7044Smk117520 				} else {
1090*7044Smk117520 					if (mdanyrpcerror(ep)) {
1091*7044Smk117520 						if (verbose)
1092*7044Smk117520 							(void) printf("%s\n",
1093*7044Smk117520 							    gettext("Unreach"
1094*7044Smk117520 							    "able"));
1095*7044Smk117520 						continue;
1096*7044Smk117520 					} else if (mdiserror(ep,
1097*7044Smk117520 						MDE_MED_ERROR)) {
1098*7044Smk117520 						if (verbose)
1099*7044Smk117520 							(void) printf("%s\n",
1100*7044Smk117520 							    gettext("Bad"));
1101*7044Smk117520 					} else {
1102*7044Smk117520 						if (verbose)
1103*7044Smk117520 							(void) printf("%s\n",
1104*7044Smk117520 							    gettext("Fatal"));
1105*7044Smk117520 					}
1106*7044Smk117520 					mde_perror(ep, "");
1107*7044Smk117520 					if (mdiserror(ep, MDE_MED_ERROR))
1108*7044Smk117520 						continue;
1109*7044Smk117520 					goto out;
1110*7044Smk117520 				}
1111*7044Smk117520 			} else {
1112*7044Smk117520 				if (sname == NULL) {
1113*7044Smk117520 					if (latest_med_dat_cc <
1114*7044Smk117520 					    medd.med_dat_cc) {
1115*7044Smk117520 						latest_med_dat_cc =
1116*7044Smk117520 						    medd.med_dat_cc;
1117*7044Smk117520 						save_medd = &medd;
1118*7044Smk117520 					}
1119*7044Smk117520 				} else {
1120*7044Smk117520 					if (verbose)
1121*7044Smk117520 						(void) printf("%s",
1122*7044Smk117520 						    gettext("Ok"));
1123*7044Smk117520 					if (medd.med_dat_fl & MED_DFL_GOLDEN) {
1124*7044Smk117520 						if (verbose)
1125*7044Smk117520 							(void) printf("\t%s",
1126*7044Smk117520 							    gettext("Yes"));
1127*7044Smk117520 						golden++;
1128*7044Smk117520 					} else {
1129*7044Smk117520 						if (verbose)
1130*7044Smk117520 							(void) printf("\t%s",
1131*7044Smk117520 							    gettext("No"));
1132*7044Smk117520 					}
1133*7044Smk117520 					if (verbose)
1134*7044Smk117520 						(void) printf("\n");
1135*7044Smk117520 						medok++;
1136*7044Smk117520 				}
1137*7044Smk117520 			}
1138*7044Smk117520 		}
1139*7044Smk117520 		if (sname == NULL) {
1140*7044Smk117520 			/*
1141*7044Smk117520 			 * Update the latest mediator information
1142*7044Smk117520 			 * on this node
1143*7044Smk117520 			 */
1144*7044Smk117520 			(void) strlcpy(mdh.a_nm[0], mynode(),
1145*7044Smk117520 			    sizeof (mdh.a_nm[0]));
1146*7044Smk117520 			if (clnt_user_med_upd_data(&mdh, obandiskset,
1147*7044Smk117520 			    setname, setnum, save_medd, ep) == -1) {
1148*7044Smk117520 				/*
1149*7044Smk117520 				 * We had some errors while updaing the
1150*7044Smk117520 				 * record. This means this metaset is
1151*7044Smk117520 				 * not updated with latest mediator
1152*7044Smk117520 				 * information.
1153*7044Smk117520 				 */
1154*7044Smk117520 				mde_perror(ep, "");
1155*7044Smk117520 				continue;
1156*7044Smk117520 			}
1157*7044Smk117520 		} else {
1158*7044Smk117520 			if (golden) {
1159*7044Smk117520 				retval = 0;
1160*7044Smk117520 				goto out;
1161*7044Smk117520 			}
1162*7044Smk117520 			if (medok < ((medrecp->med_rec_meds.n_cnt / 2) + 1))
1163*7044Smk117520 				retval = 1;
1164*7044Smk117520 		}
1165*7044Smk117520 	}
1166*7044Smk117520 
1167*7044Smk117520 out:
1168*7044Smk117520 	if (rec_buf != NULL)
1169*7044Smk117520 		Free(rec_buf);
1170*7044Smk117520 	if (close(fd) < 0) {
1171*7044Smk117520 		mde_perror(ep, "Error in closing meddb file");
1172*7044Smk117520 		return (1);
1173*7044Smk117520 	}
1174*7044Smk117520 	return (retval);
1175*7044Smk117520 }
1176