xref: /titanic_41/usr/src/cmd/lvm/rpc.metad/metad_svc_subr.c (revision c5024742c2f7d10880eae26cc592353b20a58f4a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include "metad_local.h"
29 #include <metad.h>
30 #include <sys/lvm/md_mddb.h>
31 #include <sdssc.h>
32 #include <sys/lvm/md_mirror.h>
33 #include <syslog.h>
34 
35 #include <sys/sysevent/eventdefs.h>
36 #include <sys/sysevent/svm.h>
37 #include <thread.h>
38 
39 #define	MDDOORS		"/usr/lib/lvm/mddoors"
40 
41 /*
42  * rpc.metad daemon
43  *
44  * The rpc.metad deamon supports two versions of the svm rpc calls - version 1
45  * and version 2. The over-the-wire structures sent as part of these rpc calls
46  * are also versioned - version 1 and version 2 exist. It must be noted that
47  * the version 2 structures have sub-versions or revisions as well. The
48  * revisions in the version 2 structures allow for flexiblility in changing
49  * over the wire structures without creating a new version of the svm rpc
50  * calls. No changes may be made to the version 1 routines or structures used
51  * by these routines.
52  *
53  * If, for example, the version 2 mdrpc_devinfo_args over the wire structure
54  * (mdrpc_devinfo_2_args*) is changed then the structure change must be
55  * accompanied by the following:
56  *
57  * Header file changes:
58  * . May need to introduce a new structure revision MD_METAD_ARGS_REV_X, where
59  *   X is the revision number.
60  * . Create mdrpc_devinfo_2_args_rX, where X is the new revision of the
61  *   structure.
62  * . Add a switch statement in mdrpc_devinfo_2_args.
63  *
64  * rpc.metad changes:
65  * . Check for the structure revision in the appropriate mdrpc_devinfo_svc
66  *   routine (mdrpc_devinfo_2_svc).
67  *
68  * libmeta changes:
69  * . In the libmeta code that makes the mdrpc_devinfo rpc call, the arguments
70  *   being passed as part of this call (namely mdrpc_devinfo_Y_args) must have
71  *   the revision field and associated structure populated correctly.
72  */
73 
74 static	md_setkey_t	*my_svc_sk = NULL;
75 
76 /*
77  * Add namespace entry to local mddb for using given sideno, key
78  * and names.
79  */
80 static int
81 add_sideno_sidenm(
82 	mdsidenames_t	*sidenms,
83 	mdkey_t		local_key,
84 	side_t		sideno,
85 	md_set_desc	*sd,		/* Only used with Version 2 */
86 	md_error_t	*ep
87 )
88 {
89 	mdsidenames_t	*sn;
90 	mdsetname_t	*local_sp;
91 	char		*nm;
92 
93 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
94 		return (-1);
95 
96 	for (sn = sidenms; sn != NULL; sn = sn->next)
97 		if (sn->sideno == sideno)
98 			break;
99 
100 	assert(sn != NULL);
101 
102 
103 	/*
104 	 * SKEW will be used on the traditional diskset despite of the
105 	 * rpc version.  SKEW is not used on the multinode diskset
106 	 */
107 	if (MD_MNSET_DESC(sd)) {
108 		nm = meta_getnmbykey(MD_LOCAL_SET, sideno, local_key, ep);
109 	} else {
110 		nm = meta_getnmbykey(MD_LOCAL_SET, sideno+SKEW, local_key, ep);
111 	}
112 
113 	if (nm == NULL) {
114 		if (! mdisok(ep)) {
115 			if (! mdissyserror(ep, ENOENT))
116 				return (-1);
117 			mdclrerror(ep);
118 		}
119 
120 		/*
121 		 * Ignore returned key from add_name, only care about errs
122 		 *
123 		 * SKEW is used for a regular diskset since sideno could
124 		 * have a value of 0 in that diskset type.  add_name is
125 		 * writing to the local mddb and a sideno of 0 in the
126 		 * local mddb is reserved for non-diskset names.
127 		 * SKEW is added to the sideno in the local mddb so that
128 		 * the sideno for the diskset will never be 0.
129 		 *
130 		 * In a MNdiskset, the sideno will never be 0 (by design).
131 		 * So, no SKEW is needed when writing to the local mddb.
132 		 */
133 		if (MD_MNSET_DESC(sd)) {
134 			if (add_name(local_sp, sideno, local_key,
135 			    sn->dname, sn->mnum, sn->cname, ep) == -1)
136 				return (-1);
137 		} else {
138 			if (add_name(local_sp, sideno+SKEW, local_key,
139 			    sn->dname, sn->mnum, sn->cname, ep) == -1)
140 				return (-1);
141 		}
142 	} else
143 		Free(nm);
144 
145 	return (0);
146 }
147 
148 /*
149  * Delete sidename entry from local set using key and sideno.
150  */
151 static int
152 del_sideno_sidenm(
153 	mdkey_t		sidekey,
154 	side_t		sideno,
155 	md_error_t	*ep
156 )
157 {
158 	mdsetname_t	*local_sp;
159 
160 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
161 		return (-1);
162 
163 	if (del_name(local_sp, sideno, sidekey, ep) == -1)
164 		mdclrerror(ep); /* ignore errs */
165 
166 	return (0);
167 }
168 
169 
170 /*
171  * Add namespace entries to local mddb for drives in drive list in
172  * set descriptor.
173  *
174  * If a MNset and if this host is being added to the set (this host
175  * is in the node_v list), add a namespace entry for the name of
176  * each drive using this host's sideno.
177  *
178  * If not a MNset, add namespace entries for all the new hosts being
179  * added to this set (list in node_v).
180  */
181 static void
182 add_drv_sidenms(
183 	char		*hostname,
184 	mdsetname_t	*sp,
185 	md_set_desc	*sd,
186 	int		node_c,
187 	char		**node_v,
188 	md_error_t	*ep
189 )
190 {
191 	mdsetname_t	*my_sp;
192 	md_drive_desc	*dd, *my_dd, *p, *q;
193 	mddrivename_t	*dn, *my_dn;
194 	int		i;
195 	side_t		sideno = 0, mysideno = 0;
196 	ddi_devid_t	devid_remote = NULL;
197 	ddi_devid_t	devid_local = NULL;
198 	int		devid_same = -1;
199 	int		using_devid = 0;
200 	md_mnnode_desc	*nd;
201 
202 	assert(sd->sd_drvs != NULL);
203 	dd = sd->sd_drvs;
204 
205 	if (dd->dd_dnp == NULL)
206 		return;
207 
208 	if ((my_sp = metasetname(sp->setname, ep)) == NULL)
209 		return;
210 	metaflushsetname(my_sp);
211 
212 	/* If a MN diskset */
213 	if (MD_MNSET_DESC(sd)) {
214 		/* Find sideno associated with RPC client. */
215 		nd = sd->sd_nodelist;
216 		while (nd) {
217 
218 			if (strcmp(nd->nd_nodename, hostname) == 0) {
219 				sideno = nd->nd_nodeid;
220 			}
221 
222 			/* While looping, find my side num as well */
223 			if (strcmp(nd->nd_nodename, mynode()) == 0) {
224 				mysideno = nd->nd_nodeid;
225 			}
226 
227 			if ((sideno) && (mysideno)) {
228 				break;
229 			}
230 			nd = nd->nd_next;
231 		}
232 
233 		if (!sideno) {
234 			(void) mddserror(ep, MDE_DS_HOSTNOSIDE,
235 			    sp->setno, hostname, NULL, sp->setname);
236 			return;
237 		}
238 	} else {
239 		/*
240 		 * if not a MN diskset
241 		 * do action for traditional diskset.
242 		 * despite of the rpc version
243 		 */
244 		for (sideno = 0; sideno < MD_MAXSIDES; sideno++) {
245 			/* Skip empty slots */
246 			if (sd->sd_nodes[sideno][0] == '\0')
247 				continue;
248 
249 			if (strcmp(hostname, sd->sd_nodes[sideno]) == 0)
250 				break;
251 		}
252 
253 		if (sideno == MD_MAXSIDES) {
254 			(void) mddserror(ep, MDE_DS_HOSTNOSIDE, sp->setno,
255 			    hostname, NULL, sp->setname);
256 			return;
257 		}
258 	}
259 	if ((my_dd = metaget_drivedesc_sideno(my_sp, sideno, MD_BASICNAME_OK,
260 	    ep)) == NULL) {
261 		if (! mdisok(ep))
262 			return;
263 		/* we are supposed to have drives!!!! */
264 		assert(0);
265 	}
266 
267 	/*
268 	 * The system is either all devid or all
269 	 * non-devid so we look at the first item
270 	 * in the list to determine if we're using devids or not.
271 	 * We also check to make sure it's not a multi-node diskset.
272 	 * If it is, we don't use devid's.
273 	 *
274 	 * For did disks, the dd_dnp->devid is a valid pointer which
275 	 * points to a '' string of devid.  We need to check this
276 	 * before set the using_devid.
277 	 */
278 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
279 	    (!(MD_MNSET_DESC(sd))))
280 		using_devid = 1;
281 
282 	/*
283 	 * We have to match-up the dd that were passed
284 	 * across the wire to the dd we have in this daemon.
285 	 * That way we can pick up the new sidenames that were
286 	 * passed to us and match them up with the local namespace key.
287 	 * Only we have the key, this cannot be passed in.
288 	 */
289 	for (p = dd; p != NULL; p = p->dd_next) {
290 		dn = p->dd_dnp;
291 		devid_remote = NULL;
292 
293 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
294 		    using_devid) {
295 			/*
296 			 * We have a devid so use it
297 			 */
298 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
299 		}
300 
301 		/* check to make sure using_devid agrees with reality... */
302 		if ((using_devid == 1) && (devid_remote == NULL)) {
303 			/* something went really wrong. Can't process */
304 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
305 			    hostname, dn->cname, sp->setname);
306 			return;
307 		}
308 
309 		for (q = my_dd; q != NULL; q = q->dd_next) {
310 			my_dn = q->dd_dnp;
311 			devid_same = -1;
312 
313 			if (my_dn->devid != NULL && using_devid) {
314 				if (devid_str_decode(my_dn->devid,
315 				    &devid_local, NULL) == 0) {
316 					devid_same = devid_compare(devid_remote,
317 					    devid_local);
318 					devid_free(devid_local);
319 				}
320 			}
321 
322 			if (using_devid && devid_same == 0) {
323 				break;
324 			}
325 
326 			if (!using_devid &&
327 			    strcmp(my_dn->cname, dn->cname) == 0)
328 				break;
329 		}
330 
331 		if (devid_remote) {
332 			devid_free(devid_remote);
333 		}
334 		assert(q != NULL);
335 		assert(my_dn->side_names_key != MD_KEYWILD);
336 
337 		if (MD_MNSET_DESC(sd)) {
338 			/*
339 			 * Add the side names to the local db
340 			 * for this node only.
341 			 */
342 			if (add_sideno_sidenm(dn->side_names,
343 			    my_dn->side_names_key, mysideno, sd, ep))
344 				return;
345 			/*
346 			 * Sidenames for this drive were added
347 			 * to this host during the routine adddrvs.
348 			 * The sidenames that were added are the
349 			 * names associated with this drive on
350 			 * each of the hosts that were previously
351 			 * in the set.
352 			 * When the sidename for this drive on
353 			 * this host is added, the sidename
354 			 * from the host executing the command
355 			 * (not this host) is sent to this host.
356 			 * This host finds the originating host's
357 			 * sidename and can then determine this
358 			 * host's sidename.
359 			 * The sidenames from the other hosts serve
360 			 * only as temporary sidenames until this
361 			 * host's sidename can be added.
362 			 * In order to conserve space in the
363 			 * local mddb, the code now deletes the
364 			 * temporary sidenames added during adddrvs.
365 			 * When finished, only the sidename for this
366 			 * node should be left.
367 			 * Ignore any errors during this process since
368 			 * a failure to delete the extraneous
369 			 * sidenames shouldn't cause this routine
370 			 * to fail (in case that sidename didn't exist).
371 			 */
372 			nd = sd->sd_nodelist;
373 			while (nd) {
374 				if (nd->nd_nodeid != mysideno) {
375 					if (del_sideno_sidenm(
376 					    dn->side_names_key,
377 					    nd->nd_nodeid, ep) == -1)
378 						mdclrerror(ep);
379 				}
380 				nd = nd->nd_next;
381 			}
382 		} else {
383 			for (i = 0; i < MD_MAXSIDES; i++) {
384 				/* Skip empty slots */
385 				if (sd->sd_nodes[i][0] == '\0')
386 					continue;
387 
388 				/* Skip nodes not being added */
389 				if (! strinlst(sd->sd_nodes[i],
390 					node_c, node_v))
391 					continue;
392 
393 				/* Add the per side names to local db */
394 				if (add_sideno_sidenm(dn->side_names,
395 				    my_dn->side_names_key, i, sd, ep))
396 					return;
397 			}
398 		}
399 	}
400 }
401 
402 /* ARGSUSED */
403 bool_t
404 mdrpc_flush_internal_common(mdrpc_null_args *args, mdrpc_generic_res *res,
405     struct svc_req *rqstp)
406 {
407 	md_error_t	*ep = &res->status;
408 	int		err,
409 			op_mode = W_OK;
410 
411 	memset(res, 0, sizeof (*res));
412 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
413 		return (FALSE);
414 	else if (err != 0)
415 		return (TRUE);
416 
417 	metaflushnames(1);
418 
419 	err = svc_fini(ep);
420 
421 	return (TRUE);
422 }
423 
424 bool_t
425 mdrpc_flush_internal_1_svc(mdrpc_null_args *args, mdrpc_generic_res *res,
426     struct svc_req *rqstp)
427 {
428 	return (mdrpc_flush_internal_common(args, res, rqstp));
429 }
430 
431 bool_t
432 mdrpc_flush_internal_2_svc(mdrpc_null_args *args, mdrpc_generic_res *res,
433     struct svc_req *rqstp)
434 {
435 	return (mdrpc_flush_internal_common(args, res, rqstp));
436 }
437 
438 /*
439  * add 1 or more namespace entries per drive record.
440  * (into the local namespace)
441  */
442 bool_t
443 mdrpc_add_drv_sidenms_common(
444 	mdrpc_drv_sidenm_2_args_r1	*args,
445 	mdrpc_generic_res		*res,
446 	struct svc_req			*rqstp		/* RPC stuff */
447 )
448 {
449 	md_error_t		*ep = &res->status;
450 	int			err;
451 	int			op_mode = W_OK;
452 
453 	/* setup, check permissions */
454 	(void) memset(res, 0, sizeof (*res));
455 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
456 		return (FALSE);
457 	else if (err != 0)
458 		return (TRUE);
459 
460 	if (check_set_lock(op_mode, args->cl_sk, ep))
461 		return (TRUE);
462 
463 	/* doit */
464 	add_drv_sidenms(args->hostname, args->sp, args->sd,
465 	    args->node_v.node_v_len, args->node_v.node_v_val, ep);
466 
467 	err = svc_fini(ep);
468 
469 	return (TRUE);
470 }
471 
472 /*
473  * version 1 of the remote procedure. This procedure is called if the
474  * client is running in version 1. We first convert version 1 arguments
475  * into version 2 arguments and then call the common remote procedure.
476  */
477 bool_t
478 mdrpc_add_drv_sidenms_1_svc(
479 	mdrpc_drv_sidenm_args	*args,
480 	mdrpc_generic_res	*res,
481 	struct svc_req		*rqstp		/* RPC stuff */
482 )
483 {
484 	bool_t				retval;
485 	mdrpc_drv_sidenm_2_args_r1	v2_args;
486 	int				i, j;
487 
488 	/* allocate memory */
489 	v2_args.sd = Zalloc(sizeof (md_set_desc));
490 	alloc_newdrvdesc(args->sd->sd_drvs, &v2_args.sd->sd_drvs);
491 
492 	/* build args */
493 	v2_args.hostname = args->hostname;
494 	v2_args.cl_sk = args->cl_sk;
495 	v2_args.sp = args->sp;
496 	/* set descriptor */
497 	v2_args.sd->sd_ctime = args->sd->sd_ctime;
498 	v2_args.sd->sd_genid = args->sd->sd_genid;
499 	v2_args.sd->sd_setno = args->sd->sd_setno;
500 	v2_args.sd->sd_flags = args->sd->sd_flags;
501 	for (i = 0; i < MD_MAXSIDES; i++) {
502 		v2_args.sd->sd_isown[i] = args->sd->sd_isown[i];
503 
504 		for (j = 0; j < MD_MAX_NODENAME_PLUS_1; j++)
505 			v2_args.sd->sd_nodes[i][j] =
506 			    args->sd->sd_nodes[i][j];
507 	}
508 	v2_args.sd->sd_med = args->sd->sd_med;
509 	/* convert v1 args to v2 (revision 1) args */
510 	meta_conv_drvdesc_old2new(args->sd->sd_drvs, v2_args.sd->sd_drvs);
511 	v2_args.node_v.node_v_len = args->node_v.node_v_len;
512 	v2_args.node_v.node_v_val = args->node_v.node_v_val;
513 
514 	retval = mdrpc_add_drv_sidenms_common(&v2_args, res, rqstp);
515 
516 	free(v2_args.sd);
517 	free_newdrvdesc(v2_args.sd->sd_drvs);
518 
519 	return (retval);
520 }
521 
522 bool_t
523 mdrpc_add_drv_sidenms_2_svc(
524 	mdrpc_drv_sidenm_2_args	*args,
525 	mdrpc_generic_res	*res,
526 	struct svc_req		*rqstp		/* RPC stuff */
527 )
528 {
529 	switch (args->rev) {
530 	    case MD_METAD_ARGS_REV_1:
531 		return (mdrpc_add_drv_sidenms_common(
532 		    &args->mdrpc_drv_sidenm_2_args_u.rev1, res, rqstp));
533 	    default:
534 		return (FALSE);
535 	}
536 }
537 
538 static int
539 add_sidenamelist(
540 	mddrivename_t	*dn,
541 	side_t		thisside,
542 	md_set_record	*sr, 		/* used by RPC version 2 */
543 	md_error_t	*ep
544 )
545 {
546 	mdsidenames_t	*sn;
547 	mdkey_t		key;
548 	int		err;
549 	mdsetname_t	*local_sp;
550 	md_mnset_record	*mnsr;
551 	md_mnnode_record *nr;
552 	uint_t		nodeid = 0;
553 
554 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
555 		return (-1);
556 
557 	key = MD_KEYWILD;
558 
559 	/*
560 	 * If a multi-node diskset, find nodeid associated with this node.
561 	 */
562 	if (MD_MNSET_REC(sr)) {
563 		mnsr = (struct md_mnset_record *)sr;
564 		nr = mnsr->sr_nodechain;
565 		while (nr) {
566 			if (strcmp(nr->nr_nodename, mynode()) == 0) {
567 				break;
568 			}
569 			nr = nr->nr_next;
570 		}
571 		/*
572 		 * If node is found, then a new drive is being added to
573 		 * a MN set of which this node is a member.
574 		 * If node is not found, then this host is being added to
575 		 * a MN set that has drives associated with it.
576 		 */
577 		if (nr)
578 			nodeid = nr->nr_nodeid;
579 	}
580 	for (sn = dn->side_names; sn != NULL; sn = sn->next) {
581 		if (MD_MNSET_REC(sr)) {
582 			/*
583 			 * In multi-node disksets, only add side information
584 			 * to the local mddb about this node.
585 			 * If the sideno for this node is found, then
586 			 * a new drive is being added to a MN set of
587 			 * which this node is a member.
588 			 * If the sideno for this node is not found, then
589 			 * this host is being added to a MNset that
590 			 * has drives associated with it.  In this case,
591 			 * need to add the sidename associated with the
592 			 * rpc client, but since we don't know which node
593 			 * is the client, then add temp entries for all sides.
594 			 * Later, the sidename for this node will be set
595 			 * via add_drv_sidenms and then the temp
596 			 * sidenames can be removed.
597 			 */
598 			if (nodeid == sn->sideno) {
599 				if ((err = add_name(local_sp, sn->sideno, key,
600 				    sn->dname, sn->mnum, sn->cname, ep)) == -1)
601 					return (-1);
602 				key = (mdkey_t)err;
603 				break;
604 			}
605 		} else {
606 			/*
607 			 * When a sidename is added into the namespace the local
608 			 * side information for the name is added first of all.
609 			 * When the first sidename is created this causes the
610 			 * devid of the disk to be recorded in the namespace, if
611 			 * the non-local side information is added first then
612 			 * there is the possibility of getting the wrong devid
613 			 * because there is no guarantee that the dev_t (mnum in
614 			 * this instance) is the same across all the nodes in
615 			 * the set. So the only way to make sure that the
616 			 * correct dev_t is used is to force the adding in of
617 			 * the local sidename record first of all. This same
618 			 * issue affects add_key_name().
619 			 */
620 			if (sn->sideno != thisside)
621 				continue;
622 			if ((err = add_name(local_sp, sn->sideno+SKEW, key,
623 			    sn->dname, sn->mnum, sn->cname, ep)) == -1)
624 				return (-1);
625 			key = (mdkey_t)err;
626 			break;
627 		}
628 	}
629 
630 	/*
631 	 * Now the other sides for non-MN set
632 	 */
633 	if (!MD_MNSET_REC(sr)) {
634 		for (sn = dn->side_names; sn != NULL; sn = sn->next) {
635 			if (sn->sideno == thisside)
636 				continue;
637 			if ((err = add_name(local_sp, sn->sideno+SKEW, key,
638 				sn->dname, sn->mnum, sn->cname, ep)) == -1)
639 				return (-1);
640 			key = (mdkey_t)err;
641 		}
642 	}
643 
644 	/* Temporarily add all sides. */
645 	if ((key == MD_KEYWILD) && (MD_MNSET_REC(sr))) {
646 		for (sn = dn->side_names; sn != NULL; sn = sn->next) {
647 			sn = dn->side_names;
648 			if (sn) {
649 				if ((err = add_name(local_sp, sn->sideno, key,
650 				    sn->dname, sn->mnum, sn->cname, ep)) == -1)
651 						return (-1);
652 				key = (mdkey_t)err;
653 			}
654 		}
655 	}
656 
657 	dn->side_names_key = key;
658 	return (0);
659 }
660 
661 static void
662 adddrvs(
663 	char 		*setname,
664 	md_drive_desc	*dd,
665 	md_timeval32_t	timestamp,
666 	ulong_t		genid,
667 	md_error_t	*ep
668 )
669 {
670 	mddb_userreq_t	req;
671 	md_drive_record	*dr;
672 	md_set_record	*sr;
673 	md_drive_desc	*p;
674 	mddrivename_t	*dn;
675 	mdname_t	*np;
676 	md_dev64_t	dev;
677 	md_error_t	xep = mdnullerror;
678 	int		i;
679 
680 	if ((sr = getsetbyname(setname, ep)) == NULL)
681 		return;
682 
683 	if (MD_MNSET_REC(sr))
684 		i = 0;
685 	else {
686 		/* get thisside */
687 		for (i = 0; i < MD_MAXSIDES; i++) {
688 			if (sr->sr_nodes[i][0] == '\0')
689 				continue;
690 			if (strcmp(mynode(), sr->sr_nodes[i]) == 0)
691 				break;
692 		}
693 
694 		if (i == MD_MAXSIDES) {
695 			/* so find the first free slot! */
696 			for (i = 0; i < MD_MAXSIDES; i++) {
697 				if (sr->sr_nodes[i][0] == '\0')
698 					break;
699 			}
700 		}
701 	}
702 
703 	for (p = dd; p != NULL; p = p->dd_next) {
704 		uint_t	rep_slice;
705 
706 		dn = p->dd_dnp;
707 
708 		/* Add the per side names to the local db */
709 		if (add_sidenamelist(dn, (side_t)i,  sr, ep)) {
710 				free_sr(sr);
711 				return;
712 		}
713 
714 		/* Create the drive record */
715 		(void) memset(&req, 0, sizeof (req));
716 		METAD_SETUP_DR(MD_DB_CREATE, 0);
717 		req.ur_size = sizeof (*dr);
718 		if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
719 			(void) mdstealerror(ep, &req.ur_mde);
720 			free_sr(sr);
721 			return;
722 		}
723 
724 		/* Fill in the drive record values */
725 		dr = Zalloc(sizeof (*dr));
726 		dr->dr_selfid = req.ur_recid;
727 		dr->dr_dbcnt = p->dd_dbcnt;
728 		dr->dr_dbsize = p->dd_dbsize;
729 		dr->dr_key = dn->side_names_key;
730 
731 		dr->dr_ctime = timestamp;
732 		dr->dr_genid = genid;
733 		dr->dr_revision = MD_DRIVE_RECORD_REVISION;
734 		dr->dr_flags = MD_DR_ADD;
735 
736 		/* Link the drive records and fill in in-core data */
737 		dr_cache_add(sr, dr);
738 
739 		dev = NODEV64;
740 		if ((meta_replicaslice(dn, &rep_slice, &xep) == 0) &&
741 		    ((np = metaslicename(dn, rep_slice, &xep)) != NULL))
742 			dev = np->dev;
743 		else
744 			mdclrerror(&xep);
745 
746 		SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
747 		    MD_LOCAL_SET, dev);
748 		SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
749 		    sr->sr_setno, dev);
750 	}
751 
752 	/* Commit all the records atomically */
753 	commitset(sr, TRUE, ep);
754 	free_sr(sr);
755 }
756 
757 /*
758  * add 1 or more drive records to a set.
759  */
760 bool_t
761 mdrpc_adddrvs_common(
762 	mdrpc_drives_2_args_r1	*args,
763 	mdrpc_generic_res	*res,
764 	struct svc_req		*rqstp		/* RPC stuff */
765 )
766 {
767 	md_error_t		*ep = &res->status;
768 	int			err;
769 	int			op_mode = W_OK;
770 
771 	/* setup, check permissions */
772 	(void) memset(res, 0, sizeof (*res));
773 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
774 		return (FALSE);
775 	else if (err != 0)
776 		return (TRUE);
777 
778 	if (check_set_lock(op_mode, args->cl_sk, ep))
779 		return (TRUE);
780 
781 	/* doit */
782 	adddrvs(args->sp->setname, args->drivedescs, args->timestamp,
783 	    args->genid, ep);
784 
785 	err = svc_fini(ep);
786 
787 	return (TRUE);
788 }
789 
790 /*
791  * version 1 of the remote procedure. This procedure is called if the
792  * client is running in version 1. We first convert version 1 arguments
793  * into version 2 arguments and then call the common remote procedure.
794  */
795 bool_t
796 mdrpc_adddrvs_1_svc(
797 	mdrpc_drives_args	*args,
798 	mdrpc_generic_res	*res,
799 	struct svc_req		*rqstp		/* RPC stuff */
800 )
801 {
802 	bool_t			retval;
803 	mdrpc_drives_2_args_r1	v2_args;
804 
805 	/* allocate memory */
806 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
807 
808 	/* build args */
809 	v2_args.cl_sk = args->cl_sk;
810 	v2_args.sp = args->sp;
811 	/* convert v1 args to v2 (revision 1) args */
812 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
813 	v2_args.timestamp = args->timestamp;
814 	v2_args.genid = args->genid;
815 
816 	retval = mdrpc_adddrvs_common(&v2_args, res, rqstp);
817 
818 	free_newdrvdesc(v2_args.drivedescs);
819 
820 	return (retval);
821 }
822 
823 bool_t
824 mdrpc_adddrvs_2_svc(
825 	mdrpc_drives_2_args	*args,
826 	mdrpc_generic_res	*res,
827 	struct svc_req		*rqstp		/* RPC stuff */
828 )
829 {
830 	switch (args->rev) {
831 	    case MD_METAD_ARGS_REV_1:
832 		return (mdrpc_adddrvs_common(
833 		    &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
834 	    default:
835 		return (FALSE);
836 	}
837 }
838 
839 static void
840 addhosts(
841 	char		*setname,
842 	int		node_c,
843 	char		**node_v,
844 	int		version,	/* RPC version of calling routine */
845 	md_error_t	*ep
846 )
847 {
848 	mddb_userreq_t		req;
849 	md_set_record		*sr;
850 	int			i, j;
851 	md_mnset_record		*mnsr;
852 	md_mnnode_record	*nr;
853 	mddb_set_node_params_t	snp;
854 	int			nodecnt;
855 	mndiskset_membershiplist_t *nl, *nl2;
856 
857 	if ((sr = getsetbyname(setname, ep)) == NULL)
858 		return;
859 
860 	/* Do MN operation if rpc version supports it and if a MN set */
861 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
862 		mnsr = (md_mnset_record *)sr;
863 		/*
864 		 * Verify nodes are in membership list on THIS node.
865 		 * Initiating node has verified that nodes are in membership
866 		 * list on the initiating node.
867 		 * Get membershiplist from API routine.  If there's
868 		 * an error, fail to add hosts and pass back error.
869 		 */
870 		if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) {
871 			free_sr(sr);
872 			return;
873 		}
874 		/* Verify that all nodes are in member list */
875 		for (i = 0; i < node_c; i++) {
876 			/*
877 			 * If node in list isn't a member of the membership,
878 			 * just return error.
879 			 */
880 			if (meta_is_member(node_v[i], NULL, nl) == 0) {
881 				meta_free_nodelist(nl);
882 				(void) mddserror(ep, MDE_DS_NOTINMEMBERLIST,
883 				    sr->sr_setno, node_v[i], NULL, setname);
884 				free_sr(sr);
885 				return;
886 			}
887 		}
888 	}
889 
890 	for (i = 0; i < node_c; i++) {
891 		/* Do MN operation if rpc version supports it and if a MN set */
892 		if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
893 			mnsr = (md_mnset_record *)sr;
894 			/* Create the node record */
895 			(void) memset(&req, 0, sizeof (req));
896 			METAD_SETUP_NR(MD_DB_CREATE, 0);
897 			req.ur_size = sizeof (*nr);
898 			if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL)
899 			    != 0) {
900 				(void) mdstealerror(ep, &req.ur_mde);
901 				meta_free_nodelist(nl);
902 				free_sr(sr);
903 				return;
904 			}
905 
906 			nr = Zalloc(sizeof (*nr));
907 			nr->nr_revision = MD_MNNODE_RECORD_REVISION;
908 			nr->nr_selfid = req.ur_recid;
909 			nr->nr_ctime = sr->sr_ctime;
910 			nr->nr_genid = sr->sr_genid;
911 			nr->nr_flags = MD_MN_NODE_ADD;
912 			nl2 = nl;
913 			while (nl2) {
914 				if (strcmp(nl2->msl_node_name, node_v[i])
915 				    == 0) {
916 					nr->nr_nodeid = nl2->msl_node_id;
917 					break;
918 				}
919 				nl2 = nl2->next;
920 			}
921 
922 			(void) strcpy(nr->nr_nodename, node_v[i]);
923 
924 			/*
925 			 * When a node is added to a MN diskset, set the
926 			 * nodeid of this node in the md_set structure
927 			 * in the kernel.
928 			 */
929 			if (strcmp(nr->nr_nodename, mynode()) == 0) {
930 				(void) memset(&snp, 0, sizeof (snp));
931 				snp.sn_nodeid = nr->nr_nodeid;
932 				snp.sn_setno = mnsr->sr_setno;
933 				if (metaioctl(MD_MN_SET_NODEID, &snp,
934 				    &snp.sn_mde, NULL) != 0) {
935 					(void) mdstealerror(ep, &snp.sn_mde);
936 					meta_free_nodelist(nl);
937 					free_sr(sr);
938 					return;
939 				}
940 			}
941 
942 			/* Link the node records and fill in in-core data */
943 			mnnr_cache_add(mnsr, nr);
944 
945 			SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST,
946 				mnsr->sr_setno, nr->nr_nodeid);
947 		} else {
948 			for (j = 0; j < MD_MAXSIDES; j++) {
949 				if (sr->sr_nodes[j][0] != '\0')
950 					continue;
951 				(void) strcpy(sr->sr_nodes[j], node_v[i]);
952 				SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD,
953 				    SVM_TAG_HOST, sr->sr_setno, j);
954 				break;
955 			}
956 		}
957 	}
958 	/* Do MN operation if rpc version supports it and if a MN set */
959 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
960 		meta_free_nodelist(nl);
961 	}
962 
963 	(void) memset(&req, '\0', sizeof (req));
964 
965 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
966 
967 	/* Do MN operation if rpc version supports it and if a MN set */
968 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
969 		req.ur_size = sizeof (*mnsr);
970 	} else {
971 		req.ur_size = sizeof (*sr);
972 	}
973 	req.ur_data = (uintptr_t)sr;
974 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
975 		(void) mdstealerror(ep, &req.ur_mde);
976 		free_sr(sr);
977 		return;
978 	}
979 
980 	commitset(sr, TRUE, ep);
981 
982 	free_sr(sr);
983 }
984 
985 /*
986  * add 1 or more hosts to a set.
987  */
988 bool_t
989 mdrpc_addhosts_common(
990 	mdrpc_host_args		*args,
991 	mdrpc_generic_res	*res,
992 	struct svc_req		*rqstp,		/* RPC stuff */
993 	int			version		/* RPC version */
994 )
995 {
996 	md_error_t		*ep = &res->status;
997 	int			err;
998 	int			op_mode = W_OK;
999 
1000 	/* setup, check permissions */
1001 	(void) memset(res, 0, sizeof (*res));
1002 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
1003 		return (FALSE);
1004 	else if (err != 0)
1005 		return (TRUE);
1006 
1007 	if (check_set_lock(op_mode, args->cl_sk, ep))
1008 		return (TRUE);
1009 
1010 	/* doit */
1011 	addhosts(args->sp->setname, args->hosts.hosts_len,
1012 	    args->hosts.hosts_val, version, ep);
1013 
1014 	err = svc_fini(ep);
1015 
1016 	return (TRUE);
1017 }
1018 
1019 bool_t
1020 mdrpc_addhosts_1_svc(
1021 	mdrpc_host_args		*args,
1022 	mdrpc_generic_res	*res,
1023 	struct svc_req		*rqstp		/* RPC stuff */
1024 )
1025 {
1026 	/* Pass RPC version (METAD_VERSION) to common routine */
1027 	return (mdrpc_addhosts_common(args, res, rqstp, METAD_VERSION));
1028 }
1029 
1030 bool_t
1031 mdrpc_addhosts_2_svc(
1032 	mdrpc_host_2_args	*args,
1033 	mdrpc_generic_res	*res,
1034 	struct svc_req		*rqstp		/* RPC stuff */
1035 )
1036 {
1037 	switch (args->rev) {
1038 	    case MD_METAD_ARGS_REV_1:
1039 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
1040 		return (mdrpc_addhosts_common(
1041 		    &args->mdrpc_host_2_args_u.rev1, res,
1042 		    rqstp, METAD_VERSION_DEVID));
1043 	    default:
1044 		return (FALSE);
1045 	}
1046 }
1047 
1048 static void
1049 createset(
1050 	mdsetname_t		*sp,
1051 	md_node_nm_arr_t	nodes,
1052 	md_timeval32_t		timestamp,
1053 	ulong_t			genid,
1054 	md_error_t		*ep
1055 )
1056 {
1057 	mddb_userreq_t		req;
1058 	md_set_record		*sr;
1059 	int			i;
1060 
1061 	(void) memset(&req, 0, sizeof (req));
1062 	METAD_SETUP_SR(MD_DB_CREATE, 0);
1063 	req.ur_size = sizeof (*sr);
1064 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
1065 		(void) mdstealerror(ep, &req.ur_mde);
1066 		return;
1067 	}
1068 
1069 	sr = Zalloc(sizeof (*sr));
1070 
1071 	sr->sr_selfid = req.ur_recid;
1072 	sr->sr_setno = sp->setno;
1073 	(void) strcpy(sr->sr_setname, sp->setname);
1074 
1075 	SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno,
1076 	    NODEV64);
1077 
1078 	(void) meta_smf_enable(META_SMF_DISKSET, NULL);
1079 
1080 	for (i = 0; i < MD_MAXSIDES; i++) {
1081 		(void) strcpy(sr->sr_nodes[i], nodes[i]);
1082 		/* Skip empty slots */
1083 		if (sr->sr_nodes[i][0] == '\0')
1084 			continue;
1085 		SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno,
1086 		    i);
1087 	}
1088 
1089 	sr->sr_ctime = timestamp;
1090 	sr->sr_genid = genid;
1091 	sr->sr_revision = MD_SET_RECORD_REVISION;
1092 	sr->sr_flags |= MD_SR_ADD;
1093 
1094 	sr->sr_mhiargs = defmhiargs;
1095 
1096 	sr_cache_add(sr);
1097 
1098 	commitset(sr, TRUE, ep);
1099 }
1100 
1101 static void
1102 mncreateset(
1103 	mdsetname_t		*sp,
1104 	md_mnnode_desc		*nodelist,
1105 	md_timeval32_t		timestamp,
1106 	ulong_t			genid,
1107 	md_node_nm_t		master_nodenm,
1108 	int			master_nodeid,
1109 	md_error_t		*ep
1110 )
1111 {
1112 	mddb_userreq_t			req;
1113 	md_mnset_record			*mnsr;
1114 	md_mnnode_record		*nr;
1115 	md_mnnode_desc			*nd;
1116 	mddb_set_node_params_t		snp;
1117 	int				nodecnt;
1118 	mndiskset_membershiplist_t	*nl;
1119 
1120 	/*
1121 	 * Validate that nodes in set being created are in the
1122 	 * membership list on THIS node.
1123 	 * Initiating node has verified that nodes are in membership
1124 	 * list on the initiating node.
1125 	 * Get membershiplist from API routine.  If there's
1126 	 * an error, fail to add set and pass back error.
1127 	 */
1128 	if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) {
1129 		return;
1130 	}
1131 	/* Verify that all nodes are in member list */
1132 	nd = nodelist;
1133 	while (nd) {
1134 		/*
1135 		 * If node in list isn't a member of the membership,
1136 		 * just return error.
1137 		 */
1138 		if (meta_is_member(nd->nd_nodename, 0, nl) == 0) {
1139 			meta_free_nodelist(nl);
1140 			(void) mddserror(ep, MDE_DS_NOTINMEMBERLIST,
1141 			    sp->setno, nd->nd_nodename, NULL, sp->setname);
1142 			return;
1143 		}
1144 		nd = nd->nd_next;
1145 	}
1146 	meta_free_nodelist(nl);
1147 
1148 	(void) memset(&req, 0, sizeof (req));
1149 	METAD_SETUP_SR(MD_DB_CREATE, 0);
1150 	req.ur_size = sizeof (*mnsr);
1151 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
1152 		(void) mdstealerror(ep, &req.ur_mde);
1153 		return;
1154 	}
1155 
1156 	mnsr = Zalloc(sizeof (*mnsr));
1157 	mnsr->sr_selfid = req.ur_recid;
1158 	mnsr->sr_setno = sp->setno;
1159 	(void) strlcpy(mnsr->sr_setname, sp->setname, MD_MAX_SETNAME);
1160 
1161 	SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_CREATE, SVM_TAG_SET, sp->setno,
1162 	    NODEV64);
1163 
1164 	(void) meta_smf_enable(META_SMF_DISKSET | META_SMF_MN_DISKSET, NULL);
1165 
1166 	nd = nodelist;
1167 	while (nd) {
1168 		/* Create the node record */
1169 		(void) memset(&req, 0, sizeof (req));
1170 		METAD_SETUP_NR(MD_DB_CREATE, 0);
1171 		req.ur_size = sizeof (*nr);
1172 		if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
1173 			/* Frees mnsr and any alloc'd node records */
1174 			free_sr((struct md_set_record *)mnsr);
1175 			(void) mdstealerror(ep, &req.ur_mde);
1176 			return;
1177 		}
1178 
1179 		nr = Zalloc(sizeof (*nr));
1180 		nr->nr_revision = MD_MNNODE_RECORD_REVISION;
1181 		nr->nr_selfid = req.ur_recid;
1182 		nr->nr_ctime = timestamp;
1183 		nr->nr_genid = genid;
1184 		nr->nr_nodeid = nd->nd_nodeid;
1185 		nr->nr_flags = nd->nd_flags;
1186 		(void) strlcpy(nr->nr_nodename, nd->nd_nodename,
1187 			MD_MAX_NODENAME);
1188 
1189 		/* Link the node records and fill in in-core data */
1190 		mnnr_cache_add(mnsr, nr);
1191 
1192 		SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_HOST, sp->setno,
1193 		    nr->nr_nodeid);
1194 
1195 		nd = nd->nd_next;
1196 	}
1197 
1198 	/*
1199 	 * For backward compatibility, fill in mynode name
1200 	 * as the only name in the sr_nodes array.  This
1201 	 * allows the pre-MNdiskset code to see that there
1202 	 * is a node in this diskset.  This will keep the
1203 	 * pre-MNdiskset code from removing this set.
1204 	 */
1205 	(void) strlcpy(mnsr->sr_nodes_bw_compat[0], mynode(), MD_MAX_NODENAME);
1206 
1207 	mnsr->sr_ctime = timestamp;
1208 	mnsr->sr_genid = genid;
1209 	mnsr->sr_revision = MD_SET_RECORD_REVISION;
1210 	mnsr->sr_flags |= MD_SR_ADD;
1211 
1212 	mnsr->sr_flags |= MD_SR_MN;
1213 	strcpy(mnsr->sr_master_nodenm, master_nodenm);
1214 	mnsr->sr_master_nodeid = master_nodeid;
1215 
1216 	mnsr->sr_mhiargs = defmhiargs;
1217 
1218 	sr_cache_add((struct md_set_record *)mnsr);
1219 
1220 	commitset((struct md_set_record *)mnsr, TRUE, ep);
1221 
1222 	/*
1223 	 * When a set is created for the first time, the nodelist
1224 	 * will contain this node.
1225 	 * When a node is just being added to a set, the nodelist
1226 	 * will not contain this node.  This node is added to the
1227 	 * set structure with a later call to addhosts.
1228 	 *
1229 	 * So, if the nodelist contains an entry for this node
1230 	 * then set the nodeid of this node in the md_set kernel
1231 	 * data structure.
1232 	 */
1233 	nd = nodelist;
1234 	while (nd) {
1235 		if (strcmp(nd->nd_nodename, mynode()) == 0) {
1236 			break;
1237 		}
1238 		nd = nd->nd_next;
1239 	}
1240 	if (nd) {
1241 		(void) memset(&snp, 0, sizeof (snp));
1242 		snp.sn_nodeid = nd->nd_nodeid;
1243 		snp.sn_setno = sp->setno;
1244 		if (metaioctl(MD_MN_SET_NODEID, &snp, &snp.sn_mde, NULL) != 0) {
1245 			(void) mdstealerror(ep, &snp.sn_mde);
1246 			return;
1247 		}
1248 	}
1249 }
1250 
1251 /*
1252  * create a set on a host
1253  */
1254 bool_t
1255 mdrpc_createset_common(
1256 	mdrpc_createset_args	*args,
1257 	mdrpc_generic_res	*res,
1258 	struct svc_req		*rqstp		/* RPC stuff */
1259 )
1260 {
1261 	md_error_t		*ep = &res->status;
1262 	char			stringbuf1[MAXPATHLEN];
1263 	char			stringbuf2[MAXPATHLEN];
1264 	int			err;
1265 	int			op_mode = W_OK;
1266 
1267 	/* setup, check permissions */
1268 	(void) memset(res, 0, sizeof (*res));
1269 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
1270 		return (FALSE);
1271 	else if (err != 0)
1272 		return (TRUE);
1273 
1274 	if (check_set_lock(op_mode, args->cl_sk, ep))
1275 		return (TRUE);
1276 
1277 	/* create the arguments for the symlink() and unlink() calls */
1278 	(void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s",
1279 	    args->sp->setname);
1280 	(void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d",
1281 	    args->sp->setno);
1282 
1283 	/*
1284 	 * Since we already verified that the setname was OK, make sure to
1285 	 * cleanup before proceeding.
1286 	 */
1287 	if (unlink(stringbuf2) == -1) {
1288 		if (errno != ENOENT) {
1289 			(void) mdsyserror(ep, errno, stringbuf2);
1290 			return (TRUE);
1291 		}
1292 	}
1293 
1294 	/* create the set */
1295 	createset(args->sp, args->nodes, args->timestamp, args->genid, ep);
1296 
1297 	if (! mdisok(ep))
1298 		return (TRUE);
1299 
1300 	/* create the symlink */
1301 	if (symlink(stringbuf1, stringbuf2) == -1)
1302 		(void) mdsyserror(ep, errno, stringbuf2);
1303 
1304 	err = svc_fini(ep);
1305 
1306 	return (TRUE);
1307 }
1308 
1309 bool_t
1310 mdrpc_createset_1_svc(
1311 	mdrpc_createset_args	*args,
1312 	mdrpc_generic_res	*res,
1313 	struct svc_req		*rqstp		/* RPC stuff */
1314 )
1315 {
1316 	return (mdrpc_createset_common(args, res, rqstp));
1317 }
1318 
1319 bool_t
1320 mdrpc_createset_2_svc(
1321 	mdrpc_createset_2_args	*args,
1322 	mdrpc_generic_res	*res,
1323 	struct svc_req		*rqstp		/* RPC stuff */
1324 )
1325 {
1326 	switch (args->rev) {
1327 	    case MD_METAD_ARGS_REV_1:
1328 		return (mdrpc_createset_common(
1329 		    &args->mdrpc_createset_2_args_u.rev1, res, rqstp));
1330 	    default:
1331 		return (FALSE);
1332 	}
1333 }
1334 
1335 bool_t
1336 mdrpc_mncreateset_common(
1337 	mdrpc_mncreateset_args	*args,
1338 	mdrpc_generic_res	*res,
1339 	struct svc_req		*rqstp		/* RPC stuff */
1340 )
1341 {
1342 	md_error_t		*ep = &res->status;
1343 	char			stringbuf1[MAXPATHLEN];
1344 	char			stringbuf2[MAXPATHLEN];
1345 	int			err;
1346 	int			op_mode = W_OK;
1347 
1348 	/* setup, check permissions */
1349 	(void) memset(res, 0, sizeof (*res));
1350 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
1351 		return (FALSE);
1352 	else if (err != 0)
1353 		return (TRUE);
1354 
1355 	if (check_set_lock(op_mode, args->cl_sk, ep))
1356 		return (TRUE);
1357 
1358 	/* create the arguments for the symlink() and unlink() calls */
1359 	(void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s",
1360 	    args->sp->setname);
1361 	(void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d",
1362 	    args->sp->setno);
1363 
1364 	/*
1365 	 * Since we already verified that the setname was OK, make sure to
1366 	 * cleanup before proceeding.
1367 	 */
1368 	if (unlink(stringbuf2) == -1) {
1369 		if (errno != ENOENT) {
1370 			(void) mdsyserror(ep, errno, stringbuf2);
1371 			return (TRUE);
1372 		}
1373 	}
1374 
1375 	/* create the set */
1376 	mncreateset(args->sp, args->nodelist, args->timestamp, args->genid,
1377 		    args->master_nodenm, args->master_nodeid, ep);
1378 
1379 	if (! mdisok(ep)) {
1380 		return (TRUE);
1381 	}
1382 
1383 	/* create the symlink */
1384 	if (symlink(stringbuf1, stringbuf2) == -1)
1385 		(void) mdsyserror(ep, errno, stringbuf2);
1386 
1387 	err = svc_fini(ep);
1388 
1389 	return (TRUE);
1390 }
1391 
1392 bool_t
1393 mdrpc_mncreateset_2_svc(
1394 	mdrpc_mncreateset_2_args	*args,
1395 	mdrpc_generic_res	*res,
1396 	struct svc_req		*rqstp		/* RPC stuff */
1397 )
1398 {
1399 	switch (args->rev) {
1400 	    case MD_METAD_ARGS_REV_1:
1401 		return (mdrpc_mncreateset_common(
1402 		    &args->mdrpc_mncreateset_2_args_u.rev1, res, rqstp));
1403 	    default:
1404 		return (FALSE);
1405 	}
1406 }
1407 
1408 static void
1409 del_drv_sidenms(
1410 	mdsetname_t	*sp,
1411 	int		version,	/* RPC version of calling routine */
1412 	md_error_t	*ep
1413 )
1414 {
1415 	md_set_record	*sr;
1416 	md_drive_desc	*dd, *p;
1417 	mddrivename_t	*dn;
1418 	mdsetname_t	*local_sp;
1419 	int		i;
1420 	int		rb_mode = 0;
1421 
1422 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
1423 		return;
1424 
1425 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
1426 		return;
1427 
1428 	/* Do MN operation if rpc version supports it and if a MN set */
1429 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
1430 		/*
1431 		 * In the multi-node diskset, there are no diskset
1432 		 * entries in the local set for other nodes, so there's
1433 		 * nothing to do.
1434 		 */
1435 		free_sr(sr);
1436 		return;
1437 	}
1438 
1439 	if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
1440 	    ep)) == NULL) {
1441 		if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE)) {
1442 			metaflushsetname(sp);
1443 			if (! mdisok(ep)) {
1444 				free_sr(sr);
1445 				return;
1446 			}
1447 			/* we are supposed to have drives!!!! */
1448 			assert(0);
1449 		}
1450 		rb_mode = 1;
1451 		mdclrerror(ep);
1452 		for (i = 0; i < MD_MAXSIDES; i++) {
1453 			/* Skip empty sides of the diskset */
1454 			if (sr->sr_nodes[i][0] == '\0')
1455 				continue;
1456 			dd = metaget_drivedesc_sideno(sp, i,
1457 			    (MD_BASICNAME_OK | PRINT_FAST), ep);
1458 			/* Got dd, get out of loop */
1459 			if (dd != NULL)
1460 				break;
1461 
1462 			/* some error occurred, get out of loop */
1463 			if (! mdisok(ep))
1464 				break;
1465 		}
1466 		/*
1467 		 * At this point, we have one of three possibilities:
1468 		 *	1) dd != NULL (we have found drives using an alternate
1469 		 *	   side.)
1470 		 *	2) dd == NULL (no drives) && mdisok(ep) : assert(0)
1471 		 *	3) dd == NULL (no drives) && ! mdisok(ep) : return
1472 		 *	   error information to caller.
1473 		 */
1474 		if (dd == NULL) {
1475 			metaflushsetname(sp);
1476 			if (! mdisok(ep)) {
1477 				free_sr(sr);
1478 				return;
1479 			}
1480 			/* we are supposed to have drives!!!! */
1481 			assert(0);
1482 		}
1483 	}
1484 
1485 	/*
1486 	 * Let's run through each drive descriptor, and delete the
1487 	 * sidename for all sides that are not in the sr_nodes array.
1488 	 * We will ignore errors, cause the empty side may not
1489 	 * have had any names to begin with.
1490 	 */
1491 	for (p = dd; p != NULL; p = p->dd_next) {
1492 		dn = p->dd_dnp;
1493 
1494 		for (i = 0; i < MD_MAXSIDES; i++) {
1495 			/* Skip existing sides of the diskset */
1496 			if (!rb_mode && sr->sr_nodes[i][0] != '\0')
1497 				continue;
1498 			/* An empty side, delete the sidename */
1499 			if (del_name(local_sp, i+SKEW,
1500 			    dn->side_names_key, ep)) {
1501 				if (!mdissyserror(ep, ENOENT)) {
1502 					free_sr(sr);
1503 					return;
1504 				}
1505 				mdclrerror(ep);
1506 			}
1507 		}
1508 	}
1509 	free_sr(sr);
1510 	metaflushsetname(sp);
1511 }
1512 
1513 /*
1514  * delete 1 or more sidenames per drive desc, from the local namespace
1515  */
1516 bool_t
1517 mdrpc_del_drv_sidenms_common(
1518 	mdrpc_sp_args		*args,
1519 	mdrpc_generic_res	*res,
1520 	struct svc_req		*rqstp,		/* RPC stuff */
1521 	int			version		/* RPC version */
1522 )
1523 {
1524 	md_error_t		*ep = &res->status;
1525 	int			err;
1526 	int			op_mode = W_OK;
1527 
1528 	/* setup, check permissions */
1529 	(void) memset(res, 0, sizeof (*res));
1530 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
1531 		return (FALSE);
1532 	else if (err != 0)
1533 		return (TRUE);
1534 
1535 	if (check_set_lock(op_mode, args->cl_sk, ep))
1536 		return (TRUE);
1537 
1538 	/* doit */
1539 	del_drv_sidenms(args->sp, version, ep);
1540 
1541 	err = svc_fini(ep);
1542 
1543 	return (TRUE);
1544 }
1545 
1546 bool_t
1547 mdrpc_del_drv_sidenms_1_svc(
1548 	mdrpc_sp_args		*args,
1549 	mdrpc_generic_res	*res,
1550 	struct svc_req		*rqstp		/* RPC stuff */
1551 )
1552 {
1553 	/* Pass RPC version (METAD_VERSION) to common routine */
1554 	return (mdrpc_del_drv_sidenms_common(args, res, rqstp, METAD_VERSION));
1555 }
1556 
1557 bool_t
1558 mdrpc_del_drv_sidenms_2_svc(
1559 	mdrpc_sp_2_args		*args,
1560 	mdrpc_generic_res	*res,
1561 	struct svc_req		*rqstp		/* RPC stuff */
1562 )
1563 {
1564 	switch (args->rev) {
1565 	    case MD_METAD_ARGS_REV_1:
1566 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
1567 		return (mdrpc_del_drv_sidenms_common(
1568 		    &args->mdrpc_sp_2_args_u.rev1, res,
1569 		    rqstp, METAD_VERSION_DEVID));
1570 	    default:
1571 		return (FALSE);
1572 	}
1573 }
1574 
1575 static int
1576 del_sidenamelist(
1577 	md_set_record	*sr,
1578 	mddrivename_t	*dn,
1579 	md_error_t	*ep
1580 )
1581 {
1582 	mdsidenames_t	*sn;
1583 	mdsetname_t	*local_sp;
1584 	md_mnset_record	*mnsr;
1585 	md_mnnode_record *nr;
1586 
1587 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
1588 		return (-1);
1589 
1590 	for (sn = dn->side_names; sn != NULL; sn = sn->next)
1591 		if (MD_MNSET_REC(sr)) {
1592 			mnsr = (struct md_mnset_record *)sr;
1593 			/*
1594 			 * Only delete side name entries for this node
1595 			 * on a multi-node diskset.
1596 			 */
1597 			nr = mnsr->sr_nodechain;
1598 			while (nr) {
1599 				if (nr->nr_nodeid == sn->sideno) {
1600 					if (del_name(local_sp, sn->sideno,
1601 					    dn->side_names_key, ep) == -1)
1602 						mdclrerror(ep); /* ignore err */
1603 					break;
1604 				}
1605 				nr = nr->nr_next;
1606 			}
1607 		} else {
1608 			if (del_name(local_sp, sn->sideno+SKEW,
1609 			    dn->side_names_key, ep) == -1)
1610 				mdclrerror(ep);	/* ignore errors */
1611 		}
1612 
1613 	dn->side_names_key = MD_KEYBAD;
1614 	return (0);
1615 }
1616 
1617 static void
1618 deldrvs(
1619 	char		*setname,
1620 	md_drive_desc	*dd,
1621 	md_error_t	*ep
1622 )
1623 {
1624 	mdsetname_t	*sp;
1625 	md_set_record	*sr;
1626 	md_drive_record	*dr;
1627 	mddb_userreq_t	req;
1628 	md_drive_desc	*p;
1629 	mddrivename_t	*dn, *dn1;
1630 	side_t		sideno;
1631 	int		i;
1632 	int		rb_mode = 0;
1633 	mdname_t	*np;
1634 	md_dev64_t	dev;
1635 	md_error_t	xep = mdnullerror;
1636 	ddi_devid_t	devid_remote = NULL;
1637 	ddi_devid_t	devid_local = NULL;
1638 	int		devid_same = -1;
1639 	int		using_devid = 0;
1640 	md_mnnode_record	*nr;
1641 	md_mnset_record		*mnsr;
1642 
1643 	if ((sp = metasetname(setname, ep)) == NULL)
1644 		return;
1645 
1646 	metaflushsetname(sp);
1647 
1648 	if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD) {
1649 		if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE))
1650 			return;
1651 		mdclrerror(ep);
1652 		/*
1653 		 * The set record is incomplete, so we need to make note
1654 		 * here so that we can do some special handling later.
1655 		 */
1656 		rb_mode = 1;
1657 	}
1658 
1659 	if ((sr = getsetbyname(setname, ep)) == NULL)
1660 		return;
1661 
1662 	if (dd->dd_dnp == NULL)
1663 		return;
1664 
1665 	/*
1666 	 * The system is either all devid or all
1667 	 * non-devid so we determine this by looking
1668 	 * at the first item in the list.
1669 	 *
1670 	 * For did disks, the dd_dnp->devid is a valid pointer which
1671 	 * points to a '' string of devid.  We need to check this
1672 	 * before set the using_devid.
1673 	 */
1674 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
1675 	    (!(MD_MNSET_REC(sr))))
1676 		using_devid = 1;
1677 
1678 	for (p = dd; p != NULL; p = p->dd_next) {
1679 		dn = p->dd_dnp;
1680 		devid_remote = NULL;
1681 
1682 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
1683 		    using_devid) {
1684 			/*
1685 			 * We have a devid so use it
1686 			 */
1687 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
1688 		}
1689 
1690 		/* check to make sure using_devid agrees with reality... */
1691 		if ((using_devid == 1) && (devid_remote == NULL)) {
1692 			/* something went really wrong. Can't process */
1693 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
1694 			    mynode(), dn->cname, sp->setname);
1695 			return;
1696 		}
1697 
1698 		for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
1699 			devid_same = -1;
1700 
1701 			if (! rb_mode) {
1702 				dn1 = metadrivename_withdrkey(sp, sideno,
1703 				    dr->dr_key, MD_BASICNAME_OK, ep);
1704 				if (dn1 == NULL) {
1705 					free_sr(sr);
1706 					if (devid_remote)
1707 						devid_free(devid_remote);
1708 					return;
1709 				}
1710 			} else {
1711 				/*
1712 				 * Handle special case here where sidenames
1713 				 * from other hosts for this drive may be
1714 				 * in the local mddb, but there is no
1715 				 * sidename entry for this host for this drive.
1716 				 * This could have happened if the node
1717 				 * panic'd between the 2 operations when
1718 				 * adding this node to the set.
1719 				 * So, delete all sidename entries for this
1720 				 * drive.
1721 				 */
1722 				if (MD_MNSET_REC(sr)) {
1723 					mnsr = (struct md_mnset_record *)sr;
1724 					nr = mnsr->sr_nodechain;
1725 					while (nr) {
1726 						/* We delete all dr sides */
1727 						dn1 = metadrivename_withdrkey(
1728 						    sp, nr->nr_nodeid,
1729 						    dr->dr_key,
1730 						    MD_BASICNAME_OK, ep);
1731 
1732 						/* if we do, get out of loop */
1733 						if (dn1 != NULL)
1734 							break;
1735 
1736 						/* save error for later */
1737 						(void) mdstealerror(&xep, ep);
1738 
1739 						mdclrerror(ep);
1740 
1741 						nr = nr->nr_next;
1742 					}
1743 				} else {
1744 					/*
1745 					 * Handle special case here
1746 					 * for traditional diskset
1747 					 */
1748 					for (i = 0; i < MD_MAXSIDES; i++) {
1749 						/* We delete all dr sides */
1750 						dn1 = metadrivename_withdrkey(
1751 						    sp, i, dr->dr_key,
1752 						    MD_BASICNAME_OK, ep);
1753 
1754 						/* if we do, get out of loop */
1755 						if (dn1 != NULL)
1756 							break;
1757 
1758 						/* save error for later */
1759 						(void) mdstealerror(&xep, ep);
1760 
1761 						mdclrerror(ep);
1762 					}
1763 				}
1764 
1765 				if (dn1 == NULL) {
1766 					(void) mdstealerror(ep, &xep);
1767 					free_sr(sr);
1768 					if (devid_remote)
1769 						devid_free(devid_remote);
1770 					return;
1771 				}
1772 
1773 				if (!using_devid)
1774 					mdclrerror(ep);
1775 			}
1776 
1777 			if (dn1->devid != NULL && using_devid) {
1778 				if (devid_str_decode(dn1->devid, &devid_local,
1779 				    NULL) == 0) {
1780 					devid_same = devid_compare(devid_remote,
1781 					    devid_local);
1782 					devid_free(devid_local);
1783 				}
1784 			}
1785 
1786 			/*
1787 			 * Has the required disk been found - either the devids
1788 			 * match if devid are being used or the actual name of
1789 			 * the disk matches.
1790 			 */
1791 			if ((using_devid && devid_same == 0) ||
1792 			    (!using_devid &&
1793 			    strcmp(dn->cname, dn1->cname) == 0)) {
1794 				uint_t	rep_slice;
1795 
1796 				dev = NODEV64;
1797 				np = NULL;
1798 				if (meta_replicaslice(dn1,
1799 				    &rep_slice, &xep) == 0) {
1800 					np = metaslicename(dn1,
1801 					    rep_slice, &xep);
1802 				}
1803 
1804 				if (np != NULL)
1805 					dev = np->dev;
1806 				else
1807 					mdclrerror(&xep);
1808 				break;
1809 			}
1810 		}
1811 
1812 		if (dr) {
1813 			(void) memset(&req, 0, sizeof (req));
1814 			METAD_SETUP_DR(MD_DB_DELETE, dr->dr_selfid)
1815 			if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL)
1816 			    != 0) {
1817 				(void) mdstealerror(ep, &req.ur_mde);
1818 				if (devid_remote)
1819 					devid_free(devid_remote);
1820 				free_sr(sr);
1821 				return;
1822 			}
1823 
1824 			dr_cache_del(sr, dr->dr_selfid);
1825 
1826 			if (del_sidenamelist(sr, dn1, ep) == -1) {
1827 				goto out;
1828 			}
1829 
1830 			SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
1831 			    sr->sr_setno, dev);
1832 			SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
1833 			    MD_LOCAL_SET, dev);
1834 
1835 			continue;
1836 		}
1837 
1838 		if (devid_remote)
1839 			devid_free(devid_remote);
1840 	}
1841 
1842 out:
1843 	commitset(sr, TRUE, ep);
1844 
1845 	free_sr(sr);
1846 }
1847 
1848 /*
1849  * delete 1 or more drive records from a host.
1850  */
1851 bool_t
1852 mdrpc_deldrvs_common(
1853 	mdrpc_drives_2_args_r1	*args,
1854 	mdrpc_generic_res	*res,
1855 	struct svc_req		*rqstp		/* RPC stuff */
1856 )
1857 {
1858 	md_error_t		*ep = &res->status;
1859 	int			err;
1860 	int			op_mode = W_OK;
1861 
1862 	/* setup, check permissions */
1863 	(void) memset(res, 0, sizeof (*res));
1864 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
1865 		return (FALSE);
1866 	else if (err != 0)
1867 		return (TRUE);
1868 
1869 	if (check_set_lock(op_mode, args->cl_sk, ep))
1870 		return (TRUE);
1871 
1872 	/* doit */
1873 	deldrvs(args->sp->setname, args->drivedescs, ep);
1874 
1875 	err = svc_fini(ep);
1876 
1877 	return (TRUE);
1878 }
1879 
1880 /*
1881  * version 1 of the remote procedure. This procedure is called if the
1882  * client is running in version 1. We first convert version 1 arguments
1883  * into version 2 arguments and then call the common remote procedure.
1884  */
1885 bool_t
1886 mdrpc_deldrvs_1_svc(
1887 	mdrpc_drives_args	*args,
1888 	mdrpc_generic_res	*res,
1889 	struct svc_req		*rqstp		/* RPC stuff */
1890 )
1891 {
1892 	bool_t			retval;
1893 	mdrpc_drives_2_args_r1	v2_args;
1894 
1895 	/* allocate memory */
1896 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
1897 
1898 	/* build args */
1899 	v2_args.cl_sk = args->cl_sk;
1900 	v2_args.sp = args->sp;
1901 	/* convert v1 args to v2 (revision 1) args */
1902 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
1903 	v2_args.timestamp = args->timestamp;
1904 	v2_args.genid = args->genid;
1905 
1906 	retval = mdrpc_deldrvs_common(&v2_args, res, rqstp);
1907 
1908 	free_newdrvdesc(v2_args.drivedescs);
1909 
1910 	return (retval);
1911 }
1912 
1913 bool_t
1914 mdrpc_deldrvs_2_svc(
1915 	mdrpc_drives_2_args	*args,
1916 	mdrpc_generic_res	*res,
1917 	struct svc_req		*rqstp		/* RPC stuff */
1918 )
1919 {
1920 	switch (args->rev) {
1921 	    case MD_METAD_ARGS_REV_1:
1922 		return (mdrpc_deldrvs_common(
1923 		    &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
1924 	    default:
1925 		return (FALSE);
1926 	}
1927 }
1928 
1929 static void
1930 delhosts(
1931 	char		*setname,
1932 	int		node_c,
1933 	char		**node_v,
1934 	int		version,	/* RPC version of calling routine */
1935 	md_error_t	*ep
1936 )
1937 {
1938 	mddb_userreq_t		req;
1939 	md_set_record		*sr;
1940 	int			i, j;
1941 	md_mnset_record		*mnsr;
1942 	md_mnnode_record	*nr;
1943 
1944 	if ((sr = getsetbyname(setname, ep)) == NULL)
1945 		return;
1946 
1947 	for (i = 0; i < node_c; i++) {
1948 		/* Do MN operation if rpc version supports it and if a MN set */
1949 		if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
1950 			mnsr = (struct md_mnset_record *)sr;
1951 			nr = mnsr->sr_nodechain;
1952 			while (nr) {
1953 				if (strcmp(nr->nr_nodename, node_v[i]) == 0) {
1954 					SE_NOTIFY(EC_SVM_CONFIG,
1955 						ESC_SVM_REMOVE, SVM_TAG_HOST,
1956 						sr->sr_setno, nr->nr_nodeid);
1957 					(void) memset(&req, '\0', sizeof (req));
1958 					METAD_SETUP_NR(MD_DB_DELETE,
1959 					    nr->nr_selfid);
1960 					if (metaioctl(MD_DB_USERREQ, &req,
1961 					    &req.ur_mde, NULL) != 0) {
1962 						(void) mdstealerror(ep,
1963 						    &req.ur_mde);
1964 						free_sr(sr);
1965 						return;
1966 					}
1967 					mnnr_cache_del(mnsr, nr->nr_selfid);
1968 					break;
1969 				}
1970 				nr = nr->nr_next;
1971 			}
1972 		} else {
1973 			for (j = 0; j < MD_MAXSIDES; j++) {
1974 				if (sr->sr_nodes[j][0] == '\0')
1975 					continue;
1976 				if (strcmp(sr->sr_nodes[j], node_v[i]) != 0)
1977 					continue;
1978 				(void) memset(sr->sr_nodes[j], '\0',
1979 				    sizeof (sr->sr_nodes[j]));
1980 				SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE,
1981 				    SVM_TAG_HOST, sr->sr_setno, j);
1982 				break;
1983 			}
1984 		}
1985 	}
1986 
1987 	(void) memset(&req, '\0', sizeof (req));
1988 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
1989 	/* Do MN operation if rpc version supports it and if a MN set */
1990 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
1991 		req.ur_size = sizeof (*mnsr);
1992 	} else {
1993 		req.ur_size = sizeof (*sr);
1994 	}
1995 	req.ur_data = (uintptr_t)sr;
1996 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
1997 		(void) mdstealerror(ep, &req.ur_mde);
1998 		free_sr(sr);
1999 		return;
2000 	}
2001 
2002 	commitset(sr, TRUE, ep);
2003 	free_sr(sr);
2004 }
2005 
2006 /*
2007  * delete 1 or more a hosts from a set.
2008  */
2009 bool_t
2010 mdrpc_delhosts_common(
2011 	mdrpc_host_args		*args,
2012 	mdrpc_generic_res	*res,
2013 	struct svc_req		*rqstp,		/* RPC stuff */
2014 	int			version		/* RPC version */
2015 )
2016 {
2017 	md_error_t		*ep = &res->status;
2018 	int			err;
2019 	int			op_mode = W_OK;
2020 
2021 	/* setup, check permissions */
2022 	(void) memset(res, 0, sizeof (*res));
2023 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2024 		return (FALSE);
2025 	else if (err != 0)
2026 		return (TRUE);
2027 
2028 	if (check_set_lock(op_mode, args->cl_sk, ep))
2029 		return (TRUE);
2030 
2031 	/* doit */
2032 	delhosts(args->sp->setname, args->hosts.hosts_len,
2033 	    args->hosts.hosts_val, version, ep);
2034 
2035 	err = svc_fini(ep);
2036 
2037 	return (TRUE);
2038 }
2039 
2040 bool_t
2041 mdrpc_delhosts_1_svc(
2042 	mdrpc_host_args		*args,
2043 	mdrpc_generic_res	*res,
2044 	struct svc_req		*rqstp		/* RPC stuff */
2045 )
2046 {
2047 	/* Pass RPC version (METAD_VERSION) to common routine */
2048 	return (mdrpc_delhosts_common(args, res, rqstp, METAD_VERSION));
2049 }
2050 
2051 bool_t
2052 mdrpc_delhosts_2_svc(
2053 	mdrpc_host_2_args	*args,
2054 	mdrpc_generic_res	*res,
2055 	struct svc_req		*rqstp		/* RPC stuff */
2056 )
2057 {
2058 	switch (args->rev) {
2059 	    case MD_METAD_ARGS_REV_1:
2060 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
2061 		return (mdrpc_delhosts_common(
2062 		    &args->mdrpc_host_2_args_u.rev1, res,
2063 		    rqstp, METAD_VERSION_DEVID));
2064 	    default:
2065 		return (FALSE);
2066 	}
2067 }
2068 
2069 /*
2070  * delete a set.
2071  */
2072 bool_t
2073 mdrpc_delset_common(
2074 	mdrpc_sp_args		*args,
2075 	mdrpc_generic_res	*res,
2076 	struct svc_req		*rqstp		/* RPC stuff */
2077 )
2078 {
2079 	md_error_t		*ep = &res->status;
2080 	int			err;
2081 	int			op_mode = W_OK;
2082 
2083 	/* setup, check permissions */
2084 	(void) memset(res, 0, sizeof (*res));
2085 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2086 		return (FALSE);
2087 	else if (err != 0)
2088 		return (TRUE);
2089 
2090 	if (check_set_lock(op_mode, args->cl_sk, ep))
2091 		return (TRUE);
2092 
2093 	/* doit */
2094 	s_delset(args->sp->setname, ep);
2095 
2096 	err = svc_fini(ep);
2097 
2098 	return (TRUE);
2099 }
2100 
2101 bool_t
2102 mdrpc_delset_1_svc(
2103 	mdrpc_sp_args		*args,
2104 	mdrpc_generic_res	*res,
2105 	struct svc_req		*rqstp		/* RPC stuff */
2106 )
2107 {
2108 	return (mdrpc_delset_common(args, res, rqstp));
2109 }
2110 
2111 bool_t
2112 mdrpc_delset_2_svc(
2113 	mdrpc_sp_2_args		*args,
2114 	mdrpc_generic_res	*res,
2115 	struct svc_req		*rqstp		/* RPC stuff */
2116 )
2117 {
2118 	switch (args->rev) {
2119 	    case MD_METAD_ARGS_REV_1:
2120 		return (mdrpc_delset_common(
2121 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
2122 	    default:
2123 		return (FALSE);
2124 	}
2125 }
2126 
2127 /*
2128  * return device info
2129  */
2130 static void
2131 devinfo(
2132 	mdsetname_t		*sp,
2133 	mddrivename_t		*dp,
2134 	mdrpc_devinfo_2_res 	*res,
2135 	md_error_t		*ep
2136 )
2137 {
2138 	mdname_t		*np, *real_np;
2139 
2140 	if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL)
2141 		return;
2142 
2143 	if ((real_np = metaname(&sp, np->bname, LOGICAL_DEVICE, ep)) == NULL)
2144 		return;
2145 
2146 	res->dev = real_np->dev;
2147 	(void) getdevstamp(dp, (long *)&res->vtime, ep);
2148 	res->enc_devid = meta_get_devid(np->rname);
2149 }
2150 
2151 bool_t
2152 mdrpc_devinfo_common(
2153 	mdrpc_devinfo_2_args_r1	*args,
2154 	mdrpc_devinfo_2_res 	*res,
2155 	struct svc_req		*rqstp			/* RPC stuff */
2156 )
2157 {
2158 	int			slice;
2159 	mdname_t		*np;
2160 	mddrivename_t		*dnp = args->drivenamep;
2161 	md_error_t		*ep = &res->status;
2162 	int			err;
2163 	int			op_mode = R_OK;
2164 
2165 	/* setup, check permissions */
2166 	(void) memset(res, 0, sizeof (*res));
2167 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2168 		return (FALSE);
2169 	else if (err != 0)
2170 		return (TRUE);
2171 
2172 	if (check_set_lock(op_mode, NULL, ep))
2173 		return (TRUE);
2174 
2175 	/*
2176 	 * fix all the drivenamep's in the mdname_t's to
2177 	 * point to the right place.
2178 	 */
2179 	for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
2180 		if ((np = metaslicename(dnp, slice, ep)) == NULL)
2181 			return (TRUE);
2182 		np->drivenamep = dnp;
2183 	}
2184 
2185 	/* doit */
2186 	devinfo(args->sp, dnp, res, ep);
2187 
2188 	err = svc_fini(ep);
2189 
2190 	return (TRUE);
2191 }
2192 
2193 /*
2194  * version 1 of the remote procedure. This procedure is called if the
2195  * client is running in version 1. We first convert version 1 arguments
2196  * into version 2 arguments and then call the common remote procedure.
2197  */
2198 bool_t
2199 mdrpc_devinfo_1_svc(
2200 	mdrpc_devinfo_args	*args,
2201 	mdrpc_devinfo_res 	*res,
2202 	struct svc_req		*rqstp			/* RPC stuff */
2203 )
2204 {
2205 	bool_t			retval;
2206 	mdrpc_devinfo_2_args_r1	v2_args;
2207 	mdrpc_devinfo_2_res	v2_res;
2208 
2209 	/* allocate memory */
2210 	v2_args.drivenamep = Zalloc(sizeof (mddrivename_t));
2211 	v2_args.drivenamep->parts.parts_val =
2212 	    Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len);
2213 
2214 	/* convert v1 args to v2 (revision 1) args */
2215 	meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep);
2216 	retval = mdrpc_devinfo_common(&v2_args, &v2_res, rqstp);
2217 
2218 	/*
2219 	 * Fill in the result appropriately.
2220 	 * Since dev_t's for version 2 are 64-bit,
2221 	 * we need to convert them to 32-bit for version 1.
2222 	 */
2223 	res->dev = meta_cmpldev(v2_res.dev);
2224 	res->vtime = v2_res.vtime;
2225 	res->status = v2_res.status;
2226 
2227 	free(v2_args.drivenamep);
2228 	free(v2_args.drivenamep->parts.parts_val);
2229 
2230 	return (retval);
2231 }
2232 
2233 bool_t
2234 mdrpc_devinfo_2_svc(
2235 	mdrpc_devinfo_2_args	*args,
2236 	mdrpc_devinfo_2_res 	*res,
2237 	struct svc_req		*rqstp			/* RPC stuff */
2238 )
2239 {
2240 	switch (args->rev) {
2241 	    case MD_METAD_ARGS_REV_1:
2242 		return (mdrpc_devinfo_common(
2243 		    &args->mdrpc_devinfo_2_args_u.rev1, res, rqstp));
2244 	    default:
2245 		return (FALSE);
2246 	}
2247 }
2248 
2249 /*
2250  * return device id
2251  */
2252 static void
2253 mdrpc_get_devid(
2254 	mdsetname_t		*sp,
2255 	mddrivename_t		*dp,
2256 	mdrpc_devid_res 	*res,
2257 	md_error_t		*ep
2258 )
2259 {
2260 	mdname_t	*np;
2261 
2262 	if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL)
2263 		return;
2264 
2265 	if (metaname(&sp, np->bname, LOGICAL_DEVICE, ep) == NULL)
2266 		return;
2267 
2268 	res->enc_devid = meta_get_devid(np->rname);
2269 }
2270 
2271 bool_t
2272 mdrpc_devid_2_svc(
2273 	mdrpc_devid_2_args	*args,
2274 	mdrpc_devid_res 	*res,
2275 	struct svc_req		*rqstp			/* RPC stuff */
2276 )
2277 {
2278 	int			slice;
2279 	mdname_t		*np;
2280 	mddrivename_t		*dnp;
2281 	md_error_t		*ep = &res->status;
2282 	int			err;
2283 	int			op_mode = R_OK;
2284 
2285 	switch (args->rev) {
2286 	    case MD_METAD_ARGS_REV_1:
2287 		dnp = (&(args->mdrpc_devid_2_args_u.rev1))->drivenamep;
2288 		break;
2289 	    default:
2290 		return (FALSE);
2291 	}
2292 
2293 	/* setup, check permissions */
2294 	(void) memset(res, 0, sizeof (*res));
2295 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2296 		return (FALSE);
2297 	else if (err != 0)
2298 		return (TRUE);
2299 
2300 	if (check_set_lock(op_mode, NULL, ep))
2301 		return (TRUE);
2302 
2303 	/*
2304 	 * fix all the drivenamep's in the mdname_t's to
2305 	 * point to the right place.
2306 	 */
2307 	for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
2308 		if ((np = metaslicename(dnp, slice, ep)) == NULL)
2309 			return (TRUE);
2310 		np->drivenamep = dnp;
2311 	}
2312 
2313 	/* doit */
2314 	mdrpc_get_devid((&(args->mdrpc_devid_2_args_u.rev1))->sp, dnp, res, ep);
2315 
2316 	err = svc_fini(ep);
2317 
2318 	return (TRUE);
2319 }
2320 
2321 /*
2322  * This routine should not be called for a multi-node diskset.
2323  *
2324  * The devid support is disabled for MN diskset so this routine
2325  * will not be called if the set is MN diskset.  The check has
2326  * been done early in meta_getnextside_devinfo.  However this
2327  * routine will be called when the devid support for MN set is
2328  * enabled and check is removed.
2329  */
2330 bool_t
2331 mdrpc_devinfo_by_devid_2_svc(
2332 	mdrpc_devidstr_args	*args,
2333 	mdrpc_devinfo_2_res	*res,
2334 	struct svc_req	  *rqstp		  /* RPC stuff */
2335 )
2336 {
2337 
2338 	char		*devidstr = args->enc_devid;
2339 	md_error_t	*ep = &res->status;
2340 	ddi_devid_t	devid;
2341 	char		*minor_name = NULL;
2342 	int		ret = 0;
2343 	int		err;
2344 	devid_nmlist_t	*disklist = NULL;
2345 	int		op_mode = R_OK;
2346 	mdname_t	*np;
2347 	mdsetname_t	*sp = args->sp;
2348 
2349 	/* setup, check permissions */
2350 	(void) memset(res, 0, sizeof (*res));
2351 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2352 		return (FALSE);
2353 	else if (err != 0)
2354 		return (TRUE);
2355 
2356 	if (check_set_lock(op_mode, NULL, ep))
2357 		return (TRUE);
2358 
2359 	if (devid_str_decode(devidstr, &devid, &minor_name) != 0)
2360 		return (TRUE);
2361 
2362 	/*
2363 	 * if we do not have a minor name then look for a character device.
2364 	 * This is because the caller (checkdrive_onnode) expects a character
2365 	 * device to be returned. The other client of this interface is
2366 	 * meta_getnextside_devinfo and this supplies a minor name.
2367 	 */
2368 	if (minor_name == NULL) {
2369 		ret = meta_deviceid_to_nmlist("/dev", devid,
2370 		    DEVID_MINOR_NAME_ALL_CHR, &disklist);
2371 	} else {
2372 		ret = meta_deviceid_to_nmlist("/dev", devid, minor_name,
2373 		    &disklist);
2374 		devid_str_free(minor_name);
2375 	}
2376 
2377 	devid_free(devid);
2378 	if (ret != 0) {
2379 		res->dev = NODEV64;
2380 		devid_free_nmlist(disklist);
2381 		return (TRUE);
2382 	}
2383 
2384 	np = metaname(&sp, disklist[0].devname, LOGICAL_DEVICE, ep);
2385 	if (np != NULL) {
2386 		mdcinfo_t	*cinfo;
2387 		if ((cinfo = metagetcinfo(np, ep)) != NULL) {
2388 			res->drivername = Strdup(cinfo->dname);
2389 		}
2390 	}
2391 
2392 	res->dev = meta_expldev(disklist[0].dev);
2393 	res->devname = strdup(disklist[0].devname);
2394 
2395 	devid_free_nmlist(disklist);
2396 
2397 	err = svc_fini(ep);
2398 
2399 	return (TRUE);
2400 }
2401 
2402 /*
2403  * This routine should not be called for a multi-node diskset.
2404  *
2405  * The devid support is disabled for MN diskset so this routine
2406  * will not be called if the set is MN diskset.  The check has
2407  * been done early in meta_getnextside_devinfo.  However this
2408  * routine will be called when the devid support for MN set is
2409  * enabled and check is removed.
2410  *
2411  * This function will return the device info attempting to use
2412  * both the passed in devid and device name.  This is to deal
2413  * with systems that use multi-path disks but not running mpxio.
2414  * In this situation meta_deviceid_to_nmlist will return multiple
2415  * devices.  The orig_devname is used to disambiguate.
2416  *
2417  */
2418 bool_t
2419 mdrpc_devinfo_by_devid_name_2_svc(
2420 	mdrpc_devid_name_2_args	*args,
2421 	mdrpc_devinfo_2_res	*res,
2422 	struct svc_req	  *rqstp		  /* RPC stuff */
2423 )
2424 {
2425 
2426 	char		*devidstr;
2427 	char		*orig_devname;
2428 	md_error_t	*ep = &res->status;
2429 	ddi_devid_t	devid;
2430 	char		*minor_name = NULL;
2431 	int		ret = 0;
2432 	int		err;
2433 	int		i;
2434 	devid_nmlist_t	*disklist = NULL;
2435 	int		op_mode = R_OK;
2436 	mdname_t	*np;
2437 	mdsetname_t	*sp;
2438 
2439 	switch (args->rev) {
2440 	    case MD_METAD_ARGS_REV_1:
2441 		sp = (&(args->mdrpc_devid_name_2_args_u.rev1))->sp;
2442 		devidstr = (&(args->mdrpc_devid_name_2_args_u.rev1))->enc_devid;
2443 		orig_devname =
2444 			(&(args->mdrpc_devid_name_2_args_u.rev1))->orig_devname;
2445 		break;
2446 	    default:
2447 		return (FALSE);
2448 	}
2449 
2450 	/* setup, check permissions */
2451 	(void) memset(res, 0, sizeof (*res));
2452 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2453 		return (FALSE);
2454 	else if (err != 0)
2455 		return (TRUE);
2456 
2457 	if (check_set_lock(op_mode, NULL, ep))
2458 		return (TRUE);
2459 
2460 	if (devid_str_decode(devidstr, &devid, &minor_name) != 0)
2461 		return (TRUE);
2462 
2463 	/*
2464 	 * if we do not have a minor name then look for a character device.
2465 	 * This is because the caller (checkdrive_onnode) expects a character
2466 	 * device to be returned. The other client of this interface is
2467 	 * meta_getnextside_devinfo and this supplies a minor name.
2468 	 */
2469 	if (minor_name == NULL) {
2470 		ret = meta_deviceid_to_nmlist("/dev", devid,
2471 		    DEVID_MINOR_NAME_ALL_CHR, &disklist);
2472 	} else {
2473 		ret = meta_deviceid_to_nmlist("/dev", devid, minor_name,
2474 		    &disklist);
2475 		devid_str_free(minor_name);
2476 	}
2477 
2478 	devid_free(devid);
2479 	if (ret != 0) {
2480 		res->dev = NODEV64;
2481 		devid_free_nmlist(disklist);
2482 		return (TRUE);
2483 	}
2484 
2485 	/* attempt to match to the device name on the originating node */
2486 	for (i = 0; disklist[i].dev != NODEV; i++) {
2487 		if (strncmp(orig_devname, disklist[i].devname,
2488 					strlen(disklist[i].devname)) == 0)
2489 			break;
2490 	}
2491 
2492 	/* if it's not found then use the first disk in the list */
2493 	if (disklist[i].dev == NODEV)
2494 		i = 0;
2495 
2496 	np = metaname(&sp, disklist[i].devname, LOGICAL_DEVICE, ep);
2497 	if (np != NULL) {
2498 		mdcinfo_t	*cinfo;
2499 		if ((cinfo = metagetcinfo(np, ep)) != NULL) {
2500 			res->drivername = Strdup(cinfo->dname);
2501 		}
2502 	}
2503 
2504 	res->dev = meta_expldev(disklist[i].dev);
2505 	res->devname = strdup(disklist[i].devname);
2506 
2507 	devid_free_nmlist(disklist);
2508 
2509 	err = svc_fini(ep);
2510 
2511 	return (TRUE);
2512 }
2513 
2514 static void
2515 drvused(mdsetname_t *sp, mddrivename_t *dnp, md_error_t *ep)
2516 {
2517 	if (meta_check_drivemounted(sp, dnp, ep))
2518 		return;
2519 
2520 	if (meta_check_driveswapped(sp, dnp, ep))
2521 		return;
2522 
2523 	if (meta_check_drive_inuse(metasetname(MD_LOCAL_NAME, ep), dnp,
2524 	    TRUE, ep))
2525 		return;
2526 
2527 	(void) meta_check_driveinset(sp, dnp, ep);
2528 }
2529 
2530 /*
2531  * determine if a device is in use.
2532  */
2533 bool_t
2534 mdrpc_drvused_common(
2535 	mdrpc_drvused_2_args_r1	*args,
2536 	mdrpc_generic_res	*res,
2537 	struct svc_req		*rqstp		/* RPC stuff */
2538 )
2539 {
2540 	md_error_t		*ep = &res->status;
2541 	int			slice;
2542 	mdname_t		*np;
2543 	mddrivename_t		*dnp = args->drivenamep;
2544 	int			err;
2545 	int			op_mode = R_OK;
2546 
2547 	/* setup, check permissions */
2548 	(void) memset(res, 0, sizeof (*res));
2549 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2550 		return (FALSE);
2551 	else if (err != 0)
2552 		return (TRUE);
2553 
2554 	if (check_set_lock(op_mode, NULL, ep))
2555 		return (TRUE);
2556 
2557 	if (dnp == NULL) {
2558 		/* no drive pointer specified */
2559 		return (TRUE);
2560 	}
2561 	/*
2562 	 * fix all the drivenamep's in the mdname_t's to
2563 	 * point to the right place.
2564 	 */
2565 	for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
2566 		if ((np = metaslicename(dnp, slice, ep)) == NULL)
2567 			return (TRUE);
2568 		np->drivenamep = dnp;
2569 	}
2570 
2571 	/* doit */
2572 	drvused(args->sp, dnp, ep);
2573 
2574 	err = svc_fini(ep);
2575 
2576 	return (TRUE);
2577 }
2578 
2579 /*
2580  * version 1 of the remote procedure. This procedure is called if the
2581  * client is running in version 1. We first convert version 1 arguments
2582  * into version 2 arguments and then call the common remote procedure.
2583  */
2584 bool_t
2585 mdrpc_drvused_1_svc(
2586 	mdrpc_drvused_args	*args,
2587 	mdrpc_generic_res	*res,
2588 	struct svc_req		*rqstp		/* RPC stuff */
2589 )
2590 {
2591 	bool_t			retval;
2592 	mdrpc_drvused_2_args_r1	v2_args;
2593 
2594 	/* allocate memory */
2595 	v2_args.drivenamep = Zalloc(sizeof (mddrivename_t));
2596 	v2_args.drivenamep->parts.parts_val =
2597 	    Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len);
2598 
2599 	/* build args */
2600 	v2_args.sp = args->sp;
2601 	v2_args.cl_sk = args->cl_sk;
2602 
2603 	/* convert v1 args to v2 (revision 1) args */
2604 	meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep);
2605 	retval = mdrpc_drvused_common(&v2_args, res, rqstp);
2606 
2607 	free(v2_args.drivenamep);
2608 	free(v2_args.drivenamep->parts.parts_val);
2609 
2610 	return (retval);
2611 }
2612 
2613 bool_t
2614 mdrpc_drvused_2_svc(
2615 	mdrpc_drvused_2_args	*args,
2616 	mdrpc_generic_res	*res,
2617 	struct svc_req		*rqstp		/* RPC stuff */
2618 )
2619 {
2620 	switch (args->rev) {
2621 	    case MD_METAD_ARGS_REV_1:
2622 		return (mdrpc_drvused_common(
2623 		    &args->mdrpc_drvused_2_args_u.rev1, res, rqstp));
2624 	    default:
2625 		return (FALSE);
2626 	}
2627 }
2628 
2629 /*
2630  * return a set records selected by name or number.
2631  */
2632 bool_t
2633 mdrpc_getset_common(
2634 	mdrpc_getset_args	*args,
2635 	mdrpc_getset_res 	*res,
2636 	struct svc_req		*rqstp		/* RPC stuff */
2637 )
2638 {
2639 	md_error_t		*ep = &res->status;
2640 	int			err;
2641 	int			op_mode = R_OK;
2642 
2643 	/* setup, check permissions */
2644 	(void) memset(res, 0, sizeof (*res));
2645 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2646 		return (FALSE);
2647 	else if (err != 0)
2648 		return (TRUE);
2649 
2650 	/* Don't have a setno, so we don't check the lock */
2651 	if (check_set_lock(op_mode, NULL, ep))
2652 		return (TRUE);
2653 
2654 	/* doit */
2655 	if (args->setname && *args->setname)
2656 		res->sr = setdup(getsetbyname(args->setname, ep));
2657 	else if (args->setno > 0)
2658 		res->sr = setdup(getsetbynum(args->setno, ep));
2659 	else
2660 		res->sr = NULL;
2661 
2662 	err = svc_fini(ep);
2663 
2664 	return (TRUE);
2665 }
2666 
2667 bool_t
2668 mdrpc_getset_1_svc(
2669 	mdrpc_getset_args	*args,
2670 	mdrpc_getset_res 	*res,
2671 	struct svc_req		*rqstp		/* RPC stuff */
2672 )
2673 {
2674 	return (mdrpc_getset_common(args, res, rqstp));
2675 }
2676 
2677 bool_t
2678 mdrpc_getset_2_svc(
2679 	mdrpc_getset_2_args	*args,
2680 	mdrpc_getset_res 	*res,
2681 	struct svc_req		*rqstp		/* RPC stuff */
2682 )
2683 {
2684 	switch (args->rev) {
2685 	    case MD_METAD_ARGS_REV_1:
2686 		return (mdrpc_getset_common(
2687 		    &args->mdrpc_getset_2_args_u.rev1, res, rqstp));
2688 	    default:
2689 		return (FALSE);
2690 	}
2691 }
2692 
2693 /*
2694  * return a MN set record selected by name or number.
2695  */
2696 bool_t
2697 mdrpc_mngetset_common(
2698 	mdrpc_getset_args	*args,
2699 	mdrpc_mngetset_res 	*res,
2700 	struct svc_req		*rqstp		/* RPC stuff */
2701 )
2702 {
2703 	md_error_t		*ep = &res->status;
2704 	int			err;
2705 	int			op_mode = R_OK;
2706 	md_set_record		*sr = NULL;
2707 	md_mnset_record		*mnsr = NULL;
2708 
2709 	/* setup, check permissions */
2710 	(void) memset(res, 0, sizeof (*res));
2711 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2712 		return (FALSE);
2713 	else if (err != 0)
2714 		return (TRUE);
2715 
2716 	/* Don't have a setno, so we don't check the lock */
2717 	if (check_set_lock(op_mode, NULL, ep))
2718 		return (TRUE);
2719 
2720 	/* doit */
2721 	res->mnsr = NULL;
2722 	if (args->setname && *args->setname)
2723 		sr = getsetbyname(args->setname, ep);
2724 	else if (args->setno > 0)
2725 		sr = getsetbynum(args->setno, ep);
2726 
2727 	if ((sr) && (MD_MNSET_REC(sr))) {
2728 		mnsr = (struct md_mnset_record *)sr;
2729 		res->mnsr = mnsetdup(mnsr);
2730 	}
2731 
2732 	err = svc_fini(ep);
2733 
2734 	return (TRUE);
2735 }
2736 
2737 bool_t
2738 mdrpc_mngetset_2_svc(
2739 	mdrpc_getset_2_args	*args,
2740 	mdrpc_mngetset_res	*res,
2741 	struct svc_req		*rqstp		/* RPC stuff */
2742 )
2743 {
2744 	switch (args->rev) {
2745 	    case MD_METAD_ARGS_REV_1:
2746 		return (mdrpc_mngetset_common(
2747 		    &args->mdrpc_getset_2_args_u.rev1, res, rqstp));
2748 	    default:
2749 		return (FALSE);
2750 	}
2751 }
2752 
2753 static void
2754 upd_setmaster(
2755 	mdsetname_t	*sp,
2756 	md_node_nm_t	master_nodenm,
2757 	int		master_nodeid,
2758 	md_error_t	*ep
2759 )
2760 {
2761 	mdsetname_t	*local_sp;
2762 	md_set_record	*sr;
2763 	md_mnset_record	*mnsr;
2764 	mddb_setmaster_config_t	sm;
2765 
2766 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
2767 		return;
2768 
2769 	metaflushsetname(local_sp);
2770 
2771 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
2772 		return;
2773 
2774 	if (MD_MNSET_REC(sr)) {
2775 		mnsr = (struct md_mnset_record *)sr;
2776 		strlcpy(mnsr->sr_master_nodenm, master_nodenm,
2777 			MD_MAX_NODENAME);
2778 		mnsr->sr_master_nodeid = master_nodeid;
2779 		if (master_nodeid != 0) {
2780 			(void) memset(&sm, 0, sizeof (sm));
2781 			sm.c_setno = sp->setno;
2782 			/* Use magic to help protect ioctl against attack. */
2783 			sm.c_magic = MDDB_SETMASTER_MAGIC;
2784 			if (strcmp(master_nodenm, mynode()) == 0) {
2785 				sm.c_current_host_master = 1;
2786 			} else {
2787 				sm.c_current_host_master = 0;
2788 			}
2789 			(void) metaioctl(MD_SETMASTER, &sm, &sm.c_mde, NULL);
2790 			mdclrerror(&sm.c_mde);
2791 		}
2792 	}
2793 
2794 out:
2795 	commitset(sr, FALSE, ep);
2796 	free_sr(sr);
2797 }
2798 
2799 /*
2800  * set the master and nodeid in node record
2801  */
2802 bool_t
2803 mdrpc_mnsetmaster_common(
2804 	mdrpc_mnsetmaster_args	*args,
2805 	mdrpc_generic_res 	*res,
2806 	struct svc_req		*rqstp		/* RPC stuff */
2807 )
2808 {
2809 	md_error_t		*ep = &res->status;
2810 	int			err;
2811 	int			op_mode = W_OK;
2812 
2813 	/* setup, check permissions */
2814 	(void) memset(res, 0, sizeof (*res));
2815 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2816 		return (FALSE);
2817 	else if (err != 0)
2818 		return (TRUE);
2819 
2820 	if (check_set_lock(op_mode, args->cl_sk, ep))
2821 		return (TRUE);
2822 
2823 	/* doit */
2824 	upd_setmaster(args->sp, args->master_nodenm, args->master_nodeid, ep);
2825 
2826 	err = svc_fini(ep);
2827 
2828 	return (TRUE);
2829 }
2830 
2831 bool_t
2832 mdrpc_mnsetmaster_2_svc(
2833 	mdrpc_mnsetmaster_2_args	*args,
2834 	mdrpc_generic_res	*res,
2835 	struct svc_req		*rqstp		/* RPC stuff */
2836 )
2837 {
2838 	switch (args->rev) {
2839 	    case MD_METAD_ARGS_REV_1:
2840 		return (mdrpc_mnsetmaster_common(
2841 		    &args->mdrpc_mnsetmaster_2_args_u.rev1, res, rqstp));
2842 	    default:
2843 		return (FALSE);
2844 	}
2845 }
2846 
2847 /*
2848  * Join this node to the diskset.
2849  * Pass stale_flag information to snarf_set so that snarf code
2850  * can choose a STALE or non-STALE state when starting the set.
2851  * If master is STALE, any joining node will join a stale set regardless
2852  * of the number of accessible mddbs.  Also, if master is at 50%
2853  * accessible replicas and is in the TOOFEW state, don't mark newly
2854  * joining node as STALE; mark it TOOFEW instead.
2855  */
2856 static void
2857 joinset(
2858 	mdsetname_t	*sp,
2859 	int		flags,
2860 	md_error_t	*ep
2861 )
2862 {
2863 	mdsetname_t		*local_sp;
2864 	md_drive_desc		*mydd;
2865 	bool_t			stale_bool;
2866 	mddb_block_parm_t	mbp;
2867 	md_error_t		xep = mdnullerror;
2868 
2869 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
2870 		return;
2871 
2872 	/*
2873 	 * Start mddoors daemon here.
2874 	 * mddoors itself takes care there will be
2875 	 * only one instance running, so starting it twice won't hurt
2876 	 */
2877 	pclose(popen(MDDOORS, "w"));
2878 
2879 	/*
2880 	 * Get latest copy of data.  If a drive was just added causing
2881 	 * nodes to get joined - this drive won't be in the local
2882 	 * name caches drive list yet.
2883 	 */
2884 	metaflushsetname(local_sp);
2885 
2886 	mydd = metaget_drivedesc(local_sp, (MD_BASICNAME_OK | PRINT_FAST), ep);
2887 	if (mydd) {
2888 		/*
2889 		 * Causes mddbs to be loaded into the kernel.
2890 		 * Set the force flag so that replica locations can be loaded
2891 		 * into the kernel even if a mediator node was unavailable.
2892 		 * This allows a node to join an MO diskset when there are
2893 		 * sufficient replicas available, but a mediator node
2894 		 * in unavailable.
2895 		 */
2896 		if (setup_db_bydd(local_sp, mydd, TRUE, ep) == -1) {
2897 			/* If ep isn't set for some reason, set it */
2898 			if (mdisok(ep)) {
2899 				(void) mdmddberror(ep, MDE_DB_NOTNOW,
2900 				    (minor_t)NODEV64, sp->setno, 0, NULL);
2901 			}
2902 			return;
2903 		}
2904 
2905 		if (flags & MNSET_IS_STALE)
2906 			stale_bool = TRUE;
2907 		else
2908 			stale_bool = FALSE;
2909 
2910 		/*
2911 		 * Snarf the set.  No failure has occurred if STALE or
2912 		 * ACCOK error was set.  Otherwise, fail the call setting
2913 		 * a generic error if no error was already set.
2914 		 *
2915 		 * STALE means that set has < 50% mddbs.
2916 		 * ACCOK means that the mediator provided an extra vote.
2917 		 */
2918 		if (snarf_set(local_sp, stale_bool, ep) != 0) {
2919 			if (!(mdismddberror(ep, MDE_DB_STALE)) &&
2920 			    !(mdismddberror(ep, MDE_DB_ACCOK))) {
2921 				return;
2922 			} else if (mdisok(ep)) {
2923 				/* If snarf failed, but no error set - set it */
2924 				(void) mdmddberror(ep, MDE_DB_NOTNOW,
2925 				    (minor_t)NODEV64, sp->setno, 0, NULL);
2926 				return;
2927 			}
2928 		}
2929 
2930 		/*
2931 		 * If node is joining during reconfig cycle, then
2932 		 * set mddb_parse to be in blocked state so that
2933 		 * mddb reparse messages are not generated until
2934 		 * the commd has been resumed later in the reconfig
2935 		 * cycle.
2936 		 */
2937 		if (flags & MNSET_IN_RECONFIG) {
2938 			(void) memset(&mbp, 0, sizeof (mbp));
2939 			if (s_ownset(sp->setno, &xep) == MD_SETOWNER_YES) {
2940 				(void) memset(&mbp, 0, sizeof (mbp));
2941 				mbp.c_setno = local_sp->setno;
2942 				mbp.c_blk_flags = MDDB_BLOCK_PARSE;
2943 				if (metaioctl(MD_MN_MDDB_BLOCK, &mbp,
2944 				    &mbp.c_mde, NULL)) {
2945 					mdstealerror(&xep, &mbp.c_mde);
2946 					mde_perror(ep, gettext(
2947 					    "Could not block set %s"),
2948 					    sp->setname);
2949 					return;
2950 				}
2951 			}
2952 			/*
2953 			 * If s_ownset fails and snarf_set succeeded,
2954 			 * then can steal the ownset failure information
2955 			 * and store it into ep. If snarf_set failed,
2956 			 * don't overwrite critical ep information even
2957 			 * if s_ownset failed.
2958 			 */
2959 			if (!mdisok(&xep)) {
2960 				/*
2961 				 * If snarf_set succeeded or snarf_set failed
2962 				 * with MDE_DB_ACCOK (which is set if the
2963 				 * mediator provided the extra vote) then
2964 				 * steal the xep failure information and put
2965 				 * into ep.
2966 				 */
2967 				if (mdisok(ep) ||
2968 				    mdismddberror(ep, MDE_DB_ACCOK)) {
2969 					mdstealerror(ep, &xep);
2970 				}
2971 			}
2972 		}
2973 	}
2974 }
2975 
2976 /*
2977  * Have this node join the set.
2978  * This is called when a node has been
2979  * added to a MN diskset that has drives.
2980  * Also, called when a node is an alive
2981  * member of a MN diskset and the first
2982  * drive has been added.
2983  */
2984 bool_t
2985 mdrpc_joinset_common(
2986 	mdrpc_sp_flags_args	*args,
2987 	mdrpc_generic_res 	*res,
2988 	struct svc_req		*rqstp		/* RPC stuff */
2989 )
2990 {
2991 	md_error_t		*ep = &res->status;
2992 	int			err;
2993 	int			op_mode = W_OK;
2994 
2995 	/* setup, check permissions */
2996 	(void) memset(res, 0, sizeof (*res));
2997 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2998 		return (FALSE);
2999 	else if (err != 0)
3000 		return (TRUE);
3001 
3002 	/*
3003 	 * During reconfig, joinset can happen without
3004 	 * locking first.  Turn off reconfig flag before calling
3005 	 * joinset.
3006 	 */
3007 	if (!(args->flags & MNSET_IN_RECONFIG)) {
3008 		if (check_set_lock(op_mode, args->cl_sk, ep))
3009 			return (TRUE);
3010 	}
3011 
3012 	/* doit */
3013 	joinset(args->sp, args->flags, ep);
3014 
3015 	err = svc_fini(ep);
3016 
3017 	return (TRUE);
3018 }
3019 
3020 bool_t
3021 mdrpc_joinset_2_svc(
3022 	mdrpc_sp_flags_2_args	*args,
3023 	mdrpc_generic_res	*res,
3024 	struct svc_req		*rqstp		/* RPC stuff */
3025 )
3026 {
3027 	switch (args->rev) {
3028 	    case MD_METAD_ARGS_REV_1:
3029 		return (mdrpc_joinset_common(
3030 		    &args->mdrpc_sp_flags_2_args_u.rev1, res, rqstp));
3031 	    default:
3032 		return (FALSE);
3033 	}
3034 }
3035 
3036 static void
3037 withdrawset(
3038 	mdsetname_t	*sp,
3039 	md_error_t	*ep
3040 )
3041 {
3042 	mdsetname_t	*my_sp;
3043 
3044 	if ((my_sp = metasetname(sp->setname, ep)) == NULL)
3045 		return;
3046 
3047 	(void) halt_set(my_sp, ep);
3048 }
3049 
3050 /*
3051  * Have this node withdraw from set.
3052  * In response to a failure that occurred
3053  * on the client after a joinset.
3054  */
3055 bool_t
3056 mdrpc_withdrawset_common(
3057 	mdrpc_sp_args		*args,
3058 	mdrpc_generic_res 	*res,
3059 	struct svc_req		*rqstp		/* RPC stuff */
3060 )
3061 {
3062 	md_error_t		*ep = &res->status;
3063 	int			err;
3064 	int			op_mode = W_OK;
3065 
3066 	/* setup, check permissions */
3067 	(void) memset(res, 0, sizeof (*res));
3068 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3069 		return (FALSE);
3070 	else if (err != 0)
3071 		return (TRUE);
3072 
3073 	if (check_set_lock(op_mode, args->cl_sk, ep))
3074 		return (TRUE);
3075 
3076 	/* doit */
3077 	withdrawset(args->sp, ep);
3078 
3079 	err = svc_fini(ep);
3080 
3081 	return (TRUE);
3082 }
3083 
3084 bool_t
3085 mdrpc_withdrawset_2_svc(
3086 	mdrpc_sp_2_args		*args,
3087 	mdrpc_generic_res	*res,
3088 	struct svc_req		*rqstp		/* RPC stuff */
3089 )
3090 {
3091 	switch (args->rev) {
3092 	    case MD_METAD_ARGS_REV_1:
3093 		return (mdrpc_withdrawset_common(
3094 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
3095 	    default:
3096 		return (FALSE);
3097 	}
3098 }
3099 
3100 static mhd_mhiargs_t *
3101 gtimeout(mdsetname_t *sp, md_error_t *ep)
3102 {
3103 	md_set_record		*sr;
3104 	mhd_mhiargs_t		*mhiargs;
3105 
3106 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
3107 		return (NULL);
3108 
3109 	mhiargs = Zalloc(sizeof (*mhiargs));
3110 	*mhiargs = sr->sr_mhiargs;
3111 
3112 	free_sr(sr);
3113 	return (mhiargs);
3114 }
3115 
3116 /*
3117  * Get the MH timeout values for this set.
3118  */
3119 bool_t
3120 mdrpc_gtimeout_common(
3121 	mdrpc_sp_args		*args,
3122 	mdrpc_gtimeout_res 	*res,
3123 	struct svc_req		*rqstp		/* RPC stuff */
3124 )
3125 {
3126 	md_error_t		*ep = &res->status;
3127 	int			err;
3128 	int			op_mode = R_OK;
3129 
3130 	/* setup, check permissions */
3131 	(void) memset(res, 0, sizeof (*res));
3132 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3133 		return (FALSE);
3134 	else if (err != 0)
3135 		return (TRUE);
3136 
3137 	if (check_set_lock(op_mode, NULL, ep))
3138 		return (TRUE);
3139 
3140 	/* doit */
3141 	res->mhiargsp = gtimeout(args->sp, ep);
3142 
3143 	err = svc_fini(ep);
3144 
3145 	return (TRUE);
3146 }
3147 
3148 bool_t
3149 mdrpc_gtimeout_1_svc(
3150 	mdrpc_sp_args		*args,
3151 	mdrpc_gtimeout_res 	*res,
3152 	struct svc_req		*rqstp		/* RPC stuff */
3153 )
3154 {
3155 	return (mdrpc_gtimeout_common(args, res, rqstp));
3156 }
3157 
3158 bool_t
3159 mdrpc_gtimeout_2_svc(
3160 	mdrpc_sp_2_args		*args,
3161 	mdrpc_gtimeout_res 	*res,
3162 	struct svc_req		*rqstp		/* RPC stuff */
3163 )
3164 {
3165 	switch (args->rev) {
3166 	    case MD_METAD_ARGS_REV_1:
3167 		return (mdrpc_gtimeout_common(
3168 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
3169 	    default:
3170 		return (FALSE);
3171 	}
3172 }
3173 
3174 /*
3175  * return the official host name for the callee
3176  */
3177 /*ARGSUSED*/
3178 bool_t
3179 mdrpc_hostname_common(
3180 	mdrpc_null_args		*args,
3181 	mdrpc_hostname_res 	*res,
3182 	struct svc_req		*rqstp		/* RPC stuff */
3183 )
3184 {
3185 	md_error_t		*ep = &res->status;
3186 	int			err;
3187 	int			op_mode = R_OK;
3188 
3189 	/* setup, check permissions */
3190 	(void) memset(res, 0, sizeof (*res));
3191 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3192 		return (FALSE);
3193 	else if (err != 0)
3194 		return (TRUE);
3195 
3196 	if (check_set_lock(op_mode, NULL, ep))
3197 		return (TRUE);
3198 
3199 	/* doit */
3200 	res->hostname = Strdup(mynode());
3201 
3202 	err = svc_fini(ep);
3203 
3204 	return (TRUE);
3205 }
3206 
3207 bool_t
3208 mdrpc_hostname_1_svc(
3209 	mdrpc_null_args		*args,
3210 	mdrpc_hostname_res 	*res,
3211 	struct svc_req		*rqstp		/* RPC stuff */
3212 )
3213 {
3214 	return (mdrpc_hostname_common(args, res, rqstp));
3215 }
3216 
3217 bool_t
3218 mdrpc_hostname_2_svc(
3219 	mdrpc_null_args		*args,
3220 	mdrpc_hostname_res 	*res,
3221 	struct svc_req		*rqstp		/* RPC stuff */
3222 )
3223 {
3224 	return (mdrpc_hostname_common(args, res, rqstp));
3225 }
3226 
3227 /*
3228  * return a response
3229  */
3230 /*ARGSUSED*/
3231 bool_t
3232 mdrpc_nullproc_common(
3233 	void		*args,
3234 	md_error_t	*ep,
3235 	struct svc_req	*rqstp		/* RPC stuff */
3236 )
3237 {
3238 	*ep = mdnullerror;
3239 	/* do nothing */
3240 	return (TRUE);
3241 }
3242 
3243 bool_t
3244 mdrpc_nullproc_1_svc(
3245 	void		*args,
3246 	md_error_t	*ep,
3247 	struct svc_req	*rqstp		/* RPC stuff */
3248 )
3249 {
3250 	return (mdrpc_nullproc_common(args, ep, rqstp));
3251 }
3252 
3253 bool_t
3254 mdrpc_nullproc_2_svc(
3255 	void		*args,
3256 	md_error_t	*ep,
3257 	struct svc_req	*rqstp		/* RPC stuff */
3258 )
3259 {
3260 	return (mdrpc_nullproc_common(args, ep, rqstp));
3261 }
3262 
3263 /*
3264  * determine if the caller owns the set.
3265  */
3266 bool_t
3267 mdrpc_ownset_common(
3268 	mdrpc_sp_args		*args,
3269 	mdrpc_bool_res		*res,
3270 	struct svc_req		*rqstp		/* RPC stuff */
3271 )
3272 {
3273 	md_error_t		*ep = &res->status;
3274 	int			err;
3275 	int			op_mode = R_OK;
3276 
3277 	/* setup, check permissions */
3278 	(void) memset(res, 0, sizeof (*res));
3279 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3280 		return (FALSE);
3281 	else if (err != 0)
3282 		return (TRUE);
3283 
3284 	if (check_set_lock(op_mode, NULL, ep))
3285 		return (TRUE);
3286 
3287 	/* doit */
3288 	if (s_ownset(args->sp->setno, ep))
3289 		res->value = TRUE;
3290 	else
3291 		res->value = FALSE;
3292 
3293 	err = svc_fini(ep);
3294 
3295 	return (TRUE);
3296 }
3297 
3298 bool_t
3299 mdrpc_ownset_1_svc(
3300 	mdrpc_sp_args		*args,
3301 	mdrpc_bool_res		*res,
3302 	struct svc_req		*rqstp		/* RPC stuff */
3303 )
3304 {
3305 	return (mdrpc_ownset_common(args, res, rqstp));
3306 }
3307 
3308 bool_t
3309 mdrpc_ownset_2_svc(
3310 	mdrpc_sp_2_args		*args,
3311 	mdrpc_bool_res		*res,
3312 	struct svc_req		*rqstp		/* RPC stuff */
3313 )
3314 {
3315 	switch (args->rev) {
3316 	    case MD_METAD_ARGS_REV_1:
3317 		return (mdrpc_ownset_common(
3318 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
3319 	    default:
3320 		return (FALSE);
3321 	}
3322 }
3323 
3324 static int
3325 setnameok(char *setname, md_error_t *ep)
3326 {
3327 	int			rval = 0;
3328 	struct	stat		statb;
3329 	md_set_record		*sr = NULL;
3330 	char			*setlink = NULL;
3331 
3332 	setlink = Strdup("/dev/md/");
3333 	setlink = Realloc(setlink, strlen(setlink) + strlen(setname) + 1);
3334 	(void) strcat(setlink, setname);
3335 
3336 	if (lstat(setlink, &statb) == -1) {
3337 		/*
3338 		 * If lstat() fails with ENOENT, setname is OK, if it
3339 		 * fails for other than that, we fail the RPC
3340 		 */
3341 		if (errno == ENOENT) {
3342 			rval = 1;
3343 			goto out;
3344 		}
3345 
3346 		(void) mdsyserror(ep, errno, setlink);
3347 		goto out;
3348 	}
3349 
3350 	/*
3351 	 * If the lstat() succeeded, then we see what type of object
3352 	 * we are dealing with, if it is a symlink, we do some further
3353 	 * checking, if it is not a symlink, then we return an
3354 	 * indication that the set name is NOT acceptable.
3355 	 */
3356 	if (! S_ISLNK(statb.st_mode))
3357 		goto out;
3358 
3359 	/*
3360 	 * We look up the setname to see if there is a set
3361 	 * with that name, if there is, then we return
3362 	 * an indication that the set name is NOT acceptable.
3363 	 */
3364 	if ((sr = getsetbyname(setname, ep)) != NULL)
3365 		goto out;
3366 
3367 	if (! mdiserror(ep, MDE_NO_SET))
3368 		goto out;
3369 
3370 	mdclrerror(ep);
3371 
3372 	rval = 1;
3373 out:
3374 	if (sr != NULL)
3375 		free_sr(sr);
3376 	Free(setlink);
3377 	return (rval);
3378 }
3379 
3380 /*
3381  * Make sure the name of the set is OK.
3382  */
3383 bool_t
3384 mdrpc_setnameok_common(
3385 	mdrpc_sp_args		*args,	/* device name */
3386 	mdrpc_bool_res		*res,
3387 	struct svc_req		*rqstp	/* RPC stuff */
3388 )
3389 {
3390 	md_error_t		*ep = &res->status;
3391 	int			err;
3392 	int			op_mode = R_OK;
3393 
3394 	/* setup, check permissions */
3395 	(void) memset(res, 0, sizeof (*res));
3396 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3397 		return (FALSE);
3398 	else if (err != 0)
3399 		return (TRUE);
3400 
3401 	if (check_set_lock(op_mode, NULL, ep))
3402 		return (TRUE);
3403 
3404 	/* doit */
3405 	res->value = setnameok(args->sp->setname, ep);
3406 
3407 	err = svc_fini(ep);
3408 
3409 	return (TRUE);
3410 }
3411 
3412 bool_t
3413 mdrpc_setnameok_1_svc(
3414 	mdrpc_sp_args		*args,	/* device name */
3415 	mdrpc_bool_res		*res,
3416 	struct svc_req		*rqstp	/* RPC stuff */
3417 )
3418 {
3419 	return (mdrpc_setnameok_common(args, res, rqstp));
3420 }
3421 
3422 bool_t
3423 mdrpc_setnameok_2_svc(
3424 	mdrpc_sp_2_args		*args,	/* device name */
3425 	mdrpc_bool_res		*res,
3426 	struct svc_req		*rqstp	/* RPC stuff */
3427 )
3428 {
3429 	switch (args->rev) {
3430 	    case MD_METAD_ARGS_REV_1:
3431 		return (mdrpc_setnameok_common(
3432 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
3433 	    default:
3434 		return (FALSE);
3435 	}
3436 }
3437 
3438 /*
3439  * determine if the setnumber we want to share is in use.
3440  */
3441 bool_t
3442 mdrpc_setnumbusy_common(
3443 	mdrpc_setno_args	*args,
3444 	mdrpc_bool_res		*res,
3445 	struct svc_req		*rqstp		/* RPC stuff */
3446 )
3447 {
3448 	md_error_t		*ep = &res->status;
3449 	md_set_record		*sr = NULL;
3450 	int			err;
3451 	int			op_mode = R_OK;
3452 
3453 	/* setup, check permissions */
3454 	(void) memset(res, 0, sizeof (*res));
3455 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3456 		return (FALSE);
3457 	else if (err != 0)
3458 		return (TRUE);
3459 
3460 	if (check_set_lock(op_mode, NULL, ep))
3461 		return (TRUE);
3462 
3463 	/* doit */
3464 	if ((sr = getsetbynum(args->setno, ep)) != NULL) {
3465 		res->value = TRUE;
3466 		free_sr(sr);
3467 		return (TRUE);
3468 	}
3469 	res->value = FALSE;
3470 	if (mdiserror(ep, MDE_NO_SET))
3471 		mdclrerror(ep);
3472 
3473 	err = svc_fini(ep);
3474 
3475 	return (TRUE);
3476 }
3477 
3478 bool_t
3479 mdrpc_setnumbusy_1_svc(
3480 	mdrpc_setno_args	*args,
3481 	mdrpc_bool_res		*res,
3482 	struct svc_req		*rqstp		/* RPC stuff */
3483 )
3484 {
3485 	return (mdrpc_setnumbusy_common(args, res, rqstp));
3486 }
3487 
3488 bool_t
3489 mdrpc_setnumbusy_2_svc(
3490 	mdrpc_setno_2_args	*args,
3491 	mdrpc_bool_res		*res,
3492 	struct svc_req		*rqstp		/* RPC stuff */
3493 )
3494 {
3495 	switch (args->rev) {
3496 	    case MD_METAD_ARGS_REV_1:
3497 		return (mdrpc_setnumbusy_common(
3498 		    &args->mdrpc_setno_2_args_u.rev1, res, rqstp));
3499 	    default:
3500 		return (FALSE);
3501 	}
3502 }
3503 
3504 static void
3505 stimeout(
3506 	mdsetname_t	*sp,
3507 	mhd_mhiargs_t	*mhiargsp,
3508 	int		version,	/* RPC version of calling routine */
3509 	md_error_t	*ep
3510 )
3511 {
3512 	mddb_userreq_t		req;
3513 	md_set_record		*sr;
3514 
3515 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
3516 		return;
3517 
3518 	sr->sr_mhiargs = *mhiargsp;
3519 
3520 	(void) memset(&req, '\0', sizeof (req));
3521 
3522 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
3523 	/* Do MN operation if rpc version supports it and if a MN set */
3524 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
3525 		req.ur_size = sizeof (struct md_mnset_record);
3526 	} else {
3527 		req.ur_size = sizeof (*sr);
3528 	}
3529 	req.ur_data = (uintptr_t)sr;
3530 
3531 	/*
3532 	 * Cluster nodename support
3533 	 * Convert nodename -> nodeid
3534 	 * Don't do this for MN disksets since we've already stored
3535 	 * both the nodeid and name.
3536 	 */
3537 	if ((version == METAD_VERSION) ||
3538 	    ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr)))))
3539 		sdssc_cm_sr_nm2nid(sr);
3540 
3541 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
3542 		(void) mdstealerror(ep, &req.ur_mde);
3543 		return;
3544 	}
3545 
3546 	(void) memset(&req, '\0', sizeof (req));
3547 	METAD_SETUP_SR(MD_DB_COMMIT_ONE, sr->sr_selfid)
3548 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0)
3549 		(void) mdstealerror(ep, &req.ur_mde);
3550 
3551 	/*
3552 	 * Cluster nodename support
3553 	 * Convert nodeid -> nodename
3554 	 * Don't do this for MN disksets since we've already stored
3555 	 * both the nodeid and name.
3556 	 */
3557 	if ((version == METAD_VERSION) ||
3558 	    ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr)))))
3559 		sdssc_cm_sr_nid2nm(sr);
3560 
3561 	free_sr(sr);
3562 }
3563 
3564 /*
3565  * Set MH ioctl timeout values.
3566  */
3567 bool_t
3568 mdrpc_stimeout_common(
3569 	mdrpc_stimeout_args	*args,
3570 	mdrpc_generic_res	*res,
3571 	struct svc_req		*rqstp,		/* RPC stuff */
3572 	int			version		/* RPC version */
3573 )
3574 {
3575 	md_error_t		*ep = &res->status;
3576 	int			err;
3577 	int			op_mode = W_OK;
3578 
3579 	/* setup, check permissions */
3580 	(void) memset(res, 0, sizeof (*res));
3581 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3582 		return (FALSE);
3583 	else if (err != 0)
3584 		return (TRUE);
3585 
3586 	if (check_set_lock(op_mode, NULL, ep))
3587 		return (TRUE);
3588 
3589 	/* doit */
3590 	stimeout(args->sp, args->mhiargsp, version, ep);
3591 
3592 	err = svc_fini(ep);
3593 
3594 	return (TRUE);
3595 }
3596 
3597 bool_t
3598 mdrpc_stimeout_1_svc(
3599 	mdrpc_stimeout_args	*args,
3600 	mdrpc_generic_res	*res,
3601 	struct svc_req		*rqstp		/* RPC stuff */
3602 )
3603 {
3604 	/* Pass RPC version (METAD_VERSION) to common routine */
3605 	return (mdrpc_stimeout_common(args, res, rqstp, METAD_VERSION));
3606 }
3607 
3608 bool_t
3609 mdrpc_stimeout_2_svc(
3610 	mdrpc_stimeout_2_args	*args,
3611 	mdrpc_generic_res	*res,
3612 	struct svc_req		*rqstp		/* RPC stuff */
3613 )
3614 {
3615 	switch (args->rev) {
3616 	    case MD_METAD_ARGS_REV_1:
3617 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
3618 		return (mdrpc_stimeout_common(
3619 		    &args->mdrpc_stimeout_2_args_u.rev1, res,
3620 		    rqstp, METAD_VERSION_DEVID));
3621 	    default:
3622 		return (FALSE);
3623 	}
3624 }
3625 
3626 static void
3627 upd_dr_dbinfo(
3628 	mdsetname_t	*sp,
3629 	md_drive_desc	*dd,
3630 	md_error_t	*ep
3631 )
3632 {
3633 	mdsetname_t	*local_sp;
3634 	md_set_record	*sr;
3635 	md_drive_record	*dr;
3636 	md_drive_desc	*p;
3637 	mddrivename_t	*dn, *dn1;
3638 	ddi_devid_t	devid_remote = NULL;
3639 	ddi_devid_t	devid_local = NULL;
3640 	int		devid_same = -1;
3641 	side_t		sideno;
3642 	int		using_devid = 0;
3643 
3644 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
3645 		return;
3646 
3647 	metaflushsetname(local_sp);
3648 
3649 	if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
3650 		return;
3651 
3652 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
3653 		return;
3654 
3655 	if (dd->dd_dnp == NULL)
3656 		return;
3657 
3658 	/*
3659 	 * The system is either all devid or all
3660 	 * non-devid so we determine this by looking
3661 	 * at the first item in the list.
3662 	 *
3663 	 * For did disks, the dd_dnp->devid is a valid pointer which
3664 	 * points to a '' string of devid.  We need to check this
3665 	 * before set the using_devid.
3666 	 */
3667 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
3668 	    (!(MD_MNSET_REC(sr))))
3669 		using_devid = 1;
3670 
3671 	for (p = dd; p != NULL; p = p->dd_next) {
3672 		dn = p->dd_dnp;
3673 		devid_remote = NULL;
3674 
3675 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
3676 		    using_devid) {
3677 			/*
3678 			 * We have a devid so use it.
3679 			 */
3680 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
3681 		}
3682 
3683 		/* check to make sure using_devid agrees with reality... */
3684 		if ((using_devid == 1) && (devid_remote == NULL)) {
3685 			/* something went really wrong. Can't process */
3686 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
3687 			    mynode(), dn->cname, sp->setname);
3688 			return;
3689 		}
3690 
3691 		for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
3692 			devid_same = -1;
3693 
3694 			dn1 = metadrivename_withdrkey(local_sp, sideno,
3695 			    dr->dr_key, MD_BASICNAME_OK, ep);
3696 
3697 			if (dn1 == NULL) {
3698 				if (devid_remote)
3699 					devid_free(devid_remote);
3700 				goto out;
3701 			}
3702 
3703 			if (dn1->devid != NULL && using_devid) {
3704 				if (devid_str_decode(dn1->devid, &devid_local,
3705 				    NULL) == 0) {
3706 					devid_same = devid_compare(devid_remote,
3707 					    devid_local);
3708 					devid_free(devid_local);
3709 				}
3710 			}
3711 
3712 			if (using_devid && devid_same == 0)
3713 				break;
3714 
3715 			if (!using_devid &&
3716 			    strcmp(dn->cname, dn1->cname) == 0)
3717 				break;
3718 		}
3719 
3720 		if (dr) {
3721 			/* Adjust the fields in the copy */
3722 			dr->dr_dbcnt = p->dd_dbcnt;
3723 			dr->dr_dbsize = p->dd_dbsize;
3724 		}
3725 		if (devid_remote)
3726 			devid_free(devid_remote);
3727 	}
3728 
3729 
3730 out:
3731 	commitset(sr, FALSE, ep);
3732 	free_sr(sr);
3733 }
3734 
3735 /*
3736  * update the database count and size field of drive records.
3737  */
3738 bool_t
3739 mdrpc_upd_dr_dbinfo_common(
3740 	mdrpc_drives_2_args_r1	*args,
3741 	mdrpc_generic_res	*res,
3742 	struct svc_req		*rqstp		/* RPC stuff */
3743 )
3744 {
3745 	md_error_t		*ep = &res->status;
3746 	int			err;
3747 	int			op_mode = W_OK;
3748 
3749 	/* setup, check permissions */
3750 	(void) memset(res, 0, sizeof (*res));
3751 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3752 		return (FALSE);
3753 	else if (err != 0)
3754 		return (TRUE);
3755 
3756 	if (check_set_lock(op_mode, args->cl_sk, ep))
3757 		return (TRUE);
3758 
3759 	/* doit */
3760 	upd_dr_dbinfo(args->sp, args->drivedescs, ep);
3761 
3762 	err = svc_fini(ep);
3763 
3764 	return (TRUE);
3765 }
3766 
3767 /*
3768  * version 1 of the remote procedure. This procedure is called if the
3769  * client is running in version 1. We first convert version 1 arguments
3770  * into version 2 arguments and then call the common remote procedure.
3771  */
3772 bool_t
3773 mdrpc_upd_dr_dbinfo_1_svc(
3774 	mdrpc_drives_args	*args,
3775 	mdrpc_generic_res	*res,
3776 	struct svc_req		*rqstp		/* RPC stuff */
3777 )
3778 {
3779 	bool_t			retval;
3780 	mdrpc_drives_2_args_r1	v2_args;
3781 
3782 	/* allocate memory */
3783 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
3784 
3785 	/* build args */
3786 	v2_args.cl_sk = args->cl_sk;
3787 	v2_args.sp = args->sp;
3788 	/* convert v1 args to v2 (revision 1) args */
3789 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
3790 	v2_args.timestamp = args->timestamp;
3791 	v2_args.genid = args->genid;
3792 
3793 	retval = mdrpc_upd_dr_dbinfo_common(&v2_args, res, rqstp);
3794 
3795 	free_newdrvdesc(v2_args.drivedescs);
3796 
3797 	return (retval);
3798 }
3799 
3800 bool_t
3801 mdrpc_upd_dr_dbinfo_2_svc(
3802 	mdrpc_drives_2_args	*args,
3803 	mdrpc_generic_res	*res,
3804 	struct svc_req		*rqstp		/* RPC stuff */
3805 )
3806 {
3807 	switch (args->rev) {
3808 	    case MD_METAD_ARGS_REV_1:
3809 		return (mdrpc_upd_dr_dbinfo_common(
3810 		    &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
3811 	    default:
3812 		return (FALSE);
3813 	}
3814 }
3815 
3816 static void
3817 upd_dr_flags(
3818 	mdsetname_t	*sp,
3819 	md_drive_desc	*dd,
3820 	uint_t		new_flags,
3821 	md_error_t	*ep
3822 )
3823 {
3824 	mdsetname_t	*local_sp;
3825 	md_set_record	*sr;
3826 	md_drive_record	*dr;
3827 	md_drive_desc	*p;
3828 	mddrivename_t	*dn, *dn1;
3829 	ddi_devid_t	devid_remote = NULL;
3830 	ddi_devid_t	devid_local = NULL;
3831 	int		devid_same = -1;
3832 	side_t		sideno;
3833 	int		using_devid = 0;
3834 
3835 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
3836 		return;
3837 
3838 	metaflushsetname(local_sp);
3839 
3840 	if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
3841 		return;
3842 
3843 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
3844 		return;
3845 
3846 	if (dd->dd_dnp == NULL)
3847 		return;
3848 
3849 	/*
3850 	 * The system is either all devid or all
3851 	 * non-devid so we determine this by looking
3852 	 * at the first item in the list.
3853 	 *
3854 	 * For did disks, the dd_dnp->devid is a valid pointer which
3855 	 * points to a '' string of devid.  We need to check this
3856 	 * before set the using_devid.
3857 	 */
3858 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
3859 	    (!(MD_MNSET_REC(sr))))
3860 		using_devid = 1;
3861 
3862 	for (p = dd; p != NULL; p = p->dd_next) {
3863 		dn = p->dd_dnp;
3864 		devid_remote = NULL;
3865 
3866 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
3867 		    using_devid) {
3868 			/*
3869 			 * We have a devid so use it.
3870 			 */
3871 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
3872 		}
3873 
3874 		/* check to make sure using_devid agrees with reality... */
3875 		if ((using_devid == 1) && (devid_remote == NULL)) {
3876 			/* something went really wrong. Can't process */
3877 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
3878 			    mynode(), dn->cname, sp->setname);
3879 			return;
3880 		}
3881 
3882 		for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
3883 			devid_same = -1;
3884 
3885 			dn1 = metadrivename_withdrkey(local_sp, sideno,
3886 			    dr->dr_key, MD_BASICNAME_OK, ep);
3887 
3888 			if (dn1 == NULL) {
3889 				if (devid_remote)
3890 					devid_free(devid_remote);
3891 				goto out;
3892 			}
3893 
3894 			if (dn1->devid != NULL && using_devid) {
3895 				if (devid_str_decode(dn1->devid,
3896 				    &devid_local, NULL) == 0) {
3897 					devid_same = devid_compare(devid_remote,
3898 					    devid_local);
3899 					devid_free(devid_local);
3900 				}
3901 			}
3902 
3903 			if (using_devid && devid_same == 0)
3904 				break;
3905 
3906 			if (!using_devid &&
3907 			    strcmp(dn->cname, dn1->cname) == 0)
3908 				break;
3909 		}
3910 
3911 		if (dr)
3912 			dr->dr_flags = new_flags;
3913 		if (devid_remote)
3914 			devid_free(devid_remote);
3915 	}
3916 out:
3917 	commitset(sr, TRUE, ep);
3918 	free_sr(sr);
3919 }
3920 
3921 /*
3922  * update the database count and size field of drive records.
3923  */
3924 bool_t
3925 mdrpc_upd_dr_flags_common(
3926 	mdrpc_upd_dr_flags_2_args_r1	*args,
3927 	mdrpc_generic_res		*res,
3928 	struct svc_req			*rqstp		/* RPC stuff */
3929 )
3930 {
3931 	md_error_t		*ep = &res->status;
3932 	int			err;
3933 	int			op_mode = W_OK;
3934 
3935 	/* setup, check permissions */
3936 	(void) memset(res, 0, sizeof (*res));
3937 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3938 		return (FALSE);
3939 	else if (err != 0)
3940 		return (TRUE);
3941 
3942 	if (check_set_lock(op_mode, args->cl_sk, ep))
3943 		return (TRUE);
3944 
3945 	/* doit */
3946 	upd_dr_flags(args->sp, args->drivedescs, args->new_flags, ep);
3947 
3948 	err = svc_fini(ep);
3949 
3950 	return (TRUE);
3951 }
3952 
3953 /*
3954  * version 1 of the remote procedure. This procedure is called if the
3955  * client is running in version 1. We first convert version 1 arguments
3956  * into version 2 arguments and then call the common remote procedure.
3957  */
3958 bool_t
3959 mdrpc_upd_dr_flags_1_svc(
3960 	mdrpc_upd_dr_flags_args	*args,
3961 	mdrpc_generic_res	*res,
3962 	struct svc_req		*rqstp		/* RPC stuff */
3963 )
3964 {
3965 	bool_t				retval;
3966 	mdrpc_upd_dr_flags_2_args_r1	v2_args;
3967 
3968 	/* allocate memory */
3969 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
3970 
3971 	/* build args */
3972 	v2_args.cl_sk = args->cl_sk;
3973 	v2_args.sp = args->sp;
3974 	/* convert v1 args to v2 (revision 1) args */
3975 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
3976 	v2_args.new_flags = args->new_flags;
3977 
3978 	retval = mdrpc_upd_dr_flags_common(&v2_args, res, rqstp);
3979 
3980 	free_newdrvdesc(v2_args.drivedescs);
3981 
3982 	return (retval);
3983 }
3984 
3985 bool_t
3986 mdrpc_upd_dr_flags_2_svc(
3987 	mdrpc_upd_dr_flags_2_args	*args,
3988 	mdrpc_generic_res		*res,
3989 	struct svc_req			*rqstp		/* RPC stuff */
3990 )
3991 {
3992 	switch (args->rev) {
3993 	    case MD_METAD_ARGS_REV_1:
3994 		return (mdrpc_upd_dr_flags_common(
3995 		    &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp));
3996 	    default:
3997 		return (FALSE);
3998 	}
3999 }
4000 
4001 static void
4002 upd_sr_flags(
4003 	mdsetname_t	*sp,
4004 	uint_t		new_flags,
4005 	md_error_t	*ep
4006 )
4007 {
4008 	md_set_record	*sr;
4009 
4010 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
4011 		return;
4012 
4013 	sr->sr_flags = new_flags;
4014 	commitset(sr, TRUE, ep);
4015 	free_sr(sr);
4016 }
4017 
4018 /*
4019  * update the set record flags
4020  */
4021 bool_t
4022 mdrpc_upd_sr_flags_common(
4023 	mdrpc_upd_sr_flags_args	*args,
4024 	mdrpc_generic_res	*res,
4025 	struct svc_req		*rqstp		/* RPC stuff */
4026 )
4027 {
4028 	md_error_t		*ep = &res->status;
4029 	int			err;
4030 	int			op_mode = W_OK;
4031 
4032 	/* setup, check permissions */
4033 	(void) memset(res, 0, sizeof (*res));
4034 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4035 		return (FALSE);
4036 	else if (err != 0)
4037 		return (TRUE);
4038 
4039 	if (check_set_lock(op_mode, args->cl_sk, ep))
4040 		return (TRUE);
4041 
4042 	/* doit */
4043 	upd_sr_flags(args->sp, args->new_flags, ep);
4044 
4045 	err = svc_fini(ep);
4046 
4047 	return (TRUE);
4048 }
4049 
4050 bool_t
4051 mdrpc_upd_sr_flags_1_svc(
4052 	mdrpc_upd_sr_flags_args	*args,
4053 	mdrpc_generic_res	*res,
4054 	struct svc_req		*rqstp		/* RPC stuff */
4055 )
4056 {
4057 	return (mdrpc_upd_sr_flags_common(args, res, rqstp));
4058 }
4059 
4060 bool_t
4061 mdrpc_upd_sr_flags_2_svc(
4062 	mdrpc_upd_sr_flags_2_args	*args,
4063 	mdrpc_generic_res		*res,
4064 	struct svc_req			*rqstp		/* RPC stuff */
4065 )
4066 {
4067 	switch (args->rev) {
4068 	    case MD_METAD_ARGS_REV_1:
4069 		return (mdrpc_upd_sr_flags_common(
4070 		    &args->mdrpc_upd_sr_flags_2_args_u.rev1, res, rqstp));
4071 	    default:
4072 		return (FALSE);
4073 	}
4074 }
4075 
4076 /*
4077  * upd_nr_flags updates the node records stored in this node's local mddb
4078  * given a node desciptor list and an action.  upd_nr_flags then commits
4079  * the node records to the local mddb.
4080  *
4081  * nd - A linked list of node descriptors that describes the node records
4082  *	in this diskset on which the action applies.
4083  * flag_action: action to be taken on node records that match the nd list.
4084  *	flag_action can be:
4085  *		MD_NR_JOIN: set OWN flag in node records
4086  *		MD_NR_WITHDRAW: reset OWN flag in node records
4087  *		MD_NR_OK: reset ADD flags and set OK flag in node records
4088  *		MD_NR_SET: set node record flags based on flags stored in nd
4089  *
4090  * Typically, the JOIN, WITHDRAW and OK flag_actions are used when setting
4091  * all nodes in a diskset to JOIN (add first disk to set), WITHDRAW
4092  * (remove last disk from set) or OK (after addition of host to set).
4093  *
4094  * The SET flag_action is typically used when nodelist contains all nodes
4095  * in the diskset, but specific nodes have had flag changes.  An example of
4096  * this would be the join/withdraw of a specific node to/from the set.
4097  *
4098  * Ignore the MD_MN_NODE_RB_JOIN flag if set in node record flag.  This
4099  * flag is used by the client to recover in case of failure and should not
4100  * be set in the node record flags.
4101  */
4102 static void
4103 upd_nr_flags(
4104 	mdsetname_t	*sp,
4105 	md_mnnode_desc	*nd,
4106 	uint_t		flag_action,
4107 	md_error_t	*ep
4108 )
4109 {
4110 	mdsetname_t		*local_sp;
4111 	md_set_record		*sr;
4112 	md_mnset_record		*mnsr;
4113 	md_mnnode_desc		*ndp;
4114 	md_mnnode_record	*nrp;
4115 
4116 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
4117 		return;
4118 
4119 	metaflushsetname(local_sp);
4120 
4121 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
4122 		return;
4123 
4124 	if (!(MD_MNSET_REC(sr))) {
4125 		return;
4126 	}
4127 	mnsr = (struct md_mnset_record *)sr;
4128 
4129 	switch (flag_action) {
4130 	case MD_NR_JOIN:
4131 	case MD_NR_WITHDRAW:
4132 	case MD_NR_SET:
4133 	case MD_NR_OK:
4134 	case MD_NR_DEL:
4135 		break;
4136 	default:
4137 		return;
4138 	}
4139 
4140 	for (ndp = nd; ndp != NULL; ndp = ndp->nd_next) {
4141 		/* Find matching node record for given node descriptor */
4142 		for (nrp = mnsr->sr_nodechain; nrp != NULL;
4143 		    nrp = nrp->nr_next) {
4144 			if (ndp->nd_nodeid == nrp->nr_nodeid) {
4145 				switch (flag_action) {
4146 				case MD_NR_JOIN:
4147 					nrp->nr_flags |= MD_MN_NODE_OWN;
4148 					break;
4149 				case MD_NR_WITHDRAW:
4150 					nrp->nr_flags &= ~MD_MN_NODE_OWN;
4151 					break;
4152 				case MD_NR_OK:
4153 					nrp->nr_flags &=
4154 					    ~(MD_MN_NODE_ADD | MD_MN_NODE_DEL);
4155 					nrp->nr_flags |= MD_MN_NODE_OK;
4156 					break;
4157 				case MD_NR_DEL:
4158 					nrp->nr_flags &=
4159 					    ~(MD_MN_NODE_OK | MD_MN_NODE_ADD);
4160 					nrp->nr_flags |= MD_MN_NODE_DEL;
4161 					break;
4162 				case MD_NR_SET:
4163 					/* Do not set RB_JOIN flag */
4164 					nrp->nr_flags =
4165 					    ndp->nd_flags & ~MD_MN_NODE_RB_JOIN;
4166 					break;
4167 				}
4168 				break;
4169 			}
4170 		}
4171 	}
4172 out:
4173 	/* Don't increment set genid for node record flag update */
4174 	commitset(sr, FALSE, ep);
4175 	free_sr(sr);
4176 }
4177 
4178 /*
4179  * init/fini wrapper around upd_nr_flags
4180  */
4181 bool_t
4182 mdrpc_upd_nr_flags_common(
4183 	mdrpc_upd_nr_flags_args	*args,
4184 	mdrpc_generic_res	*res,
4185 	struct svc_req		*rqstp		/* RPC stuff */
4186 )
4187 {
4188 	md_error_t		*ep = &res->status;
4189 	int			err;
4190 	int			op_mode = W_OK;
4191 
4192 	/* setup, check permissions */
4193 	(void) memset(res, 0, sizeof (*res));
4194 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4195 		return (FALSE);
4196 	else if (err != 0)
4197 		return (TRUE);
4198 
4199 	/*
4200 	 * During reconfig, node record flags can be updated without
4201 	 * locking first.
4202 	 */
4203 	if (!(args->flags & MNSET_IN_RECONFIG)) {
4204 		if (check_set_lock(op_mode, args->cl_sk, ep))
4205 			return (TRUE);
4206 	}
4207 
4208 	/* doit */
4209 	upd_nr_flags(args->sp, args->nodedescs, args->flag_action, ep);
4210 
4211 	err = svc_fini(ep);
4212 
4213 	return (TRUE);
4214 }
4215 
4216 /*
4217  * update the node records using given flag action.
4218  */
4219 bool_t
4220 mdrpc_upd_nr_flags_2_svc(
4221 	mdrpc_upd_nr_flags_2_args	*args,
4222 	mdrpc_generic_res		*res,
4223 	struct svc_req			*rqstp		/* RPC stuff */
4224 )
4225 {
4226 	switch (args->rev) {
4227 	    case MD_METAD_ARGS_REV_1:
4228 		return (mdrpc_upd_nr_flags_common(
4229 		    &args->mdrpc_upd_nr_flags_2_args_u.rev1, res, rqstp));
4230 	    default:
4231 		return (FALSE);
4232 	}
4233 }
4234 
4235 void
4236 free_sk(md_setkey_t *skp)
4237 {
4238 	Free(skp->sk_setname);
4239 	Free(skp->sk_host);
4240 	Free(skp);
4241 }
4242 
4243 void
4244 del_sk(set_t setno)
4245 {
4246 	md_setkey_t	*skp;
4247 	md_setkey_t	*tskp;
4248 
4249 	for (skp = tskp = my_svc_sk; skp; tskp = skp, skp = skp->sk_next) {
4250 		if (setno == skp->sk_setno) {
4251 			if (skp == my_svc_sk)
4252 				my_svc_sk = skp->sk_next;
4253 			else
4254 				tskp->sk_next = skp->sk_next;
4255 
4256 			Free(skp->sk_setname);
4257 			Free(skp->sk_host);
4258 			Free(skp);
4259 			break;
4260 		}
4261 	}
4262 }
4263 
4264 md_setkey_t *
4265 dupsk(md_setkey_t *skp)
4266 {
4267 	md_setkey_t	*tskp;
4268 
4269 	tskp = Zalloc(sizeof (md_setkey_t));
4270 
4271 	*tskp = *skp;
4272 	tskp->sk_host = Strdup(skp->sk_host);
4273 	tskp->sk_setname = Strdup(skp->sk_setname);
4274 
4275 	return (tskp);
4276 }
4277 
4278 md_setkey_t *
4279 svc_get_setkey(set_t setno)
4280 {
4281 	md_setkey_t	*skp;
4282 
4283 	for (skp = my_svc_sk; skp != NULL; skp = skp->sk_next)
4284 		if (setno == skp->sk_setno)
4285 			return (dupsk(skp));
4286 	return (NULL);
4287 }
4288 
4289 void
4290 svc_set_setkey(md_setkey_t *svc_sk)
4291 {
4292 	md_setkey_t	*skp;
4293 
4294 	if (my_svc_sk == NULL) {
4295 		my_svc_sk = dupsk(svc_sk);
4296 		return;
4297 	}
4298 
4299 	for (skp = my_svc_sk; skp->sk_next != NULL; skp = skp->sk_next)
4300 		assert(svc_sk->sk_setno != skp->sk_setno);
4301 
4302 	skp->sk_next = dupsk(svc_sk);
4303 }
4304 
4305 /*
4306  * Unlock the set
4307  *
4308  * To unlock the set, the user must have the correct key, once this is verified
4309  * the set is unlocked and the cached information for the set is flushed.
4310  */
4311 bool_t
4312 mdrpc_unlock_set_common(
4313 	mdrpc_null_args		*args,
4314 	mdrpc_setlock_res	*res,
4315 	struct svc_req		*rqstp		/* RPC stuff */
4316 )
4317 {
4318 	md_error_t		*ep = &res->status;
4319 	int			err;
4320 	int			op_mode = W_OK;
4321 	md_setkey_t		*svc_skp;
4322 	md_set_desc		*sd;
4323 	mdsetname_t		*sp;
4324 	int			multi_node = 0;
4325 	md_error_t		xep = mdnullerror;
4326 
4327 	/* setup, check permissions */
4328 	(void) memset(res, 0, sizeof (*res));
4329 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4330 		return (FALSE);
4331 	else if (err != 0)
4332 		return (TRUE);
4333 
4334 	/*
4335 	 * Is diskset a MN diskset?
4336 	 * Don't set error from this check since unlock set can be
4337 	 * called after a set has been deleted.
4338 	 */
4339 	if (((sp = metasetnosetname(args->cl_sk->sk_setno, &xep)) != NULL) &&
4340 	    ((sd = metaget_setdesc(sp, &xep)) != NULL)) {
4341 		if ((MD_MNSET_DESC(sd))) {
4342 			multi_node = 1;
4343 		}
4344 	}
4345 
4346 	/* Get the set key, if any */
4347 	svc_skp = svc_get_setkey(args->cl_sk->sk_setno);
4348 
4349 	/* The set is locked */
4350 	if (svc_skp != NULL) {
4351 
4352 		/* Make sure the opener has the right key. */
4353 		if (args->cl_sk->sk_key.tv_sec != svc_skp->sk_key.tv_sec ||
4354 		    args->cl_sk->sk_key.tv_usec != svc_skp->sk_key.tv_usec) {
4355 			(void) mddserror(ep, MDE_DS_ULKSBADKEY,
4356 			    svc_skp->sk_setno, mynode(), svc_skp->sk_host,
4357 			    svc_skp->sk_setname);
4358 			free_sk(svc_skp);
4359 			return (TRUE);
4360 		}
4361 
4362 		/* Unlock the set */
4363 		del_sk(args->cl_sk->sk_setno);
4364 
4365 		/* Cleanup */
4366 		free_sk(svc_skp);
4367 
4368 		goto out;
4369 	}
4370 
4371 
4372 	/*
4373 	 * It is possible on a MN diskset to attempt to unlock a set that
4374 	 * is unlocked.  This could occur when the metaset or metadb  command
4375 	 * is failing due to another metaset or metadb command running.
4376 	 * So, print no warning for MN disksets.
4377 	 */
4378 	if (multi_node == 0) {
4379 		md_eprintf("Warning: set unlocked when unlock_set called!\n");
4380 	}
4381 
4382 out:
4383 	res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
4384 
4385 	/* Flush the set cache */
4386 	sr_cache_flush_setno(args->cl_sk->sk_setno);
4387 
4388 	return (TRUE);
4389 }
4390 
4391 bool_t
4392 mdrpc_unlock_set_1_svc(
4393 	mdrpc_null_args		*args,
4394 	mdrpc_setlock_res	*res,
4395 	struct svc_req		*rqstp		/* RPC stuff */
4396 )
4397 {
4398 	return (mdrpc_unlock_set_common(args, res, rqstp));
4399 }
4400 
4401 bool_t
4402 mdrpc_unlock_set_2_svc(
4403 	mdrpc_null_args		*args,
4404 	mdrpc_setlock_res	*res,
4405 	struct svc_req		*rqstp		/* RPC stuff */
4406 )
4407 {
4408 	return (mdrpc_unlock_set_common(args, res, rqstp));
4409 }
4410 
4411 /*
4412  * Lock the set
4413  *
4414  * If the user does not hand us a key, then we generate a new key and lock the
4415  * set using this new key that was generated, if the user hands us a key then
4416  * we use the key to lock the set.
4417  */
4418 bool_t
4419 mdrpc_lock_set_common(
4420 	mdrpc_null_args		*args,
4421 	mdrpc_setlock_res	*res,
4422 	struct svc_req		*rqstp		/* RPC stuff */
4423 )
4424 {
4425 	md_error_t		*ep = &res->status;
4426 	int			err;
4427 	md_error_t		xep = mdnullerror;
4428 	int			op_mode = W_OK;
4429 	md_setkey_t		*svc_skp;
4430 	md_setkey_t		new_sk;
4431 	md_set_desc		*sd = NULL;
4432 	mdsetname_t		*sp = NULL;
4433 
4434 	/* setup, check permissions */
4435 	(void) memset(res, 0, sizeof (*res));
4436 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4437 		return (FALSE);
4438 	else if (err != 0)
4439 		return (TRUE);
4440 
4441 	svc_skp = svc_get_setkey(args->cl_sk->sk_setno);
4442 
4443 	/* The set is locked */
4444 	if (svc_skp != NULL) {
4445 
4446 		/*
4447 		 * This lock request could be for a new diskset, as
4448 		 * such metasetnosetname() may not return anything
4449 		 * useful. Only call it if there is already a key.
4450 		 */
4451 		if ((sp = metasetnosetname(args->cl_sk->sk_setno, ep))
4452 		    != NULL) {
4453 			sd = metaget_setdesc(sp, ep);
4454 		}
4455 
4456 		/*
4457 		 * meta_lock() provides local locking for non-MN
4458 		 * disksets. The local lock is held before we call
4459 		 * this RPC function. We should not receive a lock
4460 		 * request from the host which owns the lock. If we
4461 		 * do, release the lock.
4462 		 */
4463 		if (!((sd != NULL) && (MD_MNSET_DESC(sd))) &&
4464 		    (strcmp(svc_skp->sk_host, args->cl_sk->sk_host) == 0)) {
4465 			md_eprintf(
4466 			    "Warning: set locked when lock_set called!\n");
4467 
4468 			md_eprintf("Held lock info:\n");
4469 
4470 			md_eprintf("\tLock:\n");
4471 			md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname);
4472 			md_eprintf("\t\tSetno:   %d\n", svc_skp->sk_setno);
4473 			md_eprintf("\t\tHost:    %s\n", svc_skp->sk_host);
4474 			md_eprintf("\t\tKey:     %d/%d %s\n",
4475 			    svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec,
4476 			    ctime((const time_t *)&svc_skp->sk_key.tv_sec));
4477 
4478 			/* Unlock set */
4479 			del_sk(svc_skp->sk_setno);
4480 			free_sk(svc_skp);
4481 			svc_skp = NULL;
4482 
4483 			md_eprintf("Released lock held by requesting host\n");
4484 		}
4485 	}
4486 
4487 	/* The set is unlocked */
4488 	if (svc_skp == NULL) {
4489 		/* If we have been given a key, use it. */
4490 		if (args->cl_sk->sk_key.tv_sec || args->cl_sk->sk_key.tv_usec) {
4491 			svc_set_setkey(args->cl_sk);
4492 			res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
4493 			goto out;
4494 		}
4495 
4496 		/* We need to lock it, with a new key */
4497 		new_sk = *args->cl_sk;
4498 		if (meta_gettimeofday(&new_sk.sk_key) == -1) {
4499 			(void) mdsyserror(ep, errno, "meta_gettimeofday()");
4500 			mde_perror(&xep, "");
4501 			md_exit(NULL, 1);
4502 		}
4503 		svc_set_setkey(&new_sk);
4504 
4505 		res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
4506 		goto out;
4507 	}
4508 
4509 	/*
4510 	 * If a MN diskset, the lock_set routine is used as a locking
4511 	 * mechanism to keep multiple metaset and/or metadb commads
4512 	 * from interfering with each other.  If two metaset/metadb
4513 	 * commands are issued at the same time - one will complete
4514 	 * and the other command will fail with MDE_DS_NOTNOW_CMD.
4515 	 */
4516 	if ((sd != NULL) && MD_MNSET_DESC(sd)) {
4517 		(void) mddserror(ep, MDE_DS_NOTNOW_CMD,
4518 		    svc_skp->sk_setno, mynode(),
4519 		    svc_skp->sk_host, svc_skp->sk_setname);
4520 		goto out;
4521 	}
4522 
4523 	md_eprintf("Warning: set locked when lock_set called!\n");
4524 
4525 	md_eprintf("Lock info:\n");
4526 
4527 	md_eprintf("\tLock(svc):\n");
4528 	md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname);
4529 	md_eprintf("\t\tSetno:   %d\n", svc_skp->sk_setno);
4530 	md_eprintf("\t\tHost:    %s\n", svc_skp->sk_host);
4531 	md_eprintf("\t\tKey:     %d/%d %s",
4532 	    svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec,
4533 	    ctime((const time_t *)&svc_skp->sk_key.tv_sec));
4534 
4535 	md_eprintf("\tLock(cl):\n");
4536 	md_eprintf("\t\tSetname: %s\n", args->cl_sk->sk_setname);
4537 	md_eprintf("\t\tSetno:   %d\n", args->cl_sk->sk_setno);
4538 	md_eprintf("\t\tHost:    %s\n", args->cl_sk->sk_host);
4539 	md_eprintf("\t\tKey:     %d/%d %s",
4540 	    args->cl_sk->sk_key.tv_sec, args->cl_sk->sk_key.tv_usec,
4541 	    ctime((const time_t *)&args->cl_sk->sk_key.tv_sec));
4542 
4543 	/* The set is locked, do we have the key? */
4544 	if (args->cl_sk->sk_key.tv_sec == svc_skp->sk_key.tv_sec &&
4545 	    args->cl_sk->sk_key.tv_usec == svc_skp->sk_key.tv_usec) {
4546 		res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
4547 		goto out;
4548 	}
4549 
4550 	/*
4551 	 * The set is locked and we do not have the key, so we set up an error.
4552 	 */
4553 	(void) mddserror(ep, MDE_DS_LKSBADKEY, svc_skp->sk_setno, mynode(),
4554 	    svc_skp->sk_host, args->cl_sk->sk_setname);
4555 
4556 out:
4557 	if (svc_skp != NULL)
4558 		free_sk(svc_skp);
4559 
4560 	/* Flush the set cache */
4561 	sr_cache_flush_setno(args->cl_sk->sk_setno);
4562 
4563 	return (TRUE);
4564 }
4565 
4566 bool_t
4567 mdrpc_lock_set_1_svc(
4568 	mdrpc_null_args		*args,
4569 	mdrpc_setlock_res	*res,
4570 	struct svc_req		*rqstp		/* RPC stuff */
4571 )
4572 {
4573 	return (mdrpc_lock_set_common(args, res, rqstp));
4574 }
4575 
4576 bool_t
4577 mdrpc_lock_set_2_svc(
4578 	mdrpc_null_args		*args,
4579 	mdrpc_setlock_res	*res,
4580 	struct svc_req		*rqstp		/* RPC stuff */
4581 )
4582 {
4583 	return (mdrpc_lock_set_common(args, res, rqstp));
4584 }
4585 
4586 static void
4587 updmeds(
4588 	char		*setname,
4589 	md_h_arr_t	*medp,
4590 	int		version,	/* RPC version of calling routine */
4591 	md_error_t	*ep
4592 )
4593 {
4594 	mddb_userreq_t		req;
4595 	md_set_record		*sr;
4596 	mddb_med_parm_t		mp;
4597 
4598 	if ((sr = getsetbyname(setname, ep)) == NULL)
4599 		return;
4600 
4601 	sr->sr_med = *medp;			/* structure assignment */
4602 
4603 	(void) memset(&req, '\0', sizeof (req));
4604 
4605 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
4606 	/* Do MN operation if rpc version supports it and if a MN set */
4607 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
4608 		req.ur_size = sizeof (struct md_mnset_record);
4609 	} else {
4610 		req.ur_size = sizeof (*sr);
4611 	}
4612 	req.ur_data = (uintptr_t)sr;
4613 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
4614 		(void) mdstealerror(ep, &req.ur_mde);
4615 		free_sr(sr);
4616 		return;
4617 	}
4618 
4619 	commitset(sr, TRUE, ep);
4620 
4621 	/*
4622 	 * If a MN disket, send the mediator list to the kernel.
4623 	 */
4624 	if (MD_MNSET_REC(sr)) {
4625 		(void) memset(&mp, '\0', sizeof (mddb_med_parm_t));
4626 		mp.med_setno = sr->sr_setno;
4627 		if (meta_h2hi(medp, &mp.med, ep)) {
4628 			free_sr(sr);
4629 			return;
4630 		}
4631 
4632 		/* Resolve the IP addresses for the host list */
4633 		if (meta_med_hnm2ip(&mp.med, ep)) {
4634 			free_sr(sr);
4635 			return;
4636 		}
4637 
4638 		/* If node not yet joined to set, failure is ok. */
4639 		if (metaioctl(MD_MED_SET_LST, &mp, &mp.med_mde, NULL) != 0) {
4640 			if (!mdismddberror(&mp.med_mde, MDE_DB_NOTOWNER)) {
4641 				(void) mdstealerror(ep, &mp.med_mde);
4642 			}
4643 		}
4644 	}
4645 	free_sr(sr);
4646 }
4647 
4648 /*
4649  * Update the mediator data in the set record
4650  */
4651 bool_t
4652 mdrpc_updmeds_common(
4653 	mdrpc_updmeds_args	*args,
4654 	mdrpc_generic_res	*res,
4655 	struct svc_req		*rqstp,		/* RPC stuff */
4656 	int			version		/* RPC version */
4657 )
4658 {
4659 	md_error_t		*ep = &res->status;
4660 	int			err;
4661 	int			op_mode = W_OK;
4662 
4663 	/* setup, check permissions */
4664 	(void) memset(res, 0, sizeof (*res));
4665 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4666 		return (FALSE);
4667 	else if (err != 0)
4668 		return (TRUE);
4669 
4670 	if (check_set_lock(op_mode, args->cl_sk, ep))
4671 		return (TRUE);
4672 
4673 	/* doit */
4674 	updmeds(args->sp->setname, &args->meds, version, ep);
4675 
4676 	err = svc_fini(ep);
4677 
4678 	return (TRUE);
4679 }
4680 
4681 bool_t
4682 mdrpc_updmeds_1_svc(
4683 	mdrpc_updmeds_args	*args,
4684 	mdrpc_generic_res	*res,
4685 	struct svc_req		*rqstp		/* RPC stuff */
4686 )
4687 {
4688 	/* Pass RPC version (METAD_VERSION) to common routine */
4689 	return (mdrpc_updmeds_common(args, res, rqstp, METAD_VERSION));
4690 }
4691 
4692 bool_t
4693 mdrpc_updmeds_2_svc(
4694 	mdrpc_updmeds_2_args	*args,
4695 	mdrpc_generic_res	*res,
4696 	struct svc_req		*rqstp		/* RPC stuff */
4697 )
4698 {
4699 	switch (args->rev) {
4700 	    case MD_METAD_ARGS_REV_1:
4701 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
4702 		return (mdrpc_updmeds_common(
4703 		    &args->mdrpc_updmeds_2_args_u.rev1, res,
4704 		    rqstp, METAD_VERSION_DEVID));
4705 	    default:
4706 		return (FALSE);
4707 	}
4708 }
4709 
4710 /*
4711  * Call routines to suspend, reinit and resume mdcommd.
4712  * Called during metaset and metadb command.
4713  * NOT called during reconfig cycle.
4714  */
4715 bool_t
4716 mdrpc_mdcommdctl_2_svc(
4717 	mdrpc_mdcommdctl_2_args	*args,
4718 	mdrpc_generic_res	*res,
4719 	struct svc_req		*rqstp		/* RPC stuff */
4720 )
4721 {
4722 	mdrpc_mdcommdctl_args	*args_cc;
4723 	md_error_t		*ep = &res->status;
4724 	int			err;
4725 	int			op_mode = R_OK;
4726 	int			suspend_ret;
4727 
4728 	switch (args->rev) {
4729 	    case MD_METAD_ARGS_REV_1:
4730 		/* setup, check permissions */
4731 		(void) memset(res, 0, sizeof (*res));
4732 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4733 			return (FALSE);
4734 		else if (err != 0)
4735 			return (TRUE);
4736 
4737 		args_cc = &(args->mdrpc_mdcommdctl_2_args_u.rev1);
4738 		switch (args_cc->flag_action) {
4739 			case COMMDCTL_SUSPEND:
4740 				suspend_ret = mdmn_suspend(args_cc->setno,
4741 				    args_cc->class);
4742 				if (suspend_ret != 0) {
4743 					(void) mddserror(ep, suspend_ret,
4744 					    args_cc->setno, mynode(),
4745 					    NULL, mynode());
4746 				}
4747 				break;
4748 			case COMMDCTL_RESUME:
4749 				if (mdmn_resume(args_cc->setno,
4750 				    args_cc->class, args_cc->flags)) {
4751 					(void) mddserror(ep,
4752 					    MDE_DS_COMMDCTL_RESUME_FAIL,
4753 					    args_cc->setno, mynode(),
4754 					    NULL, mynode());
4755 				}
4756 				break;
4757 			case COMMDCTL_REINIT:
4758 				if (mdmn_reinit_set(args_cc->setno)) {
4759 					(void) mddserror(ep,
4760 					    MDE_DS_COMMDCTL_REINIT_FAIL,
4761 					    args_cc->setno, mynode(),
4762 					    NULL, mynode());
4763 				}
4764 				break;
4765 		}
4766 		err = svc_fini(ep);
4767 		return (TRUE);
4768 
4769 	    default:
4770 		return (FALSE);
4771 	}
4772 }
4773 
4774 /*
4775  * Return TRUE if set is stale.
4776  */
4777 bool_t
4778 mdrpc_mn_is_stale_2_svc(
4779 	mdrpc_setno_2_args	*args,
4780 	mdrpc_bool_res		*res,
4781 	struct svc_req		*rqstp		/* RPC stuff */
4782 )
4783 {
4784 	md_error_t	*ep = &res->status;
4785 	mddb_config_t	c;
4786 	int		err;
4787 	int		op_mode = R_OK;
4788 
4789 	(void) memset(&c, 0, sizeof (c));
4790 	switch (args->rev) {
4791 	    case MD_METAD_ARGS_REV_1:
4792 		c.c_id = 0;
4793 		c.c_setno = args->mdrpc_setno_2_args_u.rev1.setno;
4794 
4795 		/* setup, check permissions */
4796 		(void) memset(res, 0, sizeof (*res));
4797 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4798 			return (FALSE);
4799 		else if (err != 0)
4800 			return (TRUE);
4801 
4802 		if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) {
4803 			mdstealerror(ep, &c.c_mde);
4804 			return (TRUE);
4805 		}
4806 
4807 		if (c.c_flags & MDDB_C_STALE) {
4808 			res->value = TRUE;
4809 		} else {
4810 			res->value = FALSE;
4811 		}
4812 
4813 		err = svc_fini(ep);
4814 		return (TRUE);
4815 
4816 	    default:
4817 		return (FALSE);
4818 	}
4819 }
4820 
4821 /*
4822  * Clear out all clnt_locks held by all MN disksets.
4823  * This is only used during a reconfig cycle.
4824  */
4825 /* ARGSUSED */
4826 int
4827 mdrpc_clr_mnsetlock_2_svc(
4828 	mdrpc_null_args		*args,
4829 	mdrpc_generic_res	*res,
4830 	struct svc_req		*rqstp		/* RPC stuff */
4831 )
4832 {
4833 	set_t			max_sets, setno;
4834 	md_error_t		*ep = &res->status;
4835 	int			err;
4836 	int			op_mode = W_OK;
4837 	mdsetname_t		*sp;
4838 
4839 	/* setup, check permissions */
4840 	(void) memset(res, 0, sizeof (*res));
4841 
4842 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4843 		return (FALSE);
4844 	else if (err != 0)
4845 		return (TRUE);
4846 
4847 	/*
4848 	 * Walk through all possible disksets.
4849 	 * For each MN set, delete all keys associated with that set.
4850 	 */
4851 	if ((max_sets = get_max_sets(ep)) == 0) {
4852 		return (TRUE);
4853 	}
4854 
4855 	/* start walking through all possible disksets */
4856 	for (setno = 1; setno < max_sets; setno++) {
4857 		if ((sp = metasetnosetname(setno, ep)) == NULL) {
4858 			if (mdiserror(ep, MDE_NO_SET)) {
4859 				/* No set for this setno - continue */
4860 				mdclrerror(ep);
4861 				continue;
4862 			} else {
4863 				mde_perror(ep, gettext(
4864 				    "Unable to get set %s information"),
4865 				    sp->setname);
4866 				mdclrerror(ep);
4867 				continue;
4868 			}
4869 		}
4870 
4871 		/* only check multi-node disksets */
4872 		if (!meta_is_mn_set(sp, ep)) {
4873 			mdclrerror(ep);
4874 			continue;
4875 		}
4876 
4877 		/* Delete keys associated with rpc.metad clnt_lock */
4878 		del_sk(setno);
4879 	}
4880 
4881 	*ep = mdnullerror;
4882 
4883 	err = svc_fini(ep);
4884 
4885 	return (TRUE);
4886 }
4887 
4888 /*
4889  * Get drive desc on this host for given setno.
4890  * This is only used during a reconfig cycle.
4891  * Returns a drive desc structure for the given mdsetname
4892  * from this host.
4893  *
4894  * Returned drive desc structure is partially filled in with
4895  * the drive name but is not filled in with any other strings
4896  * in the drivename structure.
4897  */
4898 bool_t
4899 mdrpc_getdrivedesc_2_svc(
4900 	mdrpc_sp_2_args		*args,
4901 	mdrpc_getdrivedesc_res 	*res,
4902 	struct svc_req		*rqstp		/* RPC stuff */
4903 )
4904 {
4905 	md_drive_desc		*dd;
4906 	md_error_t		*ep = &res->status;
4907 	int			err;
4908 	int			op_mode = R_OK;
4909 	mdsetname_t		*my_sp;
4910 	mdrpc_sp_args		*args_r1;
4911 
4912 	switch (args->rev) {
4913 	    case MD_METAD_ARGS_REV_1:
4914 		/* setup, check permissions */
4915 		(void) memset(res, 0, sizeof (*res));
4916 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4917 			return (FALSE);
4918 		else if (err != 0)
4919 			return (TRUE);
4920 
4921 		/* doit */
4922 		args_r1 = &args->mdrpc_sp_2_args_u.rev1;
4923 		if ((my_sp = metasetname(args_r1->sp->setname, ep)) == NULL)
4924 			return (TRUE);
4925 
4926 		dd = metaget_drivedesc(my_sp,
4927 			(MD_BASICNAME_OK | PRINT_FAST), ep);
4928 
4929 		res->dd = dd_list_dup(dd);
4930 
4931 		err = svc_fini(ep);
4932 
4933 		return (TRUE);
4934 	    default:
4935 		return (FALSE);
4936 	}
4937 }
4938 
4939 /*
4940  * Update drive records given list from master during reconfig.
4941  * Make this node's list match the master's list which may include
4942  * deleting a drive record that is known by this node and not known
4943  * by the master node.
4944  *
4945  * Sync up the set/node/drive record genids to match the genid
4946  * passed in the dd structure (all genids in this structure
4947  * are the same).
4948  */
4949 bool_t
4950 mdrpc_upd_dr_reconfig_common(
4951 	mdrpc_upd_dr_flags_2_args_r1	*args,
4952 	mdrpc_generic_res		*res,
4953 	struct svc_req			*rqstp		/* RPC stuff */
4954 )
4955 {
4956 	md_error_t		*ep = &res->status;
4957 	int			err;
4958 	mdsetname_t		*local_sp;
4959 	md_set_record		*sr;
4960 	md_mnset_record		*mnsr;
4961 	md_drive_record		*dr, *dr_placeholder = NULL;
4962 	md_drive_desc		*dd;
4963 	mddrivename_t		*dn, *dn1;
4964 	side_t			sideno;
4965 	md_mnnode_record	*nrp;
4966 	int			op_mode = W_OK;
4967 	int			change = 0;
4968 
4969 	/* setup, check permissions */
4970 	(void) memset(res, 0, sizeof (*res));
4971 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4972 		return (FALSE);
4973 	else if (err != 0)
4974 		return (TRUE);
4975 
4976 	if ((local_sp = metasetname(args->sp->setname, ep)) == NULL)
4977 		return (TRUE);
4978 
4979 	metaflushsetname(local_sp);
4980 
4981 	if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
4982 		return (TRUE);
4983 
4984 	if ((sr = getsetbyname(args->sp->setname, ep)) == NULL)
4985 		return (TRUE);
4986 
4987 	if (!(MD_MNSET_REC(sr))) {
4988 		free_sr(sr);
4989 		return (TRUE);
4990 	}
4991 
4992 	mnsr = (md_mnset_record *)sr;
4993 	/* Setup genid on set and node records */
4994 	if (args->drivedescs) {
4995 		if (mnsr->sr_genid != args->drivedescs->dd_genid) {
4996 			change = 1;
4997 			mnsr->sr_genid = args->drivedescs->dd_genid;
4998 		}
4999 		nrp = mnsr->sr_nodechain;
5000 		while (nrp) {
5001 			if (nrp->nr_genid != args->drivedescs->dd_genid) {
5002 				change = 1;
5003 				nrp->nr_genid = args->drivedescs->dd_genid;
5004 			}
5005 			nrp = nrp->nr_next;
5006 		}
5007 	}
5008 	for (dr = mnsr->sr_drivechain; dr; dr = dr->dr_next) {
5009 		dn1 = metadrivename_withdrkey(local_sp, sideno,
5010 		    dr->dr_key, (MD_BASICNAME_OK | PRINT_FAST), ep);
5011 		if (dn1 == NULL)
5012 			goto out;
5013 		for (dd = args->drivedescs; dd != NULL; dd = dd->dd_next) {
5014 			dn = dd->dd_dnp;
5015 			/* Found this node's drive rec to match dd */
5016 			if (strcmp(dn->cname, dn1->cname) == 0)
5017 				break;
5018 		}
5019 
5020 		/*
5021 		 * If drive found in master's list, make slave match master.
5022 		 * If drive not found in master's list, remove drive.
5023 		 */
5024 		if (dd) {
5025 			if ((dr->dr_flags != dd->dd_flags) ||
5026 			    (dr->dr_genid != dd->dd_genid)) {
5027 				change = 1;
5028 				dr->dr_flags = dd->dd_flags;
5029 				dr->dr_genid = dd->dd_genid;
5030 			}
5031 		} else {
5032 			/*
5033 			 * Delete entry from linked list.  Need to use
5034 			 * dr_placeholder so that dr->dr_next points to
5035 			 * the next drive record in the list.
5036 			 */
5037 			if (dr_placeholder == NULL) {
5038 				dr_placeholder =
5039 					Zalloc(sizeof (md_drive_record));
5040 			}
5041 			dr_placeholder->dr_next = dr->dr_next;
5042 			dr_placeholder->dr_key = dr->dr_key;
5043 			sr_del_drv(sr, dr->dr_selfid);
5044 			(void) del_sideno_sidenm(dr_placeholder->dr_key,
5045 				sideno, ep);
5046 			change = 1;
5047 			dr = dr_placeholder;
5048 		}
5049 	}
5050 out:
5051 	/* If incore records are correct, don't need to write to disk */
5052 	if (change) {
5053 		/* Don't increment the genid in commitset */
5054 		commitset(sr, FALSE, ep);
5055 	}
5056 	free_sr(sr);
5057 
5058 	err = svc_fini(ep);
5059 
5060 	if (dr_placeholder != NULL)
5061 		Free(dr_placeholder);
5062 
5063 	return (TRUE);
5064 }
5065 
5066 /*
5067  * Version 2 routine to update this node's drive records based on
5068  * list passed in from master node.
5069  */
5070 bool_t
5071 mdrpc_upd_dr_reconfig_2_svc(
5072 	mdrpc_upd_dr_flags_2_args	*args,
5073 	mdrpc_generic_res		*res,
5074 	struct svc_req			*rqstp		/* RPC stuff */
5075 )
5076 {
5077 	switch (args->rev) {
5078 	    case MD_METAD_ARGS_REV_1:
5079 		return (mdrpc_upd_dr_reconfig_common(
5080 		    &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp));
5081 	    default:
5082 		return (FALSE);
5083 	}
5084 }
5085 
5086 /*
5087  * reset mirror owner for mirrors owned by deleted
5088  * or withdrawn host(s).  Hosts being deleted or
5089  * withdrawn are designated by nodeid since host is
5090  * already deleted or withdrawn from set and may not
5091  * be able to translate between a nodename and a nodeid.
5092  * If an error occurs, ep will be set to that error information.
5093  */
5094 static void
5095 reset_mirror_owner(
5096 	char		*setname,
5097 	int		node_c,
5098 	int		*node_id,	/* Array of node ids */
5099 	md_error_t	*ep
5100 )
5101 {
5102 	mdsetname_t		*local_sp;
5103 	int			i;
5104 	mdnamelist_t		*devnlp = NULL;
5105 	mdnamelist_t		*p;
5106 	mdname_t		*devnp = NULL;
5107 	md_set_mmown_params_t	ownpar_p;
5108 	md_set_mmown_params_t	*ownpar = &ownpar_p;
5109 	char			*miscname;
5110 
5111 	if ((local_sp = metasetname(setname, ep)) == NULL)
5112 		return;
5113 
5114 	/* get a list of all the mirrors for current set */
5115 	if (meta_get_mirror_names(local_sp, &devnlp, 0, ep) < 0)
5116 		return;
5117 
5118 	/* for each mirror */
5119 	for (p = devnlp; (p != NULL); p = p->next) {
5120 		devnp = p->namep;
5121 
5122 		/*
5123 		 * we can only do these for mirrors so make sure we
5124 		 * really have a mirror device and not a softpartition
5125 		 * imitating one. meta_get_mirror_names seems to think
5126 		 * softparts on top of a mirror are mirrors!
5127 		 */
5128 		if ((miscname = metagetmiscname(devnp, ep)) == NULL)
5129 			goto out;
5130 		if (strcmp(miscname, MD_MIRROR) != 0)
5131 			continue;
5132 
5133 		(void) memset(ownpar, 0, sizeof (*ownpar));
5134 		ownpar->d.mnum = meta_getminor(devnp->dev);
5135 		MD_SETDRIVERNAME(ownpar, MD_MIRROR, local_sp->setno);
5136 
5137 		/* get the current owner id */
5138 		if (metaioctl(MD_MN_GET_MM_OWNER, ownpar, ep,
5139 		    "MD_MN_GET_MM_OWNER") != 0) {
5140 			mde_perror(ep, gettext(
5141 			    "Unable to get mirror owner for %s/%s"),
5142 			    local_sp->setname,
5143 			    get_mdname(local_sp, ownpar->d.mnum));
5144 			goto out;
5145 		}
5146 
5147 		if (ownpar->d.owner == MD_MN_MIRROR_UNOWNED) {
5148 			mdclrerror(ep);
5149 			continue;
5150 		}
5151 		/*
5152 		 * reset owner only if the current owner is
5153 		 * in the list of nodes being deleted.
5154 		 */
5155 		for (i = 0; i < node_c; i++) {
5156 			if (ownpar->d.owner == node_id[i]) {
5157 				if (meta_mn_change_owner(&ownpar,
5158 				    local_sp->setno, ownpar->d.mnum,
5159 				    MD_MN_MIRROR_UNOWNED,
5160 				    MD_MN_MM_ALLOW_CHANGE) == -1) {
5161 					mde_perror(ep, gettext(
5162 					    "Unable to reset mirror owner for"
5163 					    " %s/%s"), local_sp->setname,
5164 					    get_mdname(local_sp,
5165 						    ownpar->d.mnum));
5166 					goto out;
5167 				}
5168 				break;
5169 			}
5170 		}
5171 	}
5172 
5173 out:
5174 	/* cleanup */
5175 	metafreenamelist(devnlp);
5176 }
5177 
5178 /*
5179  * Wrapper routine for reset_mirror_owner.
5180  * Called when hosts are deleted or withdrawn
5181  * in order to reset any mirror owners that are needed.
5182  */
5183 bool_t
5184 mdrpc_reset_mirror_owner_common(
5185 	mdrpc_nodeid_args	*args,
5186 	mdrpc_generic_res	*res,
5187 	struct svc_req		*rqstp		/* RPC stuff */
5188 )
5189 {
5190 	md_error_t		*ep = &res->status;
5191 	int			err;
5192 	int			op_mode = W_OK;
5193 
5194 	/* setup, check permissions */
5195 	(void) memset(res, 0, sizeof (*res));
5196 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5197 		return (FALSE);
5198 	else if (err != 0)
5199 		return (TRUE);
5200 
5201 	if (check_set_lock(op_mode, args->cl_sk, ep))
5202 		return (TRUE);
5203 
5204 	/* doit */
5205 	reset_mirror_owner(args->sp->setname, args->nodeid.nodeid_len,
5206 	    args->nodeid.nodeid_val, ep);
5207 
5208 	err = svc_fini(ep);
5209 
5210 	return (TRUE);
5211 }
5212 
5213 /*
5214  * RPC service routine to reset the mirror owner for mirrors owned
5215  * by the given hosts.  Typically, the list of given hosts is a list
5216  * of nodes being deleted or withdrawn from a diskset.
5217  * The given hosts are designated by nodeid since host may
5218  * already be deleted or withdrawn from set and may not
5219  * be able to translate between a nodename and a nodeid.
5220  */
5221 bool_t
5222 mdrpc_reset_mirror_owner_2_svc(
5223 	mdrpc_nodeid_2_args	*args,
5224 	mdrpc_generic_res	*res,
5225 	struct svc_req		*rqstp		/* RPC stuff */
5226 )
5227 {
5228 	switch (args->rev) {
5229 	    case MD_METAD_ARGS_REV_1:
5230 		return (mdrpc_reset_mirror_owner_common(
5231 		    &args->mdrpc_nodeid_2_args_u.rev1, res,
5232 		    rqstp));
5233 	    default:
5234 		return (FALSE);
5235 	}
5236 }
5237 
5238 /*
5239  * Call routines to suspend and resume I/O for the given diskset(s).
5240  * Called during reconfig cycle.
5241  * Diskset of 0 represents all MN disksets.
5242  */
5243 bool_t
5244 mdrpc_mn_susp_res_io_2_svc(
5245 	mdrpc_mn_susp_res_io_2_args	*args,
5246 	mdrpc_generic_res		*res,
5247 	struct svc_req			*rqstp		/* RPC stuff */
5248 )
5249 {
5250 	mdrpc_mn_susp_res_io_args	*args_sr;
5251 	md_error_t			*ep = &res->status;
5252 	int				err;
5253 	int				op_mode = R_OK;
5254 
5255 	switch (args->rev) {
5256 	    case MD_METAD_ARGS_REV_1:
5257 		/* setup, check permissions */
5258 		(void) memset(res, 0, sizeof (*res));
5259 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5260 			return (FALSE);
5261 		else if (err != 0)
5262 			return (TRUE);
5263 
5264 		args_sr = &(args->mdrpc_mn_susp_res_io_2_args_u.rev1);
5265 		switch (args_sr->susp_res_cmd) {
5266 		case MN_SUSP_IO:
5267 			(void) (metaioctl(MD_MN_SUSPEND_SET,
5268 				&args_sr->susp_res_setno, ep, NULL));
5269 			break;
5270 		case MN_RES_IO:
5271 			(void) (metaioctl(MD_MN_RESUME_SET,
5272 				&args_sr->susp_res_setno, ep, NULL));
5273 			break;
5274 		}
5275 		err = svc_fini(ep);
5276 		return (TRUE);
5277 
5278 	    default:
5279 		return (FALSE);
5280 	}
5281 }
5282 
5283 /*
5284  * Resnarf a set after it has been imported
5285  */
5286 bool_t
5287 mdrpc_resnarf_set_2_svc(
5288 	mdrpc_setno_2_args	*args,
5289 	mdrpc_generic_res	*res,
5290 	struct svc_req		*rqstp		/* RPC stuff */
5291 )
5292 {
5293 	mdrpc_setno_args	*setno_args;
5294 	md_error_t		*ep = &res->status;
5295 	int			err;
5296 	int			op_mode = R_OK;
5297 
5298 	switch (args->rev) {
5299 	    case MD_METAD_ARGS_REV_1:
5300 		setno_args = &args->mdrpc_setno_2_args_u.rev1;
5301 		break;
5302 	    default:
5303 		return (FALSE);
5304 	}
5305 
5306 	(void) memset(res, 0, sizeof (*res));
5307 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5308 		return (FALSE);
5309 	else if (err != 0)
5310 		return (TRUE);
5311 
5312 	/* do it */
5313 	if (resnarf_set(setno_args->setno, ep) < 0)
5314 		return (FALSE);
5315 
5316 	err = svc_fini(ep);
5317 	return (TRUE);
5318 }
5319 
5320 /*
5321  * Creates a resync thread.
5322  * Always returns true.
5323  */
5324 bool_t
5325 mdrpc_mn_mirror_resync_all_2_svc(
5326 	mdrpc_setno_2_args	*args,
5327 	mdrpc_generic_res	*res,
5328 	struct svc_req		*rqstp		/* RPC stuff */
5329 )
5330 {
5331 	md_error_t		*ep = &res->status;
5332 	mdrpc_setno_args	*setno_args;
5333 	int			err;
5334 	int			op_mode = R_OK;
5335 
5336 	switch (args->rev) {
5337 	    case MD_METAD_ARGS_REV_1:
5338 		/* setup, check permissions */
5339 		(void) memset(res, 0, sizeof (*res));
5340 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5341 			return (FALSE);
5342 		else if (err != 0)
5343 			return (TRUE);
5344 		setno_args = &args->mdrpc_setno_2_args_u.rev1;
5345 
5346 		/*
5347 		 * Need to invoke a metasync on a node newly added to a set.
5348 		 */
5349 		meta_mn_mirror_resync_all(&(setno_args->setno));
5350 
5351 		err = svc_fini(ep);
5352 		return (TRUE);
5353 
5354 	    default:
5355 		return (FALSE);
5356 	}
5357 }
5358 
5359 /*
5360  * Updates ABR state for all softpartitions. Calls meta_mn_sp_update_abr(),
5361  * which forks a daemon process to perform this action.
5362  * Always returns true.
5363  */
5364 bool_t
5365 mdrpc_mn_sp_update_abr_2_svc(
5366 	mdrpc_setno_2_args	*args,
5367 	mdrpc_generic_res	*res,
5368 	struct svc_req		*rqstp		/* RPC stuff */
5369 )
5370 {
5371 	md_error_t		*ep = &res->status;
5372 	mdrpc_setno_args	*setno_args;
5373 	int			err;
5374 	int			op_mode = R_OK;
5375 
5376 	switch (args->rev) {
5377 	    case MD_METAD_ARGS_REV_1:
5378 		/* setup, check permissions */
5379 		(void) memset(res, 0, sizeof (*res));
5380 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5381 			return (FALSE);
5382 		else if (err != 0)
5383 			return (TRUE);
5384 		setno_args = &args->mdrpc_setno_2_args_u.rev1;
5385 
5386 		meta_mn_sp_update_abr(&(setno_args->setno));
5387 
5388 		err = svc_fini(ep);
5389 		return (TRUE);
5390 
5391 	    default:
5392 		return (FALSE);
5393 	}
5394 }
5395