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