xref: /titanic_41/usr/src/lib/lvm/libmeta/common/meta_set.c (revision 0541156464ba74bca005fda4b225d3bbe53f7a0c)
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 /*
30  * Just in case we're not in a build environment, make sure that
31  * TEXT_DOMAIN gets set to something.
32  */
33 #if !defined(TEXT_DOMAIN)
34 #define	TEXT_DOMAIN "SYS_TEST"
35 #endif
36 
37 /*
38  * Metadevice diskset interfaces
39  */
40 
41 #include "meta_set_prv.h"
42 #include <meta.h>
43 #include <metad.h>
44 #include <mdmn_changelog.h>
45 #include <sys/lvm/md_crc.h>
46 #include <sys/utsname.h>
47 #include <sdssc.h>
48 
49 #include <sys/sysevent/eventdefs.h>
50 #include <sys/sysevent/svm.h>
51 extern	char	*blkname(char *);
52 
53 static md_drive_desc *
54 dr2drivedesc(
55 	mdsetname_t	*sp,
56 	side_t		sideno,
57 	int		flags,
58 	md_error_t	*ep
59 )
60 {
61 	md_set_record	*sr;
62 	md_drive_record	*dr;
63 	mddrivename_t	*dnp;
64 	md_drive_desc	*dd_head = NULL;
65 	md_set_desc	*sd;
66 
67 	if (flags & MD_BYPASS_DAEMON) {
68 		if ((sr = metad_getsetbynum(sp->setno, ep)) == NULL)
69 			return (NULL);
70 		sd = metaget_setdesc(sp, ep);
71 		sideno = getnodeside(mynode(), sd);
72 		sp = metafakesetname(sp->setno, sr->sr_setname);
73 	} else {
74 		if ((sr = getsetbyname(sp->setname, ep)) == NULL)
75 			return (NULL);
76 	}
77 
78 	assert(sideno != MD_SIDEWILD);
79 
80 	/*
81 	 * WARNING:
82 	 * The act of getting the dnp from the namespace means that we
83 	 * will get the devid of the disk as recorded in the namespace.
84 	 * This devid has the potential to be stale if the disk is being
85 	 * replaced via a rebind, this means that any code that relies
86 	 * on any of the dnp information should take the appropriate action
87 	 * to preserve that information. For example in the rebind code the
88 	 * devid of the new disk is saved off and then copied back in once
89 	 * the code that has called this function has completed.
90 	 */
91 	for (dr = sr->sr_drivechain; dr != NULL; dr = dr->dr_next) {
92 		if ((dnp = metadrivename_withdrkey(sp, sideno, dr->dr_key,
93 		    flags, ep)) == NULL) {
94 			if (!(flags & MD_BYPASS_DAEMON))
95 				free_sr(sr);
96 			metafreedrivedesc(&dd_head);
97 			return (NULL);
98 		}
99 
100 		(void) metadrivedesc_append(&dd_head, dnp, dr->dr_dbcnt,
101 		    dr->dr_dbsize, dr->dr_ctime, dr->dr_genid, dr->dr_flags);
102 	}
103 
104 	if (!(flags & MD_BYPASS_DAEMON)) {
105 		free_sr(sr);
106 	}
107 	return (dd_head);
108 }
109 
110 static int
111 get_sidenmlist(
112 	mdsetname_t	*sp,
113 	mddrivename_t	*dnp,
114 	md_error_t	*ep
115 )
116 {
117 	md_set_desc	*sd;
118 	mdsidenames_t	*sn, **sn_next;
119 	int		i;
120 
121 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
122 		return (-1);
123 
124 	metaflushsidenames(dnp);
125 	sn_next = &dnp->side_names;
126 	if (MD_MNSET_DESC(sd)) {
127 		/*
128 		 * Only get sidenames for this node since
129 		 * that is the only side information stored in
130 		 * the local mddb for a multi-node diskset.
131 		 */
132 		if (sd->sd_mn_mynode) {
133 			sn = Zalloc(sizeof (*sn));
134 			sn->sideno = sd->sd_mn_mynode->nd_nodeid;
135 			if ((sn->cname = meta_getnmentbykey(MD_LOCAL_SET,
136 			    sn->sideno, dnp->side_names_key, &sn->dname,
137 			    &sn->mnum, NULL, ep)) == NULL) {
138 				if (sn->dname != NULL)
139 					Free(sn->dname);
140 				Free(sn);
141 				return (-1);
142 			}
143 
144 			/* Add to the end of the linked list */
145 			assert(*sn_next == NULL);
146 			*sn_next = sn;
147 			sn_next = &sn->next;
148 		}
149 	} else {
150 		for (i = 0; i < MD_MAXSIDES; i++) {
151 			/* Skip empty slots */
152 			if (sd->sd_nodes[i][0] == '\0')
153 				continue;
154 
155 			sn = Zalloc(sizeof (*sn));
156 			sn->sideno = i;
157 			if ((sn->cname = meta_getnmentbykey(MD_LOCAL_SET,
158 			    i+SKEW, dnp->side_names_key, &sn->dname,
159 			    &sn->mnum, NULL, ep)) == NULL) {
160 				/*
161 				 * It is possible that during the add of a
162 				 * host to have a 'missing' side as the side
163 				 * for this disk will be added later. So ignore
164 				 * the error. The 'missing' side will be added
165 				 * once the addhosts process has completed.
166 				 */
167 				if (mdissyserror(ep, ENOENT)) {
168 					mdclrerror(ep);
169 					Free(sn);
170 					continue;
171 				}
172 
173 				if (sn->dname != NULL)
174 					Free(sn->dname);
175 				Free(sn);
176 				return (-1);
177 			}
178 
179 			/* Add to the end of the linked list */
180 			assert(*sn_next == NULL);
181 			*sn_next = sn;
182 			sn_next = &sn->next;
183 		}
184 	}
185 
186 	return (0);
187 }
188 
189 static md_drive_desc *
190 rl_to_dd(
191 	mdsetname_t		*sp,
192 	md_replicalist_t	*rlp,
193 	md_error_t		*ep
194 )
195 {
196 	md_replicalist_t	*rl;
197 	md_replica_t		*r;
198 	md_drive_desc		*dd = NULL;
199 	md_drive_desc		*d;
200 	int			found;
201 	md_set_desc		*sd;
202 	daddr_t			nblks = 0;
203 
204 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
205 		return (NULL);
206 
207 	/* find the smallest existing replica */
208 	for (rl = rlp; rl != NULL; rl = rl->rl_next) {
209 		r = rl->rl_repp;
210 		nblks = ((nblks == 0) ? r->r_nblk : min(r->r_nblk, nblks));
211 	}
212 
213 	if (nblks <= 0)
214 		nblks = (MD_MNSET_DESC(sd)) ? MD_MN_DBSIZE : MD_DBSIZE;
215 
216 	for (rl = rlp; rl != NULL; rl = rl->rl_next) {
217 		r = rl->rl_repp;
218 
219 		found = 0;
220 		for (d = dd; d != NULL; d = d->dd_next) {
221 			if (strcmp(r->r_namep->drivenamep->cname,
222 			    d->dd_dnp->cname) == 0) {
223 				found = 1;
224 				dd->dd_dbcnt++;
225 				break;
226 			}
227 		}
228 
229 		if (! found)
230 			(void) metadrivedesc_append(&dd, r->r_namep->drivenamep,
231 			    1, nblks, sd->sd_ctime, sd->sd_genid, MD_DR_OK);
232 	}
233 
234 	return (dd);
235 }
236 
237 /*
238  * Exported Entry Points
239  */
240 
241 set_t
242 get_max_sets(md_error_t *ep)
243 {
244 
245 	static set_t		max_sets = 0;
246 
247 	if (max_sets == 0)
248 		if (metaioctl(MD_IOCGETNSET, &max_sets, ep, NULL) != 0)
249 			return (0);
250 
251 	return (max_sets);
252 }
253 
254 int
255 get_max_meds(md_error_t *ep)
256 {
257 	static int		max_meds = 0;
258 
259 	if (max_meds == 0)
260 		if (metaioctl(MD_MED_GET_NMED, &max_meds, ep, NULL) != 0)
261 			return (0);
262 
263 	return (max_meds);
264 }
265 
266 side_t
267 getmyside(mdsetname_t *sp, md_error_t *ep)
268 {
269 	md_set_desc		*sd;
270 	char 			*node = NULL;
271 	side_t			sideno;
272 
273 	if (sp->setno == 0)
274 		return (0);
275 
276 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
277 		return (MD_SIDEWILD);
278 
279 	node = mynode();
280 
281 	assert(node != NULL);
282 
283 	sideno = getnodeside(node, sd);
284 
285 	if (sideno != MD_SIDEWILD)
286 		return (sideno);
287 
288 	return (mddserror(ep, MDE_DS_HOSTNOSIDE, sp->setno, node, NULL, node));
289 }
290 
291 /*
292  * get set info from name
293  */
294 md_set_record *
295 getsetbyname(char *setname, md_error_t *ep)
296 {
297 	md_set_record		*sr = NULL;
298 	md_mnset_record		*mnsr = NULL;
299 	char			*p;
300 	size_t			len;
301 
302 	/* get set info from daemon */
303 	if (clnt_getset(mynode(), setname, MD_SET_BAD, &sr, ep) == -1)
304 		return (NULL);
305 	if (sr != NULL) {
306 		/*
307 		 * Returned record could be for a multi-node set or a
308 		 * non-multi-node set.
309 		 */
310 		if (MD_MNSET_REC(sr)) {
311 			/*
312 			 * Record is for a multi-node set.  Reissue call
313 			 * to get mnset information.  Need to free
314 			 * record as if a non-multi-node set record since
315 			 * that is what clnt_getset gave us.  If in
316 			 * the daemon, don't free since this is a pointer
317 			 * into the setrecords array.
318 			 */
319 			if (! md_in_daemon) {
320 				sr->sr_flags &= ~MD_SR_MN;
321 				free_sr(sr);
322 			}
323 			if (clnt_mngetset(mynode(), setname, MD_SET_BAD, &mnsr,
324 			    ep) == -1)
325 				return (NULL);
326 			if (mnsr != NULL)
327 				return ((struct md_set_record *)mnsr);
328 		} else {
329 			return (sr);
330 		}
331 	}
332 
333 	/* no such set */
334 	len = strlen(setname) + 30;
335 	p = Malloc(len);
336 	(void) snprintf(p, len, "setname \"%s\"", setname);
337 	(void) mderror(ep, MDE_NO_SET, p);
338 	Free(p);
339 	return (NULL);
340 }
341 
342 /*
343  * get set info from number
344  */
345 md_set_record *
346 getsetbynum(set_t setno, md_error_t *ep)
347 {
348 	md_set_record		*sr;
349 	md_mnset_record		*mnsr = NULL;
350 	char			buf[100];
351 
352 	if (clnt_getset(mynode(), NULL, setno, &sr, ep) == -1)
353 		return (NULL);
354 
355 	if (sr != NULL) {
356 		/*
357 		 * Record is for a multi-node set.  Reissue call
358 		 * to get mnset information.  Need to free
359 		 * record as if a non-multi-node set record since
360 		 * that is what clnt_getset gave us.  If in
361 		 * the daemon, don't free since this is a pointer
362 		 * into the setrecords array.
363 		 */
364 		if (MD_MNSET_REC(sr)) {
365 			/*
366 			 * Record is for a multi-node set.  Reissue call
367 			 * to get mnset information.
368 			 */
369 			if (! md_in_daemon) {
370 				sr->sr_flags &= ~MD_SR_MN;
371 				free_sr(sr);
372 			}
373 			if (clnt_mngetset(mynode(), NULL, setno, &mnsr,
374 			    ep) == -1)
375 				return (NULL);
376 			if (mnsr != NULL)
377 				return ((struct md_set_record *)mnsr);
378 		} else {
379 			return (sr);
380 		}
381 	}
382 
383 	(void) sprintf(buf, "setno %u", setno);
384 	(void) mderror(ep, MDE_NO_SET, buf);
385 	return (NULL);
386 }
387 
388 int
389 meta_check_drive_inuse(
390 	mdsetname_t	*sp,
391 	mddrivename_t	*dnp,
392 	int		check_db,
393 	md_error_t	*ep
394 )
395 {
396 	mdnamelist_t	*nlp = NULL;
397 	mdnamelist_t	*p;
398 	int		rval = 0;
399 
400 	/* get all underlying partitions */
401 	if (meta_getalldevs(sp, &nlp, check_db, ep) != 0)
402 		return (-1);
403 
404 	/* search for drive */
405 	for (p = nlp; (p != NULL); p = p->next) {
406 		mdname_t	*np = p->namep;
407 
408 		if (strcmp(dnp->cname, np->drivenamep->cname) == 0) {
409 			rval = (mddserror(ep, MDE_DS_DRIVEINUSE, sp->setno,
410 			    NULL, dnp->cname, sp->setname));
411 			break;
412 		}
413 	}
414 
415 	/* cleanup, return success */
416 	metafreenamelist(nlp);
417 	return (rval);
418 }
419 
420 /*
421  * simple check for ownership
422  */
423 int
424 meta_check_ownership(mdsetname_t *sp, md_error_t *ep)
425 {
426 	int			ownset;
427 	md_set_desc		*sd;
428 	md_drive_desc		*dd;
429 	md_replicalist_t	*rlp = NULL;
430 	md_error_t		xep = mdnullerror;
431 
432 	if (metaislocalset(sp))
433 		return (0);
434 
435 	ownset = own_set(sp, NULL, TRUE, ep);
436 	if (! mdisok(ep))
437 		return (-1);
438 
439 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
440 		return (-1);
441 
442 	dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST), ep);
443 	if (! mdisok(ep))
444 		return (-1);
445 
446 	/* If we have no drive descriptors, check for no ownership */
447 	if (dd == NULL) {
448 		if (ownset == MD_SETOWNER_NONE)
449 			return (0);
450 
451 		/* If ownership somehow has come to exist, we must clean up */
452 
453 		if (metareplicalist(sp, (MD_BASICNAME_OK | PRINT_FAST), &rlp,
454 		    &xep) < 0)
455 			mdclrerror(&xep);
456 
457 		if ((dd = rl_to_dd(sp, rlp, &xep)) == NULL)
458 			if (! mdisok(&xep))
459 				mdclrerror(&xep);
460 
461 		if (!(MD_MNSET_DESC(sd)) && !MD_ATSET_DESC(sd)) {
462 			if (rel_own_bydd(sp, dd, TRUE, &xep))
463 				mdclrerror(&xep);
464 		}
465 
466 		if (halt_set(sp, &xep))
467 			mdclrerror(&xep);
468 
469 		metafreereplicalist(rlp);
470 
471 		metafreedrivedesc(&dd);
472 
473 		return (0);
474 	}
475 
476 	metafreedrivedesc(&sd->sd_drvs);
477 
478 	if (ownset == MD_SETOWNER_YES)
479 		return (0);
480 
481 	return (mddserror(ep, MDE_DS_NOOWNER, sp->setno, NULL, NULL,
482 	    sp->setname));
483 }
484 
485 /*
486  * simple check for ownership
487  */
488 int
489 meta_check_ownership_on_host(mdsetname_t *sp, char *hostname, md_error_t *ep)
490 {
491 	md_set_desc	*sd;
492 	md_drive_desc	*dd;
493 	int		bool;
494 
495 	if (metaislocalset(sp))
496 		return (0);
497 
498 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
499 		return (-1);
500 
501 	if (getnodeside(hostname, sd) == MD_SIDEWILD)
502 		return (mddserror(ep, MDE_DS_NODENOTINSET, sp->setno,
503 		    hostname, NULL, sp->setname));
504 
505 	dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST), ep);
506 	if (! mdisok(ep))
507 		return (-1);
508 
509 	if (clnt_ownset(hostname, sp, &bool, ep) == -1)
510 		return (-1);
511 
512 	if (dd == NULL)
513 		return (0);
514 
515 	metafreedrivedesc(&sd->sd_drvs);
516 
517 	if (bool == TRUE)
518 		return (0);
519 
520 	return (mddserror(ep, MDE_DS_NODEISNOTOWNER, sp->setno, hostname, NULL,
521 	    sp->setname));
522 }
523 
524 /*
525  * Function that determines if a node is in the multinode diskset
526  * membership list.  Calling node passes in node to be checked and
527  * the nodelist as returned from meta_read_nodelist.  This routine
528  * anticipates being called many times using the same diskset membership
529  * list which is why the alloc and free of the diskset membership list
530  * is left to the calling routine.
531  * Returns:
532  *	1 - if a member
533  *	0 - not a member
534  */
535 int
536 meta_is_member(
537 	char				*node_name,
538 	md_mn_nodeid_t			node_id,
539 	mndiskset_membershiplist_t	*nl
540 )
541 {
542 	mndiskset_membershiplist_t	*nl2;
543 	int				flag_check_name;
544 
545 	if (node_id != 0)
546 		flag_check_name = 0;
547 	else if (node_name != NULL)
548 		flag_check_name = 1;
549 	else
550 		return (0);
551 
552 	nl2 = nl;
553 	while (nl2) {
554 		if (flag_check_name) {
555 			/* Compare given name against name in member list */
556 			if (strcmp(nl2->msl_node_name, node_name) == 0)
557 				break;
558 		} else {
559 			/* Compare given nodeid against nodeid in member list */
560 			if (nl2->msl_node_id == node_id)
561 				break;
562 		}
563 		nl2 = nl2->next;
564 	}
565 	/* No match found in member list */
566 	if (nl2 == NULL) {
567 		return (0);
568 	}
569 	/* Return 1 if node is in member list */
570 	return (1);
571 }
572 
573 /*
574  * meta_getnext_devinfo should go to the host that
575  * has the device, to return the device name, driver name, minor num.
576  * We can take the big cheat for now, since it is a requirement
577  * that the device names and device numbers are the same, and
578  * just get the info locally.
579  *
580  * This routine is very similar to meta_getnextside_devinfo except
581  * that the specific side to be used is being passed in.
582  *
583  * Exit status:
584  *	 0 - No more side info to return
585  *	 1 - More side info's to return
586  *	-1 - An error has been detected
587  */
588 /*ARGSUSED*/
589 int
590 meta_getside_devinfo(
591 	mdsetname_t	*sp,		/* for this set */
592 	char		*bname,		/* local block name (myside) */
593 	side_t		sideno,		/* sideno */
594 	char		**ret_bname,	/* block device name of returned side */
595 	char		**ret_dname,	/* driver name of returned side */
596 	minor_t		*ret_mnum,	/* minor number of returned side */
597 	md_error_t	*ep
598 )
599 {
600 	mdname_t	*np;
601 
602 	if (ret_bname != NULL)
603 		*ret_bname = NULL;
604 	if (ret_dname != NULL)
605 		*ret_dname = NULL;
606 	if (ret_mnum != NULL)
607 		*ret_mnum = NODEV32;
608 
609 
610 	if ((np = metaname(&sp, bname, ep)) == NULL)
611 		return (-1);
612 
613 /*
614  * NOTE (future) - There will be more work here once devids are integrated
615  * into disksets.  Then the side should be used to find the correct
616  * host and the b/d names should be gotten from that host.
617  */
618 
619 	/*
620 	 * Return the side info.
621 	 */
622 	if (ret_bname != NULL)
623 		*ret_bname = Strdup(np->bname);
624 
625 	if (ret_dname != NULL) {
626 		mdcinfo_t	*cinfo;
627 
628 		if ((cinfo = metagetcinfo(np, ep)) == NULL)
629 			return (-1);
630 
631 		*ret_dname = Strdup(cinfo->dname);
632 	}
633 
634 	if (ret_mnum != NULL)
635 		*ret_mnum = meta_getminor(np->dev);
636 
637 	return (1);
638 }
639 
640 /*
641  * Get the information on the device from the remote node using the devid
642  * of the disk.
643  *
644  * Exit status:
645  *	 0 - No more side info to return
646  *	 1 - More side info's to return
647  *	-1 - An error has been detected
648  */
649 int
650 meta_getnextside_devinfo(
651 	mdsetname_t	*sp,		/* for this set */
652 	char		*bname,		/* local block name (myside) */
653 	side_t		*sideno,	/* previous sideno & returned sideno */
654 	char		**ret_bname,	/* block device name of returned side */
655 	char		**ret_dname,	/* driver name of returned side */
656 	minor_t		*ret_mnum,	/* minor number of returned side */
657 	md_error_t	*ep
658 )
659 {
660 	md_set_desc	*sd;
661 	int		i;
662 	mdname_t	*np;
663 	mddrivename_t	*dnp;
664 	char		*devidstr = NULL;
665 	int		devidstrlen;
666 	md_dev64_t	retdev = NODEV64;
667 	char		*ret_devname = NULL;
668 	char		*ret_blkdevname = NULL;
669 	char		*ret_driver = NULL;
670 	char		*nodename;
671 	int		fd;
672 	int		ret = -1;
673 	char		*minor_name = NULL;
674 	md_mnnode_desc	*nd;
675 
676 
677 	if (ret_bname != NULL)
678 		*ret_bname = NULL;
679 	if (ret_dname != NULL)
680 		*ret_dname = NULL;
681 	if (ret_mnum != NULL)
682 		*ret_mnum = NODEV32;
683 
684 	if (metaislocalset(sp)) {
685 		/* no more sides - we are done */
686 		if (*sideno != MD_SIDEWILD)
687 			return (0);
688 
689 		/* First time through -  set up return sideno */
690 		*sideno = 0;
691 	} else {
692 
693 		/*
694 		 * Find the next sideno, starting after the one given.
695 		 */
696 		if ((sd = metaget_setdesc(sp, ep)) == NULL)
697 			return (-1);
698 
699 		if (MD_MNSET_DESC(sd)) {
700 			nd = sd->sd_nodelist;
701 			if ((*sideno == MD_SIDEWILD) &&
702 			    (nd != (struct md_mnnode_desc *)NULL)) {
703 				*sideno = nd->nd_nodeid;
704 			} else {
705 				while (nd) {
706 					/*
707 					 * Found given sideno, now find
708 					 * next sideno, if there is one.
709 					 */
710 					if ((*sideno == nd->nd_nodeid) &&
711 					    (nd->nd_next !=
712 					    (struct md_mnnode_desc *)NULL)) {
713 						*sideno =
714 						    nd->nd_next->nd_nodeid;
715 						break;
716 					}
717 					nd = nd->nd_next;
718 				}
719 				if (nd == NULL) {
720 					return (0);
721 				}
722 			}
723 			if (*sideno == MD_SIDEWILD)
724 				return (0);
725 		} else {
726 			for (i = (*sideno)+1; i < MD_MAXSIDES; i++)
727 				/* Find next full slot */
728 				if (sd->sd_nodes[i][0] != '\0')
729 					break;
730 
731 			/* No more sides - we are done */
732 			if (i == MD_MAXSIDES)
733 				return (0);
734 
735 			/* Set up the return sideno */
736 			*sideno = i;
737 			nodename = (char *)sd->sd_nodes[i];
738 		}
739 	}
740 
741 	/*
742 	 * Need to pass the node the devid of the disk and get it to
743 	 * send back the details of the disk from that side.
744 	 */
745 	if ((np = metaname(&sp, bname, ep)) == NULL)
746 		return (-1);
747 
748 	dnp = np->drivenamep;
749 
750 	/*
751 	 * By default, set up the parameters so that they are copied out.
752 	 */
753 	if (ret_bname != NULL)
754 		*ret_bname = Strdup(np->bname);
755 
756 	if (ret_dname != NULL) {
757 		mdcinfo_t	*cinfo;
758 
759 		if ((cinfo = metagetcinfo(np, ep)) == NULL)
760 			return (-1);
761 
762 		*ret_dname = Strdup(cinfo->dname);
763 	}
764 
765 	if (ret_mnum != NULL)
766 		*ret_mnum = meta_getminor(np->dev);
767 
768 	/*
769 	 * Try some optimization. If this is the local set or the device
770 	 * is a metadevice then just copy the information. If the device
771 	 * does not have a devid (due to not having a minor name) then
772 	 * fall back to the pre-devid behaviour of copying the information
773 	 * on the device: this is okay because the sanity checks before this
774 	 * call would have found any issues with the device. If it's a
775 	 * multi-node diskset also just return ie. copy.
776 	 */
777 	if (metaislocalset(sp) || metaismeta(np) || (dnp->devid == NULL) ||
778 	    (MD_MNSET_DESC(sd)))
779 		return (1);
780 
781 	if (np->minor_name == (char *)NULL) {
782 		/*
783 		 * Have to get the minor name then. The slice should exist
784 		 * on the disk because it will have already been repartitioned
785 		 * up prior to getting to this point.
786 		 */
787 		if ((fd = open(np->bname, (O_RDONLY|O_NDELAY), 0)) < 0) {
788 			(void) mdsyserror(ep, errno, np->bname);
789 			return (-1);
790 		}
791 		(void) devid_get_minor_name(fd, &minor_name);
792 		np->minor_name = Strdup(minor_name);
793 		devid_str_free(minor_name);
794 		(void) close(fd);
795 	}
796 
797 	/* allocate extra space for "/" and NULL hence +2 */
798 	devidstrlen = strlen(dnp->devid) + strlen(np->minor_name) + 2;
799 	devidstr = (char *)Malloc(devidstrlen);
800 
801 	/*
802 	 * As a minor name is supplied then the ret_devname will be
803 	 * appropriate to that minor_name and in this case it will be
804 	 * a block device ie /dev/dsk.
805 	 */
806 	(void) snprintf(devidstr, devidstrlen,
807 		"%s/%s", dnp->devid, np->minor_name);
808 
809 	ret = clnt_devinfo_by_devid(nodename, sp, devidstr, &retdev,
810 	    np->bname, &ret_devname, &ret_driver, ep);
811 
812 	Free(devidstr);
813 
814 	/*
815 	 * If the other side is not running device id in disksets,
816 	 * 'ret' is set to ENOTSUP in which case we fallback to
817 	 * the existing behaviour
818 	 */
819 	if (ret == ENOTSUP)
820 		return (1);
821 	else if (ret == -1)
822 		return (-1);
823 
824 	/*
825 	 * ret_devname comes from the rpc call and is a
826 	 * raw device name. We need to make this into a
827 	 * block device via blkname for further processing.
828 	 * Unfortunately, when our device id isn't found in
829 	 * the system, the rpc call will return a " " in
830 	 * ret_devname in which case we need to fill that in
831 	 * as ret_blkname because blkname of " " returns NULL.
832 	 */
833 	if (ret_bname != NULL && ret_devname != NULL) {
834 		ret_blkdevname = blkname(ret_devname);
835 		if (ret_blkdevname == NULL)
836 			*ret_bname = Strdup(ret_devname);
837 		else
838 			*ret_bname = Strdup(ret_blkdevname);
839 	}
840 
841 	if (ret_dname != NULL && ret_driver != NULL)
842 		*ret_dname = Strdup(ret_driver);
843 
844 	if (ret_mnum != NULL)
845 		*ret_mnum = meta_getminor(retdev);
846 
847 	return (1);
848 }
849 
850 int
851 meta_is_drive_in_anyset(
852 	mddrivename_t	*dnp,
853 	mdsetname_t	**spp,
854 	int		bypass_daemon,
855 	md_error_t 	*ep
856 )
857 {
858 	set_t		setno;
859 	mdsetname_t	*this_sp;
860 	int		is_it;
861 	set_t		max_sets;
862 
863 	if ((max_sets = get_max_sets(ep)) == 0)
864 		return (-1);
865 
866 	assert(spp != NULL);
867 	*spp = NULL;
868 
869 	for (setno = 1; setno < max_sets; setno++) {
870 		if (!bypass_daemon) {
871 			if ((this_sp = metasetnosetname(setno, ep)) == NULL) {
872 				if (mdismddberror(ep, MDE_DB_NODB)) {
873 					mdclrerror(ep);
874 					return (0);
875 				}
876 				if (mdiserror(ep, MDE_NO_SET)) {
877 					mdclrerror(ep);
878 					continue;
879 				}
880 				return (-1);
881 			}
882 		} else
883 			this_sp = metafakesetname(setno, NULL);
884 
885 		if ((is_it = meta_is_drive_in_thisset(this_sp, dnp,
886 		    bypass_daemon, ep)) == -1) {
887 			if (mdiserror(ep, MDE_NO_SET)) {
888 				mdclrerror(ep);
889 				continue;
890 			}
891 			return (-1);
892 		}
893 		if (is_it) {
894 			*spp = this_sp;
895 			return (0);
896 		}
897 	}
898 	return (0);
899 }
900 
901 int
902 meta_is_drive_in_thisset(
903 	mdsetname_t	*sp,
904 	mddrivename_t	*dnp,
905 	int		bypass_daemon,
906 	md_error_t	*ep
907 )
908 {
909 	md_drive_desc	*dd, *p;
910 
911 	if (bypass_daemon)
912 		dd = dr2drivedesc(sp, MD_SIDEWILD,
913 		    (MD_BASICNAME_OK | MD_BYPASS_DAEMON), ep);
914 	else
915 		dd = metaget_drivedesc(sp, MD_BASICNAME_OK, ep);
916 
917 	if (dd == NULL) {
918 		if (! mdisok(ep))
919 			return (-1);
920 		return (0);
921 	}
922 
923 
924 	for (p = dd; p != NULL; p = p->dd_next)
925 		if (strcmp(p->dd_dnp->cname, dnp->cname) == 0)
926 			return (1);
927 	return (0);
928 }
929 
930 int
931 meta_set_balance(
932 	mdsetname_t		*sp,
933 	md_error_t		*ep
934 )
935 {
936 	md_set_desc		*sd;
937 	md_drive_desc		*dd, *curdd;
938 	daddr_t			dbsize;
939 	daddr_t			nblks;
940 	int			i;
941 	int			rval = 0;
942 	sigset_t		oldsigs;
943 	md_setkey_t		*cl_sk;
944 	md_error_t		xep = mdnullerror;
945 	md_mnnode_desc		*nd;
946 	int			suspend1_flag = 0;
947 
948 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
949 		return (-1);
950 
951 	dbsize = (MD_MNSET_DESC(sd)) ? MD_MN_DBSIZE : MD_DBSIZE;
952 
953 	/* Make sure we own the set */
954 	if (meta_check_ownership(sp, ep) != 0)
955 		return (-1);
956 
957 	/* END CHECK CODE */
958 
959 	/*
960 	 * Get drive descriptors for the drives that are currently in the set.
961 	 */
962 	curdd = metaget_drivedesc(sp, MD_FULLNAME_ONLY, ep);
963 
964 	if (! mdisok(ep))
965 		return (-1);
966 
967 	/* Find the minimum replica size in use is or use the default */
968 	if ((nblks = meta_db_minreplica(sp, ep)) < 0)
969 		mdclrerror(ep);
970 	else
971 		dbsize = nblks;	/* adjust replica size */
972 
973 	/* Make sure we are blocking all signals */
974 	if (procsigs(TRUE, &oldsigs, &xep) < 0)
975 		mdclrerror(&xep);
976 
977 	/*
978 	 * Lock the set on current set members.
979 	 * For MN diskset lock_set and SUSPEND are used to protect against
980 	 * other meta* commands running on the other nodes.
981 	 */
982 	if (MD_MNSET_DESC(sd)) {
983 		nd = sd->sd_nodelist;
984 		while (nd) {
985 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
986 				nd = nd->nd_next;
987 				continue;
988 			}
989 			if (clnt_lock_set(nd->nd_nodename, sp, ep)) {
990 				rval = -1;
991 				goto out;
992 			}
993 			nd = nd->nd_next;
994 		}
995 		/*
996 		 * Lock out other meta* commands by suspending
997 		 * class 1 messages across the diskset.
998 		 */
999 		nd = sd->sd_nodelist;
1000 		while (nd) {
1001 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
1002 				nd = nd->nd_next;
1003 				continue;
1004 			}
1005 			if (clnt_mdcommdctl(nd->nd_nodename,
1006 			    COMMDCTL_SUSPEND, sp, MD_MSG_CLASS1,
1007 			    MD_MSCF_NO_FLAGS, ep)) {
1008 				rval = -1;
1009 				goto out;
1010 			}
1011 			suspend1_flag = 1;
1012 			nd = nd->nd_next;
1013 		}
1014 	} else {
1015 		for (i = 0; i < MD_MAXSIDES; i++) {
1016 			/* Skip empty slots */
1017 			if (sd->sd_nodes[i][0] == '\0') continue;
1018 
1019 			if (clnt_lock_set(sd->sd_nodes[i], sp, ep)) {
1020 				rval = -1;
1021 				goto out;
1022 			}
1023 		}
1024 	}
1025 
1026 	/* We are not adding or deleting any drives, just balancing */
1027 	dd = NULL;
1028 
1029 	/*
1030 	 * Balance the DB's according to the list of existing drives and the
1031 	 * list of added drives.
1032 	 */
1033 	if ((rval = meta_db_balance(sp, dd, curdd, dbsize, ep)) == -1)
1034 		goto out;
1035 
1036 out:
1037 	/*
1038 	 * Unlock diskset by resuming class 1 messages across the diskset.
1039 	 * Just resume all classes so that resume is the same whether
1040 	 * just one class was locked or all classes were locked.
1041 	 */
1042 	if (suspend1_flag) {
1043 		nd = sd->sd_nodelist;
1044 		while (nd) {
1045 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
1046 				nd = nd->nd_next;
1047 				continue;
1048 			}
1049 			if (clnt_mdcommdctl(nd->nd_nodename, COMMDCTL_RESUME,
1050 				sp, MD_MSG_CLASS0, MD_MSCF_NO_FLAGS, &xep)) {
1051 				/*
1052 				 * We are here because we failed to resume
1053 				 * rpc.mdcommd.  However we potentially have
1054 				 * an error from the previous call
1055 				 * (meta_db_balance). If the previous call
1056 				 * did fail,  we capture that error and
1057 				 * generate a perror withthe string,
1058 				 * "Unable to resume...".
1059 				 * Setting rval to -1 ensures that in the
1060 				 * next iteration of the loop, ep is not
1061 				 * clobbered.
1062 				 */
1063 				if (rval == 0)
1064 					(void) mdstealerror(ep, &xep);
1065 				else
1066 					mdclrerror(&xep);
1067 				rval = -1;
1068 				mde_perror(ep, dgettext(TEXT_DOMAIN,
1069 				    "Unable to resume rpc.mdcommd."));
1070 			}
1071 			nd = nd->nd_next;
1072 		}
1073 	}
1074 
1075 	/* Unlock the set */
1076 	cl_sk = cl_get_setkey(sp->setno, sp->setname);
1077 	if (MD_MNSET_DESC(sd)) {
1078 		nd = sd->sd_nodelist;
1079 		while (nd) {
1080 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
1081 				nd = nd->nd_next;
1082 				continue;
1083 			}
1084 			if (clnt_unlock_set(nd->nd_nodename, cl_sk, &xep)) {
1085 				if (rval == 0)
1086 					(void) mdstealerror(ep, &xep);
1087 				else
1088 					mdclrerror(&xep);
1089 				rval = -1;
1090 			}
1091 			nd = nd->nd_next;
1092 		}
1093 	} else {
1094 		for (i = 0; i < MD_MAXSIDES; i++) {
1095 			/* Skip empty slots */
1096 			if (sd->sd_nodes[i][0] == '\0')
1097 				continue;
1098 
1099 			if (clnt_unlock_set(sd->sd_nodes[i], cl_sk, &xep)) {
1100 				if (rval == 0)
1101 					(void) mdstealerror(ep, &xep);
1102 				rval = -1;
1103 			}
1104 		}
1105 	}
1106 
1107 	/* release signals back to what they were on entry */
1108 	if (procsigs(FALSE, &oldsigs, &xep) < 0)
1109 		mdclrerror(&xep);
1110 
1111 	cl_set_setkey(NULL);
1112 
1113 	metaflushsetname(sp);
1114 
1115 	return (rval);
1116 }
1117 
1118 int
1119 meta_set_destroy(
1120 	mdsetname_t	*sp,
1121 	int		lock_set,
1122 	md_error_t	*ep
1123 )
1124 {
1125 	int		i;
1126 	med_rec_t	medr;
1127 	md_set_desc	*sd;
1128 	md_drive_desc	*dd, *p, *p1;
1129 	mddrivename_t	*dnp;
1130 	mdname_t	*np;
1131 	mdnamelist_t	*nlp = NULL;
1132 	int		num_users = 0;
1133 	int		has_set;
1134 	side_t		mysideno;
1135 	sigset_t	oldsigs;
1136 	md_error_t	xep = mdnullerror;
1137 	md_setkey_t	*cl_sk;
1138 	int		rval = 0;
1139 	int		delete_end = 1;
1140 
1141 	/* Make sure we are blocking all signals */
1142 	if (procsigs(TRUE, &oldsigs, ep) < 0)
1143 		return (-1);
1144 
1145 	if ((sd = metaget_setdesc(sp, ep)) == NULL) {
1146 		if (! mdisok(ep))
1147 			rval = -1;
1148 		goto out;
1149 	}
1150 
1151 	/*
1152 	 * meta_set_destroy should not be called for a MN diskset.
1153 	 * This routine destroys a set without communicating this information
1154 	 * to the other nodes which would lead to an inconsistency in
1155 	 * the MN diskset.
1156 	 */
1157 	if (MD_MNSET_DESC(sd)) {
1158 		rval = -1;
1159 		goto out;
1160 	}
1161 
1162 	/* Continue if a traditional diskset */
1163 
1164 	/*
1165 	 * Check to see who has the set.  If we are not the last user of the
1166 	 * set, we will not touch the replicas.
1167 	 */
1168 	for (i = 0; i < MD_MAXSIDES; i++) {
1169 		/* Skip empty slots */
1170 		if (sd->sd_nodes[i][0] == '\0')
1171 			continue;
1172 
1173 		has_set = nodehasset(sp, sd->sd_nodes[i], NHS_NST_EQ,
1174 		    ep);
1175 
1176 		if (has_set < 0) {
1177 			mdclrerror(ep);
1178 		} else
1179 			num_users++;
1180 	}
1181 
1182 	if ((dd = metaget_drivedesc(sp, MD_BASICNAME_OK, ep)) == NULL) {
1183 		if (! mdisok(ep)) {
1184 			rval = -1;
1185 			goto out;
1186 		}
1187 	}
1188 
1189 	if (setup_db_bydd(sp, dd, TRUE, ep) == -1) {
1190 		rval = -1;
1191 		goto out;
1192 	}
1193 
1194 	if (lock_set == TRUE) {
1195 		/* Lock the set on our side */
1196 		if (clnt_lock_set(mynode(), sp, ep)) {
1197 			rval = -1;
1198 			goto out;
1199 		}
1200 	}
1201 
1202 	/*
1203 	 * A traditional diskset has no diskset stale information to send
1204 	 * since there can only be one owner node at a time.
1205 	 */
1206 	if (snarf_set(sp, FALSE, ep))
1207 		mdclrerror(ep);
1208 
1209 	if (dd != NULL) {
1210 		/*
1211 		 * Make sure that no drives are in use as parts of metadrives
1212 		 * or hot spare pools, this is one of the few error conditions
1213 		 * that will stop this routine, unless the environment has
1214 		 * META_DESTROY_SET_OK set, in which case, the operation will
1215 		 * proceed.
1216 		 */
1217 		if (getenv("META_DESTROY_SET_OK") == NULL) {
1218 			for (p = dd; p != NULL; p = p->dd_next) {
1219 				dnp = p->dd_dnp;
1220 
1221 				i = meta_check_drive_inuse(sp, dnp, FALSE, ep);
1222 				if (i == -1) {
1223 					/* need xep - wire calls clear error */
1224 					i = metaget_setownership(sp, &xep);
1225 					if (i == -1) {
1226 						rval = -1;
1227 						goto out;
1228 					}
1229 
1230 					mysideno = getmyside(sp, &xep);
1231 
1232 					if (mysideno == MD_SIDEWILD) {
1233 						rval = -1;
1234 						goto out;
1235 					}
1236 
1237 					if (sd->sd_isown[mysideno] == FALSE)
1238 						if (halt_set(sp, &xep)) {
1239 							rval = -1;
1240 							goto out;
1241 						}
1242 
1243 					rval = -1;
1244 					goto out;
1245 				}
1246 			}
1247 		}
1248 
1249 		for (i = 0; i < MD_MAXSIDES; i++) {
1250 			/* Skip empty slots */
1251 			if (sd->sd_nodes[i][0] == '\0')
1252 				continue;
1253 
1254 			/* Skip non local nodes */
1255 			if (strcmp(mynode(), sd->sd_nodes[i]) != 0)
1256 				continue;
1257 
1258 			if (clnt_deldrvs(sd->sd_nodes[i], sp, dd, ep))
1259 				mdclrerror(ep);
1260 		}
1261 
1262 		/*
1263 		 * Go thru each drive and individually delete the replicas.
1264 		 * This way we can ignore individual errors.
1265 		 */
1266 		for (p = dd; p != NULL; p = p->dd_next) {
1267 			uint_t	rep_slice;
1268 
1269 			dnp = p->dd_dnp;
1270 			if ((meta_replicaslice(dnp, &rep_slice, ep) != 0) ||
1271 			    (((np = metaslicename(dnp, rep_slice, ep))
1272 				== NULL) &&
1273 				((np = metaslicename(dnp, MD_SLICE0, ep))
1274 				    == NULL))) {
1275 				rval = -1;
1276 				goto out;
1277 			}
1278 
1279 			if ((np = metaslicename(dnp,
1280 			    rep_slice, ep)) == NULL) {
1281 				if ((np = metaslicename(dnp,
1282 				    MD_SLICE0, ep)) == NULL) {
1283 					rval = -1;
1284 					goto out;
1285 				}
1286 				mdclrerror(ep);
1287 			}
1288 
1289 			/* Yes this is UGLY!!! */
1290 			p1 = p->dd_next;
1291 			p->dd_next = NULL;
1292 			if (rel_own_bydd(sp, p, FALSE, ep))
1293 				mdclrerror(ep);
1294 			p->dd_next = p1;
1295 
1296 			if (p->dd_dbcnt == 0)
1297 				continue;
1298 
1299 			/*
1300 			 * Skip the replica removal if we are not the last user
1301 			 */
1302 			if (num_users != 1)
1303 				continue;
1304 
1305 			nlp = NULL;
1306 			(void) metanamelist_append(&nlp, np);
1307 			if (meta_db_detach(sp, nlp,
1308 			    (MDFORCE_DS | MDFORCE_SET_LOCKED), NULL, ep))
1309 				mdclrerror(ep);
1310 			metafreenamelist(nlp);
1311 		}
1312 	}
1313 
1314 	if (halt_set(sp, ep)) {
1315 		rval = -1;
1316 		goto out;
1317 	}
1318 
1319 	/* Setup the mediator record */
1320 	(void) memset(&medr, '\0', sizeof (med_rec_t));
1321 	medr.med_rec_mag = MED_REC_MAGIC;
1322 	medr.med_rec_rev = MED_REC_REV;
1323 	medr.med_rec_fl  = 0;
1324 	medr.med_rec_sn  = sp->setno;
1325 	(void) strcpy(medr.med_rec_snm, sp->setname);
1326 	medr.med_rec_meds = sd->sd_med;	/* structure assigment */
1327 	(void) memset(&medr.med_rec_data, '\0', sizeof (med_data_t));
1328 	medr.med_rec_foff = 0;
1329 
1330 	/*
1331 	 * If we are the last remaining user, then remove the mediator hosts
1332 	 */
1333 	if (num_users == 1) {
1334 		for (i = 0; i < MED_MAX_HOSTS; i++) {
1335 			if (medr.med_rec_meds.n_lst[i].a_cnt != 0)
1336 				SE_NOTIFY(EC_SVM_CONFIG, ESC_SVM_REMOVE,
1337 				    SVM_TAG_MEDIATOR, sp->setno, i);
1338 			(void) memset(&medr.med_rec_meds.n_lst[i], '\0',
1339 			    sizeof (md_h_t));
1340 		}
1341 		medr.med_rec_meds.n_cnt = 0;
1342 	} else { 	/* Remove this host from the mediator node list. */
1343 		for (i = 0; i < MD_MAXSIDES; i++) {
1344 			/* Skip empty slots */
1345 			if (sd->sd_nodes[i][0] == '\0')
1346 				continue;
1347 
1348 			/* Copy non local node */
1349 			if (strcmp(mynode(), sd->sd_nodes[i]) != 0) {
1350 				(void) strcpy(medr.med_rec_nodes[i],
1351 				    sd->sd_nodes[i]);
1352 				continue;
1353 			}
1354 
1355 			/* Clear local node */
1356 			(void) memset(&medr.med_rec_nodes[i], '\0',
1357 			    sizeof (md_node_nm_t));
1358 		}
1359 	}
1360 
1361 	crcgen(&medr, &medr.med_rec_cks, sizeof (med_rec_t), NULL);
1362 
1363 	/*
1364 	 * If the client is part of a cluster put the DCS service
1365 	 * into a deleteing state.
1366 	 */
1367 	if (sdssc_delete_begin(sp->setname) == SDSSC_ERROR) {
1368 		if (metad_isautotakebyname(sp->setname)) {
1369 			delete_end = 0;
1370 		} else {
1371 			mdclrerror(ep);
1372 			goto out;
1373 		}
1374 	}
1375 
1376 	/* Inform the mediator hosts of the new information */
1377 	for (i = 0; i < MED_MAX_HOSTS; i++) {
1378 		if (sd->sd_med.n_lst[i].a_cnt == 0)
1379 			continue;
1380 
1381 		if (clnt_med_upd_rec(&sd->sd_med.n_lst[i], sp, &medr, ep))
1382 			mdclrerror(ep);
1383 	}
1384 
1385 	/* Delete the set locally */
1386 	for (i = 0; i < MD_MAXSIDES; i++) {
1387 		/* Skip empty slots */
1388 		if (sd->sd_nodes[i][0] == '\0')
1389 			continue;
1390 
1391 		/* Skip non local nodes */
1392 		if (strcmp(mynode(), sd->sd_nodes[i]) != 0)
1393 			continue;
1394 
1395 		if (clnt_delset(sd->sd_nodes[i], sp, ep) == -1)
1396 			mdclrerror(ep);
1397 	}
1398 	if (delete_end &&
1399 	    sdssc_delete_end(sp->setname, SDSSC_COMMIT) == SDSSC_ERROR)
1400 		rval = -1;
1401 
1402 out:
1403 	/* release signals back to what they were on entry */
1404 	if (procsigs(FALSE, &oldsigs, &xep) < 0) {
1405 		if (rval == 0)
1406 			(void) mdstealerror(ep, &xep);
1407 		rval = -1;
1408 	}
1409 
1410 	if (lock_set == TRUE) {
1411 		cl_sk = cl_get_setkey(sp->setno, sp->setname);
1412 		if (clnt_unlock_set(mynode(), cl_sk, &xep)) {
1413 			if (rval == 0)
1414 				(void) mdstealerror(ep, &xep);
1415 			rval = -1;
1416 		}
1417 		cl_set_setkey(NULL);
1418 	}
1419 
1420 	metaflushsetname(sp);
1421 	return (rval);
1422 }
1423 
1424 int
1425 meta_set_purge(
1426 	mdsetname_t	*sp,
1427 	int		bypass_cluster,
1428 	int		forceflg,
1429 	md_error_t	*ep
1430 )
1431 {
1432 	char		*thishost = mynode();
1433 	md_set_desc	*sd;
1434 	md_setkey_t	*cl_sk;
1435 	md_error_t	xep = mdnullerror;
1436 	int		rval = 0;
1437 	int		i, num_hosts = 0;
1438 	int		has_set = 0;
1439 	int		max_node = 0;
1440 	int		delete_end = 1;
1441 	md_mnnode_desc	*nd;
1442 
1443 	if ((sd = metaget_setdesc(sp, ep)) == NULL) {
1444 		/* unable to find set description */
1445 		rval = 1;
1446 		return (rval);
1447 	}
1448 
1449 	if (MD_MNSET_DESC(sd)) {
1450 		/*
1451 		 * Get a count of the hosts in the set and also lock the set
1452 		 * on those hosts that know about it.
1453 		 */
1454 		nd = sd->sd_nodelist;
1455 		while (nd) {
1456 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
1457 				nd = nd->nd_next;
1458 				continue;
1459 			}
1460 			has_set = nodehasset(sp, nd->nd_nodename,
1461 				NHS_NST_EQ, ep);
1462 
1463 			/*
1464 			 * The host is not aware of this set (has_set < 0) or
1465 			 * the set does not match (has_set == 0). This check
1466 			 * prevents the code getting confused by an apparent
1467 			 * inconsistancy in the set's state, this is in the
1468 			 * purge code so something is broken in any case and
1469 			 * this is just trying to fix the brokeness.
1470 			 */
1471 			if (has_set <= 0) {
1472 				mdclrerror(ep);
1473 				nd->nd_flags |= MD_MN_NODE_NOSET;
1474 			} else {
1475 				num_hosts++;
1476 				if (clnt_lock_set(nd->nd_nodename, sp, ep)) {
1477 					/*
1478 					 * If the force flag is set then
1479 					 * ignore any RPC failures because we
1480 					 * are only really interested with
1481 					 * the set on local node.
1482 					 */
1483 					if (forceflg && mdanyrpcerror(ep)) {
1484 						mdclrerror(ep);
1485 					} else {
1486 						/*
1487 						 * set max_node so that in the
1488 						 * unlock code nodes in the
1489 						 * set that have not been
1490 						 * locked are not unlocked.
1491 						 */
1492 						max_node = nd->nd_nodeid;
1493 						rval = 2;
1494 						goto out1;
1495 					}
1496 				}
1497 
1498 			}
1499 			nd = nd->nd_next;
1500 		}
1501 		max_node = 0;
1502 	} else {
1503 		/*
1504 		 * Get a count of the hosts in the set and also lock the set
1505 		 * on those hosts that know about it.
1506 		 */
1507 		for (i = 0; i < MD_MAXSIDES; i++) {
1508 			/* Skip empty slots */
1509 			if (sd->sd_nodes[i][0] == '\0')
1510 				continue;
1511 
1512 			has_set = nodehasset(sp, sd->sd_nodes[i],
1513 				NHS_NST_EQ, ep);
1514 
1515 			/*
1516 			 * The host is not aware of this set (has_set < 0) or
1517 			 * the set does not match (has_set == 0). This check
1518 			 * prevents the code getting confused by an apparent
1519 			 * inconsistancy in the set's state, this is in the
1520 			 * purge code so something is broken in any case and
1521 			 * this is just trying to fix the brokeness.
1522 			 */
1523 			if (has_set <= 0) {
1524 				mdclrerror(ep);
1525 				/*
1526 				 * set the node to NULL to prevent further
1527 				 * requests to this unresponsive node.
1528 				 */
1529 				sd->sd_nodes[i][0] = '\0';
1530 			} else {
1531 				num_hosts++;
1532 				if (clnt_lock_set(sd->sd_nodes[i], sp, ep)) {
1533 					/*
1534 					 * If the force flag is set then
1535 					 * ignore any RPC failures because we
1536 					 * are only really interested with
1537 					 * the set on local node.
1538 					 */
1539 					if (forceflg && mdanyrpcerror(ep)) {
1540 						mdclrerror(ep);
1541 					} else {
1542 						rval = 2;
1543 						/*
1544 						 * set max_node so that in the
1545 						 * unlock code nodes in the
1546 						 * set that have not been
1547 						 * locked are not unlocked.
1548 						 */
1549 						max_node = i;
1550 						goto out1;
1551 					}
1552 				}
1553 			}
1554 		}
1555 		max_node = i;	/* now MD_MAXSIDES */
1556 	}
1557 	if (!bypass_cluster) {
1558 		/*
1559 		 * If there is only one host associated with the
1560 		 * set then remove the set from the cluster.
1561 		 */
1562 		if (num_hosts == 1) {
1563 			if (sdssc_delete_begin(sp->setname) == SDSSC_ERROR) {
1564 				if (metad_isautotakebyname(sp->setname)) {
1565 					delete_end = 0;
1566 				} else {
1567 					mdclrerror(ep);
1568 					rval = 3;
1569 					goto out1;
1570 				}
1571 			}
1572 		}
1573 	}
1574 
1575 	if (MD_MNSET_DESC(sd)) {
1576 		/*
1577 		 * Get a count of the hosts in the set and also lock the set
1578 		 * on those hosts that know about it.
1579 		 */
1580 		nd = sd->sd_nodelist;
1581 		while (nd) {
1582 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
1583 				nd = nd->nd_next;
1584 				continue;
1585 			}
1586 			if (nd->nd_nodeid != sd->sd_mn_mynode->nd_nodeid) {
1587 				/*
1588 				 * Tell the remote node to remove this node
1589 				 */
1590 				if (clnt_delhosts(nd->nd_nodename, sp, 1,
1591 					&thishost, ep) == -1) {
1592 					/*
1593 					 * If we fail to delete ourselves
1594 					 * from the remote host it does not
1595 					 * really matter because the set is
1596 					 * being "purged" from this node. The
1597 					 * set can be purged from the other
1598 					 * node at a later time.
1599 					 */
1600 					mdclrerror(ep);
1601 				}
1602 				nd = nd->nd_next;
1603 				continue;
1604 			}
1605 			/* remove the set from this host */
1606 			if (clnt_delset(nd->nd_nodename, sp, ep) == -1) {
1607 				md_perror(dgettext(TEXT_DOMAIN, "delset"));
1608 				if (!bypass_cluster && num_hosts == 1)
1609 					(void) sdssc_delete_end(sp->setname,
1610 					    SDSSC_CLEANUP);
1611 				mdclrerror(ep);
1612 				goto out1;
1613 			}
1614 			nd = nd->nd_next;
1615 		}
1616 	} else {
1617 		for (i = 0; i < MD_MAXSIDES; i++) {
1618 			/* Skip empty slots */
1619 			if (sd->sd_nodes[i][0] == '\0')
1620 				continue;
1621 			if (strcmp(thishost, sd->sd_nodes[i]) != 0) {
1622 				/*
1623 				 * Tell the remote node to remove this node
1624 				 */
1625 				if (clnt_delhosts(sd->sd_nodes[i], sp, 1,
1626 				    &thishost, ep) == -1) {
1627 					/*
1628 					 * If we fail to delete ourselves
1629 					 * from the remote host it does not
1630 					 * really matter because the set is
1631 					 * being "purged" from this node. The
1632 					 * set can be purged from the other
1633 					 * node at a later time.
1634 					 */
1635 					mdclrerror(ep);
1636 				}
1637 				continue;
1638 			}
1639 
1640 			/* remove the set from this host */
1641 			if (clnt_delset(sd->sd_nodes[i], sp, ep) == -1) {
1642 				md_perror(dgettext(TEXT_DOMAIN, "delset"));
1643 				if (!bypass_cluster && num_hosts == 1)
1644 					(void) sdssc_delete_end(sp->setname,
1645 					    SDSSC_CLEANUP);
1646 				mdclrerror(ep);
1647 				goto out1;
1648 			}
1649 		}
1650 	}
1651 
1652 	if (!bypass_cluster && num_hosts == 1) {
1653 		if (delete_end && sdssc_delete_end(sp->setname, SDSSC_COMMIT) ==
1654 		    SDSSC_ERROR) {
1655 			rval = 4;
1656 		}
1657 	}
1658 
1659 out1:
1660 
1661 	cl_sk = cl_get_setkey(sp->setno, sp->setname);
1662 
1663 	/*
1664 	 * Remove the set lock on those nodes that had the set locked
1665 	 * max_node will either be MD_MAXSIDES or array index of the last
1666 	 * node contacted (or rather failed to contact) for traditional
1667 	 * diskset.  For a MN diskset, max_node is the node_id of the node
1668 	 * that failed the lock.
1669 	 */
1670 	if (MD_MNSET_DESC(sd)) {
1671 		nd = sd->sd_nodelist;
1672 		while (nd) {
1673 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
1674 				nd = nd->nd_next;
1675 				continue;
1676 			}
1677 			if (nd->nd_nodeid == max_node)
1678 				break;
1679 			if (clnt_unlock_set(nd->nd_nodename, cl_sk, &xep)) {
1680 				if (forceflg && mdanyrpcerror(&xep)) {
1681 					mdclrerror(&xep);
1682 					nd = nd->nd_next;
1683 					continue;
1684 				}
1685 				if (rval == 0)
1686 					(void) mdstealerror(ep, &xep);
1687 				rval = 5;
1688 			}
1689 			nd = nd->nd_next;
1690 		}
1691 	} else {
1692 		for (i = 0; i < max_node; i++) {
1693 			/* Skip empty slots */
1694 			if (sd->sd_nodes[i][0] == '\0')
1695 				continue;
1696 
1697 			if (clnt_unlock_set(sd->sd_nodes[i], cl_sk, &xep)) {
1698 				if (forceflg && mdanyrpcerror(&xep)) {
1699 					mdclrerror(&xep);
1700 					continue;
1701 				}
1702 				if (rval == 0)
1703 					(void) mdstealerror(ep, &xep);
1704 				rval = 5;
1705 			}
1706 		}
1707 	}
1708 
1709 	cl_set_setkey(NULL);
1710 
1711 	return (rval);
1712 }
1713 
1714 int
1715 meta_set_query(
1716 	mdsetname_t		*sp,
1717 	mddb_dtag_lst_t		**dtlpp,
1718 	md_error_t		*ep
1719 )
1720 {
1721 	mddb_dtag_get_parm_t	dtgp;
1722 
1723 	(void) memset(&dtgp, '\0', sizeof (mddb_dtag_get_parm_t));
1724 	dtgp.dtgp_setno = sp->setno;
1725 
1726 	/*CONSTCOND*/
1727 	while (1) {
1728 		if (metaioctl(MD_MED_GET_TAG, &dtgp, &dtgp.dtgp_mde, NULL) != 0)
1729 			if (! mdismddberror(&dtgp.dtgp_mde, MDE_DB_NOTAG) ||
1730 			    *dtlpp == NULL)
1731 				return (mdstealerror(ep, &dtgp.dtgp_mde));
1732 			else
1733 				break;
1734 
1735 		/*
1736 		 * Run to the end of the list
1737 		 */
1738 		for (/* void */; (*dtlpp != NULL); dtlpp = &(*dtlpp)->dtl_nx)
1739 			/* void */;
1740 
1741 		*dtlpp = Zalloc(sizeof (mddb_dtag_lst_t));
1742 
1743 		(void) memmove(&(*dtlpp)->dtl_dt, &dtgp.dtgp_dt,
1744 		    sizeof (mddb_dtag_t));
1745 
1746 		dtgp.dtgp_dt.dt_id++;
1747 	}
1748 	return (0);
1749 }
1750 
1751 /*
1752  * return drivename get by key
1753  */
1754 mddrivename_t *
1755 metadrivename_withdrkey(
1756 	mdsetname_t	*sp,
1757 	side_t		sideno,
1758 	mdkey_t		key,
1759 	int		flags,
1760 	md_error_t	*ep
1761 )
1762 {
1763 	char		*nm;
1764 	mdname_t	*np;
1765 	mddrivename_t	*dnp;
1766 	ddi_devid_t	devidp;
1767 	md_set_desc	*sd;
1768 
1769 	if ((sd = metaget_setdesc(sp, ep)) == NULL) {
1770 		return (NULL);
1771 	}
1772 
1773 	/* get namespace info */
1774 	if (MD_MNSET_DESC(sd)) {
1775 		if ((nm = meta_getnmbykey(MD_LOCAL_SET, sideno,
1776 		    key, ep)) == NULL)
1777 			return (NULL);
1778 	} else {
1779 		if ((nm = meta_getnmbykey(MD_LOCAL_SET, sideno+SKEW,
1780 		    key, ep)) == NULL)
1781 			return (NULL);
1782 	}
1783 
1784 	/* get device name */
1785 	if (flags & PRINT_FAST) {
1786 		if ((np = metaname_fast(&sp, nm, ep)) == NULL) {
1787 			Free(nm);
1788 			return (NULL);
1789 		}
1790 	} else {
1791 		if ((np = metaname(&sp, nm, ep)) == NULL) {
1792 			Free(nm);
1793 			return (NULL);
1794 		}
1795 	}
1796 	Free(nm);
1797 
1798 	/* make sure it's OK */
1799 	if ((! (flags & MD_BASICNAME_OK)) && (metachkcomp(np, ep) != 0))
1800 		return (NULL);
1801 
1802 	/* get drivename */
1803 	dnp = np->drivenamep;
1804 	dnp->side_names_key = key;
1805 
1806 	/*
1807 	 * Skip the following devid check if dnp is did device
1808 	 * The device id is disabled for did device due to the
1809 	 * lack of minor name support in the did driver. The following
1810 	 * devid code path can set and propagate the error and
1811 	 * eventually prevent did disks from being added to the
1812 	 * diskset under SunCluster systems
1813 	 */
1814 	if (strncmp(dnp->rname, "/dev/did/", strlen("/dev/did/")) == 0) {
1815 		goto out;
1816 	}
1817 
1818 	/* Also, Skip the check if MN diskset, no devid's */
1819 	if (MD_MNSET_DESC(sd)) {
1820 		goto out;
1821 	}
1822 
1823 	/*
1824 	 * Get the devid associated with the key.
1825 	 *
1826 	 * If a devid was returned, it MUST be valid even in
1827 	 * the case where a device id has been "updated". The
1828 	 * "update" of the device id may have occured due to
1829 	 * a firmware upgrade.
1830 	 */
1831 	if ((devidp = meta_getdidbykey(MD_LOCAL_SET, sideno+SKEW, key, ep))
1832 	    != NULL) {
1833 		dnp->devid = devid_str_encode(devidp, NULL);
1834 		free(devidp);
1835 	} else {
1836 		/*
1837 		 * It is okay if replica is not in devid mode
1838 		 */
1839 		if (mdissyserror(ep, MDDB_F_NODEVID)) {
1840 			mdclrerror(ep);
1841 			goto out;
1842 		}
1843 
1844 		/*
1845 		 * devid is missing so this means that we have
1846 		 * just upgraded from a configuration where
1847 		 * devid's were not used so try to add in
1848 		 * the devid and requery.
1849 		 */
1850 		if (meta_setdid(MD_LOCAL_SET, sideno + SKEW, key,
1851 		    ep) < 0)
1852 			return (NULL);
1853 		if ((devidp = (ddi_devid_t)meta_getdidbykey(MD_LOCAL_SET,
1854 		    sideno+SKEW, key, ep)) == NULL)
1855 			return (NULL);
1856 		dnp->devid = devid_str_encode(devidp, NULL);
1857 		devid_free(devidp);
1858 	}
1859 
1860 out:
1861 	if (flags & MD_BYPASS_DAEMON)
1862 		return (dnp);
1863 
1864 	if (get_sidenmlist(sp, dnp, ep))
1865 		return (NULL);
1866 
1867 	/* return success */
1868 	return (dnp);
1869 }
1870 
1871 void
1872 metafreedrivedesc(md_drive_desc **dd)
1873 {
1874 	md_drive_desc	*p, *next = NULL;
1875 
1876 	for (p = *dd; p != NULL; p = next) {
1877 		next = p->dd_next;
1878 		Free(p);
1879 	}
1880 	*dd = NULL;
1881 }
1882 
1883 md_drive_desc *
1884 metaget_drivedesc(
1885 	mdsetname_t	*sp,
1886 	int		flags,
1887 	md_error_t	*ep
1888 )
1889 {
1890 	side_t		sideno = MD_SIDEWILD;
1891 
1892 	assert(! (flags & MD_BYPASS_DAEMON));
1893 
1894 	if ((sideno = getmyside(sp, ep)) == MD_SIDEWILD)
1895 		return (NULL);
1896 
1897 	return (metaget_drivedesc_sideno(sp, sideno, flags, ep));
1898 }
1899 
1900 md_drive_desc *
1901 metaget_drivedesc_fromnamelist(
1902 	mdsetname_t	*sp,
1903 	mdnamelist_t	*nlp,
1904 	md_error_t	*ep
1905 )
1906 {
1907 	md_set_desc		*sd;
1908 	mdnamelist_t		*p;
1909 	md_drive_desc		*dd = NULL;
1910 
1911 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
1912 		return (NULL);
1913 
1914 	for (p = nlp; p != NULL; p = p->next)
1915 		(void) metadrivedesc_append(&dd, p->namep->drivenamep, 0, 0,
1916 		    sd->sd_ctime, sd->sd_genid, MD_DR_ADD);
1917 
1918 	return (dd);
1919 }
1920 
1921 md_drive_desc *
1922 metaget_drivedesc_sideno(
1923 	mdsetname_t *sp,
1924 	side_t sideno,
1925 	int flags,
1926 	md_error_t *ep
1927 )
1928 {
1929 	md_set_desc	*sd = NULL;
1930 
1931 	assert(! (flags & MD_BYPASS_DAEMON));
1932 
1933 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
1934 		return (NULL);
1935 
1936 	if (sd->sd_drvs)
1937 		return (sd->sd_drvs);
1938 
1939 	if ((sd->sd_drvs = dr2drivedesc(sp, sideno, flags, ep)) == NULL)
1940 		return (NULL);
1941 
1942 	return (sd->sd_drvs);
1943 }
1944 
1945 int
1946 metaget_setownership(
1947 	mdsetname_t	*sp,
1948 	md_error_t	*ep
1949 )
1950 {
1951 	md_set_desc	*sd;
1952 	int		bool;
1953 	int		i;
1954 	md_mnnode_desc	*nd;
1955 
1956 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
1957 		return (-1);
1958 
1959 	if (MD_MNSET_DESC(sd)) {
1960 		nd = sd->sd_nodelist;
1961 		while (nd) {
1962 			/* If node isn't alive, can't own diskset */
1963 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
1964 				nd->nd_flags &= ~MD_MN_NODE_OWN;
1965 				nd = nd->nd_next;
1966 				continue;
1967 			}
1968 			/*
1969 			 * If can't communicate with rpc.metad, then mark
1970 			 * this node as not an owner.  That node may
1971 			 * in fact, be an owner, but without rpc.metad running
1972 			 * that node can't do much.
1973 			 */
1974 			if (clnt_ownset(nd->nd_nodename, sp, &bool, ep) == -1) {
1975 				nd->nd_flags &= ~MD_MN_NODE_OWN;
1976 			} else if (bool == TRUE) {
1977 				nd->nd_flags |= MD_MN_NODE_OWN;
1978 			} else {
1979 				nd->nd_flags &= ~MD_MN_NODE_OWN;
1980 			}
1981 			nd = nd->nd_next;
1982 		}
1983 		return (0);
1984 	}
1985 
1986 	/* Rest of code handles traditional disksets */
1987 
1988 	for (i = 0; i < MD_MAXSIDES; i++)
1989 		sd->sd_isown[i] = 0;
1990 
1991 	if (clnt_ownset(mynode(), sp, &bool, ep) == -1)
1992 		return (-1);
1993 
1994 	if (bool == TRUE)
1995 		sd->sd_isown[getmyside(sp, ep)] = 1;
1996 
1997 	return (0);
1998 }
1999 
2000 char *
2001 mynode(void)
2002 {
2003 	static struct utsname	myuname;
2004 	static int		done = 0;
2005 
2006 	if (! done) {
2007 		if (uname(&myuname) == -1) {
2008 			md_perror(dgettext(TEXT_DOMAIN, "uname"));
2009 			assert(0);
2010 		}
2011 		done = 1;
2012 	}
2013 	return (myuname.nodename);
2014 }
2015 
2016 int
2017 strinlst(char *str, int cnt, char **lst)
2018 {
2019 	int i;
2020 
2021 	for (i = 0; i < cnt; i++)
2022 		if (strcmp(lst[i], str) == 0)
2023 			return (TRUE);
2024 
2025 	return (FALSE);
2026 }
2027 
2028 /*
2029  * meta_get_reserved_names
2030  *  returns an mdnamelist_t of reserved slices
2031  *  reserved slices are those that are used but don't necessarily
2032  *  show up as metadevices (ex. reserved slice for db in sets, logs)
2033  */
2034 
2035 /*ARGSUSED*/
2036 int
2037 meta_get_reserved_names(
2038 	mdsetname_t	*sp,
2039 	mdnamelist_t	**nlpp,
2040 	int		options,
2041 	md_error_t	*ep)
2042 {
2043 	int		 count		= 0;
2044 	mdname_t	*np		= NULL;
2045 	mdnamelist_t	*transnlp	= NULL;
2046 	mdnamelist_t	**tailpp 	= nlpp;
2047 	mdnamelist_t	*nlp;
2048 	md_drive_desc	*dd, *di;
2049 
2050 	if (metaislocalset(sp))
2051 		goto out;
2052 
2053 	if (!(dd = metaget_drivedesc(sp, MD_BASICNAME_OK, ep)) && !mdisok(ep)) {
2054 		count = -1;
2055 		goto out;
2056 	}
2057 
2058 	/* db in for sets on reserved slice */
2059 	for (di = dd; di && count >= 0; di = di->dd_next) {
2060 		uint_t	rep_slice;
2061 
2062 		/*
2063 		 * Add the name struct to the end of the
2064 		 * namelist but keep a pointer to the last
2065 		 * element so that we don't incur the overhead
2066 		 * of traversing the list each time
2067 		 */
2068 		if (di->dd_dnp &&
2069 		    (meta_replicaslice(di->dd_dnp, &rep_slice, ep) == 0) &&
2070 		    (np = metaslicename(di->dd_dnp, rep_slice, ep)) &&
2071 		    (tailpp = meta_namelist_append_wrapper(tailpp, np)))
2072 			count++;
2073 		else
2074 			count = -1;
2075 	}
2076 
2077 	/* now find logs */
2078 	if (meta_get_trans_names(sp, &transnlp, 0, ep) < 0) {
2079 		count = -1;
2080 		goto out;
2081 	}
2082 
2083 	for (nlp = transnlp; (nlp != NULL); nlp = nlp->next) {
2084 		mdname_t	*transnp = nlp->namep;
2085 		md_trans_t	*transp;
2086 
2087 		if ((transp = meta_get_trans(sp, transnp, ep)) == NULL) {
2088 			count = -1;
2089 			goto out;
2090 		}
2091 		if (transp->lognamep) {
2092 			/*
2093 			 * Add the name struct to the end of the
2094 			 * namelist but keep a pointer to the last
2095 			 * element so that we don't incur the overhead
2096 			 * of traversing the list each time
2097 			 */
2098 			tailpp = meta_namelist_append_wrapper(
2099 			    tailpp, transp->lognamep);
2100 		}
2101 	}
2102 out:
2103 	metafreenamelist(transnlp);
2104 	return (count);
2105 }
2106 
2107 /*
2108  * Entry point to join a node to MultiNode diskset.
2109  *
2110  * Validate host in diskset.
2111  *	- Should be in membership list from API
2112  *	- Should not already be joined into diskset.
2113  *	- Set must have drives
2114  * Assume valid configuration is stored in the set/drive/node records
2115  * in the local mddb since no node or drive can be added to the MNset
2116  * unless all drives and nodes are available.  Reconfig steps will
2117  * resync all ALIVE nodes in case of panic in critical areas.
2118  *
2119  * Lock down the set.
2120  * Verify host is a member of this diskset.
2121  * If drives exist in the configuration, load the mddbs.
2122  * Set this node to active by notifying master if one exists.
2123  * If this is the first node active in the diskset, this node
2124  * 	becomes the master.
2125  * Unlock the set.
2126  *
2127  * Mirror Resync:
2128  * If this node is the last node to join the set and clustering
2129  * isn't running, then start the 'metasync -r' type resync
2130  * on all mirrors in this diskset.
2131  * If clustering is running, this resync operation will
2132  * be handled by the reconfig steps and should NOT
2133  * be handled during a join operation.
2134  *
2135  * There are multiple return values in order to assist
2136  * the join operation of all sets in the metaset command.
2137  *
2138  * Return values:
2139  *	0  - Node successfully joined to set.
2140  *	-1 - Join attempted but failed
2141  *		- any failure from libmeta calls
2142  *		- node not in the member list
2143  *	-2 - Join not attempted since
2144  *		- this set had no drives in set
2145  *		- this node already joined to set
2146  *		- set is not a multinode set
2147  *	-3 - Node joined to STALE set.
2148  */
2149 extern int
2150 meta_set_join(
2151 	mdsetname_t	*sp,
2152 	md_error_t	*ep
2153 )
2154 {
2155 	md_set_desc		*sd;
2156 	md_drive_desc		*dd;
2157 	md_mnnode_desc		*nd, *nd2, my_nd;
2158 	int			rval = 0;
2159 	md_setkey_t		*cl_sk;
2160 	md_error_t		xep = mdnullerror;
2161 	md_error_t		ep_snarf = mdnullerror;
2162 	int			master_flag = 0;
2163 	md_mnset_record		*mas_mnsr = NULL;
2164 	int			clear_nr_flags = 0;
2165 	md_mnnode_record	*nr;
2166 	int			stale_set = 0;
2167 	int			rb_flags = 0;
2168 	int			stale_bool = FALSE;
2169 	int			suspendall_flag = 0;
2170 	int			suspend1_flag = 0;
2171 	sigset_t		oldsigs;
2172 	int			send_reinit = 0;
2173 
2174 	if ((sd = metaget_setdesc(sp, ep)) == NULL) {
2175 		return (-1);
2176 	}
2177 
2178 	/* Must be a multinode diskset */
2179 	if (!MD_MNSET_DESC(sd)) {
2180 		(void) mderror(ep, MDE_NOT_MN, sp->setname);
2181 		return (-2);
2182 	}
2183 
2184 	/* Verify that the node is ALIVE (i.e. is in the API membership list) */
2185 	if (!(sd->sd_mn_mynode->nd_flags & MD_MN_NODE_ALIVE)) {
2186 		(void) mddserror(ep, MDE_DS_NOTINMEMBERLIST, sp->setno,
2187 			sd->sd_mn_mynode->nd_nodename, NULL,
2188 			sp->setname);
2189 		return (-1);
2190 	}
2191 
2192 	/* Make sure we are blocking all signals */
2193 	if (procsigs(TRUE, &oldsigs, &xep) < 0)
2194 		mdclrerror(&xep);
2195 
2196 	/*
2197 	 * Lock the set on current set members.
2198 	 * For MN diskset lock_set and SUSPEND are used to protect against
2199 	 * other meta* commands running on the other nodes.
2200 	 */
2201 	nd = sd->sd_nodelist;
2202 	while (nd) {
2203 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
2204 			nd = nd->nd_next;
2205 			continue;
2206 		}
2207 		if (clnt_lock_set(nd->nd_nodename, sp, ep)) {
2208 			rval = -1;
2209 			goto out;
2210 		}
2211 		nd = nd->nd_next;
2212 	}
2213 
2214 	/*
2215 	 * Lock out other meta* commands by suspending
2216 	 * class 1 messages across the diskset.
2217 	 */
2218 	nd = sd->sd_nodelist;
2219 	while (nd) {
2220 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
2221 			nd = nd->nd_next;
2222 			continue;
2223 		}
2224 		if (clnt_mdcommdctl(nd->nd_nodename, COMMDCTL_SUSPEND,
2225 			    sp, MD_MSG_CLASS1, MD_MSCF_NO_FLAGS, ep)) {
2226 			rval = -1;
2227 			goto out;
2228 		}
2229 		suspend1_flag = 1;
2230 		nd = nd->nd_next;
2231 	}
2232 
2233 	/*
2234 	 * Verify that this host is a member (in the host list) of the set.
2235 	 */
2236 	nd = sd->sd_nodelist;
2237 	while (nd) {
2238 		if (strcmp(mynode(), nd->nd_nodename) == 0) {
2239 			break;
2240 		}
2241 		nd = nd->nd_next;
2242 	}
2243 	if (!nd) {
2244 		(void) mddserror(ep, MDE_DS_NODENOTINSET, sp->setno,
2245 			sd->sd_mn_mynode->nd_nodename, NULL,
2246 			sp->setname);
2247 		rval = -1;
2248 		goto out;
2249 	}
2250 
2251 	/*
2252 	 * Need to return failure if host is already 'joined'
2253 	 * into the set.  This is done so that if later the user
2254 	 * issues a command to join all sets and a failure is
2255 	 * encountered - that the resulting cleanup effort
2256 	 * (withdrawing from all sets that were joined
2257 	 * during that command) won't withdraw from this set.
2258 	 */
2259 	if (nd->nd_flags & MD_MN_NODE_OWN) {
2260 		rval = -2;
2261 		goto out2;
2262 	}
2263 
2264 	/*
2265 	 * Call metaget_setownership that calls each node in diskset and
2266 	 * marks in set descriptor if node is an owner of the set or not.
2267 	 * metaget_setownership checks to see if a node is an owner by
2268 	 * checking to see if that node's kernel has the mddb loaded.
2269 	 * If a node had panic'd during a reconfig or an
2270 	 * add/delete/join/withdraw operation, the other nodes' node
2271 	 * records may not reflect the current state of the diskset,
2272 	 * so calling metaget_setownership is the safest thing to do.
2273 	 */
2274 	if (metaget_setownership(sp, ep) == -1) {
2275 		rval = -1;
2276 		goto out;
2277 	}
2278 
2279 	/* If first active member of diskset, become the master. */
2280 	nd = sd->sd_nodelist;
2281 	while (nd) {
2282 		if (nd->nd_flags & MD_MN_NODE_OWN)
2283 			break;
2284 		nd = nd->nd_next;
2285 	}
2286 	if (nd == NULL)
2287 		master_flag = 1;
2288 
2289 	/*
2290 	 * If not first active member of diskset, then get the
2291 	 * master information from a node that is already joined
2292 	 * and set the master information for this node.  Be sure
2293 	 * that this node (the already joined node) has its own
2294 	 * join flag set.  If not, then this diskset isn't currently
2295 	 * consistent and shouldn't allow a node to join.  This diskset
2296 	 * inconsistency should only occur when a node has panic'd in
2297 	 * the set while doing a metaset operation and the sysadmin is
2298 	 * attempting to join a node into the set.  This inconsistency
2299 	 * will be fixed during a reconfig cycle which should be occurring
2300 	 * soon since a node panic'd.
2301 	 *
2302 	 * If unable to get this information from an owning node, then
2303 	 * this diskset isn't currently consistent and shouldn't
2304 	 * allow a node to join.
2305 	 */
2306 	if (!master_flag) {
2307 		/* get master information from an owner (joined) node */
2308 		if (clnt_mngetset(nd->nd_nodename, sp->setname,
2309 		    sp->setno, &mas_mnsr, ep) == -1) {
2310 			rval = -1;
2311 			goto out;
2312 		}
2313 
2314 		/* Verify that owner (joined) node has its own JOIN flag set */
2315 		nr = mas_mnsr->sr_nodechain;
2316 		while (nr) {
2317 			if ((nd->nd_nodeid == nr->nr_nodeid) &&
2318 			    ((nr->nr_flags & MD_MN_NODE_OWN) == NULL)) {
2319 				(void) mddserror(ep, MDE_DS_NODENOSET,
2320 				    sp->setno, nd->nd_nodename, NULL,
2321 				    nd->nd_nodename);
2322 				free_sr((md_set_record *)mas_mnsr);
2323 				rval = -1;
2324 				goto out;
2325 			}
2326 			nr = nr->nr_next;
2327 		}
2328 
2329 		/*
2330 		 * Does master have set marked as STALE?
2331 		 * If so, need to pass this down to kernel when
2332 		 * this node snarfs the set.
2333 		 */
2334 		if (clnt_mn_is_stale(nd->nd_nodename, sp,
2335 		    &stale_bool, ep) == -1) {
2336 			rval = -1;
2337 			goto out;
2338 		}
2339 
2340 		/* set master information in my rpc.metad's set record */
2341 		if (clnt_mnsetmaster(mynode(), sp, mas_mnsr->sr_master_nodenm,
2342 		    mas_mnsr->sr_master_nodeid, ep)) {
2343 			free_sr((md_set_record *)mas_mnsr);
2344 			rval = -1;
2345 			goto out;
2346 		}
2347 
2348 		/* set master information in my cached set desc */
2349 		(void) strcpy(sd->sd_mn_master_nodenm,
2350 		    mas_mnsr->sr_master_nodenm);
2351 		sd->sd_mn_master_nodeid = mas_mnsr->sr_master_nodeid;
2352 		nd2 = sd->sd_nodelist;
2353 		while (nd2) {
2354 		    if (nd2->nd_nodeid == mas_mnsr->sr_master_nodeid) {
2355 			sd->sd_mn_masternode = nd2;
2356 			break;
2357 		    }
2358 		    nd2 = nd2->nd_next;
2359 		}
2360 		free_sr((md_set_record *)mas_mnsr);
2361 
2362 		/*
2363 		 * Set the node flags in mynode's rpc.metad node records for
2364 		 * the nodes that are in the diskset.  Can use my sd
2365 		 * since earlier call to metaget_setownership set the
2366 		 * owner flags based on whether that node had snarfed
2367 		 * the MN diskset mddb.  Reconfig steps guarantee that
2368 		 * return of metaget_setownership will match the owning
2369 		 * node's owner list except in the case where a node
2370 		 * has just panic'd and in this case, a reconfig will
2371 		 * be starting immediately and the owner lists will
2372 		 * be sync'd up by the reconfig.
2373 		 *
2374 		 * Flag of SET means to take no action except to
2375 		 * set the node flags as given in the nodelist linked list.
2376 		 */
2377 		if (clnt_upd_nr_flags(mynode(), sp, sd->sd_nodelist,
2378 		    MD_NR_SET, NULL, ep)) {
2379 			rval = -1;
2380 			goto out;
2381 		}
2382 	}
2383 
2384 	/*
2385 	 * Read in the mddb if there are drives in the set.
2386 	 */
2387 	if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
2388 	    ep)) == NULL) {
2389 		/* No drives in list */
2390 		if (! mdisok(ep)) {
2391 			rval = -1;
2392 			goto out;
2393 		}
2394 		rval = -2;
2395 		goto out;
2396 	}
2397 
2398 	/*
2399 	 * Notify rpc.mdcommd on all nodes of a nodelist change.
2400 	 * Start by suspending rpc.mdcommd (which drains it of all messages),
2401 	 * then change the nodelist followed by a reinit and resume.
2402 	 */
2403 	nd = sd->sd_nodelist;
2404 	while (nd) {
2405 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
2406 			nd = nd->nd_next;
2407 			continue;
2408 		}
2409 
2410 		if (clnt_mdcommdctl(nd->nd_nodename, COMMDCTL_SUSPEND, sp,
2411 		    MD_MSG_CLASS0, MD_MSCF_NO_FLAGS, ep)) {
2412 			rval = -1;
2413 			goto out;
2414 		}
2415 		suspendall_flag = 1;
2416 		nd = nd->nd_next;
2417 	}
2418 
2419 	/* Set master in my set record in rpc.metad */
2420 	if (master_flag) {
2421 		if (clnt_mnsetmaster(mynode(), sp,
2422 		    sd->sd_mn_mynode->nd_nodename,
2423 		    sd->sd_mn_mynode->nd_nodeid, ep)) {
2424 			rval = -1;
2425 			goto out;
2426 		}
2427 	}
2428 	/* Causes mddbs to be loaded in kernel */
2429 	if (setup_db_bydd(sp, dd, 0, ep) == -1) {
2430 		mde_perror(ep, dgettext(TEXT_DOMAIN,
2431 		    "Host not able to start diskset."));
2432 		rval = -1;
2433 		goto out;
2434 	}
2435 
2436 	if (! mdisok(ep)) {
2437 		rval = -1;
2438 		goto out;
2439 	}
2440 
2441 	/*
2442 	 * Set rollback flags to 1 so that halt_set is called if a failure
2443 	 * is seen after this point.  If snarf_set fails, still need to
2444 	 * call halt_set to cleanup the diskset.
2445 	 */
2446 	rb_flags = 1;
2447 
2448 	/* Starts the set */
2449 	if (snarf_set(sp, stale_bool, ep) != 0) {
2450 		if (mdismddberror(ep, MDE_DB_STALE)) {
2451 			/*
2452 			 * Don't fail join, STALE means that set has
2453 			 * < 50% mddbs.
2454 			 */
2455 			(void) mdstealerror(&ep_snarf, ep);
2456 			stale_set = 1;
2457 		} else if (mdisok(ep)) {
2458 			/* If snarf failed, but no error was set - set it */
2459 			(void) mdmddberror(ep, MDE_DB_NOTNOW, (minor_t)NODEV64,
2460 			    sp->setno, 0, NULL);
2461 				rval = -1;
2462 				goto out;
2463 		} else if (!(mdismddberror(ep, MDE_DB_ACCOK))) {
2464 			/*
2465 			 * Don't fail join if ACCOK; ACCOK means that mediator
2466 			 * provided extra vote.
2467 			 */
2468 			rval = -1;
2469 			goto out;
2470 		}
2471 	}
2472 
2473 	/* Did set really get snarfed? */
2474 	if (own_set(sp, NULL, TRUE, ep) == MD_SETOWNER_NO) {
2475 		if (mdisok(ep)) {
2476 			/* If snarf failed, but no error was set - set it */
2477 			(void) mdmddberror(ep, MDE_DB_NOTNOW, (minor_t)NODEV64,
2478 				sp->setno, 0, NULL);
2479 		}
2480 		mde_perror(ep, dgettext(TEXT_DOMAIN,
2481 		    "Host not able to start diskset."));
2482 		rval = -1;
2483 		goto out;
2484 	}
2485 
2486 	/* Change to nodelist so need to send reinit to rpc.mdcommd */
2487 	send_reinit = 1;
2488 
2489 	/* If first node to enter set, setup master and clear change log */
2490 	if (master_flag) {
2491 		/* Set master in my locally cached set descriptor */
2492 		(void) strcpy(sd->sd_mn_master_nodenm,
2493 		    sd->sd_mn_mynode->nd_nodename);
2494 		sd->sd_mn_master_nodeid = sd->sd_mn_mynode->nd_nodeid;
2495 		sd->sd_mn_am_i_master = 1;
2496 
2497 		/*
2498 		 * If first node to join set, then clear out change log
2499 		 * entries.  Change log entries are only needed when a
2500 		 * change of master is occurring in a diskset that has
2501 		 * multiple owners.   Since this node is the first owner
2502 		 * of the diskset, clear the entries.
2503 		 *
2504 		 * Only do this if we are in a single node non-SC3.x
2505 		 * situation.
2506 		 */
2507 		if (meta_mn_singlenode() &&
2508 			mdmn_reset_changelog(sp, ep,  MDMN_CLF_RESETLOG) != 0) {
2509 			mde_perror(ep, dgettext(TEXT_DOMAIN,
2510 			    "Unable to reset changelog."));
2511 			rval = -1;
2512 			goto out;
2513 		}
2514 	}
2515 
2516 	/* Set my locally cached flag */
2517 	sd->sd_mn_mynode->nd_flags |= MD_MN_NODE_OWN;
2518 
2519 	/*
2520 	 * Set this node's own flag on all joined nodes in the set
2521 	 * (including my node).
2522 	 */
2523 	clear_nr_flags = 1;
2524 
2525 	my_nd = *(sd->sd_mn_mynode);
2526 	my_nd.nd_next = NULL;
2527 	nd = sd->sd_nodelist;
2528 	while (nd) {
2529 		if (!(nd->nd_flags & MD_MN_NODE_OWN)) {
2530 			nd = nd->nd_next;
2531 			continue;
2532 		}
2533 		if (clnt_upd_nr_flags(nd->nd_nodename, sp, &my_nd,
2534 		    MD_NR_JOIN, NULL, ep)) {
2535 			rval = -1;
2536 			goto out;
2537 		}
2538 		nd = nd->nd_next;
2539 	}
2540 
2541 out:
2542 	if (rval != NULL) {
2543 		/*
2544 		 * If rollback flag is 1, then node was joined to set.
2545 		 * Since an error occurred, withdraw node from set in
2546 		 * order to rollback to before command was run.
2547 		 * Need to preserve ep so that calling function can
2548 		 * get error information.
2549 		 */
2550 		if (rb_flags == 1) {
2551 			if (halt_set(sp, &xep)) {
2552 				mdclrerror(&xep);
2553 			}
2554 		}
2555 
2556 		/*
2557 		 * If error, reset master to INVALID.
2558 		 * Ignore error since (next) first node to successfully join
2559 		 * will set master on all nodes.
2560 		 */
2561 		(void) clnt_mnsetmaster(mynode(), sp, "",
2562 			MD_MN_INVALID_NID, &xep);
2563 		mdclrerror(&xep);
2564 		/* Reset master in my locally cached set descriptor */
2565 		sd->sd_mn_master_nodeid = MD_MN_INVALID_NID;
2566 		sd->sd_mn_am_i_master = 0;
2567 
2568 		/*
2569 		 * If nr flags set on other nodes, reset them.
2570 		 */
2571 		if (clear_nr_flags) {
2572 			nd = sd->sd_nodelist;
2573 			while (nd) {
2574 				if (!(nd->nd_flags & MD_MN_NODE_OWN)) {
2575 					nd = nd->nd_next;
2576 					continue;
2577 				}
2578 				(void) clnt_upd_nr_flags(nd->nd_nodename, sp,
2579 					&my_nd, MD_NR_WITHDRAW, NULL, &xep);
2580 				mdclrerror(&xep);
2581 				nd = nd->nd_next;
2582 			}
2583 			/* Reset my locally cached flag */
2584 			sd->sd_mn_mynode->nd_flags &= ~MD_MN_NODE_OWN;
2585 		}
2586 	}
2587 
2588 	/*
2589 	 * Notify rpc.mdcommd on all nodes of a nodelist change.
2590 	 * Send reinit command to mdcommd which forces it to get
2591 	 * fresh set description.
2592 	 */
2593 	if (send_reinit) {
2594 		/* Send reinit */
2595 		nd = sd->sd_nodelist;
2596 		while (nd) {
2597 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
2598 				nd = nd->nd_next;
2599 				continue;
2600 			}
2601 
2602 			/* Class is ignored for REINIT */
2603 			if (clnt_mdcommdctl(nd->nd_nodename, COMMDCTL_REINIT,
2604 				sp, NULL, MD_MSCF_NO_FLAGS, &xep)) {
2605 				/*
2606 				 * We are here because we failed to resume
2607 				 * rpc.mdcommd.  However we potentially have
2608 				 * an error from the previous call
2609 				 * If the previous call did fail,  we capture
2610 				 * that error and generate a perror with
2611 				 * the string, "Unable to resume...".
2612 				 * Setting rval to -1 ensures that in the
2613 				 * next iteration of the loop, ep is not
2614 				 * clobbered.
2615 				 */
2616 				if (rval == 0)
2617 					(void) mdstealerror(ep, &xep);
2618 				else
2619 					mdclrerror(&xep);
2620 				rval = -1;
2621 				mde_perror(ep, dgettext(TEXT_DOMAIN,
2622 				    "Unable to reinit rpc.mdcommd."));
2623 			}
2624 			nd = nd->nd_next;
2625 		}
2626 
2627 	}
2628 
2629 out2:
2630 	/*
2631 	 * Unlock diskset by resuming messages across the diskset.
2632 	 * Just resume all classes so that resume is the same whether
2633 	 * just one class was locked or all classes were locked.
2634 	 */
2635 	if ((suspend1_flag) || (suspendall_flag)) {
2636 		nd = sd->sd_nodelist;
2637 		while (nd) {
2638 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
2639 				nd = nd->nd_next;
2640 				continue;
2641 			}
2642 			if (clnt_mdcommdctl(nd->nd_nodename, COMMDCTL_RESUME,
2643 				sp, MD_MSG_CLASS0, MD_MSCF_NO_FLAGS, &xep)) {
2644 				/*
2645 				 * We are here because we failed to resume
2646 				 * rpc.mdcommd.  However we potentially have
2647 				 * an error from the previous call
2648 				 * If the previous call did fail,  we capture
2649 				 * that error and generate a perror with
2650 				 * the string, "Unable to resume...".
2651 				 * Setting rval to -1 ensures that in the
2652 				 * next iteration of the loop, ep is not
2653 				 * clobbered.
2654 				 */
2655 				if (rval == 0)
2656 					(void) mdstealerror(ep, &xep);
2657 				else
2658 					mdclrerror(&xep);
2659 				rval = -1;
2660 				mde_perror(ep, dgettext(TEXT_DOMAIN,
2661 				    "Unable to resume rpc.mdcommd."));
2662 			}
2663 			nd = nd->nd_next;
2664 		}
2665 		meta_ping_mnset(sp->setno);
2666 	}
2667 
2668 	/*
2669 	 * Unlock set.  This flushes the caches on the servers.
2670 	 */
2671 	cl_sk = cl_get_setkey(sp->setno, sp->setname);
2672 	nd = sd->sd_nodelist;
2673 	while (nd) {
2674 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
2675 			nd = nd->nd_next;
2676 			continue;
2677 		}
2678 		if (clnt_unlock_set(nd->nd_nodename, cl_sk, &xep)) {
2679 			if (rval == 0)
2680 				(void) mdstealerror(ep, &xep);
2681 			else
2682 				mdclrerror(&xep);
2683 			rval = -1;
2684 		}
2685 		nd = nd->nd_next;
2686 	}
2687 
2688 	/*
2689 	 * If this node is the last to join the diskset and clustering isn't
2690 	 * running, then resync the mirrors in the diskset. We have to wait
2691 	 * until all nodes are joined so that the status gets propagated to
2692 	 * all of the members of the set.
2693 	 * Ignore any error from the resync as the join function shouldn't fail
2694 	 * because the mirror resync had a problem.
2695 	 *
2696 	 * Don't start resync if set is stale.
2697 	 */
2698 	if ((rval == 0) && (sdssc_bind_library() != SDSSC_OKAY) &&
2699 	    (stale_set != 1)) {
2700 		nd = sd->sd_nodelist;
2701 		while (nd) {
2702 			if (!(nd->nd_flags & MD_MN_NODE_OWN))
2703 				break;
2704 			nd = nd->nd_next;
2705 		}
2706 		/*
2707 		 * nd set to NULL means that we have no nodes in the set that
2708 		 * haven't joined. In this case we start the resync.
2709 		 */
2710 		if (nd == NULL) {
2711 			(void) meta_mirror_resync_all(sp, 0, &xep);
2712 			mdclrerror(&xep);
2713 		}
2714 	}
2715 
2716 	/* Update ABR state for all soft partitions */
2717 	(void) meta_sp_update_abr(sp, &xep);
2718 	mdclrerror(&xep);
2719 
2720 	/*
2721 	 * call metaflushsetnames to reset local cache for master and
2722 	 * node information.
2723 	 */
2724 	metaflushsetname(sp);
2725 
2726 	/* release signals back to what they were on entry */
2727 	if (procsigs(FALSE, &oldsigs, &xep) < 0)
2728 		mdclrerror(&xep);
2729 
2730 	/*
2731 	 * If no error and stale_set is set, then set ep back
2732 	 * to ep from snarf_set call and return -3.  If another error
2733 	 * occurred and rval is not 0, then that error would have
2734 	 * caused the node to be withdrawn from the set and would
2735 	 * have set ep to that error information.
2736 	 */
2737 	if ((rval == 0) && (stale_set)) {
2738 		(void) mdstealerror(ep, &ep_snarf);
2739 		return (-3);
2740 	}
2741 
2742 	return (rval);
2743 }
2744 
2745 /*
2746  * Entry point to withdraw a node from MultiNode diskset.
2747  *
2748  * Validate host in diskset.
2749  *	- Should be joined into diskset.
2750  * Assume valid configuration is stored in the set/drive/node records
2751  * in the local mddb since no node or drive can be added to the MNset
2752  * unless all drives and nodes are available.  Reconfig steps will
2753  * resync all ALIVE nodes in case of panic in critical areas.
2754  *
2755  * Lock down the set.
2756  * Verify that drives exist in configuration.
2757  * Verify host is a member of this diskset.
2758  * Verify host is an owner of the diskset (host is joined to diskset).
2759  * Only allow withdrawal of master node if master node is the only joined
2760  * in the diskset.
2761  * Halt the diskset on this node.
2762  * Reset Master on this node.
2763  * Updated node flags that this node with withdrawn.
2764  * Unlock the set.
2765  *
2766  * Return values:
2767  *	0  - Node successfully withdrew from set.
2768  *	-1 - Withdrawal attempted but failed
2769  *		- any failure from libmeta calls
2770  *		- node not in the member list
2771  *	-2 - Withdrawal not attempted since
2772  *		- this set had no drives in set
2773  *		- this node not joined to set
2774  *		- set is not a multinode set
2775  */
2776 extern int
2777 meta_set_withdraw(
2778 	mdsetname_t	*sp,
2779 	md_error_t	*ep
2780 )
2781 {
2782 	md_set_desc		*sd;
2783 	md_drive_desc		*dd = 0;
2784 	md_mnnode_desc		*nd, my_nd;
2785 	int			rval = 0;
2786 	md_setkey_t		*cl_sk;
2787 	md_error_t		xep = mdnullerror;
2788 	int			set_halted = 0;
2789 	int			suspendall_flag = 0;
2790 	int			suspend1_flag = 0;
2791 	bool_t			stale_bool = FALSE;
2792 	mddb_config_t		c;
2793 	int			node_id_list[1];
2794 	sigset_t		oldsigs;
2795 	int			send_reinit = 0;
2796 
2797 	if ((sd = metaget_setdesc(sp, ep)) == NULL) {
2798 		return (-1);
2799 	}
2800 
2801 	/* Must be a multinode diskset */
2802 	if (!MD_MNSET_DESC(sd)) {
2803 		(void) mderror(ep, MDE_NOT_MN, sp->setname);
2804 		return (-1);
2805 	}
2806 
2807 	/* Make sure we are blocking all signals */
2808 	if (procsigs(TRUE, &oldsigs, &xep) < 0)
2809 		mdclrerror(&xep);
2810 
2811 	/*
2812 	 * Lock the set on current set members.
2813 	 * For MN diskset lock_set and SUSPEND are used to protect against
2814 	 * other meta* commands running on the other nodes.
2815 	 */
2816 	nd = sd->sd_nodelist;
2817 	while (nd) {
2818 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
2819 			nd = nd->nd_next;
2820 			continue;
2821 		}
2822 		if (clnt_lock_set(nd->nd_nodename, sp, ep)) {
2823 			rval = -1;
2824 			goto out;
2825 		}
2826 		nd = nd->nd_next;
2827 	}
2828 	/*
2829 	 * Lock out other meta* commands by suspending
2830 	 * class 1 messages across the diskset.
2831 	 */
2832 	nd = sd->sd_nodelist;
2833 	while (nd) {
2834 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
2835 			nd = nd->nd_next;
2836 			continue;
2837 		}
2838 		if (clnt_mdcommdctl(nd->nd_nodename, COMMDCTL_SUSPEND,
2839 			sp, MD_MSG_CLASS1, MD_MSCF_NO_FLAGS, ep)) {
2840 			rval = -1;
2841 			goto out;
2842 		}
2843 		suspend1_flag = 1;
2844 		nd = nd->nd_next;
2845 	}
2846 
2847 	/* Get list of drives - needed in case of failure */
2848 	if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
2849 	    ep)) == NULL) {
2850 		/* Error getting drives in list */
2851 		if (! mdisok(ep)) {
2852 			rval = -1;
2853 			goto out2;
2854 		}
2855 		/* no drives in list */
2856 		rval = -2;
2857 		goto out2;
2858 	}
2859 
2860 	/*
2861 	 * Verify that this host is a member (in the host list) of the set.
2862 	 */
2863 	nd = sd->sd_nodelist;
2864 	while (nd) {
2865 		if (strcmp(mynode(), nd->nd_nodename) == 0) {
2866 			break;
2867 		}
2868 		nd = nd->nd_next;
2869 	}
2870 	if (!nd) {
2871 		(void) mddserror(ep, MDE_DS_NODENOTINSET, sp->setno,
2872 			sd->sd_mn_mynode->nd_nodename, NULL,
2873 			sp->setname);
2874 		rval = -1;
2875 		goto out2;
2876 	}
2877 
2878 	/*
2879 	 * Call metaget_setownership that calls each node in diskset and
2880 	 * marks in set descriptor if node is an owner of the set or not.
2881 	 * metaget_setownership checks to see if a node is an owner by
2882 	 * checking to see if that node's kernel has the mddb loaded.
2883 	 * If a node had panic'd during a reconfig or an
2884 	 * add/delete/join/withdraw operation, the other nodes' node
2885 	 * records may not reflect the current state of the diskset,
2886 	 * so calling metaget_setownership is the safest thing to do.
2887 	 */
2888 	if (metaget_setownership(sp, ep) == -1) {
2889 		rval = -1;
2890 		goto out2;
2891 	}
2892 
2893 	/*
2894 	 * Verify that this node is joined
2895 	 * to diskset (i.e. is an owner of the diskset).
2896 	 */
2897 	if (!(sd->sd_mn_mynode->nd_flags & MD_MN_NODE_OWN)) {
2898 		rval = -2;
2899 		goto out2;
2900 	}
2901 
2902 	/*
2903 	 * For a MN diskset, only withdraw master if it is
2904 	 * the only joined node.
2905 	 */
2906 	if (sd->sd_mn_master_nodeid == sd->sd_mn_mynode->nd_nodeid) {
2907 		nd = sd->sd_nodelist;
2908 		while (nd) {
2909 			/* Skip my node since checking for other owners */
2910 			if (nd->nd_nodeid == sd->sd_mn_master_nodeid) {
2911 				nd = nd->nd_next;
2912 				continue;
2913 			}
2914 			/* If another owner node if found, error */
2915 			if (nd->nd_flags & MD_MN_NODE_OWN) {
2916 				(void) mddserror(ep, MDE_DS_WITHDRAWMASTER,
2917 					sp->setno,
2918 					sd->sd_mn_mynode->nd_nodename, NULL,
2919 					sp->setname);
2920 				rval = -1;
2921 				goto out2;
2922 			}
2923 			nd = nd->nd_next;
2924 		}
2925 	}
2926 
2927 	/*
2928 	 * Is current set STALE?
2929 	 */
2930 	(void) memset(&c, 0, sizeof (c));
2931 	c.c_id = 0;
2932 	c.c_setno = sp->setno;
2933 	if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) {
2934 		(void) mdstealerror(ep, &c.c_mde);
2935 		rval = -1;
2936 		goto out;
2937 	}
2938 	if (c.c_flags & MDDB_C_STALE) {
2939 		stale_bool = TRUE;
2940 	}
2941 
2942 	/*
2943 	 * Notify rpc.mdcommd on all nodes of a nodelist change.
2944 	 * Start by suspending rpc.mdcommd (which drains it of all messages),
2945 	 * then change the nodelist followed by a reinit and resume.
2946 	 */
2947 	nd = sd->sd_nodelist;
2948 	while (nd) {
2949 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
2950 			nd = nd->nd_next;
2951 			continue;
2952 		}
2953 
2954 		if (clnt_mdcommdctl(nd->nd_nodename, COMMDCTL_SUSPEND,
2955 		    sp, MD_MSG_CLASS0, MD_MSCF_NO_FLAGS, ep)) {
2956 			rval = -1;
2957 			goto out;
2958 		}
2959 		suspendall_flag = 1;
2960 		nd = nd->nd_next;
2961 	}
2962 
2963 	/*
2964 	 * Withdraw the set - halt set.
2965 	 * This will fail if any I/O is occuring to any metadevice which
2966 	 * includes a resync to a mirror metadevice.
2967 	 */
2968 	set_halted = 1;
2969 	if (halt_set(sp, ep)) {
2970 		/* Was set actually halted? */
2971 		if (own_set(sp, NULL, TRUE, ep) == MD_SETOWNER_YES) {
2972 			set_halted = 0;
2973 		}
2974 		rval = -1;
2975 		goto out;
2976 	}
2977 
2978 	/* Change to nodelist so need to send reinit to rpc.mdcommd */
2979 	send_reinit = 1;
2980 
2981 	/* Reset master on withdrawn node */
2982 	if (clnt_mnsetmaster(sd->sd_mn_mynode->nd_nodename, sp, "",
2983 	    MD_MN_INVALID_NID, ep)) {
2984 		rval = -1;
2985 		goto out;
2986 	}
2987 
2988 	/* Mark my node as withdrawn and send to other nodes */
2989 	nd = sd->sd_nodelist;
2990 	my_nd = *(sd->sd_mn_mynode);	/* structure copy */
2991 	my_nd.nd_next = NULL;
2992 	while (nd) {
2993 		if (!(nd->nd_flags & MD_MN_NODE_OWN)) {
2994 			nd = nd->nd_next;
2995 			continue;
2996 		}
2997 		if (clnt_upd_nr_flags(nd->nd_nodename, sp, &my_nd,
2998 		    MD_NR_WITHDRAW, NULL, ep)) {
2999 			rval = -1;
3000 			goto out;
3001 		}
3002 		nd = nd->nd_next;
3003 	}
3004 
3005 	/*
3006 	 * If withdrawn node is a mirror owner, reset mirror owner
3007 	 * to NULL.  If an error occurs, print a warning and continue.
3008 	 * Don't fail metaset because of mirror owner reset problem since
3009 	 * next node to grab mirror will resolve this issue.
3010 	 * Before next node grabs mirrors, metaset will show the withdrawn
3011 	 * node as owner which is why an attempt to reset the mirror owner
3012 	 * is made.
3013 	 */
3014 	node_id_list[0] = sd->sd_mn_mynode->nd_nodeid;	/* Setup my nodeid */
3015 	nd = sd->sd_nodelist;
3016 	while (nd) {
3017 		if (!(nd->nd_flags & MD_MN_NODE_OWN)) {
3018 			nd = nd->nd_next;
3019 			continue;
3020 		}
3021 		if (clnt_reset_mirror_owner(nd->nd_nodename, sp,
3022 		    1, &node_id_list[0], &xep) == 01) {
3023 			mde_perror(&xep, dgettext(TEXT_DOMAIN,
3024 			    "Unable to reset mirror owner on node %s"),
3025 			    nd->nd_nodename);
3026 			mdclrerror(&xep);
3027 		}
3028 		nd = nd->nd_next;
3029 	}
3030 
3031 out:
3032 	if (rval == -1) {
3033 		/* Rejoin node - Mark node as joined and send to other nodes */
3034 		nd = sd->sd_nodelist;
3035 		my_nd = *(sd->sd_mn_mynode);	/* structure copy */
3036 		my_nd.nd_next = NULL;
3037 		while (nd) {
3038 			if (!(nd->nd_flags & MD_MN_NODE_OWN)) {
3039 				nd = nd->nd_next;
3040 				continue;
3041 			}
3042 			if (clnt_upd_nr_flags(nd->nd_nodename, sp, &my_nd,
3043 			    MD_NR_JOIN, NULL, &xep)) {
3044 				mdclrerror(&xep);
3045 			}
3046 			nd = nd->nd_next;
3047 		}
3048 
3049 		/* Set master on withdrawn node */
3050 		if (clnt_mnsetmaster(sd->sd_mn_mynode->nd_nodename, sp,
3051 		    sd->sd_mn_master_nodenm,
3052 		    sd->sd_mn_master_nodeid, &xep)) {
3053 			mdclrerror(&xep);
3054 		}
3055 
3056 		/* Join set if halt_set had succeeded */
3057 		if (set_halted) {
3058 			if (setup_db_bydd(sp, dd, 0, &xep) == -1) {
3059 				mdclrerror(&xep);
3060 			}
3061 			/* If set previously stale - make it so at re-join */
3062 			if (snarf_set(sp, stale_bool, &xep) != 0) {
3063 				mdclrerror(&xep);
3064 				(void) halt_set(sp, &xep);
3065 				mdclrerror(&xep);
3066 			}
3067 		}
3068 	}
3069 
3070 	/*
3071 	 * Notify rpc.mdcommd on all nodes of a nodelist change.
3072 	 * Send reinit command to mdcommd which forces it to get
3073 	 * fresh set description.
3074 	 */
3075 	if (send_reinit) {
3076 		/* Send reinit */
3077 		nd = sd->sd_nodelist;
3078 		while (nd) {
3079 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3080 				nd = nd->nd_next;
3081 				continue;
3082 			}
3083 
3084 			/* Class is ignored for REINIT */
3085 			if (clnt_mdcommdctl(nd->nd_nodename, COMMDCTL_REINIT,
3086 				sp, NULL, MD_MSCF_NO_FLAGS, &xep)) {
3087 				/*
3088 				 * We are here because we failed to resume
3089 				 * rpc.mdcommd.  However we potentially have
3090 				 * an error from the previous call.
3091 				 * If the previous call did fail,  we
3092 				 * capture that error and generate a perror
3093 				 * withthe string,  "Unable to resume...".
3094 				 * Setting rval to -1 ensures that in the
3095 				 * next iteration of the loop, ep is not
3096 				 * clobbered.
3097 				 */
3098 				if (rval == 0)
3099 					(void) mdstealerror(ep, &xep);
3100 				else
3101 					mdclrerror(&xep);
3102 				rval = -1;
3103 				mde_perror(ep, dgettext(TEXT_DOMAIN,
3104 				    "Unable to reinit rpc.mdcommd."));
3105 			}
3106 			nd = nd->nd_next;
3107 		}
3108 	}
3109 
3110 out2:
3111 	/*
3112 	 * Unlock diskset by resuming messages across the diskset.
3113 	 * Just resume all classes so that resume is the same whether
3114 	 * just one class was locked or all classes were locked.
3115 	 */
3116 	if ((suspend1_flag) || (suspendall_flag)) {
3117 		nd = sd->sd_nodelist;
3118 		while (nd) {
3119 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3120 				nd = nd->nd_next;
3121 				continue;
3122 			}
3123 			if (clnt_mdcommdctl(nd->nd_nodename, COMMDCTL_RESUME,
3124 				sp, MD_MSG_CLASS0, MD_MSCF_NO_FLAGS, &xep)) {
3125 				/*
3126 				 * We are here because we failed to resume
3127 				 * rpc.mdcommd.  However we potentially have
3128 				 * an error from the previous call
3129 				 * If the previous call did fail,  we capture
3130 				 * that error and generate a perror with
3131 				 * the string, "Unable to resume...".
3132 				 * Setting rval to -1 ensures that in the
3133 				 * next iteration of the loop, ep is not
3134 				 * clobbered.
3135 				 */
3136 				if (rval == 0)
3137 					(void) mdstealerror(ep, &xep);
3138 				else
3139 					mdclrerror(&xep);
3140 				rval = -1;
3141 				mde_perror(ep, dgettext(TEXT_DOMAIN,
3142 				    "Unable to resume rpc.mdcommd."));
3143 			}
3144 			nd = nd->nd_next;
3145 		}
3146 		meta_ping_mnset(sp->setno);
3147 	}
3148 
3149 	/*
3150 	 * Unlock set.  This flushes the caches on the servers.
3151 	 */
3152 	cl_sk = cl_get_setkey(sp->setno, sp->setname);
3153 	nd = sd->sd_nodelist;
3154 	while (nd) {
3155 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3156 			nd = nd->nd_next;
3157 			continue;
3158 		}
3159 		if (clnt_unlock_set(nd->nd_nodename, cl_sk, &xep)) {
3160 			if (rval == 0)
3161 				(void) mdstealerror(ep, &xep);
3162 			else
3163 				mdclrerror(&xep);
3164 			rval = -1;
3165 		}
3166 		nd = nd->nd_next;
3167 	}
3168 
3169 	/*
3170 	 * call metaflushsetnames to reset local cache for master and
3171 	 * node information.
3172 	 */
3173 	metaflushsetname(sp);
3174 
3175 	/* release signals back to what they were on entry */
3176 	if (procsigs(FALSE, &oldsigs, &xep) < 0)
3177 		mdclrerror(&xep);
3178 
3179 	return (rval);
3180 
3181 }
3182 
3183 /*
3184  * Update nodelist with cluster member information.
3185  * A node not in the member list will be marked
3186  * as not ALIVE and not OWN.
3187  * A node in the member list will be marked ALIVE, but
3188  * the OWN bit will not be changed.
3189  *
3190  * If mynode isn't in the membership list, fail causing
3191  * another reconfig cycle to be started since a non-member
3192  * node shouldn't be taking part in the reconfig cycle.
3193  *
3194  * Return values:
3195  *	0 - No problem.
3196  *	1 - Any failure including RPC failure to my node.
3197  */
3198 int
3199 meta_reconfig_update_nodelist(
3200 	mdsetname_t			*sp,
3201 	mndiskset_membershiplist_t	*nl,
3202 	md_set_desc			*sd,
3203 	md_error_t			*ep
3204 )
3205 {
3206 	mndiskset_membershiplist_t	*nl2;
3207 	md_mnnode_desc			*nd;
3208 	md_error_t			xep = mdnullerror;
3209 	int				rval = 0;
3210 
3211 	/*
3212 	 * Walk through nodelist, checking to see if each
3213 	 * node is in the member list.
3214 	 * If node is not a member, reset ALIVE and OWN node flag.
3215 	 * If node is a member, set ALIVE.
3216 	 * If mynode's OWN flag gets reset, then halt the diskset on this node.
3217 	 */
3218 	nd = sd->sd_nodelist;
3219 	while (nd) {
3220 		nl2 = nl;
3221 		while (nl2) {
3222 			/* If node is in member list, set ALIVE */
3223 			if (nl2->msl_node_id == nd->nd_nodeid) {
3224 				nd->nd_flags |= MD_MN_NODE_ALIVE;
3225 				break;
3226 			} else {
3227 				nl2 = nl2->next;
3228 			}
3229 			/* node is not in member list, mark !ALIVE and !OWN */
3230 			if (nl2 == NULL) {
3231 				/* If node is mynode, then halt set if needed */
3232 				if (strcmp(mynode(), nd->nd_nodename) == 0) {
3233 					/*
3234 					 * This shouldn't happen, but just
3235 					 * in case...  Any node not in the
3236 					 * membership list should be dead and
3237 					 * not running reconfig step1.
3238 					 */
3239 					if (nd->nd_flags & MD_MN_NODE_OWN) {
3240 						if (halt_set(sp, &xep)) {
3241 							mde_perror(&xep, "");
3242 							mdclrerror(&xep);
3243 						}
3244 					}
3245 					/*
3246 					 * Return failure since this node
3247 					 * (mynode) is not in the membership
3248 					 * list, but process the rest of the
3249 					 * nodelist first so that rpc.metad
3250 					 * can be updated with the latest
3251 					 * membership information.
3252 					 */
3253 					(void) mddserror(ep,
3254 					    MDE_DS_NOTINMEMBERLIST,
3255 					    sp->setno, nd->nd_nodename, NULL,
3256 					    sp->setname);
3257 					rval = 1;
3258 				}
3259 				nd->nd_flags &= ~MD_MN_NODE_ALIVE;
3260 				nd->nd_flags &= ~MD_MN_NODE_OWN;
3261 			}
3262 		}
3263 		nd = nd->nd_next;
3264 	}
3265 
3266 	/* Send this information to rpc.metad */
3267 	if (clnt_upd_nr_flags(mynode(), sp, sd->sd_nodelist,
3268 	    MD_NR_SET,  MNSET_IN_RECONFIG, &xep)) {
3269 		/* Return failure if can't send node flags to rpc.metad */
3270 		if (rval == 0) {
3271 			(void) mdstealerror(ep, &xep);
3272 			rval = 1;
3273 		}
3274 	}
3275 	return (rval);
3276 }
3277 
3278 /*
3279  * Choose master determines the master for a diskset.
3280  * Each node determines the master on its own and
3281  * adds this information to its local rpc.metad nodelist
3282  * and also sends it to the kernel.
3283  *
3284  * Nodelist in set descriptor (sd) is sorted in
3285  * monotonically increasing sequence of nodeid.
3286  *
3287  * Return values:
3288  *	0 - No problem.
3289  *	205 - There was an RPC problem to another node.
3290  *	-1 - There was an error.  This could be an RPC error to my node.
3291  *		This is a catastrophic failure causing node to panic.
3292  */
3293 int
3294 meta_reconfig_choose_master_for_set(
3295 	mdsetname_t	*sp,
3296 	md_set_desc	*sd,
3297 	md_error_t	*ep
3298 )
3299 {
3300 	int			is_owner;
3301 	md_mnset_record		*mnsr = NULL;
3302 	int			lowest_alive_nodeid = 0;
3303 	uint_t			master_nodeid;
3304 	md_mnnode_desc		*nd, *nd2;
3305 	md_mnnode_record	*nr;
3306 	md_drive_desc		*dd;
3307 	md_setkey_t		*cl_sk;
3308 	int			rval = 0;
3309 	md_error_t		xep = mdnullerror;
3310 	mddb_setflags_config_t	sf;
3311 
3312 	/*
3313 	 * Is current node joined to diskset?
3314 	 * Don't trust flags, really check to see if mddb is snarfed.
3315 	 */
3316 	if (s_ownset(sp->setno, ep) == MD_SETOWNER_YES) {
3317 		/*
3318 		 * If a node is joined to the diskset, this node checks
3319 		 * to see if the current master of the diskset is valid and
3320 		 * is still in the membership list (ALIVE) and is
3321 		 * still joined (OWN).  Need to verify if master is
3322 		 * really joined - don't trust the flags.  (Can trust
3323 		 * ALIVE since set during earlier part of reconfig cycle.)
3324 		 * If the current master is valid, still in the membership
3325 		 * list and joined, then master is not changed on this node.
3326 		 * Just return.
3327 		 *
3328 		 * Verify that nodeid is valid before accessing masternode.
3329 		 */
3330 		if ((sd->sd_mn_master_nodeid != MD_MN_INVALID_NID) &&
3331 		    (sd->sd_mn_masternode->nd_flags & MD_MN_NODE_ALIVE)) {
3332 			if (clnt_ownset(sd->sd_mn_master_nodenm, sp,
3333 			    &is_owner, ep) == -1) {
3334 				/* If RPC failure to another node return 205 */
3335 				if ((mdanyrpcerror(ep)) &&
3336 				    (sd->sd_mn_mynode->nd_nodeid !=
3337 				    sd->sd_mn_master_nodeid)) {
3338 					return (205);
3339 				} else {
3340 					/* Any other failure */
3341 					return (-1);
3342 				}
3343 			} else {
3344 				if (is_owner == TRUE) {
3345 
3346 					meta_mc_log(MC_LOG5, dgettext(
3347 					    TEXT_DOMAIN, "Set %s previous "
3348 					    "master chosen %s (%d): %s"),
3349 					    sp->setname,
3350 					    sd->sd_mn_master_nodenm,
3351 					    sd->sd_mn_master_nodeid,
3352 					    meta_print_hrtime(gethrtime() -
3353 					    start_time));
3354 
3355 					/* Previous master is ok - done */
3356 					return (0);
3357 				}
3358 			}
3359 		}
3360 
3361 		/*
3362 		 * If current master is no longer in the membership list or
3363 		 * is no longer joined, then this node uses the following
3364 		 * algorithm:
3365 		 * - node calls RPC routine clnt_ownset to get latest
3366 		 *	information on which nodes are owners of diskset.
3367 		 * 	clnt_ownset checks on each node to see if its kernel
3368 		 *	has that diskset snarfed.
3369 		 */
3370 		nd = sd->sd_nodelist;
3371 		while (nd) {
3372 			/* Don't consider node that isn't in member list */
3373 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3374 				nd = nd->nd_next;
3375 				continue;
3376 			}
3377 
3378 			if (clnt_ownset(nd->nd_nodename, sp,
3379 			    &is_owner, ep) == -1) {
3380 				/* If RPC failure to another node return 205 */
3381 				if ((mdanyrpcerror(ep)) &&
3382 				    (sd->sd_mn_mynode->nd_nodeid !=
3383 				    nd->nd_nodeid)) {
3384 					return (205);
3385 				} else {
3386 					/* Any other failure */
3387 					return (-1);
3388 				}
3389 			}
3390 
3391 			/*
3392 			 * Set owner flag for each node based on whether
3393 			 * that node really has a diskset mddb snarfed in
3394 			 * or not.
3395 			 */
3396 			if (is_owner == TRUE)
3397 				nd->nd_flags |= MD_MN_NODE_OWN;
3398 			else
3399 				nd->nd_flags &= ~MD_MN_NODE_OWN;
3400 
3401 			nd = nd->nd_next;
3402 		}
3403 
3404 		/*
3405 		 * - node walks through nodelist looking for nodes that are
3406 		 *	owners of the diskset that are in the membership list.
3407 		 * - for each owner, node calls RPC routine clnt_getset to
3408 		 *	 see if that node has its node record set to OK.
3409 		 * - If so, master is chosen to be this owner node.
3410 		 */
3411 		nd = sd->sd_nodelist;
3412 		while (nd) {
3413 			/* Don't consider node that isn't in member list */
3414 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3415 				nd = nd->nd_next;
3416 				continue;
3417 			}
3418 
3419 			/* Don't consider a node that isn't an owner */
3420 			if (!(nd->nd_flags & MD_MN_NODE_OWN)) {
3421 				nd = nd->nd_next;
3422 				continue;
3423 			}
3424 
3425 			/* Does node has its own node record set to OK? */
3426 			if (clnt_mngetset(nd->nd_nodename, sp->setname,
3427 			    MD_SET_BAD, &mnsr, ep) == -1) {
3428 				/* If RPC failure to another node return 205 */
3429 				if ((mdanyrpcerror(ep)) &&
3430 				    (sd->sd_mn_mynode->nd_nodeid !=
3431 				    nd->nd_nodeid)) {
3432 					return (205);
3433 				} else {
3434 					/* Any other failure */
3435 					return (-1);
3436 				}
3437 			}
3438 			nr = mnsr->sr_nodechain;
3439 			while (nr) {
3440 				if (nd->nd_nodeid == nr->nr_nodeid) {
3441 					if (nr->nr_flags & MD_MN_NODE_OK) {
3442 						/* Found a master */
3443 						free_sr(
3444 						    (md_set_record *)mnsr);
3445 						goto found_master;
3446 					}
3447 				}
3448 				nr = nr->nr_next;
3449 			}
3450 			free_sr((md_set_record *)mnsr);
3451 			nd = nd->nd_next;
3452 		}
3453 
3454 		/*
3455 		 * - If no owner node has its own node record on its own node
3456 		 *	set to OK, then this node checks all of the non-owner
3457 		 * 	nodes that are in the membership list.
3458 		 * - for each non-owner, node calls RPC routine clnt_getset to
3459 		 *	 see if that node has its node record set to OK.
3460 		 * - If set doesn't exist, don't choose node for master.
3461 		 * - If so, master is chosen to be this non-owner node.
3462 		 *
3463 		 */
3464 		nd = sd->sd_nodelist;
3465 		while (nd) {
3466 			/* Don't consider node that isn't in member list */
3467 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3468 				nd = nd->nd_next;
3469 				continue;
3470 			}
3471 
3472 			/* Only checking non-owner nodes this time around */
3473 			if (nd->nd_flags & MD_MN_NODE_OWN) {
3474 				nd = nd->nd_next;
3475 				continue;
3476 			}
3477 
3478 			/* Does node has its own node record set to OK? */
3479 			if (clnt_mngetset(nd->nd_nodename, sp->setname,
3480 			    MD_SET_BAD, &mnsr, ep) == -1) {
3481 				/*
3482 				 * If set doesn't exist on non-owner node,
3483 				 * don't consider this node for master.
3484 				 */
3485 				if (mdiserror(ep, MDE_NO_SET)) {
3486 					nd = nd->nd_next;
3487 					continue;
3488 				} else if ((mdanyrpcerror(ep)) &&
3489 				    (sd->sd_mn_mynode->nd_nodeid !=
3490 				    nd->nd_nodeid)) {
3491 					/* RPC failure to another node */
3492 					return (205);
3493 				} else {
3494 					/* Any other failure */
3495 					return (-1);
3496 				}
3497 			}
3498 			nr = mnsr->sr_nodechain;
3499 			while (nr) {
3500 				if (nd->nd_nodeid == nr->nr_nodeid) {
3501 					if (nr->nr_flags & MD_MN_NODE_OK) {
3502 						/* Found a master */
3503 						free_sr(
3504 						    (md_set_record *)mnsr);
3505 						goto found_master;
3506 					}
3507 				}
3508 				nr = nr->nr_next;
3509 			}
3510 			free_sr((md_set_record *)mnsr);
3511 			nd = nd->nd_next;
3512 		}
3513 
3514 		/*
3515 		 * - If no node can be found that has its own node record on
3516 		 *	its node to be set to OK, then all alive nodes
3517 		 * 	were in the process of being added to or deleted
3518 		 *	from set.  Each alive node will remove all
3519 		 *	information pertaining to this set from its node.
3520 		 *
3521 		 * If all nodes in set are ALIVE, then call sdssc end routines
3522 		 * since set was truly being initially created or destroyed.
3523 		 */
3524 		goto delete_set;
3525 	} else {
3526 
3527 		/*
3528 		 * If node is not joined to diskset, then this
3529 		 * node uses the following algorithm:
3530 		 * - If unjoined node doesn't have a node record for itself,
3531 		 *	just delete the diskset since diskset was in the
3532 		 *	process of being created.
3533 		 * - node needs to find master of diskset before
3534 		 *	reconfig cycle, if a master existed.
3535 		 * - node calls RPC routine clnt_ownset to get latest
3536 		 * 	information on which nodes are owners of diskset.
3537 		 *	clnt_ownset checks on each node to see if its
3538 		 *	kernel has that diskset snarfed.
3539 		 */
3540 
3541 		/*
3542 		 * Is my node in the set description?
3543 		 * If not, delete the set from this node.
3544 		 * sr2setdesc sets sd_mn_mynode pointer to the node
3545 		 * descriptor for this node if there was a node
3546 		 * record for this node.
3547 		 *
3548 		 */
3549 		if (sd->sd_mn_mynode == NULL) {
3550 			goto delete_set;
3551 		}
3552 
3553 		nd = sd->sd_nodelist;
3554 		while (nd) {
3555 			/* Don't consider node that isn't in member list */
3556 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3557 				nd = nd->nd_next;
3558 				continue;
3559 			}
3560 
3561 			if (clnt_ownset(nd->nd_nodename, sp,
3562 			    &is_owner, ep) == -1) {
3563 				/* If RPC failure to another node return 205 */
3564 				if ((mdanyrpcerror(ep)) &&
3565 				    (sd->sd_mn_mynode->nd_nodeid !=
3566 				    nd->nd_nodeid)) {
3567 					return (205);
3568 				} else {
3569 					/* Any other failure */
3570 					return (-1);
3571 				}
3572 			}
3573 
3574 			/*
3575 			 * Set owner flag for each node based on whether
3576 			 * that node really has a diskset mddb snarfed in
3577 			 * or not.
3578 			 */
3579 			if (is_owner == TRUE)
3580 				nd->nd_flags |= MD_MN_NODE_OWN;
3581 			else
3582 				nd->nd_flags &= ~MD_MN_NODE_OWN;
3583 
3584 			nd = nd->nd_next;
3585 		}
3586 
3587 		/*
3588 		 * - node walks through nodelist looking for nodes that
3589 		 *	are owners of the diskset that are in
3590 		 *	the membership list.
3591 		 * - for each owner, node calls RPC routine clnt_getset to
3592 		 *	see if that node has a master set and to get the
3593 		 *	diskset description.
3594 		 * - If the owner node has a set description that doesn't
3595 		 *	include the non-joined node in the nodelist, this node
3596 		 *	removes its set description of that diskset
3597 		 *	(i.e. removes the set from its local mddbs).  This is
3598 		 *	handling the case of when a node was removed from a
3599 		 *	diskset while it was not in the cluster membership
3600 		 *	list.
3601 		 * - If that node has a master set and the master is in the
3602 		 *	membership list and is an owner, then either this was
3603 		 *	the master from before the reconfig cycle or this
3604 		 *	node has already chosen a new master - either way,
3605 		 *	the master value is valid as long as it is in the
3606 		 *	membership list and is an owner
3607 		 * - master is chosen to be owner node's master
3608 		 */
3609 		nd = sd->sd_nodelist;
3610 		while (nd) {
3611 			/* Don't consider node that isn't in member list */
3612 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3613 				nd = nd->nd_next;
3614 				continue;
3615 			}
3616 
3617 			/* Don't consider a node that isn't an owner */
3618 			if (!(nd->nd_flags & MD_MN_NODE_OWN)) {
3619 				nd = nd->nd_next;
3620 				continue;
3621 			}
3622 
3623 			/* Get owner node's set record */
3624 			if (clnt_mngetset(nd->nd_nodename, sp->setname,
3625 			    MD_SET_BAD, &mnsr, ep) == -1) {
3626 				/* If RPC failure to another node return 205 */
3627 				if ((mdanyrpcerror(ep)) &&
3628 				    (sd->sd_mn_mynode->nd_nodeid !=
3629 				    nd->nd_nodeid)) {
3630 					return (205);
3631 				} else {
3632 					/* Any other failure */
3633 					return (-1);
3634 				}
3635 			}
3636 
3637 			/* Is this node in the owner node's set record */
3638 			nr = mnsr->sr_nodechain;
3639 			while (nr) {
3640 				if (sd->sd_mn_mynode->nd_nodeid ==
3641 				    nr->nr_nodeid) {
3642 					break;
3643 				}
3644 				nr = nr->nr_next;
3645 			}
3646 			if (nr == NULL) {
3647 				/* my node not found - delete set */
3648 				free_sr((md_set_record *)mnsr);
3649 				goto delete_set;
3650 			}
3651 
3652 			/* Is owner's node's master valid? */
3653 			master_nodeid = mnsr->sr_master_nodeid;
3654 			free_sr((md_set_record *)mnsr);
3655 			if (master_nodeid == MD_MN_INVALID_NID) {
3656 				nd = nd->nd_next;
3657 				continue;
3658 			}
3659 
3660 			nd2 = sd->sd_nodelist;
3661 			while (nd2) {
3662 				if ((nd2->nd_nodeid == master_nodeid) &&
3663 				    (nd2->nd_flags & MD_MN_NODE_ALIVE) &&
3664 				    (nd2->nd_flags & MD_MN_NODE_OWN)) {
3665 						nd = nd2;
3666 						goto found_master;
3667 				}
3668 				nd2 = nd2->nd_next;
3669 			}
3670 			nd = nd->nd_next;
3671 		}
3672 
3673 		/*
3674 		 * - If no owner node has a valid master, then follow
3675 		 * 	algorithm of when a node is joined to the diskset.
3676 		 * - node walks through nodelist looking for nodes that are
3677 		 *	owners of the diskset that are in the membership list.
3678 		 * - for each owner, node calls RPC routine clnt_getset to
3679 		 *	 see if that node has its node record set to OK.
3680 		 * - If so, master is chosen to be this owner node.
3681 		 */
3682 		nd = sd->sd_nodelist;
3683 		while (nd) {
3684 			/* Don't consider node that isn't in member list */
3685 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3686 				nd = nd->nd_next;
3687 				continue;
3688 			}
3689 
3690 			/* Don't consider a node that isn't an owner */
3691 			if (!(nd->nd_flags & MD_MN_NODE_OWN)) {
3692 				nd = nd->nd_next;
3693 				continue;
3694 			}
3695 
3696 			/* Does node has its own node record set to OK? */
3697 			if (clnt_mngetset(nd->nd_nodename, sp->setname,
3698 			    MD_SET_BAD, &mnsr, ep) == -1) {
3699 				/* If RPC failure to another node return 205 */
3700 				if ((mdanyrpcerror(ep)) &&
3701 				    (sd->sd_mn_mynode->nd_nodeid !=
3702 				    nd->nd_nodeid)) {
3703 					return (205);
3704 				} else {
3705 					/* Any other failure */
3706 					return (-1);
3707 				}
3708 			}
3709 			nr = mnsr->sr_nodechain;
3710 			while (nr) {
3711 				if (nd->nd_nodeid == nr->nr_nodeid) {
3712 					if (nr->nr_flags & MD_MN_NODE_OK) {
3713 						/* Found a master */
3714 						free_sr(
3715 						    (md_set_record *)mnsr);
3716 						goto found_master;
3717 					}
3718 				}
3719 				nr = nr->nr_next;
3720 			}
3721 			free_sr((md_set_record *)mnsr);
3722 			nd = nd->nd_next;
3723 		}
3724 
3725 		/*
3726 		 * - If no owner node has its own node record on its own node
3727 		 *	set to OK, then this node checks all of the non-owner
3728 		 *	nodes that are in the membership list.
3729 		 * - for each non-owner, node calls RPC routine clnt_getset to
3730 		 *	see if that node has its node record set to OK.
3731 		 * - If set doesn't exist, don't choose node for master.
3732 		 * - If this node doesn't exist in the nodelist on any of the
3733 		 *	non-owner nodes, this node removes its set description
3734 		 *	of that diskset (i.e. removes the set from its local
3735 		 *	mddbs). This is handling the case of when a node was
3736 		 *	removed from a diskset while it was not in the
3737 		 *	cluster membership list.
3738 		 * - If non-owner node has its node record set to OK and if
3739 		 *	this node hasn't removed this diskset (step directly
3740 		 *	before this one), then the master is chosen to be this
3741 		 *	non-owner node.
3742 		 */
3743 		nd = sd->sd_nodelist;
3744 		while (nd) {
3745 			/* Don't consider node that isn't in member list */
3746 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3747 				nd->nd_flags |= MD_MN_NODE_DEL;
3748 				nd = nd->nd_next;
3749 				continue;
3750 			}
3751 
3752 			/* Don't consider owner nodes since none are OK */
3753 			if (nd->nd_flags & MD_MN_NODE_OWN) {
3754 				nd->nd_flags |= MD_MN_NODE_DEL;
3755 				nd = nd->nd_next;
3756 				continue;
3757 			}
3758 
3759 			/*
3760 			 * Don't need to get nodelist from my node since
3761 			 * this is where sd_nodelist was obtained.
3762 			 */
3763 			if (sd->sd_mn_mynode->nd_nodeid == nd->nd_nodeid) {
3764 				nd = nd->nd_next;
3765 				continue;
3766 			}
3767 
3768 			/*
3769 			 * If node has already been decided against for
3770 			 * master, then skip it.
3771 			 */
3772 			if (nd->nd_flags & MD_MN_NODE_DEL) {
3773 				nd = nd->nd_next;
3774 				continue;
3775 			}
3776 
3777 			/*
3778 			 * Does node in my nodelist have its own node
3779 			 * record marked OK on its node?  And does node
3780 			 * in my nodelist exist on all other nodes?
3781 			 * Don't want to choose a node for master unless
3782 			 * that node is marked OK on its own node and that
3783 			 * node exists on all other alive nodes.
3784 			 *
3785 			 * This is guarding against the case when several
3786 			 * nodes are down and one of the downed nodes is
3787 			 * deleted from the diskset.  When the down nodes
3788 			 * are rebooted into the cluster, you don't want
3789 			 * any node to pick the deleted node as the master.
3790 			 */
3791 			if (clnt_mngetset(nd->nd_nodename, sp->setname,
3792 			    MD_SET_BAD, &mnsr, ep) == -1) {
3793 				/*
3794 				 * If set doesn't exist on non-owner node,
3795 				 * don't consider this node for master.
3796 				 */
3797 				if (mdiserror(ep, MDE_NO_SET)) {
3798 					nd->nd_flags |= MD_MN_NODE_DEL;
3799 					nd = nd->nd_next;
3800 					continue;
3801 				} else if (mdanyrpcerror(ep)) {
3802 					/* RPC failure to another node */
3803 					return (205);
3804 				} else {
3805 					/* Any other failure */
3806 					return (-1);
3807 				}
3808 			}
3809 			/*
3810 			 * Is my node in the nodelist gotten from the other
3811 			 * node?  If not, then remove the set from my node
3812 			 * since set was deleted from my node while my node
3813 			 * was out of the cluster.
3814 			 */
3815 			nr = mnsr->sr_nodechain;
3816 			while (nr) {
3817 				if (sd->sd_mn_mynode->nd_nodeid ==
3818 				    nr->nr_nodeid) {
3819 					break;
3820 				}
3821 				nr = nr->nr_next;
3822 			}
3823 			if (nr == NULL) {
3824 				/* my node not found - delete set */
3825 				free_sr((md_set_record *)mnsr);
3826 				goto delete_set;
3827 			}
3828 
3829 			/* Is node being checked marked OK on its own node? */
3830 			nr = mnsr->sr_nodechain;
3831 			while (nr) {
3832 				if (nd->nd_nodeid == nr->nr_nodeid) {
3833 					if (!(nr->nr_flags & MD_MN_NODE_OK)) {
3834 						nd->nd_flags |= MD_MN_NODE_DEL;
3835 					}
3836 					break;
3837 				}
3838 				nr = nr->nr_next;
3839 			}
3840 			/*
3841 			 * If node being checked doesn't exist on its
3842 			 * own node - don't choose it as master.
3843 			 */
3844 			if (nr == NULL) {
3845 				nd->nd_flags |= MD_MN_NODE_DEL;
3846 			}
3847 
3848 			/*
3849 			 * Check every node in my node's nodelist against
3850 			 * the nodelist gotten from the other node.
3851 			 * If a node in my node's nodelist is not found in the
3852 			 * other node's nodelist, then set the DEL flag.
3853 			 */
3854 			nd2 = sd->sd_nodelist;
3855 			while (nd2) {
3856 				nr = mnsr->sr_nodechain;
3857 				while (nr) {
3858 					if (nd2->nd_nodeid == nr->nr_nodeid) {
3859 						break;
3860 					}
3861 					nr = nr->nr_next;
3862 				}
3863 				/* nd2 not found in other node's nodelist */
3864 				if (nr == NULL) {
3865 					nd2->nd_flags |= MD_MN_NODE_DEL;
3866 				}
3867 				nd2 = nd2->nd_next;
3868 			}
3869 
3870 			free_sr((md_set_record *)mnsr);
3871 			nd = nd->nd_next;
3872 		}
3873 
3874 		/*
3875 		 * Rescan list look for node that has not been marked DEL.
3876 		 * First node found is the master.
3877 		 */
3878 		nd = sd->sd_nodelist;
3879 		while (nd) {
3880 			if (!(nd->nd_flags & MD_MN_NODE_DEL)) {
3881 				break;
3882 			}
3883 			nd = nd->nd_next;
3884 			continue;
3885 		}
3886 		if (nd) {
3887 			/* Found a master */
3888 			goto found_master;
3889 		}
3890 
3891 		/*
3892 		 * - If no node can be found that has its own node record on
3893 		 *	its node to be set to OK, then all alive nodes
3894 		 * 	were in the process of being added to or deleted
3895 		 *	from set.  Each alive node will remove all
3896 		 *	information pertaining to this set from its node.
3897 		 *
3898 		 * If all nodes in set are ALIVE, then call sdssc end routines
3899 		 * since set was truly being initially created or destroyed.
3900 		 */
3901 		goto delete_set;
3902 	}
3903 
3904 found_master:
3905 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
3906 	    "Set %s master chosen %s (%d): %s"),
3907 	    sp->setname, nd->nd_nodename, nd->nd_nodeid,
3908 	    meta_print_hrtime(gethrtime() - start_time));
3909 
3910 	if (clnt_lock_set(mynode(), sp, ep) == -1) {
3911 		return (-1);
3912 	}
3913 
3914 	cl_sk = cl_get_setkey(sp->setno, sp->setname);
3915 
3916 	if (clnt_mnsetmaster(mynode(), sp,
3917 	    nd->nd_nodename, nd->nd_nodeid, ep)) {
3918 		rval = -1;
3919 	} else if (sd->sd_mn_mynode->nd_nodeid == nd->nd_nodeid) {
3920 		/* If this node is new master, set flag in this node's kernel */
3921 		(void) memset(&sf, 0, sizeof (sf));
3922 		sf.sf_setno = sp->setno;
3923 		sf.sf_setflags = MD_SET_MN_NEWMAS_RC;
3924 		/* Use magic to help protect ioctl against attack. */
3925 		sf.sf_magic = MDDB_SETFLAGS_MAGIC;
3926 		sf.sf_flags = MDDB_NM_SET;
3927 
3928 		meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
3929 		    "Setting new master flag for set %s: %s"),
3930 		    sp->setname, meta_print_hrtime(gethrtime() - start_time));
3931 
3932 		/*
3933 		 * Fail reconfig cycle if ioctl fails since it is critical
3934 		 * to set new master flag.
3935 		 */
3936 		if (metaioctl(MD_MN_SET_SETFLAGS, &sf, &sf.sf_mde,
3937 		    NULL) != NULL) {
3938 			(void) mdstealerror(ep, &sf.sf_mde);
3939 			rval = -1;
3940 		}
3941 	}
3942 
3943 	if (clnt_unlock_set(mynode(), cl_sk, &xep) == -1) {
3944 		if (rval == 0) {
3945 			(void) mdstealerror(ep, &xep);
3946 			rval = -1;
3947 		}
3948 	}
3949 
3950 	cl_set_setkey(NULL);
3951 
3952 	metaflushsetname(sp);
3953 
3954 	return (rval);
3955 
3956 delete_set:
3957 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
3958 	    "Master not chosen, deleting set %s: %s"),
3959 	    sp->setname, meta_print_hrtime(gethrtime() - start_time));
3960 
3961 	/*
3962 	 * Remove all set information from this node:
3963 	 *	- node records for this set
3964 	 *	- drive records for this set
3965 	 *	- set record for this set
3966 	 * (Only do this on this node since each node
3967 	 * will do it for its own local mddb.)
3968 	 *
3969 	 * If all nodes in set are ALIVE, then
3970 	 * the lowest numbered ALIVE nodeid in set
3971 	 * (irregardless of whether an owner node or not) will
3972 	 * call the DCS service to cleanup for create/delete of set.
3973 	 *   sdssc_create_end(cleanup) if set was being created or
3974 	 *   sdssc_delete_end(cleanup) if set was being deleted.
3975 	 * A node record with flag ADD denotes a set being
3976 	 * created.  A node record with flag DEL denotes a
3977 	 * set being deleted.
3978 	 */
3979 	nd = sd->sd_nodelist;
3980 	while (nd) {
3981 		/* Found a node that isn't alive */
3982 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE))
3983 			break;
3984 
3985 		/* Is my node the lowest numbered ALIVE node? */
3986 		if (nd->nd_nodeid < sd->sd_mn_mynode->nd_nodeid) {
3987 			break;
3988 		}
3989 		nd = nd->nd_next;
3990 	}
3991 	if (nd == NULL) {
3992 		/* All nodes ALIVE and this is the lowest nodeid */
3993 		lowest_alive_nodeid = 1;
3994 	}
3995 
3996 	if (clnt_lock_set(mynode(), sp, ep) == -1) {
3997 		return (-1);
3998 	}
3999 
4000 
4001 	/*
4002 	 * If this node had been joined, withdraw and reset master.
4003 	 *
4004 	 * This could happen if a node was being added to or removed
4005 	 * from a diskset and the node doing the add/delete operation and
4006 	 * all other nodes in the diskset have left the cluster.
4007 	 */
4008 	if (sd->sd_mn_mynode) {
4009 		nd = sd->sd_mn_mynode;
4010 		if (nd->nd_flags & MD_MN_NODE_OWN) {
4011 			if (clnt_withdrawset(mynode(), sp, ep)) {
4012 				rval = -1;
4013 				goto out;
4014 			}
4015 			if (clnt_mnsetmaster(mynode(), sp, "",
4016 			    MD_MN_INVALID_NID, ep)) {
4017 				rval = -1;
4018 				goto out;
4019 			}
4020 		}
4021 	}
4022 
4023 	/*
4024 	 * Remove side records for this node (side) from local mddb
4025 	 * (clnt_deldrvs does this) if there are drives in the set.
4026 	 *
4027 	 * Don't need to mark this node as DEL since already marked as
4028 	 * ADD or DEL (or this node would have been chosen as master).
4029 	 * Don't need to mark other node records, drive records or
4030 	 * set records as DEL.  If a panic occurs during clnt_delset,
4031 	 * these records will be deleted the next time this node
4032 	 * becomes a member and goes through the reconfig cycle.
4033 	 */
4034 	/* Get the drive descriptors for this set */
4035 	if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
4036 	    ep)) == NULL) {
4037 		if (! mdisok(ep)) {
4038 			/*
4039 			 * Ignore and clear out any failures from
4040 			 * metaget_drivedesc since a panic could have
4041 			 * occurred when a node was partially added to a set.
4042 			 */
4043 			mdclrerror(ep);
4044 		}
4045 	} else {
4046 		if (clnt_deldrvs(mynode(), sp, dd, ep)) {
4047 			rval = -1;
4048 			goto out;
4049 		}
4050 	}
4051 
4052 	/*
4053 	 * Now, delete the set - this removes the node, drive
4054 	 * and set records from the local mddb.
4055 	 */
4056 	if (clnt_delset(mynode(), sp, ep)) {
4057 		rval = -1;
4058 		goto out;
4059 	}
4060 
4061 out:
4062 	cl_sk = cl_get_setkey(sp->setno, sp->setname);
4063 
4064 	/*
4065 	 * Ignore errors from unlock of set since set is no longer
4066 	 * known (if clnt_delset worked).
4067 	 */
4068 	if (clnt_unlock_set(mynode(), cl_sk, &xep) == -1) {
4069 		mdclrerror(&xep);
4070 	}
4071 
4072 	cl_set_setkey(NULL);
4073 
4074 	metaflushsetname(sp);
4075 
4076 	/*
4077 	 * If this node is the lowest numbered nodeid then
4078 	 * call sdssc_create/delete_end depending on whether
4079 	 * this node is marked as ADD or DEL in the node record.
4080 	 */
4081 	if (lowest_alive_nodeid) {
4082 		if (nd->nd_flags & MD_MN_NODE_ADD)
4083 			sdssc_create_end(sp->setname, SDSSC_CLEANUP);
4084 		else if (nd->nd_flags & MD_MN_NODE_DEL)
4085 			sdssc_delete_end(sp->setname, SDSSC_CLEANUP);
4086 	}
4087 
4088 	/* Finished with this set -- return */
4089 	return (rval);
4090 }
4091 
4092 /*
4093  * Reconfig step to choose a new master for all MN disksets.
4094  * Return values:
4095  *	0 - Everything is great.
4096  *	1 - This node failed to reconfig.
4097  *	205 - Cause another reconfig due to a nodelist problem
4098  *		or RPC failure to another node
4099  */
4100 int
4101 meta_reconfig_choose_master(
4102 	md_error_t	*ep
4103 )
4104 {
4105 	set_t				max_sets, setno;
4106 	int				nodecnt;
4107 	mndiskset_membershiplist_t	*nl;
4108 	md_set_desc			*sd;
4109 	mdsetname_t			*sp;
4110 	int				rval = 0;
4111 	mddb_setflags_config_t		sf;
4112 	int				start_node_delayed = 0;
4113 
4114 	if ((max_sets = get_max_sets(ep)) == 0) {
4115 		mde_perror(ep, dgettext(TEXT_DOMAIN,
4116 		    "Unable to get number of sets"));
4117 		return (1);
4118 	}
4119 
4120 	/*
4121 	 * Get membershiplist from API routine.  If there's
4122 	 * an error, return a 205 to cause another reconfig.
4123 	 */
4124 	if (meta_read_nodelist(&nodecnt, &nl, ep) == -1) {
4125 		mde_perror(ep, "");
4126 		return (205);
4127 	}
4128 
4129 	for (setno = 1; setno < max_sets; setno++) {
4130 		if ((sp = metasetnosetname(setno, ep)) == NULL) {
4131 			if (mdiserror(ep, MDE_NO_SET)) {
4132 				/* No set for this setno - continue */
4133 				mdclrerror(ep);
4134 				continue;
4135 			} else {
4136 				/*
4137 				 * If encountered an RPC error from my node,
4138 				 * then immediately fail.
4139 				 */
4140 				if (mdanyrpcerror(ep)) {
4141 					mde_perror(ep, "");
4142 					return (1);
4143 				}
4144 				/* Can't get set information */
4145 				mde_perror(ep, dgettext(TEXT_DOMAIN,
4146 					"Unable to get information for "
4147 					"set number %d"), setno);
4148 				mdclrerror(ep);
4149 				continue;
4150 			}
4151 		}
4152 
4153 		/* If setname is there, set desc should exist. */
4154 		if ((sd = metaget_setdesc(sp, ep)) == NULL) {
4155 			/*
4156 			 * If encountered an RPC error from my node,
4157 			 * then immediately fail.
4158 			 */
4159 			if (mdanyrpcerror(ep)) {
4160 				mde_perror(ep, "");
4161 				return (1);
4162 			}
4163 			mde_perror(ep, dgettext(TEXT_DOMAIN,
4164 				"Unable to get set %s desc information"),
4165 				sp->setname);
4166 			mdclrerror(ep);
4167 			continue;
4168 		}
4169 
4170 		/* Only reconfig MN disksets */
4171 		if (!MD_MNSET_DESC(sd)) {
4172 			continue;
4173 		}
4174 
4175 		meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
4176 		    "Begin choose master for set %s: %s"),
4177 		    sp->setname, meta_print_hrtime(gethrtime() - start_time));
4178 
4179 		/* Update nodelist with member information. */
4180 		if (meta_reconfig_update_nodelist(sp, nl, sd, ep)) {
4181 			/*
4182 			 * If encountered an RPC error from my node,
4183 			 * then immediately fail.
4184 			 */
4185 			if (mdanyrpcerror(ep)) {
4186 				mde_perror(ep, "");
4187 				return (1);
4188 			}
4189 			mde_perror(ep, "");
4190 			mdclrerror(ep);
4191 			continue;
4192 		}
4193 
4194 		/*
4195 		 * If all nodes in a cluster are starting, then
4196 		 * all nodes will attempt to contact all other nodes
4197 		 * to determine a master node.  This can lead to a
4198 		 * problem where node 1 is trying to contact the rpc.metad
4199 		 * node 2 and node 2 is trying to contact the rpc.metad
4200 		 * on node 1 -- and this causes the rpc call to fail
4201 		 * on both nodes and causes a new reconfig cycle.
4202 		 *
4203 		 * In order to break this problem, a newly starting node
4204 		 * will delay a small amount of time (nodeid mod 4 seconds)
4205 		 * and will then run the code to choose a master for the
4206 		 * first set.  Delay will only be done once regardless of the
4207 		 * number of sets.
4208 		 */
4209 		if (start_node_delayed == 0) {
4210 			(void) memset(&sf, 0, sizeof (sf));
4211 			sf.sf_setno = sp->setno;
4212 			sf.sf_flags = MDDB_NM_GET;
4213 			/* Use magic to help protect ioctl against attack. */
4214 			sf.sf_magic = MDDB_SETFLAGS_MAGIC;
4215 			if ((metaioctl(MD_MN_GET_SETFLAGS, &sf,
4216 			    &sf.sf_mde, NULL) == 0) &&
4217 			    ((sf.sf_setflags & MD_SET_MN_START_RC) ==
4218 			    MD_SET_MN_START_RC)) {
4219 				(void) sleep(sd->sd_mn_mynode->nd_nodeid % 4);
4220 			}
4221 			start_node_delayed = 1;
4222 		}
4223 
4224 		/* Choose master for this set */
4225 		rval = meta_reconfig_choose_master_for_set(sp, sd, ep);
4226 		if (rval == -1) {
4227 			mde_perror(ep, "");
4228 			return (1);
4229 		} else if (rval == 205) {
4230 			mde_perror(ep, "");
4231 			return (205);
4232 		}
4233 
4234 		/* Send new nodelist to rpc.mdcommd */
4235 		(void) mdmn_reinit_set(sp->setno);
4236 
4237 		meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
4238 		    "Choose master for set %s completed: %s"),
4239 		    sp->setname, meta_print_hrtime(gethrtime() - start_time));
4240 	}
4241 
4242 	/*
4243 	 * Each node turns on I/Os for all MN disksets.
4244 	 * This is to recover from the situation where the master died
4245 	 * during a previous reconfig cycle when I/Os were suspended
4246 	 * for a MN diskset.
4247 	 * If a failure occurs return a 1 which will force this node to
4248 	 * panic.  Cannot leave node in the situation where I/Os are
4249 	 * not resumed.
4250 	 */
4251 	setno = 0; /* 0 means all MN sets */
4252 	if (metaioctl(MD_MN_RESUME_SET, &setno, ep, NULL)) {
4253 		mde_perror(ep, "");
4254 		return (1);
4255 	}
4256 
4257 	/* Free the nodelist */
4258 	if (nodecnt)
4259 		meta_free_nodelist(nl);
4260 
4261 	return (0);
4262 }
4263 
4264 /*
4265  * meta_mnsync_user_records will synchronize the diskset user records across
4266  * all nodes in the diskset.  The diskset user records are stored in
4267  * each node's local set mddb.
4268  *
4269  * This needs to be done even if there is no master change during the
4270  * reconfig cycle since this routine should clean up any mess left by
4271  * the untimely termination of a metaset or metadb command (due to a
4272  * node panic or to user intervention).
4273  *
4274  * Caller is the Master node.
4275  *
4276  * Returns	 0 - Success
4277  *		205 - Failure during RPC to another node
4278  *		-1 - Any other failure and ep is filled in.
4279  */
4280 int
4281 meta_mnsync_user_records(
4282 	mdsetname_t	*sp,
4283 	md_error_t	*ep
4284 )
4285 {
4286 	md_set_desc		*sd;
4287 	md_mnnode_desc		*master_nodelist, *nd, *nd2, *ndtail;
4288 	md_mnset_record		*mnsr;
4289 	md_mnsr_node_t		*master_mnsr_node = NULL, *mnsr_node = NULL;
4290 	md_mnnode_record	*nr;
4291 	md_drive_record		*dr;
4292 	int			dr_cnt, dd_cnt;
4293 	int			found_my_nr;
4294 	md_drive_desc		*dd, *dd_prev, *master_dd, *other_dd;
4295 	int			all_drives_ok;
4296 	int			rval = 0;
4297 	int			max_genid = 0;
4298 	int			num_alive_nodes, num_alive_nodes_del = 0;
4299 	int			set_locked = 0;
4300 	md_setkey_t		*cl_sk;
4301 	md_error_t		xep = mdnullerror;
4302 	char			*anode[1];
4303 	mddb_setflags_config_t	sf;
4304 
4305 	/*
4306 	 * Sync up node records first.
4307 	 * Construct a master nodelist using the nodelist from this
4308 	 * node's rpc.metad node records and then setting the state of each
4309 	 * node following these rules:
4310 	 *	- If a node record is marked OK on its node, mark it OK
4311 	 *		in the master nodelist (and later OK on all nodes)
4312 	 *		If a node record is also marked OWN on its node,
4313 	 *		mark it OWN in the master nodelist.
4314 	 *	- If a node record is not marked OK on its node, then mark
4315 	 *		it as DEL in the master list (later deleting it)
4316 	 *	- If node record doesn't exist on that node, then mark it DEL
4317 	 *		(later deleting it)
4318 	 *	- If set record doesn't exist on that node, mark node as DEL
4319 	 *	- If a node record doesn't exist on all nodes, then mark it DEL
4320 	 *	- If a node is not ALIVE, then
4321 	 *		- If that node marked DEL on any node - mark it DEL
4322 	 *			in master list but leave in nodelist
4323 	 *		- If that node is marked as ADD on any node, mark it
4324 	 *			ADD in the master list but leave in nodelist
4325 	 *		- When that node returns to the living, the DEL
4326 	 *			node record will be removed and the ADD node
4327 	 *			record may be removed if marked ADD on that
4328 	 *			node.
4329 	 * The key rule is to not remove a node from the nodelist until
4330 	 * that node record is removed from its own node.  Do not want to
4331 	 * remove a node's record from all other nodes and then have
4332 	 * that node have its own record marked OK so that a node will pick
4333 	 * a different master than the other nodes.
4334 	 *
4335 	 * Next,
4336 	 * If node is ALIVE and node record is marked DEL in master nodelist,
4337 	 * remove node from set.
4338 	 * If node is ALIVE and node record is marked OK in master nodelist,
4339 	 * mark it OK on all other nodes.
4340 	 * If node is not ALIVE and node record is marked DEL in master
4341 	 * nodelist, mark it DEL on all other nodes.
4342 	 * If node is not ALIVE and node record is marked ADD in master,
4343 	 * nodelist, mark it ADD on all other nodes.
4344 	 */
4345 	if ((sd = metaget_setdesc(sp, ep)) == NULL) {
4346 		return (-1);
4347 	}
4348 	master_nodelist = sd->sd_nodelist;
4349 
4350 	/*
4351 	 * Walk through nodelist creating a master nodelist.
4352 	 */
4353 	num_alive_nodes = 0;
4354 	nd = master_nodelist;
4355 	while (nd) {
4356 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
4357 			nd = nd->nd_next;
4358 			continue;
4359 		}
4360 		num_alive_nodes++;
4361 		if (clnt_mngetset(nd->nd_nodename, sp->setname,
4362 		    MD_SET_BAD, &mnsr, ep) == -1) {
4363 			if (mdiserror(ep, MDE_NO_SET)) {
4364 				/* set doesn't exist, mark node as DEL */
4365 				nd->nd_flags &= ~MD_MN_NODE_OK;
4366 				nd->nd_flags &= ~MD_MN_NODE_ADD;
4367 				nd->nd_flags |= MD_MN_NODE_DEL;
4368 				nd->nd_flags |= MD_MN_NODE_NOSET;
4369 				nd = nd->nd_next;
4370 				continue;
4371 			} else {
4372 				/* If RPC failure to another node return 205 */
4373 				if ((mdanyrpcerror(ep)) &&
4374 				    (sd->sd_mn_mynode->nd_nodeid !=
4375 				    nd->nd_nodeid)) {
4376 					rval = 205;
4377 				} else {
4378 					/* Any other failure */
4379 					rval = -1;
4380 				}
4381 				goto out;
4382 			}
4383 		}
4384 		/* Find biggest genid in records for this diskset */
4385 		if (mnsr->sr_genid > max_genid)
4386 			max_genid = mnsr->sr_genid;
4387 
4388 		dr = mnsr->sr_drivechain;
4389 		while (dr) {
4390 			/* Find biggest genid in records for this diskset */
4391 			if (dr->dr_genid > max_genid) {
4392 				max_genid = dr->dr_genid;
4393 			}
4394 			dr = dr->dr_next;
4395 		}
4396 
4397 		found_my_nr = 0;
4398 		nr = mnsr->sr_nodechain;
4399 		/* nr is the list of node recs from nd_nodename node */
4400 		while (nr) {
4401 			/* Find biggest genid in records for this diskset */
4402 			if (nr->nr_genid > max_genid)
4403 				max_genid = nr->nr_genid;
4404 			nd2 = master_nodelist;
4405 			ndtail = NULL;
4406 			/* For each node record, is it in master list? */
4407 			while (nd2) {
4408 				if (nd2->nd_nodeid == nr->nr_nodeid)
4409 					break;
4410 				if (nd2->nd_next == NULL)
4411 					ndtail = nd2;
4412 				nd2 = nd2->nd_next;
4413 			}
4414 			/*
4415 			 * Found node record not in master list -- add it
4416 			 * to list marking it as DEL since node record
4417 			 * should exist on all nodes unless a panic occurred
4418 			 * during addition or deletion of host to diskset.
4419 			 */
4420 			if (nd2 == NULL) {
4421 				nd2 = Zalloc(sizeof (*nd2));
4422 				(void) strcpy(nd2->nd_nodename,
4423 				    nr->nr_nodename);
4424 				nd2->nd_flags = nr->nr_flags;
4425 				nd2->nd_flags |= MD_MN_NODE_DEL;
4426 				nd2->nd_nodeid = nr->nr_nodeid;
4427 				nd2->nd_next = NULL;
4428 				ndtail->nd_next = nd2;
4429 				nd2 = NULL;
4430 				nr = nr->nr_next;
4431 				continue;
4432 			}
4433 			/*
4434 			 * Is this the node record for the node that
4435 			 * we requested the set desc from?
4436 			 * If so, check if node has its own node record
4437 			 * marked OK. If marked OK, check for the OWN bit.
4438 			 */
4439 			if (nr->nr_nodeid == nd->nd_nodeid) {
4440 				found_my_nr = 1;
4441 				if (nr->nr_flags & MD_MN_NODE_OK) {
4442 					/*
4443 					 * If node record is marked OK
4444 					 * on its own node, then mark it OK
4445 					 * in the master list.  Node record
4446 					 * would have to exist on all nodes
4447 					 * in the ADD state before it could
4448 					 * be put into the OK state.
4449 					 */
4450 					nd->nd_flags |= MD_MN_NODE_OK;
4451 					nd->nd_flags &=
4452 					    ~(MD_MN_NODE_ADD | MD_MN_NODE_DEL);
4453 					/*
4454 					 * Mark own in master list as marked
4455 					 * on own node.
4456 					 */
4457 					if (nr->nr_flags & MD_MN_NODE_OWN)
4458 						nd->nd_flags |= MD_MN_NODE_OWN;
4459 					else
4460 						nd->nd_flags &= ~MD_MN_NODE_OWN;
4461 				} else {
4462 					/* Otherwise, mark node as DEL */
4463 					nd->nd_flags &= ~MD_MN_NODE_OK;
4464 					nd->nd_flags &= ~MD_MN_NODE_ADD;
4465 					nd->nd_flags |= MD_MN_NODE_DEL;
4466 				}
4467 			}
4468 			/*
4469 			 * If node is not ALIVE and marked DEL
4470 			 * on any node, make it DEL in master list.
4471 			 * If node is not ALIVE and marked ADD
4472 			 * on any node, make it ADD in master list
4473 			 * unless node record has already been marked DEL.
4474 			 */
4475 			if (!(nr->nr_flags & MD_MN_NODE_ALIVE)) {
4476 				if (nr->nr_flags & MD_MN_NODE_ADD) {
4477 					if (!(nd->nd_flags & MD_MN_NODE_DEL)) {
4478 						/* If not DEL - mark it ADD */
4479 						nd->nd_flags |= MD_MN_NODE_ADD;
4480 						nd->nd_flags &= ~MD_MN_NODE_OK;
4481 					}
4482 				}
4483 				if (nr->nr_flags & MD_MN_NODE_DEL) {
4484 					nd->nd_flags |= MD_MN_NODE_DEL;
4485 					nd->nd_flags &= ~MD_MN_NODE_OK;
4486 					/* Could already be ADD - make it DEL */
4487 					nd->nd_flags &= ~MD_MN_NODE_ADD;
4488 				}
4489 			}
4490 			nr = nr->nr_next;
4491 		}
4492 		/*
4493 		 * If a node record doesn't exist on its own node,
4494 		 * then mark node as DEL.
4495 		 */
4496 		if (found_my_nr == 0) {
4497 			nd->nd_flags &= ~MD_MN_NODE_OK;
4498 			nd->nd_flags |= MD_MN_NODE_DEL;
4499 		}
4500 
4501 		/*
4502 		 * If node is OK - put mnsr onto master_mnsr_node list for
4503 		 * later use when syncing up the drive records in the set.
4504 		 */
4505 		if (nd->nd_flags & MD_MN_NODE_OK) {
4506 			mnsr_node = Zalloc(sizeof (*mnsr_node));
4507 			mnsr_node->mmn_mnsr = mnsr;
4508 			(void) strncpy(mnsr_node->mmn_nodename,
4509 				nd->nd_nodename, MD_MAX_MNNODENAME_PLUS_1);
4510 			mnsr_node->mmn_next = master_mnsr_node;
4511 			master_mnsr_node = mnsr_node;
4512 		} else {
4513 			free_sr((struct md_set_record *)mnsr);
4514 		}
4515 
4516 		nd = nd->nd_next;
4517 	}
4518 
4519 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
4520 	    "Master nodelist created for set %s: %s"),
4521 	    sp->setname, meta_print_hrtime(gethrtime() - start_time));
4522 
4523 	/*
4524 	 * Send master nodelist to the rpc.metad on all nodes (including
4525 	 * myself) and each node will update itself.  This will set the
4526 	 * ADD and DEL flags on each node as setup in the master nodelist.
4527 	 * Don't send nodelist to node where set doesn't exist.
4528 	 */
4529 	nd = master_nodelist;
4530 	while (nd) {
4531 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE) ||
4532 		    (nd->nd_flags & MD_MN_NODE_NOSET)) {
4533 			nd = nd->nd_next;
4534 			continue;
4535 		}
4536 		if (clnt_upd_nr_flags(nd->nd_nodename, sp,
4537 		    master_nodelist, MD_NR_SET, MNSET_IN_RECONFIG, ep)) {
4538 			/* If RPC failure to another node return 205 */
4539 			if ((mdanyrpcerror(ep)) &&
4540 			    (sd->sd_mn_mynode->nd_nodeid !=
4541 			    nd->nd_nodeid)) {
4542 				rval = 205;
4543 			} else {
4544 				/* Any other failure */
4545 				rval = -1;
4546 			}
4547 			goto out;
4548 		}
4549 		nd = nd->nd_next;
4550 	}
4551 
4552 	/*
4553 	 * Now, delete nodes that need to be deleted.
4554 	 */
4555 	if ((dd = metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
4556 	    ep))  == NULL) {
4557 		if (! mdisok(ep)) {
4558 			rval = -1;
4559 			goto out;
4560 		}
4561 	}
4562 
4563 	/*
4564 	 * May be doing lots of RPC commands to the nodes, so lock the
4565 	 * ALIVE members of the set since most of the rpc.metad routines
4566 	 * require this for security reasons.
4567 	 */
4568 	nd = master_nodelist;
4569 	while (nd) {
4570 		/* Skip non-alive nodes and node without set */
4571 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE) ||
4572 		    (nd->nd_flags & MD_MN_NODE_NOSET)) {
4573 			nd = nd->nd_next;
4574 			continue;
4575 		}
4576 		if (clnt_lock_set(nd->nd_nodename, sp, ep)) {
4577 			/* If RPC failure to another node return 205 */
4578 			if ((mdanyrpcerror(ep)) &&
4579 			    (sd->sd_mn_mynode->nd_nodeid !=
4580 			    nd->nd_nodeid)) {
4581 				rval = 205;
4582 			} else {
4583 				/* Any other failure */
4584 				rval = -1;
4585 			}
4586 			goto out;
4587 		}
4588 		set_locked = 1;
4589 		nd = nd->nd_next;
4590 	}
4591 
4592 	nd = master_nodelist;
4593 	while (nd) {
4594 		/* Skip non-alive nodes */
4595 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
4596 			nd = nd->nd_next;
4597 			continue;
4598 		}
4599 		if (nd->nd_flags & MD_MN_NODE_DEL) {
4600 			num_alive_nodes_del++;
4601 			/*
4602 			 * Delete this node rec from all ALIVE nodes in diskset.
4603 			 */
4604 			nd2 = master_nodelist;
4605 			while (nd2) {
4606 				/* Skip non-alive nodes and node without set */
4607 				if (!(nd2->nd_flags & MD_MN_NODE_ALIVE) ||
4608 				    (nd2->nd_flags & MD_MN_NODE_NOSET)) {
4609 					nd2 = nd2->nd_next;
4610 					continue;
4611 				}
4612 
4613 				/* This is a node being deleted from set */
4614 				if (nd2->nd_nodeid == nd->nd_nodeid) {
4615 					/* Mark set record as DEL */
4616 					if (clnt_upd_sr_flags(nd->nd_nodename,
4617 					    sp, MD_SR_DEL, ep)) {
4618 						/* RPC failure to !my node */
4619 						if ((mdanyrpcerror(ep)) &&
4620 						    (sd->sd_mn_mynode->
4621 						    nd_nodeid
4622 						    != nd->nd_nodeid)) {
4623 							rval = 205;
4624 						} else {
4625 							/* Any other failure */
4626 							rval = -1;
4627 						}
4628 						goto out;
4629 					}
4630 					if (clnt_deldrvs(nd->nd_nodename, sp,
4631 					    dd, ep)) {
4632 						/* RPC failure to !my node */
4633 						if ((mdanyrpcerror(ep)) &&
4634 						    (sd->sd_mn_mynode->
4635 						    nd_nodeid
4636 						    != nd->nd_nodeid)) {
4637 							rval = 205;
4638 						} else {
4639 							/* Any other failure */
4640 							rval = -1;
4641 						}
4642 						goto out;
4643 					}
4644 					if (clnt_delset(nd->nd_nodename, sp,
4645 					    ep) == -1) {
4646 						/* RPC failure to !my node */
4647 						if ((mdanyrpcerror(ep)) &&
4648 						    (sd->sd_mn_mynode->
4649 						    nd_nodeid
4650 						    != nd->nd_nodeid)) {
4651 							rval = 205;
4652 						} else {
4653 							/* Any other failure */
4654 							rval = -1;
4655 						}
4656 						goto out;
4657 					}
4658 				} else {
4659 					/*
4660 					 * Delete host from sets on hosts
4661 					 * not being deleted.
4662 					 */
4663 					anode[0] = Strdup(nd->nd_nodename);
4664 					if (clnt_delhosts(nd2->nd_nodename, sp,
4665 					    1, anode, ep) == -1) {
4666 						Free(anode[0]);
4667 						/* RPC failure to !my node */
4668 						if ((mdanyrpcerror(ep)) &&
4669 						    (sd->sd_mn_mynode->
4670 						    nd_nodeid
4671 						    != nd2->nd_nodeid)) {
4672 							rval = 205;
4673 						} else {
4674 							/* Any other failure */
4675 							rval = -1;
4676 						}
4677 						goto out;
4678 					}
4679 
4680 					meta_mc_log(MC_LOG5,
4681 					    dgettext(TEXT_DOMAIN,
4682 					    "Deleted node %s (%d) on node %s "
4683 					    "from set %s: %s"),
4684 					    nd->nd_nodename, nd->nd_nodeid,
4685 					    nd2->nd_nodename,
4686 					    sp->setname,
4687 					    meta_print_hrtime(
4688 					    gethrtime() - start_time));
4689 
4690 					Free(anode[0]);
4691 				}
4692 				nd2 = nd2->nd_next;
4693 			}
4694 		}
4695 		nd = nd->nd_next;
4696 	}
4697 
4698 	nd = master_nodelist;
4699 	cl_sk = cl_get_setkey(sp->setno, sp->setname);
4700 	while (nd) {
4701 		/* Skip non-alive nodes and node without set */
4702 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE) ||
4703 		    (nd->nd_flags & MD_MN_NODE_NOSET)) {
4704 			nd = nd->nd_next;
4705 			continue;
4706 		}
4707 		if (clnt_unlock_set(nd->nd_nodename, cl_sk, ep)) {
4708 			/* If RPC failure to another node return 205 */
4709 			if ((mdanyrpcerror(ep)) &&
4710 			    (sd->sd_mn_mynode->nd_nodeid !=
4711 			    nd->nd_nodeid)) {
4712 				rval = 205;
4713 			} else {
4714 				/* Any other failure */
4715 				rval = -1;
4716 			}
4717 			goto out;
4718 		}
4719 		nd = nd->nd_next;
4720 	}
4721 	cl_set_setkey(NULL);
4722 	set_locked = 0;
4723 
4724 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
4725 	    "Nodelist syncronization complete for set %s: %s"),
4726 	    sp->setname, meta_print_hrtime(gethrtime() - start_time));
4727 
4728 	metaflushsetname(sp);
4729 
4730 	/*
4731 	 * If all alive nodes have been deleted from set, just
4732 	 * return since nothing else can be done until non-alive
4733 	 * nodes (if there are any) rejoin the cluster.
4734 	 */
4735 	if (num_alive_nodes == num_alive_nodes_del) {
4736 		rval = 0;
4737 		goto out;
4738 	}
4739 
4740 	/*
4741 	 * Sync up drive records.
4742 	 *
4743 	 * If a node panic'd (or metaset command was killed) during the
4744 	 * addition or deletion of a drive to the diskset, the nodes
4745 	 * may have a different view of the drive list.  During cleanup
4746 	 * of the drive list during reconfig, a drive will be deleted
4747 	 * from the list if the master node sees that the drive has been
4748 	 * marked in the ADD state on any node or is marked in the DEL state
4749 	 * on all nodes.
4750 	 * This cleanup must occur even if all nodes in the cluster are
4751 	 * not part of the cluster so that all nodes have the same view
4752 	 * of the drivelist.
4753 	 * Then if the entire cluster goes down and comes back up, the
4754 	 * new master node could be a node that wasn't in the cluster when
4755 	 * the node was deleted.  This could lead to a situation where the
4756 	 * master node thinks that a drive is OK, but this drive isn't
4757 	 * known to the other nodes.
4758 	 * This situation can also occur during the addition of a drive
4759 	 * where a node has the drive marked OK, but the node executing the
4760 	 * metaset command enountered a failure before marking that drive OK
4761 	 * on the rest of the nodes.  If the node with the OK drive then
4762 	 * panics, then rest of the nodes will remove that drive marked ADD
4763 	 * and when the node with the OK drive rejoins the cluster, it will
4764 	 * have a drive marked OK that is unknown by the other nodes.
4765 	 *
4766 	 * There are 2 situations to consider:
4767 	 * A) Master knows about a drive that other nodes don't know about.
4768 	 * B) At least one slave node knows about a drive that the master
4769 	 *    node doesn't know about.
4770 	 *
4771 	 * To handle these situations the following steps are followed:
4772 	 * 1) Count number of drives known by this master node and the
4773 	 *    other slave nodes.
4774 	 *    If all nodes have the same number of drives and the master has
4775 	 *    all drives marked OK, then skip to step4.
4776 	 *
4777 	 * 2) If a node has less drives listed than the master, the master
4778 	 *    must get the drive descriptor list from that node so that
4779 	 *    master can determine which drive it needs to delete from that
4780 	 *    node.  Master must get the drive descriptor list since the
4781 	 *    drive record list does not contain the name of the drive, but
4782 	 *    only a key and the key can only be interprested on that other
4783 	 *    node.
4784 	 *
4785 	 * 3) The master will then create the master drive list by doing:
4786 	 *	- Master starts with drive list known by master.
4787 	 *	- Any drive marked ADD will be removed from the list.
4788 	 *	- Any drive not known by another node (from step2) will be
4789 	 *	removed from the drive list.
4790 	 *	- If a drive is marked DEL on the master, the master must
4791 	 *	verify that the drive record is marked DEL on all nodes.
4792 	 *	If any node has the drive record marked OK, mark it OK
4793 	 *	on the master.  (The reason why is described below).
4794 	 *
4795 	 * 4) The master sends out the master drive list and the slave
4796 	 *    nodes will force their drive lists to match the master
4797 	 *    drive list by deleting drives, if necessary and by changing
4798 	 *    the drive record states from ADD->OK if master has drive
4799 	 *    marked OK and slave has drive marked ADD.
4800 	 *
4801 	 * Interesting scenarios:
4802 	 *
4803 	 * 1) System has 4 nodes with node 1 as the master.  Node 3 starts
4804 	 *    to delete a drive record (drive record on node 1 is marked DEL),
4805 	 *    but is stopped when node 3 panics.  Node 1 also panics.
4806 	 *    During reconfig cycle, node 2 is picked as master and the drive
4807 	 *    record is left alone since all nodes in the cluster have it
4808 	 *    marked OK.  User now sees drive as part of diskset.
4809 	 *    Now, entire cluster is rebooted and node 1 rejoins the cluster.
4810 	 *    Node 1 is picked as the master and node 1 has drive record
4811 	 *    marked DEL.  Node 1 contacts all other nodes in the cluster
4812 	 *    and since at least one node has the drive record marked OK,
4813 	 *    the master marks the drive record OK.
4814 	 *    User continues to see the drive as part of the diskset.
4815 	 */
4816 
4817 	/* Reget set descriptor since flushed above */
4818 	if ((sd = metaget_setdesc(sp, ep)) == NULL) {
4819 		rval = -1;
4820 		goto out;
4821 	}
4822 
4823 	/* Has side effect of setting sd->sd_drvs to same as master_dd */
4824 	if ((master_dd = metaget_drivedesc_sideno(sp,
4825 	    sd->sd_mn_mynode->nd_nodeid,
4826 	    (MD_BASICNAME_OK | PRINT_FAST), ep)) == NULL) {
4827 		/* No drives in list */
4828 		if (!mdisok(ep)) {
4829 			/*
4830 			 * Can't get drive list for this node, so
4831 			 * return -1 causing this node to be removed
4832 			 * cluster config and fixed.
4833 			 */
4834 			rval = -1;
4835 			goto out;
4836 		}
4837 	}
4838 
4839 	/* Count the number of drives for all nodes */
4840 	mnsr_node = master_mnsr_node;
4841 	while (mnsr_node) {
4842 		dr_cnt = 0;
4843 		dr = mnsr_node->mmn_mnsr->sr_drivechain;
4844 		while (dr) {
4845 			dr_cnt++;
4846 			dr = dr->dr_next;
4847 		}
4848 		mnsr_node->mmn_numdrives = dr_cnt;
4849 		mnsr_node = mnsr_node->mmn_next;
4850 	}
4851 
4852 	/* Count the number of drives for the master; also check flags */
4853 	all_drives_ok = 1;
4854 	dd_cnt = 0;
4855 	dd = master_dd;
4856 	while (dd) {
4857 		dd_cnt++;
4858 		if (!(dd->dd_flags & MD_DR_OK))
4859 			all_drives_ok = 0;
4860 		dd = dd->dd_next;
4861 	}
4862 
4863 	/* If all drives are ok, do quick check against number of drives */
4864 	if (all_drives_ok) {
4865 		/* If all nodes have same number of drives, almost done */
4866 		mnsr_node = master_mnsr_node;
4867 		while (mnsr_node) {
4868 			if (mnsr_node->mmn_numdrives != dd_cnt)
4869 				break;
4870 			mnsr_node = mnsr_node->mmn_next;
4871 		}
4872 		/* All nodes have same number of drives, just send flags */
4873 		if (mnsr_node == NULL) {
4874 			goto send_drive_list;
4875 		}
4876 	}
4877 
4878 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
4879 	    "Begin detailed drive synchronization for set %s: %s"),
4880 	    sp->setname, meta_print_hrtime(gethrtime() - start_time));
4881 
4882 	/* Detailed check required  */
4883 	mnsr_node = master_mnsr_node;
4884 	while (mnsr_node) {
4885 		/* Does slave node have less drives than master? */
4886 		if (mnsr_node->mmn_numdrives < dd_cnt) {
4887 			/* Yes - must determine which drive is missing */
4888 			if (clnt_getdrivedesc(mnsr_node->mmn_nodename, sp,
4889 			    &other_dd, ep)) {
4890 				/* RPC failure to !my node */
4891 				if ((mdanyrpcerror(ep)) &&
4892 				    (strcmp(mynode(), mnsr_node->mmn_nodename)
4893 				    != 0)) {
4894 					rval = 205;
4895 				} else {
4896 					/* Any other failure */
4897 					rval = -1;
4898 				}
4899 				mde_perror(ep, dgettext(TEXT_DOMAIN,
4900 				    "Master node %s unable to "
4901 				    "retrieve drive list from node %s"),
4902 				    mynode(), mnsr_node->mmn_nodename);
4903 				goto out;
4904 			}
4905 			mnsr_node->mmn_dd = other_dd;
4906 			dd = master_dd;
4907 			while (dd) {
4908 				if (!(dd->dd_flags & MD_DR_OK)) {
4909 					dd = dd->dd_next;
4910 					continue;
4911 				}
4912 				other_dd = mnsr_node->mmn_dd;
4913 				while (other_dd) {
4914 					/* Convert to devids, when available */
4915 					if (strcmp(other_dd->dd_dnp->cname,
4916 					    dd->dd_dnp->cname) == 0) {
4917 						break;
4918 					}
4919 					other_dd = other_dd->dd_next;
4920 				}
4921 				/*
4922 				 * dd not found on slave so mark it
4923 				 * ADD for later deletion (drives in ADD
4924 				 * state are deleted later in this routine).
4925 				 */
4926 				if (other_dd == NULL) {
4927 					dd->dd_flags = MD_DR_ADD;
4928 				}
4929 				dd = dd->dd_next;
4930 			}
4931 
4932 		}
4933 		mnsr_node = mnsr_node->mmn_next;
4934 	}
4935 
4936 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
4937 	    "Drive check completed for set %s: %s"),
4938 	    sp->setname, meta_print_hrtime(gethrtime() - start_time));
4939 
4940 	dd = master_dd;
4941 	dd_prev = 0;
4942 	while (dd) {
4943 		/* Remove any ADD drives from list */
4944 		if (dd->dd_flags & MD_DR_ADD) {
4945 			if (dd_prev) {
4946 				dd_prev->dd_next = dd->dd_next;
4947 				dd->dd_next = NULL;
4948 				metafreedrivedesc(&dd);
4949 				dd = dd_prev->dd_next;
4950 			} else {
4951 				/*
4952 				 * If removing drive descriptor from head
4953 				 * of linked list, also change sd->sd_drvs.
4954 				 */
4955 				master_dd = sd->sd_drvs = dd->dd_next;
4956 				dd->dd_next = NULL;
4957 				metafreedrivedesc(&dd);
4958 				dd = master_dd;
4959 			}
4960 			/* dd setup in if/else above */
4961 			continue;
4962 		}
4963 		/*
4964 		 * If drive is marked DEL, check all other nodes.
4965 		 * If drive on another node is marked OK, mark drive OK
4966 		 * in master list.  If drive is marked DEL or doesn't exist
4967 		 * on all nodes, remove drive from list.
4968 		 */
4969 		if (dd->dd_flags & MD_DR_DEL) {
4970 			mnsr_node = master_mnsr_node;
4971 			while (mnsr_node) {
4972 				if (mnsr_node->mmn_dd == NULL) {
4973 				    if (clnt_getdrivedesc(
4974 					mnsr_node->mmn_nodename, sp,
4975 					&other_dd, ep)) {
4976 					    /* RPC failure to !my node */
4977 					    if ((mdanyrpcerror(ep)) &&
4978 						(strcmp(mynode(),
4979 						mnsr_node->mmn_nodename)
4980 						!= 0)) {
4981 						    rval = 205;
4982 					    } else {
4983 						    /* Any other failure */
4984 						    rval = -1;
4985 					    }
4986 					    mde_perror(ep, dgettext(TEXT_DOMAIN,
4987 						"Master node %s unable "
4988 						"to retrieve drive list from "
4989 						"node %s"), mynode(),
4990 						mnsr_node->mmn_nodename);
4991 					    goto out;
4992 				    }
4993 				    mnsr_node->mmn_dd = other_dd;
4994 				}
4995 				other_dd = mnsr_node->mmn_dd;
4996 				while (other_dd) {
4997 					/* Found drive (OK) from other node */
4998 					if (strcmp(dd->dd_dnp->cname,
4999 					    other_dd->dd_dnp->cname)
5000 					    == 0) {
5001 						/* Drive marked OK */
5002 						if (other_dd->dd_flags &
5003 						    MD_DR_OK) {
5004 						    dd->dd_flags = MD_DR_OK;
5005 						}
5006 						break;
5007 					}
5008 					other_dd = other_dd->dd_next;
5009 				}
5010 				if (dd->dd_flags == MD_DR_OK)
5011 					break;
5012 
5013 				mnsr_node = mnsr_node->mmn_next;
5014 			}
5015 			/*
5016 			 * If no node had this drive marked OK, delete it.
5017 			 */
5018 			if (dd->dd_flags & MD_DR_DEL) {
5019 				if (dd_prev) {
5020 					dd_prev->dd_next = dd->dd_next;
5021 					dd->dd_next = NULL;
5022 					metafreedrivedesc(&dd);
5023 					dd = dd_prev->dd_next;
5024 				} else {
5025 					/*
5026 					 * If removing drive descriptor from
5027 					 * head of linked list, also change
5028 					 * sd->sd_drvs.
5029 					 */
5030 					master_dd = sd->sd_drvs = dd->dd_next;
5031 					dd->dd_next = NULL;
5032 					metafreedrivedesc(&dd);
5033 					dd = master_dd;
5034 				}
5035 				/* dd setup in if/else above */
5036 				continue;
5037 			}
5038 		}
5039 		dd_prev = dd;
5040 		dd = dd->dd_next;
5041 	}
5042 
5043 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
5044 	    "Setting drive states completed for set %s: %s"),
5045 	    sp->setname, meta_print_hrtime(gethrtime() - start_time));
5046 
5047 send_drive_list:
5048 	/*
5049 	 * Set genid on all drives to be the highest value seen.
5050 	 */
5051 	dd = master_dd;
5052 	while (dd) {
5053 		dd->dd_genid = max_genid;
5054 		dd = dd->dd_next;
5055 	}
5056 	/*
5057 	 * Send updated drive list to all alive nodes.
5058 	 * Will also set genid on set and node records to have same
5059 	 * as the drive records.
5060 	 */
5061 	nd = sd->sd_nodelist;
5062 	while (nd) {
5063 		/* Skip non-alive nodes */
5064 		if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
5065 			nd = nd->nd_next;
5066 			continue;
5067 		}
5068 		if (clnt_upd_dr_reconfig(nd->nd_nodename, sp, master_dd, ep)) {
5069 			/* RPC failure to another node */
5070 			if ((mdanyrpcerror(ep)) &&
5071 			    (sd->sd_mn_mynode->nd_nodeid != nd->nd_nodeid)) {
5072 				rval = 205;
5073 			} else {
5074 				/* Any other failure */
5075 				rval = -1;
5076 			}
5077 			goto out;
5078 		}
5079 		nd = nd->nd_next;
5080 	}
5081 
5082 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
5083 	    "Sent drive list to all nodes for set %s: %s"),
5084 	    sp->setname, meta_print_hrtime(gethrtime() - start_time));
5085 
5086 	/*
5087 	 * If no drive records left in set and nodes had been joined,
5088 	 * withdraw the nodes.  Always reset the master and mark
5089 	 * all nodes as withdrawn on all nodes.
5090 	 */
5091 	if (master_dd == NULL) {
5092 		/* Reset new master flag since no longer master */
5093 		(void) memset(&sf, 0, sizeof (sf));
5094 		sf.sf_setno = sp->setno;
5095 		sf.sf_setflags = MD_SET_MN_NEWMAS_RC;
5096 		sf.sf_flags = MDDB_NM_RESET;
5097 		/* Use magic to help protect ioctl against attack. */
5098 		sf.sf_magic = MDDB_SETFLAGS_MAGIC;
5099 		/* Ignore failure, failure to reset flag isn't catastrophic */
5100 		(void) metaioctl(MD_MN_SET_SETFLAGS, &sf,
5101 		    &sf.sf_mde, NULL);
5102 
5103 		meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
5104 		    "Reset new master flag for " "set %s: %s"),
5105 		    sp->setname, meta_print_hrtime(gethrtime() - start_time));
5106 
5107 		nd = sd->sd_nodelist;
5108 		while (nd) {
5109 			/* Skip non-alive nodes  */
5110 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
5111 				nd = nd->nd_next;
5112 				continue;
5113 			}
5114 
5115 			if (clnt_lock_set(nd->nd_nodename, sp, ep)) {
5116 				/* RPC failure to another node */
5117 				if ((mdanyrpcerror(ep)) &&
5118 				    (sd->sd_mn_mynode->nd_nodeid !=
5119 				    nd->nd_nodeid)) {
5120 					rval = 205;
5121 				} else {
5122 					/* Any other failure */
5123 					rval = -1;
5124 				}
5125 				goto out;
5126 			}
5127 			set_locked = 1;
5128 
5129 			/* Withdraw node from set if owner */
5130 			if ((nd->nd_flags & MD_MN_NODE_OWN) &&
5131 			    (clnt_withdrawset(nd->nd_nodename, sp, ep))) {
5132 				/* RPC failure to another node */
5133 				if ((mdanyrpcerror(ep)) &&
5134 				    (sd->sd_mn_mynode->nd_nodeid !=
5135 				    nd->nd_nodeid)) {
5136 					rval = 205;
5137 				} else {
5138 					/* Any other failure */
5139 					rval = -1;
5140 				}
5141 				goto out;
5142 			}
5143 
5144 			/* Mark all nodes as withdrawn on this node */
5145 			if (clnt_upd_nr_flags(nd->nd_nodename, sp,
5146 			    sd->sd_nodelist, MD_NR_WITHDRAW, NULL, ep)) {
5147 				/* RPC failure to another node */
5148 				if ((mdanyrpcerror(ep)) &&
5149 				    (sd->sd_mn_mynode->nd_nodeid !=
5150 				    nd->nd_nodeid)) {
5151 					rval = 205;
5152 				} else {
5153 					/* Any other failure */
5154 					rval = -1;
5155 				}
5156 				goto out;
5157 			}
5158 
5159 			/* Resets master to no-master on this node */
5160 			if (clnt_mnsetmaster(nd->nd_nodename, sp,
5161 			    "", MD_MN_INVALID_NID, ep)) {
5162 				/* RPC failure to another node */
5163 				if ((mdanyrpcerror(ep)) &&
5164 				    (sd->sd_mn_mynode->nd_nodeid !=
5165 				    nd->nd_nodeid)) {
5166 					rval = 205;
5167 				} else {
5168 					/* Any other failure */
5169 					rval = -1;
5170 				}
5171 				goto out;
5172 			}
5173 
5174 			cl_sk = cl_get_setkey(sp->setno, sp->setname);
5175 			if (clnt_unlock_set(nd->nd_nodename, cl_sk, ep)) {
5176 				/* RPC failure to another node */
5177 				if ((mdanyrpcerror(ep)) &&
5178 				    (sd->sd_mn_mynode->nd_nodeid !=
5179 				    nd->nd_nodeid)) {
5180 					rval = 205;
5181 				} else {
5182 					/* Any other failure */
5183 					rval = -1;
5184 				}
5185 				goto out;
5186 			}
5187 			set_locked = 0;
5188 			nd = nd->nd_next;
5189 		}
5190 	}
5191 
5192 out:
5193 	/*
5194 	 * If got here and set is still locked, then an error has
5195 	 * occurred and master_nodelist is still valid.
5196 	 * If error is not an RPC error, then unlock.
5197 	 * If error is an RPC error, skip unlocks since this could cause
5198 	 * yet another RPC timeout if a node has failed.
5199 	 * Ignore failures in unlock since unlock is just trying to
5200 	 * clean things up.
5201 	 */
5202 	if ((set_locked) && !(mdanyrpcerror(ep))) {
5203 		nd = master_nodelist;
5204 		cl_sk = cl_get_setkey(sp->setno, sp->setname);
5205 		while (nd) {
5206 			/* Skip non-alive nodes */
5207 			if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
5208 				nd = nd->nd_next;
5209 				continue;
5210 			}
5211 			/*
5212 			 * If clnt_unlock fails, just break out since next
5213 			 * reconfig cycle will reset the locks anyway.
5214 			 */
5215 			if (clnt_unlock_set(nd->nd_nodename, cl_sk, &xep)) {
5216 				break;
5217 			}
5218 			nd = nd->nd_next;
5219 		}
5220 		cl_set_setkey(NULL);
5221 	}
5222 	/* Free master_mnsr and drive descs */
5223 	mnsr_node = master_mnsr_node;
5224 	while (mnsr_node) {
5225 		master_mnsr_node = mnsr_node->mmn_next;
5226 		free_sr((md_set_record *)mnsr_node->mmn_mnsr);
5227 		free_rem_dd(mnsr_node->mmn_dd);
5228 		Free(mnsr_node);
5229 		mnsr_node = master_mnsr_node;
5230 	}
5231 
5232 	/* Frees sd->sd_drvs (which is also master_dd) */
5233 	metaflushsetname(sp);
5234 	return (rval);
5235 }
5236 
5237 /*
5238  * meta_mnsync_diskset_mddbs
5239  * Calling node is guaranteed to be an owner node.
5240  * Calling node is the master node.
5241  *
5242  * Master node verifies that ondisk mddb format matches its incore format.
5243  * If no nodes are joined to set, remove the change log entries.
5244  * If a node is joined to set, play the change log.
5245  *
5246  * Returns	 0 - Success
5247  *		 1 - Master unable to join to set.
5248  *		205 - Failure during RPC to another node
5249  *		-1 - Any other failure and ep is filled in.
5250  *			-1 return will eventually cause node to panic
5251  *			in a SunCluster environment.
5252  */
5253 int
5254 meta_mnsync_diskset_mddbs(
5255 	mdsetname_t	*sp,
5256 	md_error_t	*ep
5257 )
5258 {
5259 	md_set_desc		*sd;
5260 	mddb_config_t		c;
5261 	md_mn_msgclass_t	class;
5262 	mddb_setflags_config_t	sf;
5263 	md_mnnode_desc		*nd, *nd2;
5264 	md_error_t		xep = mdnullerror;
5265 	int			stale_set = 0;
5266 
5267 	/* If setname is there, set desc should exist. */
5268 	if ((sd = metaget_setdesc(sp, ep)) == NULL) {
5269 		mde_perror(ep, dgettext(TEXT_DOMAIN,
5270 		    "Unable to get set %s desc information"), sp->setname);
5271 		return (-1);
5272 	}
5273 
5274 	/* Are there drives in the set? */
5275 	if (metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
5276 	    ep) == NULL) {
5277 		if (! mdisok(ep)) {
5278 			return (-1);
5279 		}
5280 		/* No drives in set -- nothing to sync up */
5281 		return (0);
5282 	}
5283 
5284 	/*
5285 	 * Is master node (which is this node) joined to set?
5286 	 * If master node isn't joined (which means that no nodes
5287 	 * are joined to diskset), remove the change log entries
5288 	 * since no need to replay them - all nodes will have same
5289 	 * view of mddbs since all nodes are reading in the mddbs
5290 	 * from disk.
5291 	 * There is also no need to sync up the master and ondisk mddbs
5292 	 * since master has no incore knowledge.
5293 	 * Need to join master to set in order to flush the change
5294 	 * log entries. Don't need to block I/O during join of master
5295 	 * to set since no other nodes are joined to set and so no I/O
5296 	 * can be occurring.
5297 	 */
5298 	if (!(sd->sd_mn_mynode->nd_flags & MD_MN_NODE_OWN)) {
5299 		/* Join master to set */
5300 		if (clnt_joinset(mynode(), sp,
5301 		    MNSET_IN_RECONFIG, ep)) {
5302 			if (mdismddberror(ep, MDE_DB_STALE)) {
5303 				/*
5304 				 * If STALE, print message and continue on.
5305 				 * Don't do any writes or reads to mddbs
5306 				 * so don't clear change log.
5307 				 */
5308 				mde_perror(ep, dgettext(TEXT_DOMAIN,
5309 				    "Join of master node to STALE set %s"),
5310 				    sp->setname);
5311 				stale_set = 1;
5312 				mdclrerror(ep);
5313 			} else if (mdismddberror(ep, MDE_DB_ACCOK)) {
5314 				/* ACCOK means mediator provided extra vote */
5315 				mdclrerror(ep);
5316 			} else {
5317 				/*
5318 				 * If master is unable to join set, print an
5319 				 * error message.  Don't return failure or node
5320 				 * will panic during cluster reconfig cycle.
5321 				 * Also, withdraw node from set in order to
5322 				 * cleanup from failed join attempt.
5323 				 */
5324 				mde_perror(ep, dgettext(TEXT_DOMAIN,
5325 				    "Join of master node in set %s failed"),
5326 				    sp->setname);
5327 				if (clnt_withdrawset(mynode(), sp, &xep))
5328 					mdclrerror(&xep);
5329 				return (1);
5330 			}
5331 		}
5332 		/*
5333 		 * Master node successfully joined.
5334 		 * Set local copy of flags to OWN and
5335 		 * send owner flag to rpc.metad. If not stale,
5336 		 * flush the change log.
5337 		 */
5338 		sd->sd_mn_mynode->nd_flags |= MD_MN_NODE_OWN;
5339 		if (clnt_upd_nr_flags(mynode(), sp, sd->sd_nodelist, MD_NR_SET,
5340 		    MNSET_IN_RECONFIG, ep)) {
5341 			mde_perror(ep, dgettext(TEXT_DOMAIN,
5342 			    "Flag update of master node join in set %s failed"),
5343 			    sp->setname);
5344 			return (-1);
5345 		}
5346 
5347 		if (!stale_set) {
5348 			if (mdmn_reset_changelog(sp, ep,
5349 			    MDMN_CLF_RESETLOG) != 0) {
5350 				mde_perror(ep, dgettext(TEXT_DOMAIN,
5351 				    "Unable to reset changelog."));
5352 				return (-1);
5353 			}
5354 			meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
5355 			    "Removed changelog entries for set %s: %s"),
5356 			    sp->setname,
5357 			    meta_print_hrtime(gethrtime() - start_time));
5358 		}
5359 		/* Reset new master flag before return */
5360 		(void) memset(&sf, 0, sizeof (sf));
5361 		sf.sf_setno = sp->setno;
5362 		sf.sf_setflags = MD_SET_MN_NEWMAS_RC;
5363 		sf.sf_flags = MDDB_NM_RESET;
5364 		/* Use magic to help protect ioctl against attack. */
5365 		sf.sf_magic = MDDB_SETFLAGS_MAGIC;
5366 		/* Ignore failure, failure to reset flag isn't catastrophic */
5367 		(void) metaioctl(MD_MN_SET_SETFLAGS, &sf,
5368 		    &sf.sf_mde, NULL);
5369 
5370 		meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
5371 		    "Reset new master flag for set %s: %s"),
5372 		    sp->setname, meta_print_hrtime(gethrtime() - start_time));
5373 
5374 		return (0);
5375 	}
5376 
5377 	/*
5378 	 * Is master already joined to STALE set (< 50% mddbs avail)?
5379 	 * If so, can make no config changes to mddbs so don't check or play
5380 	 * changelog and don't sync master node to ondisk mddbs.
5381 	 * To get out of the stale state all nodes must be withdrawn
5382 	 * from set.  Then as nodes are re-joined, all nodes will
5383 	 * have same view of mddbs since all nodes are reading the
5384 	 * mddbs from disk.
5385 	 */
5386 	(void) memset(&c, 0, sizeof (c));
5387 	c.c_id = 0;
5388 	c.c_setno = sp->setno;
5389 	if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) {
5390 		(void) mdstealerror(ep, &c.c_mde);
5391 		return (-1);
5392 	}
5393 	if (c.c_flags & MDDB_C_STALE) {
5394 		return (0);
5395 	}
5396 
5397 	/*
5398 	 * If this node is NOT a newly chosen master, then there's
5399 	 * nothing else to do since the change log should be empty and
5400 	 * the ondisk and incore mddbs are already consistent.
5401 	 *
5402 	 * A newly chosen master is a node that was not the master
5403 	 * at the beginning of the reconfig cycle.  If a node is a new
5404 	 * master, then the new master state is reset after the ondisk
5405 	 * and incore mddbs are consistent and the change log has
5406 	 * been replayed.
5407 	 */
5408 	(void) memset(&sf, 0, sizeof (sf));
5409 	sf.sf_setno = sp->setno;
5410 	sf.sf_flags = MDDB_NM_GET;
5411 	/* Use magic to help protect ioctl against attack. */
5412 	sf.sf_magic = MDDB_SETFLAGS_MAGIC;
5413 	if ((metaioctl(MD_MN_GET_SETFLAGS, &sf, &sf.sf_mde, NULL) == 0) &&
5414 	    ((sf.sf_setflags & MD_SET_MN_NEWMAS_RC) == 0)) {
5415 		return (0);
5416 	}
5417 
5418 	/*
5419 	 * Now, sync up incore master view to ondisk mddbs.
5420 	 * This is needed in the case where a master node
5421 	 * had made a change to the mddb, but this change
5422 	 * may not have been relayed to the slaves yet.
5423 	 * So, the new master needs to verify that the ondisk
5424 	 * mddbs match what the new master has incore -
5425 	 * if different, new master rewrites all of the mddbs.
5426 	 * Then the new master will replay the changelog and the
5427 	 * new master will then execute what the old master had
5428 	 * done.
5429 	 *
5430 	 * Block all I/Os to disks in this diskset on all nodes in
5431 	 * the diskset.  This will allow the rewriting of the mddbs
5432 	 * (if needed), to proceed in a timely manner.
5433 	 *
5434 	 * If block of I/Os fail, return a -1.
5435 	 */
5436 
5437 	nd = sd->sd_nodelist;
5438 	while (nd) {
5439 		/* Skip non-alive and non-owner nodes  */
5440 		if ((!(nd->nd_flags & MD_MN_NODE_ALIVE)) ||
5441 		    (!(nd->nd_flags & MD_MN_NODE_OWN))) {
5442 			nd = nd->nd_next;
5443 			continue;
5444 		}
5445 		if (clnt_mn_susp_res_io(nd->nd_nodename, sp->setno,
5446 		    MN_SUSP_IO, ep)) {
5447 			mde_perror(ep, dgettext(TEXT_DOMAIN,
5448 			    "Unable to suspend I/O on node %s in set %s"),
5449 			    nd->nd_nodename, sp->setname);
5450 
5451 			/*
5452 			 * Resume all other nodes that had been suspended.
5453 			 * (Reconfig return step also resumes I/Os
5454 			 * for all sets.)
5455 			 */
5456 			nd2 = sd->sd_nodelist;
5457 			while (nd2) {
5458 				/* Stop when reaching failed node */
5459 				if (nd2->nd_nodeid == nd->nd_nodeid)
5460 					break;
5461 				/* Skip non-alive and non-owner nodes  */
5462 				if ((!(nd2->nd_flags & MD_MN_NODE_ALIVE)) ||
5463 				    (!(nd2->nd_flags & MD_MN_NODE_OWN))) {
5464 					nd2 = nd2->nd_next;
5465 					continue;
5466 				}
5467 				(void) (clnt_mn_susp_res_io(nd2->nd_nodename,
5468 					sp->setno, MN_RES_IO, &xep));
5469 				nd2 = nd2->nd_next;
5470 			}
5471 
5472 			/*
5473 			 * If an RPC failure on another node, return a 205.
5474 			 * Otherwise, exit with failure.
5475 			 */
5476 			if ((mdanyrpcerror(ep)) &&
5477 			    (sd->sd_mn_mynode->nd_nodeid !=
5478 			    nd->nd_nodeid)) {
5479 				return (205);
5480 			} else {
5481 				return (-1);
5482 			}
5483 
5484 		}
5485 		nd = nd->nd_next;
5486 	}
5487 
5488 	(void) memset(&c, 0, sizeof (c));
5489 	c.c_id = 0;
5490 	c.c_setno = sp->setno;
5491 	/* Master can't sync up to ondisk mddbs?  Kick it out of cluster */
5492 	if (metaioctl(MD_MN_CHK_WRT_MDDB, &c, &c.c_mde, NULL) != 0)
5493 		return (-1);
5494 
5495 	/*
5496 	 * Resume I/Os that were suspended above.
5497 	 */
5498 	nd = sd->sd_nodelist;
5499 	while (nd) {
5500 		/* Skip non-alive and non-owner nodes  */
5501 		if ((!(nd->nd_flags & MD_MN_NODE_ALIVE)) ||
5502 		    (!(nd->nd_flags & MD_MN_NODE_OWN))) {
5503 			nd = nd->nd_next;
5504 			continue;
5505 		}
5506 		if (clnt_mn_susp_res_io(nd->nd_nodename, sp->setno,
5507 		    MN_RES_IO, ep)) {
5508 			mde_perror(ep, dgettext(TEXT_DOMAIN,
5509 			    "Unable to resume I/O on node %s in set %s"),
5510 			    nd->nd_nodename, sp->setname);
5511 
5512 			/*
5513 			 * If an RPC failure then don't do any
5514 			 * more RPC calls, since one timeout is enough
5515 			 * to endure.  If RPC failure to another node, return
5516 			 * 205.  If RPC failure to my node, return -1.
5517 			 * If not an RPC failure, continue resuming the
5518 			 * rest of the nodes and then return -1.
5519 			 */
5520 			if (mdanyrpcerror(ep)) {
5521 				if (sd->sd_mn_mynode->nd_nodeid ==
5522 				    nd->nd_nodeid) {
5523 					return (-1);
5524 				} else {
5525 					return (205);
5526 				}
5527 			}
5528 
5529 			/*
5530 			 * If not an RPC error, continue resuming rest of
5531 			 * nodes, ignoring any failures except for an
5532 			 * RPC failure which constitutes an immediate exit.
5533 			 * Start in middle of list with failing node.
5534 			 */
5535 			nd2 = nd->nd_next;
5536 			while (nd2) {
5537 				/* Skip non-alive and non-owner nodes  */
5538 				if ((!(nd2->nd_flags & MD_MN_NODE_ALIVE)) ||
5539 				    (!(nd2->nd_flags & MD_MN_NODE_OWN))) {
5540 					nd2 = nd2->nd_next;
5541 					continue;
5542 				}
5543 				(void) (clnt_mn_susp_res_io(nd2->nd_nodename,
5544 					sp->setno, MN_RES_IO, &xep));
5545 				if (mdanyrpcerror(&xep)) {
5546 					return (-1);
5547 				}
5548 				nd2 = nd2->nd_next;
5549 			}
5550 		}
5551 		nd = nd->nd_next;
5552 	}
5553 
5554 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN, "Master node has completed "
5555 	    "checking/writing the mddb for set %s: %s"), sp->setname,
5556 	    meta_print_hrtime(gethrtime() - start_time));
5557 
5558 	/*
5559 	 * Send (aka replay) all messages we find in the changelog.
5560 	 * Flag the messages with
5561 	 *   MD_MSGF_REPLAY_MSG, so no new message ID is generated for them
5562 	 *   MD_MSGF_OVERRIDE_SUSPEND so they can pass the suspended commd.
5563 	 */
5564 	for (class = MD_MN_NCLASSES - 1; class > 0; class--) {
5565 		mdmn_changelog_record_t	*lr;
5566 		md_error_t	xep = mdnullerror;
5567 		md_mn_result_t	*resultp = NULL;
5568 		int		ret;
5569 
5570 		lr = mdmn_get_changelogrec(sp->setno, class);
5571 		if ((lr->lr_flags & MD_MN_LR_INUSE) == 0) {
5572 			/* no entry for this class */
5573 			continue;
5574 		}
5575 
5576 		meta_mc_log(MC_LOG1, dgettext(TEXT_DOMAIN,
5577 		    "replaying message ID=(%d, 0x%llx-%d)\n"),
5578 		    MSGID_ELEMS(lr->lr_msg.msg_msgid));
5579 
5580 		ret = mdmn_send_message_with_msgid(
5581 			lr->lr_msg.msg_setno,
5582 			lr->lr_msg.msg_type,
5583 			lr->lr_msg.msg_flags |  MD_MSGF_REPLAY_MSG |
5584 						MD_MSGF_OVERRIDE_SUSPEND,
5585 			lr->lr_msg.msg_event_data,
5586 			lr->lr_msg.msg_event_size,
5587 			&resultp,
5588 			&lr->lr_msg.msg_msgid,
5589 			&xep);
5590 
5591 		meta_mc_log(MC_LOG1, dgettext(TEXT_DOMAIN,
5592 		    "mdmn_send_message returned %d\n"), ret);
5593 
5594 		if (resultp)
5595 			free_result(resultp);
5596 	}
5597 
5598 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
5599 	    "Playing changelog completed for set %s: %s"),
5600 	    sp->setname, meta_print_hrtime(gethrtime() - start_time));
5601 
5602 	/*
5603 	 * Now that new master has ondisk and incore mddbs in sync, reset
5604 	 * this node's new master kernel flag (for this set).  If this node
5605 	 * re-enters another reconfig cycle before the completion of this
5606 	 * reconfig cycle, this master node won't need to check if the ondisk
5607 	 * and incore mddbs are in sync since this node won't be considered
5608 	 * a new master (since this flag is being reset here in the middle of
5609 	 * step2).  This will save time during any subsequent reconfig
5610 	 * cycles as long as this node continues to be master.
5611 	 */
5612 	(void) memset(&sf, 0, sizeof (sf));
5613 	sf.sf_setno = sp->setno;
5614 	sf.sf_setflags = MD_SET_MN_NEWMAS_RC;
5615 	sf.sf_flags = MDDB_NM_RESET;
5616 	/* Use magic to help protect ioctl against attack. */
5617 	sf.sf_magic = MDDB_SETFLAGS_MAGIC;
5618 	/* Ignore failure, since failure to reset flag isn't catastrophic */
5619 	(void) metaioctl(MD_MN_SET_SETFLAGS, &sf, &sf.sf_mde, NULL);
5620 
5621 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
5622 	    "Reset new master flag for set %s: %s"),
5623 	    sp->setname, meta_print_hrtime(gethrtime() - start_time));
5624 
5625 	return (0);
5626 }
5627 
5628 /*
5629  * meta_mnjoin_all will join all starting nodes in the diskset.
5630  * A starting node is considered to be any node that is not
5631  * an owner of the set but is a member of the cluster.
5632  * Master node is already joined to set (done in meta_mnsync_diskset_mddbs).
5633  *
5634  * Caller is the Master node.
5635  *
5636  * Returns	 0 - Success
5637  *		205 - Failure during RPC to another node
5638  *		-1 - Any other failure and ep is filled in.
5639  */
5640 int
5641 meta_mnjoin_all(
5642 	mdsetname_t	*sp,
5643 	md_error_t	*ep
5644 )
5645 {
5646 	md_set_desc		*sd;
5647 	md_mnnode_desc		*nd, *nd2;
5648 	int			rval = 0;
5649 	int			stale_flag = 0;
5650 	mddb_config_t		c;
5651 	int			susp_res_flag = 0;
5652 	md_error_t		xep = mdnullerror;
5653 
5654 	/* If setname is there, set desc should exist. */
5655 	if ((sd = metaget_setdesc(sp, ep)) == NULL) {
5656 		mde_perror(ep, dgettext(TEXT_DOMAIN,
5657 		    "Unable to get set %s desc information"), sp->setname);
5658 		return (-1);
5659 	}
5660 
5661 	/* Are there drives in the set? */
5662 	if (metaget_drivedesc(sp, (MD_BASICNAME_OK | PRINT_FAST),
5663 	    ep) == NULL) {
5664 		if (! mdisok(ep)) {
5665 			return (-1);
5666 		}
5667 		/* No drives in set -- nothing to join */
5668 		return (0);
5669 	}
5670 
5671 	/*
5672 	 * Is set currently stale?
5673 	 */
5674 	(void) memset(&c, 0, sizeof (c));
5675 	c.c_id = 0;
5676 	c.c_setno = sp->setno;
5677 	/* Ignore failure since master node may not be joined yet */
5678 	(void) metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL);
5679 	if (c.c_flags & MDDB_C_STALE) {
5680 		stale_flag = MNSET_IS_STALE;
5681 	}
5682 
5683 	/*
5684 	 * If any nodes are going to be joined to diskset, then
5685 	 * suspend I/O to all disks in diskset so that nodes can join
5686 	 * (read in mddbs) in a reasonable amount of time even under
5687 	 * high I/O load.  Don't need to do this if set is STALE since
5688 	 * no I/O can be occurring to a STALE set.
5689 	 */
5690 	if (stale_flag != MNSET_IS_STALE) {
5691 		nd = sd->sd_nodelist;
5692 		while (nd) {
5693 			/* Found a node that will be joined to diskset */
5694 			if ((nd->nd_flags & MD_MN_NODE_ALIVE) &&
5695 			    (!(nd->nd_flags & MD_MN_NODE_OWN))) {
5696 				/* Set flag that diskset should be suspended */
5697 				susp_res_flag = 1;
5698 				break;
5699 			}
5700 			nd = nd->nd_next;
5701 		}
5702 	}
5703 
5704 	if (susp_res_flag) {
5705 		/*
5706 		 * Block all I/Os to disks in this diskset on all joined
5707 		 * nodes in the diskset.
5708 		 * If block of I/Os fails due to an RPC failure on another
5709 		 * node, return 205; otherwise, return -1.
5710 		 */
5711 		nd = sd->sd_nodelist;
5712 		while (nd) {
5713 			/* Skip non-alive and non-owner nodes  */
5714 			if ((!(nd->nd_flags & MD_MN_NODE_ALIVE)) ||
5715 			    (!(nd->nd_flags & MD_MN_NODE_OWN))) {
5716 				nd = nd->nd_next;
5717 				continue;
5718 			}
5719 			if (clnt_mn_susp_res_io(nd->nd_nodename, sp->setno,
5720 			    MN_SUSP_IO, ep)) {
5721 				mde_perror(ep, dgettext(TEXT_DOMAIN,
5722 				    "Unable to suspend I/O on node %s"
5723 				    " in set %s"), nd->nd_nodename,
5724 				    sp->setname);
5725 				/*
5726 				 * Resume other nodes that had been suspended.
5727 				 * (Reconfig return step also resumes I/Os
5728 				 * for all sets.)
5729 				 */
5730 				nd2 = sd->sd_nodelist;
5731 				while (nd2) {
5732 					/* Stop when reaching failed node */
5733 					if (nd2->nd_nodeid == nd->nd_nodeid)
5734 						break;
5735 					/* Skip non-alive/non-owner nodes  */
5736 					if ((!(nd2->nd_flags &
5737 					    MD_MN_NODE_ALIVE)) ||
5738 					    (!(nd2->nd_flags &
5739 					    MD_MN_NODE_OWN))) {
5740 						nd2 = nd2->nd_next;
5741 						continue;
5742 					}
5743 					(void) (clnt_mn_susp_res_io(
5744 					    nd2->nd_nodename, sp->setno,
5745 					    MN_RES_IO, &xep));
5746 					nd2 = nd2->nd_next;
5747 				}
5748 
5749 				/*
5750 				 * If the suspend failed due to an
5751 				 * RPC failure on another node, return
5752 				 * a 205.
5753 				 * Otherwise, exit with failure.
5754 				 * The return reconfig step will resume
5755 				 * I/Os for all disksets.
5756 				 */
5757 				if ((mdanyrpcerror(ep)) &&
5758 				    (sd->sd_mn_mynode->nd_nodeid !=
5759 				    nd->nd_nodeid)) {
5760 					return (205);
5761 				} else {
5762 					return (-1);
5763 				}
5764 			}
5765 			nd = nd->nd_next;
5766 		}
5767 	}
5768 
5769 	nd = sd->sd_nodelist;
5770 	while (nd) {
5771 		/*
5772 		 * If a node is in the membership list but isn't joined
5773 		 * to the set, try to join the node.
5774 		 */
5775 		if ((nd->nd_flags & MD_MN_NODE_ALIVE) &&
5776 		    (!(nd->nd_flags & MD_MN_NODE_OWN))) {
5777 			if (clnt_joinset(nd->nd_nodename, sp,
5778 			    (MNSET_IN_RECONFIG | stale_flag), ep)) {
5779 				/*
5780 				 * If RPC failure to another node
5781 				 * then exit without attempting anything else.
5782 				 * (Reconfig return step will resume I/Os
5783 				 * for all sets.)
5784 				 */
5785 				if (mdanyrpcerror(ep)) {
5786 					mde_perror(ep, "");
5787 					return (205);
5788 				}
5789 				/*
5790 				 * STALE and ACCOK failures aren't true
5791 				 * failures.  STALE means that <50% mddbs
5792 				 * are available. ACCOK means that the
5793 				 * mediator provided the extra vote.
5794 				 * If a true failure, then print messasge
5795 				 * and withdraw node from set in order to
5796 				 * cleanup from failed join attempt.
5797 				 */
5798 				if ((!mdismddberror(ep, MDE_DB_STALE)) &&
5799 				    (!mdismddberror(ep, MDE_DB_ACCOK))) {
5800 					mde_perror(ep,
5801 					    "WARNING: Unable to join node %s "
5802 					    "to set %s", nd->nd_nodename,
5803 					    sp->setname);
5804 					mdclrerror(ep);
5805 					if (clnt_withdrawset(nd->nd_nodename,
5806 					    sp, &xep))
5807 						mdclrerror(&xep);
5808 					nd = nd->nd_next;
5809 					continue;
5810 				}
5811 			}
5812 			/* Set owner flag even if STALE or ACCOK */
5813 			nd->nd_flags |= MD_MN_NODE_OWN;
5814 		}
5815 		nd = nd->nd_next;
5816 	}
5817 	/*
5818 	 * Resume I/Os if suspended above.
5819 	 */
5820 	if (susp_res_flag) {
5821 		nd = sd->sd_nodelist;
5822 		while (nd) {
5823 			/*
5824 			 * Skip non-alive and non-owner nodes
5825 			 * (this list doesn't include any of
5826 			 * the nodes that were joined).
5827 			 */
5828 			if ((!(nd->nd_flags & MD_MN_NODE_ALIVE)) ||
5829 			    (!(nd->nd_flags & MD_MN_NODE_OWN))) {
5830 				nd = nd->nd_next;
5831 				continue;
5832 			}
5833 			if (clnt_mn_susp_res_io(nd->nd_nodename, sp->setno,
5834 			    MN_RES_IO, ep)) {
5835 				mde_perror(ep, dgettext(TEXT_DOMAIN,
5836 				    "Unable to resume I/O on node %s"
5837 				    " in set %s"), nd->nd_nodename,
5838 				    sp->setname);
5839 
5840 				/*
5841 				 * If an RPC failure then don't do any
5842 				 * more RPC calls, since one timeout is enough
5843 				 * to endure.  If RPC failure to another node,
5844 				 * return 205.  If RPC failure to my node,
5845 				 * return -1.
5846 				 * (Reconfig return step will resume I/Os
5847 				 * for all sets.)
5848 				 * If not an RPC failure, continue resuming the
5849 				 * rest of the nodes and then return -1.
5850 				 */
5851 				if (mdanyrpcerror(ep)) {
5852 					if (sd->sd_mn_mynode->nd_nodeid ==
5853 					    nd->nd_nodeid) {
5854 						return (-1);
5855 					} else {
5856 						return (205);
5857 					}
5858 				}
5859 
5860 				/*
5861 				 * If not an RPC error, continue resuming rest
5862 				 * of nodes, ignoring any failures except for
5863 				 * an RPC failure which constitutes an
5864 				 * immediate exit.
5865 				 * Start in middle of list with failing node.
5866 				 */
5867 				nd2 = nd->nd_next;
5868 				while (nd2) {
5869 					/* Skip non-owner nodes  */
5870 					if ((!(nd2->nd_flags &
5871 					    MD_MN_NODE_ALIVE)) ||
5872 					    (!(nd2->nd_flags &
5873 					    MD_MN_NODE_OWN))) {
5874 						nd2 = nd2->nd_next;
5875 						continue;
5876 					}
5877 					(void) (clnt_mn_susp_res_io(
5878 					    nd2->nd_nodename, sp->setno,
5879 					    MN_RES_IO, &xep));
5880 					if (mdanyrpcerror(&xep)) {
5881 						return (-1);
5882 					}
5883 					nd2 = nd2->nd_next;
5884 				}
5885 			}
5886 			nd = nd->nd_next;
5887 		}
5888 	}
5889 
5890 	nd = sd->sd_nodelist;
5891 	while (nd) {
5892 		if (!(nd->nd_flags & MD_MN_NODE_OWN)) {
5893 			nd = nd->nd_next;
5894 			continue;
5895 		}
5896 		/*
5897 		 * If 1 node fails - go ahead and update the rest except
5898 		 * in the case of an RPC failure, fail immediately.
5899 		 */
5900 		if (clnt_upd_nr_flags(nd->nd_nodename, sp,
5901 		    sd->sd_nodelist, MD_NR_SET, MNSET_IN_RECONFIG, ep)) {
5902 			/* RPC failure to another node */
5903 			if (mdanyrpcerror(ep)) {
5904 				return (205);
5905 			}
5906 			nd = nd->nd_next;
5907 			rval = -1;
5908 			continue;
5909 		}
5910 		nd = nd->nd_next;
5911 	}
5912 
5913 	meta_mc_log(MC_LOG5, dgettext(TEXT_DOMAIN,
5914 	    "Join of all nodes completed for set %s: %s"),
5915 	    sp->setname, meta_print_hrtime(gethrtime() - start_time));
5916 
5917 	return (rval);
5918 }
5919