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