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