/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1992, 2011, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Just in case we're not in a build environment, make sure that
* TEXT_DOMAIN gets set to something.
*/
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
/*
* print metedevice errors
*/
#include <meta.h>
#include <sys/lvm/md_mddb.h>
#include <syslog.h>
/*
* clear error
*/
void
mdclrerror(
md_error_t *ep
)
{
if (ep->name != NULL)
Free(ep->name);
if (ep->host != NULL)
Free(ep->host);
if (ep->extra != NULL)
Free(ep->extra);
(void) memset(ep, '\0', sizeof (*ep));
}
/*
* cook names
*/
static char *
md_name(
minor_t mnum
)
{
char *name;
/* get name, or fake it */
if ((name = get_mdname(NULL, mnum)) == NULL) {
char buf[40];
(void) sprintf(buf, "%lu/%lu", MD_MIN2SET(mnum),
MD_MIN2UNIT(mnum));
return (Strdup(buf));
}
return (Strdup(name));
}
static char *
dev_name(
set_t setno,
md_dev64_t dev
)
{
char *name;
/* get name or fake it */
if (dev == NODEV64)
return (Strdup(dgettext(TEXT_DOMAIN, "unknown device")));
if ((name = get_devname(setno, dev)) == NULL) {
char buf[40];
(void) sprintf(buf, "%lu.%lu", meta_getmajor(dev),
meta_getminor(dev));
return (Strdup(buf));
}
return (Strdup(name));
}
static char *
hsp_name(
hsp_t hsp
)
{
char *name;
if ((name = get_hspname(NULL, hsp)) == NULL) {
char buf[40];
(void) sprintf(buf, "%u/%u", HSP_SET(hsp), HSP_ID(hsp));
return (Strdup(buf));
}
return (Strdup(name));
}
static char *
set_name(
set_t setno
)
{
mdsetname_t *sp;
md_error_t xep = mdnullerror;
if (setno == MD_SET_BAD)
return (NULL);
if ((sp = metasetnosetname(setno, &xep)) == NULL) {
char buf[40];
mdclrerror(&xep);
(void) sprintf(buf, "setno %u", setno);
return (Strdup(buf));
}
return (Strdup(sp->setname));
}
/*
* fill in all the appropriate md_error_t fields
*/
static void
metacookerror(
md_error_t *ep, /* generic error */
char *name /* optional name or host */
)
{
/* get host name */
if (ep->host != NULL) {
Free(ep->host);
ep->host = NULL;
}
if ((ep->info.errclass == MDEC_RPC) &&
(name != NULL) && (*name != '\0')) {
ep->host = Strdup(name);
name = NULL;
} else
ep->host = Strdup(mynode());
/* get appropriate name */
if (ep->name != NULL) {
Free(ep->name);
ep->name = NULL;
}
if ((name != NULL) && (*name != '\0')) {
ep->name = Strdup(name);
} else {
switch (ep->info.errclass) {
/* can't do anything about these */
case MDEC_VOID:
case MDEC_SYS:
case MDEC_RPC:
default:
break;
/* device name */
case MDEC_DEV:
{
md_dev_error_t *ip =
&ep->info.md_error_info_t_u.dev_error;
ep->name = dev_name(MD_SET_BAD, ip->dev);
break;
}
/* device name */
case MDEC_USE:
{
md_use_error_t *ip =
&ep->info.md_error_info_t_u.use_error;
ep->name = dev_name(MD_SET_BAD, ip->dev);
if (ip->where == NULL) {
ip->where = Strdup(dgettext(TEXT_DOMAIN,
"unknown"));
}
break;
}
/* metadevice name */
case MDEC_MD:
{
md_md_error_t *ip =
&ep->info.md_error_info_t_u.md_error;
ep->name = md_name(ip->mnum);
break;
}
/* component name */
case MDEC_COMP:
{
md_comp_error_t *ip =
&ep->info.md_error_info_t_u.comp_error;
char *mdname, *devname;
size_t len;
mdname = md_name(ip->comp.mnum);
devname = dev_name(MD_MIN2SET(ip->comp.mnum),
ip->comp.dev);
len = strlen(mdname) + strlen(": ")
+ strlen(devname) + 1;
ep->name = Malloc(len);
(void) snprintf(ep->name, len, "%s: %s",
mdname, devname);
Free(mdname);
Free(devname);
break;
}
/* hotspare pool name */
case MDEC_HSP:
{
md_hsp_error_t *ip =
&ep->info.md_error_info_t_u.hsp_error;
ep->name = hsp_name(ip->hsp);
break;
}
/* hotspare name */
case MDEC_HS:
{
md_hs_error_t *ip =
&ep->info.md_error_info_t_u.hs_error;
char *hspname, *devname;
size_t len;
hspname = hsp_name(ip->hs.hsp);
devname = dev_name(HSP_SET(ip->hs.hsp), ip->hs.dev);
len = strlen(hspname) + strlen(": ")
+ strlen(devname) + 1;
ep->name = Malloc(len);
(void) snprintf(ep->name, len, "%s: %s",
hspname, devname);
Free(hspname);
Free(devname);
break;
}
/* mddb name */
case MDEC_MDDB:
{
md_mddb_error_t *ip =
&ep->info.md_error_info_t_u.mddb_error;
if (ip->mnum != NODEV32)
ep->name = md_name(ip->mnum);
ep->name = set_name(ip->setno);
break;
}
/* set name */
case MDEC_DS:
{
md_ds_error_t *ip =
&ep->info.md_error_info_t_u.ds_error;
ep->name = set_name(ip->setno);
break;
}
}
}
}
/*
* simple error
*/
int
mderror(
md_error_t *ep,
md_void_errno_t errnum,
char *name
)
{
md_void_error_t *ip = &ep->info.md_error_info_t_u.void_error;
mdclrerror(ep);
ep->info.errclass = MDEC_VOID;
ip->errnum = errnum;
metacookerror(ep, name);
return (-1);
}
/*
* system error
*/
int
mdsyserror(
md_error_t *ep,
int errnum,
char *name
)
{
md_sys_error_t *ip = &ep->info.md_error_info_t_u.sys_error;
mdclrerror(ep);
if (errnum != 0) {
ep->info.errclass = MDEC_SYS;
ip->errnum = errnum;
}
metacookerror(ep, name);
return (-1);
}
/*
* RPC error
*/
int
mdrpcerror(
md_error_t *ep,
CLIENT *clntp,
char *host,
char *extra
)
{
md_rpc_error_t *ip = &ep->info.md_error_info_t_u.rpc_error;
struct rpc_err rpcerr;
mdclrerror(ep);
clnt_geterr(clntp, &rpcerr);
ep->info.errclass = MDEC_RPC;
ip->errnum = rpcerr.re_status;
metacookerror(ep, host);
mderrorextra(ep, extra);
return (-1);
}
/*
* RPC create error
*/
int
mdrpccreateerror(
md_error_t *ep,
char *host,
char *extra
)
{
md_rpc_error_t *ip = &ep->info.md_error_info_t_u.rpc_error;
mdclrerror(ep);
ep->info.errclass = MDEC_RPC;
ip->errnum = rpc_createerr.cf_stat;
metacookerror(ep, host);
mderrorextra(ep, extra);
return (-1);
}
/*
* device error
*/
int
mddeverror(
md_error_t *ep,
md_dev_errno_t errnum,
md_dev64_t dev,
char *name
)
{
md_dev_error_t *ip = &ep->info.md_error_info_t_u.dev_error;
mdclrerror(ep);
ep->info.errclass = MDEC_DEV;
ip->errnum = errnum;
ip->dev = dev;
metacookerror(ep, name);
return (-1);
}
/*
* use error
*/
int
mduseerror(
md_error_t *ep,
md_use_errno_t errnum,
md_dev64_t dev,
char *where,
char *name
)
{
md_use_error_t *ip = &ep->info.md_error_info_t_u.use_error;
assert(where != NULL);
mdclrerror(ep);
ep->info.errclass = MDEC_USE;
ip->errnum = errnum;
ip->dev = dev;
ip->where = Strdup(where);
metacookerror(ep, name);
return (-1);
}
/*
* overlap error
*/
int
mdoverlaperror(
md_error_t *ep,
md_overlap_errno_t errnum,
char *name,
char *where,
char *overlap
)
{
md_overlap_error_t *ip =
&ep->info.md_error_info_t_u.overlap_error;
assert(overlap != NULL);
mdclrerror(ep);
ep->info.errclass = MDEC_OVERLAP;
ip->errnum = errnum;
ip->overlap = Strdup(overlap);
ip->where = NULL;
if (where != NULL)
ip->where = Strdup(where);
metacookerror(ep, name);
return (-1);
}
/*
* metadevice error
*/
int
mdmderror(
md_error_t *ep,
md_md_errno_t errnum,
minor_t mnum,
char *name
)
{
md_md_error_t *ip = &ep->info.md_error_info_t_u.md_error;
mdclrerror(ep);
ep->info.errclass = MDEC_MD;
ip->errnum = errnum;
ip->mnum = mnum;
metacookerror(ep, name);
return (-1);
}
/*
* component error
*/
int
mdcomperror(
md_error_t *ep,
md_comp_errno_t errnum,
minor_t mnum,
md_dev64_t dev,
char *name
)
{
md_comp_error_t *ip = &ep->info.md_error_info_t_u.comp_error;
mdclrerror(ep);
ep->info.errclass = MDEC_COMP;
ip->errnum = errnum;
ip->comp.mnum = mnum;
ip->comp.dev = dev;
metacookerror(ep, name);
return (-1);
}
/*
* hotspare pool error
*/
int
mdhsperror(
md_error_t *ep,
md_hsp_errno_t errnum,
hsp_t hsp,
char *name
)
{
md_hsp_error_t *ip = &ep->info.md_error_info_t_u.hsp_error;
mdclrerror(ep);
ep->info.errclass = MDEC_HSP;
ip->errnum = errnum;
ip->hsp = hsp;
metacookerror(ep, name);
return (-1);
}
/*
* hotspare error
*/
int
mdhserror(
md_error_t *ep,
md_hs_errno_t errnum,
hsp_t hsp,
md_dev64_t dev,
char *name
)
{
md_hs_error_t *ip = &ep->info.md_error_info_t_u.hs_error;
mdclrerror(ep);
ep->info.errclass = MDEC_HS;
ip->errnum = errnum;
ip->hs.hsp = hsp;
ip->hs.dev = dev;
metacookerror(ep, name);
return (-1);
}
/*
* MDDB error
*/
int
mdmddberror(
md_error_t *ep,
md_mddb_errno_t errnum,
minor_t mnum,
set_t setno,
size_t size,
char *name
)
{
md_mddb_error_t *ip = &ep->info.md_error_info_t_u.mddb_error;
mdclrerror(ep);
ep->info.errclass = MDEC_MDDB;
ip->errnum = errnum;
ip->mnum = mnum;
ip->setno = setno;
ip->size = size;
metacookerror(ep, name);
return (-1);
}
/*
* metadevice diskset (ds) error
*/
int
mddserror(
md_error_t *ep,
md_ds_errno_t errnum,
set_t setno,
char *node,
char *drive,
char *name
)
{
md_ds_error_t *ip = &ep->info.md_error_info_t_u.ds_error;
mdclrerror(ep);
ep->info.errclass = MDEC_DS;
ip->errnum = errnum;
ip->setno = setno;
ip->node = ((node != NULL) ? Strdup(node) : NULL);
ip->drive = ((drive != NULL) ? Strdup(drive) : NULL);
metacookerror(ep, name);
return (-1);
}
/*
* clear/attach extra context information
*/
void
mderrorextra(
md_error_t *ep,
char *extra
)
{
if (ep->extra != NULL)
Free(ep->extra);
if (extra != NULL)
ep->extra = Strdup(extra);
else
ep->extra = NULL;
}
/*
* steal (copy) an error code safely
*/
int
mdstealerror(
md_error_t *to,
md_error_t *from
)
{
mdclrerror(to);
*to = *from;
(void) memset(from, '\0', sizeof (*from));
return (-1);
}
/*
* do an ioctl, cook the error, and return status
*/
int
metaioctl(
int cmd,
void *data,
md_error_t *ep,
char *name
)
{
int fd;
/* open admin device */
if ((fd = open_admin(ep)) < 0)
return (-1);
/* do ioctl */
mdclrerror(ep);
if (ioctl(fd, cmd, data) != 0) {
return (mdsyserror(ep, errno, name));
} else if (! mdisok(ep)) {
metacookerror(ep, name);
return (-1);
}
/* return success */
return (0);
}
/*
* print void class errors
*/
static char *
void_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_void_error_t *ip = &ep->info.md_error_info_t_u.void_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
switch (ip->errnum) {
case MDE_NONE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "no error"));
break;
case MDE_UNIT_NOT_FOUND:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unit not found"));
break;
case MDE_DUPDRIVE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "drive specified more than once"));
break;
case MDE_INVAL_HSOP:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "illegal hot spare operation"));
break;
case MDE_NO_SET:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "no such set"));
break;
case MDE_SET_DIFF:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "set name is inconsistent"));
break;
case MDE_BAD_RD_OPT:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid read option"));
break;
case MDE_BAD_WR_OPT:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid write option"));
break;
case MDE_BAD_PASS_NUM:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid pass number"));
break;
case MDE_BAD_RESYNC_OPT:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid resync option"));
break;
case MDE_BAD_INTERLACE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid interlace"));
break;
case MDE_NO_HSPS:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "no hotspare pools found"));
break;
case MDE_NOTENOUGH_DB:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"must have at least 1 database (-f overrides)"));
break;
case MDE_DELDB_NOTALLOWED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"cannot delete the last database replica in the diskset"));
break;
case MDE_DEL_VALIDDB_NOTALLOWED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Deleting specified valid replicas results in stale "
"state database. Configuration changes with stale "
"database result in panic(-f overrides)"));
break;
case MDE_SYSTEM_FILE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "error in system file"));
break;
case MDE_MDDB_FILE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "error in mddb.cf file"));
break;
case MDE_MDDB_CKSUM:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "checksum error in mddb.cf file"));
break;
case MDE_VFSTAB_FILE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "error in vfstab file"));
break;
case MDE_NOSLICE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"invalid slice number for drive name"));
break;
case MDE_SYNTAX:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "syntax error"));
break;
case MDE_OPTION:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "illegal option"));
break;
case MDE_TAKE_OWN:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "failed to reserve any drives"));
break;
case MDE_NOT_DRIVENAME:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "not a valid drive name"));
break;
case MDE_RESERVED:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "reserved by another host"));
break;
case MDE_DVERSION:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "driver version mismatch"));
break;
case MDE_MVERSION:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"metadevice state database version mismatch"));
break;
case MDE_TESTERROR:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "TEST ERROR MESSAGE"));
break;
case MDE_BAD_ORIG_NCOL:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid column count"));
break;
case MDE_RAID_INVALID:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"devices were not RAIDed previously or "
"are specified in the wrong order"));
break;
case MDE_MED_ERROR:
break;
case MDE_TOOMANYMED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"too many mediator hosts requested"));
break;
case MDE_NOMED:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "no mediator hosts found"));
break;
case MDE_ONLYNODENAME:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"only the nodename of a host is required for deletes"));
break;
case MDE_RAID_BAD_PW_CNT:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"simultaneous writes out of range"));
break;
case MDE_DEVID_TOOBIG:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"relocation information size is greater than reported"));
break;
case MDE_NOPERM:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Permission denied. You must have root privilege "
"to execute this command."));
break;
case MDE_NODEVID:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Device relocation information not available "
"for this device"));
break;
case MDE_NOROOT:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"no root filesystem in /etc/mnttab"));
break;
case MDE_EOF_TRANS:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
MD_EOF_TRANS_MSG));
break;
case MDE_NOT_MN:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"option only valid within a multi-owner set"));
break;
case MDE_ABR_SET:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Invalid command for mirror with ABR set"));
break;
case MDE_INVAL_MNOP:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Invalid operation on multi-owner set"));
break;
case MDE_MNSET_NOTRANS:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Trans metadevice not supported on multi-owner set"));
break;
case MDE_MNSET_NORAID:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"RAID-5 metadevice not supported on multi-owner set"));
break;
case MDE_FORCE_DEL_ALL_DRV:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Must specify -f option to delete all drives from set"));
break;
case MDE_STRIPE_TRUNC_SINGLE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"The necessary rounding would result in data loss. "
"You can avoid this by concatenating additional devices "
"totaling at least %s blocks, or by increasing the size "
"of the specified component by exactly %s blocks."),
ep->extra, ep->extra);
break;
case MDE_STRIPE_TRUNC_MULTIPLE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"The necessary rounding would result in data loss. "
"You can avoid this by concatenating additional devices "
"totaling at least %s blocks."), ep->extra);
break;
case MDE_SMF_FAIL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"failed to enable/disable SVM service"));
break;
case MDE_SMF_NO_SERVICE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"service(s) not online in SMF"));
break;
case MDE_AMBIGUOUS_DEV:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Specify complete path to avoid ambiguity."));
break;
case MDE_NAME_IN_USE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Name already in use for metadevice or hot spare pool."));
break;
case MDE_NAME_ILLEGAL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Invalid name for metadevice or hot spare pool."));
break;
case MDE_ZONE_ADMIN:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Volume administration unavailable within non-global zones."));
break;
case MDE_MISSING_DEVID_DISK:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"device id does not exist."));
break;
default:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unknown void error code %d"), ip->errnum);
break;
}
return (buf);
}
/*
* print sys class errors
*/
static char *
sys_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_sys_error_t *ip = &ep->info.md_error_info_t_u.sys_error;
char *emsg;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
if ((emsg = strerror(ip->errnum)) == NULL) {
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unknown errno %d out of range"),
ip->errnum);
} else {
(void) snprintf(p, psize, "%s", emsg);
}
return (buf);
}
/*
* print RPC class errors
*/
static char *
rpc_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_rpc_error_t *ip = &ep->info.md_error_info_t_u.rpc_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
(void) snprintf(p, psize, "%s", clnt_sperrno(ip->errnum));
return (buf);
}
/*
* print dev class errors
*/
static char *
dev_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_dev_error_t *ip = &ep->info.md_error_info_t_u.dev_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
switch (ip->errnum) {
case MDE_INVAL_HS:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "hotspare doesn't exist"));
break;
case MDE_FIX_INVAL_STATE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"cannot enable hotspared device"));
break;
case MDE_FIX_INVAL_HS_STATE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"hotspare isn't broken, can't enable"));
break;
case MDE_NOT_META:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "not a metadevice"));
break;
case MDE_IS_DUMP:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "is a dump device"));
break;
case MDE_IS_META:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "is a metadevice"));
break;
case MDE_IS_SWAPPED:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "is swapped on"));
break;
case MDE_NAME_SPACE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "namespace error"));
break;
case MDE_IN_SHARED_SET:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "device in shared set"));
break;
case MDE_NOT_IN_SET:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "device not in set"));
break;
case MDE_NOT_DISK:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "not a disk device"));
break;
case MDE_CANT_CONFIRM:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "can't confirm device"));
break;
case MDE_INVALID_PART:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid partition"));
break;
case MDE_HAS_MDDB:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"has a metadevice database replica"));
break;
case MDE_NO_DB:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"no metadevice database replica on device"));
break;
case MDE_CANTVERIFY_VTOC:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unable to verify the vtoc"));
break;
case MDE_NOT_LOCAL:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "not in local set"));
break;
case MDE_DEVICES_NAME:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "can't parse /devices name"));
break;
case MDE_REPCOMP_INVAL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"replica slice is not usable as a metadevice component"));
break;
case MDE_REPCOMP_ONLY:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"only replica slice is usable for a diskset "
"database replica"));
break;
case MDE_INV_ROOT:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"invalid root device for this operation"));
break;
case MDE_MULTNM:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"multiple entries for device in Solaris Volume Manager "
"configuration"));
break;
case MDE_TOO_MANY_PARTS:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Disks with more than %d partitions are not supported "
"in Solaris Volume Manager"), MD_MAX_PARTS);
break;
case MDE_REPART_REPLICA:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"cannot repartition a slice with an existing replica"));
break;
case MDE_DISKNAMETOOLONG:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"disk name is too long with device ids disabled "
"in Solaris Volume Manager. Check /etc/driver/drv/md.conf "
"for md_devid_destroy, remove it and reboot"));
break;
default:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unknown dev error code %d"),
ip->errnum);
break;
}
return (buf);
}
/*
* print overlap class errors
*/
static char *
overlap_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_overlap_error_t *ip =
&ep->info.md_error_info_t_u.overlap_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
switch (ip->errnum) {
case MDE_OVERLAP_MOUNTED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"overlaps with %s which is mounted as \'%s\'"),
ip->overlap, ip->where);
break;
case MDE_OVERLAP_SWAP:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"overlaps with %s which is a swap device"), ip->overlap);
break;
case MDE_OVERLAP_DUMP:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"overlaps with %s which is the dump device"), ip->overlap);
break;
default:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unknown overlap error code %d"), ip->errnum);
break;
}
return (buf);
}
/*
* print use class errors
*/
static char *
use_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_use_error_t *ip = &ep->info.md_error_info_t_u.use_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
switch (ip->errnum) {
case MDE_IS_MOUNTED:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "is mounted on %s"),
ip->where);
break;
case MDE_ALREADY:
/*
* when the object of the error (existing device that
* would being used by SVM) is the metadb then it is necessary
* to explicitly specify the string in the error message so
* that it can be successfully localized for the Asian locales.
*/
if (strcmp(ip->where, MDB_STR) != 0) {
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"has appeared more than once in the "
"specification of %s"), ip->where);
} else {
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"has appeared more than once in the "
"specification of " MDB_STR));
}
break;
case MDE_OVERLAP:
/*
* when the object of the error (existing device that
* would overlap) is the metadb then it is necessary
* to explicitly specify the string in the error message so
* that it can be successfully localized for the Asian locales.
*/
if (strcmp(ip->where, MDB_STR) != 0) {
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "overlaps with device in %s"),
ip->where);
} else {
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "overlaps with device in "
MDB_STR));
}
break;
case MDE_SAME_DEVID:
/*
* when the object of the error (existing device in the
* metaconfiguration that has the same devid)
* is the metadb then it is necessary
* to explicitly specify the string in the error message so
* that it can be successfully localized for the Asian locales.
*/
if (strcmp(ip->where, MDB_STR) != 0) {
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"identical devid detected on %s"), ip->where);
} else {
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"identical devid detected in " MDB_STR));
}
break;
default:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unknown dev error code %d"), ip->errnum);
break;
}
return (buf);
}
/*
* print md class errors
*/
static char *
md_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_md_error_t *ip = &ep->info.md_error_info_t_u.md_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
switch (ip->errnum) {
case MDE_INVAL_UNIT:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid unit"));
break;
case MDE_UNIT_NOT_SETUP:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unit not set up"));
break;
case MDE_UNIT_ALREADY_SETUP:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unit already set up"));
break;
case MDE_NOT_MM:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unit is not a mirror"));
break;
case MDE_IS_SM:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "illegal to clear submirror"));
break;
case MDE_IS_OPEN:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "metadevice is open"));
break;
case MDE_C_WITH_INVAL_SM:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"attempted to clear mirror with submirror(s) "
"in invalid state"));
break;
case MDE_RESYNC_ACTIVE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "resync in progress"));
break;
case MDE_LAST_SM_RE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"attempt to replace a component on the last "
"running submirror"));
break;
case MDE_MIRROR_FULL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"mirror has maximum number of submirrors"));
break;
case MDE_IN_UNAVAIL_STATE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"component is in unavailable state; run 'metastat -i'"));
break;
case MDE_IN_USE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"metadevice in use"));
break;
case MDE_SM_TOO_SMALL:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "submirror too small to attach"));
break;
case MDE_NO_LABELED_SM:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"can't attach labeled submirror to an unlabeled mirror"));
break;
case MDE_SM_OPEN_ERR:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "submirror open error"));
break;
case MDE_CANT_FIND_SM:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "can't find submirror in mirror"));
break;
case MDE_LAST_SM:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"attempt to detach last running submirror"));
break;
case MDE_NO_READABLE_SM:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"operation would result in no readable submirrors"));
break;
case MDE_SM_FAILED_COMPS:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"attempt an operation on a submirror "
"that has erred components"));
break;
case MDE_ILLEGAL_SM_STATE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"attempt operation on a submirror in illegal state"));
break;
case MDE_RR_ALLOC_ERROR:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"attach failed, unable to allocate new resync info"));
break;
case MDE_MIRROR_OPEN_FAILURE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "insufficient devices to open"));
break;
case MDE_MIRROR_THREAD_FAILURE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "mirror thread failure"));
break;
case MDE_GROW_DELAYED:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "growing of metadevice delayed"));
break;
case MDE_NOT_MT:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unit is not a trans"));
break;
case MDE_HS_IN_USE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"can't modify hot spare pool, hot spare in use"));
break;
case MDE_HAS_LOG:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "already has log"));
break;
case MDE_UNKNOWN_TYPE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unknown metadevice type"));
break;
case MDE_NOT_STRIPE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unit is not a concat/stripe"));
break;
case MDE_NOT_RAID:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unit is not a RAID"));
break;
case MDE_NROWS:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "not enough stripes specified"));
break;
case MDE_NCOMPS:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "not enough components specified"));
break;
case MDE_NSUBMIRS:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "not enough submirrors specified"));
break;
case MDE_BAD_STRIPE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid stripe configuration"));
break;
case MDE_BAD_MIRROR:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid mirror configuration"));
break;
case MDE_BAD_TRANS:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid trans configuration"));
break;
case MDE_BAD_RAID:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "invalid RAID configuration"));
break;
case MDE_RAID_OPEN_FAILURE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "resync unable to open RAID unit"));
break;
case MDE_RAID_THREAD_FAILURE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"attempt to start resync thread failed"));
break;
case MDE_RAID_NEED_FORCE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"operation requires -f (force) flag"));
break;
case MDE_NO_LOG:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "log has already been detached"));
break;
case MDE_RAID_DOI:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "only valid action is metaclear"));
break;
case MDE_RAID_LAST_ERRED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"in Last Erred state, "
"errored components must be replaced"));
break;
case MDE_RAID_NOT_OKAY:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"all components must be Okay to perform this operation"));
break;
case MDE_RENAME_BUSY:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"metadevice is temporarily too busy for renames"));
break;
case MDE_RENAME_SOURCE_BAD:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"source metadevice is not able to be renamed"));
break;
case MDE_RENAME_TARGET_BAD:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"target metadevice is not able to be renamed"));
break;
case MDE_RENAME_TARGET_UNRELATED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"target metadevice is not related to source metadevice"));
break;
case MDE_RENAME_CONFIG_ERROR:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"metadevice driver configuration error; "
"rename can't occur"));
break;
case MDE_RENAME_ORDER:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"units may not be renamed in that order"));
break;
case MDE_RECOVER_FAILED:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "recovery failed"));
break;
case MDE_SP_NOSPACE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"not enough space available for request"));
break;
case MDE_SP_BADWMREAD:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "error reading extent header"));
break;
case MDE_SP_BADWMWRITE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "error writing extent header"));
break;
case MDE_SP_BADWMMAGIC:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "bad magic number in extent header"));
break;
case MDE_SP_BADWMCRC:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "bad checksum in extent header"));
break;
case MDE_NOT_SP:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unit is not a soft partition"));
break;
case MDE_SP_OVERLAP:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "overlapping extents specified"));
break;
case MDE_SP_BAD_LENGTH:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "bad length specified"));
break;
case MDE_SP_NOSP:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "no soft partitions on this device"));
break;
case MDE_UNIT_TOO_LARGE:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "Volume size cannot exceed 1 TByte"));
break;
case MDE_LOG_TOO_LARGE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Trans log size must be less than 1 TByte"));
break;
default:
(void) snprintf(p, psize,
dgettext(TEXT_DOMAIN, "unknown md error code %d"),
ip->errnum);
break;
}
return (buf);
}
/*
* print comp class errors
*/
static char *
comp_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_comp_error_t *ip = &ep->info.md_error_info_t_u.comp_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
switch (ip->errnum) {
case MDE_CANT_FIND_COMP:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"can't find component in unit"));
break;
case MDE_REPL_INVAL_STATE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"component in invalid state to replace - "
"Replace \"Maintenance\" components first"));
break;
case MDE_COMP_TOO_SMALL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"replace failure, new component is too small"));
break;
case MDE_COMP_OPEN_ERR:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unable to open concat/stripe component"));
break;
case MDE_RAID_COMP_ERRED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"must replace errored component first"));
break;
case MDE_MAXIO:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"maxtransfer is too small"));
break;
case MDE_SP_COMP_OPEN_ERR:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"error opening device under soft partition. Check"
" device status, then use metadevadm(1M)."));
break;
default:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unknown comp error code %d"), ip->errnum);
break;
}
return (buf);
}
/*
* print hsp class errors
*/
static char *
hsp_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_hsp_error_t *ip = &ep->info.md_error_info_t_u.hsp_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
switch (ip->errnum) {
case MDE_HSP_CREATE_FAILURE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"hotspare pool database create failure"));
break;
case MDE_HSP_IN_USE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"hotspare pool in use"));
break;
case MDE_INVAL_HSP:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"invalid hotspare pool"));
break;
case MDE_HSP_BUSY:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"hotspare pool is busy"));
break;
case MDE_HSP_REF:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"hotspare pool is referenced"));
break;
case MDE_HSP_ALREADY_SETUP:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"hotspare pool is already setup"));
break;
case MDE_BAD_HSP:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"invalid hotspare pool configuration"));
break;
case MDE_HSP_UNIT_TOO_LARGE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"units in the hotspare pool cannot exceed 1 TByte"));
break;
default:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unknown hsp error code %d"), ip->errnum);
break;
}
return (buf);
}
/*
* print hs class errors
*/
static char *
hs_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_hs_error_t *ip = &ep->info.md_error_info_t_u.hs_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
switch (ip->errnum) {
case MDE_HS_RESVD:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"hotspare is in use"));
break;
case MDE_HS_CREATE_FAILURE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"hotspare database create failure"));
break;
case MDE_HS_INUSE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"add or replace failed, hot spare is already in use"));
break;
case MDE_HS_UNIT_TOO_LARGE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"hotspare size cannot exceed 1 TByte"));
break;
default:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unknown hs error code %d"), ip->errnum);
break;
}
return (buf);
}
/*
* print mddb class errors
*/
static char *
mddb_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_mddb_error_t *ip = &ep->info.md_error_info_t_u.mddb_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
switch (ip->errnum) {
case MDE_TOOMANY_REPLICAS:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"%d metadevice database replicas is too many; the maximum is %d"),
ip->size, MDDB_NLB);
break;
case MDE_REPLICA_TOOSMALL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"device size %d is too small for metadevice database replica"),
ip->size);
break;
case MDE_NOTVERIFIED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"data not returned correctly from disk"));
break;
case MDE_DB_INVALID:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"invalid argument"));
break;
case MDE_DB_EXISTS:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"metadevice database replica exists on device"));
break;
case MDE_DB_MASTER:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"has bad master block on device"));
break;
case MDE_DB_TOOSMALL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"device is too small"));
break;
case MDE_DB_NORECORD:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"no such metadevice database record"));
break;
case MDE_DB_NOSPACE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"metadevice database is full, can't create new records"));
break;
case MDE_DB_NOTNOW:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"metadevice database has too few replicas, for "
"metadevice database operation"));
break;
case MDE_DB_NODB:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"there are no existing databases"));
break;
case MDE_DB_NOTOWNER:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"not owner of metadevice database"));
break;
case MDE_DB_STALE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"stale databases"));
break;
case MDE_DB_TOOFEW:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"not enough databases"));
break;
case MDE_DB_TAGDATA:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"tagged data detected, user intervention required"));
break;
case MDE_DB_ACCOK:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"50% replicas & 50% mediator hosts available, "
"user intervention required"));
break;
case MDE_DB_NTAGDATA:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"no tagged data available or only one tag found"));
break;
case MDE_DB_ACCNOTOK:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"50% replicas & 50% mediator hosts not available"));
break;
case MDE_DB_NOLOCBLK:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"no valid locator blocks were found"));
break;
case MDE_DB_NOLOCNMS:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"no valid locator name information was found"));
break;
case MDE_DB_NODIRBLK:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"no valid directory blocks were found"));
break;
case MDE_DB_NOTAGREC:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"no tag record was allocated, so data "
"tagging is disabled"));
break;
case MDE_DB_NOTAG:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"no tag records exist or no matching tag was found"));
break;
case MDE_DB_BLKRANGE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"logical block number %d out of range"), ip->size);
break;
default:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unknown mddb error code %d"), ip->errnum);
break;
}
return (buf);
}
/*
* print diskset (ds) class errors
*/
static char *
ds_to_str(
md_error_t *ep,
char *buf,
size_t size
)
{
md_ds_error_t *ip = &ep->info.md_error_info_t_u.ds_error;
char *p = buf + strlen(buf);
size_t psize = size - strlen(buf);
switch (ip->errnum) {
case MDE_DS_DUPHOST:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host %s is specified more than once"), ip->node);
break;
case MDE_DS_NOTNODENAME:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"\"%s\" is not a nodename, but a network name"), ip->node);
break;
case MDE_DS_SELFNOTIN:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"nodename of host %s creating the set must be included"),
ip->node);
break;
case MDE_DS_NODEHASSET:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host %s already has set"), ip->node);
break;
case MDE_DS_NODENOSET:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host %s does not have set"), ip->node);
break;
case MDE_DS_NOOWNER:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"must be owner of the set for this command"));
break;
case MDE_DS_NOTOWNER:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"only the current owner %s may operate on this set"),
ip->node);
break;
case MDE_DS_NODEISNOTOWNER:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host %s is not the owner"), ip->node);
break;
case MDE_DS_NODEINSET:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host %s is already in the set"), ip->node);
break;
case MDE_DS_NODENOTINSET:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host %s is not in the set"), ip->node);
break;
case MDE_DS_SETNUMBUSY:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host %s already has a set numbered %ld"),
ip->node, ip->setno);
break;
case MDE_DS_SETNUMNOTAVAIL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"no available set numbers"));
break;
case MDE_DS_SETNAMEBUSY:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"set name is in-use or invalid on host %s"), ip->node);
break;
case MDE_DS_DRIVENOTCOMMON:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"drive %s is not common with host %s"),
ip->drive, ip->node);
break;
case MDE_DS_DRIVEINSET:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"drive %s is in set %s"), ip->drive, ip->node);
break;
case MDE_DS_DRIVENOTINSET:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"drive %s is not in set"), ip->drive);
break;
case MDE_DS_DRIVEINUSE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"drive %s is in use"), ip->drive);
break;
case MDE_DS_DUPDRIVE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"drive %s is specified more than once"), ip->drive);
break;
case MDE_DS_INVALIDSETNAME:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"set name contains invalid characters"));
break;
case MDE_DS_HASDRIVES:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unable to delete set, it still has drives"));
break;
case MDE_DS_SIDENUMNOTAVAIL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"maximum number of nodenames exceeded"));
break;
case MDE_DS_SETNAMETOOLONG:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"set name is too long"));
break;
case MDE_DS_NODENAMETOOLONG:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host name %s is too long"), ip->node);
break;
case MDE_DS_OHACANTDELSELF:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"administrator host %s deletion disallowed in one host admin mode"),
ip->node);
break;
case MDE_DS_HOSTNOSIDE:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"side information missing for host %s"), ip->node);
break;
case MDE_DS_SETLOCKED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host %s is modifying set - try later or restart rpc.metad"),
ip->drive);
break;
case MDE_DS_ULKSBADKEY:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"set unlock failed - bad key"));
break;
case MDE_DS_LKSBADKEY:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"set lock failed - bad key"));
break;
case MDE_DS_WRITEWITHSULK:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"write operation attempted on set with set unlocked"));
break;
case MDE_DS_SETCLEANUP:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"set \"%s\" is out of date - cleaning up - take failed"),
ip->node);
break;
case MDE_DS_CANTDELSELF:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"administrator host %s can't be deleted, other hosts still in set\n"
"Use -f to override"), ip->node);
break;
case MDE_DS_HASMED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unable to delete set, it still has mediator hosts"));
break;
case MDE_DS_TOOMANYALIAS:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"%s causes there to be more aliases than allowed"),
ip->node);
break;
case MDE_DS_ISMED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"%s is already a mediator host"), ip->node);
break;
case MDE_DS_ISNOTMED:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"%s is not a mediator host"), ip->node);
break;
case MDE_DS_INVALIDMEDNAME:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"mediator name \"%s\" contains invalid characters"),
ip->node);
break;
case MDE_DS_ALIASNOMATCH:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"mediator alias \"%s\" is not an alias for host "
"\"%s\""), ip->node, ip->drive);
break;
case MDE_DS_NOMEDONHOST:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unable to contact %s on host \"%s\""),
MED_SERVNAME, ip->node);
break;
case MDE_DS_DRIVENOTONHOST:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"drive %s is not present on host %s"),
ip->drive, ip->node);
break;
case MDE_DS_CANTDELMASTER:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"master %s can't be deleted, other hosts still in set"),
ip->node);
break;
case MDE_DS_NOTINMEMBERLIST:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"node %s is not in membership list"),
ip->node);
break;
case MDE_DS_MNCANTDELSELF:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host %s can't delete self from multi-owner set\n"
"while other hosts still in set"),
ip->node);
break;
case MDE_DS_RPCVERSMISMATCH:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"host %s does not support multi-owner diskset"),
ip->node);
break;
case MDE_DS_WITHDRAWMASTER:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"master host %s cannot withdraw from multi-owner diskset "
"when other owner nodes are still present in diskset"),
ip->node);
break;
case MDE_DS_CANTRESNARF:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"imported set could not be loaded"));
break;
case MDE_DS_INSUFQUORUM:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"insufficient replica quorum detected. Use "
"-f to force import of the set"));
break;
case MDE_DS_EXTENDEDNM:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"multiple namespace records detected"));
break;
case MDE_DS_COMMDCTL_SUSPEND_NYD:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"rpc.mdcommd on host %s is not yet drained during "
"suspend operation"),
ip->node);
break;
case MDE_DS_COMMDCTL_SUSPEND_FAIL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"rpc.mdcommd on host %s failed suspend operation"),
ip->node);
break;
case MDE_DS_COMMDCTL_REINIT_FAIL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"rpc.mdcommd on host %s failed reinitialization operation"),
ip->node);
break;
case MDE_DS_COMMDCTL_RESUME_FAIL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"rpc.mdcommd on host %s failed resume operation"),
ip->node);
break;
case MDE_DS_NOTNOW_RECONFIG:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"command terminated, host %s starting reconfig cycle"),
ip->node);
break;
case MDE_DS_NOTNOW_CMD:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"metaset or metadb command already running on diskset "
"on host %s"), ip->node);
break;
case MDE_DS_COMMD_SEND_FAIL:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"rpc.mdcommd on host %s failed operation"),
ip->node);
break;
case MDE_DS_MASTER_ONLY:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"this command must be run on the master node of the set,"
" which is currently %s"), ip->node);
break;
case MDE_DS_SINGLEHOST:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"diskset is auto-take; cannot accept additional hosts"));
break;
case MDE_DS_AUTONOTSET:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"auto-take is not enabled on diskset"));
break;
case MDE_DS_INVALIDDEVID:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Invalid device id on drive %s on host %s"), ip->drive,
ip->node);
break;
case MDE_DS_SETNOTIMP:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Unable to import set on node %s"), ip->node);
break;
case MDE_DS_NOTSELFIDENTIFY:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"Drive %s won't be self identifying"), ip->drive);
break;
default:
(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
"unknown diskset error code %d"), ip->errnum);
break;
}
return (buf);
}
/*
* convert error to printable string
*/
static char *
mde_to_str(
md_error_t *ep
)
{
static char buf[BUFSIZ];
size_t bufsz;
/* intialize buf */
buf[0] = '\0';
bufsz = sizeof (buf);
/* class specific */
switch (ep->info.errclass) {
case MDEC_VOID:
return (void_to_str(ep, buf, bufsz));
case MDEC_SYS:
return (sys_to_str(ep, buf, bufsz));
case MDEC_RPC:
return (rpc_to_str(ep, buf, bufsz));
case MDEC_DEV:
return (dev_to_str(ep, buf, bufsz));
case MDEC_USE:
return (use_to_str(ep, buf, bufsz));
case MDEC_MD:
return (md_to_str(ep, buf, bufsz));
case MDEC_COMP:
return (comp_to_str(ep, buf, bufsz));
case MDEC_HSP:
return (hsp_to_str(ep, buf, bufsz));
case MDEC_HS:
return (hs_to_str(ep, buf, bufsz));
case MDEC_MDDB:
return (mddb_to_str(ep, buf, bufsz));
case MDEC_DS:
return (ds_to_str(ep, buf, bufsz));
case MDEC_OVERLAP:
return (overlap_to_str(ep, buf, bufsz));
default:
(void) snprintf(buf, bufsz,
dgettext(TEXT_DOMAIN, "unknown error class %d"),
ep->info.errclass);
return (buf);
}
}
/*
* print log prefix
*/
void
md_logpfx(
FILE *fp
)
{
time_t t;
struct tm *tm;
char buf[100];
if ((time(&t) != (time_t)-1) &&
((tm = localtime(&t)) != NULL) &&
(strftime(buf, sizeof (buf), (char *)0, tm) < sizeof (buf))) {
(void) fprintf(fp, "%s: ", buf);
}
(void) fprintf(fp, "%s: ", myname);
}
/*
* varargs sperror()
*/
/*PRINTFLIKE2*/
static char *
mde_vsperror(
md_error_t *ep,
const char *fmt,
va_list ap
)
{
static char buf[BUFSIZ];
size_t bufsz = sizeof (buf);
char *p = buf;
char *host1 = "";
char *host2 = "";
char *extra1 = "";
char *extra2 = "";
char *name1 = "";
char *name2 = "";
/* get stuff */
if ((ep->host != NULL) && (*(ep->host) != '\0')) {
host1 = ep->host;
host2 = ": ";
}
if ((ep->extra != NULL) && (*(ep->extra) != '\0')) {
extra1 = ep->extra;
extra2 = ": ";
}
if ((ep->name != NULL) && (*(ep->name) != '\0')) {
name1 = ep->name;
name2 = ": ";
}
/* context */
(void) snprintf(p, bufsz, "%s%s%s%s%s%s",
host1, host2, extra1, extra2, name1, name2);
p = &buf[strlen(buf)];
bufsz -= strlen(buf);
/* user defined part */
if ((fmt != NULL) && (*fmt != '\0')) {
(void) vsnprintf(p, bufsz, fmt, ap);
p = &buf[strlen(buf)];
bufsz = sizeof (buf) - strlen(buf);
(void) snprintf(p, bufsz, ": ");
p = &buf[strlen(buf)];
bufsz = sizeof (buf) - strlen(buf);
}
/* error code */
(void) snprintf(p, bufsz, "%s\n", mde_to_str(ep));
/* return error message */
return (buf);
}
/*
* printf-like sperror()
*/
/*PRINTFLIKE2*/
char *
mde_sperror(
md_error_t *ep,
const char *fmt,
...
)
{
va_list ap;
char *emsg;
va_start(ap, fmt);
emsg = mde_vsperror(ep, fmt, ap);
va_end(ap);
return (emsg);
}
/*
* printf-like perror()
*/
/*PRINTFLIKE2*/
void
mde_perror(
md_error_t *ep,
const char *fmt,
...
)
{
va_list ap;
char *emsg;
/* get error message */
va_start(ap, fmt);
emsg = mde_vsperror(ep, fmt, ap);
va_end(ap);
assert((emsg != NULL) && (*emsg != '\0'));
/* stderr */
(void) fprintf(stderr, "%s: %s\n", myname, emsg);
(void) fflush(stderr);
/* metalog */
if (metalogfp != NULL) {
md_logpfx(metalogfp);
(void) fprintf(metalogfp, "%s\n", emsg);
(void) fflush(metalogfp);
(void) fsync(fileno(metalogfp));
}
/* syslog */
if (metasyslog) {
syslog(LOG_ERR, emsg);
}
}
/*
* printf-like perror()
*/
/*PRINTFLIKE1*/
void
md_perror(
const char *fmt,
...
)
{
md_error_t status = mdnullerror;
va_list ap;
char *emsg;
/* get error message */
(void) mdsyserror(&status, errno, NULL);
va_start(ap, fmt);
emsg = mde_vsperror(&status, fmt, ap);
va_end(ap);
assert((emsg != NULL) && (*emsg != '\0'));
mdclrerror(&status);
/* stderr */
(void) fprintf(stderr, "%s: %s\n", myname, emsg);
(void) fflush(stderr);
/* metalog */
if (metalogfp != NULL) {
md_logpfx(metalogfp);
(void) fprintf(metalogfp, "%s\n", emsg);
(void) fflush(metalogfp);
(void) fsync(fileno(metalogfp));
}
/* syslog */
if (metasyslog) {
syslog(LOG_ERR, emsg);
}
}
/*
* printf-like log
*/
/*PRINTFLIKE1*/
void
md_eprintf(
const char *fmt,
...
)
{
va_list ap;
/* begin */
va_start(ap, fmt);
/* stderr */
(void) fprintf(stderr, "%s: ", myname);
(void) vfprintf(stderr, fmt, ap);
(void) fflush(stderr);
/* metalog */
if (metalogfp != NULL) {
md_logpfx(metalogfp);
(void) vfprintf(metalogfp, fmt, ap);
(void) fflush(metalogfp);
(void) fsync(fileno(metalogfp));
}
/* syslog */
if (metasyslog) {
vsyslog(LOG_ERR, fmt, ap);
}
/* end */
va_end(ap);
}
/*
* metaclust timing messages logging routine
*
* level - The class of the message to be logged. Message will be logged
* if this is less than or equal to the verbosity level.
*/
void
meta_mc_log(int level, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
/*
* Log all messages upto MC_LOG2 to syslog regardless of the
* verbosity level
*/
if (metasyslog && (level <= MC_LOG2)) {
if (level <= MC_LOG1)
(void) vsyslog(LOG_ERR, fmt, args);
else
(void) vsyslog(LOG_INFO, fmt, args);
}
/*
* Print all messages to stderr provided the message level is
* within the verbosity level
*/
if (level <= verbosity) {
(void) fprintf(stderr, "%s: ", myname);
(void) vfprintf(stderr, fmt, args);
(void) fprintf(stderr, "\n");
(void) fflush(stderr);
}
va_end(args);
}