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