/* * 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 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * 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 #include #include /* * 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 /kernel/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); }