xref: /titanic_41/usr/src/cmd/lvm/rpc.metad/metad_svc_subr.c (revision 890e8ff10cfc85bc7d33064a9a30c3e8477b4813)
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 	/* create the symlink */
1485 	if (symlink(stringbuf1, stringbuf2) == -1)
1486 		(void) mdsyserror(ep, errno, stringbuf2);
1487 
1488 	err = svc_fini(ep);
1489 
1490 	return (TRUE);
1491 }
1492 
1493 bool_t
1494 mdrpc_createset_1_svc(
1495 	mdrpc_createset_args	*args,
1496 	mdrpc_generic_res	*res,
1497 	struct svc_req		*rqstp		/* RPC stuff */
1498 )
1499 {
1500 	return (mdrpc_createset_common(args, res, rqstp));
1501 }
1502 
1503 bool_t
1504 mdrpc_createset_2_svc(
1505 	mdrpc_createset_2_args	*args,
1506 	mdrpc_generic_res	*res,
1507 	struct svc_req		*rqstp		/* RPC stuff */
1508 )
1509 {
1510 	switch (args->rev) {
1511 	    case MD_METAD_ARGS_REV_1:
1512 		return (mdrpc_createset_common(
1513 		    &args->mdrpc_createset_2_args_u.rev1, res, rqstp));
1514 	    default:
1515 		return (FALSE);
1516 	}
1517 }
1518 
1519 bool_t
1520 mdrpc_mncreateset_common(
1521 	mdrpc_mncreateset_args	*args,
1522 	mdrpc_generic_res	*res,
1523 	struct svc_req		*rqstp		/* RPC stuff */
1524 )
1525 {
1526 	md_error_t		*ep = &res->status;
1527 	char			stringbuf1[MAXPATHLEN];
1528 	char			stringbuf2[MAXPATHLEN];
1529 	int			err;
1530 	int			op_mode = W_OK;
1531 
1532 	/* setup, check permissions */
1533 	(void) memset(res, 0, sizeof (*res));
1534 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
1535 		return (FALSE);
1536 	else if (err != 0)
1537 		return (TRUE);
1538 
1539 	if (check_set_lock(op_mode, args->cl_sk, ep))
1540 		return (TRUE);
1541 
1542 	/* create the arguments for the symlink() and unlink() calls */
1543 	(void) snprintf(stringbuf2, sizeof (stringbuf2), "/dev/md/%s",
1544 	    args->sp->setname);
1545 	(void) snprintf(stringbuf1, sizeof (stringbuf1), "shared/%d",
1546 	    args->sp->setno);
1547 
1548 	/*
1549 	 * Since we already verified that the setname was OK, make sure to
1550 	 * cleanup before proceeding.
1551 	 */
1552 	if (unlink(stringbuf2) == -1) {
1553 		if (errno != ENOENT) {
1554 			(void) mdsyserror(ep, errno, stringbuf2);
1555 			return (TRUE);
1556 		}
1557 	}
1558 
1559 	/* create the set */
1560 	mncreateset(args->sp, args->nodelist, args->timestamp, args->genid,
1561 		    args->master_nodenm, args->master_nodeid, ep);
1562 
1563 	if (! mdisok(ep)) {
1564 		return (TRUE);
1565 	}
1566 
1567 	/* create the symlink */
1568 	if (symlink(stringbuf1, stringbuf2) == -1)
1569 		(void) mdsyserror(ep, errno, stringbuf2);
1570 
1571 	err = svc_fini(ep);
1572 
1573 	return (TRUE);
1574 }
1575 
1576 bool_t
1577 mdrpc_mncreateset_2_svc(
1578 	mdrpc_mncreateset_2_args	*args,
1579 	mdrpc_generic_res	*res,
1580 	struct svc_req		*rqstp		/* RPC stuff */
1581 )
1582 {
1583 	switch (args->rev) {
1584 	    case MD_METAD_ARGS_REV_1:
1585 		return (mdrpc_mncreateset_common(
1586 		    &args->mdrpc_mncreateset_2_args_u.rev1, res, rqstp));
1587 	    default:
1588 		return (FALSE);
1589 	}
1590 }
1591 
1592 static void
1593 del_drv_sidenms(
1594 	mdsetname_t	*sp,
1595 	int		version,	/* RPC version of calling routine */
1596 	md_error_t	*ep
1597 )
1598 {
1599 	md_set_record	*sr;
1600 	md_drive_desc	*dd, *p;
1601 	mddrivename_t	*dn;
1602 	mdsetname_t	*local_sp;
1603 	int		i;
1604 	int		rb_mode = 0;
1605 
1606 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
1607 		return;
1608 
1609 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
1610 		return;
1611 
1612 	/* Do MN operation if rpc version supports it and if a MN set */
1613 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
1614 		/*
1615 		 * In the multi-node diskset, there are no diskset
1616 		 * entries in the local set for other nodes, so there's
1617 		 * nothing to do.
1618 		 */
1619 		free_sr(sr);
1620 		return;
1621 	}
1622 
1623 	if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
1624 	    ep)) == NULL) {
1625 		if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE)) {
1626 			metaflushsetname(sp);
1627 			if (! mdisok(ep)) {
1628 				free_sr(sr);
1629 				return;
1630 			}
1631 			/* we are supposed to have drives!!!! */
1632 			assert(0);
1633 		}
1634 		rb_mode = 1;
1635 		mdclrerror(ep);
1636 		for (i = 0; i < MD_MAXSIDES; i++) {
1637 			/* Skip empty sides of the diskset */
1638 			if (sr->sr_nodes[i][0] == '\0')
1639 				continue;
1640 			dd = metaget_drivedesc_sideno(sp, i,
1641 			    (MD_BASICNAME_OK | PRINT_FAST), ep);
1642 			/* Got dd, get out of loop */
1643 			if (dd != NULL)
1644 				break;
1645 
1646 			/* some error occurred, get out of loop */
1647 			if (! mdisok(ep))
1648 				break;
1649 		}
1650 		/*
1651 		 * At this point, we have one of three possibilities:
1652 		 *	1) dd != NULL (we have found drives using an alternate
1653 		 *	   side.)
1654 		 *	2) dd == NULL (no drives) && mdisok(ep) : assert(0)
1655 		 *	3) dd == NULL (no drives) && ! mdisok(ep) : return
1656 		 *	   error information to caller.
1657 		 */
1658 		if (dd == NULL) {
1659 			metaflushsetname(sp);
1660 			if (! mdisok(ep)) {
1661 				free_sr(sr);
1662 				return;
1663 			}
1664 			/* we are supposed to have drives!!!! */
1665 			assert(0);
1666 		}
1667 	}
1668 
1669 	/*
1670 	 * Let's run through each drive descriptor, and delete the
1671 	 * sidename for all sides that are not in the sr_nodes array.
1672 	 * We will ignore errors, cause the empty side may not
1673 	 * have had any names to begin with.
1674 	 */
1675 	for (p = dd; p != NULL; p = p->dd_next) {
1676 		dn = p->dd_dnp;
1677 
1678 		for (i = 0; i < MD_MAXSIDES; i++) {
1679 			/* Skip existing sides of the diskset */
1680 			if (!rb_mode && sr->sr_nodes[i][0] != '\0')
1681 				continue;
1682 			/* An empty side, delete the sidename */
1683 			if (del_name(local_sp, i+SKEW,
1684 			    dn->side_names_key, ep)) {
1685 				if (!mdissyserror(ep, ENOENT)) {
1686 					free_sr(sr);
1687 					return;
1688 				}
1689 				mdclrerror(ep);
1690 			}
1691 		}
1692 	}
1693 	free_sr(sr);
1694 	metaflushsetname(sp);
1695 }
1696 
1697 /*
1698  * delete 1 or more sidenames per drive desc, from the local namespace
1699  */
1700 bool_t
1701 mdrpc_del_drv_sidenms_common(
1702 	mdrpc_sp_args		*args,
1703 	mdrpc_generic_res	*res,
1704 	struct svc_req		*rqstp,		/* RPC stuff */
1705 	int			version		/* RPC version */
1706 )
1707 {
1708 	md_error_t		*ep = &res->status;
1709 	int			err;
1710 	int			op_mode = W_OK;
1711 
1712 	/* setup, check permissions */
1713 	(void) memset(res, 0, sizeof (*res));
1714 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
1715 		return (FALSE);
1716 	else if (err != 0)
1717 		return (TRUE);
1718 
1719 	if (check_set_lock(op_mode, args->cl_sk, ep))
1720 		return (TRUE);
1721 
1722 	/* doit */
1723 	del_drv_sidenms(args->sp, version, ep);
1724 
1725 	err = svc_fini(ep);
1726 
1727 	return (TRUE);
1728 }
1729 
1730 bool_t
1731 mdrpc_del_drv_sidenms_1_svc(
1732 	mdrpc_sp_args		*args,
1733 	mdrpc_generic_res	*res,
1734 	struct svc_req		*rqstp		/* RPC stuff */
1735 )
1736 {
1737 	/* Pass RPC version (METAD_VERSION) to common routine */
1738 	return (mdrpc_del_drv_sidenms_common(args, res, rqstp, METAD_VERSION));
1739 }
1740 
1741 bool_t
1742 mdrpc_del_drv_sidenms_2_svc(
1743 	mdrpc_sp_2_args		*args,
1744 	mdrpc_generic_res	*res,
1745 	struct svc_req		*rqstp		/* RPC stuff */
1746 )
1747 {
1748 	switch (args->rev) {
1749 	    case MD_METAD_ARGS_REV_1:
1750 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
1751 		return (mdrpc_del_drv_sidenms_common(
1752 		    &args->mdrpc_sp_2_args_u.rev1, res,
1753 		    rqstp, METAD_VERSION_DEVID));
1754 	    default:
1755 		return (FALSE);
1756 	}
1757 }
1758 
1759 static int
1760 del_sidenamelist(
1761 	md_set_record	*sr,
1762 	mddrivename_t	*dn,
1763 	md_error_t	*ep
1764 )
1765 {
1766 	mdsidenames_t	*sn;
1767 	mdsetname_t	*local_sp;
1768 	md_mnset_record	*mnsr;
1769 	md_mnnode_record *nr;
1770 
1771 	if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL)
1772 		return (-1);
1773 
1774 	for (sn = dn->side_names; sn != NULL; sn = sn->next)
1775 		if (MD_MNSET_REC(sr)) {
1776 			mnsr = (struct md_mnset_record *)sr;
1777 			/*
1778 			 * Only delete side name entries for this node
1779 			 * on a multi-node diskset.
1780 			 */
1781 			nr = mnsr->sr_nodechain;
1782 			while (nr) {
1783 				if (nr->nr_nodeid == sn->sideno) {
1784 					if (del_name(local_sp, sn->sideno,
1785 					    dn->side_names_key, ep) == -1)
1786 						mdclrerror(ep); /* ignore err */
1787 					break;
1788 				}
1789 				nr = nr->nr_next;
1790 			}
1791 		} else {
1792 			if (del_name(local_sp, sn->sideno+SKEW,
1793 			    dn->side_names_key, ep) == -1)
1794 				mdclrerror(ep);	/* ignore errors */
1795 		}
1796 
1797 	dn->side_names_key = MD_KEYBAD;
1798 	return (0);
1799 }
1800 
1801 static void
1802 deldrvs(
1803 	char		*setname,
1804 	md_drive_desc	*dd,
1805 	md_error_t	*ep
1806 )
1807 {
1808 	mdsetname_t	*sp;
1809 	md_set_record	*sr;
1810 	md_drive_record	*dr;
1811 	mddb_userreq_t	req;
1812 	md_drive_desc	*p;
1813 	mddrivename_t	*dn, *dn1;
1814 	side_t		sideno;
1815 	int		i;
1816 	int		rb_mode = 0;
1817 	mdname_t	*np;
1818 	md_dev64_t	dev;
1819 	md_error_t	xep = mdnullerror;
1820 	ddi_devid_t	devid_remote = NULL;
1821 	ddi_devid_t	devid_local = NULL;
1822 	int		devid_same = -1;
1823 	int		using_devid = 0;
1824 	md_mnnode_record	*nr;
1825 	md_mnset_record		*mnsr;
1826 
1827 	if ((sp = metasetname(setname, ep)) == NULL)
1828 		return;
1829 
1830 	metaflushsetname(sp);
1831 
1832 	if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD) {
1833 		if (! mdisdserror(ep, MDE_DS_HOSTNOSIDE))
1834 			return;
1835 		mdclrerror(ep);
1836 		/*
1837 		 * The set record is incomplete, so we need to make note
1838 		 * here so that we can do some special handling later.
1839 		 */
1840 		rb_mode = 1;
1841 	}
1842 
1843 	if ((sr = getsetbyname(setname, ep)) == NULL)
1844 		return;
1845 
1846 	if (dd->dd_dnp == NULL)
1847 		return;
1848 
1849 	/*
1850 	 * The system is either all devid or all
1851 	 * non-devid so we determine this by looking
1852 	 * at the first item in the list.
1853 	 *
1854 	 * For did disks, the dd_dnp->devid is a valid pointer which
1855 	 * points to a '' string of devid.  We need to check this
1856 	 * before set the using_devid.
1857 	 */
1858 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
1859 	    (!(MD_MNSET_REC(sr))))
1860 		using_devid = 1;
1861 
1862 	for (p = dd; p != NULL; p = p->dd_next) {
1863 		dn = p->dd_dnp;
1864 		devid_remote = NULL;
1865 
1866 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
1867 		    using_devid) {
1868 			/*
1869 			 * We have a devid so use it
1870 			 */
1871 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
1872 		}
1873 
1874 		/* check to make sure using_devid agrees with reality... */
1875 		if ((using_devid == 1) && (devid_remote == NULL)) {
1876 			/* something went really wrong. Can't process */
1877 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
1878 			    mynode(), dn->cname, sp->setname);
1879 			return;
1880 		}
1881 
1882 		for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
1883 			devid_same = -1;
1884 
1885 			if (! rb_mode) {
1886 				dn1 = metadrivename_withdrkey(sp, sideno,
1887 				    dr->dr_key, MD_BASICNAME_OK, ep);
1888 				if (dn1 == NULL) {
1889 					free_sr(sr);
1890 					if (devid_remote)
1891 						devid_free(devid_remote);
1892 					return;
1893 				}
1894 			} else {
1895 				/*
1896 				 * Handle special case here where sidenames
1897 				 * from other hosts for this drive may be
1898 				 * in the local mddb, but there is no
1899 				 * sidename entry for this host for this drive.
1900 				 * This could have happened if the node
1901 				 * panic'd between the 2 operations when
1902 				 * adding this node to the set.
1903 				 * So, delete all sidename entries for this
1904 				 * drive.
1905 				 */
1906 				if (MD_MNSET_REC(sr)) {
1907 					mnsr = (struct md_mnset_record *)sr;
1908 					nr = mnsr->sr_nodechain;
1909 					while (nr) {
1910 						/* We delete all dr sides */
1911 						dn1 = metadrivename_withdrkey(
1912 						    sp, nr->nr_nodeid,
1913 						    dr->dr_key,
1914 						    MD_BASICNAME_OK, ep);
1915 
1916 						/* if we do, get out of loop */
1917 						if (dn1 != NULL)
1918 							break;
1919 
1920 						/* save error for later */
1921 						(void) mdstealerror(&xep, ep);
1922 
1923 						mdclrerror(ep);
1924 
1925 						nr = nr->nr_next;
1926 					}
1927 				} else {
1928 					/*
1929 					 * Handle special case here
1930 					 * for traditional diskset
1931 					 */
1932 					for (i = 0; i < MD_MAXSIDES; i++) {
1933 						/* We delete all dr sides */
1934 						dn1 = metadrivename_withdrkey(
1935 						    sp, i, dr->dr_key,
1936 						    MD_BASICNAME_OK, ep);
1937 
1938 						/* if we do, get out of loop */
1939 						if (dn1 != NULL)
1940 							break;
1941 
1942 						/* save error for later */
1943 						(void) mdstealerror(&xep, ep);
1944 
1945 						mdclrerror(ep);
1946 					}
1947 				}
1948 
1949 				if (dn1 == NULL) {
1950 					(void) mdstealerror(ep, &xep);
1951 					free_sr(sr);
1952 					if (devid_remote)
1953 						devid_free(devid_remote);
1954 					return;
1955 				}
1956 
1957 				if (!using_devid)
1958 					mdclrerror(ep);
1959 			}
1960 
1961 			if (dn1->devid != NULL && using_devid) {
1962 				if (devid_str_decode(dn1->devid, &devid_local,
1963 				    NULL) == 0) {
1964 					devid_same = devid_compare(devid_remote,
1965 					    devid_local);
1966 					devid_free(devid_local);
1967 				}
1968 			}
1969 
1970 			/*
1971 			 * Has the required disk been found - either the devids
1972 			 * match if devid are being used or the actual name of
1973 			 * the disk matches.
1974 			 */
1975 			if ((using_devid && devid_same == 0) ||
1976 			    (!using_devid &&
1977 			    strcmp(dn->cname, dn1->cname) == 0)) {
1978 				uint_t	rep_slice;
1979 
1980 				dev = NODEV64;
1981 				np = NULL;
1982 				if (meta_replicaslice(dn1,
1983 				    &rep_slice, &xep) == 0) {
1984 					np = metaslicename(dn1,
1985 					    rep_slice, &xep);
1986 				}
1987 
1988 				if (np != NULL)
1989 					dev = np->dev;
1990 				else
1991 					mdclrerror(&xep);
1992 				break;
1993 			}
1994 		}
1995 
1996 		if (dr) {
1997 			(void) memset(&req, 0, sizeof (req));
1998 			METAD_SETUP_DR(MD_DB_DELETE, dr->dr_selfid)
1999 			if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL)
2000 			    != 0) {
2001 				(void) mdstealerror(ep, &req.ur_mde);
2002 				if (devid_remote)
2003 					devid_free(devid_remote);
2004 				free_sr(sr);
2005 				return;
2006 			}
2007 
2008 			dr_cache_del(sr, dr->dr_selfid);
2009 
2010 			if (del_sidenamelist(sr, dn1, ep) == -1) {
2011 				goto out;
2012 			}
2013 
2014 			SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE, SVM_TAG_DRIVE,
2015 			    sr->sr_setno, dev);
2016 			SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_ADD, SVM_TAG_DRIVE,
2017 			    MD_LOCAL_SET, dev);
2018 
2019 			continue;
2020 		}
2021 
2022 		if (devid_remote)
2023 			devid_free(devid_remote);
2024 	}
2025 
2026 out:
2027 	commitset(sr, TRUE, ep);
2028 
2029 	free_sr(sr);
2030 }
2031 
2032 /*
2033  * delete 1 or more drive records from a host.
2034  */
2035 bool_t
2036 mdrpc_deldrvs_common(
2037 	mdrpc_drives_2_args_r1	*args,
2038 	mdrpc_generic_res	*res,
2039 	struct svc_req		*rqstp		/* RPC stuff */
2040 )
2041 {
2042 	md_error_t		*ep = &res->status;
2043 	int			err;
2044 	int			op_mode = W_OK;
2045 
2046 	/* setup, check permissions */
2047 	(void) memset(res, 0, sizeof (*res));
2048 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2049 		return (FALSE);
2050 	else if (err != 0)
2051 		return (TRUE);
2052 
2053 	if (check_set_lock(op_mode, args->cl_sk, ep))
2054 		return (TRUE);
2055 
2056 	/* doit */
2057 	deldrvs(args->sp->setname, args->drivedescs, ep);
2058 
2059 	err = svc_fini(ep);
2060 
2061 	return (TRUE);
2062 }
2063 
2064 /*
2065  * version 1 of the remote procedure. This procedure is called if the
2066  * client is running in version 1. We first convert version 1 arguments
2067  * into version 2 arguments and then call the common remote procedure.
2068  */
2069 bool_t
2070 mdrpc_deldrvs_1_svc(
2071 	mdrpc_drives_args	*args,
2072 	mdrpc_generic_res	*res,
2073 	struct svc_req		*rqstp		/* RPC stuff */
2074 )
2075 {
2076 	bool_t			retval;
2077 	mdrpc_drives_2_args_r1	v2_args;
2078 
2079 	/* allocate memory */
2080 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
2081 
2082 	/* build args */
2083 	v2_args.cl_sk = args->cl_sk;
2084 	v2_args.sp = args->sp;
2085 	/* convert v1 args to v2 (revision 1) args */
2086 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
2087 	v2_args.timestamp = args->timestamp;
2088 	v2_args.genid = args->genid;
2089 
2090 	retval = mdrpc_deldrvs_common(&v2_args, res, rqstp);
2091 
2092 	free_newdrvdesc(v2_args.drivedescs);
2093 
2094 	return (retval);
2095 }
2096 
2097 bool_t
2098 mdrpc_deldrvs_2_svc(
2099 	mdrpc_drives_2_args	*args,
2100 	mdrpc_generic_res	*res,
2101 	struct svc_req		*rqstp		/* RPC stuff */
2102 )
2103 {
2104 	switch (args->rev) {
2105 	    case MD_METAD_ARGS_REV_1:
2106 		return (mdrpc_deldrvs_common(
2107 		    &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
2108 	    default:
2109 		return (FALSE);
2110 	}
2111 }
2112 
2113 static void
2114 delhosts(
2115 	char		*setname,
2116 	int		node_c,
2117 	char		**node_v,
2118 	int		version,	/* RPC version of calling routine */
2119 	md_error_t	*ep
2120 )
2121 {
2122 	mddb_userreq_t		req;
2123 	md_set_record		*sr;
2124 	int			i, j;
2125 	md_mnset_record		*mnsr;
2126 	md_mnnode_record	*nr;
2127 
2128 	if ((sr = getsetbyname(setname, ep)) == NULL)
2129 		return;
2130 
2131 	for (i = 0; i < node_c; i++) {
2132 		/* Do MN operation if rpc version supports it and if a MN set */
2133 		if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
2134 			mnsr = (struct md_mnset_record *)sr;
2135 			nr = mnsr->sr_nodechain;
2136 			while (nr) {
2137 				if (strcmp(nr->nr_nodename, node_v[i]) == 0) {
2138 					SE_NOTIFY(EC_SVM_CONFIG,
2139 						ESC_SVM_REMOVE, SVM_TAG_HOST,
2140 						sr->sr_setno, nr->nr_nodeid);
2141 					(void) memset(&req, '\0', sizeof (req));
2142 					METAD_SETUP_NR(MD_DB_DELETE,
2143 					    nr->nr_selfid);
2144 					if (metaioctl(MD_DB_USERREQ, &req,
2145 					    &req.ur_mde, NULL) != 0) {
2146 						(void) mdstealerror(ep,
2147 						    &req.ur_mde);
2148 						free_sr(sr);
2149 						return;
2150 					}
2151 					mnnr_cache_del(mnsr, nr->nr_selfid);
2152 					break;
2153 				}
2154 				nr = nr->nr_next;
2155 			}
2156 		} else {
2157 			for (j = 0; j < MD_MAXSIDES; j++) {
2158 				if (sr->sr_nodes[j][0] == '\0')
2159 					continue;
2160 				if (strcmp(sr->sr_nodes[j], node_v[i]) != 0)
2161 					continue;
2162 				(void) memset(sr->sr_nodes[j], '\0',
2163 				    sizeof (sr->sr_nodes[j]));
2164 				SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE,
2165 				    SVM_TAG_HOST, sr->sr_setno, j);
2166 				break;
2167 			}
2168 		}
2169 	}
2170 
2171 	(void) memset(&req, '\0', sizeof (req));
2172 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
2173 	/* Do MN operation if rpc version supports it and if a MN set */
2174 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
2175 		req.ur_size = sizeof (*mnsr);
2176 	} else {
2177 		req.ur_size = sizeof (*sr);
2178 	}
2179 	req.ur_data = (uintptr_t)sr;
2180 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
2181 		(void) mdstealerror(ep, &req.ur_mde);
2182 		free_sr(sr);
2183 		return;
2184 	}
2185 
2186 	commitset(sr, TRUE, ep);
2187 	free_sr(sr);
2188 }
2189 
2190 /*
2191  * delete 1 or more a hosts from a set.
2192  */
2193 bool_t
2194 mdrpc_delhosts_common(
2195 	mdrpc_host_args		*args,
2196 	mdrpc_generic_res	*res,
2197 	struct svc_req		*rqstp,		/* RPC stuff */
2198 	int			version		/* RPC version */
2199 )
2200 {
2201 	md_error_t		*ep = &res->status;
2202 	int			err;
2203 	int			op_mode = W_OK;
2204 
2205 	/* setup, check permissions */
2206 	(void) memset(res, 0, sizeof (*res));
2207 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2208 		return (FALSE);
2209 	else if (err != 0)
2210 		return (TRUE);
2211 
2212 	if (check_set_lock(op_mode, args->cl_sk, ep))
2213 		return (TRUE);
2214 
2215 	/* doit */
2216 	delhosts(args->sp->setname, args->hosts.hosts_len,
2217 	    args->hosts.hosts_val, version, ep);
2218 
2219 	err = svc_fini(ep);
2220 
2221 	return (TRUE);
2222 }
2223 
2224 bool_t
2225 mdrpc_delhosts_1_svc(
2226 	mdrpc_host_args		*args,
2227 	mdrpc_generic_res	*res,
2228 	struct svc_req		*rqstp		/* RPC stuff */
2229 )
2230 {
2231 	/* Pass RPC version (METAD_VERSION) to common routine */
2232 	return (mdrpc_delhosts_common(args, res, rqstp, METAD_VERSION));
2233 }
2234 
2235 bool_t
2236 mdrpc_delhosts_2_svc(
2237 	mdrpc_host_2_args	*args,
2238 	mdrpc_generic_res	*res,
2239 	struct svc_req		*rqstp		/* RPC stuff */
2240 )
2241 {
2242 	switch (args->rev) {
2243 	    case MD_METAD_ARGS_REV_1:
2244 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
2245 		return (mdrpc_delhosts_common(
2246 		    &args->mdrpc_host_2_args_u.rev1, res,
2247 		    rqstp, METAD_VERSION_DEVID));
2248 	    default:
2249 		return (FALSE);
2250 	}
2251 }
2252 
2253 /*
2254  * delete a set.
2255  */
2256 bool_t
2257 mdrpc_delset_common(
2258 	mdrpc_sp_args		*args,
2259 	mdrpc_generic_res	*res,
2260 	struct svc_req		*rqstp		/* RPC stuff */
2261 )
2262 {
2263 	md_error_t		*ep = &res->status;
2264 	int			err;
2265 	int			op_mode = W_OK;
2266 
2267 	/* setup, check permissions */
2268 	(void) memset(res, 0, sizeof (*res));
2269 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2270 		return (FALSE);
2271 	else if (err != 0)
2272 		return (TRUE);
2273 
2274 	if (check_set_lock(op_mode, args->cl_sk, ep))
2275 		return (TRUE);
2276 
2277 	/* doit */
2278 	s_delset(args->sp->setname, ep);
2279 
2280 	err = svc_fini(ep);
2281 
2282 	return (TRUE);
2283 }
2284 
2285 bool_t
2286 mdrpc_delset_1_svc(
2287 	mdrpc_sp_args		*args,
2288 	mdrpc_generic_res	*res,
2289 	struct svc_req		*rqstp		/* RPC stuff */
2290 )
2291 {
2292 	return (mdrpc_delset_common(args, res, rqstp));
2293 }
2294 
2295 bool_t
2296 mdrpc_delset_2_svc(
2297 	mdrpc_sp_2_args		*args,
2298 	mdrpc_generic_res	*res,
2299 	struct svc_req		*rqstp		/* RPC stuff */
2300 )
2301 {
2302 	switch (args->rev) {
2303 	    case MD_METAD_ARGS_REV_1:
2304 		return (mdrpc_delset_common(
2305 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
2306 	    default:
2307 		return (FALSE);
2308 	}
2309 }
2310 
2311 /*
2312  * return device info
2313  */
2314 static void
2315 devinfo(
2316 	mdsetname_t		*sp,
2317 	mddrivename_t		*dp,
2318 	mdrpc_devinfo_2_res 	*res,
2319 	md_error_t		*ep
2320 )
2321 {
2322 	mdname_t		*np, *real_np;
2323 
2324 	if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL)
2325 		return;
2326 
2327 	if ((real_np = metaname(&sp, np->bname, LOGICAL_DEVICE, ep)) == NULL)
2328 		return;
2329 
2330 	res->dev = real_np->dev;
2331 	(void) getdevstamp(dp, (long *)&res->vtime, ep);
2332 	res->enc_devid = meta_get_devid(np->rname);
2333 }
2334 
2335 bool_t
2336 mdrpc_devinfo_common(
2337 	mdrpc_devinfo_2_args_r1	*args,
2338 	mdrpc_devinfo_2_res 	*res,
2339 	struct svc_req		*rqstp			/* RPC stuff */
2340 )
2341 {
2342 	int			slice;
2343 	mdname_t		*np;
2344 	mddrivename_t		*dnp = args->drivenamep;
2345 	md_error_t		*ep = &res->status;
2346 	int			err;
2347 	int			op_mode = R_OK;
2348 
2349 	/* setup, check permissions */
2350 	(void) memset(res, 0, sizeof (*res));
2351 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2352 		return (FALSE);
2353 	else if (err != 0)
2354 		return (TRUE);
2355 
2356 	if (check_set_lock(op_mode, NULL, ep))
2357 		return (TRUE);
2358 
2359 	/*
2360 	 * fix all the drivenamep's in the mdname_t's to
2361 	 * point to the right place.
2362 	 */
2363 	for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
2364 		if ((np = metaslicename(dnp, slice, ep)) == NULL)
2365 			return (TRUE);
2366 		np->drivenamep = dnp;
2367 	}
2368 
2369 	/* doit */
2370 	devinfo(args->sp, dnp, res, ep);
2371 
2372 	err = svc_fini(ep);
2373 
2374 	return (TRUE);
2375 }
2376 
2377 /*
2378  * version 1 of the remote procedure. This procedure is called if the
2379  * client is running in version 1. We first convert version 1 arguments
2380  * into version 2 arguments and then call the common remote procedure.
2381  */
2382 bool_t
2383 mdrpc_devinfo_1_svc(
2384 	mdrpc_devinfo_args	*args,
2385 	mdrpc_devinfo_res 	*res,
2386 	struct svc_req		*rqstp			/* RPC stuff */
2387 )
2388 {
2389 	bool_t			retval;
2390 	mdrpc_devinfo_2_args_r1	v2_args;
2391 	mdrpc_devinfo_2_res	v2_res;
2392 
2393 	/* allocate memory */
2394 	v2_args.drivenamep = Zalloc(sizeof (mddrivename_t));
2395 	v2_args.drivenamep->parts.parts_val =
2396 	    Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len);
2397 
2398 	/* convert v1 args to v2 (revision 1) args */
2399 	meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep);
2400 	retval = mdrpc_devinfo_common(&v2_args, &v2_res, rqstp);
2401 
2402 	/*
2403 	 * Fill in the result appropriately.
2404 	 * Since dev_t's for version 2 are 64-bit,
2405 	 * we need to convert them to 32-bit for version 1.
2406 	 */
2407 	res->dev = meta_cmpldev(v2_res.dev);
2408 	res->vtime = v2_res.vtime;
2409 	res->status = v2_res.status;
2410 
2411 	free(v2_args.drivenamep);
2412 	free(v2_args.drivenamep->parts.parts_val);
2413 
2414 	return (retval);
2415 }
2416 
2417 bool_t
2418 mdrpc_devinfo_2_svc(
2419 	mdrpc_devinfo_2_args	*args,
2420 	mdrpc_devinfo_2_res 	*res,
2421 	struct svc_req		*rqstp			/* RPC stuff */
2422 )
2423 {
2424 	switch (args->rev) {
2425 	    case MD_METAD_ARGS_REV_1:
2426 		return (mdrpc_devinfo_common(
2427 		    &args->mdrpc_devinfo_2_args_u.rev1, res, rqstp));
2428 	    default:
2429 		return (FALSE);
2430 	}
2431 }
2432 
2433 /*
2434  * return device id
2435  */
2436 static void
2437 mdrpc_get_devid(
2438 	mdsetname_t		*sp,
2439 	mddrivename_t		*dp,
2440 	mdrpc_devid_res 	*res,
2441 	md_error_t		*ep
2442 )
2443 {
2444 	mdname_t	*np;
2445 
2446 	if ((np = metaslicename(dp, MD_SLICE0, ep)) == NULL)
2447 		return;
2448 
2449 	if (metaname(&sp, np->bname, LOGICAL_DEVICE, ep) == NULL)
2450 		return;
2451 
2452 	res->enc_devid = meta_get_devid(np->rname);
2453 }
2454 
2455 bool_t
2456 mdrpc_devid_2_svc(
2457 	mdrpc_devid_2_args	*args,
2458 	mdrpc_devid_res 	*res,
2459 	struct svc_req		*rqstp			/* RPC stuff */
2460 )
2461 {
2462 	int			slice;
2463 	mdname_t		*np;
2464 	mddrivename_t		*dnp;
2465 	md_error_t		*ep = &res->status;
2466 	int			err;
2467 	int			op_mode = R_OK;
2468 
2469 	switch (args->rev) {
2470 	    case MD_METAD_ARGS_REV_1:
2471 		dnp = (&(args->mdrpc_devid_2_args_u.rev1))->drivenamep;
2472 		break;
2473 	    default:
2474 		return (FALSE);
2475 	}
2476 
2477 	/* setup, check permissions */
2478 	(void) memset(res, 0, sizeof (*res));
2479 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2480 		return (FALSE);
2481 	else if (err != 0)
2482 		return (TRUE);
2483 
2484 	if (check_set_lock(op_mode, NULL, ep))
2485 		return (TRUE);
2486 
2487 	/*
2488 	 * fix all the drivenamep's in the mdname_t's to
2489 	 * point to the right place.
2490 	 */
2491 	for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
2492 		if ((np = metaslicename(dnp, slice, ep)) == NULL)
2493 			return (TRUE);
2494 		np->drivenamep = dnp;
2495 	}
2496 
2497 	/* doit */
2498 	mdrpc_get_devid((&(args->mdrpc_devid_2_args_u.rev1))->sp, dnp, res, ep);
2499 
2500 	err = svc_fini(ep);
2501 
2502 	return (TRUE);
2503 }
2504 
2505 /*
2506  * This routine should not be called for a multi-node diskset.
2507  *
2508  * The devid support is disabled for MN diskset so this routine
2509  * will not be called if the set is MN diskset.  The check has
2510  * been done early in meta_getnextside_devinfo.  However this
2511  * routine will be called when the devid support for MN set is
2512  * enabled and check is removed.
2513  */
2514 bool_t
2515 mdrpc_devinfo_by_devid_2_svc(
2516 	mdrpc_devidstr_args	*args,
2517 	mdrpc_devinfo_2_res	*res,
2518 	struct svc_req	  *rqstp		  /* RPC stuff */
2519 )
2520 {
2521 
2522 	char		*devidstr = args->enc_devid;
2523 	md_error_t	*ep = &res->status;
2524 	ddi_devid_t	devid;
2525 	char		*minor_name = NULL;
2526 	int		ret = 0;
2527 	int		err;
2528 	devid_nmlist_t	*disklist = NULL;
2529 	int		op_mode = R_OK;
2530 	mdname_t	*np;
2531 	mdsetname_t	*sp = args->sp;
2532 
2533 	/* setup, check permissions */
2534 	(void) memset(res, 0, sizeof (*res));
2535 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2536 		return (FALSE);
2537 	else if (err != 0)
2538 		return (TRUE);
2539 
2540 	if (check_set_lock(op_mode, NULL, ep))
2541 		return (TRUE);
2542 
2543 	if (devid_str_decode(devidstr, &devid, &minor_name) != 0)
2544 		return (TRUE);
2545 
2546 	/*
2547 	 * if we do not have a minor name then look for a character device.
2548 	 * This is because the caller (checkdrive_onnode) expects a character
2549 	 * device to be returned. The other client of this interface is
2550 	 * meta_getnextside_devinfo and this supplies a minor name.
2551 	 */
2552 	if (minor_name == NULL) {
2553 		ret = meta_deviceid_to_nmlist("/dev", devid,
2554 		    DEVID_MINOR_NAME_ALL_CHR, &disklist);
2555 	} else {
2556 		ret = meta_deviceid_to_nmlist("/dev", devid, minor_name,
2557 		    &disklist);
2558 		devid_str_free(minor_name);
2559 	}
2560 
2561 	devid_free(devid);
2562 	if (ret != 0) {
2563 		res->dev = NODEV64;
2564 		devid_free_nmlist(disklist);
2565 		return (TRUE);
2566 	}
2567 
2568 	np = metaname(&sp, disklist[0].devname, LOGICAL_DEVICE, ep);
2569 	if (np != NULL) {
2570 		mdcinfo_t	*cinfo;
2571 		if ((cinfo = metagetcinfo(np, ep)) != NULL) {
2572 			res->drivername = Strdup(cinfo->dname);
2573 		}
2574 	}
2575 
2576 	res->dev = meta_expldev(disklist[0].dev);
2577 	res->devname = strdup(disklist[0].devname);
2578 
2579 	devid_free_nmlist(disklist);
2580 
2581 	err = svc_fini(ep);
2582 
2583 	return (TRUE);
2584 }
2585 
2586 /*
2587  * This routine should not be called for a multi-node diskset.
2588  *
2589  * The devid support is disabled for MN diskset so this routine
2590  * will not be called if the set is MN diskset.  The check has
2591  * been done early in meta_getnextside_devinfo.  However this
2592  * routine will be called when the devid support for MN set is
2593  * enabled and check is removed.
2594  *
2595  * This function will return the device info attempting to use
2596  * both the passed in devid and device name.  This is to deal
2597  * with systems that use multi-path disks but not running mpxio.
2598  * In this situation meta_deviceid_to_nmlist will return multiple
2599  * devices.  The orig_devname is used to disambiguate.
2600  *
2601  */
2602 bool_t
2603 mdrpc_devinfo_by_devid_name_2_svc(
2604 	mdrpc_devid_name_2_args	*args,
2605 	mdrpc_devinfo_2_res	*res,
2606 	struct svc_req	  *rqstp		  /* RPC stuff */
2607 )
2608 {
2609 
2610 	char		*devidstr;
2611 	char		*orig_devname;
2612 	md_error_t	*ep = &res->status;
2613 	ddi_devid_t	devid;
2614 	char		*minor_name = NULL;
2615 	int		ret = 0;
2616 	int		err;
2617 	int		i;
2618 	devid_nmlist_t	*disklist = NULL;
2619 	int		op_mode = R_OK;
2620 	mdname_t	*np;
2621 	mdsetname_t	*sp;
2622 
2623 	switch (args->rev) {
2624 	    case MD_METAD_ARGS_REV_1:
2625 		sp = (&(args->mdrpc_devid_name_2_args_u.rev1))->sp;
2626 		devidstr = (&(args->mdrpc_devid_name_2_args_u.rev1))->enc_devid;
2627 		orig_devname =
2628 			(&(args->mdrpc_devid_name_2_args_u.rev1))->orig_devname;
2629 		break;
2630 	    default:
2631 		return (FALSE);
2632 	}
2633 
2634 	/* setup, check permissions */
2635 	(void) memset(res, 0, sizeof (*res));
2636 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2637 		return (FALSE);
2638 	else if (err != 0)
2639 		return (TRUE);
2640 
2641 	if (check_set_lock(op_mode, NULL, ep))
2642 		return (TRUE);
2643 
2644 	if (devid_str_decode(devidstr, &devid, &minor_name) != 0)
2645 		return (TRUE);
2646 
2647 	/*
2648 	 * if we do not have a minor name then look for a character device.
2649 	 * This is because the caller (checkdrive_onnode) expects a character
2650 	 * device to be returned. The other client of this interface is
2651 	 * meta_getnextside_devinfo and this supplies a minor name.
2652 	 */
2653 	if (minor_name == NULL) {
2654 		ret = meta_deviceid_to_nmlist("/dev", devid,
2655 		    DEVID_MINOR_NAME_ALL_CHR, &disklist);
2656 	} else {
2657 		ret = meta_deviceid_to_nmlist("/dev", devid, minor_name,
2658 		    &disklist);
2659 		devid_str_free(minor_name);
2660 	}
2661 
2662 	devid_free(devid);
2663 	if (ret != 0) {
2664 		res->dev = NODEV64;
2665 		devid_free_nmlist(disklist);
2666 		return (TRUE);
2667 	}
2668 
2669 	/* attempt to match to the device name on the originating node */
2670 	for (i = 0; disklist[i].dev != NODEV; i++) {
2671 		if (strncmp(orig_devname, disklist[i].devname,
2672 					strlen(disklist[i].devname)) == 0)
2673 			break;
2674 	}
2675 
2676 	/* if it's not found then use the first disk in the list */
2677 	if (disklist[i].dev == NODEV)
2678 		i = 0;
2679 
2680 	np = metaname(&sp, disklist[i].devname, LOGICAL_DEVICE, ep);
2681 	if (np != NULL) {
2682 		mdcinfo_t	*cinfo;
2683 		if ((cinfo = metagetcinfo(np, ep)) != NULL) {
2684 			res->drivername = Strdup(cinfo->dname);
2685 		}
2686 	}
2687 
2688 	res->dev = meta_expldev(disklist[i].dev);
2689 	res->devname = strdup(disklist[i].devname);
2690 
2691 	devid_free_nmlist(disklist);
2692 
2693 	err = svc_fini(ep);
2694 
2695 	return (TRUE);
2696 }
2697 
2698 static void
2699 drvused(mdsetname_t *sp, mddrivename_t *dnp, md_error_t *ep)
2700 {
2701 	if (meta_check_drivemounted(sp, dnp, ep))
2702 		return;
2703 
2704 	if (meta_check_driveswapped(sp, dnp, ep))
2705 		return;
2706 
2707 	if (meta_check_drive_inuse(metasetname(MD_LOCAL_NAME, ep), dnp,
2708 	    TRUE, ep))
2709 		return;
2710 
2711 	(void) meta_check_driveinset(sp, dnp, ep);
2712 }
2713 
2714 /*
2715  * determine if a device is in use.
2716  */
2717 bool_t
2718 mdrpc_drvused_common(
2719 	mdrpc_drvused_2_args_r1	*args,
2720 	mdrpc_generic_res	*res,
2721 	struct svc_req		*rqstp		/* RPC stuff */
2722 )
2723 {
2724 	md_error_t		*ep = &res->status;
2725 	int			slice;
2726 	mdname_t		*np;
2727 	mddrivename_t		*dnp = args->drivenamep;
2728 	int			err;
2729 	int			op_mode = R_OK;
2730 
2731 	/* setup, check permissions */
2732 	(void) memset(res, 0, sizeof (*res));
2733 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2734 		return (FALSE);
2735 	else if (err != 0)
2736 		return (TRUE);
2737 
2738 	if (check_set_lock(op_mode, NULL, ep))
2739 		return (TRUE);
2740 
2741 	if (dnp == NULL) {
2742 		/* no drive pointer specified */
2743 		return (TRUE);
2744 	}
2745 	/*
2746 	 * fix all the drivenamep's in the mdname_t's to
2747 	 * point to the right place.
2748 	 */
2749 	for (slice = 0; (slice < dnp->parts.parts_len); ++slice) {
2750 		if ((np = metaslicename(dnp, slice, ep)) == NULL)
2751 			return (TRUE);
2752 		np->drivenamep = dnp;
2753 	}
2754 
2755 	/* doit */
2756 	drvused(args->sp, dnp, ep);
2757 
2758 	err = svc_fini(ep);
2759 
2760 	return (TRUE);
2761 }
2762 
2763 /*
2764  * version 1 of the remote procedure. This procedure is called if the
2765  * client is running in version 1. We first convert version 1 arguments
2766  * into version 2 arguments and then call the common remote procedure.
2767  */
2768 bool_t
2769 mdrpc_drvused_1_svc(
2770 	mdrpc_drvused_args	*args,
2771 	mdrpc_generic_res	*res,
2772 	struct svc_req		*rqstp		/* RPC stuff */
2773 )
2774 {
2775 	bool_t			retval;
2776 	mdrpc_drvused_2_args_r1	v2_args;
2777 
2778 	/* allocate memory */
2779 	v2_args.drivenamep = Zalloc(sizeof (mddrivename_t));
2780 	v2_args.drivenamep->parts.parts_val =
2781 	    Zalloc(sizeof (mdname_t) * args->drivenamep->parts.parts_len);
2782 
2783 	/* build args */
2784 	v2_args.sp = args->sp;
2785 	v2_args.cl_sk = args->cl_sk;
2786 
2787 	/* convert v1 args to v2 (revision 1) args */
2788 	meta_conv_drvname_old2new(args->drivenamep, v2_args.drivenamep);
2789 	retval = mdrpc_drvused_common(&v2_args, res, rqstp);
2790 
2791 	free(v2_args.drivenamep);
2792 	free(v2_args.drivenamep->parts.parts_val);
2793 
2794 	return (retval);
2795 }
2796 
2797 bool_t
2798 mdrpc_drvused_2_svc(
2799 	mdrpc_drvused_2_args	*args,
2800 	mdrpc_generic_res	*res,
2801 	struct svc_req		*rqstp		/* RPC stuff */
2802 )
2803 {
2804 	switch (args->rev) {
2805 	    case MD_METAD_ARGS_REV_1:
2806 		return (mdrpc_drvused_common(
2807 		    &args->mdrpc_drvused_2_args_u.rev1, res, rqstp));
2808 	    default:
2809 		return (FALSE);
2810 	}
2811 }
2812 
2813 /*
2814  * return a set records selected by name or number.
2815  */
2816 bool_t
2817 mdrpc_getset_common(
2818 	mdrpc_getset_args	*args,
2819 	mdrpc_getset_res 	*res,
2820 	struct svc_req		*rqstp		/* RPC stuff */
2821 )
2822 {
2823 	md_error_t		*ep = &res->status;
2824 	int			err;
2825 	int			op_mode = R_OK;
2826 
2827 	/* setup, check permissions */
2828 	(void) memset(res, 0, sizeof (*res));
2829 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2830 		return (FALSE);
2831 	else if (err != 0)
2832 		return (TRUE);
2833 
2834 	/* Don't have a setno, so we don't check the lock */
2835 	if (check_set_lock(op_mode, NULL, ep))
2836 		return (TRUE);
2837 
2838 	/* doit */
2839 	if (args->setname && *args->setname)
2840 		res->sr = setdup(getsetbyname(args->setname, ep));
2841 	else if (args->setno > 0)
2842 		res->sr = setdup(getsetbynum(args->setno, ep));
2843 	else
2844 		res->sr = NULL;
2845 
2846 	err = svc_fini(ep);
2847 
2848 	return (TRUE);
2849 }
2850 
2851 bool_t
2852 mdrpc_getset_1_svc(
2853 	mdrpc_getset_args	*args,
2854 	mdrpc_getset_res 	*res,
2855 	struct svc_req		*rqstp		/* RPC stuff */
2856 )
2857 {
2858 	return (mdrpc_getset_common(args, res, rqstp));
2859 }
2860 
2861 bool_t
2862 mdrpc_getset_2_svc(
2863 	mdrpc_getset_2_args	*args,
2864 	mdrpc_getset_res 	*res,
2865 	struct svc_req		*rqstp		/* RPC stuff */
2866 )
2867 {
2868 	switch (args->rev) {
2869 	    case MD_METAD_ARGS_REV_1:
2870 		return (mdrpc_getset_common(
2871 		    &args->mdrpc_getset_2_args_u.rev1, res, rqstp));
2872 	    default:
2873 		return (FALSE);
2874 	}
2875 }
2876 
2877 /*
2878  * return a MN set record selected by name or number.
2879  */
2880 bool_t
2881 mdrpc_mngetset_common(
2882 	mdrpc_getset_args	*args,
2883 	mdrpc_mngetset_res 	*res,
2884 	struct svc_req		*rqstp		/* RPC stuff */
2885 )
2886 {
2887 	md_error_t		*ep = &res->status;
2888 	int			err;
2889 	int			op_mode = R_OK;
2890 	md_set_record		*sr = NULL;
2891 	md_mnset_record		*mnsr = NULL;
2892 
2893 	/* setup, check permissions */
2894 	(void) memset(res, 0, sizeof (*res));
2895 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
2896 		return (FALSE);
2897 	else if (err != 0)
2898 		return (TRUE);
2899 
2900 	/* Don't have a setno, so we don't check the lock */
2901 	if (check_set_lock(op_mode, NULL, ep))
2902 		return (TRUE);
2903 
2904 	/* doit */
2905 	res->mnsr = NULL;
2906 	if (args->setname && *args->setname)
2907 		sr = getsetbyname(args->setname, ep);
2908 	else if (args->setno > 0)
2909 		sr = getsetbynum(args->setno, ep);
2910 
2911 	if ((sr) && (MD_MNSET_REC(sr))) {
2912 		mnsr = (struct md_mnset_record *)sr;
2913 		res->mnsr = mnsetdup(mnsr);
2914 	}
2915 
2916 	err = svc_fini(ep);
2917 
2918 	return (TRUE);
2919 }
2920 
2921 bool_t
2922 mdrpc_mngetset_2_svc(
2923 	mdrpc_getset_2_args	*args,
2924 	mdrpc_mngetset_res	*res,
2925 	struct svc_req		*rqstp		/* RPC stuff */
2926 )
2927 {
2928 	switch (args->rev) {
2929 	    case MD_METAD_ARGS_REV_1:
2930 		return (mdrpc_mngetset_common(
2931 		    &args->mdrpc_getset_2_args_u.rev1, res, rqstp));
2932 	    default:
2933 		return (FALSE);
2934 	}
2935 }
2936 
2937 static void
2938 upd_setmaster(
2939 	mdsetname_t	*sp,
2940 	md_node_nm_t	master_nodenm,
2941 	int		master_nodeid,
2942 	md_error_t	*ep
2943 )
2944 {
2945 	mdsetname_t	*local_sp;
2946 	md_set_record	*sr;
2947 	md_mnset_record	*mnsr;
2948 	mddb_setmaster_config_t	sm;
2949 
2950 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
2951 		return;
2952 
2953 	metaflushsetname(local_sp);
2954 
2955 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
2956 		return;
2957 
2958 	if (MD_MNSET_REC(sr)) {
2959 		mnsr = (struct md_mnset_record *)sr;
2960 		strlcpy(mnsr->sr_master_nodenm, master_nodenm,
2961 			MD_MAX_NODENAME);
2962 		mnsr->sr_master_nodeid = master_nodeid;
2963 		if (master_nodeid != 0) {
2964 			(void) memset(&sm, 0, sizeof (sm));
2965 			sm.c_setno = sp->setno;
2966 			/* Use magic to help protect ioctl against attack. */
2967 			sm.c_magic = MDDB_SETMASTER_MAGIC;
2968 			if (strcmp(master_nodenm, mynode()) == 0) {
2969 				sm.c_current_host_master = 1;
2970 			} else {
2971 				sm.c_current_host_master = 0;
2972 			}
2973 			(void) metaioctl(MD_SETMASTER, &sm, &sm.c_mde, NULL);
2974 			mdclrerror(&sm.c_mde);
2975 		}
2976 	}
2977 
2978 out:
2979 	commitset(sr, FALSE, ep);
2980 	free_sr(sr);
2981 }
2982 
2983 /*
2984  * set the master and nodeid in node record
2985  */
2986 bool_t
2987 mdrpc_mnsetmaster_common(
2988 	mdrpc_mnsetmaster_args	*args,
2989 	mdrpc_generic_res 	*res,
2990 	struct svc_req		*rqstp		/* RPC stuff */
2991 )
2992 {
2993 	md_error_t		*ep = &res->status;
2994 	int			err;
2995 	int			op_mode = W_OK;
2996 
2997 	/* setup, check permissions */
2998 	(void) memset(res, 0, sizeof (*res));
2999 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3000 		return (FALSE);
3001 	else if (err != 0)
3002 		return (TRUE);
3003 
3004 	if (check_set_lock(op_mode, args->cl_sk, ep))
3005 		return (TRUE);
3006 
3007 	/* doit */
3008 	upd_setmaster(args->sp, args->master_nodenm, args->master_nodeid, ep);
3009 
3010 	err = svc_fini(ep);
3011 
3012 	return (TRUE);
3013 }
3014 
3015 bool_t
3016 mdrpc_mnsetmaster_2_svc(
3017 	mdrpc_mnsetmaster_2_args	*args,
3018 	mdrpc_generic_res	*res,
3019 	struct svc_req		*rqstp		/* RPC stuff */
3020 )
3021 {
3022 	switch (args->rev) {
3023 	    case MD_METAD_ARGS_REV_1:
3024 		return (mdrpc_mnsetmaster_common(
3025 		    &args->mdrpc_mnsetmaster_2_args_u.rev1, res, rqstp));
3026 	    default:
3027 		return (FALSE);
3028 	}
3029 }
3030 
3031 /*
3032  * Join this node to the diskset.
3033  * Pass stale_flag information to snarf_set so that snarf code
3034  * can choose a STALE or non-STALE state when starting the set.
3035  * If master is STALE, any joining node will join a stale set regardless
3036  * of the number of accessible mddbs.  Also, if master is at 50%
3037  * accessible replicas and is in the TOOFEW state, don't mark newly
3038  * joining node as STALE; mark it TOOFEW instead.
3039  */
3040 static void
3041 joinset(
3042 	mdsetname_t	*sp,
3043 	int		flags,
3044 	md_error_t	*ep
3045 )
3046 {
3047 	mdsetname_t		*local_sp;
3048 	md_drive_desc		*mydd;
3049 	bool_t			stale_bool;
3050 	mddb_block_parm_t	mbp;
3051 	md_error_t		xep = mdnullerror;
3052 
3053 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
3054 		return;
3055 
3056 	/*
3057 	 * Start mddoors daemon here.
3058 	 * mddoors itself takes care there will be
3059 	 * only one instance running, so starting it twice won't hurt
3060 	 */
3061 	pclose(popen(MDDOORS, "w"));
3062 
3063 	/*
3064 	 * Get latest copy of data.  If a drive was just added causing
3065 	 * nodes to get joined - this drive won't be in the local
3066 	 * name caches drive list yet.
3067 	 */
3068 	metaflushsetname(local_sp);
3069 
3070 	mydd = metaget_drivedesc(local_sp, (MD_BASICNAME_OK | PRINT_FAST), ep);
3071 	if (mydd) {
3072 		/*
3073 		 * Causes mddbs to be loaded into the kernel.
3074 		 * Set the force flag so that replica locations can be loaded
3075 		 * into the kernel even if a mediator node was unavailable.
3076 		 * This allows a node to join an MO diskset when there are
3077 		 * sufficient replicas available, but a mediator node
3078 		 * in unavailable.
3079 		 */
3080 		if (setup_db_bydd(local_sp, mydd, TRUE, ep) == -1) {
3081 			/* If ep isn't set for some reason, set it */
3082 			if (mdisok(ep)) {
3083 				(void) mdmddberror(ep, MDE_DB_NOTNOW,
3084 				    (minor_t)NODEV64, sp->setno, 0, NULL);
3085 			}
3086 			return;
3087 		}
3088 
3089 		if (flags & MNSET_IS_STALE)
3090 			stale_bool = TRUE;
3091 		else
3092 			stale_bool = FALSE;
3093 
3094 		/*
3095 		 * Snarf the set.  No failure has occurred if STALE or
3096 		 * ACCOK error was set.  Otherwise, fail the call setting
3097 		 * a generic error if no error was already set.
3098 		 *
3099 		 * STALE means that set has < 50% mddbs.
3100 		 * ACCOK means that the mediator provided an extra vote.
3101 		 */
3102 		if (snarf_set(local_sp, stale_bool, ep) != 0) {
3103 			if (!(mdismddberror(ep, MDE_DB_STALE)) &&
3104 			    !(mdismddberror(ep, MDE_DB_ACCOK))) {
3105 				return;
3106 			} else if (mdisok(ep)) {
3107 				/* If snarf failed, but no error set - set it */
3108 				(void) mdmddberror(ep, MDE_DB_NOTNOW,
3109 				    (minor_t)NODEV64, sp->setno, 0, NULL);
3110 				return;
3111 			}
3112 		}
3113 
3114 		/*
3115 		 * If node is joining during reconfig cycle, then
3116 		 * set mddb_parse to be in blocked state so that
3117 		 * mddb reparse messages are not generated until
3118 		 * the commd has been resumed later in the reconfig
3119 		 * cycle.
3120 		 */
3121 		if (flags & MNSET_IN_RECONFIG) {
3122 			(void) memset(&mbp, 0, sizeof (mbp));
3123 			if (s_ownset(sp->setno, &xep) == MD_SETOWNER_YES) {
3124 				(void) memset(&mbp, 0, sizeof (mbp));
3125 				mbp.c_setno = local_sp->setno;
3126 				mbp.c_blk_flags = MDDB_BLOCK_PARSE;
3127 				if (metaioctl(MD_MN_MDDB_BLOCK, &mbp,
3128 				    &mbp.c_mde, NULL)) {
3129 					mdstealerror(&xep, &mbp.c_mde);
3130 					mde_perror(ep, gettext(
3131 					    "Could not block set %s"),
3132 					    sp->setname);
3133 					return;
3134 				}
3135 			}
3136 			/*
3137 			 * If s_ownset fails and snarf_set succeeded,
3138 			 * then can steal the ownset failure information
3139 			 * and store it into ep. If snarf_set failed,
3140 			 * don't overwrite critical ep information even
3141 			 * if s_ownset failed.
3142 			 */
3143 			if (!mdisok(&xep)) {
3144 				/*
3145 				 * If snarf_set succeeded or snarf_set failed
3146 				 * with MDE_DB_ACCOK (which is set if the
3147 				 * mediator provided the extra vote) then
3148 				 * steal the xep failure information and put
3149 				 * into ep.
3150 				 */
3151 				if (mdisok(ep) ||
3152 				    mdismddberror(ep, MDE_DB_ACCOK)) {
3153 					mdstealerror(ep, &xep);
3154 				}
3155 			}
3156 		}
3157 	}
3158 }
3159 
3160 /*
3161  * Have this node join the set.
3162  * This is called when a node has been
3163  * added to a MN diskset that has drives.
3164  * Also, called when a node is an alive
3165  * member of a MN diskset and the first
3166  * drive has been added.
3167  */
3168 bool_t
3169 mdrpc_joinset_common(
3170 	mdrpc_sp_flags_args	*args,
3171 	mdrpc_generic_res 	*res,
3172 	struct svc_req		*rqstp		/* RPC stuff */
3173 )
3174 {
3175 	md_error_t		*ep = &res->status;
3176 	int			err;
3177 	int			op_mode = W_OK;
3178 
3179 	/* setup, check permissions */
3180 	(void) memset(res, 0, sizeof (*res));
3181 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3182 		return (FALSE);
3183 	else if (err != 0)
3184 		return (TRUE);
3185 
3186 	/*
3187 	 * During reconfig, joinset can happen without
3188 	 * locking first.  Turn off reconfig flag before calling
3189 	 * joinset.
3190 	 */
3191 	if (!(args->flags & MNSET_IN_RECONFIG)) {
3192 		if (check_set_lock(op_mode, args->cl_sk, ep))
3193 			return (TRUE);
3194 	}
3195 
3196 	/* doit */
3197 	joinset(args->sp, args->flags, ep);
3198 
3199 	err = svc_fini(ep);
3200 
3201 	return (TRUE);
3202 }
3203 
3204 bool_t
3205 mdrpc_joinset_2_svc(
3206 	mdrpc_sp_flags_2_args	*args,
3207 	mdrpc_generic_res	*res,
3208 	struct svc_req		*rqstp		/* RPC stuff */
3209 )
3210 {
3211 	switch (args->rev) {
3212 	    case MD_METAD_ARGS_REV_1:
3213 		return (mdrpc_joinset_common(
3214 		    &args->mdrpc_sp_flags_2_args_u.rev1, res, rqstp));
3215 	    default:
3216 		return (FALSE);
3217 	}
3218 }
3219 
3220 static void
3221 withdrawset(
3222 	mdsetname_t	*sp,
3223 	md_error_t	*ep
3224 )
3225 {
3226 	mdsetname_t	*my_sp;
3227 
3228 	if ((my_sp = metasetname(sp->setname, ep)) == NULL)
3229 		return;
3230 
3231 	(void) halt_set(my_sp, ep);
3232 }
3233 
3234 /*
3235  * Have this node withdraw from set.
3236  * In response to a failure that occurred
3237  * on the client after a joinset.
3238  */
3239 bool_t
3240 mdrpc_withdrawset_common(
3241 	mdrpc_sp_args		*args,
3242 	mdrpc_generic_res 	*res,
3243 	struct svc_req		*rqstp		/* RPC stuff */
3244 )
3245 {
3246 	md_error_t		*ep = &res->status;
3247 	int			err;
3248 	int			op_mode = W_OK;
3249 
3250 	/* setup, check permissions */
3251 	(void) memset(res, 0, sizeof (*res));
3252 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3253 		return (FALSE);
3254 	else if (err != 0)
3255 		return (TRUE);
3256 
3257 	if (check_set_lock(op_mode, args->cl_sk, ep))
3258 		return (TRUE);
3259 
3260 	/* doit */
3261 	withdrawset(args->sp, ep);
3262 
3263 	err = svc_fini(ep);
3264 
3265 	return (TRUE);
3266 }
3267 
3268 bool_t
3269 mdrpc_withdrawset_2_svc(
3270 	mdrpc_sp_2_args		*args,
3271 	mdrpc_generic_res	*res,
3272 	struct svc_req		*rqstp		/* RPC stuff */
3273 )
3274 {
3275 	switch (args->rev) {
3276 	    case MD_METAD_ARGS_REV_1:
3277 		return (mdrpc_withdrawset_common(
3278 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
3279 	    default:
3280 		return (FALSE);
3281 	}
3282 }
3283 
3284 static mhd_mhiargs_t *
3285 gtimeout(mdsetname_t *sp, md_error_t *ep)
3286 {
3287 	md_set_record		*sr;
3288 	mhd_mhiargs_t		*mhiargs;
3289 
3290 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
3291 		return (NULL);
3292 
3293 	mhiargs = Zalloc(sizeof (*mhiargs));
3294 	*mhiargs = sr->sr_mhiargs;
3295 
3296 	free_sr(sr);
3297 	return (mhiargs);
3298 }
3299 
3300 /*
3301  * Get the MH timeout values for this set.
3302  */
3303 bool_t
3304 mdrpc_gtimeout_common(
3305 	mdrpc_sp_args		*args,
3306 	mdrpc_gtimeout_res 	*res,
3307 	struct svc_req		*rqstp		/* RPC stuff */
3308 )
3309 {
3310 	md_error_t		*ep = &res->status;
3311 	int			err;
3312 	int			op_mode = R_OK;
3313 
3314 	/* setup, check permissions */
3315 	(void) memset(res, 0, sizeof (*res));
3316 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3317 		return (FALSE);
3318 	else if (err != 0)
3319 		return (TRUE);
3320 
3321 	if (check_set_lock(op_mode, NULL, ep))
3322 		return (TRUE);
3323 
3324 	/* doit */
3325 	res->mhiargsp = gtimeout(args->sp, ep);
3326 
3327 	err = svc_fini(ep);
3328 
3329 	return (TRUE);
3330 }
3331 
3332 bool_t
3333 mdrpc_gtimeout_1_svc(
3334 	mdrpc_sp_args		*args,
3335 	mdrpc_gtimeout_res 	*res,
3336 	struct svc_req		*rqstp		/* RPC stuff */
3337 )
3338 {
3339 	return (mdrpc_gtimeout_common(args, res, rqstp));
3340 }
3341 
3342 bool_t
3343 mdrpc_gtimeout_2_svc(
3344 	mdrpc_sp_2_args		*args,
3345 	mdrpc_gtimeout_res 	*res,
3346 	struct svc_req		*rqstp		/* RPC stuff */
3347 )
3348 {
3349 	switch (args->rev) {
3350 	    case MD_METAD_ARGS_REV_1:
3351 		return (mdrpc_gtimeout_common(
3352 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
3353 	    default:
3354 		return (FALSE);
3355 	}
3356 }
3357 
3358 /*
3359  * return the official host name for the callee
3360  */
3361 /*ARGSUSED*/
3362 bool_t
3363 mdrpc_hostname_common(
3364 	mdrpc_null_args		*args,
3365 	mdrpc_hostname_res 	*res,
3366 	struct svc_req		*rqstp		/* RPC stuff */
3367 )
3368 {
3369 	md_error_t		*ep = &res->status;
3370 	int			err;
3371 	int			op_mode = R_OK;
3372 
3373 	/* setup, check permissions */
3374 	(void) memset(res, 0, sizeof (*res));
3375 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3376 		return (FALSE);
3377 	else if (err != 0)
3378 		return (TRUE);
3379 
3380 	if (check_set_lock(op_mode, NULL, ep))
3381 		return (TRUE);
3382 
3383 	/* doit */
3384 	res->hostname = Strdup(mynode());
3385 
3386 	err = svc_fini(ep);
3387 
3388 	return (TRUE);
3389 }
3390 
3391 bool_t
3392 mdrpc_hostname_1_svc(
3393 	mdrpc_null_args		*args,
3394 	mdrpc_hostname_res 	*res,
3395 	struct svc_req		*rqstp		/* RPC stuff */
3396 )
3397 {
3398 	return (mdrpc_hostname_common(args, res, rqstp));
3399 }
3400 
3401 bool_t
3402 mdrpc_hostname_2_svc(
3403 	mdrpc_null_args		*args,
3404 	mdrpc_hostname_res 	*res,
3405 	struct svc_req		*rqstp		/* RPC stuff */
3406 )
3407 {
3408 	return (mdrpc_hostname_common(args, res, rqstp));
3409 }
3410 
3411 /*
3412  * return a response
3413  */
3414 /*ARGSUSED*/
3415 bool_t
3416 mdrpc_nullproc_common(
3417 	void		*args,
3418 	md_error_t	*ep,
3419 	struct svc_req	*rqstp		/* RPC stuff */
3420 )
3421 {
3422 	*ep = mdnullerror;
3423 	/* do nothing */
3424 	return (TRUE);
3425 }
3426 
3427 bool_t
3428 mdrpc_nullproc_1_svc(
3429 	void		*args,
3430 	md_error_t	*ep,
3431 	struct svc_req	*rqstp		/* RPC stuff */
3432 )
3433 {
3434 	return (mdrpc_nullproc_common(args, ep, rqstp));
3435 }
3436 
3437 bool_t
3438 mdrpc_nullproc_2_svc(
3439 	void		*args,
3440 	md_error_t	*ep,
3441 	struct svc_req	*rqstp		/* RPC stuff */
3442 )
3443 {
3444 	return (mdrpc_nullproc_common(args, ep, rqstp));
3445 }
3446 
3447 /*
3448  * determine if the caller owns the set.
3449  */
3450 bool_t
3451 mdrpc_ownset_common(
3452 	mdrpc_sp_args		*args,
3453 	mdrpc_bool_res		*res,
3454 	struct svc_req		*rqstp		/* RPC stuff */
3455 )
3456 {
3457 	md_error_t		*ep = &res->status;
3458 	int			err;
3459 	int			op_mode = R_OK;
3460 
3461 	/* setup, check permissions */
3462 	(void) memset(res, 0, sizeof (*res));
3463 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3464 		return (FALSE);
3465 	else if (err != 0)
3466 		return (TRUE);
3467 
3468 	if (check_set_lock(op_mode, NULL, ep))
3469 		return (TRUE);
3470 
3471 	/* doit */
3472 	if (s_ownset(args->sp->setno, ep))
3473 		res->value = TRUE;
3474 	else
3475 		res->value = FALSE;
3476 
3477 	err = svc_fini(ep);
3478 
3479 	return (TRUE);
3480 }
3481 
3482 bool_t
3483 mdrpc_ownset_1_svc(
3484 	mdrpc_sp_args		*args,
3485 	mdrpc_bool_res		*res,
3486 	struct svc_req		*rqstp		/* RPC stuff */
3487 )
3488 {
3489 	return (mdrpc_ownset_common(args, res, rqstp));
3490 }
3491 
3492 bool_t
3493 mdrpc_ownset_2_svc(
3494 	mdrpc_sp_2_args		*args,
3495 	mdrpc_bool_res		*res,
3496 	struct svc_req		*rqstp		/* RPC stuff */
3497 )
3498 {
3499 	switch (args->rev) {
3500 	    case MD_METAD_ARGS_REV_1:
3501 		return (mdrpc_ownset_common(
3502 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
3503 	    default:
3504 		return (FALSE);
3505 	}
3506 }
3507 
3508 static int
3509 setnameok(char *setname, md_error_t *ep)
3510 {
3511 	int			rval = 0;
3512 	struct	stat		statb;
3513 	md_set_record		*sr = NULL;
3514 	char			*setlink = NULL;
3515 
3516 	setlink = Strdup("/dev/md/");
3517 	setlink = Realloc(setlink, strlen(setlink) + strlen(setname) + 1);
3518 	(void) strcat(setlink, setname);
3519 
3520 	if (lstat(setlink, &statb) == -1) {
3521 		/*
3522 		 * If lstat() fails with ENOENT, setname is OK, if it
3523 		 * fails for other than that, we fail the RPC
3524 		 */
3525 		if (errno == ENOENT) {
3526 			rval = 1;
3527 			goto out;
3528 		}
3529 
3530 		(void) mdsyserror(ep, errno, setlink);
3531 		goto out;
3532 	}
3533 
3534 	/*
3535 	 * If the lstat() succeeded, then we see what type of object
3536 	 * we are dealing with, if it is a symlink, we do some further
3537 	 * checking, if it is not a symlink, then we return an
3538 	 * indication that the set name is NOT acceptable.
3539 	 */
3540 	if (! S_ISLNK(statb.st_mode))
3541 		goto out;
3542 
3543 	/*
3544 	 * We look up the setname to see if there is a set
3545 	 * with that name, if there is, then we return
3546 	 * an indication that the set name is NOT acceptable.
3547 	 */
3548 	if ((sr = getsetbyname(setname, ep)) != NULL)
3549 		goto out;
3550 
3551 	if (! mdiserror(ep, MDE_NO_SET))
3552 		goto out;
3553 
3554 	mdclrerror(ep);
3555 
3556 	rval = 1;
3557 out:
3558 	if (sr != NULL)
3559 		free_sr(sr);
3560 	Free(setlink);
3561 	return (rval);
3562 }
3563 
3564 /*
3565  * Make sure the name of the set is OK.
3566  */
3567 bool_t
3568 mdrpc_setnameok_common(
3569 	mdrpc_sp_args		*args,	/* device name */
3570 	mdrpc_bool_res		*res,
3571 	struct svc_req		*rqstp	/* RPC stuff */
3572 )
3573 {
3574 	md_error_t		*ep = &res->status;
3575 	int			err;
3576 	int			op_mode = R_OK;
3577 
3578 	/* setup, check permissions */
3579 	(void) memset(res, 0, sizeof (*res));
3580 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3581 		return (FALSE);
3582 	else if (err != 0)
3583 		return (TRUE);
3584 
3585 	if (check_set_lock(op_mode, NULL, ep))
3586 		return (TRUE);
3587 
3588 	/* doit */
3589 	res->value = setnameok(args->sp->setname, ep);
3590 
3591 	err = svc_fini(ep);
3592 
3593 	return (TRUE);
3594 }
3595 
3596 bool_t
3597 mdrpc_setnameok_1_svc(
3598 	mdrpc_sp_args		*args,	/* device name */
3599 	mdrpc_bool_res		*res,
3600 	struct svc_req		*rqstp	/* RPC stuff */
3601 )
3602 {
3603 	return (mdrpc_setnameok_common(args, res, rqstp));
3604 }
3605 
3606 bool_t
3607 mdrpc_setnameok_2_svc(
3608 	mdrpc_sp_2_args		*args,	/* device name */
3609 	mdrpc_bool_res		*res,
3610 	struct svc_req		*rqstp	/* RPC stuff */
3611 )
3612 {
3613 	switch (args->rev) {
3614 	    case MD_METAD_ARGS_REV_1:
3615 		return (mdrpc_setnameok_common(
3616 		    &args->mdrpc_sp_2_args_u.rev1, res, rqstp));
3617 	    default:
3618 		return (FALSE);
3619 	}
3620 }
3621 
3622 /*
3623  * determine if the setnumber we want to share is in use.
3624  */
3625 bool_t
3626 mdrpc_setnumbusy_common(
3627 	mdrpc_setno_args	*args,
3628 	mdrpc_bool_res		*res,
3629 	struct svc_req		*rqstp		/* RPC stuff */
3630 )
3631 {
3632 	md_error_t		*ep = &res->status;
3633 	md_set_record		*sr = NULL;
3634 	int			err;
3635 	int			op_mode = R_OK;
3636 
3637 	/* setup, check permissions */
3638 	(void) memset(res, 0, sizeof (*res));
3639 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3640 		return (FALSE);
3641 	else if (err != 0)
3642 		return (TRUE);
3643 
3644 	if (check_set_lock(op_mode, NULL, ep))
3645 		return (TRUE);
3646 
3647 	/* doit */
3648 	if ((sr = getsetbynum(args->setno, ep)) != NULL) {
3649 		res->value = TRUE;
3650 		free_sr(sr);
3651 		return (TRUE);
3652 	}
3653 	res->value = FALSE;
3654 	if (mdiserror(ep, MDE_NO_SET))
3655 		mdclrerror(ep);
3656 
3657 	err = svc_fini(ep);
3658 
3659 	return (TRUE);
3660 }
3661 
3662 bool_t
3663 mdrpc_setnumbusy_1_svc(
3664 	mdrpc_setno_args	*args,
3665 	mdrpc_bool_res		*res,
3666 	struct svc_req		*rqstp		/* RPC stuff */
3667 )
3668 {
3669 	return (mdrpc_setnumbusy_common(args, res, rqstp));
3670 }
3671 
3672 bool_t
3673 mdrpc_setnumbusy_2_svc(
3674 	mdrpc_setno_2_args	*args,
3675 	mdrpc_bool_res		*res,
3676 	struct svc_req		*rqstp		/* RPC stuff */
3677 )
3678 {
3679 	switch (args->rev) {
3680 	    case MD_METAD_ARGS_REV_1:
3681 		return (mdrpc_setnumbusy_common(
3682 		    &args->mdrpc_setno_2_args_u.rev1, res, rqstp));
3683 	    default:
3684 		return (FALSE);
3685 	}
3686 }
3687 
3688 static void
3689 stimeout(
3690 	mdsetname_t	*sp,
3691 	mhd_mhiargs_t	*mhiargsp,
3692 	int		version,	/* RPC version of calling routine */
3693 	md_error_t	*ep
3694 )
3695 {
3696 	mddb_userreq_t		req;
3697 	md_set_record		*sr;
3698 
3699 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
3700 		return;
3701 
3702 	sr->sr_mhiargs = *mhiargsp;
3703 
3704 	(void) memset(&req, '\0', sizeof (req));
3705 
3706 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
3707 	/* Do MN operation if rpc version supports it and if a MN set */
3708 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
3709 		req.ur_size = sizeof (struct md_mnset_record);
3710 	} else {
3711 		req.ur_size = sizeof (*sr);
3712 	}
3713 	req.ur_data = (uintptr_t)sr;
3714 
3715 	/*
3716 	 * Cluster nodename support
3717 	 * Convert nodename -> nodeid
3718 	 * Don't do this for MN disksets since we've already stored
3719 	 * both the nodeid and name.
3720 	 */
3721 	if ((version == METAD_VERSION) ||
3722 	    ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr)))))
3723 		sdssc_cm_sr_nm2nid(sr);
3724 
3725 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
3726 		(void) mdstealerror(ep, &req.ur_mde);
3727 		return;
3728 	}
3729 
3730 	(void) memset(&req, '\0', sizeof (req));
3731 	METAD_SETUP_SR(MD_DB_COMMIT_ONE, sr->sr_selfid)
3732 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0)
3733 		(void) mdstealerror(ep, &req.ur_mde);
3734 
3735 	/*
3736 	 * Cluster nodename support
3737 	 * Convert nodeid -> nodename
3738 	 * Don't do this for MN disksets since we've already stored
3739 	 * both the nodeid and name.
3740 	 */
3741 	if ((version == METAD_VERSION) ||
3742 	    ((version == METAD_VERSION_DEVID) && (!(MD_MNSET_REC(sr)))))
3743 		sdssc_cm_sr_nid2nm(sr);
3744 
3745 	free_sr(sr);
3746 }
3747 
3748 /*
3749  * Set MH ioctl timeout values.
3750  */
3751 bool_t
3752 mdrpc_stimeout_common(
3753 	mdrpc_stimeout_args	*args,
3754 	mdrpc_generic_res	*res,
3755 	struct svc_req		*rqstp,		/* RPC stuff */
3756 	int			version		/* RPC version */
3757 )
3758 {
3759 	md_error_t		*ep = &res->status;
3760 	int			err;
3761 	int			op_mode = W_OK;
3762 
3763 	/* setup, check permissions */
3764 	(void) memset(res, 0, sizeof (*res));
3765 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3766 		return (FALSE);
3767 	else if (err != 0)
3768 		return (TRUE);
3769 
3770 	if (check_set_lock(op_mode, NULL, ep))
3771 		return (TRUE);
3772 
3773 	/* doit */
3774 	stimeout(args->sp, args->mhiargsp, version, ep);
3775 
3776 	err = svc_fini(ep);
3777 
3778 	return (TRUE);
3779 }
3780 
3781 bool_t
3782 mdrpc_stimeout_1_svc(
3783 	mdrpc_stimeout_args	*args,
3784 	mdrpc_generic_res	*res,
3785 	struct svc_req		*rqstp		/* RPC stuff */
3786 )
3787 {
3788 	/* Pass RPC version (METAD_VERSION) to common routine */
3789 	return (mdrpc_stimeout_common(args, res, rqstp, METAD_VERSION));
3790 }
3791 
3792 bool_t
3793 mdrpc_stimeout_2_svc(
3794 	mdrpc_stimeout_2_args	*args,
3795 	mdrpc_generic_res	*res,
3796 	struct svc_req		*rqstp		/* RPC stuff */
3797 )
3798 {
3799 	switch (args->rev) {
3800 	    case MD_METAD_ARGS_REV_1:
3801 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
3802 		return (mdrpc_stimeout_common(
3803 		    &args->mdrpc_stimeout_2_args_u.rev1, res,
3804 		    rqstp, METAD_VERSION_DEVID));
3805 	    default:
3806 		return (FALSE);
3807 	}
3808 }
3809 
3810 static void
3811 upd_dr_dbinfo(
3812 	mdsetname_t	*sp,
3813 	md_drive_desc	*dd,
3814 	md_error_t	*ep
3815 )
3816 {
3817 	mdsetname_t	*local_sp;
3818 	md_set_record	*sr;
3819 	md_drive_record	*dr;
3820 	md_drive_desc	*p;
3821 	mddrivename_t	*dn, *dn1;
3822 	ddi_devid_t	devid_remote = NULL;
3823 	ddi_devid_t	devid_local = NULL;
3824 	int		devid_same = -1;
3825 	side_t		sideno;
3826 	int		using_devid = 0;
3827 
3828 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
3829 		return;
3830 
3831 	metaflushsetname(local_sp);
3832 
3833 	if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
3834 		return;
3835 
3836 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
3837 		return;
3838 
3839 	if (dd->dd_dnp == NULL)
3840 		return;
3841 
3842 	/*
3843 	 * The system is either all devid or all
3844 	 * non-devid so we determine this by looking
3845 	 * at the first item in the list.
3846 	 *
3847 	 * For did disks, the dd_dnp->devid is a valid pointer which
3848 	 * points to a '' string of devid.  We need to check this
3849 	 * before set the using_devid.
3850 	 */
3851 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
3852 	    (!(MD_MNSET_REC(sr))))
3853 		using_devid = 1;
3854 
3855 	for (p = dd; p != NULL; p = p->dd_next) {
3856 		dn = p->dd_dnp;
3857 		devid_remote = NULL;
3858 
3859 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
3860 		    using_devid) {
3861 			/*
3862 			 * We have a devid so use it.
3863 			 */
3864 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
3865 		}
3866 
3867 		/* check to make sure using_devid agrees with reality... */
3868 		if ((using_devid == 1) && (devid_remote == NULL)) {
3869 			/* something went really wrong. Can't process */
3870 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
3871 			    mynode(), dn->cname, sp->setname);
3872 			return;
3873 		}
3874 
3875 		for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
3876 			devid_same = -1;
3877 
3878 			dn1 = metadrivename_withdrkey(local_sp, sideno,
3879 			    dr->dr_key, MD_BASICNAME_OK, ep);
3880 
3881 			if (dn1 == NULL) {
3882 				if (devid_remote)
3883 					devid_free(devid_remote);
3884 				goto out;
3885 			}
3886 
3887 			if (dn1->devid != NULL && using_devid) {
3888 				if (devid_str_decode(dn1->devid, &devid_local,
3889 				    NULL) == 0) {
3890 					devid_same = devid_compare(devid_remote,
3891 					    devid_local);
3892 					devid_free(devid_local);
3893 				}
3894 			}
3895 
3896 			if (using_devid && devid_same == 0)
3897 				break;
3898 
3899 			if (!using_devid &&
3900 			    strcmp(dn->cname, dn1->cname) == 0)
3901 				break;
3902 		}
3903 
3904 		if (dr) {
3905 			/* Adjust the fields in the copy */
3906 			dr->dr_dbcnt = p->dd_dbcnt;
3907 			dr->dr_dbsize = p->dd_dbsize;
3908 		}
3909 		if (devid_remote)
3910 			devid_free(devid_remote);
3911 	}
3912 
3913 
3914 out:
3915 	commitset(sr, FALSE, ep);
3916 	free_sr(sr);
3917 }
3918 
3919 /*
3920  * update the database count and size field of drive records.
3921  */
3922 bool_t
3923 mdrpc_upd_dr_dbinfo_common(
3924 	mdrpc_drives_2_args_r1	*args,
3925 	mdrpc_generic_res	*res,
3926 	struct svc_req		*rqstp		/* RPC stuff */
3927 )
3928 {
3929 	md_error_t		*ep = &res->status;
3930 	int			err;
3931 	int			op_mode = W_OK;
3932 
3933 	/* setup, check permissions */
3934 	(void) memset(res, 0, sizeof (*res));
3935 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
3936 		return (FALSE);
3937 	else if (err != 0)
3938 		return (TRUE);
3939 
3940 	if (check_set_lock(op_mode, args->cl_sk, ep))
3941 		return (TRUE);
3942 
3943 	/* doit */
3944 	upd_dr_dbinfo(args->sp, args->drivedescs, ep);
3945 
3946 	err = svc_fini(ep);
3947 
3948 	return (TRUE);
3949 }
3950 
3951 /*
3952  * version 1 of the remote procedure. This procedure is called if the
3953  * client is running in version 1. We first convert version 1 arguments
3954  * into version 2 arguments and then call the common remote procedure.
3955  */
3956 bool_t
3957 mdrpc_upd_dr_dbinfo_1_svc(
3958 	mdrpc_drives_args	*args,
3959 	mdrpc_generic_res	*res,
3960 	struct svc_req		*rqstp		/* RPC stuff */
3961 )
3962 {
3963 	bool_t			retval;
3964 	mdrpc_drives_2_args_r1	v2_args;
3965 
3966 	/* allocate memory */
3967 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
3968 
3969 	/* build args */
3970 	v2_args.cl_sk = args->cl_sk;
3971 	v2_args.sp = args->sp;
3972 	/* convert v1 args to v2 (revision 1) args */
3973 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
3974 	v2_args.timestamp = args->timestamp;
3975 	v2_args.genid = args->genid;
3976 
3977 	retval = mdrpc_upd_dr_dbinfo_common(&v2_args, res, rqstp);
3978 
3979 	free_newdrvdesc(v2_args.drivedescs);
3980 
3981 	return (retval);
3982 }
3983 
3984 bool_t
3985 mdrpc_upd_dr_dbinfo_2_svc(
3986 	mdrpc_drives_2_args	*args,
3987 	mdrpc_generic_res	*res,
3988 	struct svc_req		*rqstp		/* RPC stuff */
3989 )
3990 {
3991 	switch (args->rev) {
3992 	    case MD_METAD_ARGS_REV_1:
3993 		return (mdrpc_upd_dr_dbinfo_common(
3994 		    &args->mdrpc_drives_2_args_u.rev1, res, rqstp));
3995 	    default:
3996 		return (FALSE);
3997 	}
3998 }
3999 
4000 static void
4001 upd_dr_flags(
4002 	mdsetname_t	*sp,
4003 	md_drive_desc	*dd,
4004 	uint_t		new_flags,
4005 	md_error_t	*ep
4006 )
4007 {
4008 	mdsetname_t	*local_sp;
4009 	md_set_record	*sr;
4010 	md_drive_record	*dr;
4011 	md_drive_desc	*p;
4012 	mddrivename_t	*dn, *dn1;
4013 	ddi_devid_t	devid_remote = NULL;
4014 	ddi_devid_t	devid_local = NULL;
4015 	int		devid_same = -1;
4016 	side_t		sideno;
4017 	int		using_devid = 0;
4018 
4019 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
4020 		return;
4021 
4022 	metaflushsetname(local_sp);
4023 
4024 	if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
4025 		return;
4026 
4027 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
4028 		return;
4029 
4030 	if (dd->dd_dnp == NULL)
4031 		return;
4032 
4033 	/*
4034 	 * The system is either all devid or all
4035 	 * non-devid so we determine this by looking
4036 	 * at the first item in the list.
4037 	 *
4038 	 * For did disks, the dd_dnp->devid is a valid pointer which
4039 	 * points to a '' string of devid.  We need to check this
4040 	 * before set the using_devid.
4041 	 */
4042 	if ((dd->dd_dnp->devid != NULL) && (dd->dd_dnp->devid[0] != '\0') &&
4043 	    (!(MD_MNSET_REC(sr))))
4044 		using_devid = 1;
4045 
4046 	for (p = dd; p != NULL; p = p->dd_next) {
4047 		dn = p->dd_dnp;
4048 		devid_remote = NULL;
4049 
4050 		if (dn->devid != NULL && (strlen(dn->devid) != 0) &&
4051 		    using_devid) {
4052 			/*
4053 			 * We have a devid so use it.
4054 			 */
4055 			(void) devid_str_decode(dn->devid, &devid_remote, NULL);
4056 		}
4057 
4058 		/* check to make sure using_devid agrees with reality... */
4059 		if ((using_devid == 1) && (devid_remote == NULL)) {
4060 			/* something went really wrong. Can't process */
4061 			(void) mddserror(ep, MDE_DS_INVALIDDEVID, sp->setno,
4062 			    mynode(), dn->cname, sp->setname);
4063 			return;
4064 		}
4065 
4066 		for (dr = sr->sr_drivechain; dr; dr = dr->dr_next) {
4067 			devid_same = -1;
4068 
4069 			dn1 = metadrivename_withdrkey(local_sp, sideno,
4070 			    dr->dr_key, MD_BASICNAME_OK, ep);
4071 
4072 			if (dn1 == NULL) {
4073 				if (devid_remote)
4074 					devid_free(devid_remote);
4075 				goto out;
4076 			}
4077 
4078 			if (dn1->devid != NULL && using_devid) {
4079 				if (devid_str_decode(dn1->devid,
4080 				    &devid_local, NULL) == 0) {
4081 					devid_same = devid_compare(devid_remote,
4082 					    devid_local);
4083 					devid_free(devid_local);
4084 				}
4085 			}
4086 
4087 			if (using_devid && devid_same == 0)
4088 				break;
4089 
4090 			if (!using_devid &&
4091 			    strcmp(dn->cname, dn1->cname) == 0)
4092 				break;
4093 		}
4094 
4095 		if (dr)
4096 			dr->dr_flags = new_flags;
4097 		if (devid_remote)
4098 			devid_free(devid_remote);
4099 	}
4100 out:
4101 	commitset(sr, TRUE, ep);
4102 	free_sr(sr);
4103 }
4104 
4105 /*
4106  * update the database count and size field of drive records.
4107  */
4108 bool_t
4109 mdrpc_upd_dr_flags_common(
4110 	mdrpc_upd_dr_flags_2_args_r1	*args,
4111 	mdrpc_generic_res		*res,
4112 	struct svc_req			*rqstp		/* RPC stuff */
4113 )
4114 {
4115 	md_error_t		*ep = &res->status;
4116 	int			err;
4117 	int			op_mode = W_OK;
4118 
4119 	/* setup, check permissions */
4120 	(void) memset(res, 0, sizeof (*res));
4121 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4122 		return (FALSE);
4123 	else if (err != 0)
4124 		return (TRUE);
4125 
4126 	if (check_set_lock(op_mode, args->cl_sk, ep))
4127 		return (TRUE);
4128 
4129 	/* doit */
4130 	upd_dr_flags(args->sp, args->drivedescs, args->new_flags, ep);
4131 
4132 	err = svc_fini(ep);
4133 
4134 	return (TRUE);
4135 }
4136 
4137 /*
4138  * version 1 of the remote procedure. This procedure is called if the
4139  * client is running in version 1. We first convert version 1 arguments
4140  * into version 2 arguments and then call the common remote procedure.
4141  */
4142 bool_t
4143 mdrpc_upd_dr_flags_1_svc(
4144 	mdrpc_upd_dr_flags_args	*args,
4145 	mdrpc_generic_res	*res,
4146 	struct svc_req		*rqstp		/* RPC stuff */
4147 )
4148 {
4149 	bool_t				retval;
4150 	mdrpc_upd_dr_flags_2_args_r1	v2_args;
4151 
4152 	/* allocate memory */
4153 	alloc_newdrvdesc(args->drivedescs, &v2_args.drivedescs);
4154 
4155 	/* build args */
4156 	v2_args.cl_sk = args->cl_sk;
4157 	v2_args.sp = args->sp;
4158 	/* convert v1 args to v2 (revision 1) args */
4159 	meta_conv_drvdesc_old2new(args->drivedescs, v2_args.drivedescs);
4160 	v2_args.new_flags = args->new_flags;
4161 
4162 	retval = mdrpc_upd_dr_flags_common(&v2_args, res, rqstp);
4163 
4164 	free_newdrvdesc(v2_args.drivedescs);
4165 
4166 	return (retval);
4167 }
4168 
4169 bool_t
4170 mdrpc_upd_dr_flags_2_svc(
4171 	mdrpc_upd_dr_flags_2_args	*args,
4172 	mdrpc_generic_res		*res,
4173 	struct svc_req			*rqstp		/* RPC stuff */
4174 )
4175 {
4176 	switch (args->rev) {
4177 	    case MD_METAD_ARGS_REV_1:
4178 		return (mdrpc_upd_dr_flags_common(
4179 		    &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp));
4180 	    default:
4181 		return (FALSE);
4182 	}
4183 }
4184 
4185 static void
4186 upd_sr_flags(
4187 	mdsetname_t	*sp,
4188 	uint_t		new_flags,
4189 	md_error_t	*ep
4190 )
4191 {
4192 	md_set_record	*sr;
4193 
4194 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
4195 		return;
4196 
4197 	sr->sr_flags = new_flags;
4198 	commitset(sr, TRUE, ep);
4199 	free_sr(sr);
4200 }
4201 
4202 /*
4203  * update the set record flags
4204  */
4205 bool_t
4206 mdrpc_upd_sr_flags_common(
4207 	mdrpc_upd_sr_flags_args	*args,
4208 	mdrpc_generic_res	*res,
4209 	struct svc_req		*rqstp		/* RPC stuff */
4210 )
4211 {
4212 	md_error_t		*ep = &res->status;
4213 	int			err;
4214 	int			op_mode = W_OK;
4215 
4216 	/* setup, check permissions */
4217 	(void) memset(res, 0, sizeof (*res));
4218 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4219 		return (FALSE);
4220 	else if (err != 0)
4221 		return (TRUE);
4222 
4223 	if (check_set_lock(op_mode, args->cl_sk, ep))
4224 		return (TRUE);
4225 
4226 	/* doit */
4227 	upd_sr_flags(args->sp, args->new_flags, ep);
4228 
4229 	err = svc_fini(ep);
4230 
4231 	return (TRUE);
4232 }
4233 
4234 bool_t
4235 mdrpc_upd_sr_flags_1_svc(
4236 	mdrpc_upd_sr_flags_args	*args,
4237 	mdrpc_generic_res	*res,
4238 	struct svc_req		*rqstp		/* RPC stuff */
4239 )
4240 {
4241 	return (mdrpc_upd_sr_flags_common(args, res, rqstp));
4242 }
4243 
4244 bool_t
4245 mdrpc_upd_sr_flags_2_svc(
4246 	mdrpc_upd_sr_flags_2_args	*args,
4247 	mdrpc_generic_res		*res,
4248 	struct svc_req			*rqstp		/* RPC stuff */
4249 )
4250 {
4251 	switch (args->rev) {
4252 	    case MD_METAD_ARGS_REV_1:
4253 		return (mdrpc_upd_sr_flags_common(
4254 		    &args->mdrpc_upd_sr_flags_2_args_u.rev1, res, rqstp));
4255 	    default:
4256 		return (FALSE);
4257 	}
4258 }
4259 
4260 /*
4261  * upd_nr_flags updates the node records stored in this node's local mddb
4262  * given a node desciptor list and an action.  upd_nr_flags then commits
4263  * the node records to the local mddb.
4264  *
4265  * nd - A linked list of node descriptors that describes the node records
4266  *	in this diskset on which the action applies.
4267  * flag_action: action to be taken on node records that match the nd list.
4268  *	flag_action can be:
4269  *		MD_NR_JOIN: set OWN flag in node records
4270  *		MD_NR_WITHDRAW: reset OWN flag in node records
4271  *		MD_NR_OK: reset ADD flags and set OK flag in node records
4272  *		MD_NR_SET: set node record flags based on flags stored in nd
4273  *
4274  * Typically, the JOIN, WITHDRAW and OK flag_actions are used when setting
4275  * all nodes in a diskset to JOIN (add first disk to set), WITHDRAW
4276  * (remove last disk from set) or OK (after addition of host to set).
4277  *
4278  * The SET flag_action is typically used when nodelist contains all nodes
4279  * in the diskset, but specific nodes have had flag changes.  An example of
4280  * this would be the join/withdraw of a specific node to/from the set.
4281  *
4282  * Ignore the MD_MN_NODE_RB_JOIN flag if set in node record flag.  This
4283  * flag is used by the client to recover in case of failure and should not
4284  * be set in the node record flags.
4285  */
4286 static void
4287 upd_nr_flags(
4288 	mdsetname_t	*sp,
4289 	md_mnnode_desc	*nd,
4290 	uint_t		flag_action,
4291 	md_error_t	*ep
4292 )
4293 {
4294 	mdsetname_t		*local_sp;
4295 	md_set_record		*sr;
4296 	md_mnset_record		*mnsr;
4297 	md_mnnode_desc		*ndp;
4298 	md_mnnode_record	*nrp;
4299 
4300 	if ((local_sp = metasetname(sp->setname, ep)) == NULL)
4301 		return;
4302 
4303 	metaflushsetname(local_sp);
4304 
4305 	if ((sr = getsetbyname(sp->setname, ep)) == NULL)
4306 		return;
4307 
4308 	if (!(MD_MNSET_REC(sr))) {
4309 		return;
4310 	}
4311 	mnsr = (struct md_mnset_record *)sr;
4312 
4313 	switch (flag_action) {
4314 	case MD_NR_JOIN:
4315 	case MD_NR_WITHDRAW:
4316 	case MD_NR_SET:
4317 	case MD_NR_OK:
4318 	case MD_NR_DEL:
4319 		break;
4320 	default:
4321 		return;
4322 	}
4323 
4324 	for (ndp = nd; ndp != NULL; ndp = ndp->nd_next) {
4325 		/* Find matching node record for given node descriptor */
4326 		for (nrp = mnsr->sr_nodechain; nrp != NULL;
4327 		    nrp = nrp->nr_next) {
4328 			if (ndp->nd_nodeid == nrp->nr_nodeid) {
4329 				switch (flag_action) {
4330 				case MD_NR_JOIN:
4331 					nrp->nr_flags |= MD_MN_NODE_OWN;
4332 					break;
4333 				case MD_NR_WITHDRAW:
4334 					nrp->nr_flags &= ~MD_MN_NODE_OWN;
4335 					break;
4336 				case MD_NR_OK:
4337 					nrp->nr_flags &=
4338 					    ~(MD_MN_NODE_ADD | MD_MN_NODE_DEL);
4339 					nrp->nr_flags |= MD_MN_NODE_OK;
4340 					break;
4341 				case MD_NR_DEL:
4342 					nrp->nr_flags &=
4343 					    ~(MD_MN_NODE_OK | MD_MN_NODE_ADD);
4344 					nrp->nr_flags |= MD_MN_NODE_DEL;
4345 					break;
4346 				case MD_NR_SET:
4347 					/* Do not set RB_JOIN flag */
4348 					nrp->nr_flags =
4349 					    ndp->nd_flags & ~MD_MN_NODE_RB_JOIN;
4350 					break;
4351 				}
4352 				break;
4353 			}
4354 		}
4355 	}
4356 out:
4357 	/* Don't increment set genid for node record flag update */
4358 	commitset(sr, FALSE, ep);
4359 	free_sr(sr);
4360 }
4361 
4362 /*
4363  * init/fini wrapper around upd_nr_flags
4364  */
4365 bool_t
4366 mdrpc_upd_nr_flags_common(
4367 	mdrpc_upd_nr_flags_args	*args,
4368 	mdrpc_generic_res	*res,
4369 	struct svc_req		*rqstp		/* RPC stuff */
4370 )
4371 {
4372 	md_error_t		*ep = &res->status;
4373 	int			err;
4374 	int			op_mode = W_OK;
4375 
4376 	/* setup, check permissions */
4377 	(void) memset(res, 0, sizeof (*res));
4378 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4379 		return (FALSE);
4380 	else if (err != 0)
4381 		return (TRUE);
4382 
4383 	/*
4384 	 * During reconfig, node record flags can be updated without
4385 	 * locking first.
4386 	 */
4387 	if (!(args->flags & MNSET_IN_RECONFIG)) {
4388 		if (check_set_lock(op_mode, args->cl_sk, ep))
4389 			return (TRUE);
4390 	}
4391 
4392 	/* doit */
4393 	upd_nr_flags(args->sp, args->nodedescs, args->flag_action, ep);
4394 
4395 	err = svc_fini(ep);
4396 
4397 	return (TRUE);
4398 }
4399 
4400 /*
4401  * update the node records using given flag action.
4402  */
4403 bool_t
4404 mdrpc_upd_nr_flags_2_svc(
4405 	mdrpc_upd_nr_flags_2_args	*args,
4406 	mdrpc_generic_res		*res,
4407 	struct svc_req			*rqstp		/* RPC stuff */
4408 )
4409 {
4410 	switch (args->rev) {
4411 	    case MD_METAD_ARGS_REV_1:
4412 		return (mdrpc_upd_nr_flags_common(
4413 		    &args->mdrpc_upd_nr_flags_2_args_u.rev1, res, rqstp));
4414 	    default:
4415 		return (FALSE);
4416 	}
4417 }
4418 
4419 void
4420 free_sk(md_setkey_t *skp)
4421 {
4422 	Free(skp->sk_setname);
4423 	Free(skp->sk_host);
4424 	Free(skp);
4425 }
4426 
4427 void
4428 del_sk(set_t setno)
4429 {
4430 	md_setkey_t	*skp;
4431 	md_setkey_t	*tskp;
4432 
4433 	for (skp = tskp = my_svc_sk; skp; tskp = skp, skp = skp->sk_next) {
4434 		if (setno == skp->sk_setno) {
4435 			if (skp == my_svc_sk)
4436 				my_svc_sk = skp->sk_next;
4437 			else
4438 				tskp->sk_next = skp->sk_next;
4439 
4440 			Free(skp->sk_setname);
4441 			Free(skp->sk_host);
4442 			Free(skp);
4443 			break;
4444 		}
4445 	}
4446 }
4447 
4448 md_setkey_t *
4449 dupsk(md_setkey_t *skp)
4450 {
4451 	md_setkey_t	*tskp;
4452 
4453 	tskp = Zalloc(sizeof (md_setkey_t));
4454 
4455 	*tskp = *skp;
4456 	tskp->sk_host = Strdup(skp->sk_host);
4457 	tskp->sk_setname = Strdup(skp->sk_setname);
4458 
4459 	return (tskp);
4460 }
4461 
4462 md_setkey_t *
4463 svc_get_setkey(set_t setno)
4464 {
4465 	md_setkey_t	*skp;
4466 
4467 	for (skp = my_svc_sk; skp != NULL; skp = skp->sk_next)
4468 		if (setno == skp->sk_setno)
4469 			return (dupsk(skp));
4470 	return (NULL);
4471 }
4472 
4473 void
4474 svc_set_setkey(md_setkey_t *svc_sk)
4475 {
4476 	md_setkey_t	*skp;
4477 
4478 	if (my_svc_sk == NULL) {
4479 		my_svc_sk = dupsk(svc_sk);
4480 		return;
4481 	}
4482 
4483 	for (skp = my_svc_sk; skp->sk_next != NULL; skp = skp->sk_next)
4484 		assert(svc_sk->sk_setno != skp->sk_setno);
4485 
4486 	skp->sk_next = dupsk(svc_sk);
4487 }
4488 
4489 /*
4490  * Unlock the set
4491  *
4492  * To unlock the set, the user must have the correct key, once this is verified
4493  * the set is unlocked and the cached information for the set is flushed.
4494  */
4495 bool_t
4496 mdrpc_unlock_set_common(
4497 	mdrpc_null_args		*args,
4498 	mdrpc_setlock_res	*res,
4499 	struct svc_req		*rqstp		/* RPC stuff */
4500 )
4501 {
4502 	md_error_t		*ep = &res->status;
4503 	int			err;
4504 	int			op_mode = W_OK;
4505 	md_setkey_t		*svc_skp;
4506 	md_set_desc		*sd;
4507 	mdsetname_t		*sp;
4508 	int			multi_node = 0;
4509 	md_error_t		xep = mdnullerror;
4510 
4511 	/* setup, check permissions */
4512 	(void) memset(res, 0, sizeof (*res));
4513 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4514 		return (FALSE);
4515 	else if (err != 0)
4516 		return (TRUE);
4517 
4518 	/*
4519 	 * Is diskset a MN diskset?
4520 	 * Don't set error from this check since unlock set can be
4521 	 * called after a set has been deleted.
4522 	 */
4523 	if (((sp = metasetnosetname(args->cl_sk->sk_setno, &xep)) != NULL) &&
4524 	    ((sd = metaget_setdesc(sp, &xep)) != NULL)) {
4525 		if ((MD_MNSET_DESC(sd))) {
4526 			multi_node = 1;
4527 		}
4528 	}
4529 
4530 	/* Get the set key, if any */
4531 	svc_skp = svc_get_setkey(args->cl_sk->sk_setno);
4532 
4533 	/* The set is locked */
4534 	if (svc_skp != NULL) {
4535 
4536 		/* Make sure the opener has the right key. */
4537 		if (args->cl_sk->sk_key.tv_sec != svc_skp->sk_key.tv_sec ||
4538 		    args->cl_sk->sk_key.tv_usec != svc_skp->sk_key.tv_usec) {
4539 			(void) mddserror(ep, MDE_DS_ULKSBADKEY,
4540 			    svc_skp->sk_setno, mynode(), svc_skp->sk_host,
4541 			    svc_skp->sk_setname);
4542 			free_sk(svc_skp);
4543 			return (TRUE);
4544 		}
4545 
4546 		/* Unlock the set */
4547 		del_sk(args->cl_sk->sk_setno);
4548 
4549 		/* Cleanup */
4550 		free_sk(svc_skp);
4551 
4552 		goto out;
4553 	}
4554 
4555 
4556 	/*
4557 	 * It is possible on a MN diskset to attempt to unlock a set that
4558 	 * is unlocked.  This could occur when the metaset or metadb  command
4559 	 * is failing due to another metaset or metadb command running.
4560 	 * So, print no warning for MN disksets.
4561 	 */
4562 	if (multi_node == 0) {
4563 		md_eprintf("Warning: set unlocked when unlock_set called!\n");
4564 	}
4565 
4566 out:
4567 	res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
4568 
4569 	/* Flush the set cache */
4570 	sr_cache_flush_setno(args->cl_sk->sk_setno);
4571 
4572 	return (TRUE);
4573 }
4574 
4575 bool_t
4576 mdrpc_unlock_set_1_svc(
4577 	mdrpc_null_args		*args,
4578 	mdrpc_setlock_res	*res,
4579 	struct svc_req		*rqstp		/* RPC stuff */
4580 )
4581 {
4582 	return (mdrpc_unlock_set_common(args, res, rqstp));
4583 }
4584 
4585 bool_t
4586 mdrpc_unlock_set_2_svc(
4587 	mdrpc_null_args		*args,
4588 	mdrpc_setlock_res	*res,
4589 	struct svc_req		*rqstp		/* RPC stuff */
4590 )
4591 {
4592 	return (mdrpc_unlock_set_common(args, res, rqstp));
4593 }
4594 
4595 /*
4596  * Lock the set
4597  *
4598  * If the user does not hand us a key, then we generate a new key and lock the
4599  * set using this new key that was generated, if the user hands us a key then
4600  * we use the key to lock the set.
4601  */
4602 bool_t
4603 mdrpc_lock_set_common(
4604 	mdrpc_null_args		*args,
4605 	mdrpc_setlock_res	*res,
4606 	struct svc_req		*rqstp		/* RPC stuff */
4607 )
4608 {
4609 	md_error_t		*ep = &res->status;
4610 	int			err;
4611 	md_error_t		xep = mdnullerror;
4612 	int			op_mode = W_OK;
4613 	md_setkey_t		*svc_skp;
4614 	md_setkey_t		new_sk;
4615 	md_set_desc		*sd = NULL;
4616 	mdsetname_t		*sp = NULL;
4617 
4618 	/* setup, check permissions */
4619 	(void) memset(res, 0, sizeof (*res));
4620 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4621 		return (FALSE);
4622 	else if (err != 0)
4623 		return (TRUE);
4624 
4625 	svc_skp = svc_get_setkey(args->cl_sk->sk_setno);
4626 
4627 	/* The set is locked */
4628 	if (svc_skp != NULL) {
4629 
4630 		/*
4631 		 * This lock request could be for a new diskset, as
4632 		 * such metasetnosetname() may not return anything
4633 		 * useful. Only call it if there is already a key.
4634 		 */
4635 		if ((sp = metasetnosetname(args->cl_sk->sk_setno, ep))
4636 		    != NULL) {
4637 			sd = metaget_setdesc(sp, ep);
4638 		}
4639 
4640 		/*
4641 		 * meta_lock() provides local locking for non-MN
4642 		 * disksets. The local lock is held before we call
4643 		 * this RPC function. We should not receive a lock
4644 		 * request from the host which owns the lock. If we
4645 		 * do, release the lock.
4646 		 */
4647 		if (!((sd != NULL) && (MD_MNSET_DESC(sd))) &&
4648 		    (strcmp(svc_skp->sk_host, args->cl_sk->sk_host) == 0)) {
4649 			md_eprintf(
4650 			    "Warning: set locked when lock_set called!\n");
4651 
4652 			md_eprintf("Held lock info:\n");
4653 
4654 			md_eprintf("\tLock:\n");
4655 			md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname);
4656 			md_eprintf("\t\tSetno:   %d\n", svc_skp->sk_setno);
4657 			md_eprintf("\t\tHost:    %s\n", svc_skp->sk_host);
4658 			md_eprintf("\t\tKey:     %d/%d %s\n",
4659 			    svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec,
4660 			    ctime((const time_t *)&svc_skp->sk_key.tv_sec));
4661 
4662 			/* Unlock set */
4663 			del_sk(svc_skp->sk_setno);
4664 			free_sk(svc_skp);
4665 			svc_skp = NULL;
4666 
4667 			md_eprintf("Released lock held by requesting host\n");
4668 		}
4669 	}
4670 
4671 	/* The set is unlocked */
4672 	if (svc_skp == NULL) {
4673 		/* If we have been given a key, use it. */
4674 		if (args->cl_sk->sk_key.tv_sec || args->cl_sk->sk_key.tv_usec) {
4675 			svc_set_setkey(args->cl_sk);
4676 			res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
4677 			goto out;
4678 		}
4679 
4680 		/* We need to lock it, with a new key */
4681 		new_sk = *args->cl_sk;
4682 		if (meta_gettimeofday(&new_sk.sk_key) == -1) {
4683 			(void) mdsyserror(ep, errno, "meta_gettimeofday()");
4684 			mde_perror(&xep, "");
4685 			md_exit(NULL, 1);
4686 		}
4687 		svc_set_setkey(&new_sk);
4688 
4689 		res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
4690 		goto out;
4691 	}
4692 
4693 	/*
4694 	 * If a MN diskset, the lock_set routine is used as a locking
4695 	 * mechanism to keep multiple metaset and/or metadb commads
4696 	 * from interfering with each other.  If two metaset/metadb
4697 	 * commands are issued at the same time - one will complete
4698 	 * and the other command will fail with MDE_DS_NOTNOW_CMD.
4699 	 */
4700 	if ((sd != NULL) && MD_MNSET_DESC(sd)) {
4701 		(void) mddserror(ep, MDE_DS_NOTNOW_CMD,
4702 		    svc_skp->sk_setno, mynode(),
4703 		    svc_skp->sk_host, svc_skp->sk_setname);
4704 		goto out;
4705 	}
4706 
4707 	md_eprintf("Warning: set locked when lock_set called!\n");
4708 
4709 	md_eprintf("Lock info:\n");
4710 
4711 	md_eprintf("\tLock(svc):\n");
4712 	md_eprintf("\t\tSetname: %s\n", svc_skp->sk_setname);
4713 	md_eprintf("\t\tSetno:   %d\n", svc_skp->sk_setno);
4714 	md_eprintf("\t\tHost:    %s\n", svc_skp->sk_host);
4715 	md_eprintf("\t\tKey:     %d/%d %s",
4716 	    svc_skp->sk_key.tv_sec, svc_skp->sk_key.tv_usec,
4717 	    ctime((const time_t *)&svc_skp->sk_key.tv_sec));
4718 
4719 	md_eprintf("\tLock(cl):\n");
4720 	md_eprintf("\t\tSetname: %s\n", args->cl_sk->sk_setname);
4721 	md_eprintf("\t\tSetno:   %d\n", args->cl_sk->sk_setno);
4722 	md_eprintf("\t\tHost:    %s\n", args->cl_sk->sk_host);
4723 	md_eprintf("\t\tKey:     %d/%d %s",
4724 	    args->cl_sk->sk_key.tv_sec, args->cl_sk->sk_key.tv_usec,
4725 	    ctime((const time_t *)&args->cl_sk->sk_key.tv_sec));
4726 
4727 	/* The set is locked, do we have the key? */
4728 	if (args->cl_sk->sk_key.tv_sec == svc_skp->sk_key.tv_sec &&
4729 	    args->cl_sk->sk_key.tv_usec == svc_skp->sk_key.tv_usec) {
4730 		res->cl_sk = svc_get_setkey(args->cl_sk->sk_setno);
4731 		goto out;
4732 	}
4733 
4734 	/*
4735 	 * The set is locked and we do not have the key, so we set up an error.
4736 	 */
4737 	(void) mddserror(ep, MDE_DS_LKSBADKEY, svc_skp->sk_setno, mynode(),
4738 	    svc_skp->sk_host, args->cl_sk->sk_setname);
4739 
4740 out:
4741 	if (svc_skp != NULL)
4742 		free_sk(svc_skp);
4743 
4744 	/* Flush the set cache */
4745 	sr_cache_flush_setno(args->cl_sk->sk_setno);
4746 
4747 	return (TRUE);
4748 }
4749 
4750 bool_t
4751 mdrpc_lock_set_1_svc(
4752 	mdrpc_null_args		*args,
4753 	mdrpc_setlock_res	*res,
4754 	struct svc_req		*rqstp		/* RPC stuff */
4755 )
4756 {
4757 	return (mdrpc_lock_set_common(args, res, rqstp));
4758 }
4759 
4760 bool_t
4761 mdrpc_lock_set_2_svc(
4762 	mdrpc_null_args		*args,
4763 	mdrpc_setlock_res	*res,
4764 	struct svc_req		*rqstp		/* RPC stuff */
4765 )
4766 {
4767 	return (mdrpc_lock_set_common(args, res, rqstp));
4768 }
4769 
4770 static void
4771 updmeds(
4772 	char		*setname,
4773 	md_h_arr_t	*medp,
4774 	int		version,	/* RPC version of calling routine */
4775 	md_error_t	*ep
4776 )
4777 {
4778 	mddb_userreq_t		req;
4779 	md_set_record		*sr;
4780 	mddb_med_parm_t		mp;
4781 
4782 	if ((sr = getsetbyname(setname, ep)) == NULL)
4783 		return;
4784 
4785 	sr->sr_med = *medp;			/* structure assignment */
4786 
4787 	(void) memset(&req, '\0', sizeof (req));
4788 
4789 	METAD_SETUP_SR(MD_DB_SETDATA, sr->sr_selfid)
4790 	/* Do MN operation if rpc version supports it and if a MN set */
4791 	if ((version != METAD_VERSION) && (MD_MNSET_REC(sr))) {
4792 		req.ur_size = sizeof (struct md_mnset_record);
4793 	} else {
4794 		req.ur_size = sizeof (*sr);
4795 	}
4796 	req.ur_data = (uintptr_t)sr;
4797 	if (metaioctl(MD_DB_USERREQ, &req, &req.ur_mde, NULL) != 0) {
4798 		(void) mdstealerror(ep, &req.ur_mde);
4799 		free_sr(sr);
4800 		return;
4801 	}
4802 
4803 	commitset(sr, TRUE, ep);
4804 
4805 	/*
4806 	 * If a MN disket, send the mediator list to the kernel.
4807 	 */
4808 	if (MD_MNSET_REC(sr)) {
4809 		(void) memset(&mp, '\0', sizeof (mddb_med_parm_t));
4810 		mp.med_setno = sr->sr_setno;
4811 		if (meta_h2hi(medp, &mp.med, ep)) {
4812 			free_sr(sr);
4813 			return;
4814 		}
4815 
4816 		/* Resolve the IP addresses for the host list */
4817 		if (meta_med_hnm2ip(&mp.med, ep)) {
4818 			free_sr(sr);
4819 			return;
4820 		}
4821 
4822 		/* If node not yet joined to set, failure is ok. */
4823 		if (metaioctl(MD_MED_SET_LST, &mp, &mp.med_mde, NULL) != 0) {
4824 			if (!mdismddberror(&mp.med_mde, MDE_DB_NOTOWNER)) {
4825 				(void) mdstealerror(ep, &mp.med_mde);
4826 			}
4827 		}
4828 	}
4829 	free_sr(sr);
4830 }
4831 
4832 /*
4833  * Update the mediator data in the set record
4834  */
4835 bool_t
4836 mdrpc_updmeds_common(
4837 	mdrpc_updmeds_args	*args,
4838 	mdrpc_generic_res	*res,
4839 	struct svc_req		*rqstp,		/* RPC stuff */
4840 	int			version		/* RPC version */
4841 )
4842 {
4843 	md_error_t		*ep = &res->status;
4844 	int			err;
4845 	int			op_mode = W_OK;
4846 
4847 	/* setup, check permissions */
4848 	(void) memset(res, 0, sizeof (*res));
4849 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4850 		return (FALSE);
4851 	else if (err != 0)
4852 		return (TRUE);
4853 
4854 	if (check_set_lock(op_mode, args->cl_sk, ep))
4855 		return (TRUE);
4856 
4857 	/* doit */
4858 	updmeds(args->sp->setname, &args->meds, version, ep);
4859 
4860 	err = svc_fini(ep);
4861 
4862 	return (TRUE);
4863 }
4864 
4865 bool_t
4866 mdrpc_updmeds_1_svc(
4867 	mdrpc_updmeds_args	*args,
4868 	mdrpc_generic_res	*res,
4869 	struct svc_req		*rqstp		/* RPC stuff */
4870 )
4871 {
4872 	/* Pass RPC version (METAD_VERSION) to common routine */
4873 	return (mdrpc_updmeds_common(args, res, rqstp, METAD_VERSION));
4874 }
4875 
4876 bool_t
4877 mdrpc_updmeds_2_svc(
4878 	mdrpc_updmeds_2_args	*args,
4879 	mdrpc_generic_res	*res,
4880 	struct svc_req		*rqstp		/* RPC stuff */
4881 )
4882 {
4883 	switch (args->rev) {
4884 	    case MD_METAD_ARGS_REV_1:
4885 		/* Pass RPC version (METAD_VERSION_DEVID) to common routine */
4886 		return (mdrpc_updmeds_common(
4887 		    &args->mdrpc_updmeds_2_args_u.rev1, res,
4888 		    rqstp, METAD_VERSION_DEVID));
4889 	    default:
4890 		return (FALSE);
4891 	}
4892 }
4893 
4894 /*
4895  * Call routines to suspend, reinit and resume mdcommd.
4896  * Called during metaset and metadb command.
4897  * NOT called during reconfig cycle.
4898  */
4899 bool_t
4900 mdrpc_mdcommdctl_2_svc(
4901 	mdrpc_mdcommdctl_2_args	*args,
4902 	mdrpc_generic_res	*res,
4903 	struct svc_req		*rqstp		/* RPC stuff */
4904 )
4905 {
4906 	mdrpc_mdcommdctl_args	*args_cc;
4907 	md_error_t		*ep = &res->status;
4908 	int			err;
4909 	int			op_mode = R_OK;
4910 	int			suspend_ret;
4911 
4912 	switch (args->rev) {
4913 	    case MD_METAD_ARGS_REV_1:
4914 		/* setup, check permissions */
4915 		(void) memset(res, 0, sizeof (*res));
4916 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4917 			return (FALSE);
4918 		else if (err != 0)
4919 			return (TRUE);
4920 
4921 		args_cc = &(args->mdrpc_mdcommdctl_2_args_u.rev1);
4922 		switch (args_cc->flag_action) {
4923 			case COMMDCTL_SUSPEND:
4924 				suspend_ret = mdmn_suspend(args_cc->setno,
4925 				    args_cc->class);
4926 				if (suspend_ret != 0) {
4927 					(void) mddserror(ep, suspend_ret,
4928 					    args_cc->setno, mynode(),
4929 					    NULL, mynode());
4930 				}
4931 				break;
4932 			case COMMDCTL_RESUME:
4933 				if (mdmn_resume(args_cc->setno,
4934 				    args_cc->class, args_cc->flags)) {
4935 					(void) mddserror(ep,
4936 					    MDE_DS_COMMDCTL_RESUME_FAIL,
4937 					    args_cc->setno, mynode(),
4938 					    NULL, mynode());
4939 				}
4940 				break;
4941 			case COMMDCTL_REINIT:
4942 				if (mdmn_reinit_set(args_cc->setno)) {
4943 					(void) mddserror(ep,
4944 					    MDE_DS_COMMDCTL_REINIT_FAIL,
4945 					    args_cc->setno, mynode(),
4946 					    NULL, mynode());
4947 				}
4948 				break;
4949 		}
4950 		err = svc_fini(ep);
4951 		return (TRUE);
4952 
4953 	    default:
4954 		return (FALSE);
4955 	}
4956 }
4957 
4958 /*
4959  * Return TRUE if set is stale.
4960  */
4961 bool_t
4962 mdrpc_mn_is_stale_2_svc(
4963 	mdrpc_setno_2_args	*args,
4964 	mdrpc_bool_res		*res,
4965 	struct svc_req		*rqstp		/* RPC stuff */
4966 )
4967 {
4968 	md_error_t	*ep = &res->status;
4969 	mddb_config_t	c;
4970 	int		err;
4971 	int		op_mode = R_OK;
4972 
4973 	(void) memset(&c, 0, sizeof (c));
4974 	switch (args->rev) {
4975 	    case MD_METAD_ARGS_REV_1:
4976 		c.c_id = 0;
4977 		c.c_setno = args->mdrpc_setno_2_args_u.rev1.setno;
4978 
4979 		/* setup, check permissions */
4980 		(void) memset(res, 0, sizeof (*res));
4981 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
4982 			return (FALSE);
4983 		else if (err != 0)
4984 			return (TRUE);
4985 
4986 		if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) {
4987 			mdstealerror(ep, &c.c_mde);
4988 			return (TRUE);
4989 		}
4990 
4991 		if (c.c_flags & MDDB_C_STALE) {
4992 			res->value = TRUE;
4993 		} else {
4994 			res->value = FALSE;
4995 		}
4996 
4997 		err = svc_fini(ep);
4998 		return (TRUE);
4999 
5000 	    default:
5001 		return (FALSE);
5002 	}
5003 }
5004 
5005 /*
5006  * Clear out all clnt_locks held by all MN disksets.
5007  * This is only used during a reconfig cycle.
5008  */
5009 /* ARGSUSED */
5010 int
5011 mdrpc_clr_mnsetlock_2_svc(
5012 	mdrpc_null_args		*args,
5013 	mdrpc_generic_res	*res,
5014 	struct svc_req		*rqstp		/* RPC stuff */
5015 )
5016 {
5017 	set_t			max_sets, setno;
5018 	md_error_t		*ep = &res->status;
5019 	int			err;
5020 	int			op_mode = W_OK;
5021 	mdsetname_t		*sp;
5022 
5023 	/* setup, check permissions */
5024 	(void) memset(res, 0, sizeof (*res));
5025 
5026 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5027 		return (FALSE);
5028 	else if (err != 0)
5029 		return (TRUE);
5030 
5031 	/*
5032 	 * Walk through all possible disksets.
5033 	 * For each MN set, delete all keys associated with that set.
5034 	 */
5035 	if ((max_sets = get_max_sets(ep)) == 0) {
5036 		return (TRUE);
5037 	}
5038 
5039 	/* start walking through all possible disksets */
5040 	for (setno = 1; setno < max_sets; setno++) {
5041 		if ((sp = metasetnosetname(setno, ep)) == NULL) {
5042 			if (mdiserror(ep, MDE_NO_SET)) {
5043 				/* No set for this setno - continue */
5044 				mdclrerror(ep);
5045 				continue;
5046 			} else {
5047 				mde_perror(ep, gettext(
5048 				    "Unable to get set %s information"),
5049 				    sp->setname);
5050 				mdclrerror(ep);
5051 				continue;
5052 			}
5053 		}
5054 
5055 		/* only check multi-node disksets */
5056 		if (!meta_is_mn_set(sp, ep)) {
5057 			mdclrerror(ep);
5058 			continue;
5059 		}
5060 
5061 		/* Delete keys associated with rpc.metad clnt_lock */
5062 		del_sk(setno);
5063 	}
5064 
5065 	*ep = mdnullerror;
5066 
5067 	err = svc_fini(ep);
5068 
5069 	return (TRUE);
5070 }
5071 
5072 /*
5073  * Get drive desc on this host for given setno.
5074  * This is only used during a reconfig cycle.
5075  * Returns a drive desc structure for the given mdsetname
5076  * from this host.
5077  *
5078  * Returned drive desc structure is partially filled in with
5079  * the drive name but is not filled in with any other strings
5080  * in the drivename structure.
5081  */
5082 bool_t
5083 mdrpc_getdrivedesc_2_svc(
5084 	mdrpc_sp_2_args		*args,
5085 	mdrpc_getdrivedesc_res 	*res,
5086 	struct svc_req		*rqstp		/* RPC stuff */
5087 )
5088 {
5089 	md_drive_desc		*dd;
5090 	md_error_t		*ep = &res->status;
5091 	int			err;
5092 	int			op_mode = R_OK;
5093 	mdsetname_t		*my_sp;
5094 	mdrpc_sp_args		*args_r1;
5095 
5096 	switch (args->rev) {
5097 	    case MD_METAD_ARGS_REV_1:
5098 		/* setup, check permissions */
5099 		(void) memset(res, 0, sizeof (*res));
5100 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5101 			return (FALSE);
5102 		else if (err != 0)
5103 			return (TRUE);
5104 
5105 		/* doit */
5106 		args_r1 = &args->mdrpc_sp_2_args_u.rev1;
5107 		if ((my_sp = metasetname(args_r1->sp->setname, ep)) == NULL)
5108 			return (TRUE);
5109 
5110 		dd = metaget_drivedesc(my_sp,
5111 			(MD_BASICNAME_OK | PRINT_FAST), ep);
5112 
5113 		res->dd = dd_list_dup(dd);
5114 
5115 		err = svc_fini(ep);
5116 
5117 		return (TRUE);
5118 	    default:
5119 		return (FALSE);
5120 	}
5121 }
5122 
5123 /*
5124  * Update drive records given list from master during reconfig.
5125  * Make this node's list match the master's list which may include
5126  * deleting a drive record that is known by this node and not known
5127  * by the master node.
5128  *
5129  * Sync up the set/node/drive record genids to match the genid
5130  * passed in the dd structure (all genids in this structure
5131  * are the same).
5132  */
5133 bool_t
5134 mdrpc_upd_dr_reconfig_common(
5135 	mdrpc_upd_dr_flags_2_args_r1	*args,
5136 	mdrpc_generic_res		*res,
5137 	struct svc_req			*rqstp		/* RPC stuff */
5138 )
5139 {
5140 	md_error_t		*ep = &res->status;
5141 	int			err;
5142 	mdsetname_t		*local_sp;
5143 	md_set_record		*sr;
5144 	md_mnset_record		*mnsr;
5145 	md_drive_record		*dr, *dr_placeholder = NULL;
5146 	md_drive_desc		*dd;
5147 	mddrivename_t		*dn, *dn1;
5148 	side_t			sideno;
5149 	md_mnnode_record	*nrp;
5150 	int			op_mode = W_OK;
5151 	int			change = 0;
5152 
5153 	/* setup, check permissions */
5154 	(void) memset(res, 0, sizeof (*res));
5155 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5156 		return (FALSE);
5157 	else if (err != 0)
5158 		return (TRUE);
5159 
5160 	if ((local_sp = metasetname(args->sp->setname, ep)) == NULL)
5161 		return (TRUE);
5162 
5163 	metaflushsetname(local_sp);
5164 
5165 	if ((sideno = getmyside(local_sp, ep)) == MD_SIDEWILD)
5166 		return (TRUE);
5167 
5168 	if ((sr = getsetbyname(args->sp->setname, ep)) == NULL)
5169 		return (TRUE);
5170 
5171 	if (!(MD_MNSET_REC(sr))) {
5172 		free_sr(sr);
5173 		return (TRUE);
5174 	}
5175 
5176 	mnsr = (md_mnset_record *)sr;
5177 	/* Setup genid on set and node records */
5178 	if (args->drivedescs) {
5179 		if (mnsr->sr_genid != args->drivedescs->dd_genid) {
5180 			change = 1;
5181 			mnsr->sr_genid = args->drivedescs->dd_genid;
5182 		}
5183 		nrp = mnsr->sr_nodechain;
5184 		while (nrp) {
5185 			if (nrp->nr_genid != args->drivedescs->dd_genid) {
5186 				change = 1;
5187 				nrp->nr_genid = args->drivedescs->dd_genid;
5188 			}
5189 			nrp = nrp->nr_next;
5190 		}
5191 	}
5192 	for (dr = mnsr->sr_drivechain; dr; dr = dr->dr_next) {
5193 		dn1 = metadrivename_withdrkey(local_sp, sideno,
5194 		    dr->dr_key, (MD_BASICNAME_OK | PRINT_FAST), ep);
5195 		if (dn1 == NULL)
5196 			goto out;
5197 		for (dd = args->drivedescs; dd != NULL; dd = dd->dd_next) {
5198 			dn = dd->dd_dnp;
5199 			/* Found this node's drive rec to match dd */
5200 			if (strcmp(dn->cname, dn1->cname) == 0)
5201 				break;
5202 		}
5203 
5204 		/*
5205 		 * If drive found in master's list, make slave match master.
5206 		 * If drive not found in master's list, remove drive.
5207 		 */
5208 		if (dd) {
5209 			if ((dr->dr_flags != dd->dd_flags) ||
5210 			    (dr->dr_genid != dd->dd_genid)) {
5211 				change = 1;
5212 				dr->dr_flags = dd->dd_flags;
5213 				dr->dr_genid = dd->dd_genid;
5214 			}
5215 		} else {
5216 			/*
5217 			 * Delete entry from linked list.  Need to use
5218 			 * dr_placeholder so that dr->dr_next points to
5219 			 * the next drive record in the list.
5220 			 */
5221 			if (dr_placeholder == NULL) {
5222 				dr_placeholder =
5223 					Zalloc(sizeof (md_drive_record));
5224 			}
5225 			dr_placeholder->dr_next = dr->dr_next;
5226 			dr_placeholder->dr_key = dr->dr_key;
5227 			sr_del_drv(sr, dr->dr_selfid);
5228 			(void) del_sideno_sidenm(dr_placeholder->dr_key,
5229 				sideno, ep);
5230 			change = 1;
5231 			dr = dr_placeholder;
5232 		}
5233 	}
5234 out:
5235 	/* If incore records are correct, don't need to write to disk */
5236 	if (change) {
5237 		/* Don't increment the genid in commitset */
5238 		commitset(sr, FALSE, ep);
5239 	}
5240 	free_sr(sr);
5241 
5242 	err = svc_fini(ep);
5243 
5244 	if (dr_placeholder != NULL)
5245 		Free(dr_placeholder);
5246 
5247 	return (TRUE);
5248 }
5249 
5250 /*
5251  * Version 2 routine to update this node's drive records based on
5252  * list passed in from master node.
5253  */
5254 bool_t
5255 mdrpc_upd_dr_reconfig_2_svc(
5256 	mdrpc_upd_dr_flags_2_args	*args,
5257 	mdrpc_generic_res		*res,
5258 	struct svc_req			*rqstp		/* RPC stuff */
5259 )
5260 {
5261 	switch (args->rev) {
5262 	    case MD_METAD_ARGS_REV_1:
5263 		return (mdrpc_upd_dr_reconfig_common(
5264 		    &args->mdrpc_upd_dr_flags_2_args_u.rev1, res, rqstp));
5265 	    default:
5266 		return (FALSE);
5267 	}
5268 }
5269 
5270 /*
5271  * reset mirror owner for mirrors owned by deleted
5272  * or withdrawn host(s).  Hosts being deleted or
5273  * withdrawn are designated by nodeid since host is
5274  * already deleted or withdrawn from set and may not
5275  * be able to translate between a nodename and a nodeid.
5276  * If an error occurs, ep will be set to that error information.
5277  */
5278 static void
5279 reset_mirror_owner(
5280 	char		*setname,
5281 	int		node_c,
5282 	int		*node_id,	/* Array of node ids */
5283 	md_error_t	*ep
5284 )
5285 {
5286 	mdsetname_t		*local_sp;
5287 	int			i;
5288 	mdnamelist_t		*devnlp = NULL;
5289 	mdnamelist_t		*p;
5290 	mdname_t		*devnp = NULL;
5291 	md_set_mmown_params_t	ownpar_p;
5292 	md_set_mmown_params_t	*ownpar = &ownpar_p;
5293 	char			*miscname;
5294 
5295 	if ((local_sp = metasetname(setname, ep)) == NULL)
5296 		return;
5297 
5298 	/* get a list of all the mirrors for current set */
5299 	if (meta_get_mirror_names(local_sp, &devnlp, 0, ep) < 0)
5300 		return;
5301 
5302 	/* for each mirror */
5303 	for (p = devnlp; (p != NULL); p = p->next) {
5304 		devnp = p->namep;
5305 
5306 		/*
5307 		 * we can only do these for mirrors so make sure we
5308 		 * really have a mirror device and not a softpartition
5309 		 * imitating one. meta_get_mirror_names seems to think
5310 		 * softparts on top of a mirror are mirrors!
5311 		 */
5312 		if ((miscname = metagetmiscname(devnp, ep)) == NULL)
5313 			goto out;
5314 		if (strcmp(miscname, MD_MIRROR) != 0)
5315 			continue;
5316 
5317 		(void) memset(ownpar, 0, sizeof (*ownpar));
5318 		ownpar->d.mnum = meta_getminor(devnp->dev);
5319 		MD_SETDRIVERNAME(ownpar, MD_MIRROR, local_sp->setno);
5320 
5321 		/* get the current owner id */
5322 		if (metaioctl(MD_MN_GET_MM_OWNER, ownpar, ep,
5323 		    "MD_MN_GET_MM_OWNER") != 0) {
5324 			mde_perror(ep, gettext(
5325 			    "Unable to get mirror owner for %s/%s"),
5326 			    local_sp->setname,
5327 			    get_mdname(local_sp, ownpar->d.mnum));
5328 			goto out;
5329 		}
5330 
5331 		if (ownpar->d.owner == MD_MN_MIRROR_UNOWNED) {
5332 			mdclrerror(ep);
5333 			continue;
5334 		}
5335 		/*
5336 		 * reset owner only if the current owner is
5337 		 * in the list of nodes being deleted.
5338 		 */
5339 		for (i = 0; i < node_c; i++) {
5340 			if (ownpar->d.owner == node_id[i]) {
5341 				if (meta_mn_change_owner(&ownpar,
5342 				    local_sp->setno, ownpar->d.mnum,
5343 				    MD_MN_MIRROR_UNOWNED,
5344 				    MD_MN_MM_ALLOW_CHANGE) == -1) {
5345 					mde_perror(ep, gettext(
5346 					    "Unable to reset mirror owner for"
5347 					    " %s/%s"), local_sp->setname,
5348 					    get_mdname(local_sp,
5349 						    ownpar->d.mnum));
5350 					goto out;
5351 				}
5352 				break;
5353 			}
5354 		}
5355 	}
5356 
5357 out:
5358 	/* cleanup */
5359 	metafreenamelist(devnlp);
5360 }
5361 
5362 /*
5363  * Wrapper routine for reset_mirror_owner.
5364  * Called when hosts are deleted or withdrawn
5365  * in order to reset any mirror owners that are needed.
5366  */
5367 bool_t
5368 mdrpc_reset_mirror_owner_common(
5369 	mdrpc_nodeid_args	*args,
5370 	mdrpc_generic_res	*res,
5371 	struct svc_req		*rqstp		/* RPC stuff */
5372 )
5373 {
5374 	md_error_t		*ep = &res->status;
5375 	int			err;
5376 	int			op_mode = W_OK;
5377 
5378 	/* setup, check permissions */
5379 	(void) memset(res, 0, sizeof (*res));
5380 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5381 		return (FALSE);
5382 	else if (err != 0)
5383 		return (TRUE);
5384 
5385 	if (check_set_lock(op_mode, args->cl_sk, ep))
5386 		return (TRUE);
5387 
5388 	/* doit */
5389 	reset_mirror_owner(args->sp->setname, args->nodeid.nodeid_len,
5390 	    args->nodeid.nodeid_val, ep);
5391 
5392 	err = svc_fini(ep);
5393 
5394 	return (TRUE);
5395 }
5396 
5397 /*
5398  * RPC service routine to reset the mirror owner for mirrors owned
5399  * by the given hosts.  Typically, the list of given hosts is a list
5400  * of nodes being deleted or withdrawn from a diskset.
5401  * The given hosts are designated by nodeid since host may
5402  * already be deleted or withdrawn from set and may not
5403  * be able to translate between a nodename and a nodeid.
5404  */
5405 bool_t
5406 mdrpc_reset_mirror_owner_2_svc(
5407 	mdrpc_nodeid_2_args	*args,
5408 	mdrpc_generic_res	*res,
5409 	struct svc_req		*rqstp		/* RPC stuff */
5410 )
5411 {
5412 	switch (args->rev) {
5413 	    case MD_METAD_ARGS_REV_1:
5414 		return (mdrpc_reset_mirror_owner_common(
5415 		    &args->mdrpc_nodeid_2_args_u.rev1, res,
5416 		    rqstp));
5417 	    default:
5418 		return (FALSE);
5419 	}
5420 }
5421 
5422 /*
5423  * Call routines to suspend and resume I/O for the given diskset(s).
5424  * Called during reconfig cycle.
5425  * Diskset of 0 represents all MN disksets.
5426  */
5427 bool_t
5428 mdrpc_mn_susp_res_io_2_svc(
5429 	mdrpc_mn_susp_res_io_2_args	*args,
5430 	mdrpc_generic_res		*res,
5431 	struct svc_req			*rqstp		/* RPC stuff */
5432 )
5433 {
5434 	mdrpc_mn_susp_res_io_args	*args_sr;
5435 	md_error_t			*ep = &res->status;
5436 	int				err;
5437 	int				op_mode = R_OK;
5438 
5439 	switch (args->rev) {
5440 	    case MD_METAD_ARGS_REV_1:
5441 		/* setup, check permissions */
5442 		(void) memset(res, 0, sizeof (*res));
5443 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5444 			return (FALSE);
5445 		else if (err != 0)
5446 			return (TRUE);
5447 
5448 		args_sr = &(args->mdrpc_mn_susp_res_io_2_args_u.rev1);
5449 		switch (args_sr->susp_res_cmd) {
5450 		case MN_SUSP_IO:
5451 			(void) (metaioctl(MD_MN_SUSPEND_SET,
5452 				&args_sr->susp_res_setno, ep, NULL));
5453 			break;
5454 		case MN_RES_IO:
5455 			(void) (metaioctl(MD_MN_RESUME_SET,
5456 				&args_sr->susp_res_setno, ep, NULL));
5457 			break;
5458 		}
5459 		err = svc_fini(ep);
5460 		return (TRUE);
5461 
5462 	    default:
5463 		return (FALSE);
5464 	}
5465 }
5466 
5467 /*
5468  * Resnarf a set after it has been imported
5469  */
5470 bool_t
5471 mdrpc_resnarf_set_2_svc(
5472 	mdrpc_setno_2_args	*args,
5473 	mdrpc_generic_res	*res,
5474 	struct svc_req		*rqstp		/* RPC stuff */
5475 )
5476 {
5477 	mdrpc_setno_args	*setno_args;
5478 	md_error_t		*ep = &res->status;
5479 	int			err;
5480 	int			op_mode = R_OK;
5481 
5482 	switch (args->rev) {
5483 	    case MD_METAD_ARGS_REV_1:
5484 		setno_args = &args->mdrpc_setno_2_args_u.rev1;
5485 		break;
5486 	    default:
5487 		return (FALSE);
5488 	}
5489 
5490 	(void) memset(res, 0, sizeof (*res));
5491 	if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5492 		return (FALSE);
5493 	else if (err != 0)
5494 		return (TRUE);
5495 
5496 	/* do it */
5497 	if (resnarf_set(setno_args->setno, ep) < 0)
5498 		return (FALSE);
5499 
5500 	err = svc_fini(ep);
5501 	return (TRUE);
5502 }
5503 
5504 /*
5505  * Creates a resync thread.
5506  * Always returns true.
5507  */
5508 bool_t
5509 mdrpc_mn_mirror_resync_all_2_svc(
5510 	mdrpc_setno_2_args	*args,
5511 	mdrpc_generic_res	*res,
5512 	struct svc_req		*rqstp		/* RPC stuff */
5513 )
5514 {
5515 	md_error_t		*ep = &res->status;
5516 	mdrpc_setno_args	*setno_args;
5517 	int			err;
5518 	int			op_mode = R_OK;
5519 
5520 	switch (args->rev) {
5521 	    case MD_METAD_ARGS_REV_1:
5522 		/* setup, check permissions */
5523 		(void) memset(res, 0, sizeof (*res));
5524 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5525 			return (FALSE);
5526 		else if (err != 0)
5527 			return (TRUE);
5528 		setno_args = &args->mdrpc_setno_2_args_u.rev1;
5529 
5530 		/*
5531 		 * Need to invoke a metasync on a node newly added to a set.
5532 		 */
5533 		meta_mn_mirror_resync_all(&(setno_args->setno));
5534 
5535 		err = svc_fini(ep);
5536 		return (TRUE);
5537 
5538 	    default:
5539 		return (FALSE);
5540 	}
5541 }
5542 
5543 /*
5544  * Updates ABR state for all softpartitions. Calls meta_mn_sp_update_abr(),
5545  * which forks a daemon process to perform this action.
5546  * Always returns true.
5547  */
5548 bool_t
5549 mdrpc_mn_sp_update_abr_2_svc(
5550 	mdrpc_setno_2_args	*args,
5551 	mdrpc_generic_res	*res,
5552 	struct svc_req		*rqstp		/* RPC stuff */
5553 )
5554 {
5555 	md_error_t		*ep = &res->status;
5556 	mdrpc_setno_args	*setno_args;
5557 	int			err;
5558 	int			op_mode = R_OK;
5559 
5560 	switch (args->rev) {
5561 	    case MD_METAD_ARGS_REV_1:
5562 		/* setup, check permissions */
5563 		(void) memset(res, 0, sizeof (*res));
5564 		if ((err = svc_init(rqstp, op_mode, ep)) < 0)
5565 			return (FALSE);
5566 		else if (err != 0)
5567 			return (TRUE);
5568 		setno_args = &args->mdrpc_setno_2_args_u.rev1;
5569 
5570 		meta_mn_sp_update_abr(&(setno_args->setno));
5571 
5572 		err = svc_fini(ep);
5573 		return (TRUE);
5574 
5575 	    default:
5576 		return (FALSE);
5577 	}
5578 }
5579