xref: /onnv-gate/usr/src/lib/lvm/libmeta/common/meta_set_prv.c (revision 6163:54cfe5c54ea1)
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
51487Sachimm  * Common Development and Distribution License (the "License").
61487Sachimm  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*6163Sachimm  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * Metadevice diskset interfaces
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate 
320Sstevel@tonic-gate #include "meta_set_prv.h"
330Sstevel@tonic-gate #include <meta.h>
340Sstevel@tonic-gate #include <sys/lvm/md_mddb.h>
350Sstevel@tonic-gate #include <sys/cladm.h>
360Sstevel@tonic-gate #include <devid.h>
370Sstevel@tonic-gate #include <sys/lvm/md_convert.h>
382061Sjeanm #include <sdssc.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate /*
410Sstevel@tonic-gate  * Exported Entry Points
420Sstevel@tonic-gate  */
430Sstevel@tonic-gate 
440Sstevel@tonic-gate int
checkdrive_onnode(mdsetname_t * sp,mddrivename_t * dnp,char * node,md_error_t * ep)450Sstevel@tonic-gate checkdrive_onnode(
460Sstevel@tonic-gate 	mdsetname_t	*sp,
470Sstevel@tonic-gate 	mddrivename_t	*dnp,
480Sstevel@tonic-gate 	char		*node,
490Sstevel@tonic-gate 	md_error_t	*ep)
500Sstevel@tonic-gate {
510Sstevel@tonic-gate 	time_t			mystamp, otherstamp;
520Sstevel@tonic-gate 	md_dev64_t		otherdev;
530Sstevel@tonic-gate 	mdname_t		*np, *remote_np;
540Sstevel@tonic-gate 	mddrivename_t		*remote_dnp;
550Sstevel@tonic-gate 	int			release = 0;
560Sstevel@tonic-gate 	md_drive_desc		dd;
570Sstevel@tonic-gate 	int			rval = 0;
580Sstevel@tonic-gate 	int			ret = -1;
590Sstevel@tonic-gate 	mhd_mhiargs_t		mhiargs;
600Sstevel@tonic-gate 	md_set_desc		*sd;
610Sstevel@tonic-gate 	int			is_efi = 0;
620Sstevel@tonic-gate 	int			do_fallback = 0;
630Sstevel@tonic-gate 
640Sstevel@tonic-gate 	(void) memset(&mhiargs, '\0', sizeof (mhiargs));
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
670Sstevel@tonic-gate 		return (-1);
680Sstevel@tonic-gate 
690Sstevel@tonic-gate 	if (meta_is_drive_in_thisset(sp, dnp, FALSE, ep)) {
700Sstevel@tonic-gate 		release = 1;
710Sstevel@tonic-gate 		dd.dd_next = NULL;
720Sstevel@tonic-gate 		dd.dd_dbcnt = 0;
730Sstevel@tonic-gate 		dd.dd_dbsize = 0;
740Sstevel@tonic-gate 		dd.dd_dnp = dnp;
750Sstevel@tonic-gate 		if (clnt_gtimeout(mynode(), sp, &mhiargs, ep) != 0)
760Sstevel@tonic-gate 			return (-1);
770Sstevel@tonic-gate 		if (!(MD_MNSET_DESC(sd)) && !MD_ATSET_DESC(sd)) {
780Sstevel@tonic-gate 			if (rel_own_bydd(sp, &dd, TRUE, ep))
790Sstevel@tonic-gate 				return (-1);
800Sstevel@tonic-gate 		}
810Sstevel@tonic-gate 	}
820Sstevel@tonic-gate 	if ((np = metaslicename(dnp, MD_SLICE0, ep)) == NULL) {
830Sstevel@tonic-gate 		rval = -1;
840Sstevel@tonic-gate 		goto out;
850Sstevel@tonic-gate 	}
860Sstevel@tonic-gate 
870Sstevel@tonic-gate 	/*
880Sstevel@tonic-gate 	 * First try and operate assuming the other side
890Sstevel@tonic-gate 	 * is running a SVM version that supports device id
900Sstevel@tonic-gate 	 * in disksets i.e. is running SVM RPC version 2.
910Sstevel@tonic-gate 	 *
920Sstevel@tonic-gate 	 * If this call fails due to the other side running
930Sstevel@tonic-gate 	 * a SVM version that does not support device id
940Sstevel@tonic-gate 	 * in disksets i.e. is running SVM RPC version 1, we
950Sstevel@tonic-gate 	 * fallback to the old behaviour.
960Sstevel@tonic-gate 	 */
97*6163Sachimm 	if (dnp->devid != NULL) {
980Sstevel@tonic-gate 		char		*rname = NULL;
990Sstevel@tonic-gate 		md_dev64_t	dev = NODEV64;
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 		/*
1020Sstevel@tonic-gate 		 * If the disk is connected to the remote node then the
1030Sstevel@tonic-gate 		 * only thing we can be certain of is that the disk will
1040Sstevel@tonic-gate 		 * have the same devid on that node, it may not have the
1050Sstevel@tonic-gate 		 * same minor number nor the same ctd name. But if it
1060Sstevel@tonic-gate 		 * does have the same ctd name then use it.  In most cases
1070Sstevel@tonic-gate 		 * there will only be a single entry returned but if the
1080Sstevel@tonic-gate 		 * system has multi-path disks with MPXIO turned off there
1090Sstevel@tonic-gate 		 * will be multiple entries. Attempting to choose the same
1100Sstevel@tonic-gate 		 * name will give  the user as consistent a view across the
1110Sstevel@tonic-gate 		 * nodes as possible.
1120Sstevel@tonic-gate 		 */
1130Sstevel@tonic-gate 		ret = clnt_devinfo_by_devid(node, sp, dnp->devid, &dev,
114*6163Sachimm 		    np->rname, &rname, NULL, ep);
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate 		/*
1170Sstevel@tonic-gate 		 * If the return value was ENOTSUP, we know the
1180Sstevel@tonic-gate 		 * other side is not running a SVM version that
1190Sstevel@tonic-gate 		 * supports device id in disksets. We fallback
1200Sstevel@tonic-gate 		 * to the previous behaviour in that case.
1210Sstevel@tonic-gate 		 */
1220Sstevel@tonic-gate 		if (ret == ENOTSUP) {
1230Sstevel@tonic-gate 			do_fallback++;
1240Sstevel@tonic-gate 			goto fallback;
1250Sstevel@tonic-gate 		} else if (ret == -1) {
1260Sstevel@tonic-gate 			rval = -1;
1270Sstevel@tonic-gate 			goto out;
1280Sstevel@tonic-gate 		}
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 		/*
1310Sstevel@tonic-gate 		 * If the device does not exist on the remote node then
1320Sstevel@tonic-gate 		 * the returned dev should indicate this (NODEV64) but
1330Sstevel@tonic-gate 		 * we also check to make sure the returned name is not
1340Sstevel@tonic-gate 		 * empty to make sure that the namespace does not get
1350Sstevel@tonic-gate 		 * created with a NULL/empty entry (should not be possbile
1360Sstevel@tonic-gate 		 * but being paranoid).
1370Sstevel@tonic-gate 		 */
1380Sstevel@tonic-gate 		if (dev == NODEV64 || rname == (char *)NULL ||
1390Sstevel@tonic-gate 		    strcmp(rname, "") == 0) {
1400Sstevel@tonic-gate 			rval = mddserror(ep, MDE_DS_DRIVENOTCOMMON, sp->setno,
141*6163Sachimm 			    node, dnp->cname, sp->setname);
1420Sstevel@tonic-gate 			goto out;
1430Sstevel@tonic-gate 		}
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 		/*
1460Sstevel@tonic-gate 		 * The rname returned from the remote node maybe different
1470Sstevel@tonic-gate 		 * to the rname on this node, therefore we need to build up
1480Sstevel@tonic-gate 		 * a dnp for this new rname.
1490Sstevel@tonic-gate 		 */
1500Sstevel@tonic-gate 		if (strcmp(np->rname, rname) != 0) {
1510Sstevel@tonic-gate 			/* different rname */
1521623Stw21770 			remote_np = metaname_fast(&sp, rname,
1531623Stw21770 			    LOGICAL_DEVICE, ep);
1540Sstevel@tonic-gate 			if (remote_np != NULL) {
1550Sstevel@tonic-gate 				remote_dnp = remote_np->drivenamep;
1560Sstevel@tonic-gate 			}
1570Sstevel@tonic-gate 		} else {
1580Sstevel@tonic-gate 			remote_dnp = dnp;
1590Sstevel@tonic-gate 		}
1600Sstevel@tonic-gate 	} else {
1610Sstevel@tonic-gate 		do_fallback++;
1620Sstevel@tonic-gate 	}
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate fallback:
1650Sstevel@tonic-gate 	if (do_fallback) {
1660Sstevel@tonic-gate 		ret = setdevstamp(dnp, &mystamp, ep);
1670Sstevel@tonic-gate 		/*
1680Sstevel@tonic-gate 		 * Check if the disk in question is an EFI disk.
1690Sstevel@tonic-gate 		 */
1700Sstevel@tonic-gate 		if (ret == ENOTSUP)
1710Sstevel@tonic-gate 			is_efi++;
1720Sstevel@tonic-gate 		else if (ret == -1)
1730Sstevel@tonic-gate 			return (-1);
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 		if ((np = metaslicename(dnp, MD_SLICE0, ep)) == NULL) {
1760Sstevel@tonic-gate 			rval = -1;
1770Sstevel@tonic-gate 			goto out;
1780Sstevel@tonic-gate 		}
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 		if (is_efi) {
1810Sstevel@tonic-gate 			/*
1820Sstevel@tonic-gate 			 * For EFI disks, we compare the device
1830Sstevel@tonic-gate 			 * id for the disks in question.
1840Sstevel@tonic-gate 			 */
1850Sstevel@tonic-gate 			ddi_devid_t	thisdevid, otherdevid;
1860Sstevel@tonic-gate 			char		*encoded_otherdevid = NULL;
1870Sstevel@tonic-gate 			char		*encoded_thisdevid = NULL;
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 			if (clnt_devinfo(node, sp, dnp, &otherdev, NULL, ep)
1900Sstevel@tonic-gate 			    == -1) {
1910Sstevel@tonic-gate 				rval = -1;
1920Sstevel@tonic-gate 				goto out;
1930Sstevel@tonic-gate 			}
1940Sstevel@tonic-gate 			if (np->dev != otherdev) {
1950Sstevel@tonic-gate 				rval = mddserror(ep, MDE_DS_DRIVENOTCOMMON,
1960Sstevel@tonic-gate 				    sp->setno, node, dnp->cname, sp->setname);
1970Sstevel@tonic-gate 				goto out;
1980Sstevel@tonic-gate 			}
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 			if (clnt_devid(node, sp, dnp, &encoded_otherdevid,
2010Sstevel@tonic-gate 			    ep) == -1) {
2020Sstevel@tonic-gate 				rval = -1;
2030Sstevel@tonic-gate 				goto out;
2040Sstevel@tonic-gate 			}
2050Sstevel@tonic-gate 			if (encoded_otherdevid == NULL) {
2060Sstevel@tonic-gate 				rval = -1;
2070Sstevel@tonic-gate 				goto out;
2080Sstevel@tonic-gate 			}
2090Sstevel@tonic-gate 			if (devid_str_decode(encoded_otherdevid, &otherdevid,
2100Sstevel@tonic-gate 			    NULL) == 0) {
2110Sstevel@tonic-gate 				/*
2120Sstevel@tonic-gate 				 * If we are here, it means that dnp->devid
2130Sstevel@tonic-gate 				 * is NULL. This will typically happen if
2140Sstevel@tonic-gate 				 * we are dealing with SunCluster DID devices.
2150Sstevel@tonic-gate 				 *
2160Sstevel@tonic-gate 				 * We want to explicitly get the device id
2170Sstevel@tonic-gate 				 * for such a disk
2180Sstevel@tonic-gate 				 */
2190Sstevel@tonic-gate 				encoded_thisdevid = meta_get_devid(dnp->rname);
2200Sstevel@tonic-gate 				ret = devid_str_decode(encoded_thisdevid,
2210Sstevel@tonic-gate 				    &thisdevid, NULL);
2220Sstevel@tonic-gate 				if (ret == 0) {
2230Sstevel@tonic-gate 					ret = devid_compare(thisdevid,
2240Sstevel@tonic-gate 					    otherdevid);
2250Sstevel@tonic-gate 					devid_free(thisdevid);
2260Sstevel@tonic-gate 				}
2270Sstevel@tonic-gate 				devid_free(otherdevid);
2280Sstevel@tonic-gate 				if (encoded_thisdevid)
2290Sstevel@tonic-gate 					Free(encoded_thisdevid);
2300Sstevel@tonic-gate 			}
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate 			Free(encoded_otherdevid);
2330Sstevel@tonic-gate 			if (ret != 0) {
2340Sstevel@tonic-gate 				rval = mddserror(ep, MDE_DS_DRIVENOTCOMMON,
2350Sstevel@tonic-gate 				    sp->setno, node, dnp->cname, sp->setname);
2360Sstevel@tonic-gate 				goto out;
2370Sstevel@tonic-gate 			}
2380Sstevel@tonic-gate 		} else {
2390Sstevel@tonic-gate 			/*
2400Sstevel@tonic-gate 			 * For VTOC disks, we compare the dev_t and
2410Sstevel@tonic-gate 			 * timestamp for the disks in question.
2420Sstevel@tonic-gate 			 */
2430Sstevel@tonic-gate 			if (clnt_devinfo(node, sp, dnp, &otherdev,
2440Sstevel@tonic-gate 			    &otherstamp, ep) == -1) {
2450Sstevel@tonic-gate 				rval = -1;
2460Sstevel@tonic-gate 				goto out;
2470Sstevel@tonic-gate 			}
2480Sstevel@tonic-gate 			if ((mystamp != otherstamp) || (np->dev != otherdev)) {
2490Sstevel@tonic-gate 				rval = mddserror(ep, MDE_DS_DRIVENOTCOMMON,
2500Sstevel@tonic-gate 				    sp->setno, node, dnp->cname, sp->setname);
2510Sstevel@tonic-gate 				goto out;
2520Sstevel@tonic-gate 			}
2530Sstevel@tonic-gate 		}
2540Sstevel@tonic-gate 		remote_dnp = dnp;
2550Sstevel@tonic-gate 	}
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 	if (clnt_drvused(node, sp, remote_dnp, ep) == -1)
2580Sstevel@tonic-gate 		rval = -1;
2590Sstevel@tonic-gate 
2600Sstevel@tonic-gate out:
2610Sstevel@tonic-gate 	if (release)
2620Sstevel@tonic-gate 		if (!(MD_MNSET_DESC(sd)) && !MD_ATSET_DESC(sd)) {
2630Sstevel@tonic-gate 			if (tk_own_bydd(sp, &dd, &mhiargs, TRUE, ep))
2640Sstevel@tonic-gate 				rval = -1;
2650Sstevel@tonic-gate 		}
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate 	return (rval);
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate side_t
getnodeside(char * node,md_set_desc * sd)2710Sstevel@tonic-gate getnodeside(char *node, md_set_desc *sd)
2720Sstevel@tonic-gate {
2730Sstevel@tonic-gate 	side_t			sideno;
2740Sstevel@tonic-gate 	int			nid;
2750Sstevel@tonic-gate 	md_mnnode_desc		*nd;
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd)) {
2780Sstevel@tonic-gate 		nd = sd->sd_nodelist;
2790Sstevel@tonic-gate 		while (nd) {
2800Sstevel@tonic-gate 			if (strcmp(nd->nd_nodename, node) == 0) {
2810Sstevel@tonic-gate 				return (nd->nd_nodeid);
2820Sstevel@tonic-gate 			}
2830Sstevel@tonic-gate 			nd = nd->nd_next;
2840Sstevel@tonic-gate 		}
2850Sstevel@tonic-gate 		return (MD_SIDEWILD);
2860Sstevel@tonic-gate 	}
2870Sstevel@tonic-gate 
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate 	/* If regular diskset */
2900Sstevel@tonic-gate 	for (sideno = 0; sideno < MD_MAXSIDES; sideno++) {
2910Sstevel@tonic-gate 		if (sd->sd_nodes[sideno] == NULL ||
2920Sstevel@tonic-gate 		    sd->sd_nodes[sideno][0] == '\0')
2930Sstevel@tonic-gate 			continue;
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 		if (strcmp(sd->sd_nodes[sideno], node) == 0) {
2960Sstevel@tonic-gate 			return (sideno);
2970Sstevel@tonic-gate 		}
2980Sstevel@tonic-gate 	}
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate 	/*
3010Sstevel@tonic-gate 	 * If the first loop fails we may be in a situation where this host
3020Sstevel@tonic-gate 	 * is configured as part of a cluster yet not running in the cluster
3030Sstevel@tonic-gate 	 * mode. If so, the names stored in sd->sd_nodes[] are going to be
3040Sstevel@tonic-gate 	 * nodeid's instead of hostnames. See if we can find a match that way.
3050Sstevel@tonic-gate 	 */
3060Sstevel@tonic-gate 	if (_cladm(CL_CONFIG, CL_NODEID, &nid) == 0) {
3070Sstevel@tonic-gate 		for (sideno = 0; sideno < MD_MAXSIDES; sideno++) {
3080Sstevel@tonic-gate 			if (sd->sd_nodes[sideno] == NULL ||
3090Sstevel@tonic-gate 			    sd->sd_nodes[sideno][0] == '\0')
3100Sstevel@tonic-gate 				continue;
3110Sstevel@tonic-gate 			if (atoi(sd->sd_nodes[sideno]) == nid)
3120Sstevel@tonic-gate 				return (sideno);
3130Sstevel@tonic-gate 		}
3140Sstevel@tonic-gate 	}
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 	return (MD_SIDEWILD);
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate int
halt_set(mdsetname_t * sp,md_error_t * ep)3200Sstevel@tonic-gate halt_set(mdsetname_t *sp, md_error_t *ep)
3210Sstevel@tonic-gate {
3220Sstevel@tonic-gate 	mddb_config_t	c;
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 	(void) memset(&c, 0, sizeof (c));
3250Sstevel@tonic-gate 	c.c_setno = sp->setno;
3260Sstevel@tonic-gate 	if ((c.c_sideno = getmyside(sp, ep)) == MD_SIDEWILD)
3270Sstevel@tonic-gate 		return (-1);
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate 	if (s_ownset(sp->setno, ep) == MD_SETOWNER_YES) {
3300Sstevel@tonic-gate 		/* Don't need device id information from this ioctl */
3310Sstevel@tonic-gate 		c.c_locator.l_devid = (uint64_t)0;
3320Sstevel@tonic-gate 		c.c_locator.l_devid_flags = 0;
3330Sstevel@tonic-gate 		/* Kill any resyncs that are running on mirrors in this set */
3340Sstevel@tonic-gate 		meta_mirror_resync_kill(sp);
3350Sstevel@tonic-gate 		if (metaioctl(MD_RELEASE_SET, &c, &c.c_mde, NULL) != 0)
3360Sstevel@tonic-gate 			return (mdstealerror(ep, &c.c_mde));
3370Sstevel@tonic-gate 	}
3380Sstevel@tonic-gate 
3390Sstevel@tonic-gate 	return (0);
3400Sstevel@tonic-gate }
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate md_drive_desc *
metadrivedesc_append(md_drive_desc ** dd,mddrivename_t * dnp,int dbcnt,int dbsize,md_timeval32_t timestamp,ulong_t genid,uint_t flags)3430Sstevel@tonic-gate metadrivedesc_append(
3440Sstevel@tonic-gate 	md_drive_desc	**dd,
3450Sstevel@tonic-gate 	mddrivename_t	*dnp,
3460Sstevel@tonic-gate 	int		dbcnt,
3470Sstevel@tonic-gate 	int		dbsize,
3480Sstevel@tonic-gate 	md_timeval32_t	timestamp,
3490Sstevel@tonic-gate 	ulong_t		genid,
3500Sstevel@tonic-gate 	uint_t		flags
3510Sstevel@tonic-gate )
3520Sstevel@tonic-gate {
3530Sstevel@tonic-gate 	md_drive_desc	*p;
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate 	/* run to end of list */
3560Sstevel@tonic-gate 	for (/* void */; (*dd != NULL); dd = &(*dd)->dd_next)
3570Sstevel@tonic-gate 		/* void */;
3580Sstevel@tonic-gate 
3590Sstevel@tonic-gate 	/* allocate new list element */
3600Sstevel@tonic-gate 	p = *dd = Zalloc(sizeof (*p));
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 	p->dd_dnp = dnp;
3630Sstevel@tonic-gate 	p->dd_dbcnt = dbcnt;
3640Sstevel@tonic-gate 	p->dd_dbsize = dbsize;
3650Sstevel@tonic-gate 	p->dd_ctime = timestamp;
3660Sstevel@tonic-gate 	p->dd_genid = genid;
3670Sstevel@tonic-gate 	p->dd_flags = flags;
3680Sstevel@tonic-gate 	return (p);
3690Sstevel@tonic-gate }
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate int
nodehasset(mdsetname_t * sp,char * node,uint_t match_flag,md_error_t * ep)3720Sstevel@tonic-gate nodehasset(
3730Sstevel@tonic-gate 	mdsetname_t	*sp,
3740Sstevel@tonic-gate 	char		*node,
3750Sstevel@tonic-gate 	uint_t		match_flag,
3760Sstevel@tonic-gate 	md_error_t	*ep
3770Sstevel@tonic-gate )
3780Sstevel@tonic-gate {
3790Sstevel@tonic-gate 	md_set_desc	*sd;
3800Sstevel@tonic-gate 	md_set_record	*sr;
3810Sstevel@tonic-gate 	int		rval = 0;
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
3840Sstevel@tonic-gate 		return (-1);
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate 	/* Don't care if set record is MN or not */
3870Sstevel@tonic-gate 	if (clnt_getset(node, sp->setname, MD_SET_BAD, &sr, ep))
3880Sstevel@tonic-gate 		return (-1);
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 	if (sr == NULL) {
3910Sstevel@tonic-gate 		if (! mdisok(ep))
3920Sstevel@tonic-gate 			return (-1);
3930Sstevel@tonic-gate 		return (0);
3940Sstevel@tonic-gate 	}
3950Sstevel@tonic-gate 
3960Sstevel@tonic-gate 	/* Looking for name only match */
3970Sstevel@tonic-gate 	if ((match_flag & NHS_N_EQ) == NHS_N_EQ) {
3980Sstevel@tonic-gate 		rval = 1;
3990Sstevel@tonic-gate 		goto out;
4000Sstevel@tonic-gate 	}
4010Sstevel@tonic-gate 
4020Sstevel@tonic-gate 	if (sd->sd_setno != sr->sr_setno)
4030Sstevel@tonic-gate 		goto out;
4040Sstevel@tonic-gate 
4050Sstevel@tonic-gate 	/* Looking for name and setno match */
4060Sstevel@tonic-gate 	if ((match_flag & NHS_NS_EQ) == NHS_NS_EQ) {
4070Sstevel@tonic-gate 		rval = 1;
4080Sstevel@tonic-gate 		goto out;
4090Sstevel@tonic-gate 	}
4100Sstevel@tonic-gate 
4110Sstevel@tonic-gate 	if (sd->sd_ctime.tv_sec != sr->sr_ctime.tv_sec ||
4120Sstevel@tonic-gate 	    sd->sd_ctime.tv_usec != sr->sr_ctime.tv_usec)
4130Sstevel@tonic-gate 		goto out;
4140Sstevel@tonic-gate 
4150Sstevel@tonic-gate 	/* Looking for name, setno, and timestamp match */
4160Sstevel@tonic-gate 	if ((match_flag & NHS_NST_EQ) == NHS_NST_EQ) {
4170Sstevel@tonic-gate 		rval = 1;
4180Sstevel@tonic-gate 		goto out;
4190Sstevel@tonic-gate 	}
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate 	if (sd->sd_genid != sr->sr_genid) {
4220Sstevel@tonic-gate 		if (sd->sd_genid < sr->sr_genid) {
4230Sstevel@tonic-gate 			/*
4240Sstevel@tonic-gate 			 * Looking for name, setno, timestamp, and genid on
4250Sstevel@tonic-gate 			 * other host is GT than other host.
4260Sstevel@tonic-gate 			 */
4270Sstevel@tonic-gate 			if ((match_flag & NHS_NST_EQ_G_GT) == NHS_NST_EQ_G_GT) {
4280Sstevel@tonic-gate 				rval = 1;
4290Sstevel@tonic-gate 				goto out;
4300Sstevel@tonic-gate 			}
4310Sstevel@tonic-gate 		}
4320Sstevel@tonic-gate 		goto out;
4330Sstevel@tonic-gate 	}
4340Sstevel@tonic-gate 
4350Sstevel@tonic-gate 	/* Looking for name, setno, timestamp, and genid match */
4360Sstevel@tonic-gate 	if ((match_flag & NHS_NSTG_EQ) == NHS_NSTG_EQ)
4370Sstevel@tonic-gate 		rval = 1;
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate out:
4400Sstevel@tonic-gate 	/*
4410Sstevel@tonic-gate 	 * Set record structure was allocated from RPC routine getset
4420Sstevel@tonic-gate 	 * so this structure is only of size md_set_record even if
4430Sstevel@tonic-gate 	 * the MN flag is set.  So, clear the flag so that the free
4440Sstevel@tonic-gate 	 * code doesn't attempt to free a structure the size of
4450Sstevel@tonic-gate 	 * md_mnset_record.
4460Sstevel@tonic-gate 	 */
4470Sstevel@tonic-gate 	sr->sr_flags &= ~MD_SR_MN;
4480Sstevel@tonic-gate 	free_sr(sr);
4490Sstevel@tonic-gate 
4500Sstevel@tonic-gate 	return (rval);
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate int
nodesuniq(mdsetname_t * sp,int cnt,char ** strings,md_error_t * ep)4540Sstevel@tonic-gate nodesuniq(mdsetname_t *sp, int cnt, char **strings, md_error_t *ep)
4550Sstevel@tonic-gate {
4560Sstevel@tonic-gate 	int i, j;
4570Sstevel@tonic-gate 	for (i = 0; i < cnt; i++)
4580Sstevel@tonic-gate 		for (j = i + 1; j < cnt; j++)
4590Sstevel@tonic-gate 			if (strcmp(strings[i], strings[j]) == 0)
4600Sstevel@tonic-gate 				return (mddserror(ep, MDE_DS_DUPHOST,
4610Sstevel@tonic-gate 				    sp->setno, strings[i], NULL, sp->setname));
4620Sstevel@tonic-gate 	return (0);
4630Sstevel@tonic-gate }
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate int
own_set(mdsetname_t * sp,char ** owner_of_set,int forceflg,md_error_t * ep)4660Sstevel@tonic-gate own_set(mdsetname_t *sp, char **owner_of_set, int forceflg, md_error_t *ep)
4670Sstevel@tonic-gate {
4680Sstevel@tonic-gate 	md_set_desc		*sd;
4690Sstevel@tonic-gate 	int			am_i_owner;
4700Sstevel@tonic-gate 	int			i;
4710Sstevel@tonic-gate 
4720Sstevel@tonic-gate 	if (metaislocalset(sp)) {
4730Sstevel@tonic-gate 		if (owner_of_set != NULL)
4740Sstevel@tonic-gate 			*owner_of_set = Strdup(mynode());
4750Sstevel@tonic-gate 		return (MD_SETOWNER_YES);
4760Sstevel@tonic-gate 	}
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
4790Sstevel@tonic-gate 		return (-1);
4800Sstevel@tonic-gate 
4810Sstevel@tonic-gate 	if (clnt_ownset(mynode(), sp, &am_i_owner, ep) == -1)
4820Sstevel@tonic-gate 		return (-1);
4830Sstevel@tonic-gate 
4840Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd)) {
4850Sstevel@tonic-gate 		if (am_i_owner == TRUE)
4860Sstevel@tonic-gate 			return (MD_SETOWNER_YES);
4870Sstevel@tonic-gate 		else
4880Sstevel@tonic-gate 			return (MD_SETOWNER_NO);
4890Sstevel@tonic-gate 	}
4900Sstevel@tonic-gate 
4910Sstevel@tonic-gate 	if (forceflg == TRUE) {
4920Sstevel@tonic-gate 		if (am_i_owner == TRUE) {
4930Sstevel@tonic-gate 			if (owner_of_set != NULL)
4940Sstevel@tonic-gate 				*owner_of_set = Strdup(mynode());
4950Sstevel@tonic-gate 			return (MD_SETOWNER_YES);
4960Sstevel@tonic-gate 		}
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate 		if (owner_of_set != NULL)
4990Sstevel@tonic-gate 			*owner_of_set = NULL;
5000Sstevel@tonic-gate 		return (MD_SETOWNER_NONE);
5010Sstevel@tonic-gate 	}
5020Sstevel@tonic-gate 
5030Sstevel@tonic-gate 	if (am_i_owner == TRUE) {
5040Sstevel@tonic-gate 		if (owner_of_set != NULL)
5050Sstevel@tonic-gate 			*owner_of_set = Strdup(mynode());
5060Sstevel@tonic-gate 		return (MD_SETOWNER_YES);
5070Sstevel@tonic-gate 	}
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate 
5100Sstevel@tonic-gate 	for (i = 0; i < MD_MAXSIDES; i++) {
5110Sstevel@tonic-gate 		/*
5120Sstevel@tonic-gate 		 * Skip empty slots, and my own slot.
5130Sstevel@tonic-gate 		 */
5140Sstevel@tonic-gate 		if (sd->sd_nodes[i][0] == '\0' ||
5150Sstevel@tonic-gate 		    strcmp(sd->sd_nodes[i], mynode()) == 0)
5160Sstevel@tonic-gate 			continue;
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate 		if (clnt_ownset(sd->sd_nodes[i], sp, &am_i_owner, ep) == -1)
5190Sstevel@tonic-gate 			return (-1);
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate 		if (am_i_owner == TRUE) {
5220Sstevel@tonic-gate 			if (owner_of_set != NULL)
5230Sstevel@tonic-gate 				*owner_of_set = Strdup(sd->sd_nodes[i]);
5240Sstevel@tonic-gate 			return (MD_SETOWNER_NO);
5250Sstevel@tonic-gate 		}
5260Sstevel@tonic-gate 	}
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate 	/* We get here, we currently have no owner. */
5290Sstevel@tonic-gate 	if (owner_of_set != NULL)
5300Sstevel@tonic-gate 		*owner_of_set = NULL;
5310Sstevel@tonic-gate 	return (MD_SETOWNER_NONE);
5320Sstevel@tonic-gate }
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate void
resync_genid(mdsetname_t * sp,md_set_desc * sd,ulong_t max_genid,int node_c,char ** node_v)5350Sstevel@tonic-gate resync_genid(
5360Sstevel@tonic-gate 	mdsetname_t		*sp,
5370Sstevel@tonic-gate 	md_set_desc		*sd,
5380Sstevel@tonic-gate 	ulong_t			max_genid,
5390Sstevel@tonic-gate 	int			node_c,
5400Sstevel@tonic-gate 	char			**node_v
5410Sstevel@tonic-gate )
5420Sstevel@tonic-gate {
5430Sstevel@tonic-gate 	int			i, j;
5440Sstevel@tonic-gate 	ulong_t			cur_genid[MD_MAXSIDES];
5450Sstevel@tonic-gate 	md_set_record		*sr;
5460Sstevel@tonic-gate 	md_error_t		xep = mdnullerror;
5470Sstevel@tonic-gate 	md_mnnode_desc		*nd;
5480Sstevel@tonic-gate 	md_mnset_record		*mnsr;
5490Sstevel@tonic-gate 
5500Sstevel@tonic-gate 	if (node_c > 0 && node_v && *node_v) {
5510Sstevel@tonic-gate 		/*
5520Sstevel@tonic-gate 		 * Mark the set record MD_SR_OK.
5530Sstevel@tonic-gate 		 */
5540Sstevel@tonic-gate 		for (i = 0; i < node_c; i++)
5550Sstevel@tonic-gate 			if (clnt_upd_sr_flags(node_v[i], sp, MD_SR_OK, &xep))
5560Sstevel@tonic-gate 				mdclrerror(&xep);
5570Sstevel@tonic-gate 		max_genid++;
5580Sstevel@tonic-gate 	}
5590Sstevel@tonic-gate 
5600Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd)) {
5610Sstevel@tonic-gate 		nd = sd->sd_nodelist;
5620Sstevel@tonic-gate 		while (nd) {
5630Sstevel@tonic-gate 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
5640Sstevel@tonic-gate 				nd = nd->nd_next;
5650Sstevel@tonic-gate 				continue;
5660Sstevel@tonic-gate 			}
5670Sstevel@tonic-gate 			/* Will only return a multi-node diskset record */
5680Sstevel@tonic-gate 			if (clnt_mngetset(nd->nd_nodename, sp->setname,
5690Sstevel@tonic-gate 			    MD_SET_BAD, &mnsr, &xep) == -1) {
5700Sstevel@tonic-gate 				mdclrerror(&xep);
5710Sstevel@tonic-gate 				nd = nd->nd_next;
5720Sstevel@tonic-gate 				continue;
5730Sstevel@tonic-gate 			}
5740Sstevel@tonic-gate 			for (j = mnsr->sr_genid; j < max_genid; j++) {
5750Sstevel@tonic-gate 				if (clnt_upd_sr_flags(nd->nd_nodename, sp,
5760Sstevel@tonic-gate 				    MD_SR_OK, &xep))
5770Sstevel@tonic-gate 					mdclrerror(&xep);
5780Sstevel@tonic-gate 			}
5790Sstevel@tonic-gate 			free_sr((struct md_set_record *)mnsr);
5800Sstevel@tonic-gate 			nd = nd->nd_next;
5810Sstevel@tonic-gate 		}
5820Sstevel@tonic-gate 		return;
5830Sstevel@tonic-gate 	}
5840Sstevel@tonic-gate 
5850Sstevel@tonic-gate 	/*
5860Sstevel@tonic-gate 	 * Get current genid for each node.
5870Sstevel@tonic-gate 	 */
5880Sstevel@tonic-gate 	for (i = 0; i < MD_MAXSIDES; i++) {
5890Sstevel@tonic-gate 		cur_genid[i] = 0;
5900Sstevel@tonic-gate 
5910Sstevel@tonic-gate 		/* Skip empty slots */
5920Sstevel@tonic-gate 		if (sd->sd_nodes[i][0] == '\0')
5930Sstevel@tonic-gate 			continue;
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate 		/* Should be a non-multinode diskset */
5960Sstevel@tonic-gate 		if (clnt_getset(sd->sd_nodes[i], sp->setname,
5970Sstevel@tonic-gate 		    MD_SET_BAD, &sr, &xep) == -1) {
5980Sstevel@tonic-gate 			mdclrerror(&xep);
5990Sstevel@tonic-gate 			continue;
6000Sstevel@tonic-gate 		}
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 		if (MD_MNSET_REC(sr)) {
6030Sstevel@tonic-gate 			/*
6040Sstevel@tonic-gate 			 * Set record structure was allocated from RPC routine
6050Sstevel@tonic-gate 			 * getset so this structure is only of size
6060Sstevel@tonic-gate 			 * md_set_record even if the MN flag is set.  So,
6070Sstevel@tonic-gate 			 * clear the flag so that the free code doesn't
6080Sstevel@tonic-gate 			 * attempt to free a structure the size of
6090Sstevel@tonic-gate 			 * md_mnset_record.
6100Sstevel@tonic-gate 			 */
6110Sstevel@tonic-gate 			sr->sr_flags &= ~MD_SR_MN;
6120Sstevel@tonic-gate 			free_sr(sr);
6130Sstevel@tonic-gate 			continue;
6140Sstevel@tonic-gate 		}
6150Sstevel@tonic-gate 
6160Sstevel@tonic-gate 		cur_genid[i] = sr->sr_genid;
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate 		free_sr(sr);
6190Sstevel@tonic-gate 	}
6200Sstevel@tonic-gate 
6210Sstevel@tonic-gate 	/*
6220Sstevel@tonic-gate 	 * Mark the set record MD_SR_OK
6230Sstevel@tonic-gate 	 */
6240Sstevel@tonic-gate 	for (i = 0; i < MD_MAXSIDES; i++) {
6250Sstevel@tonic-gate 		/* Skip empty slots */
6260Sstevel@tonic-gate 		if (sd->sd_nodes[i][0] == '\0')
6270Sstevel@tonic-gate 			continue;
6280Sstevel@tonic-gate 
6290Sstevel@tonic-gate 		for (j = cur_genid[i]; j < max_genid; j++)
6300Sstevel@tonic-gate 			if (clnt_upd_sr_flags(sd->sd_nodes[i], sp, MD_SR_OK,
6310Sstevel@tonic-gate 			    &xep))
6320Sstevel@tonic-gate 				mdclrerror(&xep);
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate 	}
6350Sstevel@tonic-gate }
6360Sstevel@tonic-gate 
6370Sstevel@tonic-gate int
setup_db_bydd(mdsetname_t * sp,md_drive_desc * dd,int force,md_error_t * ep)6380Sstevel@tonic-gate setup_db_bydd(mdsetname_t *sp, md_drive_desc *dd, int force, md_error_t *ep)
6390Sstevel@tonic-gate {
6400Sstevel@tonic-gate 	md_drive_desc		*p;
6410Sstevel@tonic-gate 	struct mddb_config	c;
6420Sstevel@tonic-gate 	int			i;
6430Sstevel@tonic-gate 	md_set_desc		*sd;
6440Sstevel@tonic-gate 	int			use_devid = 1;
6451945Sjeanm 	ddi_devid_t		devidp, new_devidp;
6460Sstevel@tonic-gate 	char			*minor_name = NULL;
6470Sstevel@tonic-gate 	size_t			sz;
6480Sstevel@tonic-gate 	char			*devid_str = NULL;
6492061Sjeanm 	sdssc_version_t		version;
6501945Sjeanm 	int			need_to_free_devidp = 0;
6510Sstevel@tonic-gate 
6520Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
6530Sstevel@tonic-gate 		return (-1);
6540Sstevel@tonic-gate 	(void) memset(&c, 0, sizeof (c));
6550Sstevel@tonic-gate 
6560Sstevel@tonic-gate 	c.c_setno = sp->setno;
6570Sstevel@tonic-gate 	(void) strcpy(c.c_setname, sp->setname);
6580Sstevel@tonic-gate 	if ((c.c_sideno = getmyside(sp, ep)) == MD_SIDEWILD)
6590Sstevel@tonic-gate 		return (-1);
6600Sstevel@tonic-gate 
6610Sstevel@tonic-gate 	c.c_timestamp = sd->sd_ctime;
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 	if (setup_med_cfg(sp, &c, force, ep))
6640Sstevel@tonic-gate 		return (-1);
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate 	for (p = dd; p != NULL; p = p->dd_next) {
6670Sstevel@tonic-gate 		mddrivename_t	*dnp;
6680Sstevel@tonic-gate 		mdname_t	*np;
6690Sstevel@tonic-gate 		mdcinfo_t	*cinfo;
6700Sstevel@tonic-gate 		mdsidenames_t	*sn = NULL;
6710Sstevel@tonic-gate 
6720Sstevel@tonic-gate 		if (p->dd_dbcnt == 0)
6730Sstevel@tonic-gate 			continue;
6740Sstevel@tonic-gate 
6750Sstevel@tonic-gate 		dnp = p->dd_dnp;
6760Sstevel@tonic-gate 
6770Sstevel@tonic-gate 		assert(dnp != NULL);
6780Sstevel@tonic-gate 
6790Sstevel@tonic-gate 		for (sn = dnp->side_names; sn != NULL; sn = sn->next) {
6800Sstevel@tonic-gate 			if (sn->sideno == c.c_sideno)
6810Sstevel@tonic-gate 				break;
6820Sstevel@tonic-gate 		}
6830Sstevel@tonic-gate 
6840Sstevel@tonic-gate 		/*
6850Sstevel@tonic-gate 		 * The disk has no side name information
6860Sstevel@tonic-gate 		 */
6870Sstevel@tonic-gate 		if (sn == NULL) {
6880Sstevel@tonic-gate 			uint_t	rep_slice;
6890Sstevel@tonic-gate 
6900Sstevel@tonic-gate 			if ((meta_replicaslice(dnp, &rep_slice, ep) != 0) ||
6910Sstevel@tonic-gate 			    ((np = metaslicename(dnp, rep_slice, ep))
692*6163Sachimm 			    == NULL)) {
6930Sstevel@tonic-gate 				mdclrerror(ep);
6940Sstevel@tonic-gate 				continue;
6950Sstevel@tonic-gate 			}
6960Sstevel@tonic-gate 
6970Sstevel@tonic-gate 			if (np->dev == NODEV64)
6980Sstevel@tonic-gate 				continue;
6990Sstevel@tonic-gate 
7000Sstevel@tonic-gate 			c.c_locator.l_dev = meta_cmpldev(np->dev);
7010Sstevel@tonic-gate 			c.c_locator.l_mnum = meta_getminor(np->dev);
7020Sstevel@tonic-gate 
7030Sstevel@tonic-gate 			if (!MD_MNSET_DESC(sd)) {
7040Sstevel@tonic-gate 				/*
7050Sstevel@tonic-gate 				 * minor_name will be NULL if dnp->devid == NULL
7060Sstevel@tonic-gate 				 * - see metagetvtoc()
7070Sstevel@tonic-gate 				 */
7080Sstevel@tonic-gate 				if (np->minor_name != NULL) {
7090Sstevel@tonic-gate 					minor_name = Strdup(np->minor_name);
7100Sstevel@tonic-gate 				}
7110Sstevel@tonic-gate 			}
7120Sstevel@tonic-gate 
7130Sstevel@tonic-gate 			if ((cinfo = metagetcinfo(np, ep)) == NULL) {
7140Sstevel@tonic-gate 				mdclrerror(ep);
7150Sstevel@tonic-gate 				continue;
7160Sstevel@tonic-gate 			}
7170Sstevel@tonic-gate 
7180Sstevel@tonic-gate 			(void) strncpy(c.c_locator.l_driver, cinfo->dname,
7190Sstevel@tonic-gate 			    sizeof (c.c_locator.l_driver));
7200Sstevel@tonic-gate 		} else {
7210Sstevel@tonic-gate 			c.c_locator.l_dev = NODEV32;
7220Sstevel@tonic-gate 			c.c_locator.l_mnum = sn->mnum;
7230Sstevel@tonic-gate 			(void) strncpy(c.c_locator.l_driver, sn->dname,
7240Sstevel@tonic-gate 			    sizeof (c.c_locator.l_driver));
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 			if (!MD_MNSET_DESC(sd)) {
7270Sstevel@tonic-gate 				if (dnp->devid != NULL) {
7280Sstevel@tonic-gate 					minor_name = meta_getdidminorbykey(
7290Sstevel@tonic-gate 					    MD_LOCAL_SET, sn->sideno + SKEW,
7300Sstevel@tonic-gate 					    dnp->side_names_key, ep);
7310Sstevel@tonic-gate 				}
7320Sstevel@tonic-gate 			}
7330Sstevel@tonic-gate 		}
7340Sstevel@tonic-gate 
7352061Sjeanm 		/*
7362061Sjeanm 		 * If the device does not have a devid or is a multinode
7372061Sjeanm 		 * diskset or we are in a SunCluster 3.x enviroment then
7382061Sjeanm 		 * do not use devids.
7392061Sjeanm 		 */
7402061Sjeanm 		if ((dnp->devid == NULL) || MD_MNSET_DESC(sd) ||
7412061Sjeanm 		    ((sdssc_version(&version) == SDSSC_OKAY) &&
7422061Sjeanm 		    (version.major >= 3))) {
7430Sstevel@tonic-gate 			use_devid = 0;
7440Sstevel@tonic-gate 		}
7450Sstevel@tonic-gate 
7460Sstevel@tonic-gate 		if (use_devid) {
7470Sstevel@tonic-gate 			/*
7480Sstevel@tonic-gate 			 * The devid associated with the dnp does not have
7490Sstevel@tonic-gate 			 * a minor name and so we must add it in.
7500Sstevel@tonic-gate 			 */
7510Sstevel@tonic-gate 			size_t	len = strlen(dnp->devid) +
7520Sstevel@tonic-gate 			    strlen(minor_name) + 2;
7530Sstevel@tonic-gate 			devid_str = (char *)Malloc(len);
7540Sstevel@tonic-gate 			(void) snprintf(devid_str, len, "%s/%s", dnp->devid,
7550Sstevel@tonic-gate 			    minor_name);
7560Sstevel@tonic-gate 			(void) devid_str_decode(devid_str, &devidp, NULL);
7571945Sjeanm 			need_to_free_devidp = 1;
7580Sstevel@tonic-gate 
7591945Sjeanm 			/* If need to fix LB then setup old_devid info */
7601945Sjeanm 			if (p->dd_flags & MD_DR_FIX_LB_NM_DID) {
7611945Sjeanm 				sz = devid_sizeof(devidp);
7621945Sjeanm 				c.c_locator.l_old_devid_sz = sz;
7631945Sjeanm 				c.c_locator.l_old_devid = (uintptr_t)malloc(sz);
7641945Sjeanm 				(void) memcpy((void *)(uintptr_t)
7651945Sjeanm 				    c.c_locator.l_old_devid,
7661945Sjeanm 				    devidp, sz);
7671945Sjeanm 
7681945Sjeanm 				new_devidp = replicated_list_lookup(
7691945Sjeanm 				    devid_sizeof((ddi_devid_t)devidp),
7701945Sjeanm 				    (void *)(uintptr_t)devidp);
7711945Sjeanm 				devid_free(devidp);
7721945Sjeanm 				need_to_free_devidp = 0;
7731945Sjeanm 				devidp = new_devidp;
7741945Sjeanm 
7751945Sjeanm 			}
7760Sstevel@tonic-gate 			sz = devid_sizeof(devidp);
7770Sstevel@tonic-gate 			c.c_locator.l_devid = (uintptr_t)malloc(sz);
7780Sstevel@tonic-gate 			c.c_locator.l_devid_sz = sz;
7791945Sjeanm 			(void) memcpy((void *)(uintptr_t)
7801945Sjeanm 			    c.c_locator.l_devid,
78162Sjeanm 			    devidp, sz);
7821945Sjeanm 			if (need_to_free_devidp) {
7831945Sjeanm 				devid_free(devidp);
7841945Sjeanm 				need_to_free_devidp = 0;
7851945Sjeanm 			}
7860Sstevel@tonic-gate 			if (minor_name == NULL) {
7870Sstevel@tonic-gate 				/* ERROR fix up */
7880Sstevel@tonic-gate 				Free(devid_str);
7891945Sjeanm 				Free((void *)(uintptr_t)c.c_locator.l_devid);
7901945Sjeanm 				if (c.c_locator.l_old_devid_sz) {
7911945Sjeanm 					Free((void *)
7921945Sjeanm 					    (uintptr_t)c.c_locator.l_old_devid);
7931945Sjeanm 					c.c_locator.l_old_devid_sz = 0;
7941945Sjeanm 					c.c_locator.l_old_devid =
795*6163Sachimm 					    (uintptr_t)NULL;
7961945Sjeanm 				}
7970Sstevel@tonic-gate 				return (-1);
7980Sstevel@tonic-gate 			}
7991945Sjeanm 			(void) strcpy(c.c_locator.l_minor_name,
8001945Sjeanm 			    minor_name);
8010Sstevel@tonic-gate 			c.c_locator.l_devid_flags = MDDB_DEVID_VALID |
8020Sstevel@tonic-gate 			    MDDB_DEVID_SPACE | MDDB_DEVID_SZ;
8030Sstevel@tonic-gate 		} else {
8040Sstevel@tonic-gate 			/*
8050Sstevel@tonic-gate 			 * Don't need device id information from
8060Sstevel@tonic-gate 			 * this ioctl
8070Sstevel@tonic-gate 			 */
8080Sstevel@tonic-gate 			c.c_locator.l_devid = (uint64_t)0;
8090Sstevel@tonic-gate 			c.c_locator.l_devid_flags = 0;
8100Sstevel@tonic-gate 		}
8110Sstevel@tonic-gate 
8120Sstevel@tonic-gate 
8130Sstevel@tonic-gate 		for (i = 0; i < p->dd_dbcnt; i++) {
8140Sstevel@tonic-gate 			c.c_locator.l_flags = 0;
8150Sstevel@tonic-gate 			c.c_locator.l_blkno = 16 + i * p->dd_dbsize;
8160Sstevel@tonic-gate 
8170Sstevel@tonic-gate 			if (metaioctl(MD_DB_USEDEV, &c, &c.c_mde, NULL) != 0) {
8180Sstevel@tonic-gate 				if (use_devid) {
8190Sstevel@tonic-gate 					Free(devid_str);
8201945Sjeanm 					Free((void *)
8211945Sjeanm 					    (uintptr_t)c.c_locator.l_devid);
8221945Sjeanm 					if (c.c_locator.l_old_devid_sz) {
8231945Sjeanm 						Free((void *)(uintptr_t)
8241945Sjeanm 						    c.c_locator.l_old_devid);
8251945Sjeanm 						c.c_locator.l_old_devid_sz = 0;
8261945Sjeanm 						c.c_locator.l_old_devid =
8271945Sjeanm 						    (uintptr_t)NULL;
8281945Sjeanm 					}
8290Sstevel@tonic-gate 				}
8300Sstevel@tonic-gate 				Free(minor_name);
8310Sstevel@tonic-gate 				return (mdstealerror(ep, &c.c_mde));
8320Sstevel@tonic-gate 			}
8330Sstevel@tonic-gate 		}
8340Sstevel@tonic-gate 		if (use_devid) {
8350Sstevel@tonic-gate 			Free(devid_str);
8361945Sjeanm 			Free((void *)(uintptr_t)c.c_locator.l_devid);
8371945Sjeanm 			if (c.c_locator.l_old_devid_sz) {
8381945Sjeanm 				Free((void *)
8391945Sjeanm 				    (uintptr_t)c.c_locator.l_old_devid);
8401945Sjeanm 				c.c_locator.l_old_devid_sz = 0;
8411945Sjeanm 				c.c_locator.l_old_devid = (uintptr_t)NULL;
8421945Sjeanm 			}
8430Sstevel@tonic-gate 		}
8440Sstevel@tonic-gate 		Free(minor_name);
8450Sstevel@tonic-gate 	}
8460Sstevel@tonic-gate 
8470Sstevel@tonic-gate 	/* return success */
8480Sstevel@tonic-gate 	return (0);
8490Sstevel@tonic-gate }
8500Sstevel@tonic-gate 
8510Sstevel@tonic-gate int
snarf_set(mdsetname_t * sp,bool_t stale_bool,md_error_t * ep)8520Sstevel@tonic-gate snarf_set(mdsetname_t *sp, bool_t stale_bool, md_error_t *ep)
8530Sstevel@tonic-gate {
8540Sstevel@tonic-gate 	mddb_config_t	c;
8550Sstevel@tonic-gate 
8560Sstevel@tonic-gate 	(void) memset(&c, '\0', sizeof (c));
8570Sstevel@tonic-gate 
8580Sstevel@tonic-gate 	c.c_setno = sp->setno;
8590Sstevel@tonic-gate 	if ((c.c_sideno = getmyside(sp, ep)) == MD_SIDEWILD)
8600Sstevel@tonic-gate 		return (-1);
8610Sstevel@tonic-gate 
8620Sstevel@tonic-gate 	/* Don't need device id information from this ioctl */
8630Sstevel@tonic-gate 	c.c_locator.l_devid = (uint64_t)0;
8640Sstevel@tonic-gate 	c.c_locator.l_devid_flags = 0;
8650Sstevel@tonic-gate 	if (stale_bool == TRUE) {
8660Sstevel@tonic-gate 		c.c_flags = MDDB_C_STALE;
8670Sstevel@tonic-gate 	}
8680Sstevel@tonic-gate 	if (metaioctl(MD_GRAB_SET, &c, &c.c_mde, NULL) != 0)
8690Sstevel@tonic-gate 		return (mdstealerror(ep, &c.c_mde));
8700Sstevel@tonic-gate 
8710Sstevel@tonic-gate 	if (c.c_flags & MDDB_C_STALE)
87262Sjeanm 		return (mdmddberror(ep, MDE_DB_STALE, (minor_t)NODEV64,
87362Sjeanm 		    sp->setno, 0, NULL));
8740Sstevel@tonic-gate 
8750Sstevel@tonic-gate 	return (0);
8760Sstevel@tonic-gate }
877