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