xref: /onnv-gate/usr/src/lib/lvm/libmeta/common/meta_error.c (revision 127:b5442f86e50a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * Just in case we're not in a build environment, make sure that
31  * TEXT_DOMAIN gets set to something.
32  */
33 #if !defined(TEXT_DOMAIN)
34 #define	TEXT_DOMAIN "SYS_TEST"
35 #endif
36 
37 /*
38  * print metedevice errors
39  */
40 
41 #include <meta.h>
42 #include <sys/lvm/md_mddb.h>
43 
44 #include <syslog.h>
45 
46 /*
47  * clear error
48  */
49 void
50 mdclrerror(
51 	md_error_t	*ep
52 )
53 {
54 	if (ep->name != NULL)
55 		Free(ep->name);
56 	if (ep->host != NULL)
57 		Free(ep->host);
58 	if (ep->extra != NULL)
59 		Free(ep->extra);
60 	(void) memset(ep, '\0', sizeof (*ep));
61 }
62 
63 /*
64  * cook names
65  */
66 static char *
67 md_name(
68 	minor_t	mnum
69 )
70 {
71 	char	*name;
72 
73 	/* get name, or fake it */
74 	if ((name = get_mdname(mnum)) == NULL) {
75 		char	buf[40];
76 
77 		(void) sprintf(buf, "%lu/d%lu", MD_MIN2SET(mnum),
78 		    MD_MIN2UNIT(mnum));
79 		return (Strdup(buf));
80 	}
81 	return (Strdup(name));
82 }
83 
84 static char *
85 dev_name(
86 	set_t	setno,
87 	md_dev64_t dev
88 )
89 {
90 	char	*name;
91 
92 	/* get name or fake it */
93 	if (dev == NODEV64)
94 		return (Strdup(dgettext(TEXT_DOMAIN, "unknown device")));
95 	if ((name = get_devname(setno, dev)) == NULL) {
96 		char	buf[40];
97 
98 		(void) sprintf(buf, "%lu.%lu", meta_getmajor(dev),
99 		    meta_getminor(dev));
100 		return (Strdup(buf));
101 	}
102 	return (Strdup(name));
103 }
104 
105 static char *
106 hsp_name(
107 	hsp_t	hsp
108 )
109 {
110 	char	*name;
111 
112 	if ((name = get_hspname(hsp)) == NULL) {
113 		char	buf[40];
114 
115 		(void) sprintf(buf, "%u/hsp%03u", HSP_SET(hsp), HSP_ID(hsp));
116 		return (Strdup(buf));
117 	}
118 	return (Strdup(name));
119 }
120 
121 static char *
122 set_name(
123 	set_t		setno
124 )
125 {
126 	mdsetname_t	*sp;
127 	md_error_t	xep = mdnullerror;
128 
129 	if (setno == MD_SET_BAD)
130 		return (NULL);
131 
132 	if ((sp = metasetnosetname(setno, &xep)) == NULL) {
133 		char	buf[40];
134 
135 		mdclrerror(&xep);
136 		(void) sprintf(buf, "setno %u", setno);
137 		return (Strdup(buf));
138 	}
139 	return (Strdup(sp->setname));
140 }
141 
142 /*
143  * fill in all the appropriate md_error_t fields
144  */
145 static void
146 metacookerror(
147 	md_error_t	*ep,		/* generic error */
148 	char		*name		/* optional name or host */
149 )
150 {
151 	/* get host name */
152 	if (ep->host != NULL) {
153 		Free(ep->host);
154 		ep->host = NULL;
155 	}
156 	if ((ep->info.errclass == MDEC_RPC) &&
157 	    (name != NULL) && (*name != '\0')) {
158 		ep->host = Strdup(name);
159 		name = NULL;
160 	} else
161 		ep->host = Strdup(mynode());
162 
163 	/* get appropriate name */
164 	if (ep->name != NULL) {
165 		Free(ep->name);
166 		ep->name = NULL;
167 	}
168 	if ((name != NULL) && (*name != '\0')) {
169 		ep->name = Strdup(name);
170 	} else {
171 		switch (ep->info.errclass) {
172 
173 		/* can't do anything about these */
174 		case MDEC_VOID:
175 		case MDEC_SYS:
176 		case MDEC_RPC:
177 		default:
178 			break;
179 
180 		/* device name */
181 		case MDEC_DEV:
182 		{
183 			md_dev_error_t	*ip =
184 					&ep->info.md_error_info_t_u.dev_error;
185 
186 			ep->name = dev_name(MD_SET_BAD, ip->dev);
187 			break;
188 		}
189 
190 		/* device name */
191 		case MDEC_USE:
192 		{
193 			md_use_error_t	*ip =
194 					&ep->info.md_error_info_t_u.use_error;
195 
196 			ep->name = dev_name(MD_SET_BAD, ip->dev);
197 			if (ip->where == NULL) {
198 				ip->where = Strdup(dgettext(TEXT_DOMAIN,
199 				    "unknown"));
200 			}
201 			break;
202 		}
203 
204 		/* metadevice name */
205 		case MDEC_MD:
206 		{
207 			md_md_error_t	*ip =
208 					&ep->info.md_error_info_t_u.md_error;
209 
210 			ep->name = md_name(ip->mnum);
211 			break;
212 		}
213 
214 		/* component name */
215 		case MDEC_COMP:
216 		{
217 			md_comp_error_t	*ip =
218 					&ep->info.md_error_info_t_u.comp_error;
219 			char		*mdname, *devname;
220 			size_t 		len;
221 
222 			mdname = md_name(ip->comp.mnum);
223 			devname = dev_name(MD_MIN2SET(ip->comp.mnum),
224 			    ip->comp.dev);
225 			len = strlen(mdname) + strlen(": ")
226 			    + strlen(devname) + 1;
227 			ep->name = Malloc(len);
228 			(void) snprintf(ep->name, len, "%s: %s",
229 			    mdname, devname);
230 			Free(mdname);
231 			Free(devname);
232 			break;
233 		}
234 
235 		/* hotspare pool name */
236 		case MDEC_HSP:
237 		{
238 			md_hsp_error_t	*ip =
239 					&ep->info.md_error_info_t_u.hsp_error;
240 
241 			ep->name = hsp_name(ip->hsp);
242 			break;
243 		}
244 
245 		/* hotspare name */
246 		case MDEC_HS:
247 		{
248 			md_hs_error_t	*ip =
249 					&ep->info.md_error_info_t_u.hs_error;
250 			char		*hspname, *devname;
251 			size_t 		len;
252 
253 			hspname = hsp_name(ip->hs.hsp);
254 			devname = dev_name(HSP_SET(ip->hs.hsp), ip->hs.dev);
255 			len = strlen(hspname) + strlen(": ")
256 			    + strlen(devname) + 1;
257 			ep->name = Malloc(len);
258 			(void) snprintf(ep->name, len, "%s: %s",
259 			    hspname, devname);
260 			Free(hspname);
261 			Free(devname);
262 			break;
263 		}
264 
265 		/* mddb name */
266 		case MDEC_MDDB:
267 		{
268 			md_mddb_error_t	*ip =
269 					&ep->info.md_error_info_t_u.mddb_error;
270 			if (ip->mnum != NODEV32)
271 				ep->name = md_name(ip->mnum);
272 			ep->name = set_name(ip->setno);
273 			break;
274 		}
275 
276 		/* set name */
277 		case MDEC_DS:
278 		{
279 			md_ds_error_t	*ip =
280 			    &ep->info.md_error_info_t_u.ds_error;
281 
282 			ep->name = set_name(ip->setno);
283 			break;
284 		}
285 		}
286 	}
287 }
288 
289 /*
290  * simple error
291  */
292 int
293 mderror(
294 	md_error_t	*ep,
295 	md_void_errno_t	errnum,
296 	char		*name
297 )
298 {
299 	md_void_error_t	*ip = &ep->info.md_error_info_t_u.void_error;
300 
301 	mdclrerror(ep);
302 	ep->info.errclass = MDEC_VOID;
303 	ip->errnum = errnum;
304 
305 	metacookerror(ep, name);
306 	return (-1);
307 }
308 
309 /*
310  * system error
311  */
312 int
313 mdsyserror(
314 	md_error_t	*ep,
315 	int		errnum,
316 	char		*name
317 )
318 {
319 	md_sys_error_t	*ip = &ep->info.md_error_info_t_u.sys_error;
320 
321 	mdclrerror(ep);
322 	if (errnum != 0) {
323 		ep->info.errclass = MDEC_SYS;
324 		ip->errnum = errnum;
325 	}
326 
327 	metacookerror(ep, name);
328 	return (-1);
329 }
330 
331 /*
332  * RPC error
333  */
334 int
335 mdrpcerror(
336 	md_error_t	*ep,
337 	CLIENT		*clntp,
338 	char		*host,
339 	char		*extra
340 )
341 {
342 	md_rpc_error_t	*ip = &ep->info.md_error_info_t_u.rpc_error;
343 	struct rpc_err	rpcerr;
344 
345 	mdclrerror(ep);
346 	clnt_geterr(clntp, &rpcerr);
347 	ep->info.errclass = MDEC_RPC;
348 	ip->errnum = rpcerr.re_status;
349 
350 	metacookerror(ep, host);
351 	mderrorextra(ep, extra);
352 	return (-1);
353 }
354 
355 /*
356  * RPC create error
357  */
358 int
359 mdrpccreateerror(
360 	md_error_t	*ep,
361 	char		*host,
362 	char		*extra
363 )
364 {
365 	md_rpc_error_t	*ip = &ep->info.md_error_info_t_u.rpc_error;
366 
367 	mdclrerror(ep);
368 	ep->info.errclass = MDEC_RPC;
369 	ip->errnum = rpc_createerr.cf_stat;
370 
371 	metacookerror(ep, host);
372 	mderrorextra(ep, extra);
373 	return (-1);
374 }
375 
376 /*
377  * device error
378  */
379 int
380 mddeverror(
381 	md_error_t	*ep,
382 	md_dev_errno_t	errnum,
383 	md_dev64_t	dev,
384 	char		*name
385 )
386 {
387 	md_dev_error_t	*ip = &ep->info.md_error_info_t_u.dev_error;
388 
389 	mdclrerror(ep);
390 	ep->info.errclass = MDEC_DEV;
391 	ip->errnum = errnum;
392 	ip->dev = dev;
393 
394 	metacookerror(ep, name);
395 	return (-1);
396 }
397 
398 /*
399  * use error
400  */
401 int
402 mduseerror(
403 	md_error_t	*ep,
404 	md_use_errno_t	errnum,
405 	md_dev64_t	dev,
406 	char		*where,
407 	char		*name
408 )
409 {
410 	md_use_error_t	*ip = &ep->info.md_error_info_t_u.use_error;
411 
412 	assert(where != NULL);
413 	mdclrerror(ep);
414 	ep->info.errclass = MDEC_USE;
415 	ip->errnum = errnum;
416 	ip->dev = dev;
417 	ip->where = Strdup(where);
418 
419 	metacookerror(ep, name);
420 	return (-1);
421 }
422 
423 /*
424  * overlap error
425  */
426 int
427 mdoverlaperror(
428 	md_error_t		*ep,
429 	md_overlap_errno_t	errnum,
430 	char			*name,
431 	char			*where,
432 	char			*overlap
433 )
434 {
435 	md_overlap_error_t *ip =
436 			&ep->info.md_error_info_t_u.overlap_error;
437 
438 	assert(overlap != NULL);
439 	mdclrerror(ep);
440 	ep->info.errclass = MDEC_OVERLAP;
441 	ip->errnum = errnum;
442 	ip->overlap = Strdup(overlap);
443 	ip->where = NULL;
444 	if (where != NULL)
445 	    ip->where = Strdup(where);
446 
447 	metacookerror(ep, name);
448 	return (-1);
449 }
450 
451 /*
452  * metadevice error
453  */
454 int
455 mdmderror(
456 	md_error_t	*ep,
457 	md_md_errno_t	errnum,
458 	minor_t		mnum,
459 	char		*name
460 )
461 {
462 	md_md_error_t	*ip = &ep->info.md_error_info_t_u.md_error;
463 
464 	mdclrerror(ep);
465 	ep->info.errclass = MDEC_MD;
466 	ip->errnum = errnum;
467 	ip->mnum = mnum;
468 
469 	metacookerror(ep, name);
470 	return (-1);
471 }
472 
473 /*
474  * component error
475  */
476 int
477 mdcomperror(
478 	md_error_t	*ep,
479 	md_comp_errno_t	errnum,
480 	minor_t		mnum,
481 	md_dev64_t	dev,
482 	char		*name
483 )
484 {
485 	md_comp_error_t	*ip = &ep->info.md_error_info_t_u.comp_error;
486 
487 	mdclrerror(ep);
488 	ep->info.errclass = MDEC_COMP;
489 	ip->errnum = errnum;
490 	ip->comp.mnum = mnum;
491 	ip->comp.dev = dev;
492 
493 	metacookerror(ep, name);
494 	return (-1);
495 }
496 
497 /*
498  * hotspare pool error
499  */
500 int
501 mdhsperror(
502 	md_error_t	*ep,
503 	md_hsp_errno_t	errnum,
504 	hsp_t		hsp,
505 	char		*name
506 )
507 {
508 	md_hsp_error_t	*ip = &ep->info.md_error_info_t_u.hsp_error;
509 
510 	mdclrerror(ep);
511 	ep->info.errclass = MDEC_HSP;
512 	ip->errnum = errnum;
513 	ip->hsp = hsp;
514 
515 	metacookerror(ep, name);
516 	return (-1);
517 }
518 
519 /*
520  * hotspare error
521  */
522 int
523 mdhserror(
524 	md_error_t	*ep,
525 	md_hs_errno_t	errnum,
526 	hsp_t		hsp,
527 	md_dev64_t	dev,
528 	char		*name
529 )
530 {
531 	md_hs_error_t	*ip = &ep->info.md_error_info_t_u.hs_error;
532 
533 	mdclrerror(ep);
534 	ep->info.errclass = MDEC_HS;
535 	ip->errnum = errnum;
536 	ip->hs.hsp = hsp;
537 	ip->hs.dev = dev;
538 
539 	metacookerror(ep, name);
540 	return (-1);
541 }
542 
543 /*
544  * MDDB error
545  */
546 int
547 mdmddberror(
548 	md_error_t	*ep,
549 	md_mddb_errno_t	errnum,
550 	minor_t		mnum,
551 	set_t		setno,
552 	size_t		size,
553 	char		*name
554 )
555 {
556 	md_mddb_error_t	*ip = &ep->info.md_error_info_t_u.mddb_error;
557 
558 	mdclrerror(ep);
559 	ep->info.errclass = MDEC_MDDB;
560 	ip->errnum = errnum;
561 	ip->mnum = mnum;
562 	ip->setno = setno;
563 	ip->size = size;
564 
565 	metacookerror(ep, name);
566 	return (-1);
567 }
568 
569 /*
570  * metadevice diskset (ds) error
571  */
572 int
573 mddserror(
574 	md_error_t	*ep,
575 	md_ds_errno_t	errnum,
576 	set_t		setno,
577 	char		*node,
578 	char		*drive,
579 	char		*name
580 )
581 {
582 	md_ds_error_t	*ip = &ep->info.md_error_info_t_u.ds_error;
583 
584 	mdclrerror(ep);
585 	ep->info.errclass = MDEC_DS;
586 	ip->errnum = errnum;
587 	ip->setno = setno;
588 	ip->node = ((node != NULL) ? Strdup(node) : NULL);
589 	ip->drive = ((drive != NULL) ? Strdup(drive) : NULL);
590 
591 	metacookerror(ep, name);
592 	return (-1);
593 }
594 
595 /*
596  * clear/attach extra context information
597  */
598 void
599 mderrorextra(
600 	md_error_t	*ep,
601 	char		*extra
602 )
603 {
604 	if (ep->extra != NULL)
605 		Free(ep->extra);
606 	if (extra != NULL)
607 		ep->extra = Strdup(extra);
608 	else
609 		ep->extra = NULL;
610 }
611 
612 /*
613  * steal (copy) an error code safely
614  */
615 int
616 mdstealerror(
617 	md_error_t	*to,
618 	md_error_t	*from
619 )
620 {
621 	mdclrerror(to);
622 	*to = *from;
623 	(void) memset(from, '\0', sizeof (*from));
624 	return (-1);
625 }
626 
627 /*
628  * do an ioctl, cook the error, and return status
629  */
630 int
631 metaioctl(
632 	int		cmd,
633 	void		*data,
634 	md_error_t	*ep,
635 	char		*name
636 )
637 {
638 	int		fd;
639 
640 	/* open admin device */
641 	if ((fd = open_admin(ep)) < 0)
642 		return (-1);
643 
644 	/* do ioctl */
645 	mdclrerror(ep);
646 	if (ioctl(fd, cmd, data) != 0) {
647 		return (mdsyserror(ep, errno, name));
648 	} else if (! mdisok(ep)) {
649 		metacookerror(ep, name);
650 		return (-1);
651 	}
652 
653 	/* return success */
654 	return (0);
655 }
656 
657 /*
658  * print void class errors
659  */
660 static char *
661 void_to_str(
662 	md_error_t	*ep,
663 	char		*buf,
664 	size_t		size
665 )
666 {
667 	md_void_error_t	*ip = &ep->info.md_error_info_t_u.void_error;
668 	char		*p = buf + strlen(buf);
669 	size_t		psize = size - strlen(buf);
670 
671 	switch (ip->errnum) {
672 	case MDE_NONE:
673 		(void) snprintf(p, psize,
674 		    dgettext(TEXT_DOMAIN, "no error"));
675 		break;
676 	case MDE_UNIT_NOT_FOUND:
677 		(void) snprintf(p, psize,
678 		    dgettext(TEXT_DOMAIN, "unit not found"));
679 		break;
680 	case MDE_DUPDRIVE:
681 		(void) snprintf(p, psize,
682 		    dgettext(TEXT_DOMAIN, "drive specified more than once"));
683 		break;
684 	case MDE_INVAL_HSOP:
685 		(void) snprintf(p, psize,
686 		    dgettext(TEXT_DOMAIN, "illegal hot spare operation"));
687 		break;
688 	case MDE_NO_SET:
689 		(void) snprintf(p, psize,
690 		    dgettext(TEXT_DOMAIN, "no such set"));
691 		break;
692 	case MDE_SET_DIFF:
693 		(void) snprintf(p, psize,
694 		    dgettext(TEXT_DOMAIN, "set name is inconsistent"));
695 		break;
696 	case MDE_BAD_RD_OPT:
697 		(void) snprintf(p, psize,
698 		    dgettext(TEXT_DOMAIN, "invalid read option"));
699 		break;
700 	case MDE_BAD_WR_OPT:
701 		(void) snprintf(p, psize,
702 		    dgettext(TEXT_DOMAIN, "invalid write option"));
703 		break;
704 	case MDE_BAD_PASS_NUM:
705 		(void) snprintf(p, psize,
706 		    dgettext(TEXT_DOMAIN, "invalid pass number"));
707 		break;
708 	case MDE_BAD_RESYNC_OPT:
709 		(void) snprintf(p, psize,
710 		    dgettext(TEXT_DOMAIN, "invalid resync option"));
711 		break;
712 	case MDE_BAD_INTERLACE:
713 		(void) snprintf(p, psize,
714 		    dgettext(TEXT_DOMAIN, "invalid interlace"));
715 		break;
716 	case MDE_NO_HSPS:
717 		(void) snprintf(p, psize,
718 		    dgettext(TEXT_DOMAIN, "no hotspare pools found"));
719 		break;
720 	case MDE_NOTENOUGH_DB:
721 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
722 			"must have at least 1 database (-f overrides)"));
723 		break;
724 	case MDE_DELDB_NOTALLOWED:
725 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
726 		    "cannot delete the last database replica in the diskset"));
727 		break;
728 	case MDE_DEL_VALIDDB_NOTALLOWED:
729 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
730 		    "Deleting specified valid replicas results in stale "
731 		    "state database. Configuration changes with stale "
732 		    "database result in panic(-f overrides)"));
733 		break;
734 	case MDE_SYSTEM_FILE:
735 		(void) snprintf(p, psize,
736 		    dgettext(TEXT_DOMAIN, "error in system file"));
737 		break;
738 	case MDE_MDDB_FILE:
739 		(void) snprintf(p, psize,
740 		    dgettext(TEXT_DOMAIN, "error in mddb.cf file"));
741 		break;
742 	case MDE_MDDB_CKSUM:
743 		(void) snprintf(p, psize,
744 		    dgettext(TEXT_DOMAIN, "checksum error in mddb.cf file"));
745 		break;
746 	case MDE_VFSTAB_FILE:
747 		(void) snprintf(p, psize,
748 		    dgettext(TEXT_DOMAIN, "error in vfstab file"));
749 		break;
750 	case MDE_NOSLICE:
751 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
752 		    "invalid slice number for drive name"));
753 		break;
754 	case MDE_SYNTAX:
755 		(void) snprintf(p, psize,
756 		    dgettext(TEXT_DOMAIN, "syntax error"));
757 		break;
758 	case MDE_OPTION:
759 		(void) snprintf(p, psize,
760 		    dgettext(TEXT_DOMAIN, "illegal option"));
761 		break;
762 	case MDE_TAKE_OWN:
763 		(void) snprintf(p, psize,
764 		    dgettext(TEXT_DOMAIN, "failed to reserve any drives"));
765 		break;
766 	case MDE_NOT_DRIVENAME:
767 		(void) snprintf(p, psize,
768 		    dgettext(TEXT_DOMAIN, "not a valid drive name"));
769 		break;
770 	case MDE_RESERVED:
771 		(void) snprintf(p, psize,
772 		    dgettext(TEXT_DOMAIN, "reserved by another host"));
773 		break;
774 	case MDE_DVERSION:
775 		(void) snprintf(p, psize,
776 		    dgettext(TEXT_DOMAIN, "driver version mismatch"));
777 		break;
778 	case MDE_MVERSION:
779 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
780 		    "metadevice state database version mismatch"));
781 		break;
782 	case MDE_TESTERROR:
783 		(void) snprintf(p, psize,
784 		    dgettext(TEXT_DOMAIN, "TEST ERROR MESSAGE"));
785 		break;
786 	case MDE_BAD_ORIG_NCOL:
787 		(void) snprintf(p, psize,
788 		    dgettext(TEXT_DOMAIN, "invalid column count"));
789 		break;
790 	case MDE_RAID_INVALID:
791 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
792 		    "devices were not RAIDed previously or "
793 		    "are specified in the wrong order"));
794 		break;
795 	case MDE_MED_ERROR:
796 		break;
797 	case MDE_TOOMANYMED:
798 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
799 		    "too many mediator hosts requested"));
800 		break;
801 	case MDE_NOMED:
802 		(void) snprintf(p, psize,
803 		    dgettext(TEXT_DOMAIN, "no mediator hosts found"));
804 		break;
805 	case MDE_ONLYNODENAME:
806 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
807 		    "only the nodename of a host is required for deletes"));
808 		break;
809 	case MDE_RAID_BAD_PW_CNT:
810 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
811 		    "simultaneous writes out of range"));
812 		break;
813 	case MDE_DEVID_TOOBIG:
814 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
815 		    "relocation information size is greater than reported"));
816 		break;
817 	case MDE_NOPERM:
818 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
819 		    "Permission denied.  You must have root privilege "
820 		    "to execute this command."));
821 		break;
822 	case MDE_NODEVID:
823 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
824 		    "Device relocation information not available "
825 		    "for this device"));
826 		break;
827 	case MDE_NOROOT:
828 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
829 		    "no root filesystem in /etc/mnttab"));
830 		break;
831 	case MDE_EOF_TRANS:
832 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
833 		    MD_EOF_TRANS_MSG));
834 		break;
835 	case MDE_NOT_MN:
836 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
837 		    "option only valid within a multi-owner set"));
838 		break;
839 	case MDE_ABR_SET:
840 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
841 		    "Invalid command for mirror with ABR set"));
842 		break;
843 	case MDE_INVAL_MNOP:
844 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
845 		    "Invalid operation on multi-owner set"));
846 		break;
847 	case MDE_MNSET_NOTRANS:
848 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
849 		    "Trans metadevice not supported on multi-owner set"));
850 		break;
851 	case MDE_MNSET_NORAID:
852 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
853 		    "RAID-5 metadevice not supported on multi-owner set"));
854 		break;
855 	case MDE_FORCE_DEL_ALL_DRV:
856 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
857 		    "Must specify -f option to delete all drives from set"));
858 		break;
859 	case MDE_STRIPE_TRUNC_SINGLE:
860 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
861 		    "The necessary rounding would result in data loss.  "
862 		    "You can avoid this by concatenating additional devices "
863 		    "totaling at least %s blocks, or by increasing the size "
864 		    "of the specified component by exactly %s blocks."),
865 		    ep->extra, ep->extra);
866 		break;
867 	case MDE_STRIPE_TRUNC_MULTIPLE:
868 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
869 		    "The necessary rounding would result in data loss.  "
870 		    "You can avoid this by concatenating additional devices "
871 		    "totaling at least %s blocks."), ep->extra);
872 		break;
873 	case MDE_SMF_FAIL:
874 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
875 		    "failed to enable/disable SVM service"));
876 		break;
877 	case MDE_SMF_NO_SERVICE:
878 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
879 		    "service(s) not online in SMF"));
880 		break;
881 	default:
882 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
883 		    "unknown void error code %d"), ip->errnum);
884 		break;
885 	}
886 
887 	return (buf);
888 }
889 
890 /*
891  * print sys class errors
892  */
893 static char *
894 sys_to_str(
895 	md_error_t	*ep,
896 	char		*buf,
897 	size_t		size
898 )
899 {
900 	md_sys_error_t	*ip = &ep->info.md_error_info_t_u.sys_error;
901 	char		*emsg;
902 	char		*p = buf + strlen(buf);
903 	size_t		psize = size - strlen(buf);
904 
905 	if ((emsg = strerror(ip->errnum)) == NULL) {
906 		(void) snprintf(p, psize,
907 		    dgettext(TEXT_DOMAIN, "unknown errno %d out of range"),
908 		    ip->errnum);
909 	} else {
910 		(void) snprintf(p, psize, "%s", emsg);
911 	}
912 
913 	return (buf);
914 }
915 
916 /*
917  * print RPC class errors
918  */
919 static char *
920 rpc_to_str(
921 	md_error_t	*ep,
922 	char		*buf,
923 	size_t		size
924 )
925 {
926 	md_rpc_error_t	*ip = &ep->info.md_error_info_t_u.rpc_error;
927 	char		*p = buf + strlen(buf);
928 	size_t		psize = size - strlen(buf);
929 
930 	(void) snprintf(p, psize, "%s", clnt_sperrno(ip->errnum));
931 	return (buf);
932 }
933 
934 /*
935  * print dev class errors
936  */
937 static char *
938 dev_to_str(
939 	md_error_t	*ep,
940 	char		*buf,
941 	size_t		size
942 )
943 {
944 	md_dev_error_t	*ip = &ep->info.md_error_info_t_u.dev_error;
945 	char		*p = buf + strlen(buf);
946 	size_t		psize = size - strlen(buf);
947 
948 	switch (ip->errnum) {
949 	case MDE_INVAL_HS:
950 		(void) snprintf(p, psize,
951 		    dgettext(TEXT_DOMAIN, "hotspare doesn't exist"));
952 		break;
953 	case MDE_FIX_INVAL_STATE:
954 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
955 		    "cannot enable hotspared device"));
956 		break;
957 	case MDE_FIX_INVAL_HS_STATE:
958 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
959 		    "hotspare isn't broken, can't enable"));
960 		break;
961 	case MDE_NOT_META:
962 		(void) snprintf(p, psize,
963 		    dgettext(TEXT_DOMAIN, "not a metadevice"));
964 		break;
965 	case MDE_IS_DUMP:
966 		(void) snprintf(p, psize,
967 		    dgettext(TEXT_DOMAIN, "is a dump device"));
968 		break;
969 	case MDE_IS_META:
970 		(void) snprintf(p, psize,
971 		    dgettext(TEXT_DOMAIN, "is a metadevice"));
972 		break;
973 	case MDE_IS_SWAPPED:
974 		(void) snprintf(p, psize,
975 		    dgettext(TEXT_DOMAIN, "is swapped on"));
976 		break;
977 	case MDE_NAME_SPACE:
978 		(void) snprintf(p, psize,
979 		    dgettext(TEXT_DOMAIN, "namespace error"));
980 		break;
981 	case MDE_IN_SHARED_SET:
982 		(void) snprintf(p, psize,
983 		    dgettext(TEXT_DOMAIN, "device in shared set"));
984 		break;
985 	case MDE_NOT_IN_SET:
986 		(void) snprintf(p, psize,
987 		    dgettext(TEXT_DOMAIN, "device not in set"));
988 		break;
989 	case MDE_NOT_DISK:
990 		(void) snprintf(p, psize,
991 		    dgettext(TEXT_DOMAIN, "not a disk device"));
992 		break;
993 	case MDE_CANT_CONFIRM:
994 		(void) snprintf(p, psize,
995 		    dgettext(TEXT_DOMAIN, "can't confirm device"));
996 		break;
997 	case MDE_INVALID_PART:
998 		(void) snprintf(p, psize,
999 		    dgettext(TEXT_DOMAIN, "invalid partition"));
1000 		break;
1001 	case MDE_HAS_MDDB:
1002 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1003 		    "has a metadevice database replica"));
1004 		break;
1005 	case MDE_NO_DB:
1006 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1007 		    "no metadevice database replica on device"));
1008 		break;
1009 	case MDE_CANTVERIFY_VTOC:
1010 		(void) snprintf(p, psize,
1011 		    dgettext(TEXT_DOMAIN, "unable to verify the vtoc"));
1012 		break;
1013 	case MDE_NOT_LOCAL:
1014 		(void) snprintf(p, psize,
1015 		    dgettext(TEXT_DOMAIN, "not in local set"));
1016 		break;
1017 	case MDE_DEVICES_NAME:
1018 		(void) snprintf(p, psize,
1019 		    dgettext(TEXT_DOMAIN, "can't parse /devices name"));
1020 		break;
1021 	case MDE_REPCOMP_INVAL:
1022 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1023 		    "replica slice is not usable as a metadevice component"));
1024 		break;
1025 	case MDE_REPCOMP_ONLY:
1026 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1027 		    "only replica slice is usable for a diskset "
1028 		    "database replica"));
1029 		break;
1030 	case MDE_INV_ROOT:
1031 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1032 		    "invalid root device for this operation"));
1033 		break;
1034 	case MDE_MULTNM:
1035 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1036 		    "multiple entries for device in Solaris Volume Manager "
1037 		    "configuration"));
1038 		break;
1039 	case MDE_TOO_MANY_PARTS:
1040 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1041 		    "Disks with more than %d partitions are not supported "
1042 		    "in Solaris Volume Manager"), MD_MAX_PARTS);
1043 		break;
1044 	case MDE_REPART_REPLICA:
1045 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1046 		    "cannot repartition a slice with an existing replica"));
1047 		break;
1048 	default:
1049 		(void) snprintf(p, psize,
1050 		    dgettext(TEXT_DOMAIN, "unknown dev error code %d"),
1051 		    ip->errnum);
1052 		break;
1053 	}
1054 
1055 	return (buf);
1056 }
1057 
1058 /*
1059  * print overlap class errors
1060  */
1061 static char *
1062 overlap_to_str(
1063 	md_error_t	*ep,
1064 	char		*buf,
1065 	size_t		size
1066 )
1067 {
1068 	md_overlap_error_t	*ip =
1069 			&ep->info.md_error_info_t_u.overlap_error;
1070 	char		*p = buf + strlen(buf);
1071 	size_t		psize = size - strlen(buf);
1072 
1073 	switch (ip->errnum) {
1074 	case MDE_OVERLAP_MOUNTED:
1075 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1076 		    "overlaps with %s which is mounted as \'%s\'"),
1077 			ip->overlap, ip->where);
1078 		break;
1079 	case MDE_OVERLAP_SWAP:
1080 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1081 		    "overlaps with %s which is a swap device"), ip->overlap);
1082 		break;
1083 	case MDE_OVERLAP_DUMP:
1084 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1085 		    "overlaps with %s which is the dump device"), ip->overlap);
1086 		break;
1087 	default:
1088 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1089 		    "unknown overlap error code %d"), ip->errnum);
1090 		break;
1091 	}
1092 
1093 	return (buf);
1094 }
1095 
1096 /*
1097  * print use class errors
1098  */
1099 static char *
1100 use_to_str(
1101 	md_error_t	*ep,
1102 	char		*buf,
1103 	size_t		size
1104 )
1105 {
1106 	md_use_error_t	*ip = &ep->info.md_error_info_t_u.use_error;
1107 	char		*p = buf + strlen(buf);
1108 	size_t		psize = size - strlen(buf);
1109 
1110 	switch (ip->errnum) {
1111 	case MDE_IS_MOUNTED:
1112 		(void) snprintf(p, psize,
1113 		    dgettext(TEXT_DOMAIN, "is mounted on %s"),
1114 		    ip->where);
1115 		break;
1116 	case MDE_ALREADY:
1117 		/*
1118 		 * when the object of the error (existing device that
1119 		 * would being used by SVM) is the metadb then it is necessary
1120 		 * to explicitly specify the string in the error message so
1121 		 * that it can be successfully localized for the Asian locales.
1122 		 */
1123 		if (strcmp(ip->where, MDB_STR) != 0) {
1124 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1125 				"has appeared more than once in the "
1126 				"specification of %s"), ip->where);
1127 		} else {
1128 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1129 				"has appeared more than once in the "
1130 				"specification of " MDB_STR));
1131 		}
1132 		break;
1133 	case MDE_OVERLAP:
1134 		/*
1135 		 * when the object of the error (existing device that
1136 		 * would overlap) is the metadb then it is necessary
1137 		 * to explicitly specify the string in the error message so
1138 		 * that it can be successfully localized for the Asian locales.
1139 		 */
1140 		if (strcmp(ip->where, MDB_STR) != 0) {
1141 			(void) snprintf(p, psize,
1142 			    dgettext(TEXT_DOMAIN, "overlaps with device in %s"),
1143 			    ip->where);
1144 		} else {
1145 			(void) snprintf(p, psize,
1146 			    dgettext(TEXT_DOMAIN, "overlaps with device in "
1147 			    MDB_STR));
1148 		}
1149 		break;
1150 	case MDE_SAME_DEVID:
1151 		/*
1152 		 * when the object of the error (existing device in the
1153 		 * metaconfiguration that has the same devid)
1154 		 * is the metadb then it is necessary
1155 		 * to explicitly specify the string in the error message so
1156 		 * that it can be successfully localized for the Asian locales.
1157 		 */
1158 		if (strcmp(ip->where, MDB_STR) != 0) {
1159 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1160 			    "identical devid detected on %s"), ip->where);
1161 		} else {
1162 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1163 			    "identical devid detected in " MDB_STR));
1164 		}
1165 		break;
1166 	default:
1167 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1168 		    "unknown dev error code %d"), ip->errnum);
1169 		break;
1170 	}
1171 
1172 	return (buf);
1173 }
1174 
1175 /*
1176  * print md class errors
1177  */
1178 static char *
1179 md_to_str(
1180 	md_error_t	*ep,
1181 	char		*buf,
1182 	size_t		size
1183 )
1184 {
1185 	md_md_error_t	*ip = &ep->info.md_error_info_t_u.md_error;
1186 	char		*p = buf + strlen(buf);
1187 	size_t		psize = size - strlen(buf);
1188 
1189 	switch (ip->errnum) {
1190 	case MDE_INVAL_UNIT:
1191 		(void) snprintf(p, psize,
1192 		    dgettext(TEXT_DOMAIN, "invalid unit"));
1193 		break;
1194 	case MDE_UNIT_NOT_SETUP:
1195 		(void) snprintf(p, psize,
1196 		    dgettext(TEXT_DOMAIN, "unit not set up"));
1197 		break;
1198 	case MDE_UNIT_ALREADY_SETUP:
1199 		(void) snprintf(p, psize,
1200 		    dgettext(TEXT_DOMAIN, "unit already set up"));
1201 		break;
1202 	case MDE_NOT_MM:
1203 		(void) snprintf(p, psize,
1204 		    dgettext(TEXT_DOMAIN, "unit is not a mirror"));
1205 		break;
1206 	case MDE_IS_SM:
1207 		(void) snprintf(p, psize,
1208 		    dgettext(TEXT_DOMAIN, "illegal to clear submirror"));
1209 		break;
1210 	case MDE_IS_OPEN:
1211 		(void) snprintf(p, psize,
1212 		    dgettext(TEXT_DOMAIN, "metadevice is open"));
1213 		break;
1214 	case MDE_C_WITH_INVAL_SM:
1215 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1216 		    "attempted to clear mirror with submirror(s) "
1217 		    "in invalid state"));
1218 		break;
1219 	case MDE_RESYNC_ACTIVE:
1220 		(void) snprintf(p, psize,
1221 		    dgettext(TEXT_DOMAIN, "resync in progress"));
1222 		break;
1223 	case MDE_LAST_SM_RE:
1224 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1225 		    "attempt to replace a component on the last "
1226 		    "running submirror"));
1227 		break;
1228 	case MDE_MIRROR_FULL:
1229 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1230 		    "mirror has maximum number of submirrors"));
1231 		break;
1232 	case MDE_IN_UNAVAIL_STATE:
1233 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1234 		    "component is in unavailable state; run 'metastat -i'"));
1235 		break;
1236 	case MDE_IN_USE:
1237 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1238 		    "metadevice in use"));
1239 		break;
1240 	case MDE_SM_TOO_SMALL:
1241 		(void) snprintf(p, psize,
1242 		    dgettext(TEXT_DOMAIN, "submirror too small to attach"));
1243 		break;
1244 	case MDE_NO_LABELED_SM:
1245 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1246 		    "can't attach labeled submirror to an unlabeled mirror"));
1247 		break;
1248 	case MDE_SM_OPEN_ERR:
1249 		(void) snprintf(p, psize,
1250 		    dgettext(TEXT_DOMAIN, "submirror open error"));
1251 		break;
1252 	case MDE_CANT_FIND_SM:
1253 		(void) snprintf(p, psize,
1254 		    dgettext(TEXT_DOMAIN, "can't find submirror in mirror"));
1255 		break;
1256 	case MDE_LAST_SM:
1257 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1258 			"attempt to detach last running submirror"));
1259 		break;
1260 	case MDE_NO_READABLE_SM:
1261 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1262 		    "operation would result in no readable submirrors"));
1263 		break;
1264 	case MDE_SM_FAILED_COMPS:
1265 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1266 		    "attempt an operation on a submirror "
1267 		    "that has erred components"));
1268 		break;
1269 	case MDE_ILLEGAL_SM_STATE:
1270 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1271 		    "attempt operation on a submirror in illegal state"));
1272 		break;
1273 	case MDE_RR_ALLOC_ERROR:
1274 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1275 		    "attach failed, unable to allocate new resync info"));
1276 		break;
1277 	case MDE_MIRROR_OPEN_FAILURE:
1278 		(void) snprintf(p, psize,
1279 		    dgettext(TEXT_DOMAIN, "insufficient devices to open"));
1280 		break;
1281 	case MDE_MIRROR_THREAD_FAILURE:
1282 		(void) snprintf(p, psize,
1283 		    dgettext(TEXT_DOMAIN, "mirror thread failure"));
1284 		break;
1285 	case MDE_GROW_DELAYED:
1286 		(void) snprintf(p, psize,
1287 		    dgettext(TEXT_DOMAIN, "growing of metadevice delayed"));
1288 		break;
1289 	case MDE_NOT_MT:
1290 		(void) snprintf(p, psize,
1291 		    dgettext(TEXT_DOMAIN, "unit is not a trans"));
1292 		break;
1293 	case MDE_HS_IN_USE:
1294 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1295 		    "can't modify hot spare pool, hot spare in use"));
1296 		break;
1297 	case MDE_HAS_LOG:
1298 		(void) snprintf(p, psize,
1299 		    dgettext(TEXT_DOMAIN, "already has log"));
1300 		break;
1301 	case MDE_UNKNOWN_TYPE:
1302 		(void) snprintf(p, psize,
1303 		    dgettext(TEXT_DOMAIN, "unknown metadevice type"));
1304 		break;
1305 	case MDE_NOT_STRIPE:
1306 		(void) snprintf(p, psize,
1307 		    dgettext(TEXT_DOMAIN, "unit is not a concat/stripe"));
1308 		break;
1309 	case MDE_NOT_RAID:
1310 		(void) snprintf(p, psize,
1311 		    dgettext(TEXT_DOMAIN, "unit is not a RAID"));
1312 		break;
1313 	case MDE_NROWS:
1314 		(void) snprintf(p, psize,
1315 		    dgettext(TEXT_DOMAIN, "not enough stripes specified"));
1316 		break;
1317 	case MDE_NCOMPS:
1318 		(void) snprintf(p, psize,
1319 		    dgettext(TEXT_DOMAIN, "not enough components specified"));
1320 		break;
1321 	case MDE_NSUBMIRS:
1322 		(void) snprintf(p, psize,
1323 		    dgettext(TEXT_DOMAIN, "not enough submirrors specified"));
1324 		break;
1325 	case MDE_BAD_STRIPE:
1326 		(void) snprintf(p, psize,
1327 		    dgettext(TEXT_DOMAIN, "invalid stripe configuration"));
1328 		break;
1329 	case MDE_BAD_MIRROR:
1330 		(void) snprintf(p, psize,
1331 		    dgettext(TEXT_DOMAIN, "invalid mirror configuration"));
1332 		break;
1333 	case MDE_BAD_TRANS:
1334 		(void) snprintf(p, psize,
1335 		    dgettext(TEXT_DOMAIN, "invalid trans configuration"));
1336 		break;
1337 	case MDE_BAD_RAID:
1338 		(void) snprintf(p, psize,
1339 		    dgettext(TEXT_DOMAIN, "invalid RAID configuration"));
1340 		break;
1341 	case MDE_RAID_OPEN_FAILURE:
1342 		(void) snprintf(p, psize,
1343 		    dgettext(TEXT_DOMAIN, "resync unable to open RAID unit"));
1344 		break;
1345 	case MDE_RAID_THREAD_FAILURE:
1346 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1347 		    "attempt to start resync thread failed"));
1348 		break;
1349 	case MDE_RAID_NEED_FORCE:
1350 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1351 		    "operation requires -f (force) flag"));
1352 		break;
1353 	case MDE_NO_LOG:
1354 		(void) snprintf(p, psize,
1355 		    dgettext(TEXT_DOMAIN, "log has already been detached"));
1356 		break;
1357 	case MDE_RAID_DOI:
1358 		(void) snprintf(p, psize,
1359 		    dgettext(TEXT_DOMAIN, "only valid action is metaclear"));
1360 		break;
1361 	case MDE_RAID_LAST_ERRED:
1362 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1363 		    "in Last Erred state, "
1364 		    "errored components must be replaced"));
1365 		break;
1366 	case MDE_RAID_NOT_OKAY:
1367 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1368 		    "all components must be Okay to perform this operation"));
1369 		break;
1370 	case MDE_RENAME_BUSY:
1371 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1372 		    "metadevice is temporarily too busy for renames"));
1373 		break;
1374 	case MDE_RENAME_SOURCE_BAD:
1375 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1376 		    "source metadevice is not able to be renamed"));
1377 		break;
1378 	case MDE_RENAME_TARGET_BAD:
1379 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1380 		    "target metadevice is not able to be renamed"));
1381 		break;
1382 	case MDE_RENAME_TARGET_UNRELATED:
1383 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1384 		    "target metadevice is not related to source metadevice"));
1385 		break;
1386 	case MDE_RENAME_CONFIG_ERROR:
1387 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1388 		    "metadevice driver configuration error; "
1389 		    "rename can't occur"));
1390 		break;
1391 	case MDE_RENAME_ORDER:
1392 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1393 		    "units may not be renamed in that order"));
1394 		break;
1395 	case MDE_RECOVER_FAILED:
1396 		(void) snprintf(p, psize,
1397 		    dgettext(TEXT_DOMAIN, "recovery failed"));
1398 		break;
1399 	case MDE_SP_NOSPACE:
1400 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1401 		    "not enough space available for request"));
1402 		break;
1403 	case MDE_SP_BADWMREAD:
1404 		(void) snprintf(p, psize,
1405 		    dgettext(TEXT_DOMAIN, "error reading extent header"));
1406 		break;
1407 	case MDE_SP_BADWMWRITE:
1408 		(void) snprintf(p, psize,
1409 		    dgettext(TEXT_DOMAIN, "error writing extent header"));
1410 		break;
1411 	case MDE_SP_BADWMMAGIC:
1412 		(void) snprintf(p, psize,
1413 		    dgettext(TEXT_DOMAIN, "bad magic number in extent header"));
1414 		break;
1415 	case MDE_SP_BADWMCRC:
1416 		(void) snprintf(p, psize,
1417 		    dgettext(TEXT_DOMAIN, "bad checksum in extent header"));
1418 		break;
1419 	case MDE_NOT_SP:
1420 		(void) snprintf(p, psize,
1421 		    dgettext(TEXT_DOMAIN, "unit is not a soft partition"));
1422 		break;
1423 	case MDE_SP_OVERLAP:
1424 		(void) snprintf(p, psize,
1425 		    dgettext(TEXT_DOMAIN, "overlapping extents specified"));
1426 		break;
1427 	case MDE_SP_BAD_LENGTH:
1428 		(void) snprintf(p, psize,
1429 		    dgettext(TEXT_DOMAIN, "bad length specified"));
1430 		break;
1431 	case MDE_SP_NOSP:
1432 		(void) snprintf(p, psize,
1433 		    dgettext(TEXT_DOMAIN, "no soft partitions on this device"));
1434 		break;
1435 	case MDE_UNIT_TOO_LARGE:
1436 		(void) snprintf(p, psize,
1437 		    dgettext(TEXT_DOMAIN, "Volume size cannot exceed 1 TByte"));
1438 		break;
1439 	case MDE_LOG_TOO_LARGE:
1440 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1441 		    "Trans log size must be less than 1 TByte"));
1442 		break;
1443 	default:
1444 		(void) snprintf(p, psize,
1445 		    dgettext(TEXT_DOMAIN, "unknown md error code %d"),
1446 		    ip->errnum);
1447 		break;
1448 	}
1449 
1450 	return (buf);
1451 }
1452 
1453 /*
1454  * print comp class errors
1455  */
1456 static char *
1457 comp_to_str(
1458 	md_error_t	*ep,
1459 	char		*buf,
1460 	size_t		size
1461 )
1462 {
1463 	md_comp_error_t	*ip = &ep->info.md_error_info_t_u.comp_error;
1464 	char		*p = buf + strlen(buf);
1465 	size_t		psize = size - strlen(buf);
1466 
1467 	switch (ip->errnum) {
1468 	case MDE_CANT_FIND_COMP:
1469 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1470 		    "can't find component in unit"));
1471 		break;
1472 	case MDE_REPL_INVAL_STATE:
1473 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1474 		    "component in invalid state to replace - "
1475 		    "Replace \"Maintenance\" components first"));
1476 		break;
1477 	case MDE_COMP_TOO_SMALL:
1478 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1479 		    "replace failure, new component is too small"));
1480 		break;
1481 	case MDE_COMP_OPEN_ERR:
1482 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1483 		    "unable to open concat/stripe component"));
1484 		break;
1485 	case MDE_RAID_COMP_ERRED:
1486 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1487 		    "must replace errored component first"));
1488 		break;
1489 	case MDE_MAXIO:
1490 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1491 		    "maxtransfer is too small"));
1492 		break;
1493 	case MDE_SP_COMP_OPEN_ERR:
1494 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1495 		    "error opening device under soft partition. Check"
1496 		    " device status, then use metadevadm(1M)."));
1497 		break;
1498 	default:
1499 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1500 		    "unknown comp error code %d"), ip->errnum);
1501 		break;
1502 	}
1503 
1504 	return (buf);
1505 }
1506 
1507 /*
1508  * print hsp class errors
1509  */
1510 static char *
1511 hsp_to_str(
1512 	md_error_t	*ep,
1513 	char		*buf,
1514 	size_t		size
1515 )
1516 {
1517 	md_hsp_error_t	*ip = &ep->info.md_error_info_t_u.hsp_error;
1518 	char		*p = buf + strlen(buf);
1519 	size_t		psize = size - strlen(buf);
1520 
1521 	switch (ip->errnum) {
1522 	case MDE_HSP_CREATE_FAILURE:
1523 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1524 		    "hotspare pool database create failure"));
1525 		break;
1526 	case MDE_HSP_IN_USE:
1527 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1528 		    "hotspare pool in use"));
1529 		break;
1530 	case MDE_INVAL_HSP:
1531 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1532 		    "invalid hotspare pool"));
1533 		break;
1534 	case MDE_HSP_BUSY:
1535 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1536 		    "hotspare pool is busy"));
1537 		break;
1538 	case MDE_HSP_REF:
1539 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1540 		    "hotspare pool is referenced"));
1541 		break;
1542 	case MDE_HSP_ALREADY_SETUP:
1543 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1544 		    "hotspare pool is already setup"));
1545 		break;
1546 	case MDE_BAD_HSP:
1547 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1548 		    "invalid hotspare pool configuration"));
1549 		break;
1550 	case MDE_HSP_UNIT_TOO_LARGE:
1551 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1552 		    "units in the hotspare pool cannot exceed 1 TByte"));
1553 		break;
1554 	default:
1555 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1556 		    "unknown hsp error code %d"), ip->errnum);
1557 		break;
1558 	}
1559 
1560 	return (buf);
1561 }
1562 
1563 /*
1564  * print hs class errors
1565  */
1566 static char *
1567 hs_to_str(
1568 	md_error_t	*ep,
1569 	char		*buf,
1570 	size_t		size
1571 )
1572 {
1573 	md_hs_error_t	*ip = &ep->info.md_error_info_t_u.hs_error;
1574 	char		*p = buf + strlen(buf);
1575 	size_t		psize = size - strlen(buf);
1576 
1577 	switch (ip->errnum) {
1578 	case MDE_HS_RESVD:
1579 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1580 		    "hotspare is in use"));
1581 		break;
1582 	case MDE_HS_CREATE_FAILURE:
1583 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1584 		    "hotspare database create failure"));
1585 		break;
1586 	case MDE_HS_INUSE:
1587 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1588 		    "add or replace failed, hot spare is already in use"));
1589 		break;
1590 	case MDE_HS_UNIT_TOO_LARGE:
1591 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1592 		    "hotspare size cannot exceed 1 TByte"));
1593 		break;
1594 	default:
1595 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1596 		    "unknown hs error code %d"), ip->errnum);
1597 		break;
1598 	}
1599 
1600 	return (buf);
1601 }
1602 
1603 /*
1604  * print mddb class errors
1605  */
1606 static char *
1607 mddb_to_str(
1608 	md_error_t	*ep,
1609 	char		*buf,
1610 	size_t		size
1611 )
1612 {
1613 	md_mddb_error_t	*ip = &ep->info.md_error_info_t_u.mddb_error;
1614 	char		*p = buf + strlen(buf);
1615 	size_t		psize = size - strlen(buf);
1616 
1617 	switch (ip->errnum) {
1618 	case MDE_TOOMANY_REPLICAS:
1619 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1620 	"%d metadevice database replicas is too many; the maximum is %d"),
1621 		    ip->size, MDDB_NLB);
1622 		break;
1623 	case MDE_REPLICA_TOOSMALL:
1624 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1625 	"device size %d is too small for metadevice database replica"),
1626 		    ip->size);
1627 		break;
1628 	case MDE_NOTVERIFIED:
1629 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1630 		    "data not returned correctly from disk"));
1631 		break;
1632 	case MDE_DB_INVALID:
1633 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1634 		    "invalid argument"));
1635 		break;
1636 	case MDE_DB_EXISTS:
1637 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1638 		    "metadevice database replica exists on device"));
1639 		break;
1640 	case MDE_DB_MASTER:
1641 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1642 		    "has bad master block on device"));
1643 		break;
1644 	case MDE_DB_TOOSMALL:
1645 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1646 		    "device is too small"));
1647 		break;
1648 	case MDE_DB_NORECORD:
1649 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1650 		    "no such metadevice database record"));
1651 		break;
1652 	case MDE_DB_NOSPACE:
1653 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1654 		    "metadevice database is full, can't create new records"));
1655 		break;
1656 	case MDE_DB_NOTNOW:
1657 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1658 		    "metadevice database has too few replicas, for "
1659 		    "metadevice database operation"));
1660 		break;
1661 	case MDE_DB_NODB:
1662 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1663 		    "there are no existing databases"));
1664 		break;
1665 	case MDE_DB_NOTOWNER:
1666 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1667 		    "not owner of metadevice database"));
1668 		break;
1669 	case MDE_DB_STALE:
1670 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1671 		    "stale databases"));
1672 		break;
1673 	case MDE_DB_TOOFEW:
1674 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1675 		    "not enough databases"));
1676 		break;
1677 	case MDE_DB_TAGDATA:
1678 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1679 		    "tagged data detected, user intervention required"));
1680 		break;
1681 	case MDE_DB_ACCOK:
1682 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1683 		    "50% replicas & 50% mediator hosts available, "
1684 		    "user intervention required"));
1685 		break;
1686 	case MDE_DB_NTAGDATA:
1687 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1688 		    "no tagged data available or only one tag found"));
1689 		break;
1690 	case MDE_DB_ACCNOTOK:
1691 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1692 		    "50% replicas & 50% mediator hosts not available"));
1693 		break;
1694 	case MDE_DB_NOLOCBLK:
1695 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1696 		    "no valid locator blocks were found"));
1697 		break;
1698 	case MDE_DB_NOLOCNMS:
1699 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1700 		    "no valid locator name information was found"));
1701 		break;
1702 	case MDE_DB_NODIRBLK:
1703 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1704 		    "no valid directory blocks were found"));
1705 		break;
1706 	case MDE_DB_NOTAGREC:
1707 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1708 		    "no tag record was allocated, so data "
1709 		    "tagging is disabled"));
1710 		break;
1711 	case MDE_DB_NOTAG:
1712 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1713 		    "no tag records exist or no matching tag was found"));
1714 		break;
1715 	case MDE_DB_BLKRANGE:
1716 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1717 		    "logical block number %d out of range"), ip->size);
1718 		break;
1719 	default:
1720 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1721 		    "unknown mddb error code %d"), ip->errnum);
1722 		break;
1723 	}
1724 
1725 	return (buf);
1726 }
1727 
1728 /*
1729  * print diskset (ds) class errors
1730  */
1731 static char *
1732 ds_to_str(
1733 	md_error_t	*ep,
1734 	char		*buf,
1735 	size_t		size
1736 )
1737 {
1738 	md_ds_error_t	*ip = &ep->info.md_error_info_t_u.ds_error;
1739 	char		*p = buf + strlen(buf);
1740 	size_t		psize = size - strlen(buf);
1741 
1742 	switch (ip->errnum) {
1743 	case MDE_DS_DUPHOST:
1744 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1745 		    "host %s is specified more than once"), ip->node);
1746 		break;
1747 	case MDE_DS_NOTNODENAME:
1748 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1749 		    "\"%s\" is not a nodename, but a network name"), ip->node);
1750 		break;
1751 	case MDE_DS_SELFNOTIN:
1752 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1753 		    "nodename of host %s creating the set must be included"),
1754 		    ip->node);
1755 		break;
1756 	case MDE_DS_NODEHASSET:
1757 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1758 		    "host %s already has set"), ip->node);
1759 		break;
1760 	case MDE_DS_NODENOSET:
1761 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1762 		    "host %s does not have set"), ip->node);
1763 		break;
1764 	case MDE_DS_NOOWNER:
1765 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1766 		    "must be owner of the set for this command"));
1767 		break;
1768 	case MDE_DS_NOTOWNER:
1769 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1770 		    "only the current owner %s may operate on this set"),
1771 		    ip->node);
1772 		break;
1773 	case MDE_DS_NODEISNOTOWNER:
1774 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1775 		    "host %s is not the owner"), ip->node);
1776 		break;
1777 	case MDE_DS_NODEINSET:
1778 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1779 		    "host %s is already in the set"), ip->node);
1780 		break;
1781 	case MDE_DS_NODENOTINSET:
1782 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1783 		    "host %s is not in the set"), ip->node);
1784 		break;
1785 	case MDE_DS_SETNUMBUSY:
1786 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1787 		    "host %s already has a set numbered %ld"),
1788 		    ip->node, ip->setno);
1789 		break;
1790 	case MDE_DS_SETNUMNOTAVAIL:
1791 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1792 		    "no available set numbers"));
1793 		break;
1794 	case MDE_DS_SETNAMEBUSY:
1795 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1796 		    "set name is in-use or invalid on host %s"), ip->node);
1797 		break;
1798 	case MDE_DS_DRIVENOTCOMMON:
1799 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1800 		    "drive %s is not common with host %s"),
1801 		    ip->drive, ip->node);
1802 		break;
1803 	case MDE_DS_DRIVEINSET:
1804 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1805 		    "drive %s is in set %s"), ip->drive, ip->node);
1806 		break;
1807 	case MDE_DS_DRIVENOTINSET:
1808 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1809 		    "drive %s is not in set"), ip->drive);
1810 		break;
1811 	case MDE_DS_DRIVEINUSE:
1812 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1813 		    "drive %s is in use"), ip->drive);
1814 		break;
1815 	case MDE_DS_DUPDRIVE:
1816 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1817 		    "drive %s is specified more than once"), ip->drive);
1818 		break;
1819 	case MDE_DS_INVALIDSETNAME:
1820 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1821 		    "set name contains invalid characters"));
1822 		break;
1823 	case MDE_DS_HASDRIVES:
1824 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1825 		    "unable to delete set, it still has drives"));
1826 		break;
1827 	case MDE_DS_SIDENUMNOTAVAIL:
1828 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1829 		    "maximum number of nodenames exceeded"));
1830 		break;
1831 	case MDE_DS_SETNAMETOOLONG:
1832 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1833 		    "set name is too long"));
1834 		break;
1835 	case MDE_DS_NODENAMETOOLONG:
1836 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1837 		    "host name %s is too long"), ip->node);
1838 		break;
1839 	case MDE_DS_OHACANTDELSELF:
1840 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1841 "administrator host %s deletion disallowed in one host admin mode"),
1842 		    ip->node);
1843 		break;
1844 	case MDE_DS_HOSTNOSIDE:
1845 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1846 		    "side information missing for host %s"), ip->node);
1847 		break;
1848 	case MDE_DS_SETLOCKED:
1849 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1850 	    "host %s is modifying set - try later or restart rpc.metad"),
1851 		    ip->drive);
1852 		break;
1853 	case MDE_DS_ULKSBADKEY:
1854 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1855 		    "set unlock failed - bad key"));
1856 		break;
1857 	case MDE_DS_LKSBADKEY:
1858 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1859 		    "set lock failed - bad key"));
1860 		break;
1861 	case MDE_DS_WRITEWITHSULK:
1862 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1863 		    "write operation attempted on set with set unlocked"));
1864 		break;
1865 	case MDE_DS_SETCLEANUP:
1866 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1867 		    "set \"%s\" is out of date - cleaning up - take failed"),
1868 		    ip->node);
1869 		break;
1870 	case MDE_DS_CANTDELSELF:
1871 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1872 "administrator host %s can't be deleted, other hosts still in set\n"
1873 "Use -f to override"), ip->node);
1874 		break;
1875 	case MDE_DS_HASMED:
1876 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1877 		    "unable to delete set, it still has mediator hosts"));
1878 		break;
1879 	case MDE_DS_TOOMANYALIAS:
1880 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1881 		    "%s causes there to be more aliases than allowed"),
1882 		    ip->node);
1883 		break;
1884 	case MDE_DS_ISMED:
1885 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1886 		    "%s is already a mediator host"), ip->node);
1887 		break;
1888 	case MDE_DS_ISNOTMED:
1889 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1890 		    "%s is not a mediator host"), ip->node);
1891 		break;
1892 	case MDE_DS_INVALIDMEDNAME:
1893 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1894 		    "mediator name \"%s\" contains invalid characters"),
1895 		    ip->node);
1896 		break;
1897 	case MDE_DS_ALIASNOMATCH:
1898 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1899 		    "mediator alias \"%s\" is not an alias for host "
1900 		    "\"%s\""), ip->node, ip->drive);
1901 		break;
1902 	case MDE_DS_NOMEDONHOST:
1903 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1904 		    "unable to contact %s on host \"%s\""),
1905 		    MED_SERVNAME, ip->node);
1906 		break;
1907 	case MDE_DS_DRIVENOTONHOST:
1908 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1909 		    "drive %s is not present on host %s"),
1910 		    ip->drive, ip->node);
1911 		break;
1912 	case MDE_DS_CANTDELMASTER:
1913 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1914 		    "master %s can't be deleted, other hosts still in set"),
1915 		    ip->node);
1916 		break;
1917 	case MDE_DS_NOTINMEMBERLIST:
1918 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1919 		    "node %s is not in membership list"),
1920 		    ip->node);
1921 		break;
1922 	case MDE_DS_MNCANTDELSELF:
1923 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1924 		    "host %s can't delete self from multi-owner set\n"
1925 		    "while other hosts still in set"),
1926 		    ip->node);
1927 		break;
1928 	case MDE_DS_RPCVERSMISMATCH:
1929 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1930 		    "host %s does not support multi-owner diskset"),
1931 		    ip->node);
1932 		break;
1933 	case MDE_DS_WITHDRAWMASTER:
1934 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1935 		    "master host %s cannot withdraw from multi-owner diskset "
1936 		    "when other owner nodes are still present in diskset"),
1937 		    ip->node);
1938 		break;
1939 	case MDE_DS_CANTRESNARF:
1940 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1941 		    "imported set could not be loaded"));
1942 		break;
1943 	case MDE_DS_INSUFQUORUM:
1944 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1945 		    "insufficient replica quorum detected. Use "
1946 		    "-f to force import of the set"));
1947 		break;
1948 	case MDE_DS_EXTENDEDNM:
1949 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1950 		    "multiple namespace records detected"));
1951 		break;
1952 	case MDE_DS_PARTIALSET:
1953 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1954 		    "partial diskset detected\n"
1955 		    "Please refer to the Solaris Volume Manager documentation,"
1956 		    "\nTroubleshooting section, at http://docs.sun.com or from"
1957 		    "\nyour local copy"));
1958 		break;
1959 	case MDE_DS_COMMDCTL_SUSPEND_NYD:
1960 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1961 		    "rpc.mdcommd on host %s is not yet drained during "
1962 		    "suspend operation"),
1963 		    ip->node);
1964 		break;
1965 	case MDE_DS_COMMDCTL_SUSPEND_FAIL:
1966 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1967 		    "rpc.mdcommd on host %s failed suspend operation"),
1968 		    ip->node);
1969 		break;
1970 	case MDE_DS_COMMDCTL_REINIT_FAIL:
1971 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1972 		    "rpc.mdcommd on host %s failed reinitialization operation"),
1973 		    ip->node);
1974 		break;
1975 	case MDE_DS_COMMDCTL_RESUME_FAIL:
1976 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1977 		    "rpc.mdcommd on host %s failed resume operation"),
1978 		    ip->node);
1979 		break;
1980 	case MDE_DS_NOTNOW_RECONFIG:
1981 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1982 		    "command terminated, host %s starting reconfig cycle"),
1983 		    ip->node);
1984 		break;
1985 	case MDE_DS_NOTNOW_CMD:
1986 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1987 		    "metaset or metadb command already running on diskset "
1988 		    "on host %s"), ip->node);
1989 		break;
1990 	case MDE_DS_COMMD_SEND_FAIL:
1991 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1992 		    "rpc.mdcommd on host %s failed operation"),
1993 		    ip->node);
1994 		break;
1995 	case MDE_DS_MASTER_ONLY:
1996 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
1997 		    "this command must be run on the master node of the set,"
1998 		    " which is currently %s"), ip->node);
1999 		break;
2000 	case MDE_DS_SINGLEHOST:
2001 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
2002 		    "diskset is auto-take; cannot accept additional hosts"));
2003 		break;
2004 	case MDE_DS_AUTONOTSET:
2005 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
2006 		    "auto-take is not enabled on diskset"));
2007 		break;
2008 	case MDE_DS_INVALIDDEVID:
2009 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
2010 		    "Invalid device id on drive %s on host %s"), ip->drive,
2011 		    ip->node);
2012 		break;
2013 	case MDE_DS_SETNOTIMP:
2014 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
2015 		    "Unable to import set on node %s"), ip->node);
2016 		break;
2017 	case MDE_DS_NOTSELFIDENTIFY:
2018 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
2019 		    "Drive %s won't be self identifying"), ip->drive);
2020 		break;
2021 	default:
2022 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
2023 		    "unknown diskset error code %d"), ip->errnum);
2024 		break;
2025 	}
2026 
2027 	return (buf);
2028 }
2029 
2030 /*
2031  * convert error to printable string
2032  */
2033 static char *
2034 mde_to_str(
2035 	md_error_t	*ep
2036 )
2037 {
2038 	static char	buf[BUFSIZ];
2039 	size_t		bufsz;
2040 
2041 	/* intialize buf */
2042 	buf[0] = '\0';
2043 	bufsz  = sizeof (buf);
2044 
2045 	/* class specific */
2046 	switch (ep->info.errclass) {
2047 	case MDEC_VOID:
2048 		return (void_to_str(ep, buf, bufsz));
2049 	case MDEC_SYS:
2050 		return (sys_to_str(ep, buf, bufsz));
2051 	case MDEC_RPC:
2052 		return (rpc_to_str(ep, buf, bufsz));
2053 	case MDEC_DEV:
2054 		return (dev_to_str(ep, buf, bufsz));
2055 	case MDEC_USE:
2056 		return (use_to_str(ep, buf, bufsz));
2057 	case MDEC_MD:
2058 		return (md_to_str(ep, buf, bufsz));
2059 	case MDEC_COMP:
2060 		return (comp_to_str(ep, buf, bufsz));
2061 	case MDEC_HSP:
2062 		return (hsp_to_str(ep, buf, bufsz));
2063 	case MDEC_HS:
2064 		return (hs_to_str(ep, buf, bufsz));
2065 	case MDEC_MDDB:
2066 		return (mddb_to_str(ep, buf, bufsz));
2067 	case MDEC_DS:
2068 		return (ds_to_str(ep, buf, bufsz));
2069 	case MDEC_OVERLAP:
2070 		return (overlap_to_str(ep, buf, bufsz));
2071 	default:
2072 		(void) snprintf(buf, bufsz,
2073 		    dgettext(TEXT_DOMAIN, "unknown error class %d"),
2074 		    ep->info.errclass);
2075 		return (buf);
2076 	}
2077 }
2078 
2079 /*
2080  * print log prefix
2081  */
2082 void
2083 md_logpfx(
2084 	FILE		*fp
2085 )
2086 {
2087 	time_t		t;
2088 	struct tm	*tm;
2089 	char		buf[100];
2090 
2091 	if ((time(&t) != (time_t)-1) &&
2092 	    ((tm = localtime(&t)) != NULL) &&
2093 	    (strftime(buf, sizeof (buf), (char *)0, tm) < sizeof (buf))) {
2094 		(void) fprintf(fp, "%s: ", buf);
2095 	}
2096 	(void) fprintf(fp, "%s: ", myname);
2097 }
2098 
2099 /*
2100  * varargs sperror()
2101  */
2102 /*PRINTFLIKE2*/
2103 static char *
2104 mde_vsperror(
2105 	md_error_t	*ep,
2106 	const char	*fmt,
2107 	va_list		ap
2108 )
2109 {
2110 	static char	buf[BUFSIZ];
2111 	size_t		bufsz = sizeof (buf);
2112 	char		*p = buf;
2113 	char		*host1 = "";
2114 	char		*host2 = "";
2115 	char		*extra1 = "";
2116 	char		*extra2 = "";
2117 	char		*name1 = "";
2118 	char		*name2 = "";
2119 
2120 	/* get stuff */
2121 	if ((ep->host != NULL) && (*(ep->host) != '\0')) {
2122 		host1 = ep->host;
2123 		host2 = ": ";
2124 	}
2125 	if ((ep->extra != NULL) && (*(ep->extra) != '\0')) {
2126 		extra1 = ep->extra;
2127 		extra2 = ": ";
2128 	}
2129 	if ((ep->name != NULL) && (*(ep->name) != '\0')) {
2130 		name1 = ep->name;
2131 		name2 = ": ";
2132 	}
2133 
2134 	/* context */
2135 	(void) snprintf(p, bufsz, "%s%s%s%s%s%s",
2136 	    host1, host2, extra1, extra2, name1, name2);
2137 	p = &buf[strlen(buf)];
2138 	bufsz -= strlen(buf);
2139 
2140 	/* user defined part */
2141 	if ((fmt != NULL) && (*fmt != '\0')) {
2142 		(void) vsnprintf(p, bufsz, fmt, ap);
2143 		p = &buf[strlen(buf)];
2144 		bufsz = sizeof (buf) - strlen(buf);
2145 		(void) snprintf(p, bufsz, ": ");
2146 		p = &buf[strlen(buf)];
2147 		bufsz = sizeof (buf) - strlen(buf);
2148 	}
2149 
2150 	/* error code */
2151 	(void) snprintf(p, bufsz, "%s\n", mde_to_str(ep));
2152 
2153 	/* return error message */
2154 	return (buf);
2155 }
2156 
2157 /*
2158  * printf-like sperror()
2159  */
2160 /*PRINTFLIKE2*/
2161 char *
2162 mde_sperror(
2163 	md_error_t	*ep,
2164 	const char	*fmt,
2165 	...
2166 )
2167 {
2168 	va_list		ap;
2169 	char		*emsg;
2170 
2171 	va_start(ap, fmt);
2172 	emsg = mde_vsperror(ep, fmt, ap);
2173 	va_end(ap);
2174 	return (emsg);
2175 }
2176 
2177 /*
2178  * printf-like perror()
2179  */
2180 /*PRINTFLIKE2*/
2181 void
2182 mde_perror(
2183 	md_error_t	*ep,
2184 	const char	*fmt,
2185 	...
2186 )
2187 {
2188 	va_list		ap;
2189 	char		*emsg;
2190 
2191 	/* get error message */
2192 	va_start(ap, fmt);
2193 	emsg = mde_vsperror(ep, fmt, ap);
2194 	va_end(ap);
2195 	assert((emsg != NULL) && (*emsg != '\0'));
2196 
2197 	/* stderr */
2198 	(void) fprintf(stderr, "%s: %s\n", myname, emsg);
2199 	(void) fflush(stderr);
2200 
2201 	/* metalog */
2202 	if (metalogfp != NULL) {
2203 		md_logpfx(metalogfp);
2204 		(void) fprintf(metalogfp, "%s\n", emsg);
2205 		(void) fflush(metalogfp);
2206 		(void) fsync(fileno(metalogfp));
2207 	}
2208 
2209 	/* syslog */
2210 	if (metasyslog) {
2211 		syslog(LOG_ERR, emsg);
2212 	}
2213 }
2214 
2215 /*
2216  * printf-like perror()
2217  */
2218 /*PRINTFLIKE1*/
2219 void
2220 md_perror(
2221 	const char	*fmt,
2222 	...
2223 )
2224 {
2225 	md_error_t	status = mdnullerror;
2226 	va_list		ap;
2227 	char		*emsg;
2228 
2229 	/* get error message */
2230 	(void) mdsyserror(&status, errno, NULL);
2231 	va_start(ap, fmt);
2232 	emsg = mde_vsperror(&status, fmt, ap);
2233 	va_end(ap);
2234 	assert((emsg != NULL) && (*emsg != '\0'));
2235 	mdclrerror(&status);
2236 
2237 	/* stderr */
2238 	(void) fprintf(stderr, "%s: %s\n", myname, emsg);
2239 	(void) fflush(stderr);
2240 
2241 	/* metalog */
2242 	if (metalogfp != NULL) {
2243 		md_logpfx(metalogfp);
2244 		(void) fprintf(metalogfp, "%s\n", emsg);
2245 		(void) fflush(metalogfp);
2246 		(void) fsync(fileno(metalogfp));
2247 	}
2248 
2249 	/* syslog */
2250 	if (metasyslog) {
2251 		syslog(LOG_ERR, emsg);
2252 	}
2253 }
2254 
2255 /*
2256  * printf-like log
2257  */
2258 /*PRINTFLIKE1*/
2259 void
2260 md_eprintf(
2261 	const char	*fmt,
2262 	...
2263 )
2264 {
2265 	va_list		ap;
2266 
2267 	/* begin */
2268 	va_start(ap, fmt);
2269 
2270 	/* stderr */
2271 	(void) fprintf(stderr, "%s: ", myname);
2272 	(void) vfprintf(stderr, fmt, ap);
2273 	(void) fflush(stderr);
2274 
2275 	/* metalog */
2276 	if (metalogfp != NULL) {
2277 		md_logpfx(metalogfp);
2278 		(void) vfprintf(metalogfp, fmt, ap);
2279 		(void) fflush(metalogfp);
2280 		(void) fsync(fileno(metalogfp));
2281 	}
2282 
2283 	/* syslog */
2284 	if (metasyslog) {
2285 		vsyslog(LOG_ERR, fmt, ap);
2286 	}
2287 
2288 	/* end */
2289 	va_end(ap);
2290 }
2291 
2292 /*
2293  * metaclust timing messages logging routine
2294  *
2295  * level	- The class of the message to be logged. Message will be logged
2296  *		  if this is less than or equal to the verbosity level.
2297  */
2298 void
2299 meta_mc_log(int level, const char *fmt, ...)
2300 {
2301 	va_list	args;
2302 
2303 	va_start(args, fmt);
2304 	/*
2305 	 * Log all messages upto MC_LOG2 to syslog regardless of the
2306 	 * verbosity level
2307 	 */
2308 	if (metasyslog && (level <= MC_LOG2)) {
2309 		if (level <= MC_LOG1)
2310 			(void) vsyslog(LOG_ERR, fmt, args);
2311 		else
2312 			(void) vsyslog(LOG_INFO, fmt, args);
2313 	}
2314 	/*
2315 	 * Print all messages to stderr provided the message level is
2316 	 * within the verbosity level
2317 	 */
2318 	if (level <= verbosity) {
2319 		(void) fprintf(stderr, "%s: ", myname);
2320 		(void) vfprintf(stderr, fmt, args);
2321 		(void) fprintf(stderr, "\n");
2322 		(void) fflush(stderr);
2323 	}
2324 	va_end(args);
2325 }
2326