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