xref: /titanic_41/usr/src/cmd/lvm/rpc.metad/metad_svc_subr.c (revision 80148899834a4078a2bd348504aa2d6de9752837)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
543b3654dSrd117015  * Common Development and Distribution License (the "License").
643b3654dSrd117015  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*80148899SSurya Prakki  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include "metad_local.h"
277c478bd9Sstevel@tonic-gate #include <metad.h>
287c478bd9Sstevel@tonic-gate #include <sys/lvm/md_mddb.h>
297c478bd9Sstevel@tonic-gate #include <sdssc.h>
307c478bd9Sstevel@tonic-gate #include <sys/lvm/md_mirror.h>
317c478bd9Sstevel@tonic-gate #include <syslog.h>
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <sys/sysevent/eventdefs.h>
347c478bd9Sstevel@tonic-gate #include <sys/sysevent/svm.h>
357c478bd9Sstevel@tonic-gate #include <thread.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #define	MDDOORS		"/usr/lib/lvm/mddoors"
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate /*
407c478bd9Sstevel@tonic-gate  * rpc.metad daemon
417c478bd9Sstevel@tonic-gate  *
427c478bd9Sstevel@tonic-gate  * The rpc.metad deamon supports two versions of the svm rpc calls - version 1
437c478bd9Sstevel@tonic-gate  * and version 2. The over-the-wire structures sent as part of these rpc calls
447c478bd9Sstevel@tonic-gate  * are also versioned - version 1 and version 2 exist. It must be noted that
457c478bd9Sstevel@tonic-gate  * the version 2 structures have sub-versions or revisions as well. The
467c478bd9Sstevel@tonic-gate  * revisions in the version 2 structures allow for flexiblility in changing
477c478bd9Sstevel@tonic-gate  * over the wire structures without creating a new version of the svm rpc
487c478bd9Sstevel@tonic-gate  * calls. No changes may be made to the version 1 routines or structures used
497c478bd9Sstevel@tonic-gate  * by these routines.
507c478bd9Sstevel@tonic-gate  *
517c478bd9Sstevel@tonic-gate  * If, for example, the version 2 mdrpc_devinfo_args over the wire structure
527c478bd9Sstevel@tonic-gate  * (mdrpc_devinfo_2_args*) is changed then the structure change must be
537c478bd9Sstevel@tonic-gate  * accompanied by the following:
547c478bd9Sstevel@tonic-gate  *
557c478bd9Sstevel@tonic-gate  * Header file changes:
567c478bd9Sstevel@tonic-gate  * . May need to introduce a new structure revision MD_METAD_ARGS_REV_X, where
577c478bd9Sstevel@tonic-gate  *   X is the revision number.
587c478bd9Sstevel@tonic-gate  * . Create mdrpc_devinfo_2_args_rX, where X is the new revision of the
597c478bd9Sstevel@tonic-gate  *   structure.
607c478bd9Sstevel@tonic-gate  * . Add a switch statement in mdrpc_devinfo_2_args.
617c478bd9Sstevel@tonic-gate  *
627c478bd9Sstevel@tonic-gate  * rpc.metad changes:
637c478bd9Sstevel@tonic-gate  * . Check for the structure revision in the appropriate mdrpc_devinfo_svc
647c478bd9Sstevel@tonic-gate  *   routine (mdrpc_devinfo_2_svc).
657c478bd9Sstevel@tonic-gate  *
667c478bd9Sstevel@tonic-gate  * libmeta changes:
677c478bd9Sstevel@tonic-gate  * . In the libmeta code that makes the mdrpc_devinfo rpc call, the arguments
687c478bd9Sstevel@tonic-gate  *   being passed as part of this call (namely mdrpc_devinfo_Y_args) must have
697c478bd9Sstevel@tonic-gate  *   the revision field and associated structure populated correctly.
707c478bd9Sstevel@tonic-gate  */
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate static	md_setkey_t	*my_svc_sk = NULL;
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate /*
757c478bd9Sstevel@tonic-gate  * Add namespace entry to local mddb for using given sideno, key
767c478bd9Sstevel@tonic-gate  * and names.
777c478bd9Sstevel@tonic-gate  */
787c478bd9Sstevel@tonic-gate static int
add_sideno_sidenm(mdsidenames_t * sidenms,mdkey_t local_key,side_t sideno,md_set_desc * sd,md_error_t * ep)797c478bd9Sstevel@tonic-gate add_sideno_sidenm(
807c478bd9Sstevel@tonic-gate 	mdsidenames_t	*sidenms,
817c478bd9Sstevel@tonic-gate 	mdkey_t		local_key,
827c478bd9Sstevel@tonic-gate 	side_t		sideno,
837c478bd9Sstevel@tonic-gate 	md_set_desc	*sd,		/* Only used with Version 2 */
847c478bd9Sstevel@tonic-gate 	md_error_t	*ep
857c478bd9Sstevel@tonic-gate )
867c478bd9Sstevel@tonic-gate {
877c478bd9Sstevel@tonic-gate 	mdsidenames_t	*sn;
887c478bd9Sstevel@tonic-gate 	mdsetname_t	*local_sp;
897c478bd9Sstevel@tonic-gate 	char		*nm;
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
927c478bd9Sstevel@tonic-gate 		return (-1);
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate 	for (sn = sidenms; sn != NULL; sn = sn->next)
957c478bd9Sstevel@tonic-gate 		if (sn->sideno == sideno)
967c478bd9Sstevel@tonic-gate 			break;
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 	assert(sn != NULL);
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	/*
1027c478bd9Sstevel@tonic-gate 	 * SKEW will be used on the traditional diskset despite of the
1037c478bd9Sstevel@tonic-gate 	 * rpc version.  SKEW is not used on the multinode diskset
1047c478bd9Sstevel@tonic-gate 	 */
1057c478bd9Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd)) {
1067c478bd9Sstevel@tonic-gate 		nm = meta_getnmbykey(MD_LOCAL_SET, sideno, local_key, ep);
1077c478bd9Sstevel@tonic-gate 	} else {
1087c478bd9Sstevel@tonic-gate 		nm = meta_getnmbykey(MD_LOCAL_SET, sideno+SKEW, local_key, ep);
1097c478bd9Sstevel@tonic-gate 	}
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 	if (nm == NULL) {
1127c478bd9Sstevel@tonic-gate 		if (! mdisok(ep)) {
1137c478bd9Sstevel@tonic-gate 			if (! mdissyserror(ep, ENOENT))
1147c478bd9Sstevel@tonic-gate 				return (-1);
1157c478bd9Sstevel@tonic-gate 			mdclrerror(ep);
1167c478bd9Sstevel@tonic-gate 		}
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 		/*
1197c478bd9Sstevel@tonic-gate 		 * Ignore returned key from add_name, only care about errs
1207c478bd9Sstevel@tonic-gate 		 *
1217c478bd9Sstevel@tonic-gate 		 * SKEW is used for a regular diskset since sideno could
1227c478bd9Sstevel@tonic-gate 		 * have a value of 0 in that diskset type.  add_name is
1237c478bd9Sstevel@tonic-gate 		 * writing to the local mddb and a sideno of 0 in the
1247c478bd9Sstevel@tonic-gate 		 * local mddb is reserved for non-diskset names.
1257c478bd9Sstevel@tonic-gate 		 * SKEW is added to the sideno in the local mddb so that
1267c478bd9Sstevel@tonic-gate 		 * the sideno for the diskset will never be 0.
1277c478bd9Sstevel@tonic-gate 		 *
1287c478bd9Sstevel@tonic-gate 		 * In a MNdiskset, the sideno will never be 0 (by design).
1297c478bd9Sstevel@tonic-gate 		 * So, no SKEW is needed when writing to the local mddb.
1307c478bd9Sstevel@tonic-gate 		 */
1317c478bd9Sstevel@tonic-gate 		if (MD_MNSET_DESC(sd)) {
1327c478bd9Sstevel@tonic-gate 			if (add_name(local_sp, sideno, local_key,
133da833524Sjeanm 			    sn->dname, sn->mnum, sn->cname, NULL, NULL,
134da833524Sjeanm 			    ep) == -1)
1357c478bd9Sstevel@tonic-gate 				return (-1);
1367c478bd9Sstevel@tonic-gate 		} else {
1377c478bd9Sstevel@tonic-gate 			if (add_name(local_sp, sideno+SKEW, local_key,
138da833524Sjeanm 			    sn->dname, sn->mnum, sn->cname, NULL, NULL,
139da833524Sjeanm 			    ep) == -1)
1407c478bd9Sstevel@tonic-gate 				return (-1);
1417c478bd9Sstevel@tonic-gate 		}
1427c478bd9Sstevel@tonic-gate 	} else
1437c478bd9Sstevel@tonic-gate 		Free(nm);
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	return (0);
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate /*
1497c478bd9Sstevel@tonic-gate  * Delete sidename entry from local set using key and sideno.
1507c478bd9Sstevel@tonic-gate  */
1517c478bd9Sstevel@tonic-gate static int
del_sideno_sidenm(mdkey_t sidekey,side_t sideno,md_error_t * ep)1527c478bd9Sstevel@tonic-gate del_sideno_sidenm(
1537c478bd9Sstevel@tonic-gate 	mdkey_t		sidekey,
1547c478bd9Sstevel@tonic-gate 	side_t		sideno,
1557c478bd9Sstevel@tonic-gate 	md_error_t	*ep
1567c478bd9Sstevel@tonic-gate )
1577c478bd9Sstevel@tonic-gate {
1587c478bd9Sstevel@tonic-gate 	mdsetname_t	*local_sp;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
1617c478bd9Sstevel@tonic-gate 		return (-1);
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	if (del_name(local_sp, sideno, sidekey, ep) == -1)
1647c478bd9Sstevel@tonic-gate 		mdclrerror(ep); /* ignore errs */
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 	return (0);
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate /*
1717c478bd9Sstevel@tonic-gate  * Add namespace entries to local mddb for drives in drive list in
1727c478bd9Sstevel@tonic-gate  * set descriptor.
1737c478bd9Sstevel@tonic-gate  *
1747c478bd9Sstevel@tonic-gate  * If a MNset and if this host is being added to the set (this host
1757c478bd9Sstevel@tonic-gate  * is in the node_v list), add a namespace entry for the name of
1767c478bd9Sstevel@tonic-gate  * each drive using this host's sideno.
1777c478bd9Sstevel@tonic-gate  *
1787c478bd9Sstevel@tonic-gate  * If not a MNset, add namespace entries for all the new hosts being
1797c478bd9Sstevel@tonic-gate  * added to this set (list in node_v).
1807c478bd9Sstevel@tonic-gate  */
1817c478bd9Sstevel@tonic-gate static void
add_drv_sidenms(char * hostname,mdsetname_t * sp,md_set_desc * sd,int node_c,char ** node_v,md_error_t * ep)1827c478bd9Sstevel@tonic-gate add_drv_sidenms(
1837c478bd9Sstevel@tonic-gate 	char		*hostname,
1847c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
1857c478bd9Sstevel@tonic-gate 	md_set_desc	*sd,
1867c478bd9Sstevel@tonic-gate 	int		node_c,
1877c478bd9Sstevel@tonic-gate 	char		**node_v,
1887c478bd9Sstevel@tonic-gate 	md_error_t	*ep
1897c478bd9Sstevel@tonic-gate )
1907c478bd9Sstevel@tonic-gate {
1917c478bd9Sstevel@tonic-gate 	mdsetname_t	*my_sp;
1927c478bd9Sstevel@tonic-gate 	md_drive_desc	*dd, *my_dd, *p, *q;
1937c478bd9Sstevel@tonic-gate 	mddrivename_t	*dn, *my_dn;
1947c478bd9Sstevel@tonic-gate 	int		i;
1957c478bd9Sstevel@tonic-gate 	side_t		sideno = 0, mysideno = 0;
1967c478bd9Sstevel@tonic-gate 	ddi_devid_t	devid_remote = NULL;
1977c478bd9Sstevel@tonic-gate 	ddi_devid_t	devid_local = NULL;
1987c478bd9Sstevel@tonic-gate 	int		devid_same = -1;
1997c478bd9Sstevel@tonic-gate 	int		using_devid = 0;
2007c478bd9Sstevel@tonic-gate 	md_mnnode_desc	*nd;
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 	assert(sd->sd_drvs != NULL);
2037c478bd9Sstevel@tonic-gate 	dd = sd->sd_drvs;
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	if (dd->dd_dnp == NULL)
2067c478bd9Sstevel@tonic-gate 		return;
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	if ((my_sp = metasetname(sp->setname, ep)) == NULL)
2097c478bd9Sstevel@tonic-gate 		return;
2107c478bd9Sstevel@tonic-gate 	metaflushsetname(my_sp);
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 	/* If a MN diskset */
2137c478bd9Sstevel@tonic-gate 	if (MD_MNSET_DESC(sd)) {
2147c478bd9Sstevel@tonic-gate 		/* Find sideno associated with RPC client. */
2157c478bd9Sstevel@tonic-gate 		nd = sd->sd_nodelist;
2167c478bd9Sstevel@tonic-gate 		while (nd) {
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 			if (strcmp(nd->nd_nodename, hostname) == 0) {
2197c478bd9Sstevel@tonic-gate 				sideno = nd->nd_nodeid;
2207c478bd9Sstevel@tonic-gate 			}
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 			/* While looping, find my side num as well */
2237c478bd9Sstevel@tonic-gate 			if (strcmp(nd->nd_nodename, mynode()) == 0) {
2247c478bd9Sstevel@tonic-gate 				mysideno = nd->nd_nodeid;
2257c478bd9Sstevel@tonic-gate 			}
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 			if ((sideno) && (mysideno)) {
2287c478bd9Sstevel@tonic-gate 				break;
2297c478bd9Sstevel@tonic-gate 			}
2307c478bd9Sstevel@tonic-gate 			nd = nd->nd_next;
2317c478bd9Sstevel@tonic-gate 		}
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 		if (!sideno) {
2347c478bd9Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_HOSTNOSIDE,
2357c478bd9Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
2367c478bd9Sstevel@tonic-gate 			return;
2377c478bd9Sstevel@tonic-gate 		}
2387c478bd9Sstevel@tonic-gate 	} else {
2397c478bd9Sstevel@tonic-gate 		/*
2407c478bd9Sstevel@tonic-gate 		 * if not a MN diskset
2417c478bd9Sstevel@tonic-gate 		 * do action for traditional diskset.
2427c478bd9Sstevel@tonic-gate 		 * despite of the rpc version
2437c478bd9Sstevel@tonic-gate 		 */
2447c478bd9Sstevel@tonic-gate 		for (sideno = 0; sideno < MD_MAXSIDES; sideno++) {
2457c478bd9Sstevel@tonic-gate 			/* Skip empty slots */
2467c478bd9Sstevel@tonic-gate 			if (sd->sd_nodes[sideno][0] == '\0')
2477c478bd9Sstevel@tonic-gate 				continue;
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 			if (strcmp(hostname, sd->sd_nodes[sideno]) == 0)
2507c478bd9Sstevel@tonic-gate 				break;
2517c478bd9Sstevel@tonic-gate 		}
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 		if (sideno == MD_MAXSIDES) {
2547c478bd9Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_HOSTNOSIDE, sp->setno,
2557c478bd9Sstevel@tonic-gate 			    hostname, NULL, sp->setname);
2567c478bd9Sstevel@tonic-gate 			return;
2577c478bd9Sstevel@tonic-gate 		}
2587c478bd9Sstevel@tonic-gate 	}
2597c478bd9Sstevel@tonic-gate 	if ((my_dd = metaget_drivedesc_sideno(my_sp, sideno, MD_BASICNAME_OK,
2607c478bd9Sstevel@tonic-gate 	    ep)) == NULL) {
2617c478bd9Sstevel@tonic-gate 		if (! mdisok(ep))
2627c478bd9Sstevel@tonic-gate 			return;
2637c478bd9Sstevel@tonic-gate 		/* we are supposed to have drives!!!! */
2647c478bd9Sstevel@tonic-gate 		assert(0);
2657c478bd9Sstevel@tonic-gate 	}
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 	/*
2687c478bd9Sstevel@tonic-gate 	 * The system is either all devid or all
2697c478bd9Sstevel@tonic-gate 	 * non-devid so we look at the first item
2707c478bd9Sstevel@tonic-gate 	 * in the list to determine if we're using devids or not.
2717c478bd9Sstevel@tonic-gate 	 * We also check to make sure it's not a multi-node diskset.
2727c478bd9Sstevel@tonic-gate 	 * If it is, we don't use devid's.
2737c478bd9Sstevel@tonic-gate 	 *
2747c478bd9Sstevel@tonic-gate 	 * For did disks, the dd_dnp->devid is a valid pointer which
2757c478bd9Sstevel@tonic-gate 	 * points to a '' string of devid.  We need to check this
2767c478bd9Sstevel@tonic-gate 	 * before set the using_devid.
2777c478bd9Sstevel@tonic-gate 	 */
2787c478bd9Sstevel@tonic-gate 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
2797c478bd9Sstevel@tonic-gate 	    (!(MD_MNSET_DESC(sd))))
2807c478bd9Sstevel@tonic-gate 		using_devid = 1;
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 	/*
2837c478bd9Sstevel@tonic-gate 	 * We have to match-up the dd that were passed
2847c478bd9Sstevel@tonic-gate 	 * across the wire to the dd we have in this daemon.
2857c478bd9Sstevel@tonic-gate 	 * That way we can pick up the new sidenames that were
2867c478bd9Sstevel@tonic-gate 	 * passed to us and match them up with the local namespace key.
2877c478bd9Sstevel@tonic-gate 	 * Only we have the key, this cannot be passed in.
2887c478bd9Sstevel@tonic-gate 	 */
2897c478bd9Sstevel@tonic-gate 	for (p = dd; p != NULL; p = p->dd_next) {
2907c478bd9Sstevel@tonic-gate 		dn = p->dd_dnp;
2917c478bd9Sstevel@tonic-gate 		devid_remote = NULL;
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
2947c478bd9Sstevel@tonic-gate 		    using_devid) {
2957c478bd9Sstevel@tonic-gate 			/*
2967c478bd9Sstevel@tonic-gate 			 * We have a devid so use it
2977c478bd9Sstevel@tonic-gate 			 */
2987c478bd9Sstevel@tonic-gate 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
2997c478bd9Sstevel@tonic-gate 		}
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate 		/* check to make sure using_devid agrees with reality... */
3027c478bd9Sstevel@tonic-gate 		if ((using_devid == 1) && (devid_remote == NULL)) {
3037c478bd9Sstevel@tonic-gate 			/* something went really wrong. Can't process */
3047c478bd9Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
3057c478bd9Sstevel@tonic-gate 			    hostname, dn->cname, sp->setname);
3067c478bd9Sstevel@tonic-gate 			return;
3077c478bd9Sstevel@tonic-gate 		}
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 		for (q = my_dd; q != NULL; q = q->dd_next) {
3107c478bd9Sstevel@tonic-gate 			my_dn = q->dd_dnp;
3117c478bd9Sstevel@tonic-gate 			devid_same = -1;
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 			if (my_dn->devid != NULL && using_devid) {
3147c478bd9Sstevel@tonic-gate 				if (devid_str_decode(my_dn->devid,
3157c478bd9Sstevel@tonic-gate 				    &devid_local, NULL) == 0) {
3167c478bd9Sstevel@tonic-gate 					devid_same = devid_compare(devid_remote,
3177c478bd9Sstevel@tonic-gate 					    devid_local);
3187c478bd9Sstevel@tonic-gate 					devid_free(devid_local);
3197c478bd9Sstevel@tonic-gate 				}
3207c478bd9Sstevel@tonic-gate 			}
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 			if (using_devid && devid_same == 0) {
3237c478bd9Sstevel@tonic-gate 				break;
3247c478bd9Sstevel@tonic-gate 			}
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 			if (!using_devid &&
3277c478bd9Sstevel@tonic-gate 			    strcmp(my_dn->cname, dn->cname) == 0)
3287c478bd9Sstevel@tonic-gate 				break;
3297c478bd9Sstevel@tonic-gate 		}
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate 		if (devid_remote) {
3327c478bd9Sstevel@tonic-gate 			devid_free(devid_remote);
3337c478bd9Sstevel@tonic-gate 		}
3347c478bd9Sstevel@tonic-gate 		assert(q != NULL);
3357c478bd9Sstevel@tonic-gate 		assert(my_dn->side_names_key != MD_KEYWILD);
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 		if (MD_MNSET_DESC(sd)) {
3387c478bd9Sstevel@tonic-gate 			/*
3397c478bd9Sstevel@tonic-gate 			 * Add the side names to the local db
3407c478bd9Sstevel@tonic-gate 			 * for this node only.
3417c478bd9Sstevel@tonic-gate 			 */
3427c478bd9Sstevel@tonic-gate 			if (add_sideno_sidenm(dn->side_names,
3437c478bd9Sstevel@tonic-gate 			    my_dn->side_names_key, mysideno, sd, ep))
3447c478bd9Sstevel@tonic-gate 				return;
3457c478bd9Sstevel@tonic-gate 			/*
3467c478bd9Sstevel@tonic-gate 			 * Sidenames for this drive were added
3477c478bd9Sstevel@tonic-gate 			 * to this host during the routine adddrvs.
3487c478bd9Sstevel@tonic-gate 			 * The sidenames that were added are the
3497c478bd9Sstevel@tonic-gate 			 * names associated with this drive on
3507c478bd9Sstevel@tonic-gate 			 * each of the hosts that were previously
3517c478bd9Sstevel@tonic-gate 			 * in the set.
3527c478bd9Sstevel@tonic-gate 			 * When the sidename for this drive on
3537c478bd9Sstevel@tonic-gate 			 * this host is added, the sidename
3547c478bd9Sstevel@tonic-gate 			 * from the host executing the command
3557c478bd9Sstevel@tonic-gate 			 * (not this host) is sent to this host.
3567c478bd9Sstevel@tonic-gate 			 * This host finds the originating host's
3577c478bd9Sstevel@tonic-gate 			 * sidename and can then determine this
3587c478bd9Sstevel@tonic-gate 			 * host's sidename.
3597c478bd9Sstevel@tonic-gate 			 * The sidenames from the other hosts serve
3607c478bd9Sstevel@tonic-gate 			 * only as temporary sidenames until this
3617c478bd9Sstevel@tonic-gate 			 * host's sidename can be added.
3627c478bd9Sstevel@tonic-gate 			 * In order to conserve space in the
3637c478bd9Sstevel@tonic-gate 			 * local mddb, the code now deletes the
3647c478bd9Sstevel@tonic-gate 			 * temporary sidenames added during adddrvs.
3657c478bd9Sstevel@tonic-gate 			 * When finished, only the sidename for this
3667c478bd9Sstevel@tonic-gate 			 * node should be left.
3677c478bd9Sstevel@tonic-gate 			 * Ignore any errors during this process since
3687c478bd9Sstevel@tonic-gate 			 * a failure to delete the extraneous
3697c478bd9Sstevel@tonic-gate 			 * sidenames shouldn't cause this routine
3707c478bd9Sstevel@tonic-gate 			 * to fail (in case that sidename didn't exist).
3717c478bd9Sstevel@tonic-gate 			 */
3727c478bd9Sstevel@tonic-gate 			nd = sd->sd_nodelist;
3737c478bd9Sstevel@tonic-gate 			while (nd) {
3747c478bd9Sstevel@tonic-gate 				if (nd->nd_nodeid != mysideno) {
3757c478bd9Sstevel@tonic-gate 					if (del_sideno_sidenm(
3767c478bd9Sstevel@tonic-gate 					    dn->side_names_key,
3777c478bd9Sstevel@tonic-gate 					    nd->nd_nodeid, ep) == -1)
3787c478bd9Sstevel@tonic-gate 						mdclrerror(ep);
3797c478bd9Sstevel@tonic-gate 				}
3807c478bd9Sstevel@tonic-gate 				nd = nd->nd_next;
3817c478bd9Sstevel@tonic-gate 			}
3827c478bd9Sstevel@tonic-gate 		} else {
3837c478bd9Sstevel@tonic-gate 			for (i = 0; i < MD_MAXSIDES; i++) {
3847c478bd9Sstevel@tonic-gate 				/* Skip empty slots */
3857c478bd9Sstevel@tonic-gate 				if (sd->sd_nodes[i][0] == '\0')
3867c478bd9Sstevel@tonic-gate 					continue;
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 				/* Skip nodes not being added */
3897c478bd9Sstevel@tonic-gate 				if (! strinlst(sd->sd_nodes[i],
3907c478bd9Sstevel@tonic-gate 				    node_c, node_v))
3917c478bd9Sstevel@tonic-gate 					continue;
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 				/* Add the per side names to local db */
3947c478bd9Sstevel@tonic-gate 				if (add_sideno_sidenm(dn->side_names,
3957c478bd9Sstevel@tonic-gate 				    my_dn->side_names_key, i, sd, ep))
3967c478bd9Sstevel@tonic-gate 					return;
3977c478bd9Sstevel@tonic-gate 			}
3987c478bd9Sstevel@tonic-gate 		}
3997c478bd9Sstevel@tonic-gate 	}
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate /* ARGSUSED */
4037c478bd9Sstevel@tonic-gate bool_t
mdrpc_flush_internal_common(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4047c478bd9Sstevel@tonic-gate mdrpc_flush_internal_common(mdrpc_null_args *args, mdrpc_generic_res *res,
4057c478bd9Sstevel@tonic-gate     struct svc_req *rqstp)
4067c478bd9Sstevel@tonic-gate {
4077c478bd9Sstevel@tonic-gate 	md_error_t	*ep = &res->status;
408ee8af371Sachimm 	int		err, op_mode = W_OK;
4097c478bd9Sstevel@tonic-gate 
4102a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
4117c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4127c478bd9Sstevel@tonic-gate 		return (FALSE);
4137c478bd9Sstevel@tonic-gate 	else if (err != 0)
4147c478bd9Sstevel@tonic-gate 		return (TRUE);
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate 	metaflushnames(1);
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 	return (TRUE);
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate bool_t
mdrpc_flush_internal_1_svc(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4247c478bd9Sstevel@tonic-gate mdrpc_flush_internal_1_svc(mdrpc_null_args *args, mdrpc_generic_res *res,
4257c478bd9Sstevel@tonic-gate     struct svc_req *rqstp)
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate 	return (mdrpc_flush_internal_common(args, res, rqstp));
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate bool_t
mdrpc_flush_internal_2_svc(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4317c478bd9Sstevel@tonic-gate mdrpc_flush_internal_2_svc(mdrpc_null_args *args, mdrpc_generic_res *res,
4327c478bd9Sstevel@tonic-gate     struct svc_req *rqstp)
4337c478bd9Sstevel@tonic-gate {
4347c478bd9Sstevel@tonic-gate 	return (mdrpc_flush_internal_common(args, res, rqstp));
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate /*
4387c478bd9Sstevel@tonic-gate  * add 1 or more namespace entries per drive record.
4397c478bd9Sstevel@tonic-gate  * (into the local namespace)
4407c478bd9Sstevel@tonic-gate  */
4417c478bd9Sstevel@tonic-gate bool_t
mdrpc_add_drv_sidenms_common(mdrpc_drv_sidenm_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)4427c478bd9Sstevel@tonic-gate mdrpc_add_drv_sidenms_common(
4437c478bd9Sstevel@tonic-gate 	mdrpc_drv_sidenm_2_args_r1	*args,
4447c478bd9Sstevel@tonic-gate 	mdrpc_generic_res		*res,
4457c478bd9Sstevel@tonic-gate 	struct svc_req			*rqstp		/* RPC stuff */
4467c478bd9Sstevel@tonic-gate )
4477c478bd9Sstevel@tonic-gate {
4487c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
4497c478bd9Sstevel@tonic-gate 	int			err;
4507c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
4537c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4547c478bd9Sstevel@tonic-gate 		return (FALSE);
4557c478bd9Sstevel@tonic-gate 	else if (err != 0)
4567c478bd9Sstevel@tonic-gate 		return (TRUE);
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
4597c478bd9Sstevel@tonic-gate 		return (TRUE);
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate 	/* doit */
4627c478bd9Sstevel@tonic-gate 	add_drv_sidenms(args->hostname, args->sp, args->sd,
4637c478bd9Sstevel@tonic-gate 	    args->node_v.node_v_len, args->node_v.node_v_val, ep);
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 	return (TRUE);
4687c478bd9Sstevel@tonic-gate }
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate /*
4717c478bd9Sstevel@tonic-gate  * version 1 of the remote procedure. This procedure is called if the
4727c478bd9Sstevel@tonic-gate  * client is running in version 1. We first convert version 1 arguments
4737c478bd9Sstevel@tonic-gate  * into version 2 arguments and then call the common remote procedure.
4747c478bd9Sstevel@tonic-gate  */
4757c478bd9Sstevel@tonic-gate bool_t
mdrpc_add_drv_sidenms_1_svc(mdrpc_drv_sidenm_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)4767c478bd9Sstevel@tonic-gate mdrpc_add_drv_sidenms_1_svc(
4777c478bd9Sstevel@tonic-gate 	mdrpc_drv_sidenm_args	*args,
4787c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
4797c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
4807c478bd9Sstevel@tonic-gate )
4817c478bd9Sstevel@tonic-gate {
4827c478bd9Sstevel@tonic-gate 	bool_t				retval;
4837c478bd9Sstevel@tonic-gate 	mdrpc_drv_sidenm_2_args_r1	v2_args;
4847c478bd9Sstevel@tonic-gate 	int				i, j;
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate 	/* allocate memory */
4877c478bd9Sstevel@tonic-gate 	v2_args.sd = Zalloc(sizeof (md_set_desc));
4887c478bd9Sstevel@tonic-gate 	alloc_newdrvdesc(args->sd->sd_drvs, &v2_args.sd->sd_drvs);
4892a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 	/* build args */
4927c478bd9Sstevel@tonic-gate 	v2_args.hostname = args->hostname;
4937c478bd9Sstevel@tonic-gate 	v2_args.cl_sk = args->cl_sk;
4947c478bd9Sstevel@tonic-gate 	v2_args.sp = args->sp;
4957c478bd9Sstevel@tonic-gate 	/* set descriptor */
4967c478bd9Sstevel@tonic-gate 	v2_args.sd->sd_ctime = args->sd->sd_ctime;
4977c478bd9Sstevel@tonic-gate 	v2_args.sd->sd_genid = args->sd->sd_genid;
4987c478bd9Sstevel@tonic-gate 	v2_args.sd->sd_setno = args->sd->sd_setno;
4997c478bd9Sstevel@tonic-gate 	v2_args.sd->sd_flags = args->sd->sd_flags;
5007c478bd9Sstevel@tonic-gate 	for (i = 0; i < MD_MAXSIDES; i++) {
5017c478bd9Sstevel@tonic-gate 		v2_args.sd->sd_isown[i] = args->sd->sd_isown[i];
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate 		for (j = 0; j < MD_MAX_NODENAME_PLUS_1; j++)
5047c478bd9Sstevel@tonic-gate 			v2_args.sd->sd_nodes[i][j] =
5057c478bd9Sstevel@tonic-gate 			    args->sd->sd_nodes[i][j];
5067c478bd9Sstevel@tonic-gate 	}
5077c478bd9Sstevel@tonic-gate 	v2_args.sd->sd_med = args->sd->sd_med;
5087c478bd9Sstevel@tonic-gate 	/* convert v1 args to v2 (revision 1) args */
5097c478bd9Sstevel@tonic-gate 	meta_conv_drvdesc_old2new(args->sd->sd_drvs, v2_args.sd->sd_drvs);
5107c478bd9Sstevel@tonic-gate 	v2_args.node_v.node_v_len = args->node_v.node_v_len;
5117c478bd9Sstevel@tonic-gate 	v2_args.node_v.node_v_val = args->node_v.node_v_val;
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 	retval = mdrpc_add_drv_sidenms_common(&v2_args, res, rqstp);
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate 	free(v2_args.sd);
5167c478bd9Sstevel@tonic-gate 	free_newdrvdesc(v2_args.sd->sd_drvs);
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate 	return (retval);
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate bool_t
mdrpc_add_drv_sidenms_2_svc(mdrpc_drv_sidenm_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)5227c478bd9Sstevel@tonic-gate mdrpc_add_drv_sidenms_2_svc(
5237c478bd9Sstevel@tonic-gate 	mdrpc_drv_sidenm_2_args	*args,
5247c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
5257c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
5267c478bd9Sstevel@tonic-gate )
5277c478bd9Sstevel@tonic-gate {
5282a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
5297c478bd9Sstevel@tonic-gate 	switch (args->rev) {
5307c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
5317c478bd9Sstevel@tonic-gate 		return (mdrpc_add_drv_sidenms_common(
5327c478bd9Sstevel@tonic-gate 		    &args->mdrpc_drv_sidenm_2_args_u.rev1, res, rqstp));
5337c478bd9Sstevel@tonic-gate 	default:
5347c478bd9Sstevel@tonic-gate 		return (FALSE);
5357c478bd9Sstevel@tonic-gate 	}
5367c478bd9Sstevel@tonic-gate }
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate static int
add_sidenamelist(mddrivename_t * dn,side_t thisside,md_set_record * sr,md_error_t * ep)5397c478bd9Sstevel@tonic-gate add_sidenamelist(
5407c478bd9Sstevel@tonic-gate 	mddrivename_t	*dn,
5417c478bd9Sstevel@tonic-gate 	side_t		thisside,
5427c478bd9Sstevel@tonic-gate 	md_set_record	*sr, 		/* used by RPC version 2 */
5437c478bd9Sstevel@tonic-gate 	md_error_t	*ep
5447c478bd9Sstevel@tonic-gate )
5457c478bd9Sstevel@tonic-gate {
5467c478bd9Sstevel@tonic-gate 	mdsidenames_t	*sn;
5477c478bd9Sstevel@tonic-gate 	mdkey_t		key;
5487c478bd9Sstevel@tonic-gate 	int		err;
5497c478bd9Sstevel@tonic-gate 	mdsetname_t	*local_sp;
5507c478bd9Sstevel@tonic-gate 	md_mnset_record	*mnsr;
5517c478bd9Sstevel@tonic-gate 	md_mnnode_record *nr;
5527c478bd9Sstevel@tonic-gate 	uint_t		nodeid = 0;
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
5557c478bd9Sstevel@tonic-gate 		return (-1);
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	key = MD_KEYWILD;
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 	/*
5607c478bd9Sstevel@tonic-gate 	 * If a multi-node diskset, find nodeid associated with this node.
5617c478bd9Sstevel@tonic-gate 	 */
5627c478bd9Sstevel@tonic-gate 	if (MD_MNSET_REC(sr)) {
5637c478bd9Sstevel@tonic-gate 		mnsr = (struct md_mnset_record *)sr;
5647c478bd9Sstevel@tonic-gate 		nr = mnsr->sr_nodechain;
5657c478bd9Sstevel@tonic-gate 		while (nr) {
5667c478bd9Sstevel@tonic-gate 			if (strcmp(nr->nr_nodename, mynode()) == 0) {
5677c478bd9Sstevel@tonic-gate 				break;
5687c478bd9Sstevel@tonic-gate 			}
5697c478bd9Sstevel@tonic-gate 			nr = nr->nr_next;
5707c478bd9Sstevel@tonic-gate 		}
5717c478bd9Sstevel@tonic-gate 		/*
5727c478bd9Sstevel@tonic-gate 		 * If node is found, then a new drive is being added to
5737c478bd9Sstevel@tonic-gate 		 * a MN set of which this node is a member.
5747c478bd9Sstevel@tonic-gate 		 * If node is not found, then this host is being added to
5757c478bd9Sstevel@tonic-gate 		 * a MN set that has drives associated with it.
5767c478bd9Sstevel@tonic-gate 		 */
5777c478bd9Sstevel@tonic-gate 		if (nr)
5787c478bd9Sstevel@tonic-gate 			nodeid = nr->nr_nodeid;
5797c478bd9Sstevel@tonic-gate 	}
5807c478bd9Sstevel@tonic-gate 	for (sn = dn->side_names; sn != NULL; sn = sn->next) {
5817c478bd9Sstevel@tonic-gate 		if (MD_MNSET_REC(sr)) {
5827c478bd9Sstevel@tonic-gate 			/*
5837c478bd9Sstevel@tonic-gate 			 * In multi-node disksets, only add side information
5847c478bd9Sstevel@tonic-gate 			 * to the local mddb about this node.
5857c478bd9Sstevel@tonic-gate 			 * If the sideno for this node is found, then
5867c478bd9Sstevel@tonic-gate 			 * a new drive is being added to a MN set of
5877c478bd9Sstevel@tonic-gate 			 * which this node is a member.
5887c478bd9Sstevel@tonic-gate 			 * If the sideno for this node is not found, then
5897c478bd9Sstevel@tonic-gate 			 * this host is being added to a MNset that
5907c478bd9Sstevel@tonic-gate 			 * has drives associated with it.  In this case,
5917c478bd9Sstevel@tonic-gate 			 * need to add the sidename associated with the
5927c478bd9Sstevel@tonic-gate 			 * rpc client, but since we don't know which node
5937c478bd9Sstevel@tonic-gate 			 * is the client, then add temp entries for all sides.
5947c478bd9Sstevel@tonic-gate 			 * Later, the sidename for this node will be set
5957c478bd9Sstevel@tonic-gate 			 * via add_drv_sidenms and then the temp
5967c478bd9Sstevel@tonic-gate 			 * sidenames can be removed.
5977c478bd9Sstevel@tonic-gate 			 */
5987c478bd9Sstevel@tonic-gate 			if (nodeid == sn->sideno) {
5997c478bd9Sstevel@tonic-gate 				if ((err = add_name(local_sp, sn->sideno, key,
600da833524Sjeanm 				    sn->dname, sn->mnum, sn->cname,
601da833524Sjeanm 				    NULL, NULL, ep)) == -1)
6027c478bd9Sstevel@tonic-gate 					return (-1);
6037c478bd9Sstevel@tonic-gate 				key = (mdkey_t)err;
6047c478bd9Sstevel@tonic-gate 				break;
6057c478bd9Sstevel@tonic-gate 			}
6067c478bd9Sstevel@tonic-gate 		} else {
6077c478bd9Sstevel@tonic-gate 			/*
6087c478bd9Sstevel@tonic-gate 			 * When a sidename is added into the namespace the local
6097c478bd9Sstevel@tonic-gate 			 * side information for the name is added first of all.
6107c478bd9Sstevel@tonic-gate 			 * When the first sidename is created this causes the
6117c478bd9Sstevel@tonic-gate 			 * devid of the disk to be recorded in the namespace, if
6127c478bd9Sstevel@tonic-gate 			 * the non-local side information is added first then
6137c478bd9Sstevel@tonic-gate 			 * there is the possibility of getting the wrong devid
6147c478bd9Sstevel@tonic-gate 			 * because there is no guarantee that the dev_t (mnum in
6157c478bd9Sstevel@tonic-gate 			 * this instance) is the same across all the nodes in
6167c478bd9Sstevel@tonic-gate 			 * the set. So the only way to make sure that the
6177c478bd9Sstevel@tonic-gate 			 * correct dev_t is used is to force the adding in of
6187c478bd9Sstevel@tonic-gate 			 * the local sidename record first of all. This same
6197c478bd9Sstevel@tonic-gate 			 * issue affects add_key_name().
6207c478bd9Sstevel@tonic-gate 			 */
6217c478bd9Sstevel@tonic-gate 			if (sn->sideno != thisside)
6227c478bd9Sstevel@tonic-gate 				continue;
6237c478bd9Sstevel@tonic-gate 			if ((err = add_name(local_sp, sn->sideno+SKEW, key,
624da833524Sjeanm 			    sn->dname, sn->mnum, sn->cname, NULL,
625da833524Sjeanm 			    NULL, ep)) == -1)
6267c478bd9Sstevel@tonic-gate 				return (-1);
6277c478bd9Sstevel@tonic-gate 			key = (mdkey_t)err;
6287c478bd9Sstevel@tonic-gate 			break;
6297c478bd9Sstevel@tonic-gate 		}
6307c478bd9Sstevel@tonic-gate 	}
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate 	/*
6337c478bd9Sstevel@tonic-gate 	 * Now the other sides for non-MN set
6347c478bd9Sstevel@tonic-gate 	 */
6357c478bd9Sstevel@tonic-gate 	if (!MD_MNSET_REC(sr)) {
6367c478bd9Sstevel@tonic-gate 		for (sn = dn->side_names; sn != NULL; sn = sn->next) {
6377c478bd9Sstevel@tonic-gate 			if (sn->sideno == thisside)
6387c478bd9Sstevel@tonic-gate 				continue;
6397c478bd9Sstevel@tonic-gate 			if ((err = add_name(local_sp, sn->sideno+SKEW, key,
640da833524Sjeanm 			    sn->dname, sn->mnum, sn->cname, NULL, NULL,
641da833524Sjeanm 			    ep)) == -1)
6427c478bd9Sstevel@tonic-gate 				return (-1);
6437c478bd9Sstevel@tonic-gate 			key = (mdkey_t)err;
6447c478bd9Sstevel@tonic-gate 		}
6457c478bd9Sstevel@tonic-gate 	}
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 	/* Temporarily add all sides. */
6487c478bd9Sstevel@tonic-gate 	if ((key == MD_KEYWILD) && (MD_MNSET_REC(sr))) {
6497c478bd9Sstevel@tonic-gate 		for (sn = dn->side_names; sn != NULL; sn = sn->next) {
6507c478bd9Sstevel@tonic-gate 			sn = dn->side_names;
6517c478bd9Sstevel@tonic-gate 			if (sn) {
6527c478bd9Sstevel@tonic-gate 				if ((err = add_name(local_sp, sn->sideno, key,
653da833524Sjeanm 				    sn->dname, sn->mnum, sn->cname,
654da833524Sjeanm 				    NULL, NULL, ep)) == -1)
6557c478bd9Sstevel@tonic-gate 						return (-1);
6567c478bd9Sstevel@tonic-gate 				key = (mdkey_t)err;
6577c478bd9Sstevel@tonic-gate 			}
6587c478bd9Sstevel@tonic-gate 		}
6597c478bd9Sstevel@tonic-gate 	}
6607c478bd9Sstevel@tonic-gate 
6617c478bd9Sstevel@tonic-gate 	dn->side_names_key = key;
6627c478bd9Sstevel@tonic-gate 	return (0);
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate 
665da833524Sjeanm /*
666da833524Sjeanm  * imp_adddrvs
667da833524Sjeanm  *    This is a version of adddrvs that is specific to the
668da833524Sjeanm  *    metaimport command. Due to the unavailability of some disks,
669da833524Sjeanm  *    information needs to be obtained about the disk from the devid so
670da833524Sjeanm  *    it can eventually be passed down to add_sidenamelist.
671da833524Sjeanm  *    Go ahead and set drive state to MD_DR_OK here so that no
672da833524Sjeanm  *    later RPC is needed to set OK where UNRLSV_REPLICATED could
673da833524Sjeanm  *    be cleared.  Set record is still set to MD_SR_ADD which will force
674da833524Sjeanm  *    a cleanup of the set in case of panic.
675da833524Sjeanm  */
676da833524Sjeanm void
imp_adddrvs(char * setname,md_drive_desc * dd,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)677da833524Sjeanm imp_adddrvs(
678da833524Sjeanm 	char		*setname,
679da833524Sjeanm 	md_drive_desc	*dd,
680da833524Sjeanm 	md_timeval32_t	timestamp,
681da833524Sjeanm 	ulong_t		genid,
682da833524Sjeanm 	md_error_t	*ep
683da833524Sjeanm )
684da833524Sjeanm {
685da833524Sjeanm 	mddb_userreq_t	req;
686da833524Sjeanm 	md_drive_record	*dr, *tdr;
687da833524Sjeanm 	md_set_record	*sr;
688da833524Sjeanm 	md_drive_desc	*p;
689da833524Sjeanm 	mddrivename_t	*dn;
690da833524Sjeanm 	mdname_t	*np;
691da833524Sjeanm 	md_dev64_t	dev;
692da833524Sjeanm 	md_error_t	xep = mdnullerror;
693da833524Sjeanm 	char		*minorname = NULL;
694da833524Sjeanm 	ddi_devid_t	devidp = NULL;
695da833524Sjeanm 	mdsidenames_t	*sn;
696da833524Sjeanm 	mdsetname_t	*local_sp;
697da833524Sjeanm 
698da833524Sjeanm 
699da833524Sjeanm 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) {
700da833524Sjeanm 		return;
701da833524Sjeanm 	}
702da833524Sjeanm 
703da833524Sjeanm 	if ((sr = getsetbyname(setname, ep)) == NULL)
704da833524Sjeanm 		return;
705da833524Sjeanm 
706da833524Sjeanm 	for (p = dd; p != NULL; p = p->dd_next) {
707da833524Sjeanm 		uint_t	rep_slice;
708da833524Sjeanm 		int	ret = 0;
709da833524Sjeanm 
710da833524Sjeanm 		dn = p->dd_dnp;
711da833524Sjeanm 
712da833524Sjeanm 		/*
713da833524Sjeanm 		 * We need the minorname and devid string decoded from the
714da833524Sjeanm 		 * devid to add the sidename for this drive to the
715da833524Sjeanm 		 * local set.
716da833524Sjeanm 		 */
717da833524Sjeanm 		ret = devid_str_decode(dn->devid, &devidp, &minorname);
718da833524Sjeanm 		if (ret != 0) {
719da833524Sjeanm 			/* failed to decode the devid */
720da833524Sjeanm 			goto out;
721da833524Sjeanm 		}
722da833524Sjeanm 
723da833524Sjeanm 		sn = dn->side_names;
724da833524Sjeanm 		if (sn == NULL) {
725da833524Sjeanm 			dn->side_names_key = MD_KEYWILD;
726da833524Sjeanm 			continue;
727da833524Sjeanm 		}
728da833524Sjeanm 
729da833524Sjeanm 		if ((dn->side_names_key = add_name(local_sp, SKEW, MD_KEYWILD,
730da833524Sjeanm 		    sn->dname, sn->mnum, sn->cname, minorname, devidp,
731da833524Sjeanm 		    ep)) == -1) {
732da833524Sjeanm 			devid_free(devidp);
733da833524Sjeanm 			devid_str_free(minorname);
734da833524Sjeanm 			goto out;
735da833524Sjeanm 		}
736da833524Sjeanm 
737da833524Sjeanm 		devid_free(devidp);
738da833524Sjeanm 		devid_str_free(minorname);
739da833524Sjeanm 
740da833524Sjeanm 		/* Create the drive record */
741da833524Sjeanm 		(void) memset(&req, 0, sizeof (req));
742da833524Sjeanm 		METAD_SETUP_DR(MD_DB_CREATE, 0);
743da833524Sjeanm 		req.ur_size = sizeof (*dr);
744da833524Sjeanm 		if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
745da833524Sjeanm 			(void) mdstealerror(ep, &req.ur_mde);
746da833524Sjeanm 			goto out;
747da833524Sjeanm 		}
748da833524Sjeanm 
749da833524Sjeanm 		/* Fill in the drive record values */
750da833524Sjeanm 		dr = Zalloc(sizeof (*dr));
751da833524Sjeanm 		dr->dr_selfid = req.ur_recid;
752da833524Sjeanm 		dr->dr_dbcnt = p->dd_dbcnt;
753da833524Sjeanm 		dr->dr_dbsize = p->dd_dbsize;
754da833524Sjeanm 		dr->dr_key = dn->side_names_key;
755da833524Sjeanm 
756da833524Sjeanm 		dr->dr_ctime = timestamp;
757da833524Sjeanm 		dr->dr_genid = genid;
758da833524Sjeanm 		dr->dr_revision = MD_DRIVE_RECORD_REVISION;
759da833524Sjeanm 		dr->dr_flags = MD_DR_OK;
760da833524Sjeanm 		if (p->dd_flags & MD_DR_UNRSLV_REPLICATED) {
761da833524Sjeanm 			dr->dr_flags |= MD_DR_UNRSLV_REPLICATED;
762da833524Sjeanm 			sr->sr_flags |= MD_SR_UNRSLV_REPLICATED;
763da833524Sjeanm 		}
764da833524Sjeanm 
765da833524Sjeanm 		/* Link the drive records and fill in in-core data */
766da833524Sjeanm 		dr_cache_add(sr, dr);
767da833524Sjeanm 
768da833524Sjeanm 		dev = NODEV64;
769da833524Sjeanm 		if ((meta_replicaslice(dn, &rep_slice, &xep) == 0) &&
770da833524Sjeanm 		    ((np = metaslicename(dn, rep_slice, &xep)) != NULL))
771da833524Sjeanm 			dev = np->dev;
772da833524Sjeanm 		else
773da833524Sjeanm 			mdclrerror(&xep);
774da833524Sjeanm 
775da833524Sjeanm 		SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
776da833524Sjeanm 		    MD_LOCAL_SET, dev);
777da833524Sjeanm 		SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
778da833524Sjeanm 		    sr->sr_setno, dev);
779da833524Sjeanm 	}
780da833524Sjeanm 
781da833524Sjeanm 	/* Commit all the records atomically */
782da833524Sjeanm 	commitset(sr, TRUE, ep);
783da833524Sjeanm 	free_sr(sr);
784da833524Sjeanm 	return;
785da833524Sjeanm 
786da833524Sjeanm out:
787da833524Sjeanm 	/* If failures, remove drive records. */
788da833524Sjeanm 	dr = tdr = sr->sr_drivechain;
789da833524Sjeanm 	while (dr != NULL) {
790da833524Sjeanm 		tdr = dr->dr_next;
791da833524Sjeanm 		if (del_name(local_sp, 0, dr->dr_key, &xep))
792da833524Sjeanm 			mdclrerror(&xep);
793da833524Sjeanm 		sr_del_drv(sr, dr->dr_selfid);
794da833524Sjeanm 		dr = tdr;
795da833524Sjeanm 	}
796da833524Sjeanm }
797da833524Sjeanm 
7987c478bd9Sstevel@tonic-gate static void
adddrvs(char * setname,md_drive_desc * dd,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)7997c478bd9Sstevel@tonic-gate adddrvs(
8007c478bd9Sstevel@tonic-gate 	char 		*setname,
8017c478bd9Sstevel@tonic-gate 	md_drive_desc	*dd,
8027c478bd9Sstevel@tonic-gate 	md_timeval32_t	timestamp,
8037c478bd9Sstevel@tonic-gate 	ulong_t		genid,
8047c478bd9Sstevel@tonic-gate 	md_error_t	*ep
8057c478bd9Sstevel@tonic-gate )
8067c478bd9Sstevel@tonic-gate {
8077c478bd9Sstevel@tonic-gate 	mddb_userreq_t	req;
8087c478bd9Sstevel@tonic-gate 	md_drive_record	*dr;
8097c478bd9Sstevel@tonic-gate 	md_set_record	*sr;
8107c478bd9Sstevel@tonic-gate 	md_drive_desc	*p;
8117c478bd9Sstevel@tonic-gate 	mddrivename_t	*dn;
8127c478bd9Sstevel@tonic-gate 	mdname_t	*np;
8137c478bd9Sstevel@tonic-gate 	md_dev64_t	dev;
8147c478bd9Sstevel@tonic-gate 	md_error_t	xep = mdnullerror;
8157c478bd9Sstevel@tonic-gate 	int		i;
8167c478bd9Sstevel@tonic-gate 
8177c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(setname, ep)) == NULL)
8187c478bd9Sstevel@tonic-gate 		return;
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate 	if (MD_MNSET_REC(sr))
8217c478bd9Sstevel@tonic-gate 		i = 0;
8227c478bd9Sstevel@tonic-gate 	else {
8237c478bd9Sstevel@tonic-gate 		/* get thisside */
8247c478bd9Sstevel@tonic-gate 		for (i = 0; i < MD_MAXSIDES; i++) {
8257c478bd9Sstevel@tonic-gate 			if (sr->sr_nodes[i][0] == '\0')
8267c478bd9Sstevel@tonic-gate 				continue;
8277c478bd9Sstevel@tonic-gate 			if (strcmp(mynode(), sr->sr_nodes[i]) == 0)
8287c478bd9Sstevel@tonic-gate 				break;
8297c478bd9Sstevel@tonic-gate 		}
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate 		if (i == MD_MAXSIDES) {
8327c478bd9Sstevel@tonic-gate 			/* so find the first free slot! */
8337c478bd9Sstevel@tonic-gate 			for (i = 0; i < MD_MAXSIDES; i++) {
8347c478bd9Sstevel@tonic-gate 				if (sr->sr_nodes[i][0] == '\0')
8357c478bd9Sstevel@tonic-gate 					break;
8367c478bd9Sstevel@tonic-gate 			}
8377c478bd9Sstevel@tonic-gate 		}
8387c478bd9Sstevel@tonic-gate 	}
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate 	for (p = dd; p != NULL; p = p->dd_next) {
8417c478bd9Sstevel@tonic-gate 		uint_t	rep_slice;
8427c478bd9Sstevel@tonic-gate 
8437c478bd9Sstevel@tonic-gate 		dn = p->dd_dnp;
8447c478bd9Sstevel@tonic-gate 
8457c478bd9Sstevel@tonic-gate 		/* Add the per side names to the local db */
8467c478bd9Sstevel@tonic-gate 		if (add_sidenamelist(dn, (side_t)i,  sr, ep)) {
8477c478bd9Sstevel@tonic-gate 				free_sr(sr);
8487c478bd9Sstevel@tonic-gate 				return;
8497c478bd9Sstevel@tonic-gate 		}
8507c478bd9Sstevel@tonic-gate 
8517c478bd9Sstevel@tonic-gate 		/* Create the drive record */
8527c478bd9Sstevel@tonic-gate 		(void) memset(&req, 0, sizeof (req));
8537c478bd9Sstevel@tonic-gate 		METAD_SETUP_DR(MD_DB_CREATE, 0);
8547c478bd9Sstevel@tonic-gate 		req.ur_size = sizeof (*dr);
8557c478bd9Sstevel@tonic-gate 		if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
8567c478bd9Sstevel@tonic-gate 			(void) mdstealerror(ep, &req.ur_mde);
8577c478bd9Sstevel@tonic-gate 			free_sr(sr);
8587c478bd9Sstevel@tonic-gate 			return;
8597c478bd9Sstevel@tonic-gate 		}
8607c478bd9Sstevel@tonic-gate 
8617c478bd9Sstevel@tonic-gate 		/* Fill in the drive record values */
8627c478bd9Sstevel@tonic-gate 		dr = Zalloc(sizeof (*dr));
8637c478bd9Sstevel@tonic-gate 		dr->dr_selfid = req.ur_recid;
8647c478bd9Sstevel@tonic-gate 		dr->dr_dbcnt = p->dd_dbcnt;
8657c478bd9Sstevel@tonic-gate 		dr->dr_dbsize = p->dd_dbsize;
8667c478bd9Sstevel@tonic-gate 		dr->dr_key = dn->side_names_key;
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate 		dr->dr_ctime = timestamp;
8697c478bd9Sstevel@tonic-gate 		dr->dr_genid = genid;
8707c478bd9Sstevel@tonic-gate 		dr->dr_revision = MD_DRIVE_RECORD_REVISION;
8717c478bd9Sstevel@tonic-gate 		dr->dr_flags = MD_DR_ADD;
8727c478bd9Sstevel@tonic-gate 
8737c478bd9Sstevel@tonic-gate 		/* Link the drive records and fill in in-core data */
8747c478bd9Sstevel@tonic-gate 		dr_cache_add(sr, dr);
8757c478bd9Sstevel@tonic-gate 
8767c478bd9Sstevel@tonic-gate 		dev = NODEV64;
8777c478bd9Sstevel@tonic-gate 		if ((meta_replicaslice(dn, &rep_slice, &xep) == 0) &&
8787c478bd9Sstevel@tonic-gate 		    ((np = metaslicename(dn, rep_slice, &xep)) != NULL))
8797c478bd9Sstevel@tonic-gate 			dev = np->dev;
8807c478bd9Sstevel@tonic-gate 		else
8817c478bd9Sstevel@tonic-gate 			mdclrerror(&xep);
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 		SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
8847c478bd9Sstevel@tonic-gate 		    MD_LOCAL_SET, dev);
8857c478bd9Sstevel@tonic-gate 		SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
8867c478bd9Sstevel@tonic-gate 		    sr->sr_setno, dev);
8877c478bd9Sstevel@tonic-gate 	}
8887c478bd9Sstevel@tonic-gate 
8897c478bd9Sstevel@tonic-gate 	/* Commit all the records atomically */
8907c478bd9Sstevel@tonic-gate 	commitset(sr, TRUE, ep);
8917c478bd9Sstevel@tonic-gate 	free_sr(sr);
8927c478bd9Sstevel@tonic-gate }
8937c478bd9Sstevel@tonic-gate 
8947c478bd9Sstevel@tonic-gate /*
8957c478bd9Sstevel@tonic-gate  * add 1 or more drive records to a set.
8967c478bd9Sstevel@tonic-gate  */
8977c478bd9Sstevel@tonic-gate bool_t
mdrpc_adddrvs_common(mdrpc_drives_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)8987c478bd9Sstevel@tonic-gate mdrpc_adddrvs_common(
8997c478bd9Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	*args,
9007c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
9017c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
9027c478bd9Sstevel@tonic-gate )
9037c478bd9Sstevel@tonic-gate {
9047c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
9057c478bd9Sstevel@tonic-gate 	int			err;
9067c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
9077c478bd9Sstevel@tonic-gate 
9087c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
9097c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
9107c478bd9Sstevel@tonic-gate 		return (FALSE);
9117c478bd9Sstevel@tonic-gate 	else if (err != 0)
9127c478bd9Sstevel@tonic-gate 		return (TRUE);
9137c478bd9Sstevel@tonic-gate 
9147c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
9157c478bd9Sstevel@tonic-gate 		return (TRUE);
9167c478bd9Sstevel@tonic-gate 
9177c478bd9Sstevel@tonic-gate 	/* doit */
9187c478bd9Sstevel@tonic-gate 	adddrvs(args->sp->setname, args->drivedescs, args->timestamp,
9197c478bd9Sstevel@tonic-gate 	    args->genid, ep);
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
9227c478bd9Sstevel@tonic-gate 
9237c478bd9Sstevel@tonic-gate 	return (TRUE);
9247c478bd9Sstevel@tonic-gate }
9257c478bd9Sstevel@tonic-gate 
9267c478bd9Sstevel@tonic-gate /*
9277c478bd9Sstevel@tonic-gate  * version 1 of the remote procedure. This procedure is called if the
9287c478bd9Sstevel@tonic-gate  * client is running in version 1. We first convert version 1 arguments
9297c478bd9Sstevel@tonic-gate  * into version 2 arguments and then call the common remote procedure.
9307c478bd9Sstevel@tonic-gate  */
9317c478bd9Sstevel@tonic-gate bool_t
mdrpc_adddrvs_1_svc(mdrpc_drives_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)9327c478bd9Sstevel@tonic-gate mdrpc_adddrvs_1_svc(
9337c478bd9Sstevel@tonic-gate 	mdrpc_drives_args	*args,
9347c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
9357c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
9367c478bd9Sstevel@tonic-gate )
9377c478bd9Sstevel@tonic-gate {
9387c478bd9Sstevel@tonic-gate 	bool_t			retval;
9397c478bd9Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	v2_args;
9407c478bd9Sstevel@tonic-gate 
9417c478bd9Sstevel@tonic-gate 	/* allocate memory */
9427c478bd9Sstevel@tonic-gate 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
9432a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
9447c478bd9Sstevel@tonic-gate 
9457c478bd9Sstevel@tonic-gate 	/* build args */
9467c478bd9Sstevel@tonic-gate 	v2_args.cl_sk = args->cl_sk;
9477c478bd9Sstevel@tonic-gate 	v2_args.sp = args->sp;
9487c478bd9Sstevel@tonic-gate 	/* convert v1 args to v2 (revision 1) args */
9497c478bd9Sstevel@tonic-gate 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
9507c478bd9Sstevel@tonic-gate 	v2_args.timestamp = args->timestamp;
9517c478bd9Sstevel@tonic-gate 	v2_args.genid = args->genid;
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate 	retval = mdrpc_adddrvs_common(&v2_args, res, rqstp);
9547c478bd9Sstevel@tonic-gate 
9557c478bd9Sstevel@tonic-gate 	free_newdrvdesc(v2_args.drivedescs);
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 	return (retval);
9587c478bd9Sstevel@tonic-gate }
9597c478bd9Sstevel@tonic-gate 
9607c478bd9Sstevel@tonic-gate bool_t
mdrpc_adddrvs_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)9617c478bd9Sstevel@tonic-gate mdrpc_adddrvs_2_svc(
9627c478bd9Sstevel@tonic-gate 	mdrpc_drives_2_args	*args,
9637c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
9647c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
9657c478bd9Sstevel@tonic-gate )
9667c478bd9Sstevel@tonic-gate {
9672a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
9687c478bd9Sstevel@tonic-gate 	switch (args->rev) {
9697c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
9707c478bd9Sstevel@tonic-gate 		return (mdrpc_adddrvs_common(
9717c478bd9Sstevel@tonic-gate 		    &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
9727c478bd9Sstevel@tonic-gate 	default:
9737c478bd9Sstevel@tonic-gate 		return (FALSE);
9747c478bd9Sstevel@tonic-gate 	}
9757c478bd9Sstevel@tonic-gate }
9767c478bd9Sstevel@tonic-gate 
977da833524Sjeanm /*
978da833524Sjeanm  * add 1 or more drive records to a set when importing.
979da833524Sjeanm  */
980da833524Sjeanm bool_t
mdrpc_imp_adddrvs_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)981da833524Sjeanm mdrpc_imp_adddrvs_2_svc(
982da833524Sjeanm 	mdrpc_drives_2_args	*args,
983da833524Sjeanm 	mdrpc_generic_res	*res,
984da833524Sjeanm 	struct svc_req		*rqstp		/* RPC stuff */
985da833524Sjeanm )
986da833524Sjeanm {
987da833524Sjeanm 	mdrpc_drives_2_args_r1	*v2_args;
988da833524Sjeanm 	md_error_t		*ep = &res->status;
989da833524Sjeanm 	int			err;
990da833524Sjeanm 	int			op_mode = W_OK;
991da833524Sjeanm 
9922a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
993da833524Sjeanm 	switch (args->rev) {
994da833524Sjeanm 	case MD_METAD_ARGS_REV_1:
995da833524Sjeanm 		v2_args = &args->mdrpc_drives_2_args_u.rev1;
996da833524Sjeanm 		if (v2_args == NULL) {
997da833524Sjeanm 			return (FALSE);
998da833524Sjeanm 		}
999da833524Sjeanm 		break;
1000da833524Sjeanm 	default:
1001da833524Sjeanm 		return (FALSE);
1002da833524Sjeanm 	}
1003da833524Sjeanm 
1004da833524Sjeanm 	/* setup, check permissions */
1005da833524Sjeanm 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
1006da833524Sjeanm 		return (FALSE);
1007da833524Sjeanm 	else if (err != 0)
1008da833524Sjeanm 		return (TRUE);
1009da833524Sjeanm 
1010da833524Sjeanm 	if (check_set_lock(op_mode, v2_args->cl_sk, ep))
1011da833524Sjeanm 		return (TRUE);
1012da833524Sjeanm 
1013da833524Sjeanm 	/* doit */
1014da833524Sjeanm 	imp_adddrvs(v2_args->sp->setname, v2_args->drivedescs,
1015da833524Sjeanm 	    v2_args->timestamp, v2_args->genid, ep);
1016da833524Sjeanm 
1017da833524Sjeanm 	err = svc_fini(ep);
1018da833524Sjeanm 
1019da833524Sjeanm 	return (TRUE);
1020da833524Sjeanm }
1021da833524Sjeanm 
10227c478bd9Sstevel@tonic-gate static void
addhosts(char * setname,int node_c,char ** node_v,int version,md_error_t * ep)10237c478bd9Sstevel@tonic-gate addhosts(
10247c478bd9Sstevel@tonic-gate 	char		*setname,
10257c478bd9Sstevel@tonic-gate 	int		node_c,
10267c478bd9Sstevel@tonic-gate 	char		**node_v,
10277c478bd9Sstevel@tonic-gate 	int		version,	/* RPC version of calling routine */
10287c478bd9Sstevel@tonic-gate 	md_error_t	*ep
10297c478bd9Sstevel@tonic-gate )
10307c478bd9Sstevel@tonic-gate {
10317c478bd9Sstevel@tonic-gate 	mddb_userreq_t		req;
10327c478bd9Sstevel@tonic-gate 	md_set_record		*sr;
10337c478bd9Sstevel@tonic-gate 	int			i, j;
10347c478bd9Sstevel@tonic-gate 	md_mnset_record		*mnsr;
10357c478bd9Sstevel@tonic-gate 	md_mnnode_record	*nr;
10367c478bd9Sstevel@tonic-gate 	mddb_set_node_params_t	snp;
10377c478bd9Sstevel@tonic-gate 	int			nodecnt;
10387c478bd9Sstevel@tonic-gate 	mndiskset_membershiplist_t *nl, *nl2;
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(setname, ep)) == NULL)
10417c478bd9Sstevel@tonic-gate 		return;
10427c478bd9Sstevel@tonic-gate 
10437c478bd9Sstevel@tonic-gate 	/* Do MN operation if rpc version supports it and if a MN set */
10447c478bd9Sstevel@tonic-gate 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
10457c478bd9Sstevel@tonic-gate 		mnsr = (md_mnset_record *)sr;
10467c478bd9Sstevel@tonic-gate 		/*
10477c478bd9Sstevel@tonic-gate 		 * Verify nodes are in membership list on THIS node.
10487c478bd9Sstevel@tonic-gate 		 * Initiating node has verified that nodes are in membership
10497c478bd9Sstevel@tonic-gate 		 * list on the initiating node.
10507c478bd9Sstevel@tonic-gate 		 * Get membershiplist from API routine.  If there's
10517c478bd9Sstevel@tonic-gate 		 * an error, fail to add hosts and pass back error.
10527c478bd9Sstevel@tonic-gate 		 */
10537c478bd9Sstevel@tonic-gate 		if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) {
10547c478bd9Sstevel@tonic-gate 			free_sr(sr);
10557c478bd9Sstevel@tonic-gate 			return;
10567c478bd9Sstevel@tonic-gate 		}
10577c478bd9Sstevel@tonic-gate 		/* Verify that all nodes are in member list */
10587c478bd9Sstevel@tonic-gate 		for (i = 0; i < node_c; i++) {
10597c478bd9Sstevel@tonic-gate 			/*
10607c478bd9Sstevel@tonic-gate 			 * If node in list isn't a member of the membership,
10617c478bd9Sstevel@tonic-gate 			 * just return error.
10627c478bd9Sstevel@tonic-gate 			 */
10637c478bd9Sstevel@tonic-gate 			if (meta_is_member(node_v[i], NULL, nl) == 0) {
10647c478bd9Sstevel@tonic-gate 				meta_free_nodelist(nl);
10657c478bd9Sstevel@tonic-gate 				(void) mddserror(ep, MDE_DS_NOTINMEMBERLIST,
10667c478bd9Sstevel@tonic-gate 				    sr->sr_setno, node_v[i], NULL, setname);
10677c478bd9Sstevel@tonic-gate 				free_sr(sr);
10687c478bd9Sstevel@tonic-gate 				return;
10697c478bd9Sstevel@tonic-gate 			}
10707c478bd9Sstevel@tonic-gate 		}
10717c478bd9Sstevel@tonic-gate 	}
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 	for (i = 0; i < node_c; i++) {
10747c478bd9Sstevel@tonic-gate 		/* Do MN operation if rpc version supports it and if a MN set */
10757c478bd9Sstevel@tonic-gate 		if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
10767c478bd9Sstevel@tonic-gate 			mnsr = (md_mnset_record *)sr;
10777c478bd9Sstevel@tonic-gate 			/* Create the node record */
10787c478bd9Sstevel@tonic-gate 			(void) memset(&req, 0, sizeof (req));
10797c478bd9Sstevel@tonic-gate 			METAD_SETUP_NR(MD_DB_CREATE, 0);
10807c478bd9Sstevel@tonic-gate 			req.ur_size = sizeof (*nr);
10817c478bd9Sstevel@tonic-gate 			if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL)
10827c478bd9Sstevel@tonic-gate 			    != 0) {
10837c478bd9Sstevel@tonic-gate 				(void) mdstealerror(ep, &req.ur_mde);
10847c478bd9Sstevel@tonic-gate 				meta_free_nodelist(nl);
10857c478bd9Sstevel@tonic-gate 				free_sr(sr);
10867c478bd9Sstevel@tonic-gate 				return;
10877c478bd9Sstevel@tonic-gate 			}
10887c478bd9Sstevel@tonic-gate 
10897c478bd9Sstevel@tonic-gate 			nr = Zalloc(sizeof (*nr));
10907c478bd9Sstevel@tonic-gate 			nr->nr_revision = MD_MNNODE_RECORD_REVISION;
10917c478bd9Sstevel@tonic-gate 			nr->nr_selfid = req.ur_recid;
10927c478bd9Sstevel@tonic-gate 			nr->nr_ctime = sr->sr_ctime;
10937c478bd9Sstevel@tonic-gate 			nr->nr_genid = sr->sr_genid;
10947c478bd9Sstevel@tonic-gate 			nr->nr_flags = MD_MN_NODE_ADD;
10957c478bd9Sstevel@tonic-gate 			nl2 = nl;
10967c478bd9Sstevel@tonic-gate 			while (nl2) {
10977c478bd9Sstevel@tonic-gate 				if (strcmp(nl2->msl_node_name, node_v[i])
10987c478bd9Sstevel@tonic-gate 				    == 0) {
10997c478bd9Sstevel@tonic-gate 					nr->nr_nodeid = nl2->msl_node_id;
11007c478bd9Sstevel@tonic-gate 					break;
11017c478bd9Sstevel@tonic-gate 				}
11027c478bd9Sstevel@tonic-gate 				nl2 = nl2->next;
11037c478bd9Sstevel@tonic-gate 			}
11047c478bd9Sstevel@tonic-gate 
11057c478bd9Sstevel@tonic-gate 			(void) strcpy(nr->nr_nodename, node_v[i]);
11067c478bd9Sstevel@tonic-gate 
11077c478bd9Sstevel@tonic-gate 			/*
11087c478bd9Sstevel@tonic-gate 			 * When a node is added to a MN diskset, set the
11097c478bd9Sstevel@tonic-gate 			 * nodeid of this node in the md_set structure
11107c478bd9Sstevel@tonic-gate 			 * in the kernel.
11117c478bd9Sstevel@tonic-gate 			 */
11127c478bd9Sstevel@tonic-gate 			if (strcmp(nr->nr_nodename, mynode()) == 0) {
11137c478bd9Sstevel@tonic-gate 				(void) memset(&snp, 0, sizeof (snp));
11147c478bd9Sstevel@tonic-gate 				snp.sn_nodeid = nr->nr_nodeid;
11157c478bd9Sstevel@tonic-gate 				snp.sn_setno = mnsr->sr_setno;
11167c478bd9Sstevel@tonic-gate 				if (metaioctl(MD_MN_SET_NODEID, &snp,
11177c478bd9Sstevel@tonic-gate 				    &snp.sn_mde, NULL) != 0) {
11187c478bd9Sstevel@tonic-gate 					(void) mdstealerror(ep, &snp.sn_mde);
11197c478bd9Sstevel@tonic-gate 					meta_free_nodelist(nl);
11207c478bd9Sstevel@tonic-gate 					free_sr(sr);
11217c478bd9Sstevel@tonic-gate 					return;
11227c478bd9Sstevel@tonic-gate 				}
11237c478bd9Sstevel@tonic-gate 			}
11247c478bd9Sstevel@tonic-gate 
11257c478bd9Sstevel@tonic-gate 			/* Link the node records and fill in in-core data */
11267c478bd9Sstevel@tonic-gate 			mnnr_cache_add(mnsr, nr);
11277c478bd9Sstevel@tonic-gate 
11287c478bd9Sstevel@tonic-gate 			SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST,
11297c478bd9Sstevel@tonic-gate 			    mnsr->sr_setno, nr->nr_nodeid);
11307c478bd9Sstevel@tonic-gate 		} else {
11317c478bd9Sstevel@tonic-gate 			for (j = 0; j < MD_MAXSIDES; j++) {
11327c478bd9Sstevel@tonic-gate 				if (sr->sr_nodes[j][0] != '\0')
11337c478bd9Sstevel@tonic-gate 					continue;
11347c478bd9Sstevel@tonic-gate 				(void) strcpy(sr->sr_nodes[j], node_v[i]);
11357c478bd9Sstevel@tonic-gate 				SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD,
11367c478bd9Sstevel@tonic-gate 				    SVM_TAG_HOST, sr->sr_setno, j);
11377c478bd9Sstevel@tonic-gate 				break;
11387c478bd9Sstevel@tonic-gate 			}
11397c478bd9Sstevel@tonic-gate 		}
11407c478bd9Sstevel@tonic-gate 	}
11417c478bd9Sstevel@tonic-gate 	/* Do MN operation if rpc version supports it and if a MN set */
11427c478bd9Sstevel@tonic-gate 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
11437c478bd9Sstevel@tonic-gate 		meta_free_nodelist(nl);
11447c478bd9Sstevel@tonic-gate 	}
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate 	(void) memset(&req, '\0', sizeof (req));
11477c478bd9Sstevel@tonic-gate 
11487c478bd9Sstevel@tonic-gate 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
11497c478bd9Sstevel@tonic-gate 
11507c478bd9Sstevel@tonic-gate 	/* Do MN operation if rpc version supports it and if a MN set */
11517c478bd9Sstevel@tonic-gate 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
11527c478bd9Sstevel@tonic-gate 		req.ur_size = sizeof (*mnsr);
11537c478bd9Sstevel@tonic-gate 	} else {
11547c478bd9Sstevel@tonic-gate 		req.ur_size = sizeof (*sr);
11557c478bd9Sstevel@tonic-gate 	}
11567c478bd9Sstevel@tonic-gate 	req.ur_data = (uintptr_t)sr;
11577c478bd9Sstevel@tonic-gate 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
11587c478bd9Sstevel@tonic-gate 		(void) mdstealerror(ep, &req.ur_mde);
11597c478bd9Sstevel@tonic-gate 		free_sr(sr);
11607c478bd9Sstevel@tonic-gate 		return;
11617c478bd9Sstevel@tonic-gate 	}
11627c478bd9Sstevel@tonic-gate 
11637c478bd9Sstevel@tonic-gate 	commitset(sr, TRUE, ep);
11647c478bd9Sstevel@tonic-gate 
11657c478bd9Sstevel@tonic-gate 	free_sr(sr);
11667c478bd9Sstevel@tonic-gate }
11677c478bd9Sstevel@tonic-gate 
11687c478bd9Sstevel@tonic-gate /*
11697c478bd9Sstevel@tonic-gate  * add 1 or more hosts to a set.
11707c478bd9Sstevel@tonic-gate  */
11717c478bd9Sstevel@tonic-gate bool_t
mdrpc_addhosts_common(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)11727c478bd9Sstevel@tonic-gate mdrpc_addhosts_common(
11737c478bd9Sstevel@tonic-gate 	mdrpc_host_args		*args,
11747c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
11757c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp,		/* RPC stuff */
11767c478bd9Sstevel@tonic-gate 	int			version		/* RPC version */
11777c478bd9Sstevel@tonic-gate )
11787c478bd9Sstevel@tonic-gate {
11797c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
11807c478bd9Sstevel@tonic-gate 	int			err;
11817c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
11827c478bd9Sstevel@tonic-gate 
11837c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
11847c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
11857c478bd9Sstevel@tonic-gate 		return (FALSE);
11867c478bd9Sstevel@tonic-gate 	else if (err != 0)
11877c478bd9Sstevel@tonic-gate 		return (TRUE);
11887c478bd9Sstevel@tonic-gate 
11897c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
11907c478bd9Sstevel@tonic-gate 		return (TRUE);
11917c478bd9Sstevel@tonic-gate 
11927c478bd9Sstevel@tonic-gate 	/* doit */
11937c478bd9Sstevel@tonic-gate 	addhosts(args->sp->setname, args->hosts.hosts_len,
11947c478bd9Sstevel@tonic-gate 	    args->hosts.hosts_val, version, ep);
11957c478bd9Sstevel@tonic-gate 
11967c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
11977c478bd9Sstevel@tonic-gate 
11987c478bd9Sstevel@tonic-gate 	return (TRUE);
11997c478bd9Sstevel@tonic-gate }
12007c478bd9Sstevel@tonic-gate 
12017c478bd9Sstevel@tonic-gate bool_t
mdrpc_addhosts_1_svc(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)12027c478bd9Sstevel@tonic-gate mdrpc_addhosts_1_svc(
12037c478bd9Sstevel@tonic-gate 	mdrpc_host_args		*args,
12047c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
12057c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
12067c478bd9Sstevel@tonic-gate )
12077c478bd9Sstevel@tonic-gate {
12087c478bd9Sstevel@tonic-gate 	/* Pass RPC version (METAD_VERSION) to common routine */
12092a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
12107c478bd9Sstevel@tonic-gate 	return (mdrpc_addhosts_common(args, res, rqstp, METAD_VERSION));
12117c478bd9Sstevel@tonic-gate }
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate bool_t
mdrpc_addhosts_2_svc(mdrpc_host_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)12147c478bd9Sstevel@tonic-gate mdrpc_addhosts_2_svc(
12157c478bd9Sstevel@tonic-gate 	mdrpc_host_2_args	*args,
12167c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
12177c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
12187c478bd9Sstevel@tonic-gate )
12197c478bd9Sstevel@tonic-gate {
12202a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
12217c478bd9Sstevel@tonic-gate 	switch (args->rev) {
12227c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
12237c478bd9Sstevel@tonic-gate 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
12247c478bd9Sstevel@tonic-gate 		return (mdrpc_addhosts_common(
12257c478bd9Sstevel@tonic-gate 		    &args->mdrpc_host_2_args_u.rev1, res,
12267c478bd9Sstevel@tonic-gate 		    rqstp, METAD_VERSION_DEVID));
12277c478bd9Sstevel@tonic-gate 	default:
12287c478bd9Sstevel@tonic-gate 		return (FALSE);
12297c478bd9Sstevel@tonic-gate 	}
12307c478bd9Sstevel@tonic-gate }
12317c478bd9Sstevel@tonic-gate 
12327c478bd9Sstevel@tonic-gate static void
createset(mdsetname_t * sp,md_node_nm_arr_t nodes,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)12337c478bd9Sstevel@tonic-gate createset(
12347c478bd9Sstevel@tonic-gate 	mdsetname_t		*sp,
12357c478bd9Sstevel@tonic-gate 	md_node_nm_arr_t	nodes,
12367c478bd9Sstevel@tonic-gate 	md_timeval32_t		timestamp,
12377c478bd9Sstevel@tonic-gate 	ulong_t			genid,
12387c478bd9Sstevel@tonic-gate 	md_error_t		*ep
12397c478bd9Sstevel@tonic-gate )
12407c478bd9Sstevel@tonic-gate {
12417c478bd9Sstevel@tonic-gate 	mddb_userreq_t		req;
12427c478bd9Sstevel@tonic-gate 	md_set_record		*sr;
12437c478bd9Sstevel@tonic-gate 	int			i;
12447c478bd9Sstevel@tonic-gate 
12457c478bd9Sstevel@tonic-gate 	(void) memset(&req, 0, sizeof (req));
12467c478bd9Sstevel@tonic-gate 	METAD_SETUP_SR(MD_DB_CREATE, 0);
12477c478bd9Sstevel@tonic-gate 	req.ur_size = sizeof (*sr);
12487c478bd9Sstevel@tonic-gate 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
12497c478bd9Sstevel@tonic-gate 		(void) mdstealerror(ep, &req.ur_mde);
12507c478bd9Sstevel@tonic-gate 		return;
12517c478bd9Sstevel@tonic-gate 	}
12527c478bd9Sstevel@tonic-gate 
12537c478bd9Sstevel@tonic-gate 	sr = Zalloc(sizeof (*sr));
12547c478bd9Sstevel@tonic-gate 
12557c478bd9Sstevel@tonic-gate 	sr->sr_selfid = req.ur_recid;
12567c478bd9Sstevel@tonic-gate 	sr->sr_setno = sp->setno;
12577c478bd9Sstevel@tonic-gate 	(void) strcpy(sr->sr_setname, sp->setname);
12587c478bd9Sstevel@tonic-gate 
12597c478bd9Sstevel@tonic-gate 	SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno,
12607c478bd9Sstevel@tonic-gate 	    NODEV64);
12617c478bd9Sstevel@tonic-gate 
12627c478bd9Sstevel@tonic-gate 	(void) meta_smf_enable(META_SMF_DISKSET, NULL);
12637c478bd9Sstevel@tonic-gate 
12647c478bd9Sstevel@tonic-gate 	for (i = 0; i < MD_MAXSIDES; i++) {
12657c478bd9Sstevel@tonic-gate 		(void) strcpy(sr->sr_nodes[i], nodes[i]);
12667c478bd9Sstevel@tonic-gate 		/* Skip empty slots */
12677c478bd9Sstevel@tonic-gate 		if (sr->sr_nodes[i][0] == '\0')
12687c478bd9Sstevel@tonic-gate 			continue;
12697c478bd9Sstevel@tonic-gate 		SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno,
12707c478bd9Sstevel@tonic-gate 		    i);
12717c478bd9Sstevel@tonic-gate 	}
12727c478bd9Sstevel@tonic-gate 
12737c478bd9Sstevel@tonic-gate 	sr->sr_ctime = timestamp;
12747c478bd9Sstevel@tonic-gate 	sr->sr_genid = genid;
12757c478bd9Sstevel@tonic-gate 	sr->sr_revision = MD_SET_RECORD_REVISION;
12767c478bd9Sstevel@tonic-gate 	sr->sr_flags |= MD_SR_ADD;
12777c478bd9Sstevel@tonic-gate 
12787c478bd9Sstevel@tonic-gate 	sr->sr_mhiargs = defmhiargs;
12797c478bd9Sstevel@tonic-gate 
12807c478bd9Sstevel@tonic-gate 	sr_cache_add(sr);
12817c478bd9Sstevel@tonic-gate 
12827c478bd9Sstevel@tonic-gate 	commitset(sr, TRUE, ep);
12837c478bd9Sstevel@tonic-gate }
12847c478bd9Sstevel@tonic-gate 
12857c478bd9Sstevel@tonic-gate static void
mncreateset(mdsetname_t * sp,md_mnnode_desc * nodelist,md_timeval32_t timestamp,ulong_t genid,md_node_nm_t master_nodenm,int master_nodeid,md_error_t * ep)12867c478bd9Sstevel@tonic-gate mncreateset(
12877c478bd9Sstevel@tonic-gate 	mdsetname_t		*sp,
12887c478bd9Sstevel@tonic-gate 	md_mnnode_desc		*nodelist,
12897c478bd9Sstevel@tonic-gate 	md_timeval32_t		timestamp,
12907c478bd9Sstevel@tonic-gate 	ulong_t			genid,
12917c478bd9Sstevel@tonic-gate 	md_node_nm_t		master_nodenm,
12927c478bd9Sstevel@tonic-gate 	int			master_nodeid,
12937c478bd9Sstevel@tonic-gate 	md_error_t		*ep
12947c478bd9Sstevel@tonic-gate )
12957c478bd9Sstevel@tonic-gate {
12967c478bd9Sstevel@tonic-gate 	mddb_userreq_t			req;
12977c478bd9Sstevel@tonic-gate 	md_mnset_record			*mnsr;
12987c478bd9Sstevel@tonic-gate 	md_mnnode_record		*nr;
12997c478bd9Sstevel@tonic-gate 	md_mnnode_desc			*nd;
13007c478bd9Sstevel@tonic-gate 	mddb_set_node_params_t		snp;
13017c478bd9Sstevel@tonic-gate 	int				nodecnt;
13027c478bd9Sstevel@tonic-gate 	mndiskset_membershiplist_t	*nl;
13037c478bd9Sstevel@tonic-gate 
13047c478bd9Sstevel@tonic-gate 	/*
13057c478bd9Sstevel@tonic-gate 	 * Validate that nodes in set being created are in the
13067c478bd9Sstevel@tonic-gate 	 * membership list on THIS node.
13077c478bd9Sstevel@tonic-gate 	 * Initiating node has verified that nodes are in membership
13087c478bd9Sstevel@tonic-gate 	 * list on the initiating node.
13097c478bd9Sstevel@tonic-gate 	 * Get membershiplist from API routine.  If there's
13107c478bd9Sstevel@tonic-gate 	 * an error, fail to add set and pass back error.
13117c478bd9Sstevel@tonic-gate 	 */
13127c478bd9Sstevel@tonic-gate 	if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) {
13137c478bd9Sstevel@tonic-gate 		return;
13147c478bd9Sstevel@tonic-gate 	}
13157c478bd9Sstevel@tonic-gate 	/* Verify that all nodes are in member list */
13167c478bd9Sstevel@tonic-gate 	nd = nodelist;
13177c478bd9Sstevel@tonic-gate 	while (nd) {
13187c478bd9Sstevel@tonic-gate 		/*
13197c478bd9Sstevel@tonic-gate 		 * If node in list isn't a member of the membership,
13207c478bd9Sstevel@tonic-gate 		 * just return error.
13217c478bd9Sstevel@tonic-gate 		 */
13227c478bd9Sstevel@tonic-gate 		if (meta_is_member(nd->nd_nodename, 0, nl) == 0) {
13237c478bd9Sstevel@tonic-gate 			meta_free_nodelist(nl);
13247c478bd9Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_NOTINMEMBERLIST,
13257c478bd9Sstevel@tonic-gate 			    sp->setno, nd->nd_nodename, NULL, sp->setname);
13267c478bd9Sstevel@tonic-gate 			return;
13277c478bd9Sstevel@tonic-gate 		}
13287c478bd9Sstevel@tonic-gate 		nd = nd->nd_next;
13297c478bd9Sstevel@tonic-gate 	}
13307c478bd9Sstevel@tonic-gate 	meta_free_nodelist(nl);
13317c478bd9Sstevel@tonic-gate 
13327c478bd9Sstevel@tonic-gate 	(void) memset(&req, 0, sizeof (req));
13337c478bd9Sstevel@tonic-gate 	METAD_SETUP_SR(MD_DB_CREATE, 0);
13347c478bd9Sstevel@tonic-gate 	req.ur_size = sizeof (*mnsr);
13357c478bd9Sstevel@tonic-gate 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
13367c478bd9Sstevel@tonic-gate 		(void) mdstealerror(ep, &req.ur_mde);
13377c478bd9Sstevel@tonic-gate 		return;
13387c478bd9Sstevel@tonic-gate 	}
13397c478bd9Sstevel@tonic-gate 
13407c478bd9Sstevel@tonic-gate 	mnsr = Zalloc(sizeof (*mnsr));
13417c478bd9Sstevel@tonic-gate 	mnsr->sr_selfid = req.ur_recid;
13427c478bd9Sstevel@tonic-gate 	mnsr->sr_setno = sp->setno;
13437c478bd9Sstevel@tonic-gate 	(void) strlcpy(mnsr->sr_setname, sp->setname, MD_MAX_SETNAME);
13447c478bd9Sstevel@tonic-gate 
13457c478bd9Sstevel@tonic-gate 	SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno,
13467c478bd9Sstevel@tonic-gate 	    NODEV64);
13477c478bd9Sstevel@tonic-gate 
13487c478bd9Sstevel@tonic-gate 	(void) meta_smf_enable(META_SMF_DISKSET | META_SMF_MN_DISKSET, NULL);
13497c478bd9Sstevel@tonic-gate 
13507c478bd9Sstevel@tonic-gate 	nd = nodelist;
13517c478bd9Sstevel@tonic-gate 	while (nd) {
13527c478bd9Sstevel@tonic-gate 		/* Create the node record */
13537c478bd9Sstevel@tonic-gate 		(void) memset(&req, 0, sizeof (req));
13547c478bd9Sstevel@tonic-gate 		METAD_SETUP_NR(MD_DB_CREATE, 0);
13557c478bd9Sstevel@tonic-gate 		req.ur_size = sizeof (*nr);
13567c478bd9Sstevel@tonic-gate 		if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
13577c478bd9Sstevel@tonic-gate 			/* Frees mnsr and any alloc'd node records */
13587c478bd9Sstevel@tonic-gate 			free_sr((struct md_set_record *)mnsr);
13597c478bd9Sstevel@tonic-gate 			(void) mdstealerror(ep, &req.ur_mde);
13607c478bd9Sstevel@tonic-gate 			return;
13617c478bd9Sstevel@tonic-gate 		}
13627c478bd9Sstevel@tonic-gate 
13637c478bd9Sstevel@tonic-gate 		nr = Zalloc(sizeof (*nr));
13647c478bd9Sstevel@tonic-gate 		nr->nr_revision = MD_MNNODE_RECORD_REVISION;
13657c478bd9Sstevel@tonic-gate 		nr->nr_selfid = req.ur_recid;
13667c478bd9Sstevel@tonic-gate 		nr->nr_ctime = timestamp;
13677c478bd9Sstevel@tonic-gate 		nr->nr_genid = genid;
13687c478bd9Sstevel@tonic-gate 		nr->nr_nodeid = nd->nd_nodeid;
13697c478bd9Sstevel@tonic-gate 		nr->nr_flags = nd->nd_flags;
13707c478bd9Sstevel@tonic-gate 		(void) strlcpy(nr->nr_nodename, nd->nd_nodename,
13717c478bd9Sstevel@tonic-gate 		    MD_MAX_NODENAME);
13727c478bd9Sstevel@tonic-gate 
13737c478bd9Sstevel@tonic-gate 		/* Link the node records and fill in in-core data */
13747c478bd9Sstevel@tonic-gate 		mnnr_cache_add(mnsr, nr);
13757c478bd9Sstevel@tonic-gate 
13767c478bd9Sstevel@tonic-gate 		SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno,
13777c478bd9Sstevel@tonic-gate 		    nr->nr_nodeid);
13787c478bd9Sstevel@tonic-gate 
13797c478bd9Sstevel@tonic-gate 		nd = nd->nd_next;
13807c478bd9Sstevel@tonic-gate 	}
13817c478bd9Sstevel@tonic-gate 
13827c478bd9Sstevel@tonic-gate 	/*
13837c478bd9Sstevel@tonic-gate 	 * For backward compatibility, fill in mynode name
13847c478bd9Sstevel@tonic-gate 	 * as the only name in the sr_nodes array.  This
13857c478bd9Sstevel@tonic-gate 	 * allows the pre-MNdiskset code to see that there
13867c478bd9Sstevel@tonic-gate 	 * is a node in this diskset.  This will keep the
13877c478bd9Sstevel@tonic-gate 	 * pre-MNdiskset code from removing this set.
13887c478bd9Sstevel@tonic-gate 	 */
13897c478bd9Sstevel@tonic-gate 	(void) strlcpy(mnsr->sr_nodes_bw_compat[0], mynode(), MD_MAX_NODENAME);
13907c478bd9Sstevel@tonic-gate 
13917c478bd9Sstevel@tonic-gate 	mnsr->sr_ctime = timestamp;
13927c478bd9Sstevel@tonic-gate 	mnsr->sr_genid = genid;
13937c478bd9Sstevel@tonic-gate 	mnsr->sr_revision = MD_SET_RECORD_REVISION;
13947c478bd9Sstevel@tonic-gate 	mnsr->sr_flags |= MD_SR_ADD;
13957c478bd9Sstevel@tonic-gate 
13967c478bd9Sstevel@tonic-gate 	mnsr->sr_flags |= MD_SR_MN;
1397*80148899SSurya Prakki 	(void) strcpy(mnsr->sr_master_nodenm, master_nodenm);
13987c478bd9Sstevel@tonic-gate 	mnsr->sr_master_nodeid = master_nodeid;
13997c478bd9Sstevel@tonic-gate 
14007c478bd9Sstevel@tonic-gate 	mnsr->sr_mhiargs = defmhiargs;
14017c478bd9Sstevel@tonic-gate 
14027c478bd9Sstevel@tonic-gate 	sr_cache_add((struct md_set_record *)mnsr);
14037c478bd9Sstevel@tonic-gate 
14047c478bd9Sstevel@tonic-gate 	commitset((struct md_set_record *)mnsr, TRUE, ep);
14057c478bd9Sstevel@tonic-gate 
14067c478bd9Sstevel@tonic-gate 	/*
14077c478bd9Sstevel@tonic-gate 	 * When a set is created for the first time, the nodelist
14087c478bd9Sstevel@tonic-gate 	 * will contain this node.
14097c478bd9Sstevel@tonic-gate 	 * When a node is just being added to a set, the nodelist
14107c478bd9Sstevel@tonic-gate 	 * will not contain this node.  This node is added to the
14117c478bd9Sstevel@tonic-gate 	 * set structure with a later call to addhosts.
14127c478bd9Sstevel@tonic-gate 	 *
14137c478bd9Sstevel@tonic-gate 	 * So, if the nodelist contains an entry for this node
14147c478bd9Sstevel@tonic-gate 	 * then set the nodeid of this node in the md_set kernel
14157c478bd9Sstevel@tonic-gate 	 * data structure.
14167c478bd9Sstevel@tonic-gate 	 */
14177c478bd9Sstevel@tonic-gate 	nd = nodelist;
14187c478bd9Sstevel@tonic-gate 	while (nd) {
14197c478bd9Sstevel@tonic-gate 		if (strcmp(nd->nd_nodename, mynode()) == 0) {
14207c478bd9Sstevel@tonic-gate 			break;
14217c478bd9Sstevel@tonic-gate 		}
14227c478bd9Sstevel@tonic-gate 		nd = nd->nd_next;
14237c478bd9Sstevel@tonic-gate 	}
14247c478bd9Sstevel@tonic-gate 	if (nd) {
14257c478bd9Sstevel@tonic-gate 		(void) memset(&snp, 0, sizeof (snp));
14267c478bd9Sstevel@tonic-gate 		snp.sn_nodeid = nd->nd_nodeid;
14277c478bd9Sstevel@tonic-gate 		snp.sn_setno = sp->setno;
14287c478bd9Sstevel@tonic-gate 		if (metaioctl(MD_MN_SET_NODEID, &snp, &snp.sn_mde, NULL) != 0) {
14297c478bd9Sstevel@tonic-gate 			(void) mdstealerror(ep, &snp.sn_mde);
14307c478bd9Sstevel@tonic-gate 			return;
14317c478bd9Sstevel@tonic-gate 		}
14327c478bd9Sstevel@tonic-gate 	}
14337c478bd9Sstevel@tonic-gate }
14347c478bd9Sstevel@tonic-gate 
14357c478bd9Sstevel@tonic-gate /*
14367c478bd9Sstevel@tonic-gate  * create a set on a host
14377c478bd9Sstevel@tonic-gate  */
14387c478bd9Sstevel@tonic-gate bool_t
mdrpc_createset_common(mdrpc_createset_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)14397c478bd9Sstevel@tonic-gate mdrpc_createset_common(
14407c478bd9Sstevel@tonic-gate 	mdrpc_createset_args	*args,
14417c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
14427c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
14437c478bd9Sstevel@tonic-gate )
14447c478bd9Sstevel@tonic-gate {
14457c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
14467c478bd9Sstevel@tonic-gate 	char			stringbuf1[MAXPATHLEN];
14477c478bd9Sstevel@tonic-gate 	char			stringbuf2[MAXPATHLEN];
14487c478bd9Sstevel@tonic-gate 	int			err;
14497c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
14507c478bd9Sstevel@tonic-gate 
14517c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
14527c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
14537c478bd9Sstevel@tonic-gate 		return (FALSE);
14547c478bd9Sstevel@tonic-gate 	else if (err != 0)
14557c478bd9Sstevel@tonic-gate 		return (TRUE);
14567c478bd9Sstevel@tonic-gate 
14577c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
14587c478bd9Sstevel@tonic-gate 		return (TRUE);
14597c478bd9Sstevel@tonic-gate 
14607c478bd9Sstevel@tonic-gate 	/* create the arguments for the symlink() and unlink() calls */
14617c478bd9Sstevel@tonic-gate 	(void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s",
14627c478bd9Sstevel@tonic-gate 	    args->sp->setname);
14637c478bd9Sstevel@tonic-gate 	(void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d",
14647c478bd9Sstevel@tonic-gate 	    args->sp->setno);
14657c478bd9Sstevel@tonic-gate 
14667c478bd9Sstevel@tonic-gate 	/*
14677c478bd9Sstevel@tonic-gate 	 * Since we already verified that the setname was OK, make sure to
14687c478bd9Sstevel@tonic-gate 	 * cleanup before proceeding.
14697c478bd9Sstevel@tonic-gate 	 */
14707c478bd9Sstevel@tonic-gate 	if (unlink(stringbuf2) == -1) {
14717c478bd9Sstevel@tonic-gate 		if (errno != ENOENT) {
14727c478bd9Sstevel@tonic-gate 			(void) mdsyserror(ep, errno, stringbuf2);
14737c478bd9Sstevel@tonic-gate 			return (TRUE);
14747c478bd9Sstevel@tonic-gate 		}
14757c478bd9Sstevel@tonic-gate 	}
14767c478bd9Sstevel@tonic-gate 
14777c478bd9Sstevel@tonic-gate 	/* create the set */
14787c478bd9Sstevel@tonic-gate 	createset(args->sp, args->nodes, args->timestamp, args->genid, ep);
14797c478bd9Sstevel@tonic-gate 
14807c478bd9Sstevel@tonic-gate 	if (! mdisok(ep))
14817c478bd9Sstevel@tonic-gate 		return (TRUE);
14827c478bd9Sstevel@tonic-gate 
1483ee8af371Sachimm 	/* create the symlink */
1484ee8af371Sachimm 	if (symlink(stringbuf1, stringbuf2) == -1)
1485ee8af371Sachimm 		(void) mdsyserror(ep, errno, stringbuf2);
1486ee8af371Sachimm 
14877c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
14887c478bd9Sstevel@tonic-gate 
14897c478bd9Sstevel@tonic-gate 	return (TRUE);
14907c478bd9Sstevel@tonic-gate }
14917c478bd9Sstevel@tonic-gate 
14927c478bd9Sstevel@tonic-gate bool_t
mdrpc_createset_1_svc(mdrpc_createset_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)14937c478bd9Sstevel@tonic-gate mdrpc_createset_1_svc(
14947c478bd9Sstevel@tonic-gate 	mdrpc_createset_args	*args,
14957c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
14967c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
14977c478bd9Sstevel@tonic-gate )
14987c478bd9Sstevel@tonic-gate {
14992a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
15007c478bd9Sstevel@tonic-gate 	return (mdrpc_createset_common(args, res, rqstp));
15017c478bd9Sstevel@tonic-gate }
15027c478bd9Sstevel@tonic-gate 
15037c478bd9Sstevel@tonic-gate bool_t
mdrpc_createset_2_svc(mdrpc_createset_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)15047c478bd9Sstevel@tonic-gate mdrpc_createset_2_svc(
15057c478bd9Sstevel@tonic-gate 	mdrpc_createset_2_args	*args,
15067c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
15077c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
15087c478bd9Sstevel@tonic-gate )
15097c478bd9Sstevel@tonic-gate {
15102a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
15117c478bd9Sstevel@tonic-gate 	switch (args->rev) {
15127c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
15137c478bd9Sstevel@tonic-gate 		return (mdrpc_createset_common(
15147c478bd9Sstevel@tonic-gate 		    &args->mdrpc_createset_2_args_u.rev1, res, rqstp));
15157c478bd9Sstevel@tonic-gate 	default:
15167c478bd9Sstevel@tonic-gate 		return (FALSE);
15177c478bd9Sstevel@tonic-gate 	}
15187c478bd9Sstevel@tonic-gate }
15197c478bd9Sstevel@tonic-gate 
15207c478bd9Sstevel@tonic-gate bool_t
mdrpc_mncreateset_common(mdrpc_mncreateset_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)15217c478bd9Sstevel@tonic-gate mdrpc_mncreateset_common(
15227c478bd9Sstevel@tonic-gate 	mdrpc_mncreateset_args	*args,
15237c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
15247c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
15257c478bd9Sstevel@tonic-gate )
15267c478bd9Sstevel@tonic-gate {
15277c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
15287c478bd9Sstevel@tonic-gate 	char			stringbuf1[MAXPATHLEN];
15297c478bd9Sstevel@tonic-gate 	char			stringbuf2[MAXPATHLEN];
15307c478bd9Sstevel@tonic-gate 	int			err;
15317c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
15327c478bd9Sstevel@tonic-gate 
15337c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
15347c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
15357c478bd9Sstevel@tonic-gate 		return (FALSE);
15367c478bd9Sstevel@tonic-gate 	else if (err != 0)
15377c478bd9Sstevel@tonic-gate 		return (TRUE);
15387c478bd9Sstevel@tonic-gate 
15397c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
15407c478bd9Sstevel@tonic-gate 		return (TRUE);
15417c478bd9Sstevel@tonic-gate 
15427c478bd9Sstevel@tonic-gate 	/* create the arguments for the symlink() and unlink() calls */
15437c478bd9Sstevel@tonic-gate 	(void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s",
15447c478bd9Sstevel@tonic-gate 	    args->sp->setname);
15457c478bd9Sstevel@tonic-gate 	(void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d",
15467c478bd9Sstevel@tonic-gate 	    args->sp->setno);
15477c478bd9Sstevel@tonic-gate 
15487c478bd9Sstevel@tonic-gate 	/*
15497c478bd9Sstevel@tonic-gate 	 * Since we already verified that the setname was OK, make sure to
15507c478bd9Sstevel@tonic-gate 	 * cleanup before proceeding.
15517c478bd9Sstevel@tonic-gate 	 */
15527c478bd9Sstevel@tonic-gate 	if (unlink(stringbuf2) == -1) {
15537c478bd9Sstevel@tonic-gate 		if (errno != ENOENT) {
15547c478bd9Sstevel@tonic-gate 			(void) mdsyserror(ep, errno, stringbuf2);
15557c478bd9Sstevel@tonic-gate 			return (TRUE);
15567c478bd9Sstevel@tonic-gate 		}
15577c478bd9Sstevel@tonic-gate 	}
15587c478bd9Sstevel@tonic-gate 
15597c478bd9Sstevel@tonic-gate 	/* create the set */
15607c478bd9Sstevel@tonic-gate 	mncreateset(args->sp, args->nodelist, args->timestamp, args->genid,
15617c478bd9Sstevel@tonic-gate 	    args->master_nodenm, args->master_nodeid, ep);
15627c478bd9Sstevel@tonic-gate 
15637c478bd9Sstevel@tonic-gate 	if (! mdisok(ep)) {
15647c478bd9Sstevel@tonic-gate 		return (TRUE);
15657c478bd9Sstevel@tonic-gate 	}
1566ee8af371Sachimm 
1567ee8af371Sachimm 	/* create the symlink */
1568ee8af371Sachimm 	if (symlink(stringbuf1, stringbuf2) == -1)
1569ee8af371Sachimm 		(void) mdsyserror(ep, errno, stringbuf2);
1570ee8af371Sachimm 
15717c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
15727c478bd9Sstevel@tonic-gate 
15737c478bd9Sstevel@tonic-gate 	return (TRUE);
15747c478bd9Sstevel@tonic-gate }
15757c478bd9Sstevel@tonic-gate 
15767c478bd9Sstevel@tonic-gate bool_t
mdrpc_mncreateset_2_svc(mdrpc_mncreateset_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)15777c478bd9Sstevel@tonic-gate mdrpc_mncreateset_2_svc(
15787c478bd9Sstevel@tonic-gate 	mdrpc_mncreateset_2_args	*args,
15797c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
15807c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
15817c478bd9Sstevel@tonic-gate )
15827c478bd9Sstevel@tonic-gate {
15832a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
15847c478bd9Sstevel@tonic-gate 	switch (args->rev) {
15857c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
15867c478bd9Sstevel@tonic-gate 		return (mdrpc_mncreateset_common(
15877c478bd9Sstevel@tonic-gate 		    &args->mdrpc_mncreateset_2_args_u.rev1, res, rqstp));
15887c478bd9Sstevel@tonic-gate 	default:
15897c478bd9Sstevel@tonic-gate 		return (FALSE);
15907c478bd9Sstevel@tonic-gate 	}
15917c478bd9Sstevel@tonic-gate }
15927c478bd9Sstevel@tonic-gate 
15937c478bd9Sstevel@tonic-gate static void
del_drv_sidenms(mdsetname_t * sp,int version,md_error_t * ep)15947c478bd9Sstevel@tonic-gate del_drv_sidenms(
15957c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
15967c478bd9Sstevel@tonic-gate 	int		version,	/* RPC version of calling routine */
15977c478bd9Sstevel@tonic-gate 	md_error_t	*ep
15987c478bd9Sstevel@tonic-gate )
15997c478bd9Sstevel@tonic-gate {
16007c478bd9Sstevel@tonic-gate 	md_set_record	*sr;
16017c478bd9Sstevel@tonic-gate 	md_drive_desc	*dd, *p;
16027c478bd9Sstevel@tonic-gate 	mddrivename_t	*dn;
16037c478bd9Sstevel@tonic-gate 	mdsetname_t	*local_sp;
16047c478bd9Sstevel@tonic-gate 	int		i;
16057c478bd9Sstevel@tonic-gate 	int		rb_mode = 0;
16067c478bd9Sstevel@tonic-gate 
16077c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
16087c478bd9Sstevel@tonic-gate 		return;
16097c478bd9Sstevel@tonic-gate 
16107c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
16117c478bd9Sstevel@tonic-gate 		return;
16127c478bd9Sstevel@tonic-gate 
16137c478bd9Sstevel@tonic-gate 	/* Do MN operation if rpc version supports it and if a MN set */
16147c478bd9Sstevel@tonic-gate 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
16157c478bd9Sstevel@tonic-gate 		/*
16167c478bd9Sstevel@tonic-gate 		 * In the multi-node diskset, there are no diskset
16177c478bd9Sstevel@tonic-gate 		 * entries in the local set for other nodes, so there's
16187c478bd9Sstevel@tonic-gate 		 * nothing to do.
16197c478bd9Sstevel@tonic-gate 		 */
16207c478bd9Sstevel@tonic-gate 		free_sr(sr);
16217c478bd9Sstevel@tonic-gate 		return;
16227c478bd9Sstevel@tonic-gate 	}
16237c478bd9Sstevel@tonic-gate 
16247c478bd9Sstevel@tonic-gate 	if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
16257c478bd9Sstevel@tonic-gate 	    ep)) == NULL) {
16267c478bd9Sstevel@tonic-gate 		if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE)) {
16277c478bd9Sstevel@tonic-gate 			metaflushsetname(sp);
16287c478bd9Sstevel@tonic-gate 			if (! mdisok(ep)) {
16297c478bd9Sstevel@tonic-gate 				free_sr(sr);
16307c478bd9Sstevel@tonic-gate 				return;
16317c478bd9Sstevel@tonic-gate 			}
16327c478bd9Sstevel@tonic-gate 			/* we are supposed to have drives!!!! */
16337c478bd9Sstevel@tonic-gate 			assert(0);
16347c478bd9Sstevel@tonic-gate 		}
16357c478bd9Sstevel@tonic-gate 		rb_mode = 1;
16367c478bd9Sstevel@tonic-gate 		mdclrerror(ep);
16377c478bd9Sstevel@tonic-gate 		for (i = 0; i < MD_MAXSIDES; i++) {
16387c478bd9Sstevel@tonic-gate 			/* Skip empty sides of the diskset */
16397c478bd9Sstevel@tonic-gate 			if (sr->sr_nodes[i][0] == '\0')
16407c478bd9Sstevel@tonic-gate 				continue;
16417c478bd9Sstevel@tonic-gate 			dd = metaget_drivedesc_sideno(sp, i,
16427c478bd9Sstevel@tonic-gate 			    (MD_BASICNAME_OK | PRINT_FAST), ep);
16437c478bd9Sstevel@tonic-gate 			/* Got dd, get out of loop */
16447c478bd9Sstevel@tonic-gate 			if (dd != NULL)
16457c478bd9Sstevel@tonic-gate 				break;
16467c478bd9Sstevel@tonic-gate 
16477c478bd9Sstevel@tonic-gate 			/* some error occurred, get out of loop */
16487c478bd9Sstevel@tonic-gate 			if (! mdisok(ep))
16497c478bd9Sstevel@tonic-gate 				break;
16507c478bd9Sstevel@tonic-gate 		}
16517c478bd9Sstevel@tonic-gate 		/*
16527c478bd9Sstevel@tonic-gate 		 * At this point, we have one of three possibilities:
16537c478bd9Sstevel@tonic-gate 		 *	1) dd != NULL (we have found drives using an alternate
16547c478bd9Sstevel@tonic-gate 		 *	   side.)
16557c478bd9Sstevel@tonic-gate 		 *	2) dd == NULL (no drives) && mdisok(ep) : assert(0)
16567c478bd9Sstevel@tonic-gate 		 *	3) dd == NULL (no drives) && ! mdisok(ep) : return
16577c478bd9Sstevel@tonic-gate 		 *	   error information to caller.
16587c478bd9Sstevel@tonic-gate 		 */
16597c478bd9Sstevel@tonic-gate 		if (dd == NULL) {
16607c478bd9Sstevel@tonic-gate 			metaflushsetname(sp);
16617c478bd9Sstevel@tonic-gate 			if (! mdisok(ep)) {
16627c478bd9Sstevel@tonic-gate 				free_sr(sr);
16637c478bd9Sstevel@tonic-gate 				return;
16647c478bd9Sstevel@tonic-gate 			}
16657c478bd9Sstevel@tonic-gate 			/* we are supposed to have drives!!!! */
16667c478bd9Sstevel@tonic-gate 			assert(0);
16677c478bd9Sstevel@tonic-gate 		}
16687c478bd9Sstevel@tonic-gate 	}
16697c478bd9Sstevel@tonic-gate 
16707c478bd9Sstevel@tonic-gate 	/*
16717c478bd9Sstevel@tonic-gate 	 * Let's run through each drive descriptor, and delete the
16727c478bd9Sstevel@tonic-gate 	 * sidename for all sides that are not in the sr_nodes array.
16737c478bd9Sstevel@tonic-gate 	 * We will ignore errors, cause the empty side may not
16747c478bd9Sstevel@tonic-gate 	 * have had any names to begin with.
16757c478bd9Sstevel@tonic-gate 	 */
16767c478bd9Sstevel@tonic-gate 	for (p = dd; p != NULL; p = p->dd_next) {
16777c478bd9Sstevel@tonic-gate 		dn = p->dd_dnp;
16787c478bd9Sstevel@tonic-gate 
16797c478bd9Sstevel@tonic-gate 		for (i = 0; i < MD_MAXSIDES; i++) {
16807c478bd9Sstevel@tonic-gate 			/* Skip existing sides of the diskset */
16817c478bd9Sstevel@tonic-gate 			if (!rb_mode && sr->sr_nodes[i][0] != '\0')
16827c478bd9Sstevel@tonic-gate 				continue;
16837c478bd9Sstevel@tonic-gate 			/* An empty side, delete the sidename */
16847c478bd9Sstevel@tonic-gate 			if (del_name(local_sp, i+SKEW,
16857c478bd9Sstevel@tonic-gate 			    dn->side_names_key, ep)) {
16867c478bd9Sstevel@tonic-gate 				if (!mdissyserror(ep, ENOENT)) {
16877c478bd9Sstevel@tonic-gate 					free_sr(sr);
16887c478bd9Sstevel@tonic-gate 					return;
16897c478bd9Sstevel@tonic-gate 				}
16907c478bd9Sstevel@tonic-gate 				mdclrerror(ep);
16917c478bd9Sstevel@tonic-gate 			}
16927c478bd9Sstevel@tonic-gate 		}
16937c478bd9Sstevel@tonic-gate 	}
16947c478bd9Sstevel@tonic-gate 	free_sr(sr);
16957c478bd9Sstevel@tonic-gate 	metaflushsetname(sp);
16967c478bd9Sstevel@tonic-gate }
16977c478bd9Sstevel@tonic-gate 
16987c478bd9Sstevel@tonic-gate /*
16997c478bd9Sstevel@tonic-gate  * delete 1 or more sidenames per drive desc, from the local namespace
17007c478bd9Sstevel@tonic-gate  */
17017c478bd9Sstevel@tonic-gate bool_t
mdrpc_del_drv_sidenms_common(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)17027c478bd9Sstevel@tonic-gate mdrpc_del_drv_sidenms_common(
17037c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,
17047c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
17057c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp,		/* RPC stuff */
17067c478bd9Sstevel@tonic-gate 	int			version		/* RPC version */
17077c478bd9Sstevel@tonic-gate )
17087c478bd9Sstevel@tonic-gate {
17097c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
17107c478bd9Sstevel@tonic-gate 	int			err;
17117c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
17127c478bd9Sstevel@tonic-gate 
17137c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
17147c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
17157c478bd9Sstevel@tonic-gate 		return (FALSE);
17167c478bd9Sstevel@tonic-gate 	else if (err != 0)
17177c478bd9Sstevel@tonic-gate 		return (TRUE);
17187c478bd9Sstevel@tonic-gate 
17197c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
17207c478bd9Sstevel@tonic-gate 		return (TRUE);
17217c478bd9Sstevel@tonic-gate 
17227c478bd9Sstevel@tonic-gate 	/* doit */
17237c478bd9Sstevel@tonic-gate 	del_drv_sidenms(args->sp, version, ep);
17247c478bd9Sstevel@tonic-gate 
17257c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
17267c478bd9Sstevel@tonic-gate 
17277c478bd9Sstevel@tonic-gate 	return (TRUE);
17287c478bd9Sstevel@tonic-gate }
17297c478bd9Sstevel@tonic-gate 
17307c478bd9Sstevel@tonic-gate bool_t
mdrpc_del_drv_sidenms_1_svc(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)17317c478bd9Sstevel@tonic-gate mdrpc_del_drv_sidenms_1_svc(
17327c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,
17337c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
17347c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
17357c478bd9Sstevel@tonic-gate )
17367c478bd9Sstevel@tonic-gate {
17372a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
17387c478bd9Sstevel@tonic-gate 	/* Pass RPC version (METAD_VERSION) to common routine */
17397c478bd9Sstevel@tonic-gate 	return (mdrpc_del_drv_sidenms_common(args, res, rqstp, METAD_VERSION));
17407c478bd9Sstevel@tonic-gate }
17417c478bd9Sstevel@tonic-gate 
17427c478bd9Sstevel@tonic-gate bool_t
mdrpc_del_drv_sidenms_2_svc(mdrpc_sp_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)17437c478bd9Sstevel@tonic-gate mdrpc_del_drv_sidenms_2_svc(
17447c478bd9Sstevel@tonic-gate 	mdrpc_sp_2_args		*args,
17457c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
17467c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
17477c478bd9Sstevel@tonic-gate )
17487c478bd9Sstevel@tonic-gate {
17492a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
17507c478bd9Sstevel@tonic-gate 	switch (args->rev) {
17517c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
17527c478bd9Sstevel@tonic-gate 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
17537c478bd9Sstevel@tonic-gate 		return (mdrpc_del_drv_sidenms_common(
17547c478bd9Sstevel@tonic-gate 		    &args->mdrpc_sp_2_args_u.rev1, res,
17557c478bd9Sstevel@tonic-gate 		    rqstp, METAD_VERSION_DEVID));
17567c478bd9Sstevel@tonic-gate 	default:
17577c478bd9Sstevel@tonic-gate 		return (FALSE);
17587c478bd9Sstevel@tonic-gate 	}
17597c478bd9Sstevel@tonic-gate }
17607c478bd9Sstevel@tonic-gate 
17617c478bd9Sstevel@tonic-gate static int
del_sidenamelist(md_set_record * sr,mddrivename_t * dn,md_error_t * ep)17627c478bd9Sstevel@tonic-gate del_sidenamelist(
17637c478bd9Sstevel@tonic-gate 	md_set_record	*sr,
17647c478bd9Sstevel@tonic-gate 	mddrivename_t	*dn,
17657c478bd9Sstevel@tonic-gate 	md_error_t	*ep
17667c478bd9Sstevel@tonic-gate )
17677c478bd9Sstevel@tonic-gate {
17687c478bd9Sstevel@tonic-gate 	mdsidenames_t	*sn;
17697c478bd9Sstevel@tonic-gate 	mdsetname_t	*local_sp;
17707c478bd9Sstevel@tonic-gate 	md_mnset_record	*mnsr;
17717c478bd9Sstevel@tonic-gate 	md_mnnode_record *nr;
17727c478bd9Sstevel@tonic-gate 
17737c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
17747c478bd9Sstevel@tonic-gate 		return (-1);
17757c478bd9Sstevel@tonic-gate 
17767c478bd9Sstevel@tonic-gate 	for (sn = dn->side_names; sn != NULL; sn = sn->next)
17777c478bd9Sstevel@tonic-gate 		if (MD_MNSET_REC(sr)) {
17787c478bd9Sstevel@tonic-gate 			mnsr = (struct md_mnset_record *)sr;
17797c478bd9Sstevel@tonic-gate 			/*
17807c478bd9Sstevel@tonic-gate 			 * Only delete side name entries for this node
17817c478bd9Sstevel@tonic-gate 			 * on a multi-node diskset.
17827c478bd9Sstevel@tonic-gate 			 */
17837c478bd9Sstevel@tonic-gate 			nr = mnsr->sr_nodechain;
17847c478bd9Sstevel@tonic-gate 			while (nr) {
17857c478bd9Sstevel@tonic-gate 				if (nr->nr_nodeid == sn->sideno) {
17867c478bd9Sstevel@tonic-gate 					if (del_name(local_sp, sn->sideno,
17877c478bd9Sstevel@tonic-gate 					    dn->side_names_key, ep) == -1)
17887c478bd9Sstevel@tonic-gate 						mdclrerror(ep); /* ignore err */
17897c478bd9Sstevel@tonic-gate 					break;
17907c478bd9Sstevel@tonic-gate 				}
17917c478bd9Sstevel@tonic-gate 				nr = nr->nr_next;
17927c478bd9Sstevel@tonic-gate 			}
17937c478bd9Sstevel@tonic-gate 		} else {
17947c478bd9Sstevel@tonic-gate 			if (del_name(local_sp, sn->sideno+SKEW,
17957c478bd9Sstevel@tonic-gate 			    dn->side_names_key, ep) == -1)
17967c478bd9Sstevel@tonic-gate 				mdclrerror(ep);	/* ignore errors */
17977c478bd9Sstevel@tonic-gate 		}
17987c478bd9Sstevel@tonic-gate 
17997c478bd9Sstevel@tonic-gate 	dn->side_names_key = MD_KEYBAD;
18007c478bd9Sstevel@tonic-gate 	return (0);
18017c478bd9Sstevel@tonic-gate }
18027c478bd9Sstevel@tonic-gate 
18037c478bd9Sstevel@tonic-gate static void
deldrvs(char * setname,md_drive_desc * dd,md_error_t * ep)18047c478bd9Sstevel@tonic-gate deldrvs(
18057c478bd9Sstevel@tonic-gate 	char		*setname,
18067c478bd9Sstevel@tonic-gate 	md_drive_desc	*dd,
18077c478bd9Sstevel@tonic-gate 	md_error_t	*ep
18087c478bd9Sstevel@tonic-gate )
18097c478bd9Sstevel@tonic-gate {
18107c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp;
18117c478bd9Sstevel@tonic-gate 	md_set_record	*sr;
18127c478bd9Sstevel@tonic-gate 	md_drive_record	*dr;
18137c478bd9Sstevel@tonic-gate 	mddb_userreq_t	req;
18147c478bd9Sstevel@tonic-gate 	md_drive_desc	*p;
18157c478bd9Sstevel@tonic-gate 	mddrivename_t	*dn, *dn1;
18167c478bd9Sstevel@tonic-gate 	side_t		sideno;
18177c478bd9Sstevel@tonic-gate 	int		i;
18187c478bd9Sstevel@tonic-gate 	int		rb_mode = 0;
18197c478bd9Sstevel@tonic-gate 	mdname_t	*np;
18207c478bd9Sstevel@tonic-gate 	md_dev64_t	dev;
18217c478bd9Sstevel@tonic-gate 	md_error_t	xep = mdnullerror;
18227c478bd9Sstevel@tonic-gate 	ddi_devid_t	devid_remote = NULL;
18237c478bd9Sstevel@tonic-gate 	ddi_devid_t	devid_local = NULL;
18247c478bd9Sstevel@tonic-gate 	int		devid_same = -1;
18257c478bd9Sstevel@tonic-gate 	int		using_devid = 0;
18267c478bd9Sstevel@tonic-gate 	md_mnnode_record	*nr;
18277c478bd9Sstevel@tonic-gate 	md_mnset_record		*mnsr;
18287c478bd9Sstevel@tonic-gate 
18297c478bd9Sstevel@tonic-gate 	if ((sp = metasetname(setname, ep)) == NULL)
18307c478bd9Sstevel@tonic-gate 		return;
18317c478bd9Sstevel@tonic-gate 
18327c478bd9Sstevel@tonic-gate 	metaflushsetname(sp);
18337c478bd9Sstevel@tonic-gate 
18347c478bd9Sstevel@tonic-gate 	if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD) {
18357c478bd9Sstevel@tonic-gate 		if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE))
18367c478bd9Sstevel@tonic-gate 			return;
18377c478bd9Sstevel@tonic-gate 		mdclrerror(ep);
18387c478bd9Sstevel@tonic-gate 		/*
18397c478bd9Sstevel@tonic-gate 		 * The set record is incomplete, so we need to make note
18407c478bd9Sstevel@tonic-gate 		 * here so that we can do some special handling later.
18417c478bd9Sstevel@tonic-gate 		 */
18427c478bd9Sstevel@tonic-gate 		rb_mode = 1;
18437c478bd9Sstevel@tonic-gate 	}
18447c478bd9Sstevel@tonic-gate 
18457c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(setname, ep)) == NULL)
18467c478bd9Sstevel@tonic-gate 		return;
18477c478bd9Sstevel@tonic-gate 
18487c478bd9Sstevel@tonic-gate 	if (dd->dd_dnp == NULL)
18497c478bd9Sstevel@tonic-gate 		return;
18507c478bd9Sstevel@tonic-gate 
18517c478bd9Sstevel@tonic-gate 	/*
18527c478bd9Sstevel@tonic-gate 	 * The system is either all devid or all
18537c478bd9Sstevel@tonic-gate 	 * non-devid so we determine this by looking
18547c478bd9Sstevel@tonic-gate 	 * at the first item in the list.
18557c478bd9Sstevel@tonic-gate 	 *
18567c478bd9Sstevel@tonic-gate 	 * For did disks, the dd_dnp->devid is a valid pointer which
18577c478bd9Sstevel@tonic-gate 	 * points to a '' string of devid.  We need to check this
18587c478bd9Sstevel@tonic-gate 	 * before set the using_devid.
18597c478bd9Sstevel@tonic-gate 	 */
18607c478bd9Sstevel@tonic-gate 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
18617c478bd9Sstevel@tonic-gate 	    (!(MD_MNSET_REC(sr))))
18627c478bd9Sstevel@tonic-gate 		using_devid = 1;
18637c478bd9Sstevel@tonic-gate 
18647c478bd9Sstevel@tonic-gate 	for (p = dd; p != NULL; p = p->dd_next) {
18657c478bd9Sstevel@tonic-gate 		dn = p->dd_dnp;
18667c478bd9Sstevel@tonic-gate 		devid_remote = NULL;
18677c478bd9Sstevel@tonic-gate 
18687c478bd9Sstevel@tonic-gate 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
18697c478bd9Sstevel@tonic-gate 		    using_devid) {
18707c478bd9Sstevel@tonic-gate 			/*
18717c478bd9Sstevel@tonic-gate 			 * We have a devid so use it
18727c478bd9Sstevel@tonic-gate 			 */
18737c478bd9Sstevel@tonic-gate 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
18747c478bd9Sstevel@tonic-gate 		}
18757c478bd9Sstevel@tonic-gate 
18767c478bd9Sstevel@tonic-gate 		/* check to make sure using_devid agrees with reality... */
18777c478bd9Sstevel@tonic-gate 		if ((using_devid == 1) && (devid_remote == NULL)) {
18787c478bd9Sstevel@tonic-gate 			/* something went really wrong. Can't process */
18797c478bd9Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
18807c478bd9Sstevel@tonic-gate 			    mynode(), dn->cname, sp->setname);
18817c478bd9Sstevel@tonic-gate 			return;
18827c478bd9Sstevel@tonic-gate 		}
18837c478bd9Sstevel@tonic-gate 
18847c478bd9Sstevel@tonic-gate 		for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
18857c478bd9Sstevel@tonic-gate 			devid_same = -1;
18867c478bd9Sstevel@tonic-gate 
18877c478bd9Sstevel@tonic-gate 			if (! rb_mode) {
18887c478bd9Sstevel@tonic-gate 				dn1 = metadrivename_withdrkey(sp, sideno,
18897c478bd9Sstevel@tonic-gate 				    dr->dr_key, MD_BASICNAME_OK, ep);
18907c478bd9Sstevel@tonic-gate 				if (dn1 == NULL) {
18917c478bd9Sstevel@tonic-gate 					free_sr(sr);
18927c478bd9Sstevel@tonic-gate 					if (devid_remote)
18937c478bd9Sstevel@tonic-gate 						devid_free(devid_remote);
18947c478bd9Sstevel@tonic-gate 					return;
18957c478bd9Sstevel@tonic-gate 				}
18967c478bd9Sstevel@tonic-gate 			} else {
18977c478bd9Sstevel@tonic-gate 				/*
18987c478bd9Sstevel@tonic-gate 				 * Handle special case here where sidenames
18997c478bd9Sstevel@tonic-gate 				 * from other hosts for this drive may be
19007c478bd9Sstevel@tonic-gate 				 * in the local mddb, but there is no
19017c478bd9Sstevel@tonic-gate 				 * sidename entry for this host for this drive.
19027c478bd9Sstevel@tonic-gate 				 * This could have happened if the node
19037c478bd9Sstevel@tonic-gate 				 * panic'd between the 2 operations when
19047c478bd9Sstevel@tonic-gate 				 * adding this node to the set.
19057c478bd9Sstevel@tonic-gate 				 * So, delete all sidename entries for this
19067c478bd9Sstevel@tonic-gate 				 * drive.
19077c478bd9Sstevel@tonic-gate 				 */
19087c478bd9Sstevel@tonic-gate 				if (MD_MNSET_REC(sr)) {
19097c478bd9Sstevel@tonic-gate 					mnsr = (struct md_mnset_record *)sr;
19107c478bd9Sstevel@tonic-gate 					nr = mnsr->sr_nodechain;
19117c478bd9Sstevel@tonic-gate 					while (nr) {
19127c478bd9Sstevel@tonic-gate 						/* We delete all dr sides */
19137c478bd9Sstevel@tonic-gate 						dn1 = metadrivename_withdrkey(
19147c478bd9Sstevel@tonic-gate 						    sp, nr->nr_nodeid,
19157c478bd9Sstevel@tonic-gate 						    dr->dr_key,
19167c478bd9Sstevel@tonic-gate 						    MD_BASICNAME_OK, ep);
19177c478bd9Sstevel@tonic-gate 
19187c478bd9Sstevel@tonic-gate 						/* if we do, get out of loop */
19197c478bd9Sstevel@tonic-gate 						if (dn1 != NULL)
19207c478bd9Sstevel@tonic-gate 							break;
19217c478bd9Sstevel@tonic-gate 
19227c478bd9Sstevel@tonic-gate 						/* save error for later */
19237c478bd9Sstevel@tonic-gate 						(void) mdstealerror(&xep, ep);
19247c478bd9Sstevel@tonic-gate 
19257c478bd9Sstevel@tonic-gate 						mdclrerror(ep);
19267c478bd9Sstevel@tonic-gate 
19277c478bd9Sstevel@tonic-gate 						nr = nr->nr_next;
19287c478bd9Sstevel@tonic-gate 					}
19297c478bd9Sstevel@tonic-gate 				} else {
19307c478bd9Sstevel@tonic-gate 					/*
19317c478bd9Sstevel@tonic-gate 					 * Handle special case here
19327c478bd9Sstevel@tonic-gate 					 * for traditional diskset
19337c478bd9Sstevel@tonic-gate 					 */
19347c478bd9Sstevel@tonic-gate 					for (i = 0; i < MD_MAXSIDES; i++) {
19357c478bd9Sstevel@tonic-gate 						/* We delete all dr sides */
19367c478bd9Sstevel@tonic-gate 						dn1 = metadrivename_withdrkey(
19377c478bd9Sstevel@tonic-gate 						    sp, i, dr->dr_key,
19387c478bd9Sstevel@tonic-gate 						    MD_BASICNAME_OK, ep);
19397c478bd9Sstevel@tonic-gate 
19407c478bd9Sstevel@tonic-gate 						/* if we do, get out of loop */
19417c478bd9Sstevel@tonic-gate 						if (dn1 != NULL)
19427c478bd9Sstevel@tonic-gate 							break;
19437c478bd9Sstevel@tonic-gate 
19447c478bd9Sstevel@tonic-gate 						/* save error for later */
19457c478bd9Sstevel@tonic-gate 						(void) mdstealerror(&xep, ep);
19467c478bd9Sstevel@tonic-gate 
19477c478bd9Sstevel@tonic-gate 						mdclrerror(ep);
19487c478bd9Sstevel@tonic-gate 					}
19497c478bd9Sstevel@tonic-gate 				}
19507c478bd9Sstevel@tonic-gate 
19517c478bd9Sstevel@tonic-gate 				if (dn1 == NULL) {
19527c478bd9Sstevel@tonic-gate 					(void) mdstealerror(ep, &xep);
19537c478bd9Sstevel@tonic-gate 					free_sr(sr);
19547c478bd9Sstevel@tonic-gate 					if (devid_remote)
19557c478bd9Sstevel@tonic-gate 						devid_free(devid_remote);
19567c478bd9Sstevel@tonic-gate 					return;
19577c478bd9Sstevel@tonic-gate 				}
19587c478bd9Sstevel@tonic-gate 
19597c478bd9Sstevel@tonic-gate 				if (!using_devid)
19607c478bd9Sstevel@tonic-gate 					mdclrerror(ep);
19617c478bd9Sstevel@tonic-gate 			}
19627c478bd9Sstevel@tonic-gate 
19637c478bd9Sstevel@tonic-gate 			if (dn1->devid != NULL && using_devid) {
19647c478bd9Sstevel@tonic-gate 				if (devid_str_decode(dn1->devid, &devid_local,
19657c478bd9Sstevel@tonic-gate 				    NULL) == 0) {
19667c478bd9Sstevel@tonic-gate 					devid_same = devid_compare(devid_remote,
19677c478bd9Sstevel@tonic-gate 					    devid_local);
19687c478bd9Sstevel@tonic-gate 					devid_free(devid_local);
19697c478bd9Sstevel@tonic-gate 				}
19707c478bd9Sstevel@tonic-gate 			}
19717c478bd9Sstevel@tonic-gate 
19727c478bd9Sstevel@tonic-gate 			/*
19737c478bd9Sstevel@tonic-gate 			 * Has the required disk been found - either the devids
19747c478bd9Sstevel@tonic-gate 			 * match if devid are being used or the actual name of
19757c478bd9Sstevel@tonic-gate 			 * the disk matches.
19767c478bd9Sstevel@tonic-gate 			 */
19777c478bd9Sstevel@tonic-gate 			if ((using_devid && devid_same == 0) ||
19787c478bd9Sstevel@tonic-gate 			    (!using_devid &&
19797c478bd9Sstevel@tonic-gate 			    strcmp(dn->cname, dn1->cname) == 0)) {
19807c478bd9Sstevel@tonic-gate 				uint_t	rep_slice;
19817c478bd9Sstevel@tonic-gate 
19827c478bd9Sstevel@tonic-gate 				dev = NODEV64;
19837c478bd9Sstevel@tonic-gate 				np = NULL;
19847c478bd9Sstevel@tonic-gate 				if (meta_replicaslice(dn1,
19857c478bd9Sstevel@tonic-gate 				    &rep_slice, &xep) == 0) {
19867c478bd9Sstevel@tonic-gate 					np = metaslicename(dn1,
19877c478bd9Sstevel@tonic-gate 					    rep_slice, &xep);
19887c478bd9Sstevel@tonic-gate 				}
19897c478bd9Sstevel@tonic-gate 
19907c478bd9Sstevel@tonic-gate 				if (np != NULL)
19917c478bd9Sstevel@tonic-gate 					dev = np->dev;
19927c478bd9Sstevel@tonic-gate 				else
19937c478bd9Sstevel@tonic-gate 					mdclrerror(&xep);
19947c478bd9Sstevel@tonic-gate 				break;
19957c478bd9Sstevel@tonic-gate 			}
19967c478bd9Sstevel@tonic-gate 		}
19977c478bd9Sstevel@tonic-gate 
19987c478bd9Sstevel@tonic-gate 		if (dr) {
19997c478bd9Sstevel@tonic-gate 			(void) memset(&req, 0, sizeof (req));
20007c478bd9Sstevel@tonic-gate 			METAD_SETUP_DR(MD_DB_DELETE, dr->dr_selfid)
20017c478bd9Sstevel@tonic-gate 			if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL)
20027c478bd9Sstevel@tonic-gate 			    != 0) {
20037c478bd9Sstevel@tonic-gate 				(void) mdstealerror(ep, &req.ur_mde);
20047c478bd9Sstevel@tonic-gate 				if (devid_remote)
20057c478bd9Sstevel@tonic-gate 					devid_free(devid_remote);
20067c478bd9Sstevel@tonic-gate 				free_sr(sr);
20077c478bd9Sstevel@tonic-gate 				return;
20087c478bd9Sstevel@tonic-gate 			}
20097c478bd9Sstevel@tonic-gate 
20107c478bd9Sstevel@tonic-gate 			dr_cache_del(sr, dr->dr_selfid);
20117c478bd9Sstevel@tonic-gate 
20127c478bd9Sstevel@tonic-gate 			if (del_sidenamelist(sr, dn1, ep) == -1) {
20137c478bd9Sstevel@tonic-gate 				goto out;
20147c478bd9Sstevel@tonic-gate 			}
20157c478bd9Sstevel@tonic-gate 
20167c478bd9Sstevel@tonic-gate 			SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
20177c478bd9Sstevel@tonic-gate 			    sr->sr_setno, dev);
20187c478bd9Sstevel@tonic-gate 			SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
20197c478bd9Sstevel@tonic-gate 			    MD_LOCAL_SET, dev);
20207c478bd9Sstevel@tonic-gate 
20217c478bd9Sstevel@tonic-gate 			continue;
20227c478bd9Sstevel@tonic-gate 		}
20237c478bd9Sstevel@tonic-gate 
20247c478bd9Sstevel@tonic-gate 		if (devid_remote)
20257c478bd9Sstevel@tonic-gate 			devid_free(devid_remote);
20267c478bd9Sstevel@tonic-gate 	}
20277c478bd9Sstevel@tonic-gate 
20287c478bd9Sstevel@tonic-gate out:
20297c478bd9Sstevel@tonic-gate 	commitset(sr, TRUE, ep);
20307c478bd9Sstevel@tonic-gate 
20317c478bd9Sstevel@tonic-gate 	free_sr(sr);
20327c478bd9Sstevel@tonic-gate }
20337c478bd9Sstevel@tonic-gate 
20347c478bd9Sstevel@tonic-gate /*
20357c478bd9Sstevel@tonic-gate  * delete 1 or more drive records from a host.
20367c478bd9Sstevel@tonic-gate  */
20377c478bd9Sstevel@tonic-gate bool_t
mdrpc_deldrvs_common(mdrpc_drives_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)20387c478bd9Sstevel@tonic-gate mdrpc_deldrvs_common(
20397c478bd9Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	*args,
20407c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
20417c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
20427c478bd9Sstevel@tonic-gate )
20437c478bd9Sstevel@tonic-gate {
20447c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
20457c478bd9Sstevel@tonic-gate 	int			err;
20467c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
20477c478bd9Sstevel@tonic-gate 
20487c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
20497c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
20507c478bd9Sstevel@tonic-gate 		return (FALSE);
20517c478bd9Sstevel@tonic-gate 	else if (err != 0)
20527c478bd9Sstevel@tonic-gate 		return (TRUE);
20537c478bd9Sstevel@tonic-gate 
20547c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
20557c478bd9Sstevel@tonic-gate 		return (TRUE);
20567c478bd9Sstevel@tonic-gate 
20577c478bd9Sstevel@tonic-gate 	/* doit */
20587c478bd9Sstevel@tonic-gate 	deldrvs(args->sp->setname, args->drivedescs, ep);
20597c478bd9Sstevel@tonic-gate 
20607c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
20617c478bd9Sstevel@tonic-gate 
20627c478bd9Sstevel@tonic-gate 	return (TRUE);
20637c478bd9Sstevel@tonic-gate }
20647c478bd9Sstevel@tonic-gate 
20657c478bd9Sstevel@tonic-gate /*
20667c478bd9Sstevel@tonic-gate  * version 1 of the remote procedure. This procedure is called if the
20677c478bd9Sstevel@tonic-gate  * client is running in version 1. We first convert version 1 arguments
20687c478bd9Sstevel@tonic-gate  * into version 2 arguments and then call the common remote procedure.
20697c478bd9Sstevel@tonic-gate  */
20707c478bd9Sstevel@tonic-gate bool_t
mdrpc_deldrvs_1_svc(mdrpc_drives_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)20717c478bd9Sstevel@tonic-gate mdrpc_deldrvs_1_svc(
20727c478bd9Sstevel@tonic-gate 	mdrpc_drives_args	*args,
20737c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
20747c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
20757c478bd9Sstevel@tonic-gate )
20767c478bd9Sstevel@tonic-gate {
20777c478bd9Sstevel@tonic-gate 	bool_t			retval;
20787c478bd9Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	v2_args;
20797c478bd9Sstevel@tonic-gate 
20807c478bd9Sstevel@tonic-gate 	/* allocate memory */
20817c478bd9Sstevel@tonic-gate 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
20822a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
20837c478bd9Sstevel@tonic-gate 
20847c478bd9Sstevel@tonic-gate 	/* build args */
20857c478bd9Sstevel@tonic-gate 	v2_args.cl_sk = args->cl_sk;
20867c478bd9Sstevel@tonic-gate 	v2_args.sp = args->sp;
20877c478bd9Sstevel@tonic-gate 	/* convert v1 args to v2 (revision 1) args */
20887c478bd9Sstevel@tonic-gate 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
20897c478bd9Sstevel@tonic-gate 	v2_args.timestamp = args->timestamp;
20907c478bd9Sstevel@tonic-gate 	v2_args.genid = args->genid;
20917c478bd9Sstevel@tonic-gate 
20927c478bd9Sstevel@tonic-gate 	retval = mdrpc_deldrvs_common(&v2_args, res, rqstp);
20937c478bd9Sstevel@tonic-gate 
20947c478bd9Sstevel@tonic-gate 	free_newdrvdesc(v2_args.drivedescs);
20957c478bd9Sstevel@tonic-gate 
20967c478bd9Sstevel@tonic-gate 	return (retval);
20977c478bd9Sstevel@tonic-gate }
20987c478bd9Sstevel@tonic-gate 
20997c478bd9Sstevel@tonic-gate bool_t
mdrpc_deldrvs_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)21007c478bd9Sstevel@tonic-gate mdrpc_deldrvs_2_svc(
21017c478bd9Sstevel@tonic-gate 	mdrpc_drives_2_args	*args,
21027c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
21037c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
21047c478bd9Sstevel@tonic-gate )
21057c478bd9Sstevel@tonic-gate {
21062a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
21077c478bd9Sstevel@tonic-gate 	switch (args->rev) {
21087c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
21097c478bd9Sstevel@tonic-gate 		return (mdrpc_deldrvs_common(
21107c478bd9Sstevel@tonic-gate 		    &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
21117c478bd9Sstevel@tonic-gate 	default:
21127c478bd9Sstevel@tonic-gate 		return (FALSE);
21137c478bd9Sstevel@tonic-gate 	}
21147c478bd9Sstevel@tonic-gate }
21157c478bd9Sstevel@tonic-gate 
21167c478bd9Sstevel@tonic-gate static void
delhosts(char * setname,int node_c,char ** node_v,int version,md_error_t * ep)21177c478bd9Sstevel@tonic-gate delhosts(
21187c478bd9Sstevel@tonic-gate 	char		*setname,
21197c478bd9Sstevel@tonic-gate 	int		node_c,
21207c478bd9Sstevel@tonic-gate 	char		**node_v,
21217c478bd9Sstevel@tonic-gate 	int		version,	/* RPC version of calling routine */
21227c478bd9Sstevel@tonic-gate 	md_error_t	*ep
21237c478bd9Sstevel@tonic-gate )
21247c478bd9Sstevel@tonic-gate {
21257c478bd9Sstevel@tonic-gate 	mddb_userreq_t		req;
21267c478bd9Sstevel@tonic-gate 	md_set_record		*sr;
21277c478bd9Sstevel@tonic-gate 	int			i, j;
21287c478bd9Sstevel@tonic-gate 	md_mnset_record		*mnsr;
21297c478bd9Sstevel@tonic-gate 	md_mnnode_record	*nr;
21307c478bd9Sstevel@tonic-gate 
21317c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(setname, ep)) == NULL)
21327c478bd9Sstevel@tonic-gate 		return;
21337c478bd9Sstevel@tonic-gate 
21347c478bd9Sstevel@tonic-gate 	for (i = 0; i < node_c; i++) {
21357c478bd9Sstevel@tonic-gate 		/* Do MN operation if rpc version supports it and if a MN set */
21367c478bd9Sstevel@tonic-gate 		if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
21377c478bd9Sstevel@tonic-gate 			mnsr = (struct md_mnset_record *)sr;
21387c478bd9Sstevel@tonic-gate 			nr = mnsr->sr_nodechain;
21397c478bd9Sstevel@tonic-gate 			while (nr) {
21407c478bd9Sstevel@tonic-gate 				if (strcmp(nr->nr_nodename, node_v[i]) == 0) {
21417c478bd9Sstevel@tonic-gate 					SE_NOTIFY(EC_SVM_CONFIG,
21427c478bd9Sstevel@tonic-gate 					    ESC_SVM_REMOVE, SVM_TAG_HOST,
21437c478bd9Sstevel@tonic-gate 					    sr->sr_setno, nr->nr_nodeid);
21447c478bd9Sstevel@tonic-gate 					(void) memset(&req, '\0', sizeof (req));
21457c478bd9Sstevel@tonic-gate 					METAD_SETUP_NR(MD_DB_DELETE,
21467c478bd9Sstevel@tonic-gate 					    nr->nr_selfid);
21477c478bd9Sstevel@tonic-gate 					if (metaioctl(MD_DB_USERREQ, &req,
21487c478bd9Sstevel@tonic-gate 					    &req.ur_mde, NULL) != 0) {
21497c478bd9Sstevel@tonic-gate 						(void) mdstealerror(ep,
21507c478bd9Sstevel@tonic-gate 						    &req.ur_mde);
21517c478bd9Sstevel@tonic-gate 						free_sr(sr);
21527c478bd9Sstevel@tonic-gate 						return;
21537c478bd9Sstevel@tonic-gate 					}
21547c478bd9Sstevel@tonic-gate 					mnnr_cache_del(mnsr, nr->nr_selfid);
21557c478bd9Sstevel@tonic-gate 					break;
21567c478bd9Sstevel@tonic-gate 				}
21577c478bd9Sstevel@tonic-gate 				nr = nr->nr_next;
21587c478bd9Sstevel@tonic-gate 			}
21597c478bd9Sstevel@tonic-gate 		} else {
21607c478bd9Sstevel@tonic-gate 			for (j = 0; j < MD_MAXSIDES; j++) {
21617c478bd9Sstevel@tonic-gate 				if (sr->sr_nodes[j][0] == '\0')
21627c478bd9Sstevel@tonic-gate 					continue;
21637c478bd9Sstevel@tonic-gate 				if (strcmp(sr->sr_nodes[j], node_v[i]) != 0)
21647c478bd9Sstevel@tonic-gate 					continue;
21657c478bd9Sstevel@tonic-gate 				(void) memset(sr->sr_nodes[j], '\0',
21667c478bd9Sstevel@tonic-gate 				    sizeof (sr->sr_nodes[j]));
21677c478bd9Sstevel@tonic-gate 				SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE,
21687c478bd9Sstevel@tonic-gate 				    SVM_TAG_HOST, sr->sr_setno, j);
21697c478bd9Sstevel@tonic-gate 				break;
21707c478bd9Sstevel@tonic-gate 			}
21717c478bd9Sstevel@tonic-gate 		}
21727c478bd9Sstevel@tonic-gate 	}
21737c478bd9Sstevel@tonic-gate 
21747c478bd9Sstevel@tonic-gate 	(void) memset(&req, '\0', sizeof (req));
21757c478bd9Sstevel@tonic-gate 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
21767c478bd9Sstevel@tonic-gate 	/* Do MN operation if rpc version supports it and if a MN set */
21777c478bd9Sstevel@tonic-gate 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
21787c478bd9Sstevel@tonic-gate 		req.ur_size = sizeof (*mnsr);
21797c478bd9Sstevel@tonic-gate 	} else {
21807c478bd9Sstevel@tonic-gate 		req.ur_size = sizeof (*sr);
21817c478bd9Sstevel@tonic-gate 	}
21827c478bd9Sstevel@tonic-gate 	req.ur_data = (uintptr_t)sr;
21837c478bd9Sstevel@tonic-gate 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
21847c478bd9Sstevel@tonic-gate 		(void) mdstealerror(ep, &req.ur_mde);
21857c478bd9Sstevel@tonic-gate 		free_sr(sr);
21867c478bd9Sstevel@tonic-gate 		return;
21877c478bd9Sstevel@tonic-gate 	}
21887c478bd9Sstevel@tonic-gate 
21897c478bd9Sstevel@tonic-gate 	commitset(sr, TRUE, ep);
21907c478bd9Sstevel@tonic-gate 	free_sr(sr);
21917c478bd9Sstevel@tonic-gate }
21927c478bd9Sstevel@tonic-gate 
21937c478bd9Sstevel@tonic-gate /*
21947c478bd9Sstevel@tonic-gate  * delete 1 or more a hosts from a set.
21957c478bd9Sstevel@tonic-gate  */
21967c478bd9Sstevel@tonic-gate bool_t
mdrpc_delhosts_common(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)21977c478bd9Sstevel@tonic-gate mdrpc_delhosts_common(
21987c478bd9Sstevel@tonic-gate 	mdrpc_host_args		*args,
21997c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
22007c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp,		/* RPC stuff */
22017c478bd9Sstevel@tonic-gate 	int			version		/* RPC version */
22027c478bd9Sstevel@tonic-gate )
22037c478bd9Sstevel@tonic-gate {
22047c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
22057c478bd9Sstevel@tonic-gate 	int			err;
22067c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
22077c478bd9Sstevel@tonic-gate 
22087c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
22097c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
22107c478bd9Sstevel@tonic-gate 		return (FALSE);
22117c478bd9Sstevel@tonic-gate 	else if (err != 0)
22127c478bd9Sstevel@tonic-gate 		return (TRUE);
22137c478bd9Sstevel@tonic-gate 
22147c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
22157c478bd9Sstevel@tonic-gate 		return (TRUE);
22167c478bd9Sstevel@tonic-gate 
22177c478bd9Sstevel@tonic-gate 	/* doit */
22187c478bd9Sstevel@tonic-gate 	delhosts(args->sp->setname, args->hosts.hosts_len,
22197c478bd9Sstevel@tonic-gate 	    args->hosts.hosts_val, version, ep);
22207c478bd9Sstevel@tonic-gate 
22217c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
22227c478bd9Sstevel@tonic-gate 
22237c478bd9Sstevel@tonic-gate 	return (TRUE);
22247c478bd9Sstevel@tonic-gate }
22257c478bd9Sstevel@tonic-gate 
22267c478bd9Sstevel@tonic-gate bool_t
mdrpc_delhosts_1_svc(mdrpc_host_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22277c478bd9Sstevel@tonic-gate mdrpc_delhosts_1_svc(
22287c478bd9Sstevel@tonic-gate 	mdrpc_host_args		*args,
22297c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
22307c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
22317c478bd9Sstevel@tonic-gate )
22327c478bd9Sstevel@tonic-gate {
22332a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
22347c478bd9Sstevel@tonic-gate 	/* Pass RPC version (METAD_VERSION) to common routine */
22357c478bd9Sstevel@tonic-gate 	return (mdrpc_delhosts_common(args, res, rqstp, METAD_VERSION));
22367c478bd9Sstevel@tonic-gate }
22377c478bd9Sstevel@tonic-gate 
22387c478bd9Sstevel@tonic-gate bool_t
mdrpc_delhosts_2_svc(mdrpc_host_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22397c478bd9Sstevel@tonic-gate mdrpc_delhosts_2_svc(
22407c478bd9Sstevel@tonic-gate 	mdrpc_host_2_args	*args,
22417c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
22427c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
22437c478bd9Sstevel@tonic-gate )
22447c478bd9Sstevel@tonic-gate {
22452a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
22467c478bd9Sstevel@tonic-gate 	switch (args->rev) {
22477c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
22487c478bd9Sstevel@tonic-gate 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
22497c478bd9Sstevel@tonic-gate 		return (mdrpc_delhosts_common(
22507c478bd9Sstevel@tonic-gate 		    &args->mdrpc_host_2_args_u.rev1, res,
22517c478bd9Sstevel@tonic-gate 		    rqstp, METAD_VERSION_DEVID));
22527c478bd9Sstevel@tonic-gate 	default:
22537c478bd9Sstevel@tonic-gate 		return (FALSE);
22547c478bd9Sstevel@tonic-gate 	}
22557c478bd9Sstevel@tonic-gate }
22567c478bd9Sstevel@tonic-gate 
22577c478bd9Sstevel@tonic-gate /*
22587c478bd9Sstevel@tonic-gate  * delete a set.
22597c478bd9Sstevel@tonic-gate  */
22607c478bd9Sstevel@tonic-gate bool_t
mdrpc_delset_common(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22617c478bd9Sstevel@tonic-gate mdrpc_delset_common(
22627c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,
22637c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
22647c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
22657c478bd9Sstevel@tonic-gate )
22667c478bd9Sstevel@tonic-gate {
22677c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
22687c478bd9Sstevel@tonic-gate 	int			err;
22697c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
22707c478bd9Sstevel@tonic-gate 
22717c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
22727c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
22737c478bd9Sstevel@tonic-gate 		return (FALSE);
22747c478bd9Sstevel@tonic-gate 	else if (err != 0)
22757c478bd9Sstevel@tonic-gate 		return (TRUE);
22767c478bd9Sstevel@tonic-gate 
22777c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
22787c478bd9Sstevel@tonic-gate 		return (TRUE);
22797c478bd9Sstevel@tonic-gate 
22807c478bd9Sstevel@tonic-gate 	/* doit */
22817c478bd9Sstevel@tonic-gate 	s_delset(args->sp->setname, ep);
22827c478bd9Sstevel@tonic-gate 
22837c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
22847c478bd9Sstevel@tonic-gate 
22857c478bd9Sstevel@tonic-gate 	return (TRUE);
22867c478bd9Sstevel@tonic-gate }
22877c478bd9Sstevel@tonic-gate 
22887c478bd9Sstevel@tonic-gate bool_t
mdrpc_delset_1_svc(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)22897c478bd9Sstevel@tonic-gate mdrpc_delset_1_svc(
22907c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,
22917c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
22927c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
22937c478bd9Sstevel@tonic-gate )
22947c478bd9Sstevel@tonic-gate {
22952a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
22967c478bd9Sstevel@tonic-gate 	return (mdrpc_delset_common(args, res, rqstp));
22977c478bd9Sstevel@tonic-gate }
22987c478bd9Sstevel@tonic-gate 
22997c478bd9Sstevel@tonic-gate bool_t
mdrpc_delset_2_svc(mdrpc_sp_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)23007c478bd9Sstevel@tonic-gate mdrpc_delset_2_svc(
23017c478bd9Sstevel@tonic-gate 	mdrpc_sp_2_args		*args,
23027c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
23037c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
23047c478bd9Sstevel@tonic-gate )
23057c478bd9Sstevel@tonic-gate {
23062a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
23077c478bd9Sstevel@tonic-gate 	switch (args->rev) {
23087c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
23097c478bd9Sstevel@tonic-gate 		return (mdrpc_delset_common(
23107c478bd9Sstevel@tonic-gate 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
23117c478bd9Sstevel@tonic-gate 	default:
23127c478bd9Sstevel@tonic-gate 		return (FALSE);
23137c478bd9Sstevel@tonic-gate 	}
23147c478bd9Sstevel@tonic-gate }
23157c478bd9Sstevel@tonic-gate 
23167c478bd9Sstevel@tonic-gate /*
23177c478bd9Sstevel@tonic-gate  * return device info
23187c478bd9Sstevel@tonic-gate  */
23197c478bd9Sstevel@tonic-gate static void
devinfo(mdsetname_t * sp,mddrivename_t * dp,mdrpc_devinfo_2_res * res,md_error_t * ep)23207c478bd9Sstevel@tonic-gate devinfo(
23217c478bd9Sstevel@tonic-gate 	mdsetname_t		*sp,
23227c478bd9Sstevel@tonic-gate 	mddrivename_t		*dp,
23237c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_2_res 	*res,
23247c478bd9Sstevel@tonic-gate 	md_error_t		*ep
23257c478bd9Sstevel@tonic-gate )
23267c478bd9Sstevel@tonic-gate {
23277c478bd9Sstevel@tonic-gate 	mdname_t		*np, *real_np;
23287c478bd9Sstevel@tonic-gate 
23297c478bd9Sstevel@tonic-gate 	if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL)
23307c478bd9Sstevel@tonic-gate 		return;
23317c478bd9Sstevel@tonic-gate 
2332d7cd8252Stw21770 	if ((real_np = metaname(&sp, np->bname, LOGICAL_DEVICE, ep)) == NULL)
23337c478bd9Sstevel@tonic-gate 		return;
23347c478bd9Sstevel@tonic-gate 
23357c478bd9Sstevel@tonic-gate 	res->dev = real_np->dev;
23367c478bd9Sstevel@tonic-gate 	(void) getdevstamp(dp, (long *)&res->vtime, ep);
23377c478bd9Sstevel@tonic-gate 	res->enc_devid = meta_get_devid(np->rname);
23387c478bd9Sstevel@tonic-gate }
23397c478bd9Sstevel@tonic-gate 
23407c478bd9Sstevel@tonic-gate bool_t
mdrpc_devinfo_common(mdrpc_devinfo_2_args_r1 * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)23417c478bd9Sstevel@tonic-gate mdrpc_devinfo_common(
23427c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_2_args_r1	*args,
23437c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_2_res 	*res,
23447c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp			/* RPC stuff */
23457c478bd9Sstevel@tonic-gate )
23467c478bd9Sstevel@tonic-gate {
23477c478bd9Sstevel@tonic-gate 	int			slice;
23487c478bd9Sstevel@tonic-gate 	mdname_t		*np;
23497c478bd9Sstevel@tonic-gate 	mddrivename_t		*dnp = args->drivenamep;
23507c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
23517c478bd9Sstevel@tonic-gate 	int			err;
23527c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
23537c478bd9Sstevel@tonic-gate 
23547c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
23557c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
23567c478bd9Sstevel@tonic-gate 		return (FALSE);
23577c478bd9Sstevel@tonic-gate 	else if (err != 0)
23587c478bd9Sstevel@tonic-gate 		return (TRUE);
23597c478bd9Sstevel@tonic-gate 
23607c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
23617c478bd9Sstevel@tonic-gate 		return (TRUE);
23627c478bd9Sstevel@tonic-gate 
23637c478bd9Sstevel@tonic-gate 	/*
23647c478bd9Sstevel@tonic-gate 	 * fix all the drivenamep's in the mdname_t's to
23657c478bd9Sstevel@tonic-gate 	 * point to the right place.
23667c478bd9Sstevel@tonic-gate 	 */
23677c478bd9Sstevel@tonic-gate 	for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
23687c478bd9Sstevel@tonic-gate 		if ((np = metaslicename(dnp, slice, ep)) == NULL)
23697c478bd9Sstevel@tonic-gate 			return (TRUE);
23707c478bd9Sstevel@tonic-gate 		np->drivenamep = dnp;
23717c478bd9Sstevel@tonic-gate 	}
23727c478bd9Sstevel@tonic-gate 
23737c478bd9Sstevel@tonic-gate 	/* doit */
23747c478bd9Sstevel@tonic-gate 	devinfo(args->sp, dnp, res, ep);
23757c478bd9Sstevel@tonic-gate 
23767c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
23777c478bd9Sstevel@tonic-gate 
23787c478bd9Sstevel@tonic-gate 	return (TRUE);
23797c478bd9Sstevel@tonic-gate }
23807c478bd9Sstevel@tonic-gate 
23817c478bd9Sstevel@tonic-gate /*
23827c478bd9Sstevel@tonic-gate  * version 1 of the remote procedure. This procedure is called if the
23837c478bd9Sstevel@tonic-gate  * client is running in version 1. We first convert version 1 arguments
23847c478bd9Sstevel@tonic-gate  * into version 2 arguments and then call the common remote procedure.
23857c478bd9Sstevel@tonic-gate  */
23867c478bd9Sstevel@tonic-gate bool_t
mdrpc_devinfo_1_svc(mdrpc_devinfo_args * args,mdrpc_devinfo_res * res,struct svc_req * rqstp)23877c478bd9Sstevel@tonic-gate mdrpc_devinfo_1_svc(
23887c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_args	*args,
23897c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_res 	*res,
23907c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp			/* RPC stuff */
23917c478bd9Sstevel@tonic-gate )
23927c478bd9Sstevel@tonic-gate {
23937c478bd9Sstevel@tonic-gate 	bool_t			retval;
23947c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_2_args_r1	v2_args;
23957c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_2_res	v2_res;
23967c478bd9Sstevel@tonic-gate 
23977c478bd9Sstevel@tonic-gate 	/* allocate memory */
23987c478bd9Sstevel@tonic-gate 	v2_args.drivenamep = Zalloc(sizeof (mddrivename_t));
23997c478bd9Sstevel@tonic-gate 	v2_args.drivenamep->parts.parts_val =
24007c478bd9Sstevel@tonic-gate 	    Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len);
24012a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
24027c478bd9Sstevel@tonic-gate 
24037c478bd9Sstevel@tonic-gate 	/* convert v1 args to v2 (revision 1) args */
24047c478bd9Sstevel@tonic-gate 	meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep);
24057c478bd9Sstevel@tonic-gate 	retval = mdrpc_devinfo_common(&v2_args, &v2_res, rqstp);
24067c478bd9Sstevel@tonic-gate 
24077c478bd9Sstevel@tonic-gate 	/*
24087c478bd9Sstevel@tonic-gate 	 * Fill in the result appropriately.
24097c478bd9Sstevel@tonic-gate 	 * Since dev_t's for version 2 are 64-bit,
24107c478bd9Sstevel@tonic-gate 	 * we need to convert them to 32-bit for version 1.
24117c478bd9Sstevel@tonic-gate 	 */
24127c478bd9Sstevel@tonic-gate 	res->dev = meta_cmpldev(v2_res.dev);
24137c478bd9Sstevel@tonic-gate 	res->vtime = v2_res.vtime;
24147c478bd9Sstevel@tonic-gate 	res->status = v2_res.status;
24157c478bd9Sstevel@tonic-gate 
24167c478bd9Sstevel@tonic-gate 	free(v2_args.drivenamep);
24177c478bd9Sstevel@tonic-gate 	free(v2_args.drivenamep->parts.parts_val);
24187c478bd9Sstevel@tonic-gate 
24197c478bd9Sstevel@tonic-gate 	return (retval);
24207c478bd9Sstevel@tonic-gate }
24217c478bd9Sstevel@tonic-gate 
24227c478bd9Sstevel@tonic-gate bool_t
mdrpc_devinfo_2_svc(mdrpc_devinfo_2_args * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)24237c478bd9Sstevel@tonic-gate mdrpc_devinfo_2_svc(
24247c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_2_args	*args,
24257c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_2_res 	*res,
24267c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp			/* RPC stuff */
24277c478bd9Sstevel@tonic-gate )
24287c478bd9Sstevel@tonic-gate {
24292a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
24307c478bd9Sstevel@tonic-gate 	switch (args->rev) {
24317c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
24327c478bd9Sstevel@tonic-gate 		return (mdrpc_devinfo_common(
24337c478bd9Sstevel@tonic-gate 		    &args->mdrpc_devinfo_2_args_u.rev1, res, rqstp));
24347c478bd9Sstevel@tonic-gate 	default:
24357c478bd9Sstevel@tonic-gate 		return (FALSE);
24367c478bd9Sstevel@tonic-gate 	}
24377c478bd9Sstevel@tonic-gate }
24387c478bd9Sstevel@tonic-gate 
24397c478bd9Sstevel@tonic-gate /*
24407c478bd9Sstevel@tonic-gate  * return device id
24417c478bd9Sstevel@tonic-gate  */
24427c478bd9Sstevel@tonic-gate static void
mdrpc_get_devid(mdsetname_t * sp,mddrivename_t * dp,mdrpc_devid_res * res,md_error_t * ep)24437c478bd9Sstevel@tonic-gate mdrpc_get_devid(
24447c478bd9Sstevel@tonic-gate 	mdsetname_t		*sp,
24457c478bd9Sstevel@tonic-gate 	mddrivename_t		*dp,
24467c478bd9Sstevel@tonic-gate 	mdrpc_devid_res 	*res,
24477c478bd9Sstevel@tonic-gate 	md_error_t		*ep
24487c478bd9Sstevel@tonic-gate )
24497c478bd9Sstevel@tonic-gate {
24507c478bd9Sstevel@tonic-gate 	mdname_t	*np;
24517c478bd9Sstevel@tonic-gate 
24527c478bd9Sstevel@tonic-gate 	if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL)
24537c478bd9Sstevel@tonic-gate 		return;
24547c478bd9Sstevel@tonic-gate 
2455d7cd8252Stw21770 	if (metaname(&sp, np->bname, LOGICAL_DEVICE, ep) == NULL)
24567c478bd9Sstevel@tonic-gate 		return;
24577c478bd9Sstevel@tonic-gate 
24587c478bd9Sstevel@tonic-gate 	res->enc_devid = meta_get_devid(np->rname);
24597c478bd9Sstevel@tonic-gate }
24607c478bd9Sstevel@tonic-gate 
24617c478bd9Sstevel@tonic-gate bool_t
mdrpc_devid_2_svc(mdrpc_devid_2_args * args,mdrpc_devid_res * res,struct svc_req * rqstp)24627c478bd9Sstevel@tonic-gate mdrpc_devid_2_svc(
24637c478bd9Sstevel@tonic-gate 	mdrpc_devid_2_args	*args,
24647c478bd9Sstevel@tonic-gate 	mdrpc_devid_res 	*res,
24657c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp			/* RPC stuff */
24667c478bd9Sstevel@tonic-gate )
24677c478bd9Sstevel@tonic-gate {
24687c478bd9Sstevel@tonic-gate 	int			slice;
24697c478bd9Sstevel@tonic-gate 	mdname_t		*np;
24707c478bd9Sstevel@tonic-gate 	mddrivename_t		*dnp;
24717c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
24727c478bd9Sstevel@tonic-gate 	int			err;
24737c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
24747c478bd9Sstevel@tonic-gate 
24752a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
24767c478bd9Sstevel@tonic-gate 	switch (args->rev) {
24777c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
24787c478bd9Sstevel@tonic-gate 		dnp = (&(args->mdrpc_devid_2_args_u.rev1))->drivenamep;
24797c478bd9Sstevel@tonic-gate 		break;
24807c478bd9Sstevel@tonic-gate 	default:
24817c478bd9Sstevel@tonic-gate 		return (FALSE);
24827c478bd9Sstevel@tonic-gate 	}
24837c478bd9Sstevel@tonic-gate 
24847c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
24857c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
24867c478bd9Sstevel@tonic-gate 		return (FALSE);
24877c478bd9Sstevel@tonic-gate 	else if (err != 0)
24887c478bd9Sstevel@tonic-gate 		return (TRUE);
24897c478bd9Sstevel@tonic-gate 
24907c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
24917c478bd9Sstevel@tonic-gate 		return (TRUE);
24927c478bd9Sstevel@tonic-gate 
24937c478bd9Sstevel@tonic-gate 	/*
24947c478bd9Sstevel@tonic-gate 	 * fix all the drivenamep's in the mdname_t's to
24957c478bd9Sstevel@tonic-gate 	 * point to the right place.
24967c478bd9Sstevel@tonic-gate 	 */
24977c478bd9Sstevel@tonic-gate 	for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
24987c478bd9Sstevel@tonic-gate 		if ((np = metaslicename(dnp, slice, ep)) == NULL)
24997c478bd9Sstevel@tonic-gate 			return (TRUE);
25007c478bd9Sstevel@tonic-gate 		np->drivenamep = dnp;
25017c478bd9Sstevel@tonic-gate 	}
25027c478bd9Sstevel@tonic-gate 
25037c478bd9Sstevel@tonic-gate 	/* doit */
25047c478bd9Sstevel@tonic-gate 	mdrpc_get_devid((&(args->mdrpc_devid_2_args_u.rev1))->sp, dnp, res, ep);
25057c478bd9Sstevel@tonic-gate 
25067c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
25077c478bd9Sstevel@tonic-gate 
25087c478bd9Sstevel@tonic-gate 	return (TRUE);
25097c478bd9Sstevel@tonic-gate }
25107c478bd9Sstevel@tonic-gate 
25117c478bd9Sstevel@tonic-gate /*
25127c478bd9Sstevel@tonic-gate  * This routine should not be called for a multi-node diskset.
25137c478bd9Sstevel@tonic-gate  *
25147c478bd9Sstevel@tonic-gate  * The devid support is disabled for MN diskset so this routine
25157c478bd9Sstevel@tonic-gate  * will not be called if the set is MN diskset.  The check has
25167c478bd9Sstevel@tonic-gate  * been done early in meta_getnextside_devinfo.  However this
25177c478bd9Sstevel@tonic-gate  * routine will be called when the devid support for MN set is
25187c478bd9Sstevel@tonic-gate  * enabled and check is removed.
25197c478bd9Sstevel@tonic-gate  */
25207c478bd9Sstevel@tonic-gate bool_t
mdrpc_devinfo_by_devid_2_svc(mdrpc_devidstr_args * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)25217c478bd9Sstevel@tonic-gate mdrpc_devinfo_by_devid_2_svc(
25227c478bd9Sstevel@tonic-gate 	mdrpc_devidstr_args	*args,
25237c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_2_res	*res,
25247c478bd9Sstevel@tonic-gate 	struct svc_req	  *rqstp		  /* RPC stuff */
25257c478bd9Sstevel@tonic-gate )
25267c478bd9Sstevel@tonic-gate {
25277c478bd9Sstevel@tonic-gate 
25287c478bd9Sstevel@tonic-gate 	char		*devidstr = args->enc_devid;
25297c478bd9Sstevel@tonic-gate 	md_error_t	*ep = &res->status;
25307c478bd9Sstevel@tonic-gate 	ddi_devid_t	devid;
25317c478bd9Sstevel@tonic-gate 	char		*minor_name = NULL;
25327c478bd9Sstevel@tonic-gate 	int		ret = 0;
25337c478bd9Sstevel@tonic-gate 	int		err;
25347c478bd9Sstevel@tonic-gate 	devid_nmlist_t	*disklist = NULL;
25357c478bd9Sstevel@tonic-gate 	int		op_mode = R_OK;
25367c478bd9Sstevel@tonic-gate 	mdname_t	*np;
25377c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp = args->sp;
25387c478bd9Sstevel@tonic-gate 
25397c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
25407c478bd9Sstevel@tonic-gate 	(void) memset(res, 0, sizeof (*res));
25417c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
25427c478bd9Sstevel@tonic-gate 		return (FALSE);
25437c478bd9Sstevel@tonic-gate 	else if (err != 0)
25447c478bd9Sstevel@tonic-gate 		return (TRUE);
25457c478bd9Sstevel@tonic-gate 
25467c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
25477c478bd9Sstevel@tonic-gate 		return (TRUE);
25487c478bd9Sstevel@tonic-gate 
25497c478bd9Sstevel@tonic-gate 	if (devid_str_decode(devidstr, &devid, &minor_name) != 0)
25507c478bd9Sstevel@tonic-gate 		return (TRUE);
25517c478bd9Sstevel@tonic-gate 
25527c478bd9Sstevel@tonic-gate 	/*
25537c478bd9Sstevel@tonic-gate 	 * if we do not have a minor name then look for a character device.
25547c478bd9Sstevel@tonic-gate 	 * This is because the caller (checkdrive_onnode) expects a character
25557c478bd9Sstevel@tonic-gate 	 * device to be returned. The other client of this interface is
25567c478bd9Sstevel@tonic-gate 	 * meta_getnextside_devinfo and this supplies a minor name.
25577c478bd9Sstevel@tonic-gate 	 */
25587c478bd9Sstevel@tonic-gate 	if (minor_name == NULL) {
25597c478bd9Sstevel@tonic-gate 		ret = meta_deviceid_to_nmlist("/dev", devid,
25607c478bd9Sstevel@tonic-gate 		    DEVID_MINOR_NAME_ALL_CHR, &disklist);
25617c478bd9Sstevel@tonic-gate 	} else {
25627c478bd9Sstevel@tonic-gate 		ret = meta_deviceid_to_nmlist("/dev", devid, minor_name,
25637c478bd9Sstevel@tonic-gate 		    &disklist);
25647c478bd9Sstevel@tonic-gate 		devid_str_free(minor_name);
25657c478bd9Sstevel@tonic-gate 	}
25667c478bd9Sstevel@tonic-gate 
25677c478bd9Sstevel@tonic-gate 	devid_free(devid);
25687c478bd9Sstevel@tonic-gate 	if (ret != 0) {
25697c478bd9Sstevel@tonic-gate 		res->dev = NODEV64;
25707c478bd9Sstevel@tonic-gate 		devid_free_nmlist(disklist);
25717c478bd9Sstevel@tonic-gate 		return (TRUE);
25727c478bd9Sstevel@tonic-gate 	}
25737c478bd9Sstevel@tonic-gate 
2574d7cd8252Stw21770 	np = metaname(&sp, disklist[0].devname, LOGICAL_DEVICE, ep);
25757c478bd9Sstevel@tonic-gate 	if (np != NULL) {
25767c478bd9Sstevel@tonic-gate 		mdcinfo_t	*cinfo;
25777c478bd9Sstevel@tonic-gate 		if ((cinfo = metagetcinfo(np, ep)) != NULL) {
25787c478bd9Sstevel@tonic-gate 			res->drivername = Strdup(cinfo->dname);
25797c478bd9Sstevel@tonic-gate 		}
25807c478bd9Sstevel@tonic-gate 	}
25817c478bd9Sstevel@tonic-gate 
25827c478bd9Sstevel@tonic-gate 	res->dev = meta_expldev(disklist[0].dev);
25837c478bd9Sstevel@tonic-gate 	res->devname = strdup(disklist[0].devname);
25847c478bd9Sstevel@tonic-gate 
25857c478bd9Sstevel@tonic-gate 	devid_free_nmlist(disklist);
25867c478bd9Sstevel@tonic-gate 
25877c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
25887c478bd9Sstevel@tonic-gate 
25897c478bd9Sstevel@tonic-gate 	return (TRUE);
25907c478bd9Sstevel@tonic-gate }
25917c478bd9Sstevel@tonic-gate 
25927c478bd9Sstevel@tonic-gate /*
25937c478bd9Sstevel@tonic-gate  * This routine should not be called for a multi-node diskset.
25947c478bd9Sstevel@tonic-gate  *
25957c478bd9Sstevel@tonic-gate  * The devid support is disabled for MN diskset so this routine
25967c478bd9Sstevel@tonic-gate  * will not be called if the set is MN diskset.  The check has
25977c478bd9Sstevel@tonic-gate  * been done early in meta_getnextside_devinfo.  However this
25987c478bd9Sstevel@tonic-gate  * routine will be called when the devid support for MN set is
25997c478bd9Sstevel@tonic-gate  * enabled and check is removed.
26007c478bd9Sstevel@tonic-gate  *
26017c478bd9Sstevel@tonic-gate  * This function will return the device info attempting to use
26027c478bd9Sstevel@tonic-gate  * both the passed in devid and device name.  This is to deal
26037c478bd9Sstevel@tonic-gate  * with systems that use multi-path disks but not running mpxio.
26047c478bd9Sstevel@tonic-gate  * In this situation meta_deviceid_to_nmlist will return multiple
26057c478bd9Sstevel@tonic-gate  * devices.  The orig_devname is used to disambiguate.
26067c478bd9Sstevel@tonic-gate  *
26077c478bd9Sstevel@tonic-gate  */
26087c478bd9Sstevel@tonic-gate bool_t
mdrpc_devinfo_by_devid_name_2_svc(mdrpc_devid_name_2_args * args,mdrpc_devinfo_2_res * res,struct svc_req * rqstp)26097c478bd9Sstevel@tonic-gate mdrpc_devinfo_by_devid_name_2_svc(
26107c478bd9Sstevel@tonic-gate 	mdrpc_devid_name_2_args	*args,
26117c478bd9Sstevel@tonic-gate 	mdrpc_devinfo_2_res	*res,
26127c478bd9Sstevel@tonic-gate 	struct svc_req	  *rqstp		  /* RPC stuff */
26137c478bd9Sstevel@tonic-gate )
26147c478bd9Sstevel@tonic-gate {
26157c478bd9Sstevel@tonic-gate 
26167c478bd9Sstevel@tonic-gate 	char		*devidstr;
26177c478bd9Sstevel@tonic-gate 	char		*orig_devname;
26187c478bd9Sstevel@tonic-gate 	md_error_t	*ep = &res->status;
26197c478bd9Sstevel@tonic-gate 	ddi_devid_t	devid;
26207c478bd9Sstevel@tonic-gate 	char		*minor_name = NULL;
26217c478bd9Sstevel@tonic-gate 	int		ret = 0;
26227c478bd9Sstevel@tonic-gate 	int		err;
26237c478bd9Sstevel@tonic-gate 	int		i;
26247c478bd9Sstevel@tonic-gate 	devid_nmlist_t	*disklist = NULL;
26257c478bd9Sstevel@tonic-gate 	int		op_mode = R_OK;
26267c478bd9Sstevel@tonic-gate 	mdname_t	*np;
26277c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp;
26287c478bd9Sstevel@tonic-gate 
26292a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
26307c478bd9Sstevel@tonic-gate 	switch (args->rev) {
26317c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
26327c478bd9Sstevel@tonic-gate 		sp = (&(args->mdrpc_devid_name_2_args_u.rev1))->sp;
26337c478bd9Sstevel@tonic-gate 		devidstr = (&(args->mdrpc_devid_name_2_args_u.rev1))->enc_devid;
26347c478bd9Sstevel@tonic-gate 		orig_devname =
26357c478bd9Sstevel@tonic-gate 		    (&(args->mdrpc_devid_name_2_args_u.rev1))->orig_devname;
26367c478bd9Sstevel@tonic-gate 		break;
26377c478bd9Sstevel@tonic-gate 	default:
26387c478bd9Sstevel@tonic-gate 		return (FALSE);
26397c478bd9Sstevel@tonic-gate 	}
26407c478bd9Sstevel@tonic-gate 
26417c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
26427c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
26437c478bd9Sstevel@tonic-gate 		return (FALSE);
26447c478bd9Sstevel@tonic-gate 	else if (err != 0)
26457c478bd9Sstevel@tonic-gate 		return (TRUE);
26467c478bd9Sstevel@tonic-gate 
26477c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
26487c478bd9Sstevel@tonic-gate 		return (TRUE);
26497c478bd9Sstevel@tonic-gate 
26507c478bd9Sstevel@tonic-gate 	if (devid_str_decode(devidstr, &devid, &minor_name) != 0)
26517c478bd9Sstevel@tonic-gate 		return (TRUE);
26527c478bd9Sstevel@tonic-gate 
26537c478bd9Sstevel@tonic-gate 	/*
26547c478bd9Sstevel@tonic-gate 	 * if we do not have a minor name then look for a character device.
26557c478bd9Sstevel@tonic-gate 	 * This is because the caller (checkdrive_onnode) expects a character
26567c478bd9Sstevel@tonic-gate 	 * device to be returned. The other client of this interface is
26577c478bd9Sstevel@tonic-gate 	 * meta_getnextside_devinfo and this supplies a minor name.
26587c478bd9Sstevel@tonic-gate 	 */
26597c478bd9Sstevel@tonic-gate 	if (minor_name == NULL) {
26607c478bd9Sstevel@tonic-gate 		ret = meta_deviceid_to_nmlist("/dev", devid,
26617c478bd9Sstevel@tonic-gate 		    DEVID_MINOR_NAME_ALL_CHR, &disklist);
26627c478bd9Sstevel@tonic-gate 	} else {
26637c478bd9Sstevel@tonic-gate 		ret = meta_deviceid_to_nmlist("/dev", devid, minor_name,
26647c478bd9Sstevel@tonic-gate 		    &disklist);
26657c478bd9Sstevel@tonic-gate 		devid_str_free(minor_name);
26667c478bd9Sstevel@tonic-gate 	}
26677c478bd9Sstevel@tonic-gate 
26687c478bd9Sstevel@tonic-gate 	devid_free(devid);
26697c478bd9Sstevel@tonic-gate 	if (ret != 0) {
26707c478bd9Sstevel@tonic-gate 		res->dev = NODEV64;
26717c478bd9Sstevel@tonic-gate 		devid_free_nmlist(disklist);
26727c478bd9Sstevel@tonic-gate 		return (TRUE);
26737c478bd9Sstevel@tonic-gate 	}
26747c478bd9Sstevel@tonic-gate 
26757c478bd9Sstevel@tonic-gate 	/* attempt to match to the device name on the originating node */
26767c478bd9Sstevel@tonic-gate 	for (i = 0; disklist[i].dev != NODEV; i++) {
26777c478bd9Sstevel@tonic-gate 		if (strncmp(orig_devname, disklist[i].devname,
26787c478bd9Sstevel@tonic-gate 		    strlen(disklist[i].devname)) == 0)
26797c478bd9Sstevel@tonic-gate 			break;
26807c478bd9Sstevel@tonic-gate 	}
26817c478bd9Sstevel@tonic-gate 
26827c478bd9Sstevel@tonic-gate 	/* if it's not found then use the first disk in the list */
26837c478bd9Sstevel@tonic-gate 	if (disklist[i].dev == NODEV)
26847c478bd9Sstevel@tonic-gate 		i = 0;
26857c478bd9Sstevel@tonic-gate 
2686d7cd8252Stw21770 	np = metaname(&sp, disklist[i].devname, LOGICAL_DEVICE, ep);
26877c478bd9Sstevel@tonic-gate 	if (np != NULL) {
26887c478bd9Sstevel@tonic-gate 		mdcinfo_t	*cinfo;
26897c478bd9Sstevel@tonic-gate 		if ((cinfo = metagetcinfo(np, ep)) != NULL) {
26907c478bd9Sstevel@tonic-gate 			res->drivername = Strdup(cinfo->dname);
26917c478bd9Sstevel@tonic-gate 		}
26927c478bd9Sstevel@tonic-gate 	}
26937c478bd9Sstevel@tonic-gate 
26947c478bd9Sstevel@tonic-gate 	res->dev = meta_expldev(disklist[i].dev);
26957c478bd9Sstevel@tonic-gate 	res->devname = strdup(disklist[i].devname);
26967c478bd9Sstevel@tonic-gate 
26977c478bd9Sstevel@tonic-gate 	devid_free_nmlist(disklist);
26987c478bd9Sstevel@tonic-gate 
26997c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
27007c478bd9Sstevel@tonic-gate 
27017c478bd9Sstevel@tonic-gate 	return (TRUE);
27027c478bd9Sstevel@tonic-gate }
27037c478bd9Sstevel@tonic-gate 
27047c478bd9Sstevel@tonic-gate static void
drvused(mdsetname_t * sp,mddrivename_t * dnp,md_error_t * ep)27057c478bd9Sstevel@tonic-gate drvused(mdsetname_t *sp, mddrivename_t *dnp, md_error_t *ep)
27067c478bd9Sstevel@tonic-gate {
27077c478bd9Sstevel@tonic-gate 	if (meta_check_drivemounted(sp, dnp, ep))
27087c478bd9Sstevel@tonic-gate 		return;
27097c478bd9Sstevel@tonic-gate 
27107c478bd9Sstevel@tonic-gate 	if (meta_check_driveswapped(sp, dnp, ep))
27117c478bd9Sstevel@tonic-gate 		return;
27127c478bd9Sstevel@tonic-gate 
27137c478bd9Sstevel@tonic-gate 	if (meta_check_drive_inuse(metasetname(MD_LOCAL_NAME, ep), dnp,
27147c478bd9Sstevel@tonic-gate 	    TRUE, ep))
27157c478bd9Sstevel@tonic-gate 		return;
27167c478bd9Sstevel@tonic-gate 
27177c478bd9Sstevel@tonic-gate 	(void) meta_check_driveinset(sp, dnp, ep);
27187c478bd9Sstevel@tonic-gate }
27197c478bd9Sstevel@tonic-gate 
27207c478bd9Sstevel@tonic-gate /*
27217c478bd9Sstevel@tonic-gate  * determine if a device is in use.
27227c478bd9Sstevel@tonic-gate  */
27237c478bd9Sstevel@tonic-gate bool_t
mdrpc_drvused_common(mdrpc_drvused_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)27247c478bd9Sstevel@tonic-gate mdrpc_drvused_common(
27257c478bd9Sstevel@tonic-gate 	mdrpc_drvused_2_args_r1	*args,
27267c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
27277c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
27287c478bd9Sstevel@tonic-gate )
27297c478bd9Sstevel@tonic-gate {
27307c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
27317c478bd9Sstevel@tonic-gate 	int			slice;
27327c478bd9Sstevel@tonic-gate 	mdname_t		*np;
27337c478bd9Sstevel@tonic-gate 	mddrivename_t		*dnp = args->drivenamep;
27347c478bd9Sstevel@tonic-gate 	int			err;
27357c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
27367c478bd9Sstevel@tonic-gate 
27377c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
27387c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
27397c478bd9Sstevel@tonic-gate 		return (FALSE);
27407c478bd9Sstevel@tonic-gate 	else if (err != 0)
27417c478bd9Sstevel@tonic-gate 		return (TRUE);
27427c478bd9Sstevel@tonic-gate 
27437c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
27447c478bd9Sstevel@tonic-gate 		return (TRUE);
27457c478bd9Sstevel@tonic-gate 
27467c478bd9Sstevel@tonic-gate 	if (dnp == NULL) {
27477c478bd9Sstevel@tonic-gate 		/* no drive pointer specified */
27487c478bd9Sstevel@tonic-gate 		return (TRUE);
27497c478bd9Sstevel@tonic-gate 	}
27507c478bd9Sstevel@tonic-gate 	/*
27517c478bd9Sstevel@tonic-gate 	 * fix all the drivenamep's in the mdname_t's to
27527c478bd9Sstevel@tonic-gate 	 * point to the right place.
27537c478bd9Sstevel@tonic-gate 	 */
27547c478bd9Sstevel@tonic-gate 	for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
27557c478bd9Sstevel@tonic-gate 		if ((np = metaslicename(dnp, slice, ep)) == NULL)
27567c478bd9Sstevel@tonic-gate 			return (TRUE);
27577c478bd9Sstevel@tonic-gate 		np->drivenamep = dnp;
27587c478bd9Sstevel@tonic-gate 	}
27597c478bd9Sstevel@tonic-gate 
27607c478bd9Sstevel@tonic-gate 	/* doit */
27617c478bd9Sstevel@tonic-gate 	drvused(args->sp, dnp, ep);
27627c478bd9Sstevel@tonic-gate 
27637c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
27647c478bd9Sstevel@tonic-gate 
27657c478bd9Sstevel@tonic-gate 	return (TRUE);
27667c478bd9Sstevel@tonic-gate }
27677c478bd9Sstevel@tonic-gate 
27687c478bd9Sstevel@tonic-gate /*
27697c478bd9Sstevel@tonic-gate  * version 1 of the remote procedure. This procedure is called if the
27707c478bd9Sstevel@tonic-gate  * client is running in version 1. We first convert version 1 arguments
27717c478bd9Sstevel@tonic-gate  * into version 2 arguments and then call the common remote procedure.
27727c478bd9Sstevel@tonic-gate  */
27737c478bd9Sstevel@tonic-gate bool_t
mdrpc_drvused_1_svc(mdrpc_drvused_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)27747c478bd9Sstevel@tonic-gate mdrpc_drvused_1_svc(
27757c478bd9Sstevel@tonic-gate 	mdrpc_drvused_args	*args,
27767c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
27777c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
27787c478bd9Sstevel@tonic-gate )
27797c478bd9Sstevel@tonic-gate {
27807c478bd9Sstevel@tonic-gate 	bool_t			retval;
27817c478bd9Sstevel@tonic-gate 	mdrpc_drvused_2_args_r1	v2_args;
27827c478bd9Sstevel@tonic-gate 
27837c478bd9Sstevel@tonic-gate 	/* allocate memory */
27847c478bd9Sstevel@tonic-gate 	v2_args.drivenamep = Zalloc(sizeof (mddrivename_t));
27857c478bd9Sstevel@tonic-gate 	v2_args.drivenamep->parts.parts_val =
27867c478bd9Sstevel@tonic-gate 	    Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len);
27872a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
27887c478bd9Sstevel@tonic-gate 
27897c478bd9Sstevel@tonic-gate 	/* build args */
27907c478bd9Sstevel@tonic-gate 	v2_args.sp = args->sp;
27917c478bd9Sstevel@tonic-gate 	v2_args.cl_sk = args->cl_sk;
27927c478bd9Sstevel@tonic-gate 
27937c478bd9Sstevel@tonic-gate 	/* convert v1 args to v2 (revision 1) args */
27947c478bd9Sstevel@tonic-gate 	meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep);
27957c478bd9Sstevel@tonic-gate 	retval = mdrpc_drvused_common(&v2_args, res, rqstp);
27967c478bd9Sstevel@tonic-gate 
27977c478bd9Sstevel@tonic-gate 	free(v2_args.drivenamep);
27987c478bd9Sstevel@tonic-gate 	free(v2_args.drivenamep->parts.parts_val);
27997c478bd9Sstevel@tonic-gate 
28007c478bd9Sstevel@tonic-gate 	return (retval);
28017c478bd9Sstevel@tonic-gate }
28027c478bd9Sstevel@tonic-gate 
28037c478bd9Sstevel@tonic-gate bool_t
mdrpc_drvused_2_svc(mdrpc_drvused_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)28047c478bd9Sstevel@tonic-gate mdrpc_drvused_2_svc(
28057c478bd9Sstevel@tonic-gate 	mdrpc_drvused_2_args	*args,
28067c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
28077c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
28087c478bd9Sstevel@tonic-gate )
28097c478bd9Sstevel@tonic-gate {
28102a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
28117c478bd9Sstevel@tonic-gate 	switch (args->rev) {
28127c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
28137c478bd9Sstevel@tonic-gate 		return (mdrpc_drvused_common(
28147c478bd9Sstevel@tonic-gate 		    &args->mdrpc_drvused_2_args_u.rev1, res, rqstp));
28157c478bd9Sstevel@tonic-gate 	default:
28167c478bd9Sstevel@tonic-gate 		return (FALSE);
28177c478bd9Sstevel@tonic-gate 	}
28187c478bd9Sstevel@tonic-gate }
28197c478bd9Sstevel@tonic-gate 
28207c478bd9Sstevel@tonic-gate /*
28217c478bd9Sstevel@tonic-gate  * return a set records selected by name or number.
28227c478bd9Sstevel@tonic-gate  */
28237c478bd9Sstevel@tonic-gate bool_t
mdrpc_getset_common(mdrpc_getset_args * args,mdrpc_getset_res * res,struct svc_req * rqstp)28247c478bd9Sstevel@tonic-gate mdrpc_getset_common(
28257c478bd9Sstevel@tonic-gate 	mdrpc_getset_args	*args,
28267c478bd9Sstevel@tonic-gate 	mdrpc_getset_res 	*res,
28277c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
28287c478bd9Sstevel@tonic-gate )
28297c478bd9Sstevel@tonic-gate {
28307c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
28317c478bd9Sstevel@tonic-gate 	int			err;
28327c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
28337c478bd9Sstevel@tonic-gate 
28347c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
28357c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
28367c478bd9Sstevel@tonic-gate 		return (FALSE);
28377c478bd9Sstevel@tonic-gate 	else if (err != 0)
28387c478bd9Sstevel@tonic-gate 		return (TRUE);
28397c478bd9Sstevel@tonic-gate 
28407c478bd9Sstevel@tonic-gate 	/* Don't have a setno, so we don't check the lock */
28417c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
28427c478bd9Sstevel@tonic-gate 		return (TRUE);
28437c478bd9Sstevel@tonic-gate 
28447c478bd9Sstevel@tonic-gate 	/* doit */
28457c478bd9Sstevel@tonic-gate 	if (args->setname && *args->setname)
28467c478bd9Sstevel@tonic-gate 		res->sr = setdup(getsetbyname(args->setname, ep));
28477c478bd9Sstevel@tonic-gate 	else if (args->setno > 0)
28487c478bd9Sstevel@tonic-gate 		res->sr = setdup(getsetbynum(args->setno, ep));
28497c478bd9Sstevel@tonic-gate 	else
28507c478bd9Sstevel@tonic-gate 		res->sr = NULL;
28517c478bd9Sstevel@tonic-gate 
28527c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
28537c478bd9Sstevel@tonic-gate 
28547c478bd9Sstevel@tonic-gate 	return (TRUE);
28557c478bd9Sstevel@tonic-gate }
28567c478bd9Sstevel@tonic-gate 
28577c478bd9Sstevel@tonic-gate bool_t
mdrpc_getset_1_svc(mdrpc_getset_args * args,mdrpc_getset_res * res,struct svc_req * rqstp)28587c478bd9Sstevel@tonic-gate mdrpc_getset_1_svc(
28597c478bd9Sstevel@tonic-gate 	mdrpc_getset_args	*args,
28607c478bd9Sstevel@tonic-gate 	mdrpc_getset_res 	*res,
28617c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
28627c478bd9Sstevel@tonic-gate )
28637c478bd9Sstevel@tonic-gate {
28642a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
28657c478bd9Sstevel@tonic-gate 	return (mdrpc_getset_common(args, res, rqstp));
28667c478bd9Sstevel@tonic-gate }
28677c478bd9Sstevel@tonic-gate 
28687c478bd9Sstevel@tonic-gate bool_t
mdrpc_getset_2_svc(mdrpc_getset_2_args * args,mdrpc_getset_res * res,struct svc_req * rqstp)28697c478bd9Sstevel@tonic-gate mdrpc_getset_2_svc(
28707c478bd9Sstevel@tonic-gate 	mdrpc_getset_2_args	*args,
28717c478bd9Sstevel@tonic-gate 	mdrpc_getset_res 	*res,
28727c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
28737c478bd9Sstevel@tonic-gate )
28747c478bd9Sstevel@tonic-gate {
28752a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
28767c478bd9Sstevel@tonic-gate 	switch (args->rev) {
28777c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
28787c478bd9Sstevel@tonic-gate 		return (mdrpc_getset_common(
28797c478bd9Sstevel@tonic-gate 		    &args->mdrpc_getset_2_args_u.rev1, res, rqstp));
28807c478bd9Sstevel@tonic-gate 	default:
28817c478bd9Sstevel@tonic-gate 		return (FALSE);
28827c478bd9Sstevel@tonic-gate 	}
28837c478bd9Sstevel@tonic-gate }
28847c478bd9Sstevel@tonic-gate 
28857c478bd9Sstevel@tonic-gate /*
28867c478bd9Sstevel@tonic-gate  * return a MN set record selected by name or number.
28877c478bd9Sstevel@tonic-gate  */
28887c478bd9Sstevel@tonic-gate bool_t
mdrpc_mngetset_common(mdrpc_getset_args * args,mdrpc_mngetset_res * res,struct svc_req * rqstp)28897c478bd9Sstevel@tonic-gate mdrpc_mngetset_common(
28907c478bd9Sstevel@tonic-gate 	mdrpc_getset_args	*args,
28917c478bd9Sstevel@tonic-gate 	mdrpc_mngetset_res 	*res,
28927c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
28937c478bd9Sstevel@tonic-gate )
28947c478bd9Sstevel@tonic-gate {
28957c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
28967c478bd9Sstevel@tonic-gate 	int			err;
28977c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
28987c478bd9Sstevel@tonic-gate 	md_set_record		*sr = NULL;
28997c478bd9Sstevel@tonic-gate 	md_mnset_record		*mnsr = NULL;
29007c478bd9Sstevel@tonic-gate 
29017c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
29027c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
29037c478bd9Sstevel@tonic-gate 		return (FALSE);
29047c478bd9Sstevel@tonic-gate 	else if (err != 0)
29057c478bd9Sstevel@tonic-gate 		return (TRUE);
29067c478bd9Sstevel@tonic-gate 
29077c478bd9Sstevel@tonic-gate 	/* Don't have a setno, so we don't check the lock */
29087c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
29097c478bd9Sstevel@tonic-gate 		return (TRUE);
29107c478bd9Sstevel@tonic-gate 
29117c478bd9Sstevel@tonic-gate 	/* doit */
29127c478bd9Sstevel@tonic-gate 	res->mnsr = NULL;
29137c478bd9Sstevel@tonic-gate 	if (args->setname && *args->setname)
29147c478bd9Sstevel@tonic-gate 		sr = getsetbyname(args->setname, ep);
29157c478bd9Sstevel@tonic-gate 	else if (args->setno > 0)
29167c478bd9Sstevel@tonic-gate 		sr = getsetbynum(args->setno, ep);
29177c478bd9Sstevel@tonic-gate 
29187c478bd9Sstevel@tonic-gate 	if ((sr) && (MD_MNSET_REC(sr))) {
29197c478bd9Sstevel@tonic-gate 		mnsr = (struct md_mnset_record *)sr;
29207c478bd9Sstevel@tonic-gate 		res->mnsr = mnsetdup(mnsr);
29217c478bd9Sstevel@tonic-gate 	}
29227c478bd9Sstevel@tonic-gate 
29237c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
29247c478bd9Sstevel@tonic-gate 
29257c478bd9Sstevel@tonic-gate 	return (TRUE);
29267c478bd9Sstevel@tonic-gate }
29277c478bd9Sstevel@tonic-gate 
29287c478bd9Sstevel@tonic-gate bool_t
mdrpc_mngetset_2_svc(mdrpc_getset_2_args * args,mdrpc_mngetset_res * res,struct svc_req * rqstp)29297c478bd9Sstevel@tonic-gate mdrpc_mngetset_2_svc(
29307c478bd9Sstevel@tonic-gate 	mdrpc_getset_2_args	*args,
29317c478bd9Sstevel@tonic-gate 	mdrpc_mngetset_res	*res,
29327c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
29337c478bd9Sstevel@tonic-gate )
29347c478bd9Sstevel@tonic-gate {
29352a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
29367c478bd9Sstevel@tonic-gate 	switch (args->rev) {
29377c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
29387c478bd9Sstevel@tonic-gate 		return (mdrpc_mngetset_common(
29397c478bd9Sstevel@tonic-gate 		    &args->mdrpc_getset_2_args_u.rev1, res, rqstp));
29407c478bd9Sstevel@tonic-gate 	default:
29417c478bd9Sstevel@tonic-gate 		return (FALSE);
29427c478bd9Sstevel@tonic-gate 	}
29437c478bd9Sstevel@tonic-gate }
29447c478bd9Sstevel@tonic-gate 
29457c478bd9Sstevel@tonic-gate static void
upd_setmaster(mdsetname_t * sp,md_node_nm_t master_nodenm,int master_nodeid,md_error_t * ep)29467c478bd9Sstevel@tonic-gate upd_setmaster(
29477c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
29487c478bd9Sstevel@tonic-gate 	md_node_nm_t	master_nodenm,
29497c478bd9Sstevel@tonic-gate 	int		master_nodeid,
29507c478bd9Sstevel@tonic-gate 	md_error_t	*ep
29517c478bd9Sstevel@tonic-gate )
29527c478bd9Sstevel@tonic-gate {
29537c478bd9Sstevel@tonic-gate 	mdsetname_t	*local_sp;
29547c478bd9Sstevel@tonic-gate 	md_set_record	*sr;
29557c478bd9Sstevel@tonic-gate 	md_mnset_record	*mnsr;
29567c478bd9Sstevel@tonic-gate 	mddb_setmaster_config_t	sm;
29577c478bd9Sstevel@tonic-gate 
29587c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
29597c478bd9Sstevel@tonic-gate 		return;
29607c478bd9Sstevel@tonic-gate 
29617c478bd9Sstevel@tonic-gate 	metaflushsetname(local_sp);
29627c478bd9Sstevel@tonic-gate 
29637c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
29647c478bd9Sstevel@tonic-gate 		return;
29657c478bd9Sstevel@tonic-gate 
29667c478bd9Sstevel@tonic-gate 	if (MD_MNSET_REC(sr)) {
29677c478bd9Sstevel@tonic-gate 		mnsr = (struct md_mnset_record *)sr;
2968*80148899SSurya Prakki 		(void) strlcpy(mnsr->sr_master_nodenm, master_nodenm,
29697c478bd9Sstevel@tonic-gate 		    MD_MAX_NODENAME);
29707c478bd9Sstevel@tonic-gate 		mnsr->sr_master_nodeid = master_nodeid;
29717c478bd9Sstevel@tonic-gate 		if (master_nodeid != 0) {
29727c478bd9Sstevel@tonic-gate 			(void) memset(&sm, 0, sizeof (sm));
29737c478bd9Sstevel@tonic-gate 			sm.c_setno = sp->setno;
29747c478bd9Sstevel@tonic-gate 			/* Use magic to help protect ioctl against attack. */
29757c478bd9Sstevel@tonic-gate 			sm.c_magic = MDDB_SETMASTER_MAGIC;
29767c478bd9Sstevel@tonic-gate 			if (strcmp(master_nodenm, mynode()) == 0) {
29777c478bd9Sstevel@tonic-gate 				sm.c_current_host_master = 1;
29787c478bd9Sstevel@tonic-gate 			} else {
29797c478bd9Sstevel@tonic-gate 				sm.c_current_host_master = 0;
29807c478bd9Sstevel@tonic-gate 			}
29817c478bd9Sstevel@tonic-gate 			(void) metaioctl(MD_SETMASTER, &sm, &sm.c_mde, NULL);
29827c478bd9Sstevel@tonic-gate 			mdclrerror(&sm.c_mde);
29837c478bd9Sstevel@tonic-gate 		}
29847c478bd9Sstevel@tonic-gate 	}
29857c478bd9Sstevel@tonic-gate 
29867c478bd9Sstevel@tonic-gate out:
29877c478bd9Sstevel@tonic-gate 	commitset(sr, FALSE, ep);
29887c478bd9Sstevel@tonic-gate 	free_sr(sr);
29897c478bd9Sstevel@tonic-gate }
29907c478bd9Sstevel@tonic-gate 
29917c478bd9Sstevel@tonic-gate /*
29927c478bd9Sstevel@tonic-gate  * set the master and nodeid in node record
29937c478bd9Sstevel@tonic-gate  */
29947c478bd9Sstevel@tonic-gate bool_t
mdrpc_mnsetmaster_common(mdrpc_mnsetmaster_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)29957c478bd9Sstevel@tonic-gate mdrpc_mnsetmaster_common(
29967c478bd9Sstevel@tonic-gate 	mdrpc_mnsetmaster_args	*args,
29977c478bd9Sstevel@tonic-gate 	mdrpc_generic_res 	*res,
29987c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
29997c478bd9Sstevel@tonic-gate )
30007c478bd9Sstevel@tonic-gate {
30017c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
30027c478bd9Sstevel@tonic-gate 	int			err;
30037c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
30047c478bd9Sstevel@tonic-gate 
30057c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
30067c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
30077c478bd9Sstevel@tonic-gate 		return (FALSE);
30087c478bd9Sstevel@tonic-gate 	else if (err != 0)
30097c478bd9Sstevel@tonic-gate 		return (TRUE);
30107c478bd9Sstevel@tonic-gate 
30117c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
30127c478bd9Sstevel@tonic-gate 		return (TRUE);
30137c478bd9Sstevel@tonic-gate 
30147c478bd9Sstevel@tonic-gate 	/* doit */
30157c478bd9Sstevel@tonic-gate 	upd_setmaster(args->sp, args->master_nodenm, args->master_nodeid, ep);
30167c478bd9Sstevel@tonic-gate 
30177c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
30187c478bd9Sstevel@tonic-gate 
30197c478bd9Sstevel@tonic-gate 	return (TRUE);
30207c478bd9Sstevel@tonic-gate }
30217c478bd9Sstevel@tonic-gate 
30227c478bd9Sstevel@tonic-gate bool_t
mdrpc_mnsetmaster_2_svc(mdrpc_mnsetmaster_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)30237c478bd9Sstevel@tonic-gate mdrpc_mnsetmaster_2_svc(
30247c478bd9Sstevel@tonic-gate 	mdrpc_mnsetmaster_2_args	*args,
30257c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
30267c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
30277c478bd9Sstevel@tonic-gate )
30287c478bd9Sstevel@tonic-gate {
30292a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
30307c478bd9Sstevel@tonic-gate 	switch (args->rev) {
30317c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
30327c478bd9Sstevel@tonic-gate 		return (mdrpc_mnsetmaster_common(
30337c478bd9Sstevel@tonic-gate 		    &args->mdrpc_mnsetmaster_2_args_u.rev1, res, rqstp));
30347c478bd9Sstevel@tonic-gate 	default:
30357c478bd9Sstevel@tonic-gate 		return (FALSE);
30367c478bd9Sstevel@tonic-gate 	}
30377c478bd9Sstevel@tonic-gate }
30387c478bd9Sstevel@tonic-gate 
30397c478bd9Sstevel@tonic-gate /*
30407c478bd9Sstevel@tonic-gate  * Join this node to the diskset.
30417c478bd9Sstevel@tonic-gate  * Pass stale_flag information to snarf_set so that snarf code
30427c478bd9Sstevel@tonic-gate  * can choose a STALE or non-STALE state when starting the set.
30437c478bd9Sstevel@tonic-gate  * If master is STALE, any joining node will join a stale set regardless
30447c478bd9Sstevel@tonic-gate  * of the number of accessible mddbs.  Also, if master is at 50%
30457c478bd9Sstevel@tonic-gate  * accessible replicas and is in the TOOFEW state, don't mark newly
30467c478bd9Sstevel@tonic-gate  * joining node as STALE; mark it TOOFEW instead.
30477c478bd9Sstevel@tonic-gate  */
30487c478bd9Sstevel@tonic-gate static void
joinset(mdsetname_t * sp,int flags,md_error_t * ep)30497c478bd9Sstevel@tonic-gate joinset(
30507c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
30517c478bd9Sstevel@tonic-gate 	int		flags,
30527c478bd9Sstevel@tonic-gate 	md_error_t	*ep
30537c478bd9Sstevel@tonic-gate )
30547c478bd9Sstevel@tonic-gate {
30557c478bd9Sstevel@tonic-gate 	mdsetname_t		*local_sp;
30567c478bd9Sstevel@tonic-gate 	md_drive_desc		*mydd;
30577c478bd9Sstevel@tonic-gate 	bool_t			stale_bool;
30587c478bd9Sstevel@tonic-gate 	mddb_block_parm_t	mbp;
30597c478bd9Sstevel@tonic-gate 	md_error_t		xep = mdnullerror;
30607c478bd9Sstevel@tonic-gate 
30617c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
30627c478bd9Sstevel@tonic-gate 		return;
30637c478bd9Sstevel@tonic-gate 
30647c478bd9Sstevel@tonic-gate 	/*
30657c478bd9Sstevel@tonic-gate 	 * Start mddoors daemon here.
30667c478bd9Sstevel@tonic-gate 	 * mddoors itself takes care there will be
30677c478bd9Sstevel@tonic-gate 	 * only one instance running, so starting it twice won't hurt
30687c478bd9Sstevel@tonic-gate 	 */
3069*80148899SSurya Prakki 	(void) pclose(popen(MDDOORS, "w"));
30707c478bd9Sstevel@tonic-gate 
30717c478bd9Sstevel@tonic-gate 	/*
30727c478bd9Sstevel@tonic-gate 	 * Get latest copy of data.  If a drive was just added causing
30737c478bd9Sstevel@tonic-gate 	 * nodes to get joined - this drive won't be in the local
30747c478bd9Sstevel@tonic-gate 	 * name caches drive list yet.
30757c478bd9Sstevel@tonic-gate 	 */
30767c478bd9Sstevel@tonic-gate 	metaflushsetname(local_sp);
30777c478bd9Sstevel@tonic-gate 
30787c478bd9Sstevel@tonic-gate 	mydd = metaget_drivedesc(local_sp, (MD_BASICNAME_OK | PRINT_FAST), ep);
30797c478bd9Sstevel@tonic-gate 	if (mydd) {
3080b45175a7Sskamm 		/*
3081b45175a7Sskamm 		 * Causes mddbs to be loaded into the kernel.
3082b45175a7Sskamm 		 * Set the force flag so that replica locations can be loaded
3083b45175a7Sskamm 		 * into the kernel even if a mediator node was unavailable.
3084b45175a7Sskamm 		 * This allows a node to join an MO diskset when there are
3085b45175a7Sskamm 		 * sufficient replicas available, but a mediator node
3086b45175a7Sskamm 		 * in unavailable.
3087b45175a7Sskamm 		 */
3088b45175a7Sskamm 		if (setup_db_bydd(local_sp, mydd, TRUE, ep) == -1) {
30897c478bd9Sstevel@tonic-gate 			/* If ep isn't set for some reason, set it */
3090b45175a7Sskamm 			if (mdisok(ep)) {
3091b6c8bd52Sjeanm 				(void) mdmddberror(ep, MDE_DB_NOTNOW,
3092b6c8bd52Sjeanm 				    (minor_t)NODEV64, sp->setno, 0, NULL);
30937c478bd9Sstevel@tonic-gate 			}
30947c478bd9Sstevel@tonic-gate 			return;
30957c478bd9Sstevel@tonic-gate 		}
30967c478bd9Sstevel@tonic-gate 
30977c478bd9Sstevel@tonic-gate 		if (flags & MNSET_IS_STALE)
30987c478bd9Sstevel@tonic-gate 			stale_bool = TRUE;
30997c478bd9Sstevel@tonic-gate 		else
31007c478bd9Sstevel@tonic-gate 			stale_bool = FALSE;
31017c478bd9Sstevel@tonic-gate 
31027c478bd9Sstevel@tonic-gate 		/*
31037c478bd9Sstevel@tonic-gate 		 * Snarf the set.  No failure has occurred if STALE or
31047c478bd9Sstevel@tonic-gate 		 * ACCOK error was set.  Otherwise, fail the call setting
31057c478bd9Sstevel@tonic-gate 		 * a generic error if no error was already set.
31067c478bd9Sstevel@tonic-gate 		 *
31077c478bd9Sstevel@tonic-gate 		 * STALE means that set has < 50% mddbs.
31087c478bd9Sstevel@tonic-gate 		 * ACCOK means that the mediator provided an extra vote.
31097c478bd9Sstevel@tonic-gate 		 */
31107c478bd9Sstevel@tonic-gate 		if (snarf_set(local_sp, stale_bool, ep) != 0) {
31117c478bd9Sstevel@tonic-gate 			if (!(mdismddberror(ep, MDE_DB_STALE)) &&
31127c478bd9Sstevel@tonic-gate 			    !(mdismddberror(ep, MDE_DB_ACCOK))) {
31137c478bd9Sstevel@tonic-gate 				return;
31147c478bd9Sstevel@tonic-gate 			} else if (mdisok(ep)) {
31157c478bd9Sstevel@tonic-gate 				/* If snarf failed, but no error set - set it */
3116b6c8bd52Sjeanm 				(void) mdmddberror(ep, MDE_DB_NOTNOW,
3117b6c8bd52Sjeanm 				    (minor_t)NODEV64, sp->setno, 0, NULL);
31187c478bd9Sstevel@tonic-gate 				return;
31197c478bd9Sstevel@tonic-gate 			}
31207c478bd9Sstevel@tonic-gate 		}
31217c478bd9Sstevel@tonic-gate 
31227c478bd9Sstevel@tonic-gate 		/*
31237c478bd9Sstevel@tonic-gate 		 * If node is joining during reconfig cycle, then
31247c478bd9Sstevel@tonic-gate 		 * set mddb_parse to be in blocked state so that
31257c478bd9Sstevel@tonic-gate 		 * mddb reparse messages are not generated until
31267c478bd9Sstevel@tonic-gate 		 * the commd has been resumed later in the reconfig
31277c478bd9Sstevel@tonic-gate 		 * cycle.
31287c478bd9Sstevel@tonic-gate 		 */
31297c478bd9Sstevel@tonic-gate 		if (flags & MNSET_IN_RECONFIG) {
31307c478bd9Sstevel@tonic-gate 			(void) memset(&mbp, 0, sizeof (mbp));
31317c478bd9Sstevel@tonic-gate 			if (s_ownset(sp->setno, &xep) == MD_SETOWNER_YES) {
31327c478bd9Sstevel@tonic-gate 				(void) memset(&mbp, 0, sizeof (mbp));
31337c478bd9Sstevel@tonic-gate 				mbp.c_setno = local_sp->setno;
31347c478bd9Sstevel@tonic-gate 				mbp.c_blk_flags = MDDB_BLOCK_PARSE;
31357c478bd9Sstevel@tonic-gate 				if (metaioctl(MD_MN_MDDB_BLOCK, &mbp,
31367c478bd9Sstevel@tonic-gate 				    &mbp.c_mde, NULL)) {
3137*80148899SSurya Prakki 					(void) mdstealerror(&xep, &mbp.c_mde);
31387c478bd9Sstevel@tonic-gate 					mde_perror(ep, gettext(
31397c478bd9Sstevel@tonic-gate 					    "Could not block set %s"),
31407c478bd9Sstevel@tonic-gate 					    sp->setname);
31417c478bd9Sstevel@tonic-gate 					return;
31427c478bd9Sstevel@tonic-gate 				}
31437c478bd9Sstevel@tonic-gate 			}
31447c478bd9Sstevel@tonic-gate 			/*
31457c478bd9Sstevel@tonic-gate 			 * If s_ownset fails and snarf_set succeeded,
31467c478bd9Sstevel@tonic-gate 			 * then can steal the ownset failure information
31477c478bd9Sstevel@tonic-gate 			 * and store it into ep. If snarf_set failed,
31487c478bd9Sstevel@tonic-gate 			 * don't overwrite critical ep information even
31497c478bd9Sstevel@tonic-gate 			 * if s_ownset failed.
31507c478bd9Sstevel@tonic-gate 			 */
31517c478bd9Sstevel@tonic-gate 			if (!mdisok(&xep)) {
31527c478bd9Sstevel@tonic-gate 				/*
31537c478bd9Sstevel@tonic-gate 				 * If snarf_set succeeded or snarf_set failed
31547c478bd9Sstevel@tonic-gate 				 * with MDE_DB_ACCOK (which is set if the
31557c478bd9Sstevel@tonic-gate 				 * mediator provided the extra vote) then
31567c478bd9Sstevel@tonic-gate 				 * steal the xep failure information and put
31577c478bd9Sstevel@tonic-gate 				 * into ep.
31587c478bd9Sstevel@tonic-gate 				 */
31597c478bd9Sstevel@tonic-gate 				if (mdisok(ep) ||
31607c478bd9Sstevel@tonic-gate 				    mdismddberror(ep, MDE_DB_ACCOK)) {
3161*80148899SSurya Prakki 					(void) mdstealerror(ep, &xep);
31627c478bd9Sstevel@tonic-gate 				}
31637c478bd9Sstevel@tonic-gate 			}
31647c478bd9Sstevel@tonic-gate 		}
31657c478bd9Sstevel@tonic-gate 	}
31667c478bd9Sstevel@tonic-gate }
31677c478bd9Sstevel@tonic-gate 
31687c478bd9Sstevel@tonic-gate /*
31697c478bd9Sstevel@tonic-gate  * Have this node join the set.
31707c478bd9Sstevel@tonic-gate  * This is called when a node has been
31717c478bd9Sstevel@tonic-gate  * added to a MN diskset that has drives.
31727c478bd9Sstevel@tonic-gate  * Also, called when a node is an alive
31737c478bd9Sstevel@tonic-gate  * member of a MN diskset and the first
31747c478bd9Sstevel@tonic-gate  * drive has been added.
31757c478bd9Sstevel@tonic-gate  */
31767c478bd9Sstevel@tonic-gate bool_t
mdrpc_joinset_common(mdrpc_sp_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)31777c478bd9Sstevel@tonic-gate mdrpc_joinset_common(
31787c478bd9Sstevel@tonic-gate 	mdrpc_sp_flags_args	*args,
31797c478bd9Sstevel@tonic-gate 	mdrpc_generic_res 	*res,
31807c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
31817c478bd9Sstevel@tonic-gate )
31827c478bd9Sstevel@tonic-gate {
31837c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
31847c478bd9Sstevel@tonic-gate 	int			err;
31857c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
31867c478bd9Sstevel@tonic-gate 
31877c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
31887c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
31897c478bd9Sstevel@tonic-gate 		return (FALSE);
31907c478bd9Sstevel@tonic-gate 	else if (err != 0)
31917c478bd9Sstevel@tonic-gate 		return (TRUE);
31927c478bd9Sstevel@tonic-gate 
31937c478bd9Sstevel@tonic-gate 	/*
31947c478bd9Sstevel@tonic-gate 	 * During reconfig, joinset can happen without
31957c478bd9Sstevel@tonic-gate 	 * locking first.  Turn off reconfig flag before calling
31967c478bd9Sstevel@tonic-gate 	 * joinset.
31977c478bd9Sstevel@tonic-gate 	 */
31987c478bd9Sstevel@tonic-gate 	if (!(args->flags & MNSET_IN_RECONFIG)) {
31997c478bd9Sstevel@tonic-gate 		if (check_set_lock(op_mode, args->cl_sk, ep))
32007c478bd9Sstevel@tonic-gate 			return (TRUE);
32017c478bd9Sstevel@tonic-gate 	}
32027c478bd9Sstevel@tonic-gate 
32037c478bd9Sstevel@tonic-gate 	/* doit */
32047c478bd9Sstevel@tonic-gate 	joinset(args->sp, args->flags, ep);
32057c478bd9Sstevel@tonic-gate 
32067c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
32077c478bd9Sstevel@tonic-gate 
32087c478bd9Sstevel@tonic-gate 	return (TRUE);
32097c478bd9Sstevel@tonic-gate }
32107c478bd9Sstevel@tonic-gate 
32117c478bd9Sstevel@tonic-gate bool_t
mdrpc_joinset_2_svc(mdrpc_sp_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)32127c478bd9Sstevel@tonic-gate mdrpc_joinset_2_svc(
32137c478bd9Sstevel@tonic-gate 	mdrpc_sp_flags_2_args	*args,
32147c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
32157c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
32167c478bd9Sstevel@tonic-gate )
32177c478bd9Sstevel@tonic-gate {
32182a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
32197c478bd9Sstevel@tonic-gate 	switch (args->rev) {
32207c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
32217c478bd9Sstevel@tonic-gate 		return (mdrpc_joinset_common(
32227c478bd9Sstevel@tonic-gate 		    &args->mdrpc_sp_flags_2_args_u.rev1, res, rqstp));
32237c478bd9Sstevel@tonic-gate 	default:
32247c478bd9Sstevel@tonic-gate 		return (FALSE);
32257c478bd9Sstevel@tonic-gate 	}
32267c478bd9Sstevel@tonic-gate }
32277c478bd9Sstevel@tonic-gate 
32287c478bd9Sstevel@tonic-gate static void
withdrawset(mdsetname_t * sp,md_error_t * ep)32297c478bd9Sstevel@tonic-gate withdrawset(
32307c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
32317c478bd9Sstevel@tonic-gate 	md_error_t	*ep
32327c478bd9Sstevel@tonic-gate )
32337c478bd9Sstevel@tonic-gate {
32347c478bd9Sstevel@tonic-gate 	mdsetname_t	*my_sp;
32357c478bd9Sstevel@tonic-gate 
32367c478bd9Sstevel@tonic-gate 	if ((my_sp = metasetname(sp->setname, ep)) == NULL)
32377c478bd9Sstevel@tonic-gate 		return;
32387c478bd9Sstevel@tonic-gate 
32397c478bd9Sstevel@tonic-gate 	(void) halt_set(my_sp, ep);
32407c478bd9Sstevel@tonic-gate }
32417c478bd9Sstevel@tonic-gate 
32427c478bd9Sstevel@tonic-gate /*
32437c478bd9Sstevel@tonic-gate  * Have this node withdraw from set.
32447c478bd9Sstevel@tonic-gate  * In response to a failure that occurred
32457c478bd9Sstevel@tonic-gate  * on the client after a joinset.
32467c478bd9Sstevel@tonic-gate  */
32477c478bd9Sstevel@tonic-gate bool_t
mdrpc_withdrawset_common(mdrpc_sp_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)32487c478bd9Sstevel@tonic-gate mdrpc_withdrawset_common(
32497c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,
32507c478bd9Sstevel@tonic-gate 	mdrpc_generic_res 	*res,
32517c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
32527c478bd9Sstevel@tonic-gate )
32537c478bd9Sstevel@tonic-gate {
32547c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
32557c478bd9Sstevel@tonic-gate 	int			err;
32567c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
32577c478bd9Sstevel@tonic-gate 
32587c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
32597c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
32607c478bd9Sstevel@tonic-gate 		return (FALSE);
32617c478bd9Sstevel@tonic-gate 	else if (err != 0)
32627c478bd9Sstevel@tonic-gate 		return (TRUE);
32637c478bd9Sstevel@tonic-gate 
32647c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
32657c478bd9Sstevel@tonic-gate 		return (TRUE);
32667c478bd9Sstevel@tonic-gate 
32677c478bd9Sstevel@tonic-gate 	/* doit */
32687c478bd9Sstevel@tonic-gate 	withdrawset(args->sp, ep);
32697c478bd9Sstevel@tonic-gate 
32707c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
32717c478bd9Sstevel@tonic-gate 
32727c478bd9Sstevel@tonic-gate 	return (TRUE);
32737c478bd9Sstevel@tonic-gate }
32747c478bd9Sstevel@tonic-gate 
32757c478bd9Sstevel@tonic-gate bool_t
mdrpc_withdrawset_2_svc(mdrpc_sp_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)32767c478bd9Sstevel@tonic-gate mdrpc_withdrawset_2_svc(
32777c478bd9Sstevel@tonic-gate 	mdrpc_sp_2_args		*args,
32787c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
32797c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
32807c478bd9Sstevel@tonic-gate )
32817c478bd9Sstevel@tonic-gate {
32822a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
32837c478bd9Sstevel@tonic-gate 	switch (args->rev) {
32847c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
32857c478bd9Sstevel@tonic-gate 		return (mdrpc_withdrawset_common(
32867c478bd9Sstevel@tonic-gate 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
32877c478bd9Sstevel@tonic-gate 	default:
32887c478bd9Sstevel@tonic-gate 		return (FALSE);
32897c478bd9Sstevel@tonic-gate 	}
32907c478bd9Sstevel@tonic-gate }
32917c478bd9Sstevel@tonic-gate 
32927c478bd9Sstevel@tonic-gate static mhd_mhiargs_t *
gtimeout(mdsetname_t * sp,md_error_t * ep)32937c478bd9Sstevel@tonic-gate gtimeout(mdsetname_t *sp, md_error_t *ep)
32947c478bd9Sstevel@tonic-gate {
32957c478bd9Sstevel@tonic-gate 	md_set_record		*sr;
32967c478bd9Sstevel@tonic-gate 	mhd_mhiargs_t		*mhiargs;
32977c478bd9Sstevel@tonic-gate 
32987c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
32997c478bd9Sstevel@tonic-gate 		return (NULL);
33007c478bd9Sstevel@tonic-gate 
33017c478bd9Sstevel@tonic-gate 	mhiargs = Zalloc(sizeof (*mhiargs));
33027c478bd9Sstevel@tonic-gate 	*mhiargs = sr->sr_mhiargs;
33037c478bd9Sstevel@tonic-gate 
33047c478bd9Sstevel@tonic-gate 	free_sr(sr);
33057c478bd9Sstevel@tonic-gate 	return (mhiargs);
33067c478bd9Sstevel@tonic-gate }
33077c478bd9Sstevel@tonic-gate 
33087c478bd9Sstevel@tonic-gate /*
33097c478bd9Sstevel@tonic-gate  * Get the MH timeout values for this set.
33107c478bd9Sstevel@tonic-gate  */
33117c478bd9Sstevel@tonic-gate bool_t
mdrpc_gtimeout_common(mdrpc_sp_args * args,mdrpc_gtimeout_res * res,struct svc_req * rqstp)33127c478bd9Sstevel@tonic-gate mdrpc_gtimeout_common(
33137c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,
33147c478bd9Sstevel@tonic-gate 	mdrpc_gtimeout_res 	*res,
33157c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
33167c478bd9Sstevel@tonic-gate )
33177c478bd9Sstevel@tonic-gate {
33187c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
33197c478bd9Sstevel@tonic-gate 	int			err;
33207c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
33217c478bd9Sstevel@tonic-gate 
33227c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
33237c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
33247c478bd9Sstevel@tonic-gate 		return (FALSE);
33257c478bd9Sstevel@tonic-gate 	else if (err != 0)
33267c478bd9Sstevel@tonic-gate 		return (TRUE);
33277c478bd9Sstevel@tonic-gate 
33287c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
33297c478bd9Sstevel@tonic-gate 		return (TRUE);
33307c478bd9Sstevel@tonic-gate 
33317c478bd9Sstevel@tonic-gate 	/* doit */
33327c478bd9Sstevel@tonic-gate 	res->mhiargsp = gtimeout(args->sp, ep);
33337c478bd9Sstevel@tonic-gate 
33347c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
33357c478bd9Sstevel@tonic-gate 
33367c478bd9Sstevel@tonic-gate 	return (TRUE);
33377c478bd9Sstevel@tonic-gate }
33387c478bd9Sstevel@tonic-gate 
33397c478bd9Sstevel@tonic-gate bool_t
mdrpc_gtimeout_1_svc(mdrpc_sp_args * args,mdrpc_gtimeout_res * res,struct svc_req * rqstp)33407c478bd9Sstevel@tonic-gate mdrpc_gtimeout_1_svc(
33417c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,
33427c478bd9Sstevel@tonic-gate 	mdrpc_gtimeout_res 	*res,
33437c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
33447c478bd9Sstevel@tonic-gate )
33457c478bd9Sstevel@tonic-gate {
33462a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
33477c478bd9Sstevel@tonic-gate 	return (mdrpc_gtimeout_common(args, res, rqstp));
33487c478bd9Sstevel@tonic-gate }
33497c478bd9Sstevel@tonic-gate 
33507c478bd9Sstevel@tonic-gate bool_t
mdrpc_gtimeout_2_svc(mdrpc_sp_2_args * args,mdrpc_gtimeout_res * res,struct svc_req * rqstp)33517c478bd9Sstevel@tonic-gate mdrpc_gtimeout_2_svc(
33527c478bd9Sstevel@tonic-gate 	mdrpc_sp_2_args		*args,
33537c478bd9Sstevel@tonic-gate 	mdrpc_gtimeout_res 	*res,
33547c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
33557c478bd9Sstevel@tonic-gate )
33567c478bd9Sstevel@tonic-gate {
33572a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
33587c478bd9Sstevel@tonic-gate 	switch (args->rev) {
33597c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
33607c478bd9Sstevel@tonic-gate 		return (mdrpc_gtimeout_common(
33617c478bd9Sstevel@tonic-gate 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
33627c478bd9Sstevel@tonic-gate 	default:
33637c478bd9Sstevel@tonic-gate 		return (FALSE);
33647c478bd9Sstevel@tonic-gate 	}
33657c478bd9Sstevel@tonic-gate }
33667c478bd9Sstevel@tonic-gate 
33677c478bd9Sstevel@tonic-gate /*
33687c478bd9Sstevel@tonic-gate  * return the official host name for the callee
33697c478bd9Sstevel@tonic-gate  */
33707c478bd9Sstevel@tonic-gate /*ARGSUSED*/
33717c478bd9Sstevel@tonic-gate bool_t
mdrpc_hostname_common(mdrpc_null_args * args,mdrpc_hostname_res * res,struct svc_req * rqstp)33727c478bd9Sstevel@tonic-gate mdrpc_hostname_common(
33737c478bd9Sstevel@tonic-gate 	mdrpc_null_args		*args,
33747c478bd9Sstevel@tonic-gate 	mdrpc_hostname_res 	*res,
33757c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
33767c478bd9Sstevel@tonic-gate )
33777c478bd9Sstevel@tonic-gate {
33787c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
33797c478bd9Sstevel@tonic-gate 	int			err;
33807c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
33817c478bd9Sstevel@tonic-gate 
33827c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
33837c478bd9Sstevel@tonic-gate 	(void) memset(res, 0, sizeof (*res));
33847c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
33857c478bd9Sstevel@tonic-gate 		return (FALSE);
33867c478bd9Sstevel@tonic-gate 	else if (err != 0)
33877c478bd9Sstevel@tonic-gate 		return (TRUE);
33887c478bd9Sstevel@tonic-gate 
33897c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
33907c478bd9Sstevel@tonic-gate 		return (TRUE);
33917c478bd9Sstevel@tonic-gate 
33927c478bd9Sstevel@tonic-gate 	/* doit */
33937c478bd9Sstevel@tonic-gate 	res->hostname = Strdup(mynode());
33947c478bd9Sstevel@tonic-gate 
33957c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
33967c478bd9Sstevel@tonic-gate 
33977c478bd9Sstevel@tonic-gate 	return (TRUE);
33987c478bd9Sstevel@tonic-gate }
33997c478bd9Sstevel@tonic-gate 
34007c478bd9Sstevel@tonic-gate bool_t
mdrpc_hostname_1_svc(mdrpc_null_args * args,mdrpc_hostname_res * res,struct svc_req * rqstp)34017c478bd9Sstevel@tonic-gate mdrpc_hostname_1_svc(
34027c478bd9Sstevel@tonic-gate 	mdrpc_null_args		*args,
34037c478bd9Sstevel@tonic-gate 	mdrpc_hostname_res 	*res,
34047c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
34057c478bd9Sstevel@tonic-gate )
34067c478bd9Sstevel@tonic-gate {
34077c478bd9Sstevel@tonic-gate 	return (mdrpc_hostname_common(args, res, rqstp));
34087c478bd9Sstevel@tonic-gate }
34097c478bd9Sstevel@tonic-gate 
34107c478bd9Sstevel@tonic-gate bool_t
mdrpc_hostname_2_svc(mdrpc_null_args * args,mdrpc_hostname_res * res,struct svc_req * rqstp)34117c478bd9Sstevel@tonic-gate mdrpc_hostname_2_svc(
34127c478bd9Sstevel@tonic-gate 	mdrpc_null_args		*args,
34137c478bd9Sstevel@tonic-gate 	mdrpc_hostname_res 	*res,
34147c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
34157c478bd9Sstevel@tonic-gate )
34167c478bd9Sstevel@tonic-gate {
34177c478bd9Sstevel@tonic-gate 	return (mdrpc_hostname_common(args, res, rqstp));
34187c478bd9Sstevel@tonic-gate }
34197c478bd9Sstevel@tonic-gate 
34207c478bd9Sstevel@tonic-gate /*
34217c478bd9Sstevel@tonic-gate  * return a response
34227c478bd9Sstevel@tonic-gate  */
34237c478bd9Sstevel@tonic-gate /*ARGSUSED*/
34247c478bd9Sstevel@tonic-gate bool_t
mdrpc_nullproc_common(void * args,md_error_t * ep,struct svc_req * rqstp)34257c478bd9Sstevel@tonic-gate mdrpc_nullproc_common(
34267c478bd9Sstevel@tonic-gate 	void		*args,
34277c478bd9Sstevel@tonic-gate 	md_error_t	*ep,
34287c478bd9Sstevel@tonic-gate 	struct svc_req	*rqstp		/* RPC stuff */
34297c478bd9Sstevel@tonic-gate )
34307c478bd9Sstevel@tonic-gate {
34317c478bd9Sstevel@tonic-gate 	*ep = mdnullerror;
34327c478bd9Sstevel@tonic-gate 	/* do nothing */
34337c478bd9Sstevel@tonic-gate 	return (TRUE);
34347c478bd9Sstevel@tonic-gate }
34357c478bd9Sstevel@tonic-gate 
34367c478bd9Sstevel@tonic-gate bool_t
mdrpc_nullproc_1_svc(void * args,md_error_t * ep,struct svc_req * rqstp)34377c478bd9Sstevel@tonic-gate mdrpc_nullproc_1_svc(
34387c478bd9Sstevel@tonic-gate 	void		*args,
34397c478bd9Sstevel@tonic-gate 	md_error_t	*ep,
34407c478bd9Sstevel@tonic-gate 	struct svc_req	*rqstp		/* RPC stuff */
34417c478bd9Sstevel@tonic-gate )
34427c478bd9Sstevel@tonic-gate {
34437c478bd9Sstevel@tonic-gate 	return (mdrpc_nullproc_common(args, ep, rqstp));
34447c478bd9Sstevel@tonic-gate }
34457c478bd9Sstevel@tonic-gate 
34467c478bd9Sstevel@tonic-gate bool_t
mdrpc_nullproc_2_svc(void * args,md_error_t * ep,struct svc_req * rqstp)34477c478bd9Sstevel@tonic-gate mdrpc_nullproc_2_svc(
34487c478bd9Sstevel@tonic-gate 	void		*args,
34497c478bd9Sstevel@tonic-gate 	md_error_t	*ep,
34507c478bd9Sstevel@tonic-gate 	struct svc_req	*rqstp		/* RPC stuff */
34517c478bd9Sstevel@tonic-gate )
34527c478bd9Sstevel@tonic-gate {
34537c478bd9Sstevel@tonic-gate 	return (mdrpc_nullproc_common(args, ep, rqstp));
34547c478bd9Sstevel@tonic-gate }
34557c478bd9Sstevel@tonic-gate 
34567c478bd9Sstevel@tonic-gate /*
34577c478bd9Sstevel@tonic-gate  * determine if the caller owns the set.
34587c478bd9Sstevel@tonic-gate  */
34597c478bd9Sstevel@tonic-gate bool_t
mdrpc_ownset_common(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)34607c478bd9Sstevel@tonic-gate mdrpc_ownset_common(
34617c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,
34627c478bd9Sstevel@tonic-gate 	mdrpc_bool_res		*res,
34637c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
34647c478bd9Sstevel@tonic-gate )
34657c478bd9Sstevel@tonic-gate {
34667c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
34677c478bd9Sstevel@tonic-gate 	int			err;
34687c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
34697c478bd9Sstevel@tonic-gate 
34707c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
34717c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
34727c478bd9Sstevel@tonic-gate 		return (FALSE);
34737c478bd9Sstevel@tonic-gate 	else if (err != 0)
34747c478bd9Sstevel@tonic-gate 		return (TRUE);
34757c478bd9Sstevel@tonic-gate 
34767c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
34777c478bd9Sstevel@tonic-gate 		return (TRUE);
34787c478bd9Sstevel@tonic-gate 
34797c478bd9Sstevel@tonic-gate 	/* doit */
34807c478bd9Sstevel@tonic-gate 	if (s_ownset(args->sp->setno, ep))
34817c478bd9Sstevel@tonic-gate 		res->value = TRUE;
34827c478bd9Sstevel@tonic-gate 	else
34837c478bd9Sstevel@tonic-gate 		res->value = FALSE;
34847c478bd9Sstevel@tonic-gate 
34857c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
34867c478bd9Sstevel@tonic-gate 
34877c478bd9Sstevel@tonic-gate 	return (TRUE);
34887c478bd9Sstevel@tonic-gate }
34897c478bd9Sstevel@tonic-gate 
34907c478bd9Sstevel@tonic-gate bool_t
mdrpc_ownset_1_svc(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)34917c478bd9Sstevel@tonic-gate mdrpc_ownset_1_svc(
34927c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,
34937c478bd9Sstevel@tonic-gate 	mdrpc_bool_res		*res,
34947c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
34957c478bd9Sstevel@tonic-gate )
34967c478bd9Sstevel@tonic-gate {
34972a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
34987c478bd9Sstevel@tonic-gate 	return (mdrpc_ownset_common(args, res, rqstp));
34997c478bd9Sstevel@tonic-gate }
35007c478bd9Sstevel@tonic-gate 
35017c478bd9Sstevel@tonic-gate bool_t
mdrpc_ownset_2_svc(mdrpc_sp_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)35027c478bd9Sstevel@tonic-gate mdrpc_ownset_2_svc(
35037c478bd9Sstevel@tonic-gate 	mdrpc_sp_2_args		*args,
35047c478bd9Sstevel@tonic-gate 	mdrpc_bool_res		*res,
35057c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
35067c478bd9Sstevel@tonic-gate )
35077c478bd9Sstevel@tonic-gate {
35082a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
35097c478bd9Sstevel@tonic-gate 	switch (args->rev) {
35107c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
35117c478bd9Sstevel@tonic-gate 		return (mdrpc_ownset_common(
35127c478bd9Sstevel@tonic-gate 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
35137c478bd9Sstevel@tonic-gate 	default:
35147c478bd9Sstevel@tonic-gate 		return (FALSE);
35157c478bd9Sstevel@tonic-gate 	}
35167c478bd9Sstevel@tonic-gate }
35177c478bd9Sstevel@tonic-gate 
35187c478bd9Sstevel@tonic-gate static int
setnameok(char * setname,md_error_t * ep)35197c478bd9Sstevel@tonic-gate setnameok(char *setname, md_error_t *ep)
35207c478bd9Sstevel@tonic-gate {
35217c478bd9Sstevel@tonic-gate 	int			rval = 0;
35227c478bd9Sstevel@tonic-gate 	struct	stat		statb;
35237c478bd9Sstevel@tonic-gate 	md_set_record		*sr = NULL;
35247c478bd9Sstevel@tonic-gate 	char			*setlink = NULL;
35257c478bd9Sstevel@tonic-gate 
35267c478bd9Sstevel@tonic-gate 	setlink = Strdup("/dev/md/");
35277c478bd9Sstevel@tonic-gate 	setlink = Realloc(setlink, strlen(setlink) + strlen(setname) + 1);
35287c478bd9Sstevel@tonic-gate 	(void) strcat(setlink, setname);
35297c478bd9Sstevel@tonic-gate 
35307c478bd9Sstevel@tonic-gate 	if (lstat(setlink, &statb) == -1) {
35317c478bd9Sstevel@tonic-gate 		/*
35327c478bd9Sstevel@tonic-gate 		 * If lstat() fails with ENOENT, setname is OK, if it
35337c478bd9Sstevel@tonic-gate 		 * fails for other than that, we fail the RPC
35347c478bd9Sstevel@tonic-gate 		 */
35357c478bd9Sstevel@tonic-gate 		if (errno == ENOENT) {
35367c478bd9Sstevel@tonic-gate 			rval = 1;
35377c478bd9Sstevel@tonic-gate 			goto out;
35387c478bd9Sstevel@tonic-gate 		}
35397c478bd9Sstevel@tonic-gate 
35407c478bd9Sstevel@tonic-gate 		(void) mdsyserror(ep, errno, setlink);
35417c478bd9Sstevel@tonic-gate 		goto out;
35427c478bd9Sstevel@tonic-gate 	}
35437c478bd9Sstevel@tonic-gate 
35447c478bd9Sstevel@tonic-gate 	/*
35457c478bd9Sstevel@tonic-gate 	 * If the lstat() succeeded, then we see what type of object
35467c478bd9Sstevel@tonic-gate 	 * we are dealing with, if it is a symlink, we do some further
35477c478bd9Sstevel@tonic-gate 	 * checking, if it is not a symlink, then we return an
35487c478bd9Sstevel@tonic-gate 	 * indication that the set name is NOT acceptable.
35497c478bd9Sstevel@tonic-gate 	 */
35507c478bd9Sstevel@tonic-gate 	if (! S_ISLNK(statb.st_mode))
35517c478bd9Sstevel@tonic-gate 		goto out;
35527c478bd9Sstevel@tonic-gate 
35537c478bd9Sstevel@tonic-gate 	/*
35547c478bd9Sstevel@tonic-gate 	 * We look up the setname to see if there is a set
35557c478bd9Sstevel@tonic-gate 	 * with that name, if there is, then we return
35567c478bd9Sstevel@tonic-gate 	 * an indication that the set name is NOT acceptable.
35577c478bd9Sstevel@tonic-gate 	 */
35587c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(setname, ep)) != NULL)
35597c478bd9Sstevel@tonic-gate 		goto out;
35607c478bd9Sstevel@tonic-gate 
35617c478bd9Sstevel@tonic-gate 	if (! mdiserror(ep, MDE_NO_SET))
35627c478bd9Sstevel@tonic-gate 		goto out;
35637c478bd9Sstevel@tonic-gate 
35647c478bd9Sstevel@tonic-gate 	mdclrerror(ep);
35657c478bd9Sstevel@tonic-gate 
35667c478bd9Sstevel@tonic-gate 	rval = 1;
35677c478bd9Sstevel@tonic-gate out:
35687c478bd9Sstevel@tonic-gate 	if (sr != NULL)
35697c478bd9Sstevel@tonic-gate 		free_sr(sr);
35707c478bd9Sstevel@tonic-gate 	Free(setlink);
35717c478bd9Sstevel@tonic-gate 	return (rval);
35727c478bd9Sstevel@tonic-gate }
35737c478bd9Sstevel@tonic-gate 
35747c478bd9Sstevel@tonic-gate /*
35757c478bd9Sstevel@tonic-gate  * Make sure the name of the set is OK.
35767c478bd9Sstevel@tonic-gate  */
35777c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnameok_common(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)35787c478bd9Sstevel@tonic-gate mdrpc_setnameok_common(
35797c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,	/* device name */
35807c478bd9Sstevel@tonic-gate 	mdrpc_bool_res		*res,
35817c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp	/* RPC stuff */
35827c478bd9Sstevel@tonic-gate )
35837c478bd9Sstevel@tonic-gate {
35847c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
35857c478bd9Sstevel@tonic-gate 	int			err;
35867c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
35877c478bd9Sstevel@tonic-gate 
35887c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
35897c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
35907c478bd9Sstevel@tonic-gate 		return (FALSE);
35917c478bd9Sstevel@tonic-gate 	else if (err != 0)
35927c478bd9Sstevel@tonic-gate 		return (TRUE);
35937c478bd9Sstevel@tonic-gate 
35947c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
35957c478bd9Sstevel@tonic-gate 		return (TRUE);
35967c478bd9Sstevel@tonic-gate 
35977c478bd9Sstevel@tonic-gate 	/* doit */
35987c478bd9Sstevel@tonic-gate 	res->value = setnameok(args->sp->setname, ep);
35997c478bd9Sstevel@tonic-gate 
36007c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
36017c478bd9Sstevel@tonic-gate 
36027c478bd9Sstevel@tonic-gate 	return (TRUE);
36037c478bd9Sstevel@tonic-gate }
36047c478bd9Sstevel@tonic-gate 
36057c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnameok_1_svc(mdrpc_sp_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36067c478bd9Sstevel@tonic-gate mdrpc_setnameok_1_svc(
36077c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args,	/* device name */
36087c478bd9Sstevel@tonic-gate 	mdrpc_bool_res		*res,
36097c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp	/* RPC stuff */
36107c478bd9Sstevel@tonic-gate )
36117c478bd9Sstevel@tonic-gate {
36122a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
36137c478bd9Sstevel@tonic-gate 	return (mdrpc_setnameok_common(args, res, rqstp));
36147c478bd9Sstevel@tonic-gate }
36157c478bd9Sstevel@tonic-gate 
36167c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnameok_2_svc(mdrpc_sp_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36177c478bd9Sstevel@tonic-gate mdrpc_setnameok_2_svc(
36187c478bd9Sstevel@tonic-gate 	mdrpc_sp_2_args		*args,	/* device name */
36197c478bd9Sstevel@tonic-gate 	mdrpc_bool_res		*res,
36207c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp	/* RPC stuff */
36217c478bd9Sstevel@tonic-gate )
36227c478bd9Sstevel@tonic-gate {
36232a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
36247c478bd9Sstevel@tonic-gate 	switch (args->rev) {
36257c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
36267c478bd9Sstevel@tonic-gate 		return (mdrpc_setnameok_common(
36277c478bd9Sstevel@tonic-gate 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
36287c478bd9Sstevel@tonic-gate 	default:
36297c478bd9Sstevel@tonic-gate 		return (FALSE);
36307c478bd9Sstevel@tonic-gate 	}
36317c478bd9Sstevel@tonic-gate }
36327c478bd9Sstevel@tonic-gate 
36337c478bd9Sstevel@tonic-gate /*
36347c478bd9Sstevel@tonic-gate  * determine if the setnumber we want to share is in use.
36357c478bd9Sstevel@tonic-gate  */
36367c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnumbusy_common(mdrpc_setno_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36377c478bd9Sstevel@tonic-gate mdrpc_setnumbusy_common(
36387c478bd9Sstevel@tonic-gate 	mdrpc_setno_args	*args,
36397c478bd9Sstevel@tonic-gate 	mdrpc_bool_res		*res,
36407c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
36417c478bd9Sstevel@tonic-gate )
36427c478bd9Sstevel@tonic-gate {
36437c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
36447c478bd9Sstevel@tonic-gate 	md_set_record		*sr = NULL;
36457c478bd9Sstevel@tonic-gate 	int			err;
36467c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
36477c478bd9Sstevel@tonic-gate 
36487c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
36497c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
36507c478bd9Sstevel@tonic-gate 		return (FALSE);
36517c478bd9Sstevel@tonic-gate 	else if (err != 0)
36527c478bd9Sstevel@tonic-gate 		return (TRUE);
36537c478bd9Sstevel@tonic-gate 
36547c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
36557c478bd9Sstevel@tonic-gate 		return (TRUE);
36567c478bd9Sstevel@tonic-gate 
36577c478bd9Sstevel@tonic-gate 	/* doit */
36587c478bd9Sstevel@tonic-gate 	if ((sr = getsetbynum(args->setno, ep)) != NULL) {
36597c478bd9Sstevel@tonic-gate 		res->value = TRUE;
36607c478bd9Sstevel@tonic-gate 		free_sr(sr);
36617c478bd9Sstevel@tonic-gate 		return (TRUE);
36627c478bd9Sstevel@tonic-gate 	}
36637c478bd9Sstevel@tonic-gate 	res->value = FALSE;
36647c478bd9Sstevel@tonic-gate 	if (mdiserror(ep, MDE_NO_SET))
36657c478bd9Sstevel@tonic-gate 		mdclrerror(ep);
36667c478bd9Sstevel@tonic-gate 
36677c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
36687c478bd9Sstevel@tonic-gate 
36697c478bd9Sstevel@tonic-gate 	return (TRUE);
36707c478bd9Sstevel@tonic-gate }
36717c478bd9Sstevel@tonic-gate 
36727c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnumbusy_1_svc(mdrpc_setno_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36737c478bd9Sstevel@tonic-gate mdrpc_setnumbusy_1_svc(
36747c478bd9Sstevel@tonic-gate 	mdrpc_setno_args	*args,
36757c478bd9Sstevel@tonic-gate 	mdrpc_bool_res		*res,
36767c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
36777c478bd9Sstevel@tonic-gate )
36787c478bd9Sstevel@tonic-gate {
36792a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
36807c478bd9Sstevel@tonic-gate 	return (mdrpc_setnumbusy_common(args, res, rqstp));
36817c478bd9Sstevel@tonic-gate }
36827c478bd9Sstevel@tonic-gate 
36837c478bd9Sstevel@tonic-gate bool_t
mdrpc_setnumbusy_2_svc(mdrpc_setno_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)36847c478bd9Sstevel@tonic-gate mdrpc_setnumbusy_2_svc(
36857c478bd9Sstevel@tonic-gate 	mdrpc_setno_2_args	*args,
36867c478bd9Sstevel@tonic-gate 	mdrpc_bool_res		*res,
36877c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
36887c478bd9Sstevel@tonic-gate )
36897c478bd9Sstevel@tonic-gate {
36902a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
36917c478bd9Sstevel@tonic-gate 	switch (args->rev) {
36927c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
36937c478bd9Sstevel@tonic-gate 		return (mdrpc_setnumbusy_common(
36947c478bd9Sstevel@tonic-gate 		    &args->mdrpc_setno_2_args_u.rev1, res, rqstp));
36957c478bd9Sstevel@tonic-gate 	default:
36967c478bd9Sstevel@tonic-gate 		return (FALSE);
36977c478bd9Sstevel@tonic-gate 	}
36987c478bd9Sstevel@tonic-gate }
36997c478bd9Sstevel@tonic-gate 
37007c478bd9Sstevel@tonic-gate static void
stimeout(mdsetname_t * sp,mhd_mhiargs_t * mhiargsp,int version,md_error_t * ep)37017c478bd9Sstevel@tonic-gate stimeout(
37027c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
37037c478bd9Sstevel@tonic-gate 	mhd_mhiargs_t	*mhiargsp,
37047c478bd9Sstevel@tonic-gate 	int		version,	/* RPC version of calling routine */
37057c478bd9Sstevel@tonic-gate 	md_error_t	*ep
37067c478bd9Sstevel@tonic-gate )
37077c478bd9Sstevel@tonic-gate {
37087c478bd9Sstevel@tonic-gate 	mddb_userreq_t		req;
37097c478bd9Sstevel@tonic-gate 	md_set_record		*sr;
37107c478bd9Sstevel@tonic-gate 
37117c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
37127c478bd9Sstevel@tonic-gate 		return;
37137c478bd9Sstevel@tonic-gate 
37147c478bd9Sstevel@tonic-gate 	sr->sr_mhiargs = *mhiargsp;
37157c478bd9Sstevel@tonic-gate 
37167c478bd9Sstevel@tonic-gate 	(void) memset(&req, '\0', sizeof (req));
37177c478bd9Sstevel@tonic-gate 
37187c478bd9Sstevel@tonic-gate 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
37197c478bd9Sstevel@tonic-gate 	/* Do MN operation if rpc version supports it and if a MN set */
37207c478bd9Sstevel@tonic-gate 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
37217c478bd9Sstevel@tonic-gate 		req.ur_size = sizeof (struct md_mnset_record);
37227c478bd9Sstevel@tonic-gate 	} else {
37237c478bd9Sstevel@tonic-gate 		req.ur_size = sizeof (*sr);
37247c478bd9Sstevel@tonic-gate 	}
37257c478bd9Sstevel@tonic-gate 	req.ur_data = (uintptr_t)sr;
37267c478bd9Sstevel@tonic-gate 
37277c478bd9Sstevel@tonic-gate 	/*
37287c478bd9Sstevel@tonic-gate 	 * Cluster nodename support
37297c478bd9Sstevel@tonic-gate 	 * Convert nodename -> nodeid
37307c478bd9Sstevel@tonic-gate 	 * Don't do this for MN disksets since we've already stored
37317c478bd9Sstevel@tonic-gate 	 * both the nodeid and name.
37327c478bd9Sstevel@tonic-gate 	 */
37337c478bd9Sstevel@tonic-gate 	if ((version == METAD_VERSION) ||
37347c478bd9Sstevel@tonic-gate 	    ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr)))))
37357c478bd9Sstevel@tonic-gate 		sdssc_cm_sr_nm2nid(sr);
37367c478bd9Sstevel@tonic-gate 
37377c478bd9Sstevel@tonic-gate 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
37387c478bd9Sstevel@tonic-gate 		(void) mdstealerror(ep, &req.ur_mde);
37397c478bd9Sstevel@tonic-gate 		return;
37407c478bd9Sstevel@tonic-gate 	}
37417c478bd9Sstevel@tonic-gate 
37427c478bd9Sstevel@tonic-gate 	(void) memset(&req, '\0', sizeof (req));
37437c478bd9Sstevel@tonic-gate 	METAD_SETUP_SR(MD_DB_COMMIT_ONE, sr->sr_selfid)
37447c478bd9Sstevel@tonic-gate 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0)
37457c478bd9Sstevel@tonic-gate 		(void) mdstealerror(ep, &req.ur_mde);
37467c478bd9Sstevel@tonic-gate 
37477c478bd9Sstevel@tonic-gate 	/*
37487c478bd9Sstevel@tonic-gate 	 * Cluster nodename support
37497c478bd9Sstevel@tonic-gate 	 * Convert nodeid -> nodename
37507c478bd9Sstevel@tonic-gate 	 * Don't do this for MN disksets since we've already stored
37517c478bd9Sstevel@tonic-gate 	 * both the nodeid and name.
37527c478bd9Sstevel@tonic-gate 	 */
37537c478bd9Sstevel@tonic-gate 	if ((version == METAD_VERSION) ||
37547c478bd9Sstevel@tonic-gate 	    ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr)))))
37557c478bd9Sstevel@tonic-gate 		sdssc_cm_sr_nid2nm(sr);
37567c478bd9Sstevel@tonic-gate 
37577c478bd9Sstevel@tonic-gate 	free_sr(sr);
37587c478bd9Sstevel@tonic-gate }
37597c478bd9Sstevel@tonic-gate 
37607c478bd9Sstevel@tonic-gate /*
37617c478bd9Sstevel@tonic-gate  * Set MH ioctl timeout values.
37627c478bd9Sstevel@tonic-gate  */
37637c478bd9Sstevel@tonic-gate bool_t
mdrpc_stimeout_common(mdrpc_stimeout_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)37647c478bd9Sstevel@tonic-gate mdrpc_stimeout_common(
37657c478bd9Sstevel@tonic-gate 	mdrpc_stimeout_args	*args,
37667c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
37677c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp,		/* RPC stuff */
37687c478bd9Sstevel@tonic-gate 	int			version		/* RPC version */
37697c478bd9Sstevel@tonic-gate )
37707c478bd9Sstevel@tonic-gate {
37717c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
37727c478bd9Sstevel@tonic-gate 	int			err;
37737c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
37747c478bd9Sstevel@tonic-gate 
37757c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
37767c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
37777c478bd9Sstevel@tonic-gate 		return (FALSE);
37787c478bd9Sstevel@tonic-gate 	else if (err != 0)
37797c478bd9Sstevel@tonic-gate 		return (TRUE);
37807c478bd9Sstevel@tonic-gate 
37817c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, NULL, ep))
37827c478bd9Sstevel@tonic-gate 		return (TRUE);
37837c478bd9Sstevel@tonic-gate 
37847c478bd9Sstevel@tonic-gate 	/* doit */
37857c478bd9Sstevel@tonic-gate 	stimeout(args->sp, args->mhiargsp, version, ep);
37867c478bd9Sstevel@tonic-gate 
37877c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
37887c478bd9Sstevel@tonic-gate 
37897c478bd9Sstevel@tonic-gate 	return (TRUE);
37907c478bd9Sstevel@tonic-gate }
37917c478bd9Sstevel@tonic-gate 
37927c478bd9Sstevel@tonic-gate bool_t
mdrpc_stimeout_1_svc(mdrpc_stimeout_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)37937c478bd9Sstevel@tonic-gate mdrpc_stimeout_1_svc(
37947c478bd9Sstevel@tonic-gate 	mdrpc_stimeout_args	*args,
37957c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
37967c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
37977c478bd9Sstevel@tonic-gate )
37987c478bd9Sstevel@tonic-gate {
37992a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
38007c478bd9Sstevel@tonic-gate 	/* Pass RPC version (METAD_VERSION) to common routine */
38017c478bd9Sstevel@tonic-gate 	return (mdrpc_stimeout_common(args, res, rqstp, METAD_VERSION));
38027c478bd9Sstevel@tonic-gate }
38037c478bd9Sstevel@tonic-gate 
38047c478bd9Sstevel@tonic-gate bool_t
mdrpc_stimeout_2_svc(mdrpc_stimeout_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)38057c478bd9Sstevel@tonic-gate mdrpc_stimeout_2_svc(
38067c478bd9Sstevel@tonic-gate 	mdrpc_stimeout_2_args	*args,
38077c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
38087c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
38097c478bd9Sstevel@tonic-gate )
38107c478bd9Sstevel@tonic-gate {
38112a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
38127c478bd9Sstevel@tonic-gate 	switch (args->rev) {
38137c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
38147c478bd9Sstevel@tonic-gate 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
38157c478bd9Sstevel@tonic-gate 		return (mdrpc_stimeout_common(
38167c478bd9Sstevel@tonic-gate 		    &args->mdrpc_stimeout_2_args_u.rev1, res,
38177c478bd9Sstevel@tonic-gate 		    rqstp, METAD_VERSION_DEVID));
38187c478bd9Sstevel@tonic-gate 	default:
38197c478bd9Sstevel@tonic-gate 		return (FALSE);
38207c478bd9Sstevel@tonic-gate 	}
38217c478bd9Sstevel@tonic-gate }
38227c478bd9Sstevel@tonic-gate 
38237c478bd9Sstevel@tonic-gate static void
upd_dr_dbinfo(mdsetname_t * sp,md_drive_desc * dd,md_error_t * ep)38247c478bd9Sstevel@tonic-gate upd_dr_dbinfo(
38257c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
38267c478bd9Sstevel@tonic-gate 	md_drive_desc	*dd,
38277c478bd9Sstevel@tonic-gate 	md_error_t	*ep
38287c478bd9Sstevel@tonic-gate )
38297c478bd9Sstevel@tonic-gate {
38307c478bd9Sstevel@tonic-gate 	mdsetname_t	*local_sp;
38317c478bd9Sstevel@tonic-gate 	md_set_record	*sr;
38327c478bd9Sstevel@tonic-gate 	md_drive_record	*dr;
38337c478bd9Sstevel@tonic-gate 	md_drive_desc	*p;
38347c478bd9Sstevel@tonic-gate 	mddrivename_t	*dn, *dn1;
38357c478bd9Sstevel@tonic-gate 	ddi_devid_t	devid_remote = NULL;
38367c478bd9Sstevel@tonic-gate 	ddi_devid_t	devid_local = NULL;
38377c478bd9Sstevel@tonic-gate 	int		devid_same = -1;
38387c478bd9Sstevel@tonic-gate 	side_t		sideno;
38397c478bd9Sstevel@tonic-gate 	int		using_devid = 0;
38407c478bd9Sstevel@tonic-gate 
38417c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
38427c478bd9Sstevel@tonic-gate 		return;
38437c478bd9Sstevel@tonic-gate 
38447c478bd9Sstevel@tonic-gate 	metaflushsetname(local_sp);
38457c478bd9Sstevel@tonic-gate 
38467c478bd9Sstevel@tonic-gate 	if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
38477c478bd9Sstevel@tonic-gate 		return;
38487c478bd9Sstevel@tonic-gate 
38497c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
38507c478bd9Sstevel@tonic-gate 		return;
38517c478bd9Sstevel@tonic-gate 
38527c478bd9Sstevel@tonic-gate 	if (dd->dd_dnp == NULL)
38537c478bd9Sstevel@tonic-gate 		return;
38547c478bd9Sstevel@tonic-gate 
38557c478bd9Sstevel@tonic-gate 	/*
38567c478bd9Sstevel@tonic-gate 	 * The system is either all devid or all
38577c478bd9Sstevel@tonic-gate 	 * non-devid so we determine this by looking
38587c478bd9Sstevel@tonic-gate 	 * at the first item in the list.
38597c478bd9Sstevel@tonic-gate 	 *
38607c478bd9Sstevel@tonic-gate 	 * For did disks, the dd_dnp->devid is a valid pointer which
38617c478bd9Sstevel@tonic-gate 	 * points to a '' string of devid.  We need to check this
38627c478bd9Sstevel@tonic-gate 	 * before set the using_devid.
38637c478bd9Sstevel@tonic-gate 	 */
38647c478bd9Sstevel@tonic-gate 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
38657c478bd9Sstevel@tonic-gate 	    (!(MD_MNSET_REC(sr))))
38667c478bd9Sstevel@tonic-gate 		using_devid = 1;
38677c478bd9Sstevel@tonic-gate 
38687c478bd9Sstevel@tonic-gate 	for (p = dd; p != NULL; p = p->dd_next) {
38697c478bd9Sstevel@tonic-gate 		dn = p->dd_dnp;
38707c478bd9Sstevel@tonic-gate 		devid_remote = NULL;
38717c478bd9Sstevel@tonic-gate 
38727c478bd9Sstevel@tonic-gate 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
38737c478bd9Sstevel@tonic-gate 		    using_devid) {
38747c478bd9Sstevel@tonic-gate 			/*
38757c478bd9Sstevel@tonic-gate 			 * We have a devid so use it.
38767c478bd9Sstevel@tonic-gate 			 */
38777c478bd9Sstevel@tonic-gate 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
38787c478bd9Sstevel@tonic-gate 		}
38797c478bd9Sstevel@tonic-gate 
38807c478bd9Sstevel@tonic-gate 		/* check to make sure using_devid agrees with reality... */
38817c478bd9Sstevel@tonic-gate 		if ((using_devid == 1) && (devid_remote == NULL)) {
38827c478bd9Sstevel@tonic-gate 			/* something went really wrong. Can't process */
38837c478bd9Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
38847c478bd9Sstevel@tonic-gate 			    mynode(), dn->cname, sp->setname);
38857c478bd9Sstevel@tonic-gate 			return;
38867c478bd9Sstevel@tonic-gate 		}
38877c478bd9Sstevel@tonic-gate 
38887c478bd9Sstevel@tonic-gate 		for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
38897c478bd9Sstevel@tonic-gate 			devid_same = -1;
38907c478bd9Sstevel@tonic-gate 
38917c478bd9Sstevel@tonic-gate 			dn1 = metadrivename_withdrkey(local_sp, sideno,
38927c478bd9Sstevel@tonic-gate 			    dr->dr_key, MD_BASICNAME_OK, ep);
38937c478bd9Sstevel@tonic-gate 
38947c478bd9Sstevel@tonic-gate 			if (dn1 == NULL) {
38957c478bd9Sstevel@tonic-gate 				if (devid_remote)
38967c478bd9Sstevel@tonic-gate 					devid_free(devid_remote);
38977c478bd9Sstevel@tonic-gate 				goto out;
38987c478bd9Sstevel@tonic-gate 			}
38997c478bd9Sstevel@tonic-gate 
39007c478bd9Sstevel@tonic-gate 			if (dn1->devid != NULL && using_devid) {
39017c478bd9Sstevel@tonic-gate 				if (devid_str_decode(dn1->devid, &devid_local,
39027c478bd9Sstevel@tonic-gate 				    NULL) == 0) {
39037c478bd9Sstevel@tonic-gate 					devid_same = devid_compare(devid_remote,
39047c478bd9Sstevel@tonic-gate 					    devid_local);
39057c478bd9Sstevel@tonic-gate 					devid_free(devid_local);
39067c478bd9Sstevel@tonic-gate 				}
39077c478bd9Sstevel@tonic-gate 			}
39087c478bd9Sstevel@tonic-gate 
39097c478bd9Sstevel@tonic-gate 			if (using_devid && devid_same == 0)
39107c478bd9Sstevel@tonic-gate 				break;
39117c478bd9Sstevel@tonic-gate 
39127c478bd9Sstevel@tonic-gate 			if (!using_devid &&
39137c478bd9Sstevel@tonic-gate 			    strcmp(dn->cname, dn1->cname) == 0)
39147c478bd9Sstevel@tonic-gate 				break;
39157c478bd9Sstevel@tonic-gate 		}
39167c478bd9Sstevel@tonic-gate 
39177c478bd9Sstevel@tonic-gate 		if (dr) {
39187c478bd9Sstevel@tonic-gate 			/* Adjust the fields in the copy */
39197c478bd9Sstevel@tonic-gate 			dr->dr_dbcnt = p->dd_dbcnt;
39207c478bd9Sstevel@tonic-gate 			dr->dr_dbsize = p->dd_dbsize;
39217c478bd9Sstevel@tonic-gate 		}
39227c478bd9Sstevel@tonic-gate 		if (devid_remote)
39237c478bd9Sstevel@tonic-gate 			devid_free(devid_remote);
39247c478bd9Sstevel@tonic-gate 	}
39257c478bd9Sstevel@tonic-gate 
39267c478bd9Sstevel@tonic-gate 
39277c478bd9Sstevel@tonic-gate out:
39287c478bd9Sstevel@tonic-gate 	commitset(sr, FALSE, ep);
39297c478bd9Sstevel@tonic-gate 	free_sr(sr);
39307c478bd9Sstevel@tonic-gate }
39317c478bd9Sstevel@tonic-gate 
39327c478bd9Sstevel@tonic-gate /*
39337c478bd9Sstevel@tonic-gate  * update the database count and size field of drive records.
39347c478bd9Sstevel@tonic-gate  */
39357c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_dbinfo_common(mdrpc_drives_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)39367c478bd9Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_common(
39377c478bd9Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	*args,
39387c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
39397c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
39407c478bd9Sstevel@tonic-gate )
39417c478bd9Sstevel@tonic-gate {
39427c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
39437c478bd9Sstevel@tonic-gate 	int			err;
39447c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
39457c478bd9Sstevel@tonic-gate 
39467c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
39477c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
39487c478bd9Sstevel@tonic-gate 		return (FALSE);
39497c478bd9Sstevel@tonic-gate 	else if (err != 0)
39507c478bd9Sstevel@tonic-gate 		return (TRUE);
39517c478bd9Sstevel@tonic-gate 
39527c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
39537c478bd9Sstevel@tonic-gate 		return (TRUE);
39547c478bd9Sstevel@tonic-gate 
39557c478bd9Sstevel@tonic-gate 	/* doit */
39567c478bd9Sstevel@tonic-gate 	upd_dr_dbinfo(args->sp, args->drivedescs, ep);
39577c478bd9Sstevel@tonic-gate 
39587c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
39597c478bd9Sstevel@tonic-gate 
39607c478bd9Sstevel@tonic-gate 	return (TRUE);
39617c478bd9Sstevel@tonic-gate }
39627c478bd9Sstevel@tonic-gate 
39637c478bd9Sstevel@tonic-gate /*
39647c478bd9Sstevel@tonic-gate  * version 1 of the remote procedure. This procedure is called if the
39657c478bd9Sstevel@tonic-gate  * client is running in version 1. We first convert version 1 arguments
39667c478bd9Sstevel@tonic-gate  * into version 2 arguments and then call the common remote procedure.
39677c478bd9Sstevel@tonic-gate  */
39687c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_dbinfo_1_svc(mdrpc_drives_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)39697c478bd9Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_1_svc(
39707c478bd9Sstevel@tonic-gate 	mdrpc_drives_args	*args,
39717c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
39727c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
39737c478bd9Sstevel@tonic-gate )
39747c478bd9Sstevel@tonic-gate {
39757c478bd9Sstevel@tonic-gate 	bool_t			retval;
39767c478bd9Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	v2_args;
39777c478bd9Sstevel@tonic-gate 
39787c478bd9Sstevel@tonic-gate 	/* allocate memory */
39797c478bd9Sstevel@tonic-gate 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
39802a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
39817c478bd9Sstevel@tonic-gate 
39827c478bd9Sstevel@tonic-gate 	/* build args */
39837c478bd9Sstevel@tonic-gate 	v2_args.cl_sk = args->cl_sk;
39847c478bd9Sstevel@tonic-gate 	v2_args.sp = args->sp;
39857c478bd9Sstevel@tonic-gate 	/* convert v1 args to v2 (revision 1) args */
39867c478bd9Sstevel@tonic-gate 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
39877c478bd9Sstevel@tonic-gate 	v2_args.timestamp = args->timestamp;
39887c478bd9Sstevel@tonic-gate 	v2_args.genid = args->genid;
39897c478bd9Sstevel@tonic-gate 
39907c478bd9Sstevel@tonic-gate 	retval = mdrpc_upd_dr_dbinfo_common(&v2_args, res, rqstp);
39917c478bd9Sstevel@tonic-gate 
39927c478bd9Sstevel@tonic-gate 	free_newdrvdesc(v2_args.drivedescs);
39937c478bd9Sstevel@tonic-gate 
39947c478bd9Sstevel@tonic-gate 	return (retval);
39957c478bd9Sstevel@tonic-gate }
39967c478bd9Sstevel@tonic-gate 
39977c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_dbinfo_2_svc(mdrpc_drives_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)39987c478bd9Sstevel@tonic-gate mdrpc_upd_dr_dbinfo_2_svc(
39997c478bd9Sstevel@tonic-gate 	mdrpc_drives_2_args	*args,
40007c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
40017c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
40027c478bd9Sstevel@tonic-gate )
40037c478bd9Sstevel@tonic-gate {
40042a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
40057c478bd9Sstevel@tonic-gate 	switch (args->rev) {
40067c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
40077c478bd9Sstevel@tonic-gate 		return (mdrpc_upd_dr_dbinfo_common(
40087c478bd9Sstevel@tonic-gate 		    &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
40097c478bd9Sstevel@tonic-gate 	default:
40107c478bd9Sstevel@tonic-gate 		return (FALSE);
40117c478bd9Sstevel@tonic-gate 	}
40127c478bd9Sstevel@tonic-gate }
40137c478bd9Sstevel@tonic-gate 
40147c478bd9Sstevel@tonic-gate static void
upd_dr_flags(mdsetname_t * sp,md_drive_desc * dd,uint_t new_flags,md_error_t * ep)40157c478bd9Sstevel@tonic-gate upd_dr_flags(
40167c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
40177c478bd9Sstevel@tonic-gate 	md_drive_desc	*dd,
40187c478bd9Sstevel@tonic-gate 	uint_t		new_flags,
40197c478bd9Sstevel@tonic-gate 	md_error_t	*ep
40207c478bd9Sstevel@tonic-gate )
40217c478bd9Sstevel@tonic-gate {
40227c478bd9Sstevel@tonic-gate 	mdsetname_t	*local_sp;
40237c478bd9Sstevel@tonic-gate 	md_set_record	*sr;
40247c478bd9Sstevel@tonic-gate 	md_drive_record	*dr;
40257c478bd9Sstevel@tonic-gate 	md_drive_desc	*p;
40267c478bd9Sstevel@tonic-gate 	mddrivename_t	*dn, *dn1;
40277c478bd9Sstevel@tonic-gate 	ddi_devid_t	devid_remote = NULL;
40287c478bd9Sstevel@tonic-gate 	ddi_devid_t	devid_local = NULL;
40297c478bd9Sstevel@tonic-gate 	int		devid_same = -1;
40307c478bd9Sstevel@tonic-gate 	side_t		sideno;
40317c478bd9Sstevel@tonic-gate 	int		using_devid = 0;
40327c478bd9Sstevel@tonic-gate 
40337c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
40347c478bd9Sstevel@tonic-gate 		return;
40357c478bd9Sstevel@tonic-gate 
40367c478bd9Sstevel@tonic-gate 	metaflushsetname(local_sp);
40377c478bd9Sstevel@tonic-gate 
40387c478bd9Sstevel@tonic-gate 	if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
40397c478bd9Sstevel@tonic-gate 		return;
40407c478bd9Sstevel@tonic-gate 
40417c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
40427c478bd9Sstevel@tonic-gate 		return;
40437c478bd9Sstevel@tonic-gate 
40447c478bd9Sstevel@tonic-gate 	if (dd->dd_dnp == NULL)
40457c478bd9Sstevel@tonic-gate 		return;
40467c478bd9Sstevel@tonic-gate 
40477c478bd9Sstevel@tonic-gate 	/*
40487c478bd9Sstevel@tonic-gate 	 * The system is either all devid or all
40497c478bd9Sstevel@tonic-gate 	 * non-devid so we determine this by looking
40507c478bd9Sstevel@tonic-gate 	 * at the first item in the list.
40517c478bd9Sstevel@tonic-gate 	 *
40527c478bd9Sstevel@tonic-gate 	 * For did disks, the dd_dnp->devid is a valid pointer which
40537c478bd9Sstevel@tonic-gate 	 * points to a '' string of devid.  We need to check this
40547c478bd9Sstevel@tonic-gate 	 * before set the using_devid.
40557c478bd9Sstevel@tonic-gate 	 */
40567c478bd9Sstevel@tonic-gate 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
40577c478bd9Sstevel@tonic-gate 	    (!(MD_MNSET_REC(sr))))
40587c478bd9Sstevel@tonic-gate 		using_devid = 1;
40597c478bd9Sstevel@tonic-gate 
40607c478bd9Sstevel@tonic-gate 	for (p = dd; p != NULL; p = p->dd_next) {
40617c478bd9Sstevel@tonic-gate 		dn = p->dd_dnp;
40627c478bd9Sstevel@tonic-gate 		devid_remote = NULL;
40637c478bd9Sstevel@tonic-gate 
40647c478bd9Sstevel@tonic-gate 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
40657c478bd9Sstevel@tonic-gate 		    using_devid) {
40667c478bd9Sstevel@tonic-gate 			/*
40677c478bd9Sstevel@tonic-gate 			 * We have a devid so use it.
40687c478bd9Sstevel@tonic-gate 			 */
40697c478bd9Sstevel@tonic-gate 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
40707c478bd9Sstevel@tonic-gate 		}
40717c478bd9Sstevel@tonic-gate 
40727c478bd9Sstevel@tonic-gate 		/* check to make sure using_devid agrees with reality... */
40737c478bd9Sstevel@tonic-gate 		if ((using_devid == 1) && (devid_remote == NULL)) {
40747c478bd9Sstevel@tonic-gate 			/* something went really wrong. Can't process */
40757c478bd9Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
40767c478bd9Sstevel@tonic-gate 			    mynode(), dn->cname, sp->setname);
40777c478bd9Sstevel@tonic-gate 			return;
40787c478bd9Sstevel@tonic-gate 		}
40797c478bd9Sstevel@tonic-gate 
40807c478bd9Sstevel@tonic-gate 		for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
40817c478bd9Sstevel@tonic-gate 			devid_same = -1;
40827c478bd9Sstevel@tonic-gate 
40837c478bd9Sstevel@tonic-gate 			dn1 = metadrivename_withdrkey(local_sp, sideno,
40847c478bd9Sstevel@tonic-gate 			    dr->dr_key, MD_BASICNAME_OK, ep);
40857c478bd9Sstevel@tonic-gate 
40867c478bd9Sstevel@tonic-gate 			if (dn1 == NULL) {
40877c478bd9Sstevel@tonic-gate 				if (devid_remote)
40887c478bd9Sstevel@tonic-gate 					devid_free(devid_remote);
40897c478bd9Sstevel@tonic-gate 				goto out;
40907c478bd9Sstevel@tonic-gate 			}
40917c478bd9Sstevel@tonic-gate 
40927c478bd9Sstevel@tonic-gate 			if (dn1->devid != NULL && using_devid) {
40937c478bd9Sstevel@tonic-gate 				if (devid_str_decode(dn1->devid,
40947c478bd9Sstevel@tonic-gate 				    &devid_local, NULL) == 0) {
40957c478bd9Sstevel@tonic-gate 					devid_same = devid_compare(devid_remote,
40967c478bd9Sstevel@tonic-gate 					    devid_local);
40977c478bd9Sstevel@tonic-gate 					devid_free(devid_local);
40987c478bd9Sstevel@tonic-gate 				}
40997c478bd9Sstevel@tonic-gate 			}
41007c478bd9Sstevel@tonic-gate 
41017c478bd9Sstevel@tonic-gate 			if (using_devid && devid_same == 0)
41027c478bd9Sstevel@tonic-gate 				break;
41037c478bd9Sstevel@tonic-gate 
41047c478bd9Sstevel@tonic-gate 			if (!using_devid &&
41057c478bd9Sstevel@tonic-gate 			    strcmp(dn->cname, dn1->cname) == 0)
41067c478bd9Sstevel@tonic-gate 				break;
41077c478bd9Sstevel@tonic-gate 		}
41087c478bd9Sstevel@tonic-gate 
41097c478bd9Sstevel@tonic-gate 		if (dr)
41107c478bd9Sstevel@tonic-gate 			dr->dr_flags = new_flags;
41117c478bd9Sstevel@tonic-gate 		if (devid_remote)
41127c478bd9Sstevel@tonic-gate 			devid_free(devid_remote);
41137c478bd9Sstevel@tonic-gate 	}
41147c478bd9Sstevel@tonic-gate out:
41157c478bd9Sstevel@tonic-gate 	commitset(sr, TRUE, ep);
41167c478bd9Sstevel@tonic-gate 	free_sr(sr);
41177c478bd9Sstevel@tonic-gate }
41187c478bd9Sstevel@tonic-gate 
41197c478bd9Sstevel@tonic-gate /*
41207c478bd9Sstevel@tonic-gate  * update the database count and size field of drive records.
41217c478bd9Sstevel@tonic-gate  */
41227c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_flags_common(mdrpc_upd_dr_flags_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)41237c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_common(
41247c478bd9Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args_r1	*args,
41257c478bd9Sstevel@tonic-gate 	mdrpc_generic_res		*res,
41267c478bd9Sstevel@tonic-gate 	struct svc_req			*rqstp		/* RPC stuff */
41277c478bd9Sstevel@tonic-gate )
41287c478bd9Sstevel@tonic-gate {
41297c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
41307c478bd9Sstevel@tonic-gate 	int			err;
41317c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
41327c478bd9Sstevel@tonic-gate 
41337c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
41347c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
41357c478bd9Sstevel@tonic-gate 		return (FALSE);
41367c478bd9Sstevel@tonic-gate 	else if (err != 0)
41377c478bd9Sstevel@tonic-gate 		return (TRUE);
41387c478bd9Sstevel@tonic-gate 
41397c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
41407c478bd9Sstevel@tonic-gate 		return (TRUE);
41417c478bd9Sstevel@tonic-gate 
41427c478bd9Sstevel@tonic-gate 	/* doit */
41437c478bd9Sstevel@tonic-gate 	upd_dr_flags(args->sp, args->drivedescs, args->new_flags, ep);
41447c478bd9Sstevel@tonic-gate 
41457c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
41467c478bd9Sstevel@tonic-gate 
41477c478bd9Sstevel@tonic-gate 	return (TRUE);
41487c478bd9Sstevel@tonic-gate }
41497c478bd9Sstevel@tonic-gate 
41507c478bd9Sstevel@tonic-gate /*
41517c478bd9Sstevel@tonic-gate  * version 1 of the remote procedure. This procedure is called if the
41527c478bd9Sstevel@tonic-gate  * client is running in version 1. We first convert version 1 arguments
41537c478bd9Sstevel@tonic-gate  * into version 2 arguments and then call the common remote procedure.
41547c478bd9Sstevel@tonic-gate  */
41557c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_flags_1_svc(mdrpc_upd_dr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)41567c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_1_svc(
41577c478bd9Sstevel@tonic-gate 	mdrpc_upd_dr_flags_args	*args,
41587c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
41597c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
41607c478bd9Sstevel@tonic-gate )
41617c478bd9Sstevel@tonic-gate {
41627c478bd9Sstevel@tonic-gate 	bool_t				retval;
41637c478bd9Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args_r1	v2_args;
41647c478bd9Sstevel@tonic-gate 
41657c478bd9Sstevel@tonic-gate 	/* allocate memory */
41667c478bd9Sstevel@tonic-gate 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
41672a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
41687c478bd9Sstevel@tonic-gate 
41697c478bd9Sstevel@tonic-gate 	/* build args */
41707c478bd9Sstevel@tonic-gate 	v2_args.cl_sk = args->cl_sk;
41717c478bd9Sstevel@tonic-gate 	v2_args.sp = args->sp;
41727c478bd9Sstevel@tonic-gate 	/* convert v1 args to v2 (revision 1) args */
41737c478bd9Sstevel@tonic-gate 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
41747c478bd9Sstevel@tonic-gate 	v2_args.new_flags = args->new_flags;
41757c478bd9Sstevel@tonic-gate 
41767c478bd9Sstevel@tonic-gate 	retval = mdrpc_upd_dr_flags_common(&v2_args, res, rqstp);
41777c478bd9Sstevel@tonic-gate 
41787c478bd9Sstevel@tonic-gate 	free_newdrvdesc(v2_args.drivedescs);
41797c478bd9Sstevel@tonic-gate 
41807c478bd9Sstevel@tonic-gate 	return (retval);
41817c478bd9Sstevel@tonic-gate }
41827c478bd9Sstevel@tonic-gate 
41837c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_flags_2_svc(mdrpc_upd_dr_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)41847c478bd9Sstevel@tonic-gate mdrpc_upd_dr_flags_2_svc(
41857c478bd9Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args	*args,
41867c478bd9Sstevel@tonic-gate 	mdrpc_generic_res		*res,
41877c478bd9Sstevel@tonic-gate 	struct svc_req			*rqstp		/* RPC stuff */
41887c478bd9Sstevel@tonic-gate )
41897c478bd9Sstevel@tonic-gate {
41902a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
41917c478bd9Sstevel@tonic-gate 	switch (args->rev) {
41927c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
41937c478bd9Sstevel@tonic-gate 		return (mdrpc_upd_dr_flags_common(
41947c478bd9Sstevel@tonic-gate 		    &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp));
41957c478bd9Sstevel@tonic-gate 	default:
41967c478bd9Sstevel@tonic-gate 		return (FALSE);
41977c478bd9Sstevel@tonic-gate 	}
41987c478bd9Sstevel@tonic-gate }
41997c478bd9Sstevel@tonic-gate 
42007c478bd9Sstevel@tonic-gate static void
upd_sr_flags(mdsetname_t * sp,uint_t new_flags,md_error_t * ep)42017c478bd9Sstevel@tonic-gate upd_sr_flags(
42027c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
42037c478bd9Sstevel@tonic-gate 	uint_t		new_flags,
42047c478bd9Sstevel@tonic-gate 	md_error_t	*ep
42057c478bd9Sstevel@tonic-gate )
42067c478bd9Sstevel@tonic-gate {
42077c478bd9Sstevel@tonic-gate 	md_set_record	*sr;
42087c478bd9Sstevel@tonic-gate 
42097c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
42107c478bd9Sstevel@tonic-gate 		return;
42117c478bd9Sstevel@tonic-gate 
42127c478bd9Sstevel@tonic-gate 	sr->sr_flags = new_flags;
42137c478bd9Sstevel@tonic-gate 	commitset(sr, TRUE, ep);
42147c478bd9Sstevel@tonic-gate 	free_sr(sr);
42157c478bd9Sstevel@tonic-gate }
42167c478bd9Sstevel@tonic-gate 
42177c478bd9Sstevel@tonic-gate /*
42187c478bd9Sstevel@tonic-gate  * update the set record flags
42197c478bd9Sstevel@tonic-gate  */
42207c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_sr_flags_common(mdrpc_upd_sr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)42217c478bd9Sstevel@tonic-gate mdrpc_upd_sr_flags_common(
42227c478bd9Sstevel@tonic-gate 	mdrpc_upd_sr_flags_args	*args,
42237c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
42247c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
42257c478bd9Sstevel@tonic-gate )
42267c478bd9Sstevel@tonic-gate {
42277c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
42287c478bd9Sstevel@tonic-gate 	int			err;
42297c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
42307c478bd9Sstevel@tonic-gate 
42317c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
42327c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
42337c478bd9Sstevel@tonic-gate 		return (FALSE);
42347c478bd9Sstevel@tonic-gate 	else if (err != 0)
42357c478bd9Sstevel@tonic-gate 		return (TRUE);
42367c478bd9Sstevel@tonic-gate 
42377c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
42387c478bd9Sstevel@tonic-gate 		return (TRUE);
42397c478bd9Sstevel@tonic-gate 
42407c478bd9Sstevel@tonic-gate 	/* doit */
42417c478bd9Sstevel@tonic-gate 	upd_sr_flags(args->sp, args->new_flags, ep);
42427c478bd9Sstevel@tonic-gate 
42437c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
42447c478bd9Sstevel@tonic-gate 
42457c478bd9Sstevel@tonic-gate 	return (TRUE);
42467c478bd9Sstevel@tonic-gate }
42477c478bd9Sstevel@tonic-gate 
42487c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_sr_flags_1_svc(mdrpc_upd_sr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)42497c478bd9Sstevel@tonic-gate mdrpc_upd_sr_flags_1_svc(
42507c478bd9Sstevel@tonic-gate 	mdrpc_upd_sr_flags_args	*args,
42517c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
42527c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
42537c478bd9Sstevel@tonic-gate )
42547c478bd9Sstevel@tonic-gate {
42552a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
42567c478bd9Sstevel@tonic-gate 	return (mdrpc_upd_sr_flags_common(args, res, rqstp));
42577c478bd9Sstevel@tonic-gate }
42587c478bd9Sstevel@tonic-gate 
42597c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_sr_flags_2_svc(mdrpc_upd_sr_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)42607c478bd9Sstevel@tonic-gate mdrpc_upd_sr_flags_2_svc(
42617c478bd9Sstevel@tonic-gate 	mdrpc_upd_sr_flags_2_args	*args,
42627c478bd9Sstevel@tonic-gate 	mdrpc_generic_res		*res,
42637c478bd9Sstevel@tonic-gate 	struct svc_req			*rqstp		/* RPC stuff */
42647c478bd9Sstevel@tonic-gate )
42657c478bd9Sstevel@tonic-gate {
42662a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
42677c478bd9Sstevel@tonic-gate 	switch (args->rev) {
42687c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
42697c478bd9Sstevel@tonic-gate 		return (mdrpc_upd_sr_flags_common(
42707c478bd9Sstevel@tonic-gate 		    &args->mdrpc_upd_sr_flags_2_args_u.rev1, res, rqstp));
42717c478bd9Sstevel@tonic-gate 	default:
42727c478bd9Sstevel@tonic-gate 		return (FALSE);
42737c478bd9Sstevel@tonic-gate 	}
42747c478bd9Sstevel@tonic-gate }
42757c478bd9Sstevel@tonic-gate 
42767c478bd9Sstevel@tonic-gate /*
42777c478bd9Sstevel@tonic-gate  * upd_nr_flags updates the node records stored in this node's local mddb
42787c478bd9Sstevel@tonic-gate  * given a node desciptor list and an action.  upd_nr_flags then commits
42797c478bd9Sstevel@tonic-gate  * the node records to the local mddb.
42807c478bd9Sstevel@tonic-gate  *
42817c478bd9Sstevel@tonic-gate  * nd - A linked list of node descriptors that describes the node records
42827c478bd9Sstevel@tonic-gate  *	in this diskset on which the action applies.
42837c478bd9Sstevel@tonic-gate  * flag_action: action to be taken on node records that match the nd list.
42847c478bd9Sstevel@tonic-gate  *	flag_action can be:
42857c478bd9Sstevel@tonic-gate  *		MD_NR_JOIN: set OWN flag in node records
42867c478bd9Sstevel@tonic-gate  *		MD_NR_WITHDRAW: reset OWN flag in node records
42877c478bd9Sstevel@tonic-gate  *		MD_NR_OK: reset ADD flags and set OK flag in node records
42887c478bd9Sstevel@tonic-gate  *		MD_NR_SET: set node record flags based on flags stored in nd
42897c478bd9Sstevel@tonic-gate  *
42907c478bd9Sstevel@tonic-gate  * Typically, the JOIN, WITHDRAW and OK flag_actions are used when setting
42917c478bd9Sstevel@tonic-gate  * all nodes in a diskset to JOIN (add first disk to set), WITHDRAW
42927c478bd9Sstevel@tonic-gate  * (remove last disk from set) or OK (after addition of host to set).
42937c478bd9Sstevel@tonic-gate  *
42947c478bd9Sstevel@tonic-gate  * The SET flag_action is typically used when nodelist contains all nodes
42957c478bd9Sstevel@tonic-gate  * in the diskset, but specific nodes have had flag changes.  An example of
42967c478bd9Sstevel@tonic-gate  * this would be the join/withdraw of a specific node to/from the set.
42977c478bd9Sstevel@tonic-gate  *
42987c478bd9Sstevel@tonic-gate  * Ignore the MD_MN_NODE_RB_JOIN flag if set in node record flag.  This
42997c478bd9Sstevel@tonic-gate  * flag is used by the client to recover in case of failure and should not
43007c478bd9Sstevel@tonic-gate  * be set in the node record flags.
43017c478bd9Sstevel@tonic-gate  */
43027c478bd9Sstevel@tonic-gate static void
upd_nr_flags(mdsetname_t * sp,md_mnnode_desc * nd,uint_t flag_action,md_error_t * ep)43037c478bd9Sstevel@tonic-gate upd_nr_flags(
43047c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
43057c478bd9Sstevel@tonic-gate 	md_mnnode_desc	*nd,
43067c478bd9Sstevel@tonic-gate 	uint_t		flag_action,
43077c478bd9Sstevel@tonic-gate 	md_error_t	*ep
43087c478bd9Sstevel@tonic-gate )
43097c478bd9Sstevel@tonic-gate {
43107c478bd9Sstevel@tonic-gate 	mdsetname_t		*local_sp;
43117c478bd9Sstevel@tonic-gate 	md_set_record		*sr;
43127c478bd9Sstevel@tonic-gate 	md_mnset_record		*mnsr;
43137c478bd9Sstevel@tonic-gate 	md_mnnode_desc		*ndp;
43147c478bd9Sstevel@tonic-gate 	md_mnnode_record	*nrp;
43157c478bd9Sstevel@tonic-gate 
43167c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
43177c478bd9Sstevel@tonic-gate 		return;
43187c478bd9Sstevel@tonic-gate 
43197c478bd9Sstevel@tonic-gate 	metaflushsetname(local_sp);
43207c478bd9Sstevel@tonic-gate 
43217c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
43227c478bd9Sstevel@tonic-gate 		return;
43237c478bd9Sstevel@tonic-gate 
43247c478bd9Sstevel@tonic-gate 	if (!(MD_MNSET_REC(sr))) {
43257c478bd9Sstevel@tonic-gate 		return;
43267c478bd9Sstevel@tonic-gate 	}
43277c478bd9Sstevel@tonic-gate 	mnsr = (struct md_mnset_record *)sr;
43287c478bd9Sstevel@tonic-gate 
43297c478bd9Sstevel@tonic-gate 	switch (flag_action) {
43307c478bd9Sstevel@tonic-gate 	case MD_NR_JOIN:
43317c478bd9Sstevel@tonic-gate 	case MD_NR_WITHDRAW:
43327c478bd9Sstevel@tonic-gate 	case MD_NR_SET:
43337c478bd9Sstevel@tonic-gate 	case MD_NR_OK:
43347c478bd9Sstevel@tonic-gate 	case MD_NR_DEL:
43357c478bd9Sstevel@tonic-gate 		break;
43367c478bd9Sstevel@tonic-gate 	default:
43377c478bd9Sstevel@tonic-gate 		return;
43387c478bd9Sstevel@tonic-gate 	}
43397c478bd9Sstevel@tonic-gate 
43407c478bd9Sstevel@tonic-gate 	for (ndp = nd; ndp != NULL; ndp = ndp->nd_next) {
43417c478bd9Sstevel@tonic-gate 		/* Find matching node record for given node descriptor */
43427c478bd9Sstevel@tonic-gate 		for (nrp = mnsr->sr_nodechain; nrp != NULL;
43437c478bd9Sstevel@tonic-gate 		    nrp = nrp->nr_next) {
43447c478bd9Sstevel@tonic-gate 			if (ndp->nd_nodeid == nrp->nr_nodeid) {
43457c478bd9Sstevel@tonic-gate 				switch (flag_action) {
43467c478bd9Sstevel@tonic-gate 				case MD_NR_JOIN:
43477c478bd9Sstevel@tonic-gate 					nrp->nr_flags |= MD_MN_NODE_OWN;
43487c478bd9Sstevel@tonic-gate 					break;
43497c478bd9Sstevel@tonic-gate 				case MD_NR_WITHDRAW:
43507c478bd9Sstevel@tonic-gate 					nrp->nr_flags &= ~MD_MN_NODE_OWN;
43517c478bd9Sstevel@tonic-gate 					break;
43527c478bd9Sstevel@tonic-gate 				case MD_NR_OK:
43537c478bd9Sstevel@tonic-gate 					nrp->nr_flags &=
43547c478bd9Sstevel@tonic-gate 					    ~(MD_MN_NODE_ADD | MD_MN_NODE_DEL);
43557c478bd9Sstevel@tonic-gate 					nrp->nr_flags |= MD_MN_NODE_OK;
43567c478bd9Sstevel@tonic-gate 					break;
43577c478bd9Sstevel@tonic-gate 				case MD_NR_DEL:
43587c478bd9Sstevel@tonic-gate 					nrp->nr_flags &=
43597c478bd9Sstevel@tonic-gate 					    ~(MD_MN_NODE_OK | MD_MN_NODE_ADD);
43607c478bd9Sstevel@tonic-gate 					nrp->nr_flags |= MD_MN_NODE_DEL;
43617c478bd9Sstevel@tonic-gate 					break;
43627c478bd9Sstevel@tonic-gate 				case MD_NR_SET:
43637c478bd9Sstevel@tonic-gate 					/* Do not set RB_JOIN flag */
43647c478bd9Sstevel@tonic-gate 					nrp->nr_flags =
43657c478bd9Sstevel@tonic-gate 					    ndp->nd_flags & ~MD_MN_NODE_RB_JOIN;
43667c478bd9Sstevel@tonic-gate 					break;
43677c478bd9Sstevel@tonic-gate 				}
43687c478bd9Sstevel@tonic-gate 				break;
43697c478bd9Sstevel@tonic-gate 			}
43707c478bd9Sstevel@tonic-gate 		}
43717c478bd9Sstevel@tonic-gate 	}
43727c478bd9Sstevel@tonic-gate out:
43737c478bd9Sstevel@tonic-gate 	/* Don't increment set genid for node record flag update */
43747c478bd9Sstevel@tonic-gate 	commitset(sr, FALSE, ep);
43757c478bd9Sstevel@tonic-gate 	free_sr(sr);
43767c478bd9Sstevel@tonic-gate }
43777c478bd9Sstevel@tonic-gate 
43787c478bd9Sstevel@tonic-gate /*
43797c478bd9Sstevel@tonic-gate  * init/fini wrapper around upd_nr_flags
43807c478bd9Sstevel@tonic-gate  */
43817c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_nr_flags_common(mdrpc_upd_nr_flags_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)43827c478bd9Sstevel@tonic-gate mdrpc_upd_nr_flags_common(
43837c478bd9Sstevel@tonic-gate 	mdrpc_upd_nr_flags_args	*args,
43847c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
43857c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
43867c478bd9Sstevel@tonic-gate )
43877c478bd9Sstevel@tonic-gate {
43887c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
43897c478bd9Sstevel@tonic-gate 	int			err;
43907c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
43917c478bd9Sstevel@tonic-gate 
43927c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
43937c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
43947c478bd9Sstevel@tonic-gate 		return (FALSE);
43957c478bd9Sstevel@tonic-gate 	else if (err != 0)
43967c478bd9Sstevel@tonic-gate 		return (TRUE);
43977c478bd9Sstevel@tonic-gate 
43987c478bd9Sstevel@tonic-gate 	/*
43997c478bd9Sstevel@tonic-gate 	 * During reconfig, node record flags can be updated without
44007c478bd9Sstevel@tonic-gate 	 * locking first.
44017c478bd9Sstevel@tonic-gate 	 */
44027c478bd9Sstevel@tonic-gate 	if (!(args->flags & MNSET_IN_RECONFIG)) {
44037c478bd9Sstevel@tonic-gate 		if (check_set_lock(op_mode, args->cl_sk, ep))
44047c478bd9Sstevel@tonic-gate 			return (TRUE);
44057c478bd9Sstevel@tonic-gate 	}
44067c478bd9Sstevel@tonic-gate 
44077c478bd9Sstevel@tonic-gate 	/* doit */
44087c478bd9Sstevel@tonic-gate 	upd_nr_flags(args->sp, args->nodedescs, args->flag_action, ep);
44097c478bd9Sstevel@tonic-gate 
44107c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
44117c478bd9Sstevel@tonic-gate 
44127c478bd9Sstevel@tonic-gate 	return (TRUE);
44137c478bd9Sstevel@tonic-gate }
44147c478bd9Sstevel@tonic-gate 
44157c478bd9Sstevel@tonic-gate /*
44167c478bd9Sstevel@tonic-gate  * update the node records using given flag action.
44177c478bd9Sstevel@tonic-gate  */
44187c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_nr_flags_2_svc(mdrpc_upd_nr_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)44197c478bd9Sstevel@tonic-gate mdrpc_upd_nr_flags_2_svc(
44207c478bd9Sstevel@tonic-gate 	mdrpc_upd_nr_flags_2_args	*args,
44217c478bd9Sstevel@tonic-gate 	mdrpc_generic_res		*res,
44227c478bd9Sstevel@tonic-gate 	struct svc_req			*rqstp		/* RPC stuff */
44237c478bd9Sstevel@tonic-gate )
44247c478bd9Sstevel@tonic-gate {
44252a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
44267c478bd9Sstevel@tonic-gate 	switch (args->rev) {
44277c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
44287c478bd9Sstevel@tonic-gate 		return (mdrpc_upd_nr_flags_common(
44297c478bd9Sstevel@tonic-gate 		    &args->mdrpc_upd_nr_flags_2_args_u.rev1, res, rqstp));
44307c478bd9Sstevel@tonic-gate 	default:
44317c478bd9Sstevel@tonic-gate 		return (FALSE);
44327c478bd9Sstevel@tonic-gate 	}
44337c478bd9Sstevel@tonic-gate }
44347c478bd9Sstevel@tonic-gate 
44357c478bd9Sstevel@tonic-gate void
free_sk(md_setkey_t * skp)44367c478bd9Sstevel@tonic-gate free_sk(md_setkey_t *skp)
44377c478bd9Sstevel@tonic-gate {
44387c478bd9Sstevel@tonic-gate 	Free(skp->sk_setname);
44397c478bd9Sstevel@tonic-gate 	Free(skp->sk_host);
44407c478bd9Sstevel@tonic-gate 	Free(skp);
44417c478bd9Sstevel@tonic-gate }
44427c478bd9Sstevel@tonic-gate 
44437c478bd9Sstevel@tonic-gate void
del_sk(set_t setno)44447c478bd9Sstevel@tonic-gate del_sk(set_t setno)
44457c478bd9Sstevel@tonic-gate {
44467c478bd9Sstevel@tonic-gate 	md_setkey_t	*skp;
44477c478bd9Sstevel@tonic-gate 	md_setkey_t	*tskp;
44487c478bd9Sstevel@tonic-gate 
44497c478bd9Sstevel@tonic-gate 	for (skp = tskp = my_svc_sk; skp; tskp = skp, skp = skp->sk_next) {
44507c478bd9Sstevel@tonic-gate 		if (setno == skp->sk_setno) {
44517c478bd9Sstevel@tonic-gate 			if (skp == my_svc_sk)
44527c478bd9Sstevel@tonic-gate 				my_svc_sk = skp->sk_next;
44537c478bd9Sstevel@tonic-gate 			else
44547c478bd9Sstevel@tonic-gate 				tskp->sk_next = skp->sk_next;
44557c478bd9Sstevel@tonic-gate 
44567c478bd9Sstevel@tonic-gate 			Free(skp->sk_setname);
44577c478bd9Sstevel@tonic-gate 			Free(skp->sk_host);
44587c478bd9Sstevel@tonic-gate 			Free(skp);
44597c478bd9Sstevel@tonic-gate 			break;
44607c478bd9Sstevel@tonic-gate 		}
44617c478bd9Sstevel@tonic-gate 	}
44627c478bd9Sstevel@tonic-gate }
44637c478bd9Sstevel@tonic-gate 
44647c478bd9Sstevel@tonic-gate md_setkey_t *
dupsk(md_setkey_t * skp)44657c478bd9Sstevel@tonic-gate dupsk(md_setkey_t *skp)
44667c478bd9Sstevel@tonic-gate {
44677c478bd9Sstevel@tonic-gate 	md_setkey_t	*tskp;
44687c478bd9Sstevel@tonic-gate 
44697c478bd9Sstevel@tonic-gate 	tskp = Zalloc(sizeof (md_setkey_t));
44707c478bd9Sstevel@tonic-gate 
44717c478bd9Sstevel@tonic-gate 	*tskp = *skp;
44727c478bd9Sstevel@tonic-gate 	tskp->sk_host = Strdup(skp->sk_host);
44737c478bd9Sstevel@tonic-gate 	tskp->sk_setname = Strdup(skp->sk_setname);
44747c478bd9Sstevel@tonic-gate 
44757c478bd9Sstevel@tonic-gate 	return (tskp);
44767c478bd9Sstevel@tonic-gate }
44777c478bd9Sstevel@tonic-gate 
44787c478bd9Sstevel@tonic-gate md_setkey_t *
svc_get_setkey(set_t setno)44797c478bd9Sstevel@tonic-gate svc_get_setkey(set_t setno)
44807c478bd9Sstevel@tonic-gate {
44817c478bd9Sstevel@tonic-gate 	md_setkey_t	*skp;
44827c478bd9Sstevel@tonic-gate 
44837c478bd9Sstevel@tonic-gate 	for (skp = my_svc_sk; skp != NULL; skp = skp->sk_next)
44847c478bd9Sstevel@tonic-gate 		if (setno == skp->sk_setno)
44857c478bd9Sstevel@tonic-gate 			return (dupsk(skp));
44867c478bd9Sstevel@tonic-gate 	return (NULL);
44877c478bd9Sstevel@tonic-gate }
44887c478bd9Sstevel@tonic-gate 
44897c478bd9Sstevel@tonic-gate void
svc_set_setkey(md_setkey_t * svc_sk)44907c478bd9Sstevel@tonic-gate svc_set_setkey(md_setkey_t *svc_sk)
44917c478bd9Sstevel@tonic-gate {
44927c478bd9Sstevel@tonic-gate 	md_setkey_t	*skp;
44937c478bd9Sstevel@tonic-gate 
44947c478bd9Sstevel@tonic-gate 	if (my_svc_sk == NULL) {
44957c478bd9Sstevel@tonic-gate 		my_svc_sk = dupsk(svc_sk);
44967c478bd9Sstevel@tonic-gate 		return;
44977c478bd9Sstevel@tonic-gate 	}
44987c478bd9Sstevel@tonic-gate 
44997c478bd9Sstevel@tonic-gate 	for (skp = my_svc_sk; skp->sk_next != NULL; skp = skp->sk_next)
45007c478bd9Sstevel@tonic-gate 		assert(svc_sk->sk_setno != skp->sk_setno);
45017c478bd9Sstevel@tonic-gate 
45027c478bd9Sstevel@tonic-gate 	skp->sk_next = dupsk(svc_sk);
45037c478bd9Sstevel@tonic-gate }
45047c478bd9Sstevel@tonic-gate 
45057c478bd9Sstevel@tonic-gate /*
45067c478bd9Sstevel@tonic-gate  * Unlock the set
45077c478bd9Sstevel@tonic-gate  *
45087c478bd9Sstevel@tonic-gate  * To unlock the set, the user must have the correct key, once this is verified
45097c478bd9Sstevel@tonic-gate  * the set is unlocked and the cached information for the set is flushed.
45107c478bd9Sstevel@tonic-gate  */
45117c478bd9Sstevel@tonic-gate bool_t
mdrpc_unlock_set_common(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)45127c478bd9Sstevel@tonic-gate mdrpc_unlock_set_common(
45137c478bd9Sstevel@tonic-gate 	mdrpc_null_args		*args,
45147c478bd9Sstevel@tonic-gate 	mdrpc_setlock_res	*res,
45157c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
45167c478bd9Sstevel@tonic-gate )
45177c478bd9Sstevel@tonic-gate {
45187c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
45197c478bd9Sstevel@tonic-gate 	int			err;
45207c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
45217c478bd9Sstevel@tonic-gate 	md_setkey_t		*svc_skp;
45227c478bd9Sstevel@tonic-gate 	md_set_desc		*sd;
45237c478bd9Sstevel@tonic-gate 	mdsetname_t		*sp;
45247c478bd9Sstevel@tonic-gate 	int			multi_node = 0;
45257c478bd9Sstevel@tonic-gate 	md_error_t		xep = mdnullerror;
45267c478bd9Sstevel@tonic-gate 
45277c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
45287c478bd9Sstevel@tonic-gate 	(void) memset(res, 0, sizeof (*res));
45297c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
45307c478bd9Sstevel@tonic-gate 		return (FALSE);
45317c478bd9Sstevel@tonic-gate 	else if (err != 0)
45327c478bd9Sstevel@tonic-gate 		return (TRUE);
45337c478bd9Sstevel@tonic-gate 
45347c478bd9Sstevel@tonic-gate 	/*
45357c478bd9Sstevel@tonic-gate 	 * Is diskset a MN diskset?
45367c478bd9Sstevel@tonic-gate 	 * Don't set error from this check since unlock set can be
45377c478bd9Sstevel@tonic-gate 	 * called after a set has been deleted.
45387c478bd9Sstevel@tonic-gate 	 */
45397c478bd9Sstevel@tonic-gate 	if (((sp = metasetnosetname(args->cl_sk->sk_setno, &xep)) != NULL) &&
45407c478bd9Sstevel@tonic-gate 	    ((sd = metaget_setdesc(sp, &xep)) != NULL)) {
45417c478bd9Sstevel@tonic-gate 		if ((MD_MNSET_DESC(sd))) {
45427c478bd9Sstevel@tonic-gate 			multi_node = 1;
45437c478bd9Sstevel@tonic-gate 		}
45447c478bd9Sstevel@tonic-gate 	}
45457c478bd9Sstevel@tonic-gate 
45467c478bd9Sstevel@tonic-gate 	/* Get the set key, if any */
45477c478bd9Sstevel@tonic-gate 	svc_skp = svc_get_setkey(args->cl_sk->sk_setno);
45487c478bd9Sstevel@tonic-gate 
45497c478bd9Sstevel@tonic-gate 	/* The set is locked */
45507c478bd9Sstevel@tonic-gate 	if (svc_skp != NULL) {
45517c478bd9Sstevel@tonic-gate 
45527c478bd9Sstevel@tonic-gate 		/* Make sure the opener has the right key. */
45537c478bd9Sstevel@tonic-gate 		if (args->cl_sk->sk_key.tv_sec != svc_skp->sk_key.tv_sec ||
45547c478bd9Sstevel@tonic-gate 		    args->cl_sk->sk_key.tv_usec != svc_skp->sk_key.tv_usec) {
45557c478bd9Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_ULKSBADKEY,
45567c478bd9Sstevel@tonic-gate 			    svc_skp->sk_setno, mynode(), svc_skp->sk_host,
45577c478bd9Sstevel@tonic-gate 			    svc_skp->sk_setname);
45587c478bd9Sstevel@tonic-gate 			free_sk(svc_skp);
45597c478bd9Sstevel@tonic-gate 			return (TRUE);
45607c478bd9Sstevel@tonic-gate 		}
45617c478bd9Sstevel@tonic-gate 
45627c478bd9Sstevel@tonic-gate 		/* Unlock the set */
45637c478bd9Sstevel@tonic-gate 		del_sk(args->cl_sk->sk_setno);
45647c478bd9Sstevel@tonic-gate 
45657c478bd9Sstevel@tonic-gate 		/* Cleanup */
45667c478bd9Sstevel@tonic-gate 		free_sk(svc_skp);
45677c478bd9Sstevel@tonic-gate 
45687c478bd9Sstevel@tonic-gate 		goto out;
45697c478bd9Sstevel@tonic-gate 	}
45707c478bd9Sstevel@tonic-gate 
45717c478bd9Sstevel@tonic-gate 
45727c478bd9Sstevel@tonic-gate 	/*
45737c478bd9Sstevel@tonic-gate 	 * It is possible on a MN diskset to attempt to unlock a set that
45747c478bd9Sstevel@tonic-gate 	 * is unlocked.  This could occur when the metaset or metadb  command
45757c478bd9Sstevel@tonic-gate 	 * is failing due to another metaset or metadb command running.
45767c478bd9Sstevel@tonic-gate 	 * So, print no warning for MN disksets.
45777c478bd9Sstevel@tonic-gate 	 */
45787c478bd9Sstevel@tonic-gate 	if (multi_node == 0) {
45797c478bd9Sstevel@tonic-gate 		md_eprintf("Warning: set unlocked when unlock_set called!\n");
45807c478bd9Sstevel@tonic-gate 	}
45817c478bd9Sstevel@tonic-gate 
45827c478bd9Sstevel@tonic-gate out:
45837c478bd9Sstevel@tonic-gate 	res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
45847c478bd9Sstevel@tonic-gate 
45857c478bd9Sstevel@tonic-gate 	/* Flush the set cache */
45867c478bd9Sstevel@tonic-gate 	sr_cache_flush_setno(args->cl_sk->sk_setno);
45877c478bd9Sstevel@tonic-gate 
45887c478bd9Sstevel@tonic-gate 	return (TRUE);
45897c478bd9Sstevel@tonic-gate }
45907c478bd9Sstevel@tonic-gate 
45917c478bd9Sstevel@tonic-gate bool_t
mdrpc_unlock_set_1_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)45927c478bd9Sstevel@tonic-gate mdrpc_unlock_set_1_svc(
45937c478bd9Sstevel@tonic-gate 	mdrpc_null_args		*args,
45947c478bd9Sstevel@tonic-gate 	mdrpc_setlock_res	*res,
45957c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
45967c478bd9Sstevel@tonic-gate )
45977c478bd9Sstevel@tonic-gate {
45987c478bd9Sstevel@tonic-gate 	return (mdrpc_unlock_set_common(args, res, rqstp));
45997c478bd9Sstevel@tonic-gate }
46007c478bd9Sstevel@tonic-gate 
46017c478bd9Sstevel@tonic-gate bool_t
mdrpc_unlock_set_2_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)46027c478bd9Sstevel@tonic-gate mdrpc_unlock_set_2_svc(
46037c478bd9Sstevel@tonic-gate 	mdrpc_null_args		*args,
46047c478bd9Sstevel@tonic-gate 	mdrpc_setlock_res	*res,
46057c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
46067c478bd9Sstevel@tonic-gate )
46077c478bd9Sstevel@tonic-gate {
46087c478bd9Sstevel@tonic-gate 	return (mdrpc_unlock_set_common(args, res, rqstp));
46097c478bd9Sstevel@tonic-gate }
46107c478bd9Sstevel@tonic-gate 
46117c478bd9Sstevel@tonic-gate /*
46127c478bd9Sstevel@tonic-gate  * Lock the set
46137c478bd9Sstevel@tonic-gate  *
46147c478bd9Sstevel@tonic-gate  * If the user does not hand us a key, then we generate a new key and lock the
46157c478bd9Sstevel@tonic-gate  * set using this new key that was generated, if the user hands us a key then
46167c478bd9Sstevel@tonic-gate  * we use the key to lock the set.
46177c478bd9Sstevel@tonic-gate  */
46187c478bd9Sstevel@tonic-gate bool_t
mdrpc_lock_set_common(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)46197c478bd9Sstevel@tonic-gate mdrpc_lock_set_common(
46207c478bd9Sstevel@tonic-gate 	mdrpc_null_args		*args,
46217c478bd9Sstevel@tonic-gate 	mdrpc_setlock_res	*res,
46227c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
46237c478bd9Sstevel@tonic-gate )
46247c478bd9Sstevel@tonic-gate {
46257c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
46267c478bd9Sstevel@tonic-gate 	int			err;
46277c478bd9Sstevel@tonic-gate 	md_error_t		xep = mdnullerror;
46287c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
46297c478bd9Sstevel@tonic-gate 	md_setkey_t		*svc_skp;
46307c478bd9Sstevel@tonic-gate 	md_setkey_t		new_sk;
463143b3654dSrd117015 	md_set_desc		*sd = NULL;
463243b3654dSrd117015 	mdsetname_t		*sp = NULL;
46337c478bd9Sstevel@tonic-gate 
46347c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
46357c478bd9Sstevel@tonic-gate 	(void) memset(res, 0, sizeof (*res));
46367c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
46377c478bd9Sstevel@tonic-gate 		return (FALSE);
46387c478bd9Sstevel@tonic-gate 	else if (err != 0)
46397c478bd9Sstevel@tonic-gate 		return (TRUE);
46407c478bd9Sstevel@tonic-gate 
46417c478bd9Sstevel@tonic-gate 	svc_skp = svc_get_setkey(args->cl_sk->sk_setno);
46427c478bd9Sstevel@tonic-gate 
464343b3654dSrd117015 	/* The set is locked */
464443b3654dSrd117015 	if (svc_skp != NULL) {
464543b3654dSrd117015 
464643b3654dSrd117015 		/*
464743b3654dSrd117015 		 * This lock request could be for a new diskset, as
464843b3654dSrd117015 		 * such metasetnosetname() may not return anything
464943b3654dSrd117015 		 * useful. Only call it if there is already a key.
465043b3654dSrd117015 		 */
465143b3654dSrd117015 		if ((sp = metasetnosetname(args->cl_sk->sk_setno, ep))
465243b3654dSrd117015 		    != NULL) {
465343b3654dSrd117015 			sd = metaget_setdesc(sp, ep);
465443b3654dSrd117015 		}
465543b3654dSrd117015 
465643b3654dSrd117015 		/*
465743b3654dSrd117015 		 * meta_lock() provides local locking for non-MN
465843b3654dSrd117015 		 * disksets. The local lock is held before we call
465943b3654dSrd117015 		 * this RPC function. We should not receive a lock
466043b3654dSrd117015 		 * request from the host which owns the lock. If we
466143b3654dSrd117015 		 * do, release the lock.
466243b3654dSrd117015 		 */
466343b3654dSrd117015 		if (!((sd != NULL) && (MD_MNSET_DESC(sd))) &&
466443b3654dSrd117015 		    (strcmp(svc_skp->sk_host, args->cl_sk->sk_host) == 0)) {
466543b3654dSrd117015 			md_eprintf(
466643b3654dSrd117015 			    "Warning: set locked when lock_set called!\n");
466743b3654dSrd117015 
466843b3654dSrd117015 			md_eprintf("Held lock info:\n");
466943b3654dSrd117015 
467043b3654dSrd117015 			md_eprintf("\tLock:\n");
467143b3654dSrd117015 			md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname);
467243b3654dSrd117015 			md_eprintf("\t\tSetno:   %d\n", svc_skp->sk_setno);
467343b3654dSrd117015 			md_eprintf("\t\tHost:    %s\n", svc_skp->sk_host);
467443b3654dSrd117015 			md_eprintf("\t\tKey:     %d/%d %s\n",
467543b3654dSrd117015 			    svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec,
467643b3654dSrd117015 			    ctime((const time_t *)&svc_skp->sk_key.tv_sec));
467743b3654dSrd117015 
467843b3654dSrd117015 			/* Unlock set */
467943b3654dSrd117015 			del_sk(svc_skp->sk_setno);
468043b3654dSrd117015 			free_sk(svc_skp);
468143b3654dSrd117015 			svc_skp = NULL;
468243b3654dSrd117015 
468343b3654dSrd117015 			md_eprintf("Released lock held by requesting host\n");
468443b3654dSrd117015 		}
468543b3654dSrd117015 	}
468643b3654dSrd117015 
46877c478bd9Sstevel@tonic-gate 	/* The set is unlocked */
46887c478bd9Sstevel@tonic-gate 	if (svc_skp == NULL) {
46897c478bd9Sstevel@tonic-gate 		/* If we have been given a key, use it. */
46907c478bd9Sstevel@tonic-gate 		if (args->cl_sk->sk_key.tv_sec || args->cl_sk->sk_key.tv_usec) {
46917c478bd9Sstevel@tonic-gate 			svc_set_setkey(args->cl_sk);
46927c478bd9Sstevel@tonic-gate 			res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
46937c478bd9Sstevel@tonic-gate 			goto out;
46947c478bd9Sstevel@tonic-gate 		}
46957c478bd9Sstevel@tonic-gate 
46967c478bd9Sstevel@tonic-gate 		/* We need to lock it, with a new key */
46977c478bd9Sstevel@tonic-gate 		new_sk = *args->cl_sk;
46987c478bd9Sstevel@tonic-gate 		if (meta_gettimeofday(&new_sk.sk_key) == -1) {
46997c478bd9Sstevel@tonic-gate 			(void) mdsyserror(ep, errno, "meta_gettimeofday()");
47007c478bd9Sstevel@tonic-gate 			mde_perror(&xep, "");
47017c478bd9Sstevel@tonic-gate 			md_exit(NULL, 1);
47027c478bd9Sstevel@tonic-gate 		}
47037c478bd9Sstevel@tonic-gate 		svc_set_setkey(&new_sk);
47047c478bd9Sstevel@tonic-gate 
47057c478bd9Sstevel@tonic-gate 		res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
47067c478bd9Sstevel@tonic-gate 		goto out;
47077c478bd9Sstevel@tonic-gate 	}
47087c478bd9Sstevel@tonic-gate 
47097c478bd9Sstevel@tonic-gate 	/*
47107c478bd9Sstevel@tonic-gate 	 * If a MN diskset, the lock_set routine is used as a locking
47117c478bd9Sstevel@tonic-gate 	 * mechanism to keep multiple metaset and/or metadb commads
47127c478bd9Sstevel@tonic-gate 	 * from interfering with each other.  If two metaset/metadb
47137c478bd9Sstevel@tonic-gate 	 * commands are issued at the same time - one will complete
47147c478bd9Sstevel@tonic-gate 	 * and the other command will fail with MDE_DS_NOTNOW_CMD.
47157c478bd9Sstevel@tonic-gate 	 */
471643b3654dSrd117015 	if ((sd != NULL) && MD_MNSET_DESC(sd)) {
47177c478bd9Sstevel@tonic-gate 		(void) mddserror(ep, MDE_DS_NOTNOW_CMD,
47187c478bd9Sstevel@tonic-gate 		    svc_skp->sk_setno, mynode(),
47197c478bd9Sstevel@tonic-gate 		    svc_skp->sk_host, svc_skp->sk_setname);
47207c478bd9Sstevel@tonic-gate 		goto out;
47217c478bd9Sstevel@tonic-gate 	}
47227c478bd9Sstevel@tonic-gate 
47237c478bd9Sstevel@tonic-gate 	md_eprintf("Warning: set locked when lock_set called!\n");
47247c478bd9Sstevel@tonic-gate 
47257c478bd9Sstevel@tonic-gate 	md_eprintf("Lock info:\n");
47267c478bd9Sstevel@tonic-gate 
47277c478bd9Sstevel@tonic-gate 	md_eprintf("\tLock(svc):\n");
47287c478bd9Sstevel@tonic-gate 	md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname);
47297c478bd9Sstevel@tonic-gate 	md_eprintf("\t\tSetno:   %d\n", svc_skp->sk_setno);
47307c478bd9Sstevel@tonic-gate 	md_eprintf("\t\tHost:    %s\n", svc_skp->sk_host);
47317c478bd9Sstevel@tonic-gate 	md_eprintf("\t\tKey:     %d/%d %s",
47327c478bd9Sstevel@tonic-gate 	    svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec,
47337c478bd9Sstevel@tonic-gate 	    ctime((const time_t *)&svc_skp->sk_key.tv_sec));
47347c478bd9Sstevel@tonic-gate 
47357c478bd9Sstevel@tonic-gate 	md_eprintf("\tLock(cl):\n");
47367c478bd9Sstevel@tonic-gate 	md_eprintf("\t\tSetname: %s\n", args->cl_sk->sk_setname);
47377c478bd9Sstevel@tonic-gate 	md_eprintf("\t\tSetno:   %d\n", args->cl_sk->sk_setno);
47387c478bd9Sstevel@tonic-gate 	md_eprintf("\t\tHost:    %s\n", args->cl_sk->sk_host);
47397c478bd9Sstevel@tonic-gate 	md_eprintf("\t\tKey:     %d/%d %s",
47407c478bd9Sstevel@tonic-gate 	    args->cl_sk->sk_key.tv_sec, args->cl_sk->sk_key.tv_usec,
47417c478bd9Sstevel@tonic-gate 	    ctime((const time_t *)&args->cl_sk->sk_key.tv_sec));
47427c478bd9Sstevel@tonic-gate 
47437c478bd9Sstevel@tonic-gate 	/* The set is locked, do we have the key? */
47447c478bd9Sstevel@tonic-gate 	if (args->cl_sk->sk_key.tv_sec == svc_skp->sk_key.tv_sec &&
47457c478bd9Sstevel@tonic-gate 	    args->cl_sk->sk_key.tv_usec == svc_skp->sk_key.tv_usec) {
47467c478bd9Sstevel@tonic-gate 		res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
47477c478bd9Sstevel@tonic-gate 		goto out;
47487c478bd9Sstevel@tonic-gate 	}
47497c478bd9Sstevel@tonic-gate 
47507c478bd9Sstevel@tonic-gate 	/*
47517c478bd9Sstevel@tonic-gate 	 * The set is locked and we do not have the key, so we set up an error.
47527c478bd9Sstevel@tonic-gate 	 */
47537c478bd9Sstevel@tonic-gate 	(void) mddserror(ep, MDE_DS_LKSBADKEY, svc_skp->sk_setno, mynode(),
47547c478bd9Sstevel@tonic-gate 	    svc_skp->sk_host, args->cl_sk->sk_setname);
47557c478bd9Sstevel@tonic-gate 
47567c478bd9Sstevel@tonic-gate out:
47577c478bd9Sstevel@tonic-gate 	if (svc_skp != NULL)
47587c478bd9Sstevel@tonic-gate 		free_sk(svc_skp);
47597c478bd9Sstevel@tonic-gate 
47607c478bd9Sstevel@tonic-gate 	/* Flush the set cache */
47617c478bd9Sstevel@tonic-gate 	sr_cache_flush_setno(args->cl_sk->sk_setno);
47627c478bd9Sstevel@tonic-gate 
47637c478bd9Sstevel@tonic-gate 	return (TRUE);
47647c478bd9Sstevel@tonic-gate }
47657c478bd9Sstevel@tonic-gate 
47667c478bd9Sstevel@tonic-gate bool_t
mdrpc_lock_set_1_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)47677c478bd9Sstevel@tonic-gate mdrpc_lock_set_1_svc(
47687c478bd9Sstevel@tonic-gate 	mdrpc_null_args		*args,
47697c478bd9Sstevel@tonic-gate 	mdrpc_setlock_res	*res,
47707c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
47717c478bd9Sstevel@tonic-gate )
47727c478bd9Sstevel@tonic-gate {
47737c478bd9Sstevel@tonic-gate 	return (mdrpc_lock_set_common(args, res, rqstp));
47747c478bd9Sstevel@tonic-gate }
47757c478bd9Sstevel@tonic-gate 
47767c478bd9Sstevel@tonic-gate bool_t
mdrpc_lock_set_2_svc(mdrpc_null_args * args,mdrpc_setlock_res * res,struct svc_req * rqstp)47777c478bd9Sstevel@tonic-gate mdrpc_lock_set_2_svc(
47787c478bd9Sstevel@tonic-gate 	mdrpc_null_args		*args,
47797c478bd9Sstevel@tonic-gate 	mdrpc_setlock_res	*res,
47807c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
47817c478bd9Sstevel@tonic-gate )
47827c478bd9Sstevel@tonic-gate {
47837c478bd9Sstevel@tonic-gate 	return (mdrpc_lock_set_common(args, res, rqstp));
47847c478bd9Sstevel@tonic-gate }
47857c478bd9Sstevel@tonic-gate 
47867c478bd9Sstevel@tonic-gate static void
updmeds(char * setname,md_h_arr_t * medp,int version,md_error_t * ep)47877c478bd9Sstevel@tonic-gate updmeds(
47887c478bd9Sstevel@tonic-gate 	char		*setname,
47897c478bd9Sstevel@tonic-gate 	md_h_arr_t	*medp,
47907c478bd9Sstevel@tonic-gate 	int		version,	/* RPC version of calling routine */
47917c478bd9Sstevel@tonic-gate 	md_error_t	*ep
47927c478bd9Sstevel@tonic-gate )
47937c478bd9Sstevel@tonic-gate {
47947c478bd9Sstevel@tonic-gate 	mddb_userreq_t		req;
47957c478bd9Sstevel@tonic-gate 	md_set_record		*sr;
47967c478bd9Sstevel@tonic-gate 	mddb_med_parm_t		mp;
47977c478bd9Sstevel@tonic-gate 
47987c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(setname, ep)) == NULL)
47997c478bd9Sstevel@tonic-gate 		return;
48007c478bd9Sstevel@tonic-gate 
48017c478bd9Sstevel@tonic-gate 	sr->sr_med = *medp;			/* structure assignment */
48027c478bd9Sstevel@tonic-gate 
48037c478bd9Sstevel@tonic-gate 	(void) memset(&req, '\0', sizeof (req));
48047c478bd9Sstevel@tonic-gate 
48057c478bd9Sstevel@tonic-gate 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
48067c478bd9Sstevel@tonic-gate 	/* Do MN operation if rpc version supports it and if a MN set */
48077c478bd9Sstevel@tonic-gate 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
48087c478bd9Sstevel@tonic-gate 		req.ur_size = sizeof (struct md_mnset_record);
48097c478bd9Sstevel@tonic-gate 	} else {
48107c478bd9Sstevel@tonic-gate 		req.ur_size = sizeof (*sr);
48117c478bd9Sstevel@tonic-gate 	}
48127c478bd9Sstevel@tonic-gate 	req.ur_data = (uintptr_t)sr;
48137c478bd9Sstevel@tonic-gate 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
48147c478bd9Sstevel@tonic-gate 		(void) mdstealerror(ep, &req.ur_mde);
48157c478bd9Sstevel@tonic-gate 		free_sr(sr);
48167c478bd9Sstevel@tonic-gate 		return;
48177c478bd9Sstevel@tonic-gate 	}
48187c478bd9Sstevel@tonic-gate 
48197c478bd9Sstevel@tonic-gate 	commitset(sr, TRUE, ep);
48207c478bd9Sstevel@tonic-gate 
48217c478bd9Sstevel@tonic-gate 	/*
48227c478bd9Sstevel@tonic-gate 	 * If a MN disket, send the mediator list to the kernel.
48237c478bd9Sstevel@tonic-gate 	 */
48247c478bd9Sstevel@tonic-gate 	if (MD_MNSET_REC(sr)) {
48257c478bd9Sstevel@tonic-gate 		(void) memset(&mp, '\0', sizeof (mddb_med_parm_t));
48267c478bd9Sstevel@tonic-gate 		mp.med_setno = sr->sr_setno;
48277c478bd9Sstevel@tonic-gate 		if (meta_h2hi(medp, &mp.med, ep)) {
48287c478bd9Sstevel@tonic-gate 			free_sr(sr);
48297c478bd9Sstevel@tonic-gate 			return;
48307c478bd9Sstevel@tonic-gate 		}
48317c478bd9Sstevel@tonic-gate 
48327c478bd9Sstevel@tonic-gate 		/* Resolve the IP addresses for the host list */
48337c478bd9Sstevel@tonic-gate 		if (meta_med_hnm2ip(&mp.med, ep)) {
48347c478bd9Sstevel@tonic-gate 			free_sr(sr);
48357c478bd9Sstevel@tonic-gate 			return;
48367c478bd9Sstevel@tonic-gate 		}
48377c478bd9Sstevel@tonic-gate 
48387c478bd9Sstevel@tonic-gate 		/* If node not yet joined to set, failure is ok. */
48397c478bd9Sstevel@tonic-gate 		if (metaioctl(MD_MED_SET_LST, &mp, &mp.med_mde, NULL) != 0) {
48407c478bd9Sstevel@tonic-gate 			if (!mdismddberror(&mp.med_mde, MDE_DB_NOTOWNER)) {
48417c478bd9Sstevel@tonic-gate 				(void) mdstealerror(ep, &mp.med_mde);
48427c478bd9Sstevel@tonic-gate 			}
48437c478bd9Sstevel@tonic-gate 		}
48447c478bd9Sstevel@tonic-gate 	}
48457c478bd9Sstevel@tonic-gate 	free_sr(sr);
48467c478bd9Sstevel@tonic-gate }
48477c478bd9Sstevel@tonic-gate 
48487c478bd9Sstevel@tonic-gate /*
48497c478bd9Sstevel@tonic-gate  * Update the mediator data in the set record
48507c478bd9Sstevel@tonic-gate  */
48517c478bd9Sstevel@tonic-gate bool_t
mdrpc_updmeds_common(mdrpc_updmeds_args * args,mdrpc_generic_res * res,struct svc_req * rqstp,int version)48527c478bd9Sstevel@tonic-gate mdrpc_updmeds_common(
48537c478bd9Sstevel@tonic-gate 	mdrpc_updmeds_args	*args,
48547c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
48557c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp,		/* RPC stuff */
48567c478bd9Sstevel@tonic-gate 	int			version		/* RPC version */
48577c478bd9Sstevel@tonic-gate )
48587c478bd9Sstevel@tonic-gate {
48597c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
48607c478bd9Sstevel@tonic-gate 	int			err;
48617c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
48627c478bd9Sstevel@tonic-gate 
48637c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
48647c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
48657c478bd9Sstevel@tonic-gate 		return (FALSE);
48667c478bd9Sstevel@tonic-gate 	else if (err != 0)
48677c478bd9Sstevel@tonic-gate 		return (TRUE);
48687c478bd9Sstevel@tonic-gate 
48697c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
48707c478bd9Sstevel@tonic-gate 		return (TRUE);
48717c478bd9Sstevel@tonic-gate 
48727c478bd9Sstevel@tonic-gate 	/* doit */
48737c478bd9Sstevel@tonic-gate 	updmeds(args->sp->setname, &args->meds, version, ep);
48747c478bd9Sstevel@tonic-gate 
48757c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
48767c478bd9Sstevel@tonic-gate 
48777c478bd9Sstevel@tonic-gate 	return (TRUE);
48787c478bd9Sstevel@tonic-gate }
48797c478bd9Sstevel@tonic-gate 
48807c478bd9Sstevel@tonic-gate bool_t
mdrpc_updmeds_1_svc(mdrpc_updmeds_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)48817c478bd9Sstevel@tonic-gate mdrpc_updmeds_1_svc(
48827c478bd9Sstevel@tonic-gate 	mdrpc_updmeds_args	*args,
48837c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
48847c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
48857c478bd9Sstevel@tonic-gate )
48867c478bd9Sstevel@tonic-gate {
48872a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
48887c478bd9Sstevel@tonic-gate 	/* Pass RPC version (METAD_VERSION) to common routine */
48897c478bd9Sstevel@tonic-gate 	return (mdrpc_updmeds_common(args, res, rqstp, METAD_VERSION));
48907c478bd9Sstevel@tonic-gate }
48917c478bd9Sstevel@tonic-gate 
48927c478bd9Sstevel@tonic-gate bool_t
mdrpc_updmeds_2_svc(mdrpc_updmeds_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)48937c478bd9Sstevel@tonic-gate mdrpc_updmeds_2_svc(
48947c478bd9Sstevel@tonic-gate 	mdrpc_updmeds_2_args	*args,
48957c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
48967c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
48977c478bd9Sstevel@tonic-gate )
48987c478bd9Sstevel@tonic-gate {
48992a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
49007c478bd9Sstevel@tonic-gate 	switch (args->rev) {
49017c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
49027c478bd9Sstevel@tonic-gate 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
49037c478bd9Sstevel@tonic-gate 		return (mdrpc_updmeds_common(
49047c478bd9Sstevel@tonic-gate 		    &args->mdrpc_updmeds_2_args_u.rev1, res,
49057c478bd9Sstevel@tonic-gate 		    rqstp, METAD_VERSION_DEVID));
49067c478bd9Sstevel@tonic-gate 	default:
49077c478bd9Sstevel@tonic-gate 		return (FALSE);
49087c478bd9Sstevel@tonic-gate 	}
49097c478bd9Sstevel@tonic-gate }
49107c478bd9Sstevel@tonic-gate 
49117c478bd9Sstevel@tonic-gate /*
49127c478bd9Sstevel@tonic-gate  * Call routines to suspend, reinit and resume mdcommd.
49137c478bd9Sstevel@tonic-gate  * Called during metaset and metadb command.
49147c478bd9Sstevel@tonic-gate  * NOT called during reconfig cycle.
49157c478bd9Sstevel@tonic-gate  */
49167c478bd9Sstevel@tonic-gate bool_t
mdrpc_mdcommdctl_2_svc(mdrpc_mdcommdctl_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)49177c478bd9Sstevel@tonic-gate mdrpc_mdcommdctl_2_svc(
49187c478bd9Sstevel@tonic-gate 	mdrpc_mdcommdctl_2_args	*args,
49197c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
49207c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
49217c478bd9Sstevel@tonic-gate )
49227c478bd9Sstevel@tonic-gate {
49237c478bd9Sstevel@tonic-gate 	mdrpc_mdcommdctl_args	*args_cc;
49247c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
49257c478bd9Sstevel@tonic-gate 	int			err;
49267c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
49277c478bd9Sstevel@tonic-gate 	int			suspend_ret;
49287c478bd9Sstevel@tonic-gate 
49292a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
49307c478bd9Sstevel@tonic-gate 	switch (args->rev) {
49317c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
49327c478bd9Sstevel@tonic-gate 		/* setup, check permissions */
49337c478bd9Sstevel@tonic-gate 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
49347c478bd9Sstevel@tonic-gate 			return (FALSE);
49357c478bd9Sstevel@tonic-gate 		else if (err != 0)
49367c478bd9Sstevel@tonic-gate 			return (TRUE);
49377c478bd9Sstevel@tonic-gate 
49387c478bd9Sstevel@tonic-gate 		args_cc = &(args->mdrpc_mdcommdctl_2_args_u.rev1);
49397c478bd9Sstevel@tonic-gate 		switch (args_cc->flag_action) {
49407c478bd9Sstevel@tonic-gate 			case COMMDCTL_SUSPEND:
49417c478bd9Sstevel@tonic-gate 				suspend_ret = mdmn_suspend(args_cc->setno,
4942ab3487b0Sjkennedy 				    args_cc->class, 0);
49437c478bd9Sstevel@tonic-gate 				if (suspend_ret != 0) {
49447c478bd9Sstevel@tonic-gate 					(void) mddserror(ep, suspend_ret,
49457c478bd9Sstevel@tonic-gate 					    args_cc->setno, mynode(),
49467c478bd9Sstevel@tonic-gate 					    NULL, mynode());
49477c478bd9Sstevel@tonic-gate 				}
49487c478bd9Sstevel@tonic-gate 				break;
49497c478bd9Sstevel@tonic-gate 			case COMMDCTL_RESUME:
49507c478bd9Sstevel@tonic-gate 				if (mdmn_resume(args_cc->setno,
4951ab3487b0Sjkennedy 				    args_cc->class, args_cc->flags, 0)) {
49527c478bd9Sstevel@tonic-gate 					(void) mddserror(ep,
49537c478bd9Sstevel@tonic-gate 					    MDE_DS_COMMDCTL_RESUME_FAIL,
49547c478bd9Sstevel@tonic-gate 					    args_cc->setno, mynode(),
49557c478bd9Sstevel@tonic-gate 					    NULL, mynode());
49567c478bd9Sstevel@tonic-gate 				}
49577c478bd9Sstevel@tonic-gate 				break;
49587c478bd9Sstevel@tonic-gate 			case COMMDCTL_REINIT:
4959ab3487b0Sjkennedy 				if (mdmn_reinit_set(args_cc->setno, 0)) {
49607c478bd9Sstevel@tonic-gate 					(void) mddserror(ep,
49617c478bd9Sstevel@tonic-gate 					    MDE_DS_COMMDCTL_REINIT_FAIL,
49627c478bd9Sstevel@tonic-gate 					    args_cc->setno, mynode(),
49637c478bd9Sstevel@tonic-gate 					    NULL, mynode());
49647c478bd9Sstevel@tonic-gate 				}
49657c478bd9Sstevel@tonic-gate 				break;
49667c478bd9Sstevel@tonic-gate 		}
49677c478bd9Sstevel@tonic-gate 		err = svc_fini(ep);
49687c478bd9Sstevel@tonic-gate 		return (TRUE);
49697c478bd9Sstevel@tonic-gate 
49707c478bd9Sstevel@tonic-gate 	default:
49717c478bd9Sstevel@tonic-gate 		return (FALSE);
49727c478bd9Sstevel@tonic-gate 	}
49737c478bd9Sstevel@tonic-gate }
49747c478bd9Sstevel@tonic-gate 
49757c478bd9Sstevel@tonic-gate /*
49767c478bd9Sstevel@tonic-gate  * Return TRUE if set is stale.
49777c478bd9Sstevel@tonic-gate  */
49787c478bd9Sstevel@tonic-gate bool_t
mdrpc_mn_is_stale_2_svc(mdrpc_setno_2_args * args,mdrpc_bool_res * res,struct svc_req * rqstp)49797c478bd9Sstevel@tonic-gate mdrpc_mn_is_stale_2_svc(
49807c478bd9Sstevel@tonic-gate 	mdrpc_setno_2_args	*args,
49817c478bd9Sstevel@tonic-gate 	mdrpc_bool_res		*res,
49827c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
49837c478bd9Sstevel@tonic-gate )
49847c478bd9Sstevel@tonic-gate {
49857c478bd9Sstevel@tonic-gate 	md_error_t	*ep = &res->status;
49867c478bd9Sstevel@tonic-gate 	mddb_config_t	c;
49877c478bd9Sstevel@tonic-gate 	int		err;
49887c478bd9Sstevel@tonic-gate 	int		op_mode = R_OK;
49897c478bd9Sstevel@tonic-gate 
49902a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
49917c478bd9Sstevel@tonic-gate 	(void) memset(&c, 0, sizeof (c));
49927c478bd9Sstevel@tonic-gate 	switch (args->rev) {
49937c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
49947c478bd9Sstevel@tonic-gate 		c.c_id = 0;
49957c478bd9Sstevel@tonic-gate 		c.c_setno = args->mdrpc_setno_2_args_u.rev1.setno;
49967c478bd9Sstevel@tonic-gate 
49977c478bd9Sstevel@tonic-gate 		/* setup, check permissions */
49987c478bd9Sstevel@tonic-gate 		(void) memset(res, 0, sizeof (*res));
49997c478bd9Sstevel@tonic-gate 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
50007c478bd9Sstevel@tonic-gate 			return (FALSE);
50017c478bd9Sstevel@tonic-gate 		else if (err != 0)
50027c478bd9Sstevel@tonic-gate 			return (TRUE);
50037c478bd9Sstevel@tonic-gate 
50047c478bd9Sstevel@tonic-gate 		if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) {
5005*80148899SSurya Prakki 			(void) mdstealerror(ep, &c.c_mde);
50067c478bd9Sstevel@tonic-gate 			return (TRUE);
50077c478bd9Sstevel@tonic-gate 		}
50087c478bd9Sstevel@tonic-gate 
50097c478bd9Sstevel@tonic-gate 		if (c.c_flags & MDDB_C_STALE) {
50107c478bd9Sstevel@tonic-gate 			res->value = TRUE;
50117c478bd9Sstevel@tonic-gate 		} else {
50127c478bd9Sstevel@tonic-gate 			res->value = FALSE;
50137c478bd9Sstevel@tonic-gate 		}
50147c478bd9Sstevel@tonic-gate 
50157c478bd9Sstevel@tonic-gate 		err = svc_fini(ep);
50167c478bd9Sstevel@tonic-gate 		return (TRUE);
50177c478bd9Sstevel@tonic-gate 
50187c478bd9Sstevel@tonic-gate 	default:
50197c478bd9Sstevel@tonic-gate 		return (FALSE);
50207c478bd9Sstevel@tonic-gate 	}
50217c478bd9Sstevel@tonic-gate }
50227c478bd9Sstevel@tonic-gate 
50237c478bd9Sstevel@tonic-gate /*
50247c478bd9Sstevel@tonic-gate  * Clear out all clnt_locks held by all MN disksets.
50257c478bd9Sstevel@tonic-gate  * This is only used during a reconfig cycle.
50267c478bd9Sstevel@tonic-gate  */
50277c478bd9Sstevel@tonic-gate /* ARGSUSED */
5028b6c8bd52Sjeanm int
mdrpc_clr_mnsetlock_2_svc(mdrpc_null_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)50297c478bd9Sstevel@tonic-gate mdrpc_clr_mnsetlock_2_svc(
50307c478bd9Sstevel@tonic-gate 	mdrpc_null_args		*args,
50317c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
50327c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
50337c478bd9Sstevel@tonic-gate )
50347c478bd9Sstevel@tonic-gate {
50357c478bd9Sstevel@tonic-gate 	set_t			max_sets, setno;
50367c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
50377c478bd9Sstevel@tonic-gate 	int			err;
50387c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
50397c478bd9Sstevel@tonic-gate 	mdsetname_t		*sp;
50407c478bd9Sstevel@tonic-gate 
50417c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
50427c478bd9Sstevel@tonic-gate 	(void) memset(res, 0, sizeof (*res));
50437c478bd9Sstevel@tonic-gate 
50447c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
50457c478bd9Sstevel@tonic-gate 		return (FALSE);
50467c478bd9Sstevel@tonic-gate 	else if (err != 0)
50477c478bd9Sstevel@tonic-gate 		return (TRUE);
50487c478bd9Sstevel@tonic-gate 
50497c478bd9Sstevel@tonic-gate 	/*
50507c478bd9Sstevel@tonic-gate 	 * Walk through all possible disksets.
50517c478bd9Sstevel@tonic-gate 	 * For each MN set, delete all keys associated with that set.
50527c478bd9Sstevel@tonic-gate 	 */
50537c478bd9Sstevel@tonic-gate 	if ((max_sets = get_max_sets(ep)) == 0) {
50547c478bd9Sstevel@tonic-gate 		return (TRUE);
50557c478bd9Sstevel@tonic-gate 	}
50567c478bd9Sstevel@tonic-gate 
50577c478bd9Sstevel@tonic-gate 	/* start walking through all possible disksets */
50587c478bd9Sstevel@tonic-gate 	for (setno = 1; setno < max_sets; setno++) {
50597c478bd9Sstevel@tonic-gate 		if ((sp = metasetnosetname(setno, ep)) == NULL) {
50607c478bd9Sstevel@tonic-gate 			if (mdiserror(ep, MDE_NO_SET)) {
50617c478bd9Sstevel@tonic-gate 				/* No set for this setno - continue */
50627c478bd9Sstevel@tonic-gate 				mdclrerror(ep);
50637c478bd9Sstevel@tonic-gate 				continue;
50647c478bd9Sstevel@tonic-gate 			} else {
50657c478bd9Sstevel@tonic-gate 				mde_perror(ep, gettext(
50667c478bd9Sstevel@tonic-gate 				    "Unable to get set %s information"),
50677c478bd9Sstevel@tonic-gate 				    sp->setname);
50687c478bd9Sstevel@tonic-gate 				mdclrerror(ep);
50697c478bd9Sstevel@tonic-gate 				continue;
50707c478bd9Sstevel@tonic-gate 			}
50717c478bd9Sstevel@tonic-gate 		}
50727c478bd9Sstevel@tonic-gate 
50737c478bd9Sstevel@tonic-gate 		/* only check multi-node disksets */
50747c478bd9Sstevel@tonic-gate 		if (!meta_is_mn_set(sp, ep)) {
50757c478bd9Sstevel@tonic-gate 			mdclrerror(ep);
50767c478bd9Sstevel@tonic-gate 			continue;
50777c478bd9Sstevel@tonic-gate 		}
50787c478bd9Sstevel@tonic-gate 
50797c478bd9Sstevel@tonic-gate 		/* Delete keys associated with rpc.metad clnt_lock */
50807c478bd9Sstevel@tonic-gate 		del_sk(setno);
50817c478bd9Sstevel@tonic-gate 	}
50827c478bd9Sstevel@tonic-gate 
50837c478bd9Sstevel@tonic-gate 	*ep = mdnullerror;
50847c478bd9Sstevel@tonic-gate 
50857c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
50867c478bd9Sstevel@tonic-gate 
50877c478bd9Sstevel@tonic-gate 	return (TRUE);
50887c478bd9Sstevel@tonic-gate }
50897c478bd9Sstevel@tonic-gate 
50907c478bd9Sstevel@tonic-gate /*
50917c478bd9Sstevel@tonic-gate  * Get drive desc on this host for given setno.
50927c478bd9Sstevel@tonic-gate  * This is only used during a reconfig cycle.
50937c478bd9Sstevel@tonic-gate  * Returns a drive desc structure for the given mdsetname
50947c478bd9Sstevel@tonic-gate  * from this host.
50957c478bd9Sstevel@tonic-gate  *
50967c478bd9Sstevel@tonic-gate  * Returned drive desc structure is partially filled in with
50977c478bd9Sstevel@tonic-gate  * the drive name but is not filled in with any other strings
50987c478bd9Sstevel@tonic-gate  * in the drivename structure.
50997c478bd9Sstevel@tonic-gate  */
51007c478bd9Sstevel@tonic-gate bool_t
mdrpc_getdrivedesc_2_svc(mdrpc_sp_2_args * args,mdrpc_getdrivedesc_res * res,struct svc_req * rqstp)51017c478bd9Sstevel@tonic-gate mdrpc_getdrivedesc_2_svc(
51027c478bd9Sstevel@tonic-gate 	mdrpc_sp_2_args		*args,
51037c478bd9Sstevel@tonic-gate 	mdrpc_getdrivedesc_res 	*res,
51047c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
51057c478bd9Sstevel@tonic-gate )
51067c478bd9Sstevel@tonic-gate {
51077c478bd9Sstevel@tonic-gate 	md_drive_desc		*dd;
51087c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
51097c478bd9Sstevel@tonic-gate 	int			err;
51107c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
51117c478bd9Sstevel@tonic-gate 	mdsetname_t		*my_sp;
51127c478bd9Sstevel@tonic-gate 	mdrpc_sp_args		*args_r1;
51137c478bd9Sstevel@tonic-gate 
51142a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
51157c478bd9Sstevel@tonic-gate 	switch (args->rev) {
51167c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
51177c478bd9Sstevel@tonic-gate 		/* setup, check permissions */
51187c478bd9Sstevel@tonic-gate 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
51197c478bd9Sstevel@tonic-gate 			return (FALSE);
51207c478bd9Sstevel@tonic-gate 		else if (err != 0)
51217c478bd9Sstevel@tonic-gate 			return (TRUE);
51227c478bd9Sstevel@tonic-gate 
51237c478bd9Sstevel@tonic-gate 		/* doit */
51247c478bd9Sstevel@tonic-gate 		args_r1 = &args->mdrpc_sp_2_args_u.rev1;
51257c478bd9Sstevel@tonic-gate 		if ((my_sp = metasetname(args_r1->sp->setname, ep)) == NULL)
51267c478bd9Sstevel@tonic-gate 			return (TRUE);
51277c478bd9Sstevel@tonic-gate 
51287c478bd9Sstevel@tonic-gate 		dd = metaget_drivedesc(my_sp,
51297c478bd9Sstevel@tonic-gate 		    (MD_BASICNAME_OK | PRINT_FAST), ep);
51307c478bd9Sstevel@tonic-gate 
51317c478bd9Sstevel@tonic-gate 		res->dd = dd_list_dup(dd);
51327c478bd9Sstevel@tonic-gate 
51337c478bd9Sstevel@tonic-gate 		err = svc_fini(ep);
51347c478bd9Sstevel@tonic-gate 
51357c478bd9Sstevel@tonic-gate 		return (TRUE);
51367c478bd9Sstevel@tonic-gate 	default:
51377c478bd9Sstevel@tonic-gate 		return (FALSE);
51387c478bd9Sstevel@tonic-gate 	}
51397c478bd9Sstevel@tonic-gate }
51407c478bd9Sstevel@tonic-gate 
51417c478bd9Sstevel@tonic-gate /*
51427c478bd9Sstevel@tonic-gate  * Update drive records given list from master during reconfig.
51437c478bd9Sstevel@tonic-gate  * Make this node's list match the master's list which may include
51447c478bd9Sstevel@tonic-gate  * deleting a drive record that is known by this node and not known
51457c478bd9Sstevel@tonic-gate  * by the master node.
51467c478bd9Sstevel@tonic-gate  *
51477c478bd9Sstevel@tonic-gate  * Sync up the set/node/drive record genids to match the genid
51487c478bd9Sstevel@tonic-gate  * passed in the dd structure (all genids in this structure
51497c478bd9Sstevel@tonic-gate  * are the same).
51507c478bd9Sstevel@tonic-gate  */
51517c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_reconfig_common(mdrpc_upd_dr_flags_2_args_r1 * args,mdrpc_generic_res * res,struct svc_req * rqstp)51527c478bd9Sstevel@tonic-gate mdrpc_upd_dr_reconfig_common(
51537c478bd9Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args_r1	*args,
51547c478bd9Sstevel@tonic-gate 	mdrpc_generic_res		*res,
51557c478bd9Sstevel@tonic-gate 	struct svc_req			*rqstp		/* RPC stuff */
51567c478bd9Sstevel@tonic-gate )
51577c478bd9Sstevel@tonic-gate {
51587c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
51597c478bd9Sstevel@tonic-gate 	int			err;
51607c478bd9Sstevel@tonic-gate 	mdsetname_t		*local_sp;
51617c478bd9Sstevel@tonic-gate 	md_set_record		*sr;
51627c478bd9Sstevel@tonic-gate 	md_mnset_record		*mnsr;
51637c478bd9Sstevel@tonic-gate 	md_drive_record		*dr, *dr_placeholder = NULL;
51647c478bd9Sstevel@tonic-gate 	md_drive_desc		*dd;
51657c478bd9Sstevel@tonic-gate 	mddrivename_t		*dn, *dn1;
51667c478bd9Sstevel@tonic-gate 	side_t			sideno;
51677c478bd9Sstevel@tonic-gate 	md_mnnode_record	*nrp;
51687c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
51697c478bd9Sstevel@tonic-gate 	int			change = 0;
51707c478bd9Sstevel@tonic-gate 
51717c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
51727c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
51737c478bd9Sstevel@tonic-gate 		return (FALSE);
51747c478bd9Sstevel@tonic-gate 	else if (err != 0)
51757c478bd9Sstevel@tonic-gate 		return (TRUE);
51767c478bd9Sstevel@tonic-gate 
51777c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(args->sp->setname, ep)) == NULL)
51787c478bd9Sstevel@tonic-gate 		return (TRUE);
51797c478bd9Sstevel@tonic-gate 
51807c478bd9Sstevel@tonic-gate 	metaflushsetname(local_sp);
51817c478bd9Sstevel@tonic-gate 
51827c478bd9Sstevel@tonic-gate 	if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
51837c478bd9Sstevel@tonic-gate 		return (TRUE);
51847c478bd9Sstevel@tonic-gate 
51857c478bd9Sstevel@tonic-gate 	if ((sr = getsetbyname(args->sp->setname, ep)) == NULL)
51867c478bd9Sstevel@tonic-gate 		return (TRUE);
51877c478bd9Sstevel@tonic-gate 
51887c478bd9Sstevel@tonic-gate 	if (!(MD_MNSET_REC(sr))) {
51897c478bd9Sstevel@tonic-gate 		free_sr(sr);
51907c478bd9Sstevel@tonic-gate 		return (TRUE);
51917c478bd9Sstevel@tonic-gate 	}
51927c478bd9Sstevel@tonic-gate 
51937c478bd9Sstevel@tonic-gate 	mnsr = (md_mnset_record *)sr;
51947c478bd9Sstevel@tonic-gate 	/* Setup genid on set and node records */
51957c478bd9Sstevel@tonic-gate 	if (args->drivedescs) {
51967c478bd9Sstevel@tonic-gate 		if (mnsr->sr_genid != args->drivedescs->dd_genid) {
51977c478bd9Sstevel@tonic-gate 			change = 1;
51987c478bd9Sstevel@tonic-gate 			mnsr->sr_genid = args->drivedescs->dd_genid;
51997c478bd9Sstevel@tonic-gate 		}
52007c478bd9Sstevel@tonic-gate 		nrp = mnsr->sr_nodechain;
52017c478bd9Sstevel@tonic-gate 		while (nrp) {
52027c478bd9Sstevel@tonic-gate 			if (nrp->nr_genid != args->drivedescs->dd_genid) {
52037c478bd9Sstevel@tonic-gate 				change = 1;
52047c478bd9Sstevel@tonic-gate 				nrp->nr_genid = args->drivedescs->dd_genid;
52057c478bd9Sstevel@tonic-gate 			}
52067c478bd9Sstevel@tonic-gate 			nrp = nrp->nr_next;
52077c478bd9Sstevel@tonic-gate 		}
52087c478bd9Sstevel@tonic-gate 	}
52097c478bd9Sstevel@tonic-gate 	for (dr = mnsr->sr_drivechain; dr; dr = dr->dr_next) {
52107c478bd9Sstevel@tonic-gate 		dn1 = metadrivename_withdrkey(local_sp, sideno,
52117c478bd9Sstevel@tonic-gate 		    dr->dr_key, (MD_BASICNAME_OK | PRINT_FAST), ep);
52127c478bd9Sstevel@tonic-gate 		if (dn1 == NULL)
52137c478bd9Sstevel@tonic-gate 			goto out;
52147c478bd9Sstevel@tonic-gate 		for (dd = args->drivedescs; dd != NULL; dd = dd->dd_next) {
52157c478bd9Sstevel@tonic-gate 			dn = dd->dd_dnp;
52167c478bd9Sstevel@tonic-gate 			/* Found this node's drive rec to match dd */
52177c478bd9Sstevel@tonic-gate 			if (strcmp(dn->cname, dn1->cname) == 0)
52187c478bd9Sstevel@tonic-gate 				break;
52197c478bd9Sstevel@tonic-gate 		}
52207c478bd9Sstevel@tonic-gate 
52217c478bd9Sstevel@tonic-gate 		/*
52227c478bd9Sstevel@tonic-gate 		 * If drive found in master's list, make slave match master.
52237c478bd9Sstevel@tonic-gate 		 * If drive not found in master's list, remove drive.
52247c478bd9Sstevel@tonic-gate 		 */
52257c478bd9Sstevel@tonic-gate 		if (dd) {
52267c478bd9Sstevel@tonic-gate 			if ((dr->dr_flags != dd->dd_flags) ||
52277c478bd9Sstevel@tonic-gate 			    (dr->dr_genid != dd->dd_genid)) {
52287c478bd9Sstevel@tonic-gate 				change = 1;
52297c478bd9Sstevel@tonic-gate 				dr->dr_flags = dd->dd_flags;
52307c478bd9Sstevel@tonic-gate 				dr->dr_genid = dd->dd_genid;
52317c478bd9Sstevel@tonic-gate 			}
52327c478bd9Sstevel@tonic-gate 		} else {
52337c478bd9Sstevel@tonic-gate 			/*
52347c478bd9Sstevel@tonic-gate 			 * Delete entry from linked list.  Need to use
52357c478bd9Sstevel@tonic-gate 			 * dr_placeholder so that dr->dr_next points to
52367c478bd9Sstevel@tonic-gate 			 * the next drive record in the list.
52377c478bd9Sstevel@tonic-gate 			 */
52387c478bd9Sstevel@tonic-gate 			if (dr_placeholder == NULL) {
52397c478bd9Sstevel@tonic-gate 				dr_placeholder =
52407c478bd9Sstevel@tonic-gate 				    Zalloc(sizeof (md_drive_record));
52417c478bd9Sstevel@tonic-gate 			}
52427c478bd9Sstevel@tonic-gate 			dr_placeholder->dr_next = dr->dr_next;
52437c478bd9Sstevel@tonic-gate 			dr_placeholder->dr_key = dr->dr_key;
52447c478bd9Sstevel@tonic-gate 			sr_del_drv(sr, dr->dr_selfid);
52457c478bd9Sstevel@tonic-gate 			(void) del_sideno_sidenm(dr_placeholder->dr_key,
52467c478bd9Sstevel@tonic-gate 			    sideno, ep);
52477c478bd9Sstevel@tonic-gate 			change = 1;
52487c478bd9Sstevel@tonic-gate 			dr = dr_placeholder;
52497c478bd9Sstevel@tonic-gate 		}
52507c478bd9Sstevel@tonic-gate 	}
52517c478bd9Sstevel@tonic-gate out:
52527c478bd9Sstevel@tonic-gate 	/* If incore records are correct, don't need to write to disk */
52537c478bd9Sstevel@tonic-gate 	if (change) {
52547c478bd9Sstevel@tonic-gate 		/* Don't increment the genid in commitset */
52557c478bd9Sstevel@tonic-gate 		commitset(sr, FALSE, ep);
52567c478bd9Sstevel@tonic-gate 	}
52577c478bd9Sstevel@tonic-gate 	free_sr(sr);
52587c478bd9Sstevel@tonic-gate 
52597c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
52607c478bd9Sstevel@tonic-gate 
52617c478bd9Sstevel@tonic-gate 	if (dr_placeholder != NULL)
52627c478bd9Sstevel@tonic-gate 		Free(dr_placeholder);
52637c478bd9Sstevel@tonic-gate 
52647c478bd9Sstevel@tonic-gate 	return (TRUE);
52657c478bd9Sstevel@tonic-gate }
52667c478bd9Sstevel@tonic-gate 
52677c478bd9Sstevel@tonic-gate /*
52687c478bd9Sstevel@tonic-gate  * Version 2 routine to update this node's drive records based on
52697c478bd9Sstevel@tonic-gate  * list passed in from master node.
52707c478bd9Sstevel@tonic-gate  */
52717c478bd9Sstevel@tonic-gate bool_t
mdrpc_upd_dr_reconfig_2_svc(mdrpc_upd_dr_flags_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)52727c478bd9Sstevel@tonic-gate mdrpc_upd_dr_reconfig_2_svc(
52737c478bd9Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args	*args,
52747c478bd9Sstevel@tonic-gate 	mdrpc_generic_res		*res,
52757c478bd9Sstevel@tonic-gate 	struct svc_req			*rqstp		/* RPC stuff */
52767c478bd9Sstevel@tonic-gate )
52777c478bd9Sstevel@tonic-gate {
52782a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
52797c478bd9Sstevel@tonic-gate 	switch (args->rev) {
52807c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
52817c478bd9Sstevel@tonic-gate 		return (mdrpc_upd_dr_reconfig_common(
52827c478bd9Sstevel@tonic-gate 		    &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp));
52837c478bd9Sstevel@tonic-gate 	default:
52847c478bd9Sstevel@tonic-gate 		return (FALSE);
52857c478bd9Sstevel@tonic-gate 	}
52867c478bd9Sstevel@tonic-gate }
52877c478bd9Sstevel@tonic-gate 
52887c478bd9Sstevel@tonic-gate /*
52897c478bd9Sstevel@tonic-gate  * reset mirror owner for mirrors owned by deleted
52907c478bd9Sstevel@tonic-gate  * or withdrawn host(s).  Hosts being deleted or
52917c478bd9Sstevel@tonic-gate  * withdrawn are designated by nodeid since host is
52927c478bd9Sstevel@tonic-gate  * already deleted or withdrawn from set and may not
52937c478bd9Sstevel@tonic-gate  * be able to translate between a nodename and a nodeid.
52947c478bd9Sstevel@tonic-gate  * If an error occurs, ep will be set to that error information.
52957c478bd9Sstevel@tonic-gate  */
52967c478bd9Sstevel@tonic-gate static void
reset_mirror_owner(char * setname,int node_c,int * node_id,md_error_t * ep)52977c478bd9Sstevel@tonic-gate reset_mirror_owner(
52987c478bd9Sstevel@tonic-gate 	char		*setname,
52997c478bd9Sstevel@tonic-gate 	int		node_c,
53007c478bd9Sstevel@tonic-gate 	int		*node_id,	/* Array of node ids */
53017c478bd9Sstevel@tonic-gate 	md_error_t	*ep
53027c478bd9Sstevel@tonic-gate )
53037c478bd9Sstevel@tonic-gate {
53047c478bd9Sstevel@tonic-gate 	mdsetname_t		*local_sp;
53057c478bd9Sstevel@tonic-gate 	int			i;
53067c478bd9Sstevel@tonic-gate 	mdnamelist_t		*devnlp = NULL;
53077c478bd9Sstevel@tonic-gate 	mdnamelist_t		*p;
53087c478bd9Sstevel@tonic-gate 	mdname_t		*devnp = NULL;
53097c478bd9Sstevel@tonic-gate 	md_set_mmown_params_t	ownpar_p;
53107c478bd9Sstevel@tonic-gate 	md_set_mmown_params_t	*ownpar = &ownpar_p;
53117c478bd9Sstevel@tonic-gate 	char			*miscname;
53127c478bd9Sstevel@tonic-gate 
53137c478bd9Sstevel@tonic-gate 	if ((local_sp = metasetname(setname, ep)) == NULL)
53147c478bd9Sstevel@tonic-gate 		return;
53157c478bd9Sstevel@tonic-gate 
53167c478bd9Sstevel@tonic-gate 	/* get a list of all the mirrors for current set */
53177c478bd9Sstevel@tonic-gate 	if (meta_get_mirror_names(local_sp, &devnlp, 0, ep) < 0)
53187c478bd9Sstevel@tonic-gate 		return;
53197c478bd9Sstevel@tonic-gate 
53207c478bd9Sstevel@tonic-gate 	/* for each mirror */
53217c478bd9Sstevel@tonic-gate 	for (p = devnlp; (p != NULL); p = p->next) {
53227c478bd9Sstevel@tonic-gate 		devnp = p->namep;
53237c478bd9Sstevel@tonic-gate 
53247c478bd9Sstevel@tonic-gate 		/*
53257c478bd9Sstevel@tonic-gate 		 * we can only do these for mirrors so make sure we
53267c478bd9Sstevel@tonic-gate 		 * really have a mirror device and not a softpartition
53277c478bd9Sstevel@tonic-gate 		 * imitating one. meta_get_mirror_names seems to think
53287c478bd9Sstevel@tonic-gate 		 * softparts on top of a mirror are mirrors!
53297c478bd9Sstevel@tonic-gate 		 */
53307c478bd9Sstevel@tonic-gate 		if ((miscname = metagetmiscname(devnp, ep)) == NULL)
53317c478bd9Sstevel@tonic-gate 			goto out;
53327c478bd9Sstevel@tonic-gate 		if (strcmp(miscname, MD_MIRROR) != 0)
53337c478bd9Sstevel@tonic-gate 			continue;
53347c478bd9Sstevel@tonic-gate 
53357c478bd9Sstevel@tonic-gate 		(void) memset(ownpar, 0, sizeof (*ownpar));
53367c478bd9Sstevel@tonic-gate 		ownpar->d.mnum = meta_getminor(devnp->dev);
53377c478bd9Sstevel@tonic-gate 		MD_SETDRIVERNAME(ownpar, MD_MIRROR, local_sp->setno);
53387c478bd9Sstevel@tonic-gate 
53397c478bd9Sstevel@tonic-gate 		/* get the current owner id */
53407c478bd9Sstevel@tonic-gate 		if (metaioctl(MD_MN_GET_MM_OWNER, ownpar, ep,
53417c478bd9Sstevel@tonic-gate 		    "MD_MN_GET_MM_OWNER") != 0) {
53427c478bd9Sstevel@tonic-gate 			mde_perror(ep, gettext(
5343d7cd8252Stw21770 			    "Unable to get mirror owner for %s/%s"),
53447c478bd9Sstevel@tonic-gate 			    local_sp->setname,
5345d7cd8252Stw21770 			    get_mdname(local_sp, ownpar->d.mnum));
53467c478bd9Sstevel@tonic-gate 			goto out;
53477c478bd9Sstevel@tonic-gate 		}
53487c478bd9Sstevel@tonic-gate 
53497c478bd9Sstevel@tonic-gate 		if (ownpar->d.owner == MD_MN_MIRROR_UNOWNED) {
53507c478bd9Sstevel@tonic-gate 			mdclrerror(ep);
53517c478bd9Sstevel@tonic-gate 			continue;
53527c478bd9Sstevel@tonic-gate 		}
53537c478bd9Sstevel@tonic-gate 		/*
53547c478bd9Sstevel@tonic-gate 		 * reset owner only if the current owner is
53557c478bd9Sstevel@tonic-gate 		 * in the list of nodes being deleted.
53567c478bd9Sstevel@tonic-gate 		 */
53577c478bd9Sstevel@tonic-gate 		for (i = 0; i < node_c; i++) {
53587c478bd9Sstevel@tonic-gate 			if (ownpar->d.owner == node_id[i]) {
53597c478bd9Sstevel@tonic-gate 				if (meta_mn_change_owner(&ownpar,
53607c478bd9Sstevel@tonic-gate 				    local_sp->setno, ownpar->d.mnum,
53617c478bd9Sstevel@tonic-gate 				    MD_MN_MIRROR_UNOWNED,
53627c478bd9Sstevel@tonic-gate 				    MD_MN_MM_ALLOW_CHANGE) == -1) {
53637c478bd9Sstevel@tonic-gate 					mde_perror(ep, gettext(
53647c478bd9Sstevel@tonic-gate 					    "Unable to reset mirror owner for"
5365d7cd8252Stw21770 					    " %s/%s"), local_sp->setname,
5366d7cd8252Stw21770 					    get_mdname(local_sp,
53677c478bd9Sstevel@tonic-gate 					    ownpar->d.mnum));
53687c478bd9Sstevel@tonic-gate 					goto out;
53697c478bd9Sstevel@tonic-gate 				}
53707c478bd9Sstevel@tonic-gate 				break;
53717c478bd9Sstevel@tonic-gate 			}
53727c478bd9Sstevel@tonic-gate 		}
53737c478bd9Sstevel@tonic-gate 	}
53747c478bd9Sstevel@tonic-gate 
53757c478bd9Sstevel@tonic-gate out:
53767c478bd9Sstevel@tonic-gate 	/* cleanup */
53777c478bd9Sstevel@tonic-gate 	metafreenamelist(devnlp);
53787c478bd9Sstevel@tonic-gate }
53797c478bd9Sstevel@tonic-gate 
53807c478bd9Sstevel@tonic-gate /*
53817c478bd9Sstevel@tonic-gate  * Wrapper routine for reset_mirror_owner.
53827c478bd9Sstevel@tonic-gate  * Called when hosts are deleted or withdrawn
53837c478bd9Sstevel@tonic-gate  * in order to reset any mirror owners that are needed.
53847c478bd9Sstevel@tonic-gate  */
53857c478bd9Sstevel@tonic-gate bool_t
mdrpc_reset_mirror_owner_common(mdrpc_nodeid_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)53867c478bd9Sstevel@tonic-gate mdrpc_reset_mirror_owner_common(
53877c478bd9Sstevel@tonic-gate 	mdrpc_nodeid_args	*args,
53887c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
53897c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
53907c478bd9Sstevel@tonic-gate )
53917c478bd9Sstevel@tonic-gate {
53927c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
53937c478bd9Sstevel@tonic-gate 	int			err;
53947c478bd9Sstevel@tonic-gate 	int			op_mode = W_OK;
53957c478bd9Sstevel@tonic-gate 
53967c478bd9Sstevel@tonic-gate 	/* setup, check permissions */
53977c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
53987c478bd9Sstevel@tonic-gate 		return (FALSE);
53997c478bd9Sstevel@tonic-gate 	else if (err != 0)
54007c478bd9Sstevel@tonic-gate 		return (TRUE);
54017c478bd9Sstevel@tonic-gate 
54027c478bd9Sstevel@tonic-gate 	if (check_set_lock(op_mode, args->cl_sk, ep))
54037c478bd9Sstevel@tonic-gate 		return (TRUE);
54047c478bd9Sstevel@tonic-gate 
54057c478bd9Sstevel@tonic-gate 	/* doit */
54067c478bd9Sstevel@tonic-gate 	reset_mirror_owner(args->sp->setname, args->nodeid.nodeid_len,
54077c478bd9Sstevel@tonic-gate 	    args->nodeid.nodeid_val, ep);
54087c478bd9Sstevel@tonic-gate 
54097c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
54107c478bd9Sstevel@tonic-gate 
54117c478bd9Sstevel@tonic-gate 	return (TRUE);
54127c478bd9Sstevel@tonic-gate }
54137c478bd9Sstevel@tonic-gate 
54147c478bd9Sstevel@tonic-gate /*
54157c478bd9Sstevel@tonic-gate  * RPC service routine to reset the mirror owner for mirrors owned
54167c478bd9Sstevel@tonic-gate  * by the given hosts.  Typically, the list of given hosts is a list
54177c478bd9Sstevel@tonic-gate  * of nodes being deleted or withdrawn from a diskset.
54187c478bd9Sstevel@tonic-gate  * The given hosts are designated by nodeid since host may
54197c478bd9Sstevel@tonic-gate  * already be deleted or withdrawn from set and may not
54207c478bd9Sstevel@tonic-gate  * be able to translate between a nodename and a nodeid.
54217c478bd9Sstevel@tonic-gate  */
54227c478bd9Sstevel@tonic-gate bool_t
mdrpc_reset_mirror_owner_2_svc(mdrpc_nodeid_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)54237c478bd9Sstevel@tonic-gate mdrpc_reset_mirror_owner_2_svc(
54247c478bd9Sstevel@tonic-gate 	mdrpc_nodeid_2_args	*args,
54257c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
54267c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
54277c478bd9Sstevel@tonic-gate )
54287c478bd9Sstevel@tonic-gate {
54292a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
54307c478bd9Sstevel@tonic-gate 	switch (args->rev) {
54317c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
54327c478bd9Sstevel@tonic-gate 		return (mdrpc_reset_mirror_owner_common(
54337c478bd9Sstevel@tonic-gate 		    &args->mdrpc_nodeid_2_args_u.rev1, res,
54347c478bd9Sstevel@tonic-gate 		    rqstp));
54357c478bd9Sstevel@tonic-gate 	default:
54367c478bd9Sstevel@tonic-gate 		return (FALSE);
54377c478bd9Sstevel@tonic-gate 	}
54387c478bd9Sstevel@tonic-gate }
54397c478bd9Sstevel@tonic-gate 
54407c478bd9Sstevel@tonic-gate /*
54417c478bd9Sstevel@tonic-gate  * Call routines to suspend and resume I/O for the given diskset(s).
54427c478bd9Sstevel@tonic-gate  * Called during reconfig cycle.
54437c478bd9Sstevel@tonic-gate  * Diskset of 0 represents all MN disksets.
54447c478bd9Sstevel@tonic-gate  */
54457c478bd9Sstevel@tonic-gate bool_t
mdrpc_mn_susp_res_io_2_svc(mdrpc_mn_susp_res_io_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)54467c478bd9Sstevel@tonic-gate mdrpc_mn_susp_res_io_2_svc(
54477c478bd9Sstevel@tonic-gate 	mdrpc_mn_susp_res_io_2_args	*args,
54487c478bd9Sstevel@tonic-gate 	mdrpc_generic_res		*res,
54497c478bd9Sstevel@tonic-gate 	struct svc_req			*rqstp		/* RPC stuff */
54507c478bd9Sstevel@tonic-gate )
54517c478bd9Sstevel@tonic-gate {
54527c478bd9Sstevel@tonic-gate 	mdrpc_mn_susp_res_io_args	*args_sr;
54537c478bd9Sstevel@tonic-gate 	md_error_t			*ep = &res->status;
54547c478bd9Sstevel@tonic-gate 	int				err;
54557c478bd9Sstevel@tonic-gate 	int				op_mode = R_OK;
54567c478bd9Sstevel@tonic-gate 
54572a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
54587c478bd9Sstevel@tonic-gate 	switch (args->rev) {
54597c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
54607c478bd9Sstevel@tonic-gate 		/* setup, check permissions */
54617c478bd9Sstevel@tonic-gate 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
54627c478bd9Sstevel@tonic-gate 			return (FALSE);
54637c478bd9Sstevel@tonic-gate 		else if (err != 0)
54647c478bd9Sstevel@tonic-gate 			return (TRUE);
54657c478bd9Sstevel@tonic-gate 
54667c478bd9Sstevel@tonic-gate 		args_sr = &(args->mdrpc_mn_susp_res_io_2_args_u.rev1);
54677c478bd9Sstevel@tonic-gate 		switch (args_sr->susp_res_cmd) {
54687c478bd9Sstevel@tonic-gate 		case MN_SUSP_IO:
54697c478bd9Sstevel@tonic-gate 			(void) (metaioctl(MD_MN_SUSPEND_SET,
54707c478bd9Sstevel@tonic-gate 			    &args_sr->susp_res_setno, ep, NULL));
54717c478bd9Sstevel@tonic-gate 			break;
54727c478bd9Sstevel@tonic-gate 		case MN_RES_IO:
54737c478bd9Sstevel@tonic-gate 			(void) (metaioctl(MD_MN_RESUME_SET,
54747c478bd9Sstevel@tonic-gate 			    &args_sr->susp_res_setno, ep, NULL));
54757c478bd9Sstevel@tonic-gate 			break;
54767c478bd9Sstevel@tonic-gate 		}
54777c478bd9Sstevel@tonic-gate 		err = svc_fini(ep);
54787c478bd9Sstevel@tonic-gate 		return (TRUE);
54797c478bd9Sstevel@tonic-gate 
54807c478bd9Sstevel@tonic-gate 	default:
54817c478bd9Sstevel@tonic-gate 		return (FALSE);
54827c478bd9Sstevel@tonic-gate 	}
54837c478bd9Sstevel@tonic-gate }
54847c478bd9Sstevel@tonic-gate 
54857c478bd9Sstevel@tonic-gate /*
54867c478bd9Sstevel@tonic-gate  * Resnarf a set after it has been imported
54877c478bd9Sstevel@tonic-gate  */
54887c478bd9Sstevel@tonic-gate bool_t
mdrpc_resnarf_set_2_svc(mdrpc_setno_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)54897c478bd9Sstevel@tonic-gate mdrpc_resnarf_set_2_svc(
54907c478bd9Sstevel@tonic-gate 	mdrpc_setno_2_args	*args,
54917c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
54927c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
54937c478bd9Sstevel@tonic-gate )
54947c478bd9Sstevel@tonic-gate {
54957c478bd9Sstevel@tonic-gate 	mdrpc_setno_args	*setno_args;
54967c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
54977c478bd9Sstevel@tonic-gate 	int			err;
54987c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
54997c478bd9Sstevel@tonic-gate 
55002a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
55017c478bd9Sstevel@tonic-gate 	switch (args->rev) {
55027c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
55037c478bd9Sstevel@tonic-gate 		setno_args = &args->mdrpc_setno_2_args_u.rev1;
55047c478bd9Sstevel@tonic-gate 		break;
55057c478bd9Sstevel@tonic-gate 	default:
55067c478bd9Sstevel@tonic-gate 		return (FALSE);
55077c478bd9Sstevel@tonic-gate 	}
55087c478bd9Sstevel@tonic-gate 
55097c478bd9Sstevel@tonic-gate 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
55107c478bd9Sstevel@tonic-gate 		return (FALSE);
55117c478bd9Sstevel@tonic-gate 	else if (err != 0)
55127c478bd9Sstevel@tonic-gate 		return (TRUE);
55137c478bd9Sstevel@tonic-gate 
55147c478bd9Sstevel@tonic-gate 	/* do it */
55157c478bd9Sstevel@tonic-gate 	if (resnarf_set(setno_args->setno, ep) < 0)
55167c478bd9Sstevel@tonic-gate 		return (FALSE);
55177c478bd9Sstevel@tonic-gate 
55187c478bd9Sstevel@tonic-gate 	err = svc_fini(ep);
55197c478bd9Sstevel@tonic-gate 	return (TRUE);
55207c478bd9Sstevel@tonic-gate }
55217c478bd9Sstevel@tonic-gate 
55227c478bd9Sstevel@tonic-gate /*
55237c478bd9Sstevel@tonic-gate  * Creates a resync thread.
55247c478bd9Sstevel@tonic-gate  * Always returns true.
55257c478bd9Sstevel@tonic-gate  */
55267c478bd9Sstevel@tonic-gate bool_t
mdrpc_mn_mirror_resync_all_2_svc(mdrpc_setno_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)55277c478bd9Sstevel@tonic-gate mdrpc_mn_mirror_resync_all_2_svc(
55287c478bd9Sstevel@tonic-gate 	mdrpc_setno_2_args	*args,
55297c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
55307c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
55317c478bd9Sstevel@tonic-gate )
55327c478bd9Sstevel@tonic-gate {
55337c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
55347c478bd9Sstevel@tonic-gate 	mdrpc_setno_args	*setno_args;
55357c478bd9Sstevel@tonic-gate 	int			err;
55367c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
55377c478bd9Sstevel@tonic-gate 
55382a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
55397c478bd9Sstevel@tonic-gate 	switch (args->rev) {
55407c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
55417c478bd9Sstevel@tonic-gate 		/* setup, check permissions */
55427c478bd9Sstevel@tonic-gate 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
55437c478bd9Sstevel@tonic-gate 			return (FALSE);
55447c478bd9Sstevel@tonic-gate 		else if (err != 0)
55457c478bd9Sstevel@tonic-gate 			return (TRUE);
55467c478bd9Sstevel@tonic-gate 		setno_args = &args->mdrpc_setno_2_args_u.rev1;
55477c478bd9Sstevel@tonic-gate 
55487c478bd9Sstevel@tonic-gate 		/*
55497c478bd9Sstevel@tonic-gate 		 * Need to invoke a metasync on a node newly added to a set.
55507c478bd9Sstevel@tonic-gate 		 */
5551*80148899SSurya Prakki 		(void) meta_mn_mirror_resync_all(&(setno_args->setno));
55527c478bd9Sstevel@tonic-gate 
55537c478bd9Sstevel@tonic-gate 		err = svc_fini(ep);
55547c478bd9Sstevel@tonic-gate 		return (TRUE);
55557c478bd9Sstevel@tonic-gate 
55567c478bd9Sstevel@tonic-gate 	default:
55577c478bd9Sstevel@tonic-gate 		return (FALSE);
55587c478bd9Sstevel@tonic-gate 	}
55597c478bd9Sstevel@tonic-gate }
55607c478bd9Sstevel@tonic-gate 
55617c478bd9Sstevel@tonic-gate /*
55627c478bd9Sstevel@tonic-gate  * Updates ABR state for all softpartitions. Calls meta_mn_sp_update_abr(),
55637c478bd9Sstevel@tonic-gate  * which forks a daemon process to perform this action.
55647c478bd9Sstevel@tonic-gate  * Always returns true.
55657c478bd9Sstevel@tonic-gate  */
55667c478bd9Sstevel@tonic-gate bool_t
mdrpc_mn_sp_update_abr_2_svc(mdrpc_setno_2_args * args,mdrpc_generic_res * res,struct svc_req * rqstp)55677c478bd9Sstevel@tonic-gate mdrpc_mn_sp_update_abr_2_svc(
55687c478bd9Sstevel@tonic-gate 	mdrpc_setno_2_args	*args,
55697c478bd9Sstevel@tonic-gate 	mdrpc_generic_res	*res,
55707c478bd9Sstevel@tonic-gate 	struct svc_req		*rqstp		/* RPC stuff */
55717c478bd9Sstevel@tonic-gate )
55727c478bd9Sstevel@tonic-gate {
55737c478bd9Sstevel@tonic-gate 	md_error_t		*ep = &res->status;
55747c478bd9Sstevel@tonic-gate 	mdrpc_setno_args	*setno_args;
55757c478bd9Sstevel@tonic-gate 	int			err;
55767c478bd9Sstevel@tonic-gate 	int			op_mode = R_OK;
55777c478bd9Sstevel@tonic-gate 
55782a1e69baSabalfour 	(void) memset(res, 0, sizeof (*res));
55797c478bd9Sstevel@tonic-gate 	switch (args->rev) {
55807c478bd9Sstevel@tonic-gate 	case MD_METAD_ARGS_REV_1:
55817c478bd9Sstevel@tonic-gate 		/* setup, check permissions */
55827c478bd9Sstevel@tonic-gate 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
55837c478bd9Sstevel@tonic-gate 			return (FALSE);
55847c478bd9Sstevel@tonic-gate 		else if (err != 0)
55857c478bd9Sstevel@tonic-gate 			return (TRUE);
55867c478bd9Sstevel@tonic-gate 		setno_args = &args->mdrpc_setno_2_args_u.rev1;
55877c478bd9Sstevel@tonic-gate 
5588*80148899SSurya Prakki 		(void) meta_mn_sp_update_abr(&(setno_args->setno));
55897c478bd9Sstevel@tonic-gate 
55907c478bd9Sstevel@tonic-gate 		err = svc_fini(ep);
55917c478bd9Sstevel@tonic-gate 		return (TRUE);
55927c478bd9Sstevel@tonic-gate 
55937c478bd9Sstevel@tonic-gate 	default:
55947c478bd9Sstevel@tonic-gate 		return (FALSE);
55957c478bd9Sstevel@tonic-gate 	}
55967c478bd9Sstevel@tonic-gate }
5597