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