xref: /onnv-gate/usr/src/lib/lvm/libmeta/common/meta_mirror.c (revision 1623:7bac4a816ebe)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * Just in case we're not in a build environment, make sure that
30  * TEXT_DOMAIN gets set to something.
31  */
32 #if !defined(TEXT_DOMAIN)
33 #define	TEXT_DOMAIN "SYS_TEST"
34 #endif
35 
36 /*
37  * mirror operations
38  */
39 
40 #include <meta.h>
41 #include <sys/lvm/md_mirror.h>
42 #include <sys/lvm/md_convert.h>
43 
44 #include <ctype.h>
45 #include <stddef.h>
46 
47 /*
48  * FUNCTION:    meta_get_mirror_names()
49  * INPUT:       sp      - the set name to get mirrors from
50  *              options - options from the command line
51  * OUTPUT:      nlpp    - list of all mirror names
52  *              ep      - return error pointer
53  * RETURNS:     int     - -1 if error, 0 success
54  * PURPOSE:     returns a list of all mirrors in the metadb
55  *              for all devices in the specified set
56  */
57 int
58 meta_get_mirror_names(
59 	mdsetname_t	*sp,
60 	mdnamelist_t	**nlpp,
61 	int		options,
62 	md_error_t	*ep
63 )
64 {
65 	return (meta_get_names(MD_MIRROR, sp, nlpp, options, ep));
66 }
67 
68 /*
69  * free mirror unit
70  */
71 void
72 meta_free_mirror(
73 	md_mirror_t	*mirrorp
74 )
75 {
76 	Free(mirrorp);
77 }
78 
79 /*
80  * get mirror unit
81  */
82 static md_mirror_t *
83 meta_get_mirror_common(
84 	mdsetname_t	*sp,
85 	mdname_t	*mirnp,
86 	int		fast,
87 	md_error_t	*ep
88 )
89 {
90 	mddrivename_t	*dnp = mirnp->drivenamep;
91 	char		*miscname;
92 	mm_unit_t	*mm;
93 	md_mirror_t	*mirrorp;
94 	uint_t		smi, nsm;
95 	md_resync_ioctl_t ri;
96 
97 	/* must have set */
98 	assert(sp != NULL);
99 
100 	/* short circuit */
101 	if (dnp->unitp != NULL) {
102 		assert(dnp->unitp->type == MD_METAMIRROR);
103 		return ((md_mirror_t *)dnp->unitp);
104 	}
105 
106 	/* get miscname and unit */
107 	if ((miscname = metagetmiscname(mirnp, ep)) == NULL)
108 		return (NULL);
109 	if (strcmp(miscname, MD_MIRROR) != 0) {
110 		(void) mdmderror(ep, MDE_NOT_MM, meta_getminor(mirnp->dev),
111 		    mirnp->cname);
112 		return (NULL);
113 	}
114 	if ((mm = (mm_unit_t *)meta_get_mdunit(sp, mirnp, ep)) == NULL)
115 		return (NULL);
116 	assert(mm->c.un_type == MD_METAMIRROR);
117 
118 	/* allocate mirror */
119 	mirrorp = Zalloc(sizeof (*mirrorp));
120 
121 	/* get common info */
122 	mirrorp->common.namep = mirnp;
123 	mirrorp->common.type = mm->c.un_type;
124 	mirrorp->common.state = mm->c.un_status;
125 	mirrorp->common.capabilities = mm->c.un_capabilities;
126 	mirrorp->common.parent = mm->c.un_parent;
127 	mirrorp->common.size = mm->c.un_total_blocks;
128 	mirrorp->common.user_flags = mm->c.un_user_flags;
129 	mirrorp->common.revision = mm->c.un_revision;
130 
131 	/* get options */
132 	mirrorp->read_option = mm->un_read_option;
133 	mirrorp->write_option = mm->un_write_option;
134 	mirrorp->pass_num = mm->un_pass_num;
135 
136 	/* get submirrors */
137 	for (smi = 0, nsm = 0; (smi < NMIRROR); ++smi) {
138 		mm_submirror_t	*mmsp = &mm->un_sm[smi];
139 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
140 
141 		/* get submirror state */
142 		mdsp->state = mmsp->sm_state;
143 		if (mdsp->state == SMS_UNUSED)
144 			continue;
145 		++nsm;
146 
147 		/* get submirror time of last state change */
148 		mdsp->timestamp = mmsp->sm_timestamp;
149 
150 		/* get submirror flags */
151 		mdsp->flags = mmsp->sm_flags;
152 
153 		/* get submirror name */
154 		mdsp->submirnamep = metakeyname(&sp, mmsp->sm_key, fast, ep);
155 		if (mdsp->submirnamep == NULL)
156 			goto out;
157 	}
158 	assert(nsm == mm->un_nsm);
159 
160 	/* get resync info */
161 	(void) memset(&ri, 0, sizeof (ri));
162 	ri.ri_mnum = meta_getminor(mirnp->dev);
163 	MD_SETDRIVERNAME(&ri, MD_MIRROR, sp->setno);
164 	if (metaioctl(MD_IOCGETSYNC, &ri, &ri.mde, mirnp->cname) != 0) {
165 		(void) mdstealerror(ep, &ri.mde);
166 		goto out;
167 	}
168 	mirrorp->percent_done = ri.ri_percent_done;
169 	mirrorp->percent_dirty = ri.ri_percent_dirty;
170 
171 	/* cleanup, return success */
172 	Free(mm);
173 	dnp->unitp = (md_common_t *)mirrorp;
174 	return (mirrorp);
175 
176 	/* cleanup, return error */
177 out:
178 	Free(mm);
179 	meta_free_mirror(mirrorp);
180 	return (NULL);
181 }
182 
183 /*
184  * get mirror unit
185  */
186 md_mirror_t *
187 meta_get_mirror(
188 	mdsetname_t	*sp,
189 	mdname_t	*mirnp,
190 	md_error_t	*ep
191 )
192 {
193 	return (meta_get_mirror_common(sp, mirnp, 0, ep));
194 }
195 
196 /*
197  * check mirror for dev
198  */
199 static int
200 in_mirror(
201 	mdsetname_t	*sp,
202 	mdname_t	*mirnp,
203 	mdname_t	*np,
204 	diskaddr_t	slblk,
205 	diskaddr_t	nblks,
206 	md_error_t	*ep
207 )
208 {
209 	md_mirror_t	*mirrorp;
210 	uint_t		smi;
211 
212 	/* should be in the same set */
213 	assert(sp != NULL);
214 	assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)));
215 
216 	/* get unit */
217 	if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL)
218 		return (-1);
219 
220 	/* look in submirrors */
221 	for (smi = 0; (smi < NMIRROR); ++smi) {
222 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
223 		mdname_t	*submirnp = mdsp->submirnamep;
224 
225 		/* skip unused submirrors */
226 		if (submirnp == NULL) {
227 			assert(mdsp->state == SMS_UNUSED);
228 			continue;
229 		}
230 
231 		/* check overlap */
232 		if (metaismeta(submirnp))
233 			continue;
234 		if (meta_check_overlap(mirnp->cname, np, slblk, nblks,
235 		    submirnp, 0, -1, ep) != 0)
236 			return (-1);
237 	}
238 
239 	/* return success */
240 	return (0);
241 }
242 
243 /*
244  * check to see if we're in a mirror
245  */
246 int
247 meta_check_inmirror(
248 	mdsetname_t	*sp,
249 	mdname_t	*np,
250 	diskaddr_t	slblk,
251 	diskaddr_t	nblks,
252 	md_error_t	*ep
253 )
254 {
255 	mdnamelist_t	*mirrornlp = NULL;
256 	mdnamelist_t	*p;
257 	int		rval = 0;
258 
259 	/* should have a set */
260 	assert(sp != NULL);
261 
262 	/* for each mirror */
263 	if (meta_get_mirror_names(sp, &mirrornlp, 0, ep) < 0)
264 		return (-1);
265 	for (p = mirrornlp; (p != NULL); p = p->next) {
266 		mdname_t	*mirnp = p->namep;
267 
268 		/* check mirror */
269 		if (in_mirror(sp, mirnp, np, slblk, nblks, ep) != 0) {
270 			rval = -1;
271 			break;
272 		}
273 	}
274 
275 	/* cleanup, return success */
276 	metafreenamelist(mirrornlp);
277 	return (rval);
278 }
279 
280 /*
281  * Check to see if the primary mirror is built on top of a
282  * root slice which is mounted. This check is primarily to
283  * account for this case -
284  *
285  * # metainit -f d1 1 1 <root slice>
286  * # metainit d0 -m d1
287  * # metainit d2 1 1 ctds
288  * # metattach d0 d2
289  *
290  * The metattach here needs to fail if the root slice is
291  * being mirrored; otherwise there is a potential for
292  * data corruption.
293  */
294 static int
295 meta_check_primary_mirror(
296 	mdsetname_t	*sp,
297 	mdname_t	*mirnp,
298 	md_error_t	*ep
299 )
300 {
301 	int		smi;
302 	char		*curroot;
303 	mdname_t	*rootnp;
304 	md_mirror_t	*mirrorp;
305 	md_stripe_t	*stripep;
306 	md_row_t	*rp;
307 	md_comp_t	*cp;
308 
309 	if ((curroot = meta_get_current_root(ep)) == NULL)
310 		return (-1);
311 	/*
312 	 * Get device name of current root metadevice. If root
313 	 * is net mounted as happens if we're part of the
314 	 * install process, rootnp will be set to NULL and we
315 	 * return success.
316 	 *
317 	 * Since curroot should be a complete path, we only
318 	 * need to check whether the device is a logical device.
319 	 * The metaname below returns NULL if curroot is not a logical
320 	 * device.
321 	 */
322 	if ((rootnp = metaname(&sp, curroot, LOGICAL_DEVICE, ep)) == NULL)
323 		return (0);
324 	/*
325 	 * If we're here, the curroot is a mounted on a logical device.
326 	 * Make sure this mirror is not on the root logical device.
327 	 */
328 	if (metaismeta(mirnp)) {
329 		if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL)
330 			return (-1);
331 
332 		for (smi = 0; (smi < NMIRROR); ++smi) {
333 			/* Check all submirrors */
334 			md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
335 			mdname_t	*submirnamep = mdsp->submirnamep;
336 
337 			/* skip unused submirrors */
338 			if (submirnamep == NULL) {
339 				assert(mdsp->state == SMS_UNUSED);
340 				continue;
341 			}
342 			/* check if submirror is a stripe or not */
343 			if (strcmp(metagetmiscname(submirnamep, ep), MD_STRIPE)
344 			    != 0)
345 				return (-1);
346 			if ((stripep = meta_get_stripe(sp, submirnamep, ep))
347 			    == NULL)
348 				return (-1);
349 
350 			/*
351 			 * Examine the first component of the first row and
352 			 * check to see if it has a mounted root slice
353 			 */
354 			rp = &stripep->rows.rows_val[0];
355 			cp = &rp->comps.comps_val[0];
356 			/*
357 			 * we just care about the component built on
358 			 * top of a raw device
359 			 */
360 			if (!metaismeta(cp->compnamep)) {
361 				/*
362 				 * If root device is the 1st component of
363 				 * the stripe, then fail.
364 				 */
365 				if (strcmp(rootnp->cname, cp->compnamep->cname)
366 				    == 0) {
367 					(void) mduseerror(ep, MDE_IS_MOUNTED,
368 					rootnp->dev, "/", rootnp->cname);
369 					return (-1);
370 				}
371 			}
372 		}
373 	}
374 	/* return success */
375 	return (0);
376 }
377 
378 /*
379  * check submirror
380  */
381 int
382 meta_check_submirror(
383 	mdsetname_t	*sp,
384 	mdname_t	*np,
385 	mdname_t	*mirnp,
386 	int		force,
387 	md_error_t	*ep
388 )
389 {
390 	mdchkopts_t	options = 0;
391 	md_common_t	*mdp;
392 
393 	/* make sure we have a metadevice disk */
394 	if (metachkmeta(np, ep) != 0)
395 		return (-1);
396 
397 	/*
398 	 * Check to see if the primary mirror consists of a root
399 	 * mounted device
400 	 */
401 	if (mirnp && (!force) && ((meta_check_primary_mirror(sp, mirnp, ep)
402 	    != 0)))
403 		return (-1);
404 
405 	/* check to ensure that it is not already in use */
406 	if ((! force) &&
407 	    (meta_check_inuse(sp, np, MDCHK_INUSE, ep) != 0)) {
408 		return (-1);
409 	}
410 
411 	/* make sure it is in the set */
412 	if (meta_check_inset(sp, np, ep) != 0)
413 		return (-1);
414 
415 	/* make sure its not in a metadevice */
416 	if (! metaismeta(np)) {		/* Non-metadevices */
417 		if (meta_check_inmeta(sp, np, options, 0, -1, ep) != 0)
418 			return (-1);
419 	} else {			/* Metadevices only! */
420 		/* make sure it can be parented */
421 		if ((mdp = meta_get_unit(sp, np, ep)) == NULL)
422 			return (-1);
423 
424 		if ((! (mdp->capabilities & MD_CAN_PARENT)) ||
425 		    (! (mdp->capabilities & MD_CAN_SUB_MIRROR)) ||
426 		    (mdp->parent != MD_NO_PARENT)) {
427 			return (mdmderror(ep, MDE_INVAL_UNIT,
428 					meta_getminor(np->dev), np->cname));
429 		}
430 	}
431 
432 	/* return success */
433 	return (0);
434 }
435 
436 /*
437  * convert read options
438  */
439 char *
440 rd_opt_to_name(
441 	mm_rd_opt_t	opt
442 )
443 {
444 	switch (opt) {
445 	case RD_LOAD_BAL:
446 		return ("roundrobin");
447 	case RD_GEOMETRY:
448 		return ("geometric");
449 	case RD_FIRST:
450 		return ("first");
451 	default:
452 		assert(0);
453 		return (dgettext(TEXT_DOMAIN, "invalid"));
454 	}
455 }
456 
457 static char *
458 rd_opt_to_opt(
459 	mm_rd_opt_t	opt
460 )
461 {
462 	switch (opt) {
463 	case RD_LOAD_BAL:
464 		return (NULL);	/* default */
465 	case RD_GEOMETRY:
466 		return ("-g");
467 	case RD_FIRST:
468 		return ("-r");
469 	default:
470 		assert(0);
471 		return (dgettext(TEXT_DOMAIN, "invalid"));
472 	}
473 }
474 
475 int
476 name_to_rd_opt(
477 	char		*uname,
478 	char		*name,
479 	mm_rd_opt_t	*optp,
480 	md_error_t	*ep
481 )
482 {
483 	if (strcasecmp(name, "roundrobin") == 0) {
484 		*optp = RD_LOAD_BAL;
485 		return (0);
486 	}
487 	if (strcasecmp(name, "geometric") == 0) {
488 		*optp = RD_GEOMETRY;
489 		return (0);
490 	}
491 	if (strcasecmp(name, "first") == 0) {
492 		*optp = RD_FIRST;
493 		return (0);
494 	}
495 	return (meta_cook_syntax(ep, MDE_BAD_RD_OPT, uname, 1, &name));
496 }
497 
498 /*
499  * convert write options
500  */
501 char *
502 wr_opt_to_name(
503 	mm_wr_opt_t	opt
504 )
505 {
506 	switch (opt) {
507 	case WR_PARALLEL:
508 		return ("parallel");
509 	case WR_SERIAL:
510 		return ("serial");
511 	default:
512 		assert(0);
513 		return (dgettext(TEXT_DOMAIN, "invalid"));
514 	}
515 }
516 
517 static char *
518 wr_opt_to_opt(
519 	mm_wr_opt_t	opt
520 )
521 {
522 	switch (opt) {
523 	case WR_PARALLEL:
524 		return (NULL);	/* default */
525 	case WR_SERIAL:
526 		return ("-S");
527 	default:
528 		assert(0);
529 		return (dgettext(TEXT_DOMAIN, "invalid"));
530 	}
531 }
532 
533 int
534 name_to_wr_opt(
535 	char		*uname,
536 	char		*name,
537 	mm_wr_opt_t	*optp,
538 	md_error_t	*ep
539 )
540 {
541 	if (strcasecmp(name, "parallel") == 0) {
542 		*optp = WR_PARALLEL;
543 		return (0);
544 	}
545 	if (strcasecmp(name, "serial") == 0) {
546 		*optp = WR_SERIAL;
547 		return (0);
548 	}
549 	return (meta_cook_syntax(ep, MDE_BAD_WR_OPT, uname, 1, &name));
550 }
551 
552 /*
553  * convert pass numbers
554  */
555 int
556 name_to_pass_num(
557 	char		*uname,
558 	char		*name,
559 	mm_pass_num_t	*passp,
560 	md_error_t	*ep
561 )
562 {
563 	if ((sscanf(name, "%hd", passp) != 1) ||
564 	    (*passp < 0) || (*passp > MD_PASS_MAX)) {
565 		return (meta_cook_syntax(ep, MDE_BAD_PASS_NUM,
566 		    uname, 1, &name));
567 	}
568 	return (0);
569 }
570 
571 /*
572  * convert resync option
573  */
574 
575 static char *
576 resync_opt_to_name(
577 	uint_t	tstate
578 )
579 {
580 	if (tstate & MD_ABR_CAP)
581 		return (dgettext(TEXT_DOMAIN, "application based"));
582 	else
583 		return (dgettext(TEXT_DOMAIN, "optimized resync"));
584 }
585 
586 /*
587  * print mirror
588  */
589 static int
590 mirror_print(
591 	md_mirror_t	*mirrorp,
592 	char		*fname,
593 	FILE		*fp,
594 	mdprtopts_t	options,
595 	md_error_t	*ep
596 )
597 {
598 	uint_t		smi;
599 	char		*p;
600 	int		rval = -1;
601 
602 
603 	if (options & PRINT_LARGEDEVICES) {
604 		if ((mirrorp->common.revision & MD_64BIT_META_DEV) == 0) {
605 			rval = 0;
606 			goto out;
607 		}
608 	}
609 
610 	if (options & PRINT_FN) {
611 		if ((mirrorp->common.revision & MD_FN_META_DEV) == 0) {
612 			rval = 0;
613 			goto out;
614 		}
615 	}
616 
617 	/* print name and -m */
618 	if (fprintf(fp, "%s -m", mirrorp->common.namep->cname) == EOF)
619 		goto out;
620 
621 	/* print submirrors */
622 	for (smi = 0; (smi < NMIRROR); ++smi) {
623 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
624 		mdname_t	*submirnamep = mdsp->submirnamep;
625 
626 		/* skip unused submirrors */
627 		if (submirnamep == NULL) {
628 			assert(mdsp->state == SMS_UNUSED);
629 			continue;
630 		}
631 
632 		/* print submirror */
633 		if (fprintf(fp, " %s", submirnamep->rname) == EOF)
634 			goto out;
635 	}
636 
637 	/* print options */
638 	if ((p = rd_opt_to_opt(mirrorp->read_option)) != NULL) {
639 		if (fprintf(fp, " %s", p) == EOF)
640 			goto out;
641 	}
642 	if ((p = wr_opt_to_opt(mirrorp->write_option)) != NULL) {
643 		if (fprintf(fp, " %s", p) == EOF)
644 			goto out;
645 	}
646 	if (fprintf(fp, " %u\n", mirrorp->pass_num) == EOF)
647 		goto out;
648 
649 	/* success */
650 	rval = 0;
651 
652 	/* cleanup, return error */
653 out:
654 	if (rval != 0)
655 		(void) mdsyserror(ep, errno, fname);
656 	return (rval);
657 }
658 
659 /*
660  * convert submirror state to name
661  */
662 char *
663 sm_state_to_name(
664 	md_submirror_t	*mdsp,
665 	md_status_t	mirror_status,
666 	md_timeval32_t	*tvp,
667 	uint_t		tstate
668 )
669 {
670 	static char	state_to_str[100];
671 	sm_state_t	state = mdsp->state;
672 	uint_t		is_target = mdsp->flags & MD_SM_RESYNC_TARGET;
673 
674 	/* grab time */
675 	if (tvp != NULL)
676 		*tvp = mdsp->timestamp;
677 
678 	/*
679 	 * Only return Unavailable if there is no flagged error on the
680 	 * submirror. If the mirror has received any writes since the submirror
681 	 * went into Unavailable state a resync is required. To alert the
682 	 * administrator to this we return a 'Needs maintenance' message.
683 	 */
684 	if ((tstate != 0) && (state & SMS_RUNNING)) {
685 		return (dgettext(TEXT_DOMAIN, "Unavailable"));
686 	}
687 
688 	/* all is well */
689 	if (state & SMS_RUNNING) {
690 		if (!(mirror_status & MD_UN_OPT_NOT_DONE) ||
691 		    ((mirror_status & MD_UN_OPT_NOT_DONE) && !is_target)) {
692 			return (dgettext(TEXT_DOMAIN, "Okay"));
693 		}
694 	}
695 
696 	/* resyncing, needs repair */
697 	if ((state & (SMS_COMP_RESYNC | SMS_ATTACHED_RESYNC |
698 	    SMS_OFFLINE_RESYNC)) ||
699 	    (mirror_status & MD_UN_OPT_NOT_DONE)) {
700 		if (mirror_status & MD_UN_RESYNC_ACTIVE) {
701 			return (dgettext(TEXT_DOMAIN, "Resyncing"));
702 		}
703 		if (mirror_status & MD_UN_RESYNC_CANCEL) {
704 			return (dgettext(TEXT_DOMAIN, "Resync cancelled"));
705 		}
706 		return (dgettext(TEXT_DOMAIN, "Needs maintenance"));
707 	}
708 
709 	/* needs repair */
710 	if (state & (SMS_COMP_ERRED | SMS_ATTACHED | SMS_OFFLINE)) {
711 		if (mirror_status & MD_UN_RESYNC_CANCEL) {
712 			return (dgettext(TEXT_DOMAIN, "Resync cancelled"));
713 		}
714 		return (dgettext(TEXT_DOMAIN, "Needs maintenance"));
715 	}
716 
717 	/* unknown */
718 	assert(0);
719 	(void) sprintf(state_to_str, "0x%x", state);
720 	return (state_to_str);
721 }
722 
723 /*
724  * convert submirror state to repair action
725  */
726 int
727 sm_state_to_action(
728 	mdsetname_t	*sp,
729 	md_submirror_t	*mdsp,
730 	md_status_t	mirror_status,
731 	md_mirror_t	*mirrorp,
732 	char		**actionp,
733 	md_error_t	*ep
734 )
735 {
736 	static char	buf[1024];
737 	mdname_t	*submirnamep = mdsp->submirnamep;
738 	sm_state_t	state = mdsp->state;
739 	char		*miscname;
740 
741 	/* all is well */
742 	*actionp = NULL;
743 	if (mirror_status & MD_UN_RESYNC_ACTIVE)
744 		return (0);
745 	if ((state == SMS_RUNNING) && !(mirror_status & MD_UN_OPT_NOT_DONE))
746 		return (0);
747 
748 	/* complete cancelled resync */
749 	if (mirror_status & MD_UN_RESYNC_CANCEL) {
750 		(void) snprintf(buf, sizeof (buf),
751 		    dgettext(TEXT_DOMAIN, "metasync %s"),
752 		    mirrorp->common.namep->cname);
753 		*actionp = buf;
754 		return (0);
755 	}
756 
757 	/* replace stripe component */
758 	if ((metaismeta(submirnamep)) && (state & SMS_COMP_ERRED)) {
759 		if ((miscname = metagetmiscname(submirnamep, ep)) == NULL)
760 			return (-1);
761 		if (strcmp(miscname, MD_STRIPE) == 0) {
762 			mdname_t	*compnamep;
763 			comp_state_t	compstate;
764 
765 			if (meta_find_erred_comp(sp, submirnamep,
766 			    &compnamep, &compstate, ep) != 0) {
767 				return (-1);
768 			}
769 			if (compstate != CS_LAST_ERRED)
770 				(void) snprintf(buf, sizeof (buf),
771 				    "metareplace %s %s <%s>",
772 				    mirrorp->common.namep->cname,
773 				    compnamep->cname,
774 				    dgettext(TEXT_DOMAIN, "new device"));
775 			else
776 				(void) snprintf(buf, sizeof (buf),
777 				    dgettext(TEXT_DOMAIN,
778 				    "after replacing \"Maintenance\" "
779 				    "components:\n"
780 				    "\t\tmetareplace %s %s <new device>"),
781 				    mirrorp->common.namep->cname,
782 				    compnamep->cname);
783 			*actionp = buf;
784 			return (0);
785 		}
786 	}
787 
788 	/* resync mirror */
789 	if ((state & (SMS_ATTACHED_RESYNC | SMS_OFFLINE_RESYNC |
790 	    SMS_COMP_RESYNC | SMS_ATTACHED)) ||
791 	    (mirror_status & MD_UN_OPT_NOT_DONE)) {
792 		(void) snprintf(buf, sizeof (buf), "metasync %s",
793 		    mirrorp->common.namep->cname);
794 		*actionp = buf;
795 		return (0);
796 	}
797 
798 	/* online submirror */
799 	if (state & SMS_OFFLINE) {
800 		(void) snprintf(buf, sizeof (buf), "metaonline %s %s",
801 		    mirrorp->common.namep->cname, submirnamep->cname);
802 		*actionp = buf;
803 		return (0);
804 	}
805 
806 	/* unknown action */
807 	*actionp = dgettext(TEXT_DOMAIN, "???");
808 	return (0);
809 }
810 
811 /*
812  * print mirror options
813  */
814 int
815 meta_print_mirror_options(
816 	mm_rd_opt_t	read_option,
817 	mm_wr_opt_t	write_option,
818 	mm_pass_num_t	pass_num,
819 	uint_t		tstate,
820 	char		*fname,
821 	mdsetname_t	*sp,
822 	FILE		*fp,
823 	md_error_t	*ep
824 )
825 {
826 	char		*p;
827 	int		rval = -1;
828 
829 	/* print options */
830 	if (fprintf(fp, dgettext(TEXT_DOMAIN, "    Pass: %u\n"),
831 	    pass_num) == EOF) {
832 		goto out;
833 	}
834 	if ((p = rd_opt_to_opt(read_option)) == NULL)
835 		p = dgettext(TEXT_DOMAIN, "default");
836 	if (fprintf(fp, dgettext(TEXT_DOMAIN, "    Read option: %s (%s)\n"),
837 	    rd_opt_to_name(read_option), p) == EOF) {
838 		goto out;
839 	}
840 	if ((p = wr_opt_to_opt(write_option)) == NULL)
841 		p = dgettext(TEXT_DOMAIN, "default");
842 	if (fprintf(fp, dgettext(TEXT_DOMAIN, "    Write option: %s (%s)\n"),
843 	    wr_opt_to_name(write_option), p) == EOF) {
844 		goto out;
845 	}
846 	/* Display resync option for mirror, if MultiNode set */
847 	if (meta_is_mn_set(sp, ep)) {
848 		if (fprintf(fp, dgettext(TEXT_DOMAIN,
849 		    "    Resync option: %s\n"),
850 		    resync_opt_to_name(tstate)) == EOF) {
851 			goto out;
852 		}
853 	}
854 
855 	/* success */
856 	rval = 0;
857 
858 	/* cleanup, return error */
859 out:
860 	if (rval != 0)
861 		(void) mdsyserror(ep, errno, fname);
862 	return (rval);
863 }
864 
865 static char *
866 get_node_name(uint_t nid, md_error_t *ep)
867 {
868 	mndiskset_membershiplist_t	*nl, *p;
869 	int				n;
870 	char				*node_nm;
871 
872 	/* get the known membership list */
873 	if (meta_read_nodelist(&n, &nl, ep)) {
874 		return (NULL);
875 	}
876 
877 	/* find the matching node and return the name */
878 	for (p = nl; (p != NULL); p = p->next) {
879 		if (nid == p->msl_node_id) {
880 			/* match found */
881 			node_nm = Strdup(p->msl_node_name);
882 			goto out;
883 		}
884 	}
885 
886 	/* match not found */
887 	node_nm = Strdup(dgettext(TEXT_DOMAIN, "None"));
888 
889 out:
890 	meta_free_nodelist(nl);
891 	return (node_nm);
892 }
893 
894 /*
895  * report mirror
896  */
897 static int
898 mirror_report(
899 	mdsetname_t	*sp,
900 	md_mirror_t	*mirrorp,
901 	mdnamelist_t	**nlpp,
902 	char		*fname,
903 	FILE		*fp,
904 	mdprtopts_t	options,
905 	md_error_t	*ep
906 )
907 {
908 	md_status_t	status = mirrorp->common.state;
909 	uint_t		smi;
910 	char		*p;
911 	int		rval = -1;
912 	uint_t		tstate = 0;
913 
914 	/*
915 	 * check for the -B option. If -B and the metadevice is
916 	 * a 64 bit device, get the dev for relocation information
917 	 * printout. If not a 64 bit device, just don't print this
918 	 * information out but you need to go down to the subdevice
919 	 * level and print there if appropriate.
920 	 */
921 	if (options & PRINT_LARGEDEVICES) {
922 		if ((mirrorp->common.revision & MD_64BIT_META_DEV) == 0) {
923 			for (smi = 0; (smi < NMIRROR); ++smi) {
924 				md_submirror_t	*mdsp =
925 				    &mirrorp->submirrors[smi];
926 				mdname_t	*submirnamep =
927 				    mdsp->submirnamep;
928 				if (submirnamep == NULL) {
929 					continue;
930 				}
931 				if ((metaismeta(submirnamep)) &&
932 				    (meta_print_name(sp, submirnamep, nlpp,
933 				    fname, fp, options | PRINT_SUBDEVS, NULL,
934 				    ep) != 0)) {
935 					return (-1);
936 				}
937 			}
938 			rval = 0;
939 			goto out;
940 		} else {
941 			if (meta_getdevs(sp, mirrorp->common.namep,
942 			    nlpp, ep) != 0)
943 				goto out;
944 		}
945 	}
946 
947 	/*
948 	 * check for the -D option. If -D and the name is
949 	 * a descriptive name, get the dev for relocation information
950 	 * printout. If not a descriptive name, don't print this
951 	 * information out but you need to go down to the subdevice
952 	 * level and print there if appropriate.
953 	 */
954 	if (options & PRINT_FN) {
955 		if ((mirrorp->common.revision & MD_FN_META_DEV) == 0) {
956 			for (smi = 0; (smi < NMIRROR); ++smi) {
957 				md_submirror_t	*mdsp =
958 				    &mirrorp->submirrors[smi];
959 				mdname_t	*submirnamep =
960 				    mdsp->submirnamep;
961 				if (submirnamep == NULL) {
962 					continue;
963 				}
964 				if ((metaismeta(submirnamep)) &&
965 				    (meta_print_name(sp, submirnamep, nlpp,
966 				    fname, fp, options | PRINT_SUBDEVS, NULL,
967 				    ep) != 0)) {
968 					return (-1);
969 				}
970 			}
971 			rval = 0;
972 			goto out;
973 		} else {
974 			if (meta_getdevs(sp, mirrorp->common.namep,
975 			    nlpp, ep) != 0)
976 				goto out;
977 		}
978 	}
979 
980 	/* print header */
981 	if (options & PRINT_HEADER) {
982 		if (fprintf(fp, dgettext(TEXT_DOMAIN, "%s: Mirror\n"),
983 		    mirrorp->common.namep->cname) == EOF) {
984 			goto out;
985 		}
986 	}
987 
988 	/* print submirrors, adjust status */
989 	for (smi = 0; (smi < NMIRROR); ++smi) {
990 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
991 		mdname_t	*submirnamep = mdsp->submirnamep;
992 		char		*sm_state;
993 		md_timeval32_t	tv;
994 		char		*timep;
995 
996 		/* skip unused submirrors */
997 		if (submirnamep == NULL) {
998 			assert(mdsp->state == SMS_UNUSED);
999 			continue;
1000 		}
1001 
1002 		if (mdsp->state & SMS_OFFLINE)
1003 			status &= ~MD_UN_OPT_NOT_DONE;
1004 
1005 		/* print submirror */
1006 		if (fprintf(fp, dgettext(TEXT_DOMAIN, "    Submirror %u: %s\n"),
1007 		    smi, submirnamep->cname) == EOF) {
1008 			goto out;
1009 		}
1010 
1011 		/* print state */
1012 		if (metaismeta(mdsp->submirnamep)) {
1013 			if (meta_get_tstate(mdsp->submirnamep->dev, &tstate,
1014 			    ep) != 0)
1015 				return (-1);
1016 		}
1017 		sm_state = sm_state_to_name(mdsp, status, &tv,
1018 		    tstate & MD_DEV_ERRORED);
1019 		if (options & PRINT_TIMES) {
1020 			timep = meta_print_time(&tv);
1021 		} else {
1022 			timep = "";
1023 		}
1024 		if (fprintf(fp, dgettext(TEXT_DOMAIN,
1025 		    "      State: %-12s %s\n"),
1026 		    sm_state, timep) == EOF) {
1027 			goto out;
1028 		}
1029 	}
1030 
1031 	/* print resync status */
1032 	if (status & MD_UN_RESYNC_CANCEL) {
1033 		/* Resync was cancelled but is restartable */
1034 		if (mirrorp->common.revision & MD_64BIT_META_DEV) {
1035 			if (fprintf(fp, dgettext(TEXT_DOMAIN,
1036 			    "    Resync cancelled: %2d.%1d %% done\n"),
1037 			    mirrorp->percent_done/10,
1038 			    mirrorp->percent_done%10) == EOF) {
1039 				goto out;
1040 			}
1041 		} else {
1042 			if (fprintf(fp, dgettext(TEXT_DOMAIN,
1043 			    "    Resync cancelled: %d %% done\n"),
1044 			    mirrorp->percent_done) == EOF) {
1045 				goto out;
1046 			}
1047 		}
1048 	} else if (status & MD_UN_RESYNC_ACTIVE) {
1049 		if (mirrorp->common.revision & MD_64BIT_META_DEV) {
1050 			if (fprintf(fp, dgettext(TEXT_DOMAIN,
1051 			    "    Resync in progress: %2d.%1d %% done\n"),
1052 			    mirrorp->percent_done/10,
1053 			    mirrorp->percent_done%10) == EOF) {
1054 				goto out;
1055 			}
1056 		} else {
1057 			if (fprintf(fp, dgettext(TEXT_DOMAIN,
1058 			    "    Resync in progress: %d %% done\n"),
1059 			    mirrorp->percent_done) == EOF) {
1060 				goto out;
1061 			}
1062 		}
1063 	}
1064 
1065 	/* print options */
1066 	if (meta_get_tstate(mirrorp->common.namep->dev, &tstate, ep) != 0)
1067 		return (-1);
1068 
1069 	if (meta_print_mirror_options(mirrorp->read_option,
1070 	    mirrorp->write_option, mirrorp->pass_num,
1071 	    tstate, fname, sp, fp, ep) != 0)
1072 		return (-1);
1073 
1074 	/* print mirror owner for multi-node metadevice */
1075 	if (meta_is_mn_set(sp, ep)) {
1076 		md_set_mmown_params_t	ownpar;
1077 		mdname_t		*mirnp = mirrorp->common.namep;
1078 		char			*node_name;
1079 
1080 		(void) memset(&ownpar, 0, sizeof (ownpar));
1081 		ownpar.d.mnum = meta_getminor(mirnp->dev);
1082 		MD_SETDRIVERNAME(&ownpar, MD_MIRROR, sp->setno);
1083 
1084 		if (metaioctl(MD_MN_GET_MM_OWNER, &ownpar, ep,
1085 		    "MD_MN_GET_MM_OWNER") != 0) {
1086 			return (-1);
1087 		}
1088 
1089 		node_name = get_node_name(ownpar.d.owner, ep);
1090 		if (node_name == NULL)
1091 			return (-1);
1092 		else if (fprintf(fp, dgettext(TEXT_DOMAIN, "    Owner: %s\n"),
1093 		    node_name) == EOF) {
1094 			Free(node_name);
1095 			goto out;
1096 		}
1097 		Free(node_name);
1098 
1099 	}
1100 
1101 	/* print size */
1102 	if (fprintf(fp, dgettext(TEXT_DOMAIN, "    Size: %lld blocks (%s)\n"),
1103 	    mirrorp->common.size,
1104 	    meta_number_to_string(mirrorp->common.size, DEV_BSIZE))
1105 	    == EOF) {
1106 		goto out;
1107 	}
1108 
1109 	/* MD_DEBUG stuff */
1110 	if (options & PRINT_DEBUG) {
1111 		mdname_t	*mirnp = mirrorp->common.namep;
1112 		mm_unit_t	*mm;
1113 		mddb_optloc_t	optloc;
1114 		uint_t		i;
1115 
1116 		/* get real mirror unit */
1117 		if ((mm = (mm_unit_t *)meta_get_mdunit(sp, mirnp, ep))
1118 		    == NULL) {
1119 			return (-1);
1120 		}
1121 		assert(mm->c.un_type == MD_METAMIRROR);
1122 
1123 		/* print dirty regions */
1124 		if (fprintf(fp, dgettext(TEXT_DOMAIN,
1125 "    Regions which are dirty: %d%% (blksize %d num %d)\n"),
1126 		    mirrorp->percent_dirty, mm->un_rrd_blksize,
1127 		    mm->un_rrd_num) == EOF) {
1128 			Free(mm);
1129 			goto out;
1130 		}
1131 
1132 		/* print optimized resync record locations */
1133 		(void) memset(&optloc, 0, sizeof (optloc));
1134 		optloc.recid = mm->un_rr_dirty_recid;
1135 		if (metaioctl(MD_DB_GETOPTLOC, &optloc, ep,
1136 		    "MD_DB_GETOPTLOC") != 0) {
1137 			Free(mm);
1138 			return (-1);
1139 		}
1140 		for (i = 0; (i < ((sizeof optloc.li) / sizeof (optloc.li[0])));
1141 		    ++i) {
1142 			mddb_config_t	dbconf;
1143 			char		*devname;
1144 
1145 			(void) memset(&dbconf, 0, sizeof (dbconf));
1146 			dbconf.c_id = optloc.li[i];
1147 			dbconf.c_setno = sp->setno;
1148 			dbconf.c_subcmd = MDDB_CONFIG_ABS;
1149 			/* Don't need device id information from this ioctl */
1150 			dbconf.c_locator.l_devid = (uint64_t)0;
1151 			dbconf.c_locator.l_devid_flags = 0;
1152 			if (metaioctl(MD_DB_ENDDEV, &dbconf, &dbconf.c_mde,
1153 			    "MD_DB_ENDDEV") != 0) {
1154 				Free(mm);
1155 				return (mdstealerror(ep, &dbconf.c_mde));
1156 			}
1157 			if ((devname = splicename(&dbconf.c_devname))
1158 			    == NULL) {
1159 				devname = Strdup(dgettext(TEXT_DOMAIN,
1160 				    "unknown"));
1161 			}
1162 			if (fprintf(fp, dgettext(TEXT_DOMAIN,
1163 			    "    Resync record[%u]: %d (%s %d %d)\n"), i,
1164 			    optloc.li[i], devname, dbconf.c_locator.l_blkno,
1165 			    (dbconf.c_dbend - dbconf.c_locator.l_blkno + 1))
1166 			    == EOF) {
1167 				Free(mm);
1168 				Free(devname);
1169 				goto out;
1170 			}
1171 			Free(devname);
1172 		}
1173 		Free(mm);
1174 	}
1175 
1176 	/* print submirror details */
1177 	for (smi = 0; (smi < NMIRROR); ++smi) {
1178 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
1179 		mdname_t	*submirnamep = mdsp->submirnamep;
1180 		char		*sm_state;
1181 		md_timeval32_t	tv;
1182 		char		*timep;
1183 		md_stripe_t	*stripep;
1184 
1185 		/* skip unused submirrors */
1186 		if (submirnamep == NULL) {
1187 			assert(mdsp->state == SMS_UNUSED);
1188 			continue;
1189 		}
1190 
1191 		if (options & PRINT_FN) {
1192 			/* get unit structure */
1193 			if ((stripep = meta_get_stripe_common(sp, submirnamep,
1194 			    ((options & PRINT_FAST) ? 1 : 0), ep)) == NULL)
1195 				goto out;
1196 
1197 			if ((stripep->common.revision & MD_FN_META_DEV)
1198 			    == 0)
1199 				continue;
1200 		}
1201 
1202 		/* add extra line */
1203 		if (fprintf(fp, "\n") == EOF)
1204 			goto out;
1205 
1206 		/* print submirror */
1207 		if (fprintf(fp, dgettext(TEXT_DOMAIN,
1208 		    "%s: Submirror of %s\n"),
1209 		    submirnamep->cname,
1210 		    mirrorp->common.namep->cname) == EOF) {
1211 			goto out;
1212 		}
1213 
1214 		/* print state */
1215 		if (metaismeta(mdsp->submirnamep)) {
1216 			if (meta_get_tstate(mdsp->submirnamep->dev, &tstate, ep)
1217 			    != 0)
1218 				return (-1);
1219 		}
1220 		sm_state = sm_state_to_name(mdsp, status, &tv, NULL);
1221 		if (options & PRINT_TIMES) {
1222 			timep = meta_print_time(&tv);
1223 		} else {
1224 			timep = "";
1225 		}
1226 
1227 		if ((tstate & MD_DEV_ERRORED) == 0) {
1228 			if (fprintf(fp, dgettext(TEXT_DOMAIN,
1229 			    "    State: %-12s %s\n"),
1230 			    sm_state, timep) == EOF) {
1231 				goto out;
1232 			}
1233 
1234 			/* print what to do */
1235 			if (sm_state_to_action(sp, mdsp, status,
1236 			    mirrorp, &p, ep) != 0)
1237 				return (-1);
1238 			if ((p != NULL) &&
1239 			    (fprintf(fp, dgettext(TEXT_DOMAIN,
1240 			    "    Invoke: %s\n"), p) == EOF)) {
1241 				goto out;
1242 			}
1243 		}
1244 
1245 		/* print underlying metadevice */
1246 		if ((metaismeta(submirnamep)) &&
1247 		    (meta_print_name(sp, submirnamep, nlpp, fname, fp,
1248 		    ((options & ~PRINT_HEADER) | PRINT_SUBDEVS),
1249 		    NULL, ep) != 0)) {
1250 			return (-1);
1251 		}
1252 	}
1253 
1254 	/* add extra line */
1255 	if (fprintf(fp, "\n") == EOF)
1256 		goto out;
1257 
1258 	/* success */
1259 	rval = 0;
1260 
1261 	/* cleanup, return error */
1262 out:
1263 	if (rval != 0)
1264 		(void) mdsyserror(ep, errno, fname);
1265 	return (rval);
1266 }
1267 
1268 /*
1269  * print/report mirror
1270  */
1271 int
1272 meta_mirror_print(
1273 	mdsetname_t	*sp,
1274 	mdname_t	*mirnp,
1275 	mdnamelist_t	**nlpp,
1276 	char		*fname,
1277 	FILE		*fp,
1278 	mdprtopts_t	options,
1279 	md_error_t	*ep
1280 )
1281 {
1282 	md_mirror_t	*mirrorp;
1283 	uint_t		smi;
1284 
1285 	/* should have same set */
1286 	assert(sp != NULL);
1287 	assert((mirnp == NULL) ||
1288 	    (sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))));
1289 
1290 	/* print all mirrors */
1291 	if (mirnp == NULL) {
1292 		mdnamelist_t	*nlp = NULL;
1293 		mdnamelist_t	*p;
1294 		int		cnt;
1295 		int		rval = 0;
1296 
1297 		/* get list */
1298 		if ((cnt = meta_get_mirror_names(sp, &nlp, options, ep)) < 0)
1299 			return (-1);
1300 		else if (cnt == 0)
1301 			return (0);
1302 
1303 		/* recurse */
1304 		for (p = nlp; (p != NULL); p = p->next) {
1305 			mdname_t	*np = p->namep;
1306 
1307 			if (meta_mirror_print(sp, np, nlpp, fname, fp,
1308 			    options, ep) != 0)
1309 				rval = -1;
1310 		}
1311 
1312 		/* cleanup, return success */
1313 		metafreenamelist(nlp);
1314 		return (rval);
1315 	}
1316 
1317 	/* get unit structure */
1318 	if ((mirrorp = meta_get_mirror_common(sp, mirnp,
1319 	    ((options & PRINT_FAST) ? 1 : 0), ep)) == NULL)
1320 		return (-1);
1321 
1322 	/* check for parented */
1323 	if ((! (options & PRINT_SUBDEVS)) &&
1324 	    (MD_HAS_PARENT(mirrorp->common.parent))) {
1325 		return (0);
1326 	}
1327 
1328 	/* print appropriate detail */
1329 	if (options & PRINT_SHORT) {
1330 		/* print mirror */
1331 		if (mirror_print(mirrorp, fname, fp, options, ep) != 0)
1332 			return (-1);
1333 
1334 		/* print underlying metadevices */
1335 		for (smi = 0; (smi < NMIRROR); ++smi) {
1336 			md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
1337 			mdname_t	*submirnamep = mdsp->submirnamep;
1338 
1339 			/* skip unused submirrors */
1340 			if (submirnamep == NULL) {
1341 				assert(mdsp->state == SMS_UNUSED);
1342 				continue;
1343 			}
1344 
1345 			/* print submirror */
1346 			if (metaismeta(submirnamep)) {
1347 				if (meta_print_name(sp, submirnamep, nlpp,
1348 				    fname, fp, (options | PRINT_SUBDEVS), NULL,
1349 				    ep) != 0) {
1350 					return (-1);
1351 				}
1352 			}
1353 		}
1354 
1355 		/* return success */
1356 		return (0);
1357 	} else {
1358 		return (mirror_report(sp, mirrorp, nlpp, fname, fp,
1359 		    options, ep));
1360 	}
1361 }
1362 
1363 /*
1364  * online submirror
1365  */
1366 int
1367 meta_mirror_online(
1368 	mdsetname_t	*sp,
1369 	mdname_t	*mirnp,
1370 	mdname_t	*submirnp,
1371 	mdcmdopts_t	options,
1372 	md_error_t	*ep
1373 )
1374 {
1375 	md_i_off_on_t	mio;
1376 	md_mirror_t	*mirrorp;
1377 	md_set_desc	*sd;
1378 	uint_t		tstate;
1379 
1380 	/* should have same set */
1381 	assert(sp != NULL);
1382 	assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)));
1383 
1384 	/* check name */
1385 	if (metachkmeta(mirnp, ep) != 0)
1386 		return (-1);
1387 
1388 	if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL)
1389 		return (-1);
1390 
1391 	/* Only valid for mirror without ABR set */
1392 	if (meta_get_tstate(mirrorp->common.namep->dev, &tstate, ep) != 0)
1393 		return (-1);
1394 	if (tstate & MD_ABR_CAP) {
1395 		(void) mderror(ep, MDE_ABR_SET, NULL);
1396 		return (-1);
1397 	}
1398 
1399 	/*
1400 	 * In a MN set, the master always executes the online command first.
1401 	 * Before the master executes the IOC_ONLINE ioctl,
1402 	 * the master sends a message to all nodes to suspend writes to
1403 	 * this mirror.  Then the master executes the IOC_ONLINE ioctl
1404 	 * which resumes writes to this mirror from the master node.
1405 	 * As each slave executes the online command, each slave will
1406 	 * call the IOC_ONLINE ioctl which will resume writes to this mirror
1407 	 * from that slave node.
1408 	 */
1409 	if (! metaislocalset(sp)) {
1410 		if ((sd = metaget_setdesc(sp, ep)) == NULL)
1411 			return (-1);
1412 		if ((MD_MNSET_DESC(sd)) && sd->sd_mn_am_i_master)
1413 			if (meta_mn_send_suspend_writes(
1414 			    meta_getminor(mirnp->dev), ep) != 0)
1415 				return (-1);
1416 	}
1417 
1418 	/* online submirror */
1419 	(void) memset(&mio, 0, sizeof (mio));
1420 	mio.mnum = meta_getminor(mirnp->dev);
1421 	MD_SETDRIVERNAME(&mio, MD_MIRROR, sp->setno);
1422 	mio.submirror = submirnp->dev;
1423 	if (metaioctl(MD_IOCONLINE, &mio, &mio.mde, NULL) != 0)
1424 		return (mdstealerror(ep, &mio.mde));
1425 
1426 	/* clear cache */
1427 	meta_invalidate_name(mirnp);
1428 	meta_invalidate_name(submirnp);
1429 
1430 	/* let em know */
1431 	if (options & MDCMD_PRINT) {
1432 		(void) printf(dgettext(TEXT_DOMAIN,
1433 		    "%s: submirror %s is onlined\n"),
1434 		    mirnp->cname, submirnp->cname);
1435 		(void) fflush(stdout);
1436 	}
1437 
1438 	/* return success */
1439 	return (0);
1440 }
1441 
1442 /*
1443  * offline submirror
1444  */
1445 int
1446 meta_mirror_offline(
1447 	mdsetname_t	*sp,
1448 	mdname_t	*mirnp,
1449 	mdname_t	*submirnp,
1450 	mdcmdopts_t	options,
1451 	md_error_t	*ep
1452 )
1453 {
1454 	int		force = ((options & MDCMD_FORCE) ? 1 : 0);
1455 	md_i_off_on_t	mio;
1456 	md_mirror_t	*mirrorp;
1457 	md_set_desc	*sd;
1458 	uint_t		tstate;
1459 
1460 	/* should have same set */
1461 	assert(sp != NULL);
1462 	assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)));
1463 
1464 	/* check name */
1465 	if (metachkmeta(mirnp, ep) != 0)
1466 		return (-1);
1467 
1468 	if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL)
1469 		return (-1);
1470 
1471 	/* Only valid for mirror without ABR set */
1472 	if (meta_get_tstate(mirrorp->common.namep->dev, &tstate, ep) != 0)
1473 		return (-1);
1474 	if (tstate & MD_ABR_CAP) {
1475 		(void) mderror(ep, MDE_ABR_SET, NULL);
1476 		return (-1);
1477 	}
1478 
1479 	/*
1480 	 * In a MN set, the master always executes the offline command first.
1481 	 * Before the master executes the IOC_OFFLINE ioctl,
1482 	 * the master sends a message to all nodes to suspend writes to
1483 	 * this mirror.  Then the master executes the IOC_OFFLINE ioctl
1484 	 * which resumes writes to this mirror from the master node.
1485 	 * As each slave executes the offline command, each slave will
1486 	 * call the IOC_OFFLINE ioctl which will resume writes to this mirror
1487 	 * from that slave node.
1488 	 */
1489 	if (! metaislocalset(sp)) {
1490 		if ((sd = metaget_setdesc(sp, ep)) == NULL)
1491 			return (-1);
1492 		if ((MD_MNSET_DESC(sd)) && sd->sd_mn_am_i_master)
1493 			if (meta_mn_send_suspend_writes(
1494 			    meta_getminor(mirnp->dev), ep) != 0)
1495 				return (-1);
1496 	}
1497 
1498 	/* offline submirror */
1499 	(void) memset(&mio, 0, sizeof (mio));
1500 	mio.mnum = meta_getminor(mirnp->dev);
1501 	MD_SETDRIVERNAME(&mio, MD_MIRROR, sp->setno);
1502 	mio.submirror = submirnp->dev;
1503 	mio.force_offline = force;
1504 	if (metaioctl(MD_IOCOFFLINE, &mio, &mio.mde, NULL) != 0)
1505 		return (mdstealerror(ep, &mio.mde));
1506 
1507 	/* clear cache */
1508 	meta_invalidate_name(mirnp);
1509 	meta_invalidate_name(submirnp);
1510 
1511 	/* let em know */
1512 	if (options & MDCMD_PRINT) {
1513 		(void) printf(dgettext(TEXT_DOMAIN,
1514 		    "%s: submirror %s is offlined\n"),
1515 		    mirnp->cname, submirnp->cname);
1516 		(void) fflush(stdout);
1517 	}
1518 
1519 	/* return success */
1520 	return (0);
1521 }
1522 
1523 /*
1524  * attach submirror to mirror
1525  * we actually never have to worry about crossing a thresh hold here.
1526  * 2 cases 1) attach and the only way the mirror can be 64 bit is if
1527  * one of the submirrors already is. 2) grow and the only way the mirror
1528  * is 64 bit is if one of the submirror's already is.
1529  */
1530 int
1531 meta_mirror_attach(
1532 	mdsetname_t	*sp,
1533 	mdname_t	*mirnp,
1534 	mdname_t	*submirnp,
1535 	mdcmdopts_t	options,
1536 	md_error_t	*ep
1537 )
1538 {
1539 	md_att_struct_t	att;
1540 	md_set_desc		*sd;
1541 
1542 	/* should have same set */
1543 	assert(sp != NULL);
1544 	assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)));
1545 
1546 	/* check name */
1547 	if (metachkmeta(mirnp, ep) != 0)
1548 		return (-1);
1549 
1550 	/* just grow */
1551 	if (submirnp == NULL) {
1552 		return (meta_concat_generic(sp, mirnp, NULL, ep));
1553 	}
1554 
1555 	/* check submirror */
1556 	if (meta_check_submirror(sp, submirnp, mirnp, 0, ep) != 0)
1557 		return (-1);
1558 
1559 	/* In dryrun mode (DOIT not set) we must not alter the mddb */
1560 	if (options & MDCMD_DOIT) {
1561 		/* store name in namespace */
1562 		if (add_key_name(sp, submirnp, NULL, ep) != 0)
1563 			return (-1);
1564 	}
1565 
1566 	/*
1567 	 * In a MN set, the master always executes the attach command first.
1568 	 * Before the master executes the IOC_ATTACH ioctl, in non-DRYRUN mode
1569 	 * the master sends a message to all nodes to suspend writes to
1570 	 * this mirror.  Then the master executes the IOC_ATTACH ioctl
1571 	 * which resumes writes to this mirror from the master node.
1572 	 * As each slave executes the attach command, each slave will
1573 	 * call the IOC_ATTACH ioctl which will resume writes to this mirror
1574 	 * from that slave node.
1575 	 */
1576 	if (! metaislocalset(sp)) {
1577 		if ((sd = metaget_setdesc(sp, ep)) == NULL)
1578 			return (-1);
1579 		if ((MD_MNSET_DESC(sd)) && (options & MDCMD_DOIT) &&
1580 		    sd->sd_mn_am_i_master)
1581 			if (meta_mn_send_suspend_writes(
1582 			    meta_getminor(mirnp->dev), ep) != 0)
1583 				return (-1);
1584 	}
1585 
1586 	/* attach submirror */
1587 	(void) memset(&att, 0, sizeof (att));
1588 	att.mnum = meta_getminor(mirnp->dev);
1589 	MD_SETDRIVERNAME(&att, MD_MIRROR, sp->setno);
1590 	att.submirror = submirnp->dev;
1591 	att.key = submirnp->key;
1592 	/* if the comamnd was issued with -n option, use dryrun mode */
1593 	if ((options & MDCMD_DOIT) == 0) {
1594 		att.options = MDIOCTL_DRYRUN;
1595 	}
1596 	if (metaioctl(MD_IOCATTACH, &att, &att.mde, NULL) != 0) {
1597 		/* In dryrun mode (DOIT not set) we must not alter the mddb */
1598 		if (options & MDCMD_DOIT) {
1599 			(void) del_key_name(sp, submirnp, ep);
1600 		}
1601 		return (mdstealerror(ep, &att.mde));
1602 	}
1603 
1604 	/* In dryrun mode (DOIT not set) we must not alter the mddb */
1605 	if (options & MDCMD_DOIT) {
1606 		/* clear cache */
1607 		meta_invalidate_name(mirnp);
1608 		meta_invalidate_name(submirnp);
1609 	}
1610 
1611 	/* let em know */
1612 	if (options & MDCMD_PRINT) {
1613 		(void) printf(dgettext(TEXT_DOMAIN,
1614 		    "%s: submirror %s %s\n"), mirnp->cname, submirnp->cname,
1615 		    (options & MDCMD_DOIT) ? "is attached" : "would attach");
1616 		(void) fflush(stdout);
1617 	}
1618 
1619 	/* return success */
1620 	return (0);
1621 }
1622 
1623 /*
1624  * detach submirror
1625  */
1626 int
1627 meta_mirror_detach(
1628 	mdsetname_t		*sp,
1629 	mdname_t		*mirnp,
1630 	mdname_t		*submirnp,
1631 	mdcmdopts_t		options,
1632 	md_error_t		*ep
1633 )
1634 {
1635 	int			force = ((options & MDCMD_FORCE) ? 1 : 0);
1636 	md_detach_params_t	detach;
1637 	md_set_desc		*sd;
1638 
1639 	/* should have same set */
1640 	assert(sp != NULL);
1641 	assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)));
1642 
1643 	/* check name */
1644 	if (metachkmeta(mirnp, ep) != 0)
1645 		return (-1);
1646 
1647 	/*
1648 	 * In a MN set, the master always executes the detach command first.
1649 	 * Before the master executes the IOC_DETACH ioctl,
1650 	 * the master sends a message to all nodes to suspend writes to
1651 	 * this mirror.  Then the master executes the IOC_DETACH ioctl
1652 	 * which resumes writes to this mirror from the master node.
1653 	 * As each slave executes the detach command, each slave will
1654 	 * call the IOC_DETACH ioctl which will resume writes to this mirror
1655 	 * from that slave node.
1656 	 */
1657 	if (! metaislocalset(sp)) {
1658 		if ((sd = metaget_setdesc(sp, ep)) == NULL)
1659 			return (-1);
1660 		if ((MD_MNSET_DESC(sd)) && sd->sd_mn_am_i_master)
1661 			if (meta_mn_send_suspend_writes(
1662 			    meta_getminor(mirnp->dev), ep) != 0)
1663 				return (-1);
1664 	}
1665 
1666 	/* detach submirror */
1667 	(void) memset(&detach, 0, sizeof (detach));
1668 	detach.mnum = meta_getminor(mirnp->dev);
1669 	MD_SETDRIVERNAME(&detach, MD_MIRROR, sp->setno);
1670 	detach.submirror = submirnp->dev;
1671 	detach.force_detach = force;
1672 	if (metaioctl(MD_IOCDETACH, &detach, &detach.mde, NULL) != 0)
1673 		return (mdstealerror(ep, &detach.mde));
1674 
1675 	/* clear cache */
1676 	meta_invalidate_name(mirnp);
1677 	meta_invalidate_name(submirnp);
1678 
1679 	/* let em know */
1680 	if (options & MDCMD_PRINT) {
1681 		(void) printf(dgettext(TEXT_DOMAIN,
1682 		    "%s: submirror %s is detached\n"),
1683 		    mirnp->cname, submirnp->cname);
1684 		(void) fflush(stdout);
1685 	}
1686 
1687 	/* return success */
1688 	return (0);
1689 }
1690 
1691 /*
1692  * get mirror parameters
1693  */
1694 int
1695 meta_mirror_get_params(
1696 	mdsetname_t	*sp,
1697 	mdname_t	*mirnp,
1698 	mm_params_t	*paramsp,
1699 	md_error_t	*ep
1700 )
1701 {
1702 	md_mirror_t	*mirrorp;
1703 
1704 	/* should have a set */
1705 	assert(sp != NULL);
1706 	assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)));
1707 
1708 	/* check name */
1709 	if (metachkmeta(mirnp, ep) != 0)
1710 		return (-1);
1711 
1712 	/* get unit */
1713 	if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL)
1714 		return (-1);
1715 
1716 	/* return parameters */
1717 	(void) memset(paramsp, 0, sizeof (*paramsp));
1718 	paramsp->read_option = mirrorp->read_option;
1719 	paramsp->write_option = mirrorp->write_option;
1720 	paramsp->pass_num = mirrorp->pass_num;
1721 	return (0);
1722 }
1723 
1724 /*
1725  * set mirror parameters
1726  */
1727 int
1728 meta_mirror_set_params(
1729 	mdsetname_t		*sp,
1730 	mdname_t		*mirnp,
1731 	mm_params_t		*paramsp,
1732 	md_error_t		*ep
1733 )
1734 {
1735 	md_mirror_params_t	mmp;
1736 
1737 	/* should have a set */
1738 	assert(sp != NULL);
1739 	assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)));
1740 
1741 	/* check name */
1742 	if (metachkmeta(mirnp, ep) != 0)
1743 		return (-1);
1744 
1745 	/* set parameters */
1746 	(void) memset(&mmp, 0, sizeof (mmp));
1747 	MD_SETDRIVERNAME(&mmp, MD_MIRROR, sp->setno);
1748 	mmp.mnum = meta_getminor(mirnp->dev);
1749 	mmp.params = *paramsp;
1750 	if (metaioctl(MD_IOCCHANGE, &mmp, &mmp.mde, mirnp->cname) != 0)
1751 		return (mdstealerror(ep, &mmp.mde));
1752 
1753 	/* clear cache */
1754 	meta_invalidate_name(mirnp);
1755 
1756 	/* return success */
1757 	return (0);
1758 }
1759 
1760 /*
1761  * invalidate submirror names
1762  */
1763 static int
1764 invalidate_submirrors(
1765 	mdsetname_t	*sp,
1766 	mdname_t	*mirnp,
1767 	md_error_t	*ep
1768 )
1769 {
1770 	md_mirror_t	*mirrorp;
1771 	uint_t		smi;
1772 
1773 	if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL)
1774 		return (-1);
1775 	for (smi = 0; (smi < NMIRROR); ++smi) {
1776 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
1777 		mdname_t	*submirnp = mdsp->submirnamep;
1778 
1779 		if (submirnp == NULL) {
1780 			assert(mdsp->state == SMS_UNUSED);
1781 			continue;
1782 		}
1783 		meta_invalidate_name(submirnp);
1784 	}
1785 	return (0);
1786 }
1787 
1788 /*
1789  * replace mirror component
1790  */
1791 int
1792 meta_mirror_replace(
1793 	mdsetname_t		*sp,
1794 	mdname_t		*mirnp,
1795 	mdname_t		*oldnp,
1796 	mdname_t		*newnp,
1797 	mdcmdopts_t		options,
1798 	md_error_t		*ep
1799 )
1800 {
1801 	md_mirror_t		*mirrorp;
1802 	uint_t			smi;
1803 	replace_params_t	params;
1804 	diskaddr_t		size, label, start_blk;
1805 	md_dev64_t		old_dev, new_dev;
1806 	diskaddr_t		new_start_blk, new_end_blk;
1807 	int			rebind;
1808 	md_set_desc		*sd;
1809 	char			*new_devidp = NULL;
1810 	int			ret;
1811 	md_error_t		xep = mdnullerror;
1812 
1813 	/* should have same set */
1814 	assert(sp != NULL);
1815 	assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)));
1816 
1817 	/* check name */
1818 	if (metachkmeta(mirnp, ep) != 0)
1819 		return (-1);
1820 
1821 	/* save new binding incase this is a rebind where oldnp==newnp */
1822 	new_dev = newnp->dev;
1823 	new_start_blk = newnp->start_blk;
1824 	new_end_blk = newnp->end_blk;
1825 
1826 	/* invalidate, then get the mirror (fill in oldnp from metadb) */
1827 	meta_invalidate_name(mirnp);
1828 	if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL)
1829 		return (-1);
1830 	for (smi = 0; (smi < NMIRROR); ++smi) {
1831 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
1832 		mdname_t	*submirnp = mdsp->submirnamep;
1833 
1834 		if (submirnp == NULL) {
1835 			assert(mdsp->state == SMS_UNUSED);
1836 			continue;
1837 		}
1838 
1839 		if (! metaismeta(submirnp))
1840 			continue;
1841 
1842 		meta_invalidate_name(submirnp);
1843 		if (meta_get_unit(sp, submirnp, ep) == NULL)
1844 			return (-1);
1845 	}
1846 
1847 	/* the old device binding is now established */
1848 	if ((old_dev = oldnp->dev) == NODEV64)
1849 		return (mdsyserror(ep, ENODEV, oldnp->cname));
1850 
1851 	/*
1852 	 * check for the case where oldnp and newnp indicate the same
1853 	 * device, but the dev_t of the device has changed between old
1854 	 * and new.  This is called a rebind.  On entry the dev_t
1855 	 * represents the new device binding determined from the
1856 	 * filesystem (meta_getdev). After calling meta_get_unit
1857 	 * oldnp (and maybe newnp if this is a rebind) is updated based
1858 	 * to the old binding from the metadb (done by metakeyname).
1859 	 */
1860 	if ((strcmp(oldnp->rname, newnp->rname) == 0) &&
1861 	    (old_dev != new_dev)) {
1862 		rebind = 1;
1863 	} else {
1864 		rebind = 0;
1865 	}
1866 	if (rebind) {
1867 		newnp->dev = new_dev;
1868 		newnp->start_blk = new_start_blk;
1869 		newnp->end_blk = new_end_blk;
1870 	}
1871 
1872 	/*
1873 	 * Save a copy of the devid associated with the new disk, the reason
1874 	 * is that if we are rebinding then the call to meta_check_component()
1875 	 * will cause the devid of the disk to be overwritten with what is in
1876 	 * the replica namespace. The function that actually overwrites the
1877 	 * devid is dr2drivedesc().
1878 	 */
1879 	if (newnp->drivenamep->devid != NULL)
1880 		new_devidp = Strdup(newnp->drivenamep->devid);
1881 
1882 	/* if it's a multi-node diskset clear new_devidp */
1883 	if (!metaislocalset(sp)) {
1884 		if ((sd = metaget_setdesc(sp, ep)) == NULL)
1885 			return (-1);
1886 		if (MD_MNSET_DESC(sd))
1887 			new_devidp = NULL;
1888 	}
1889 
1890 	/* check it out (dup on rebind is ok) */
1891 	if (meta_check_component(sp, newnp, 0, ep) != 0) {
1892 		if ((! rebind) || (! mdisuseerror(ep, MDE_ALREADY))) {
1893 			Free(new_devidp);
1894 			return (-1);
1895 		}
1896 		mdclrerror(ep);
1897 	}
1898 	if ((size = metagetsize(newnp, ep)) == MD_DISKADDR_ERROR) {
1899 		Free(new_devidp);
1900 		return (-1);
1901 	}
1902 	if ((label = metagetlabel(newnp, ep)) == MD_DISKADDR_ERROR) {
1903 		Free(new_devidp);
1904 		return (-1);
1905 	}
1906 	if ((start_blk = metagetstart(sp, newnp, ep)) == MD_DISKADDR_ERROR) {
1907 		Free(new_devidp);
1908 		return (-1);
1909 	}
1910 	if (start_blk >= size) {
1911 		(void) mdsyserror(ep, ENOSPC, newnp->cname);
1912 		Free(new_devidp);
1913 		return (-1);
1914 	}
1915 
1916 	/*
1917 	 * Copy back the saved devid.
1918 	 */
1919 	Free(newnp->drivenamep->devid);
1920 	if (new_devidp != NULL) {
1921 		newnp->drivenamep->devid = Strdup(new_devidp);
1922 		Free(new_devidp);
1923 	}
1924 
1925 	/* store name in namespace, allocate new key */
1926 	if (add_key_name(sp, newnp, NULL, ep) != 0)
1927 		return (-1);
1928 
1929 	/*
1930 	 * In a MN set, the master always executes the replace command first.
1931 	 * Before the master executes the IOC_REPLACE ioctl, in non-DRYRUN mode
1932 	 * the master sends a message to all nodes to suspend writes to
1933 	 * this mirror.  Then the master executes the IOC_REPLACE ioctl
1934 	 * which resumes writes to this mirror from the master node.
1935 	 * As each slave executes the replace command, each slave will
1936 	 * call the IOC_REPLACE ioctl which will resume writes to this mirror
1937 	 * from that slave node.
1938 	 */
1939 	if (! metaislocalset(sp)) {
1940 		if ((MD_MNSET_DESC(sd)) && (options & MDCMD_DOIT) &&
1941 		    sd->sd_mn_am_i_master)
1942 			if (meta_mn_send_suspend_writes(
1943 			    meta_getminor(mirnp->dev), ep) != 0)
1944 				return (-1);
1945 	}
1946 
1947 	if (rebind && !metaislocalset(sp)) {
1948 		/*
1949 		 * We are 'rebind'ing a disk that is in a diskset so as well
1950 		 * as updating the diskset's namespace the local set needs
1951 		 * to be updated because it also contains a reference to
1952 		 * the disk in question.
1953 		 */
1954 		ret = meta_fixdevid(sp, DEV_UPDATE|DEV_LOCAL_SET,
1955 		    newnp->cname, ep);
1956 
1957 		if (ret != METADEVADM_SUCCESS) {
1958 			(void) del_key_name(sp, newnp, &xep);
1959 			return (-1);
1960 		}
1961 	}
1962 
1963 	/* replace component */
1964 	(void) memset(&params, 0, sizeof (params));
1965 	params.mnum = meta_getminor(mirnp->dev);
1966 	MD_SETDRIVERNAME(&params, MD_MIRROR, sp->setno);
1967 	params.cmd = REPLACE_COMP;
1968 	params.old_dev = old_dev;
1969 	params.new_dev = new_dev;
1970 	params.start_blk = start_blk;
1971 	params.has_label = ((label > 0) ? 1 : 0);
1972 	params.number_blks = size;
1973 	params.new_key = newnp->key;
1974 	/* Is this just a dryrun ? */
1975 	if ((options & MDCMD_DOIT) == 0) {
1976 		params.options |= MDIOCTL_DRYRUN;
1977 	}
1978 	if (metaioctl(MD_IOCREPLACE, &params, &params.mde, NULL) != 0) {
1979 		(void) del_key_name(sp, newnp, ep);
1980 		return (mdstealerror(ep, &params.mde));
1981 	}
1982 
1983 	/* clear cache */
1984 	meta_invalidate_name(oldnp);
1985 	meta_invalidate_name(newnp);
1986 	if (invalidate_submirrors(sp, mirnp, ep) != 0) {
1987 		meta_invalidate_name(mirnp);
1988 		return (-1);
1989 	}
1990 	meta_invalidate_name(mirnp);
1991 
1992 	/* let em know */
1993 	if (options & MDCMD_PRINT) {
1994 		(void) printf(dgettext(TEXT_DOMAIN,
1995 		    "%s: device %s is replaced with %s\n"),
1996 		    mirnp->cname, oldnp->cname, newnp->cname);
1997 		(void) fflush(stdout);
1998 	}
1999 
2000 	/* return success */
2001 	return (0);
2002 }
2003 
2004 /*
2005  * enable mirror component
2006  */
2007 int
2008 meta_mirror_enable(
2009 	mdsetname_t		*sp,
2010 	mdname_t		*mirnp,
2011 	mdname_t		*compnp,
2012 	mdcmdopts_t		options,
2013 	md_error_t		*ep
2014 )
2015 {
2016 	md_mirror_t		*mirrorp;
2017 	uint_t			smi;
2018 	replace_params_t	params;
2019 	diskaddr_t		size, label, start_blk;
2020 	md_dev64_t		fs_dev;
2021 	md_set_desc		*sd;
2022 	int			ret;
2023 
2024 	/* should have same set */
2025 	assert(sp != NULL);
2026 	assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)));
2027 
2028 	/* check name */
2029 	if (metachkmeta(mirnp, ep) != 0)
2030 		return (-1);
2031 
2032 	/* get the file_system dev binding */
2033 	if (meta_getdev(sp, compnp, ep) != 0)
2034 		return (-1);
2035 	fs_dev = compnp->dev;
2036 
2037 	/* get the mirror unit (fill in compnp->dev with metadb version) */
2038 	meta_invalidate_name(mirnp);
2039 	if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL)
2040 		return (-1);
2041 
2042 	for (smi = 0; (smi < NMIRROR); ++smi) {
2043 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
2044 		mdname_t	*submirnp = mdsp->submirnamep;
2045 
2046 		if (submirnp == NULL) {
2047 			assert(mdsp->state == SMS_UNUSED);
2048 			continue;
2049 		}
2050 
2051 		if (! metaismeta(submirnp))
2052 			continue;
2053 
2054 		meta_invalidate_name(submirnp);
2055 		if (meta_get_unit(sp, submirnp, ep) == NULL)
2056 			return (-1);
2057 	}
2058 
2059 	/* the metadb device binding is now established */
2060 	if (compnp->dev == NODEV64)
2061 		return (mdsyserror(ep, ENODEV, compnp->cname));
2062 
2063 	/*
2064 	 * check for the case where the dev_t has changed between the
2065 	 * filesystem and the metadb.  This is called a rebind, and
2066 	 * is handled by meta_mirror_replace.
2067 	 */
2068 	if (fs_dev != compnp->dev) {
2069 		/* establish file system binding with invalid start/end */
2070 		compnp->dev = fs_dev;
2071 		compnp->start_blk = -1;
2072 		compnp->end_blk = -1;
2073 		return (meta_mirror_replace(sp, mirnp,
2074 		    compnp, compnp, options, ep));
2075 	}
2076 
2077 	/* setup mirror info */
2078 	(void) memset(&params, 0, sizeof (params));
2079 	params.mnum = meta_getminor(mirnp->dev);
2080 	MD_SETDRIVERNAME(&params, MD_MIRROR, sp->setno);
2081 	params.cmd = ENABLE_COMP;
2082 
2083 	/* check it out */
2084 	if (meta_check_component(sp, compnp, 0, ep) != 0) {
2085 		if (! mdisuseerror(ep, MDE_ALREADY))
2086 			return (-1);
2087 		mdclrerror(ep);
2088 	}
2089 
2090 	if ((size = metagetsize(compnp, ep)) == MD_DISKADDR_ERROR)
2091 		return (-1);
2092 	if ((label = metagetlabel(compnp, ep)) == MD_DISKADDR_ERROR)
2093 		return (-1);
2094 	if ((start_blk = metagetstart(sp, compnp, ep)) == MD_DISKADDR_ERROR)
2095 		return (-1);
2096 	if (start_blk >= size) {
2097 		(void) mdsyserror(ep, ENOSPC, compnp->cname);
2098 		return (-1);
2099 	}
2100 
2101 	/*
2102 	 * In a MN set, the master always executes the replace command first.
2103 	 * Before the master executes the IOC_REPLACE ioctl, in non-DRYRUN mode
2104 	 * the master sends a message to all nodes to suspend writes to
2105 	 * this mirror.  Then the master executes the IOC_REPLACE ioctl
2106 	 * which resumes writes to this mirror from the master node.
2107 	 * As each slave executes the replace command, each slave will
2108 	 * call the IOC_REPLACE ioctl which will resume writes to this mirror
2109 	 * from that slave node.
2110 	 */
2111 	if (! metaislocalset(sp)) {
2112 		if ((sd = metaget_setdesc(sp, ep)) == NULL)
2113 			return (-1);
2114 		if ((MD_MNSET_DESC(sd)) && (options & MDCMD_DOIT) &&
2115 		    sd->sd_mn_am_i_master)
2116 			if (meta_mn_send_suspend_writes(
2117 			    meta_getminor(mirnp->dev), ep) != 0)
2118 				return (-1);
2119 	}
2120 
2121 	/* enable component */
2122 	params.old_dev = compnp->dev;
2123 	params.new_dev = compnp->dev;
2124 	params.start_blk = start_blk;
2125 	params.has_label = ((label > 0) ? 1 : 0);
2126 	params.number_blks = size;
2127 
2128 	/* Is this just a dryrun ? */
2129 	if ((options & MDCMD_DOIT) == 0) {
2130 		params.options |= MDIOCTL_DRYRUN;
2131 	}
2132 	if (metaioctl(MD_IOCREPLACE, &params, &params.mde, NULL) != 0)
2133 		return (mdstealerror(ep, &params.mde));
2134 
2135 	/*
2136 	 * Are we dealing with a non-local set? If so need to update the
2137 	 * local namespace so that the disk record has the correct devid.
2138 	 */
2139 	if (!metaislocalset(sp)) {
2140 		ret = meta_fixdevid(sp, DEV_UPDATE|DEV_LOCAL_SET, compnp->cname,
2141 		    ep);
2142 
2143 		if (ret != METADEVADM_SUCCESS) {
2144 			/*
2145 			 * Failed to update the local set. Nothing to do here
2146 			 * apart from report the error. The namespace is
2147 			 * most likely broken and some form of remedial
2148 			 * recovery is going to be required.
2149 			 */
2150 			mde_perror(ep, "");
2151 			mdclrerror(ep);
2152 		}
2153 	}
2154 
2155 	/* clear cache */
2156 	meta_invalidate_name(compnp);
2157 	if (invalidate_submirrors(sp, mirnp, ep) != 0) {
2158 		meta_invalidate_name(mirnp);
2159 		return (-1);
2160 	}
2161 	meta_invalidate_name(mirnp);
2162 
2163 	/* let em know */
2164 	if (options & MDCMD_PRINT) {
2165 		(void) printf(dgettext(TEXT_DOMAIN,
2166 		    "%s: device %s is enabled\n"),
2167 		    mirnp->cname, compnp->cname);
2168 		(void) fflush(stdout);
2169 	}
2170 
2171 	/* return success */
2172 	return (0);
2173 }
2174 
2175 /*
2176  * check for dups in the mirror itself
2177  */
2178 static int
2179 check_twice(
2180 	md_mirror_t	*mirrorp,
2181 	uint_t		smi,
2182 	md_error_t	*ep
2183 )
2184 {
2185 	mdname_t	*mirnp = mirrorp->common.namep;
2186 	mdname_t	*thisnp;
2187 	uint_t		s;
2188 
2189 	thisnp = mirrorp->submirrors[smi].submirnamep;
2190 	for (s = 0; (s < smi); ++s) {
2191 		md_submirror_t	*mdsp = &mirrorp->submirrors[s];
2192 		mdname_t	*submirnp = mdsp->submirnamep;
2193 
2194 		if (submirnp == NULL)
2195 			continue;
2196 
2197 		if (meta_check_overlap(mirnp->cname, thisnp, 0, -1,
2198 		    submirnp, 0, -1, ep) != 0) {
2199 			return (-1);
2200 		}
2201 	}
2202 	return (0);
2203 }
2204 
2205 /*
2206  * check mirror
2207  */
2208 int
2209 meta_check_mirror(
2210 	mdsetname_t	*sp,
2211 	md_mirror_t	*mirrorp,
2212 	mdcmdopts_t	options,
2213 	md_error_t	*ep
2214 )
2215 {
2216 	mdname_t	*mirnp = mirrorp->common.namep;
2217 	int		force = ((options & MDCMD_FORCE) ? 1 : 0);
2218 	int		doit = ((options & MDCMD_DOIT) ? 1 : 0);
2219 	uint_t		nsm = 0;
2220 	uint_t		smi;
2221 
2222 	/* check submirrors */
2223 	for (smi = 0; (smi < NMIRROR); ++smi) {
2224 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
2225 		mdname_t	*submirnp = mdsp->submirnamep;
2226 
2227 		if (submirnp == NULL)
2228 			continue;
2229 		++nsm;
2230 	}
2231 	if (nsm < 1) {
2232 		return (mdmderror(ep, MDE_BAD_MIRROR,
2233 		    meta_getminor(mirnp->dev), mirnp->cname));
2234 	}
2235 	for (smi = 0; (smi < NMIRROR); ++smi) {
2236 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
2237 		mdname_t	*submirnp = mdsp->submirnamep;
2238 		diskaddr_t	size;
2239 
2240 		/* skip unused submirrors */
2241 		if (submirnp == NULL) {
2242 			if (mdsp->state != SMS_UNUSED) {
2243 				return (mdmderror(ep, MDE_BAD_MIRROR,
2244 				    meta_getminor(mirnp->dev), mirnp->cname));
2245 			}
2246 			continue;
2247 		}
2248 
2249 		/* check submirror */
2250 		if (doit) {
2251 			if (meta_check_submirror(sp, submirnp, NULL, force,
2252 			    ep) != 0)
2253 				return (-1);
2254 			if ((size = metagetsize(submirnp, ep)) ==
2255 			    MD_DISKADDR_ERROR) {
2256 				return (-1);
2257 			} else if (size == 0) {
2258 				return (mdsyserror(ep, ENOSPC,
2259 					submirnp->cname));
2260 			}
2261 		}
2262 
2263 		/* check this mirror too */
2264 		if (check_twice(mirrorp, smi, ep) != 0)
2265 			return (-1);
2266 	}
2267 
2268 	/* check read option */
2269 	switch (mirrorp->read_option) {
2270 	case RD_LOAD_BAL:
2271 	case RD_GEOMETRY:
2272 	case RD_FIRST:
2273 		break;
2274 	default:
2275 		return (mderror(ep, MDE_BAD_RD_OPT, mirnp->cname));
2276 	}
2277 
2278 	/* check write option */
2279 	switch (mirrorp->write_option) {
2280 	case WR_PARALLEL:
2281 	case WR_SERIAL:
2282 		break;
2283 	default:
2284 		return (mderror(ep, MDE_BAD_WR_OPT, mirnp->cname));
2285 	}
2286 
2287 	/* check pass number */
2288 	if ((mirrorp->pass_num < 0) || (mirrorp->pass_num > MD_PASS_MAX))
2289 		return (mderror(ep, MDE_BAD_PASS_NUM, mirnp->cname));
2290 
2291 	/* return success */
2292 	return (0);
2293 }
2294 
2295 /*
2296  * setup mirror geometry
2297  */
2298 static int
2299 mirror_geom(
2300 	md_mirror_t	*mirrorp,
2301 	mm_unit_t	*mm,
2302 	md_error_t	*ep
2303 )
2304 {
2305 	uint_t		write_reinstruct = 0;
2306 	uint_t		read_reinstruct = 0;
2307 	uint_t		round_cyl = 1;
2308 	mdname_t	*smnp = NULL;
2309 	uint_t		smi;
2310 	mdgeom_t	*geomp;
2311 
2312 	/* get worst reinstructs */
2313 	for (smi = 0; (smi < NMIRROR); ++smi) {
2314 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
2315 		mdname_t	*submirnp = mdsp->submirnamep;
2316 
2317 		if (submirnp == NULL)
2318 			continue;
2319 
2320 		if ((geomp = metagetgeom(submirnp, ep)) == NULL)
2321 			return (-1);
2322 		if (geomp->write_reinstruct > write_reinstruct)
2323 			write_reinstruct = geomp->write_reinstruct;
2324 		if (geomp->read_reinstruct > read_reinstruct)
2325 			read_reinstruct = geomp->read_reinstruct;
2326 
2327 		if (smnp == NULL)
2328 			smnp = submirnp;
2329 	}
2330 
2331 	/* setup geometry from first submirror */
2332 	assert(smnp != NULL);
2333 	if ((geomp = metagetgeom(smnp, ep)) == NULL)
2334 		return (-1);
2335 	if (meta_setup_geom((md_unit_t *)mm, mirrorp->common.namep, geomp,
2336 	    write_reinstruct, read_reinstruct, round_cyl, ep) != 0)
2337 		return (-1);
2338 
2339 	/* return success */
2340 	return (0);
2341 }
2342 
2343 /*
2344  * create mirror
2345  */
2346 int
2347 meta_create_mirror(
2348 	mdsetname_t	*sp,
2349 	md_mirror_t	*mirrorp,
2350 	mdcmdopts_t	options,
2351 	md_error_t	*ep
2352 )
2353 {
2354 	mdname_t	*mirnp = mirrorp->common.namep;
2355 	mm_unit_t	*mm;
2356 	diskaddr_t	submir_size = MD_DISKADDR_ERROR;
2357 	ushort_t	nsm = 0;
2358 	uint_t		smi;
2359 	mdnamelist_t	*keynlp = NULL;
2360 	md_set_params_t	set_params;
2361 	int		rval = -1;
2362 	md_timeval32_t	creation_time;
2363 	int		create_flag = MD_CRO_32BIT;
2364 
2365 	/* validate mirror */
2366 	if (meta_check_mirror(sp, mirrorp, options, ep) != 0)
2367 		return (-1);
2368 
2369 
2370 	/* allocate mirror unit */
2371 	mm = Zalloc(sizeof (*mm));
2372 
2373 	if (meta_gettimeofday(&creation_time) == -1)
2374 		return (mdsyserror(ep, errno, NULL));
2375 
2376 	/* do submirrors */
2377 	for (smi = 0; (smi < NMIRROR); ++smi) {
2378 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
2379 		mdname_t	*submirnp = mdsp->submirnamep;
2380 		mm_submirror_t	*mmsp = &mm->un_sm[smi];
2381 		diskaddr_t	size;
2382 
2383 		/* skip unused submirrors */
2384 		if (submirnp == NULL) {
2385 			assert(mdsp->state == SMS_UNUSED);
2386 			continue;
2387 		}
2388 		++nsm;
2389 
2390 		/* get size */
2391 		if ((size = metagetsize(submirnp, ep)) == MD_DISKADDR_ERROR)
2392 			goto out;
2393 		assert(size > 0);
2394 
2395 		/* adjust for smallest submirror */
2396 		if (submir_size == MD_DISKADDR_ERROR) {
2397 			submir_size = size;
2398 		} else if (size < submir_size) {
2399 			submir_size = size;
2400 		}
2401 
2402 		if (options & MDCMD_DOIT) {
2403 			/* store name in namespace */
2404 			if (add_key_name(sp, submirnp, &keynlp, ep) != 0)
2405 				goto out;
2406 		}
2407 
2408 		/* setup submirror */
2409 		mmsp->sm_key = submirnp->key;
2410 		mmsp->sm_dev = submirnp->dev;
2411 		mmsp->sm_state = SMS_RUNNING;
2412 		mmsp->sm_timestamp = creation_time;
2413 	}
2414 
2415 	/* setup unit */
2416 	mm->c.un_type = MD_METAMIRROR;
2417 	MD_SID(mm) = meta_getminor(mirnp->dev);
2418 	mm->c.un_actual_tb = submir_size;
2419 	mm->c.un_size = offsetof(mm_unit_t, un_smic);
2420 	mm->un_nsm = nsm;
2421 	mm->un_read_option = mirrorp->read_option;
2422 	mm->un_write_option = mirrorp->write_option;
2423 	mm->un_pass_num = mirrorp->pass_num;
2424 	if (mirror_geom(mirrorp, mm, ep) != 0)
2425 		goto out;
2426 
2427 	/* fill in the size of the mirror */
2428 	if (options & MDCMD_UPDATE) {
2429 		mirrorp->common.size = mm->c.un_total_blocks;
2430 	}
2431 
2432 	/* if we're not doing anything, return success */
2433 	if (! (options & MDCMD_DOIT)) {
2434 		rval = 0;	/* success */
2435 		goto out;
2436 	}
2437 
2438 	/* create mirror */
2439 	(void) memset(&set_params, 0, sizeof (set_params));
2440 	/* did the user tell us to generate a large device? */
2441 	create_flag = meta_check_devicesize(mm->c.un_total_blocks);
2442 	if (create_flag == MD_CRO_64BIT) {
2443 		mm->c.un_revision |= MD_64BIT_META_DEV;
2444 		set_params.options = MD_CRO_64BIT;
2445 	} else {
2446 		mm->c.un_revision &= ~MD_64BIT_META_DEV;
2447 		set_params.options = MD_CRO_32BIT;
2448 	}
2449 	set_params.mnum = MD_SID(mm);
2450 	set_params.size = mm->c.un_size;
2451 	set_params.mdp = (uintptr_t)mm;
2452 	MD_SETDRIVERNAME(&set_params, MD_MIRROR, MD_MIN2SET(set_params.mnum));
2453 	if (metaioctl(MD_IOCSET, &set_params, &set_params.mde,
2454 	    mirnp->cname) != 0) {
2455 		(void) mdstealerror(ep, &set_params.mde);
2456 		goto out;
2457 	}
2458 	rval = 0;	/* success */
2459 
2460 	/* cleanup, return success */
2461 out:
2462 	Free(mm);
2463 	if (rval != 0) {
2464 		(void) del_key_names(sp, keynlp, NULL);
2465 	}
2466 	metafreenamelist(keynlp);
2467 	if ((rval == 0) && (options & MDCMD_DOIT)) {
2468 		if (invalidate_submirrors(sp, mirnp, ep) != 0)
2469 			rval = -1;
2470 		meta_invalidate_name(mirnp);
2471 	}
2472 	return (rval);
2473 }
2474 
2475 /*
2476  * initialize mirror
2477  * NOTE: this functions is metainit(1m)'s command line parser!
2478  */
2479 int
2480 meta_init_mirror(
2481 	mdsetname_t	**spp,
2482 	int		argc,
2483 	char		*argv[],
2484 	mdcmdopts_t	options,
2485 	md_error_t	*ep
2486 )
2487 {
2488 	char		*uname = argv[0];
2489 	mdname_t	*mirnp = NULL;
2490 	int		old_optind;
2491 	int		c;
2492 	md_mirror_t	*mirrorp = NULL;
2493 	uint_t		smi;
2494 	int		rval = -1;
2495 
2496 	/* get mirror name */
2497 	assert(argc > 0);
2498 	if (argc < 1)
2499 		goto syntax;
2500 	if ((mirnp = metaname(spp, uname, META_DEVICE, ep)) == NULL)
2501 		goto out;
2502 	assert(*spp != NULL);
2503 	uname = mirnp->cname;
2504 	if (metachkmeta(mirnp, ep) != 0)
2505 		goto out;
2506 
2507 	if (!(options & MDCMD_NOLOCK)) {
2508 		/* grab set lock */
2509 		if (meta_lock(*spp, TRUE, ep) != 0)
2510 			goto out;
2511 
2512 		if (meta_check_ownership(*spp, ep) != 0)
2513 			goto out;
2514 	}
2515 
2516 	/* see if it exists already */
2517 	if (metagetmiscname(mirnp, ep) != NULL) {
2518 		(void) mdmderror(ep, MDE_UNIT_ALREADY_SETUP,
2519 		    meta_getminor(mirnp->dev), uname);
2520 		goto out;
2521 	} else if (! mdismderror(ep, MDE_UNIT_NOT_SETUP)) {
2522 		goto out;
2523 	} else {
2524 		mdclrerror(ep);
2525 	}
2526 	--argc, ++argv;
2527 
2528 	/* grab -m */
2529 	if ((argc < 1) || (strcmp(argv[0], "-m") != 0))
2530 		goto syntax;
2531 	--argc, ++argv;
2532 
2533 	if (argc == 0)
2534 		goto syntax;
2535 
2536 	/* parse general options */
2537 	optind = 0;
2538 	opterr = 0;
2539 	if (getopt(argc, argv, "") != -1)
2540 		goto options;
2541 
2542 	/* allocate mirror */
2543 	mirrorp = Zalloc(sizeof (*mirrorp));
2544 
2545 	/* setup common */
2546 	mirrorp->common.namep = mirnp;
2547 	mirrorp->common.type = MD_METAMIRROR;
2548 
2549 	/* parse submirrors */
2550 	for (smi = 0; ((argc > 0) && (argv[0][0] != '-') &&
2551 	    (! isdigit(argv[0][0]))); ++smi) {
2552 		md_submirror_t	*mdsm = &mirrorp->submirrors[smi];
2553 		mdname_t	*submirnamep;
2554 
2555 		/* check for room */
2556 		if (smi >= NMIRROR) {
2557 			(void) mdmderror(ep, MDE_MIRROR_FULL,
2558 			    meta_getminor(mirnp->dev), uname);
2559 			goto out;
2560 		}
2561 
2562 		/* parse submirror name */
2563 		if ((submirnamep = metaname(spp, argv[0],
2564 		    META_DEVICE, ep)) == NULL)
2565 			goto out;
2566 		mdsm->submirnamep = submirnamep;
2567 		--argc, ++argv;
2568 	}
2569 	if (smi == 0) {
2570 		(void) mdmderror(ep, MDE_NSUBMIRS, meta_getminor(mirnp->dev),
2571 					uname);
2572 		goto out;
2573 	}
2574 
2575 	/* dangerous n-way mirror creation */
2576 	if ((smi > 1) && (options & MDCMD_PRINT)) {
2577 		md_eprintf(dgettext(TEXT_DOMAIN,
2578 "%s: WARNING: This form of metainit is not recommended.\n"
2579 "The submirrors may not have the same data.\n"
2580 "Please see ERRORS in metainit(1M) for additional information.\n"),
2581 		    uname);
2582 	}
2583 
2584 	/* parse mirror options */
2585 	mirrorp->read_option = RD_LOAD_BAL;
2586 	mirrorp->write_option = WR_PARALLEL;
2587 	mirrorp->pass_num = MD_PASS_DEFAULT;
2588 	old_optind = optind = 0;
2589 	opterr = 0;
2590 	while ((c = getopt(argc, argv, "grS")) != -1) {
2591 		switch (c) {
2592 		case 'g':
2593 			if (mirrorp->read_option != RD_LOAD_BAL) {
2594 				(void) mderror(ep, MDE_BAD_RD_OPT, uname);
2595 				goto out;
2596 			}
2597 			mirrorp->read_option = RD_GEOMETRY;
2598 			break;
2599 
2600 		case 'r':
2601 			if (mirrorp->read_option != RD_LOAD_BAL) {
2602 				(void) mderror(ep, MDE_BAD_RD_OPT, uname);
2603 				goto out;
2604 			}
2605 			mirrorp->read_option = RD_FIRST;
2606 			break;
2607 
2608 		case 'S':
2609 			if (mirrorp->write_option != WR_PARALLEL) {
2610 				(void) mderror(ep, MDE_BAD_WR_OPT, uname);
2611 				goto out;
2612 			}
2613 			mirrorp->write_option = WR_SERIAL;
2614 			break;
2615 
2616 		default:
2617 			argc -= old_optind;
2618 			argv += old_optind;
2619 			goto options;
2620 		}
2621 		old_optind = optind;
2622 	}
2623 	argc -= optind;
2624 	argv += optind;
2625 
2626 	/* parse pass number */
2627 	if ((argc > 0) && (isdigit(argv[0][0]))) {
2628 		if (name_to_pass_num(uname, argv[0],
2629 		    &mirrorp->pass_num, ep) != 0) {
2630 			goto out;
2631 		}
2632 		--argc, ++argv;
2633 	}
2634 
2635 	/* we should be at the end */
2636 	if (argc != 0)
2637 		goto syntax;
2638 
2639 	/* create mirror */
2640 	if (meta_create_mirror(*spp, mirrorp, options, ep) != 0)
2641 		goto out;
2642 	rval = 0;	/* success */
2643 
2644 	/* let em know */
2645 	if (options & MDCMD_PRINT) {
2646 		(void) printf(dgettext(TEXT_DOMAIN,
2647 		    "%s: Mirror is setup\n"),
2648 		    uname);
2649 		(void) fflush(stdout);
2650 	}
2651 	goto out;
2652 
2653 	/* syntax error */
2654 syntax:
2655 	rval = meta_cook_syntax(ep, MDE_SYNTAX, uname, argc, argv);
2656 	goto out;
2657 
2658 	/* options error */
2659 options:
2660 	rval = meta_cook_syntax(ep, MDE_OPTION, uname, argc, argv);
2661 	goto out;
2662 
2663 	/* cleanup, return error */
2664 out:
2665 	if (mirrorp != NULL)
2666 		meta_free_mirror(mirrorp);
2667 	return (rval);
2668 }
2669 
2670 /*
2671  * reset mirrors
2672  */
2673 int
2674 meta_mirror_reset(
2675 	mdsetname_t	*sp,
2676 	mdname_t	*mirnp,
2677 	mdcmdopts_t	options,
2678 	md_error_t	*ep
2679 )
2680 {
2681 	md_mirror_t	*mirrorp;
2682 	uint_t		smi;
2683 	int		rval = -1;
2684 
2685 	/* should have same set */
2686 	assert(sp != NULL);
2687 	assert((mirnp == NULL) ||
2688 	    (sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev))));
2689 
2690 	/* reset all mirrors */
2691 	if (mirnp == NULL) {
2692 		mdnamelist_t	*mirrornlp = NULL;
2693 		mdnamelist_t	*p;
2694 
2695 		/* for each mirror */
2696 		rval = 0;
2697 		if (meta_get_mirror_names(sp, &mirrornlp, 0, ep) < 0)
2698 			return (-1);
2699 		for (p = mirrornlp; (p != NULL); p = p->next) {
2700 			/* reset mirror */
2701 			mirnp = p->namep;
2702 			/*
2703 			 * If this is a multi-node set, we send a series
2704 			 * of individual metaclear commands.
2705 			 */
2706 			if (meta_is_mn_set(sp, ep)) {
2707 				if (meta_mn_send_metaclear_command(sp,
2708 				    mirnp->cname, options, 0, ep) != 0) {
2709 					rval = -1;
2710 					break;
2711 				}
2712 			} else {
2713 				if (meta_mirror_reset(sp, mirnp, options,
2714 				    ep) != 0) {
2715 					rval = -1;
2716 					break;
2717 				}
2718 			}
2719 		}
2720 
2721 		/* cleanup return success */
2722 		metafreenamelist(mirrornlp);
2723 		return (rval);
2724 	}
2725 
2726 	/* check name */
2727 	if (metachkmeta(mirnp, ep) != 0)
2728 		return (-1);
2729 
2730 	/* get unit structure */
2731 	if ((mirrorp = meta_get_mirror(sp, mirnp, ep)) == NULL)
2732 		return (-1);
2733 
2734 	/* make sure nobody owns us */
2735 	if (MD_HAS_PARENT(mirrorp->common.parent)) {
2736 		return (mdmderror(ep, MDE_IN_USE, meta_getminor(mirnp->dev),
2737 		    mirnp->cname));
2738 	}
2739 
2740 	/* clear subdevices cache */
2741 	if (invalidate_submirrors(sp, mirnp, ep) != 0)
2742 		return (-1);
2743 
2744 	/* clear metadevice */
2745 	if (meta_reset(sp, mirnp, options, ep) != 0)
2746 		goto out;
2747 	rval = 0;	/* success */
2748 
2749 	/* let em know */
2750 	if (options & MDCMD_PRINT) {
2751 		(void) printf(dgettext(TEXT_DOMAIN,
2752 		    "%s: Mirror is cleared\n"), mirnp->cname);
2753 		(void) fflush(stdout);
2754 	}
2755 
2756 	/* clear subdevices */
2757 	if (! (options & MDCMD_RECURSE))
2758 		goto out;
2759 	for (smi = 0; (smi < NMIRROR); ++smi) {
2760 		md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
2761 		mdname_t	*submirnp = mdsp->submirnamep;
2762 
2763 		/* skip unused submirrors */
2764 		if (submirnp == NULL) {
2765 			assert(mdsp->state == SMS_UNUSED);
2766 			continue;
2767 		}
2768 
2769 		/* make sure we have a metadevice */
2770 		if (! metaismeta(submirnp))
2771 			continue;
2772 
2773 		/* clear submirror */
2774 		if (meta_reset_by_name(sp, submirnp, options, ep) != 0)
2775 			rval = -1;
2776 	}
2777 
2778 	/* cleanup, return success */
2779 out:
2780 	meta_invalidate_name(mirnp);
2781 	return (rval);
2782 }
2783 
2784 /*
2785  * reports TRUE if any mirror component is in error
2786  */
2787 int
2788 meta_mirror_anycomp_is_err(mdsetname_t *sp, mdnamelist_t *mirror_names)
2789 {
2790 	mdnamelist_t	*nlp;
2791 	md_error_t	  status	= mdnullerror;
2792 	md_error_t	 *ep		= &status;
2793 	int		  any_errs	= FALSE;
2794 
2795 	for (nlp = mirror_names; nlp; nlp = nlp->next) {
2796 		md_mirror_t	*mirrorp;
2797 		int		 smi;
2798 
2799 		if ((mirrorp = meta_get_mirror(sp, nlp->namep, ep)) == NULL) {
2800 			any_errs |= TRUE;
2801 			goto out;
2802 		}
2803 
2804 		for (smi = 0; smi < NMIRROR; ++smi) {
2805 			md_submirror_t	*mdsp = &mirrorp->submirrors[smi];
2806 
2807 			if (mdsp->state &
2808 			    (SMS_COMP_ERRED|SMS_ATTACHED|SMS_OFFLINE)) {
2809 				any_errs |= TRUE;
2810 				goto out;
2811 			}
2812 		}
2813 	}
2814 out:
2815 	if (!mdisok(ep))
2816 		mdclrerror(ep);
2817 
2818 	return (any_errs);
2819 }
2820