meta_name.c revision 4bc0a2ef2b7ba50a7a717e7ddbf31472ad28e358
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
* 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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <meta.h>
#include <metad.h>
#include <ctype.h>
#include <string.h>
/*
* 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
/*
* Macros to produce a quoted string containing the value of a
* preprocessor macro. For example, if SIZE is defined to be 256,
* VAL2STR(SIZE) is "256". This is used to construct format
* strings for scanf-family functions below.
*/
#define QUOTE(x) #x
extern char *getfullblkname();
extern char *getfullrawname();
/*
* caches
*/
/*
* leak proof name conversion
*/
static char *
char *uname
)
{
char *p;
return (NULL);
} else if (*p == '\0') {
Free(p);
return (NULL);
} else {
"invalid for device %s\n"), uname);
exit(1);
}
"invalid for raw device %s\n"), p);
exit(1);
}
"line containing device %s\n"), uname);
exit(1);
}
"block device for device %s\n"), uname);
exit(1);
}
"raw device for device %s\n"), p);
exit(1);
}
return (p);
}
}
char *
char *uname
)
{
char *p;
return (NULL);
} else if (*p == '\0') {
Free(p);
return (NULL);
} else {
return (p);
}
}
/*
* parse up metadevice name
*/
static int
char *uname,
char **snamep,
)
{
int len;
char *up;
char *tp;
int lcws; /* last character was slash */
/* handle dont cares */
/* Now copy uname to tname by throwing away any duplicate '/' */
if (lcws) {
if (*up == '/') {
continue;
} else {
lcws = 0;
}
}
if (*up == '/') {
lcws = 1;
}
}
*tp = '\0';
/* without set */
return (0);
}
/* fully-qualified without set */
return (0);
}
/* with set */
} else {
}
return (0);
}
/* no match */
return (-1);
}
/*
* FUNCTION: parse_device()
* INPUT: sp - pointer to setname struct
* uname - Name of either a hotspare pool or metadevice
* This can either be a fully qualified path or
* in the form [set name/]device
* OUTPUT: setnamep - name of the set that uname is in
* uname - name of the hotspare pools or metadevice
* only contains the name of the device with all
* other path information stripped off.
* PURPOSE: Parse uname and sp into the set name and device name strings.
* If the set name is specified as part of uname then use that
* otherwise attempt to get the set name from sp.
*/
static void
char *uname,
char **setnamep /* dynamically alloced - caller must free */
)
{
int len;
char *up;
char *tp;
int lcws; /* last character was slash */
/* Now copy uname to tname by throwing away any duplicate '/' */
if (lcws) {
if (*up == '/') {
continue;
} else {
lcws = 0;
}
}
if (*up == '/') {
lcws = 1;
}
}
*tp = '\0';
/* fully-qualified - local set */
return;
}
/* with setname specified - either fully qualified and relative spec */
}
return;
}
/* without setname specified */
else
}
}
/*
* parse up hotspare pool name
*/
static int
char *uname,
char **snamep,
)
{
int len;
/* handle dont cares */
/* without set */
return (0);
}
/* with set */
} else {
}
return (0);
}
/* no match */
return (-1);
}
/*
* canonicalize metadevice name
*/
static char *
char *sname,
)
{
char *cname;
} else {
}
return (cname);
}
/*
* canonicalize hotspare pool name
*/
static char *
char *sname,
)
{
char *cname;
} else {
}
return (cname);
}
/*
* canonicalize name, return type
*
* NOTE: this is really only for use by meta_tab*
*/
char *
char *uname
)
{
char *cname;
/* return the set name and dev name */
else {
(void) snprintf(
}
return (cname);
}
/*
* check that name is a metadevice
*/
int
char *uname
)
{
return (1);
else
return (0);
}
/*
* check that name is a hotspare pool
*/
int
char *uname
)
{
return (1);
else
return (0);
}
/*
* mdsetname_t stuff
*/
/*
* initialize setname
*/
static void
)
{
}
static void
{
if (MD_MNSET_DESC(sd)) {
while (nd) {
}
}
}
/*
* free allocated setname
*/
static void
)
{
}
/*
* flush the setname cache
*/
static void
{
mdsetnamelist_t *p, *n;
n = p->next;
metafreesetname(p->sp);
Free(p);
}
}
/*
* get set number
*/
static int
char *sname,
)
{
/* local set */
*setnop = 0;
return (0);
}
/* shared set */
char *p;
Free(p);
}
return (-1);
}
return (0);
}
/*
* find setname from name
*/
char *sname,
)
{
/* look for cached value first */
return (sp);
}
}
/* setup set */
return (NULL);
/* allocate new list element and setname */
return (sp);
}
/*
* find setname from setno
*/
)
{
/* look for cached value first */
return (sp);
}
/* local set */
if (setno == MD_LOCAL_SET)
/* shared set */
return (NULL);
return (sp);
}
char *sname
)
{
/* look for cached value first */
return (sp);
}
}
/* allocate new list element and setname */
return (sp);
}
/*
* setup set record (sr) and cache it in the mdsetname_t struct
*/
)
{
int i;
if (MD_MNSET_DESC(sd)) {
}
/*
* Get membershiplist from API routine. If there's
* an error, just use a NULL nodelist.
*/
nodecnt = 0; /* no nodes are alive */
}
nrcnt = 0;
/*
* Node descriptor node list must be built in
* ascending order of nodeid. The nodechain
* in the mnset record is in ascending order,
* so just make them the same.
*/
while (nr) {
if (nd_prev) {
} else {
}
sizeof (nd->nd_nodename));
}
}
/*
* If node is marked ALIVE, then set priv_ic
* from membership list. During the early part
* of a reconfig cycle, the membership list may
* have been changed, (a node entering or leaving
* the cluster), but rpc.metad hasn't flushed
* its data yet. So, if node is marked alive, but
* is no longer in the membership list (node has
* left the cluster) then just leave priv_ic to NULL.
*/
while (nl2) {
sizeof (nd->nd_priv_ic));
break;
}
}
}
nrcnt++;
}
if (nodecnt)
/* Just copying to keep consistent view between sr & sd */
} else {
for (i = 0; i < MD_MAXSIDES; i++)
}
return (sd);
}
)
{
}
}
}
}
return (NULL);
}
void
{
return;
return;
}
/*
* check for local set
*/
int
)
{
return (1);
} else {
return (0);
}
}
/*
* check for same set
*/
int
)
{
return (1);
} else {
return (0);
}
}
/*
* check to see if set changed
*/
static int
mdsetname_t **spp,
char *sname,
)
{
/* if we already have a set, make sure it's the same */
}
return (0);
}
/* otherwise store new set name and number */
return (-1);
}
/* return success */
return (0);
}
/*
* check to see if set changed from default
*/
static int
mdsetname_t **spp,
char *sname,
)
{
/* default to *spp's setname, or if that is NULL to MD_LOCAL_NAME */
if (*spp) {
} else {
}
}
/* see if changed */
}
/*
* check setname from setno
*/
static int
mdsetname_t **spp,
)
{
int rval;
/* local set */
if (setno == 0)
/* shared set */
return (-1);
return (rval);
}
/*
* mddrivename_t stuff
*/
/*
* initialize name
*/
static void
)
{
}
/*
* free allocated name
*/
static void
)
{
}
/*
* initialize drive name
*/
static void
)
{
}
/*
* flush side names
*/
void
)
{
mdsidenames_t *p, *n;
n = p->next;
Free(p);
}
}
/*
* free drive name
*/
void
)
{
}
/*
* flush the drive name cache
*/
static void
{
mddrivenamelist_t *p, *n;
n = p->next;
Free(p->drivenamep);
Free(p);
}
drivelistp = NULL;
}
/*
* peel off s%u from name
*/
char *
char *name
)
{
char *p, *e;
uint_t d = 0;
int l = 0;
if (is_metaname(name))
/*
*/
}
/*
*/
}
/* gobble number and 's' */
for (; (p > name); --p) {
if (!isdigit(*p))
break;
}
if ((p == e) || (p <= name))
p--;
*(++p) = '\0';
*p = 's';
return (e);
}
/*
* free list of drivenames
*/
void
)
{
}
}
/*
* build list of drivenames
*/
int
mdsetname_t **spp,
int argc,
char *argv[],
)
{
int count = 0;
return (-1);
}
}
return (count);
}
/*
* append to end of drivename list
*/
)
{
/* run to end of list */
;
/* allocate new list element */
/* append drivename */
return (dnp);
}
/*
* FUNCTION: meta_drivenamelist_append_wrapper()
* INPUT: tailpp - pointer to the list tail pointer
* dnp - name node to be appended to list
* OUTPUT: none
* RETURNS: mddrivenamelist_t * - new tail of the list.
* PURPOSE: wrapper to meta_namelist_append for performance.
* metanamelist_append finds the tail each time which slows
* down long lists. By keeping track of the tail ourselves
* we can change metadrivenamelist_append into a
* constant time operation.
*/
)
{
/* If it's the first item in the list, return it instead of the next */
return (tailpp);
}
/*
* mdname_t stuff
*/
/*
* check set and get comparison name
*/
char *
mdsetname_t **spp,
char *uname,
)
{
int ismeta = 0;
/* check set name */
ismeta = 1;
return (NULL);
}
/* return comparison name */
if (ismeta)
else
}
/*
* FUNCTION: getrname()
* INPUT: spp - the setname struct
* uname - the possibly unqualified device name
* OUTPUT: ep - return error pointer
* RETURNS: char* - character string containing the fully
* qualified raw device name
* PURPOSE: Create the fully qualified raw name for the possibly
* unqualified device name. If uname is an absolute
* path the raw name is derived from the input string.
* Otherwise, an attempt is made to get the rawname by
*/
static char *
{
char *rname,
*fname;
int constructed = 0;
/* if it is an absolute name then just call rawname on the input */
if (uname[0] == '/') {
return (rname);
/* out of luck */
return (NULL);
}
/*
* Check for metadevice before physical device.
* With the introduction of softpartitions it is more
* likely to be a metadevice.
*/
/* metadevice short form */
if (metaislocalset(*spp)) {
if (*uname == 'd')
constructed = 1;
} else {
char *p;
++p;
} else {
p = uname;
}
if (*p == 'd')
constructed = 1;
}
/*
* Handle the case where we have a new metadevice that does not yet
* exist in the name-space. In this case we return the constructed
* metadevice name as that will exist after the metainit call has
* created it.
*/
}
return (rname);
return (rname);
/*
* If all else fails try the straight uname.
* NOTE: This check was at the beginning of getrname instead
* of here. It was moved to avoid a conflict with SC3.0. If
* a diskset was mounted with the same name it would hang
* the cluster in a loop. Example:
*
*
* When the system was booted DiskSuite would try to take ownership
* called. rawname() stats the string which caused the cluster
* reservation code to try and take ownership which it was already
* doing and a deadlock would occur. By moving this final attempt
* at resolving the rawname to the end we avoid this deadlock.
*/
return (rname);
/* out of luck */
return (NULL);
}
/*
* get raw slice and drive names
*/
static char *
mdsetname_t **spp,
char *uname,
char **dnamep,
)
{
char *rname;
/* initialize */
/* get slice name */
return (rname);
}
/*
* If name cannot be found, if may be because is is not accessible.
* If it is an absolute name, try all possible disk name formats and
*/
if (uname[0] == '/') {
/* Absolute name */
char *p;
uint_t d = 0;
int l = 0;
/*
* Handle old style raw names
*/
mdclrerror(ep);
return (rname);
}
/*
* Handle old style block names
*/
return (rname);
}
/* /.../dsk/... */
mdclrerror(ep);
++p;
return (rname);
}
/* /.../rdsk/... */
mdclrerror(ep);
return (rname);
}
} else {
/*
* If it's not an absolute name but is a valid ctd name,
*/
uint_t s;
uname);
return (rname);
}
}
}
/* out of luck */
return (NULL);
}
/*
* get number of slices for name
*/
static int
char *rname,
char *dname,
)
{
char *srname;
size_t l = 0;
/*
* get our slice number - works only with names that end in s%u -
* all others return -1.
*/
(int)*slicep < 0) {
return (-1);
}
/*
* go find how many slices there really are
*/
/* build slice name */
/* see if it's there */
break;
}
}
/* Need to make sure that we at least have V_NUMPAR */
/* make sure we have at least our slice */
return (-1);
/* return number of slices */
return (nslice);
}
/*
* Attempt to parse the input string as a c[t]ds specifier
* The target can either be a SCSI target id or if the device
* is in a fabric configuration in a fibre channel setup then
* the target is a standard WWN (world wide name).
*
* if successful return 0
* if c[t]dp name return 1
* otherwise return -1
*/
int
char *uname,
{
int has_target = 1;
char *partial_ctd_str;
char *target_str;
char *device_start_pos;
int l = -1;
/* pull off the channel spec and the 't' for the target */
/* check for cds style name */
return (-1);
} else {
l--; /* we want to be on the 'd' */
has_target = 0;
}
}
partial_ctd_str = uname + l;
/* find the beginning of the device specifier */
if (device_start_pos == NULL) {
return (-1);
}
/* check to see if it is a ctd with a WWN or SCSI target */
if (has_target) {
/* pull off the target and see if it is a WWN */
target_str_len - 2);
l != target_str_len) {
return (-1);
}
}
/* check the device and slice */
l != cl) {
/* check the device and partition */
== 2 && l == cl) {
return (1);
}
return (-1);
}
return (0);
}
/*
* get number of slices for name
*/
static int
char *uname,
)
{
uint_t c = 0, t = 0, d = 0;
int l = 0, cl = 0;
int fd;
char *p;
if (is_metaname(uname))
return (*slicep = 0);
p++;
else
p = uname;
return (*slicep);
l == cl)
return (*slicep);
return (*slicep);
/*
* If we can't get the slice from the name, then we have to do it the
* hard and expensive way.
*/
return (-1);
/* get controller info */
return (-1);
}
else
return (-1);
}
}
}
/*
* get partition info
*/
static int
char *rname,
char *dname,
)
{
int nparts;
/* metadevice */
if (is_metaname(rname)) {
nparts = 1;
partno = 0;
goto gotit;
}
/* see how many partitions in drive, this is really tricky */
metainitname(&name);
/* partno already setup */
/* dname already setup */
goto gotit;
}
return (-1);
/* fallback and try and guess (used to check for just EACCES here) */
if (mdanysyserror(ep)) {
} else {
}
mdclrerror(ep);
/* nparts already setup */
/* partno already setup */
/* dname already setup */
goto gotit;
}
/* nothing worked */
if (mdanysyserror(ep)) {
} else {
}
mdclrerror(ep);
mdclrerror(ep);
partno = 0;
}
/* return success */
return (0);
}
/*
* get block name
*/
static int
)
{
char *bname;
/* fully qualified */
return (0);
}
/* out of luck */
}
static void
)
{
char *p;
/* regular device */
return;
}
return;
}
return;
}
/* anything else but metadevice */
return;
}
/* metadevice */
++p;
if (metaislocalset(sp)) {
} else {
}
}
/*
* get dev
*/
int
)
{
/* get dev */
/* check set */
/* return sucess */
return (0);
}
/*
* set up names for a slice
*/
static int
char *rname,
)
{
/* get names */
return (-1);
return (-1);
/* return success */
return (0);
}
/*
* fake up names for a slice
*/
static void
char *rname
)
{
char *p;
uint_t d = 0;
int l = 0;
/* fake names */
/*
* Fixup old style names
*/
/*
* Fixup new style names
*/
for (++p; (*(p + 1) != '\0'); ++p)
*p = *(p + 1);
*p = '\0';
}
}
static mdname_t *
char *uname,
char *rname,
char *dname,
)
{
/* must have a set */
if (rname)
else if (is_metaname(dname))
else {
uint_t d = 0;
/*
*/
'a' + partno);
'a' + partno);
} else {
/* build the slice that is wanted */
}
}
mdclrerror(ep);
if (mdanysyserror(ep)) {
} else {
}
mdclrerror(ep);
} else {
mdclrerror(ep);
goto fixup;
}
}
}
out:
/* return name */
return (np);
if (mdanysyserror(ep)) {
char *p;
mdclrerror(ep);
else
} else {
else
}
}
goto out;
}
/*
* flush the fast name cache
*/
static void
{
}
}
/*
* flush the fast name cache
*/
static void
{
mdnamelist_t *p, *n;
n = p->next;
metafreefastnm(&p->namep);
Free(p);
}
}
static char *
{
uint_t d = 0;
int l = 0;
char *rnm;
char *p;
if (is_metaname(unm)) {
/* without set */
return (rnm);
}
/* fully-qualified without set */
cl == l) {
return (rnm);
}
/* with set */
snm, &d, &l) == 2 ||
snm, d);
return (rnm);
}
}
/* NOT Fully qualified path, done */
if (unm[0] != '/') {
return (NULL);
}
/*
* Get slice information from old style names of the form
* devices, but after metadevices.
*/
}
}
++p;
return (rnm);
}
/*
* Shouldn't get here but if we do then we have an unrecognized
* fully qualified path - error
*/
return (NULL);
}
static mdname_t *
char *uname,
)
{
uint_t c = 0, t = 0, d = 0, s = 0;
int l = 0;
return (np);
}
/* Metadevices */
if (is_metaname(uname)) {
char *p;
++p;
else
p = uname;
if (metaislocalset(sp)) {
} else {
}
goto done;
}
/* Others */
&s, &l) == 4 ||
&s, &l) == 4 ||
&s, &l) == 4 ||
&s, &l) == 4 ||
else
} else {
}
done:
/* Driver always gives us block names */
/* canonical disk name */
} else {
return (NULL);
}
/* cleanup, return success */
return (np);
}
/*
* set up names for a device
*/
static mdname_t *
mdsetname_t **spp,
char *uname,
int fast,
)
{
/* check setname */
return (NULL);
/* get raw name (rname) of the slice and drive (dname) we have */
return (NULL);
}
/* look in cache first */
/* check to see if the drive name is already in the cache */
return (NULL);
}
}
/*
* If a fast names is OK, then get one, and be done.
*/
if (fast) {
}
/* allocate new list element and drive */
/* get parts info */
goto out;
/*
* libmeta needs at least V_NUMPAR partitions.
* If we have an EFI partition with less than V_NUMPAR slices,
* we nevertheless reserve space for V_NUMPAR
*/
}
/* allocate and link in parts */
}
/* setup name_t (or slice) wanted */
== NULL)
goto out;
/* canonical disk name */
/* cleanup, return success */
return (np);
/* cleanup, return error */
out:
return (NULL);
}
mdname_t *
mdsetname_t **spp,
char *uname,
)
{
}
mdname_t *
mdsetname_t **spp,
char *uname,
)
{
}
/*
* set up names for a drive
*/
mdsetname_t **spp,
char *uname,
)
{
char *slicename;
char *cname;
char *dname;
int i;
int mplen;
/* check setname, get comparison name */
return (NULL);
}
return (NULL);
}
/* look in cache first */
return (dnp);
}
}
/* Check each possible slice name based on MD_MAX_PARTS. */
/*
* Figure out how much string space to reserve to fit
* (MD_MAX_PARTS - 1) into the name string; the loop will
* increment the mplen counter once for each decimal digit in
* (MD_MAX_PARTS - 1).
*/
/* Check for each slice in turn until we find one */
}
char *dname;
}
return (NULL);
}
return (np->drivenamep);
}
/*
* FUNCTION: metaslicename()
* INPUT: dnp - the drivename structure
* sliceno - the slice on the drive to return
* OUTPUT: ep - return error pointer
* RETURNS: mdname_t- pointer the the slice name structure
* PURPOSE: interface to the parts struct in the drive name struct
* Since there is no guarantee that the slice name
* structures are populated users should call this
* function rather than accessing the structure directly
* since it will populate the structure values if they
* haven't already been populated before returning.
*/
mdname_t *
)
{
return (NULL);
}
/* check to see if the struct is already populated */
return (np);
}
return (NULL);
return (np);
}
/*
* set up metadevice name from id
*/
mdname_t *
mdsetname_t **spp,
int fast,
)
{
char *uname;
/* check set first */
return (NULL);
/* build corresponding device name */
if (metaislocalset(sp)) {
} else {
MD_MIN2UNIT(mnum));
}
/* setup name */
if (fast) {
} else
return (np);
}
/*
* return metadevice name
*/
char *
)
{
/* get name */
mdclrerror(&status);
return (NULL);
}
/* return name */
}
/*
* check for device type
*/
int
)
{
}
int
)
{
if (! metaismeta(np)) {
}
return (0);
}
int
)
{
case MDT_ACCES:
case MDT_UNKNOWN:
default:
assert(0);
}
}
return (0);
}
int
)
{
if (metaismeta(np)) {
}
}
/*
* free list of names
*/
void
)
{
}
}
/*
* build list of names
*/
int
mdsetname_t **spp,
mdnamelist_t **nlpp,
int argc,
char *argv[],
)
{
int count = 0;
return (-1);
}
}
return (count);
}
/*
* append to end of name list
*/
mdname_t *
mdnamelist_t **nlpp,
)
{
/* run to end of list */
;
/* allocate new list element */
/* append name */
return (np);
}
/*
* FUNCTION: meta_namelist_append_wrapper()
* INPUT: tailpp - pointer to the list tail pointer
* np - name node to be appended to list
* OUTPUT: none
* RETURNS: mdnamelist_t * - new tail of the list.
* PURPOSE: wrapper to meta_namelist_append for performance.
* metanamelist_append finds the tail each time which slows
* down long lists. By keeping track of the tail ourselves
* we can change metanamelist_append into a constant time
* operation.
*/
mdnamelist_t **
)
{
/* If it's the first item in the list, return it instead of the next */
return (tailpp);
}
/*
* mdhspname_t stuff
*/
/*
* initialize hspname
*/
static void
)
{
}
/*
* free allocated hspname
*/
static void
)
{
}
/*
* clear the hspname cache
*/
static void
{
mdhspnamelist_t *p, *n;
n = p->next;
metafreehspname(p->hspnamep);
Free(p);
}
}
/*
* check set and get comparison name
*/
static char *
mdsetname_t **spp,
char *uname,
)
{
/* check setname */
return (NULL);
}
return (NULL);
}
/* return comparison name */
}
/*
* set up names for a hotspare pool
*/
mdsetname_t **spp,
char *uname,
)
{
char *cname;
/* check setname */
return (NULL);
/* look in cache first */
return (hspnp);
}
}
/* allocate new list element and hspname */
/* save hspname and number */
/* success */
return (hspnp);
/* cleanup, return error */
out:
return (NULL);
}
/*
* set up hotspare pool name from id
*/
mdsetname_t **spp,
)
{
char *uname;
/* check set first */
return (NULL);
/* build corresponding hotspare pool name */
if (metaislocalset(sp)) {
} else {
}
/* setup name */
return (hspnp);
}
/*
* return hotspare pool name
*/
char *
{
/* get name */
mdclrerror(&status);
return (NULL);
}
/* return name */
}
/*
* free hotspare pool list
*/
void
{
}
}
/*
* build list of hotspare pool names
*/
int
mdsetname_t **spp,
int argc,
char *argv[],
)
{
int count = 0;
return (-1);
}
}
return (count);
}
/*
* append to end of hotspare pool list
*/
{
/* run to end of list */
;
/* allocate new list element */
/* append hotspare pool name */
return (hspnp);
}
/*
* get name from dev
*/
mdname_t *
mdsetname_t **spp,
md_error_t *ep)
{
char *device_name;
/* short circuit metadevices */
if (meta_dev_ismeta(dev))
/* create local set, if necessary */
return (NULL);
}
/* get name from namespace */
return (NULL);
}
return (namep);
}
/*
* return cached name from md_dev64_t
*/
static char *
{
/* look in cache */
uint_t i;
}
}
/* not found */
return (NULL);
}
/*
* Ask the driver for the name, which has been stored in the
* metadevice state database (on behalf of the utilities).
* (by devno)
*/
char *
{
/* get name */
if ((setno == MD_SET_BAD) ||
mdclrerror(&status);
return (metadevtocachename(dev));
}
/* return name */
}
/*
* get name from key
*/
mdname_t *
mdsetname_t **spp,
int fast,
)
{
char *device_name;
/* create local set, if necessary */
return (NULL);
}
/* get name from namespace */
return (NULL);
}
if (fast)
else
if (namep)
return (namep);
}
/*
* completely flush the caches
*/
void
{
if (flush_sr_cache)
sr_cache_flush(0);
}
/*
* meta_get_hotspare_names
* returns an mdnamelist_t of hot spare names
*/
int
mdnamelist_t **nlpp,
int options,
)
{
int cnt = 0;
/* get hotspare names */
cnt = -1;
goto out;
}
/* build name list */
int i;
cnt = -1;
goto out;
}
++cnt;
}
}
/* cleanup and return count or error */
out:
/*
* At least try to give some sort of meaningful error
*/
}
return (cnt);
}
/*
* meta_create_non_dup_list
* INPUT: mdnp mdname_t pointer to add to the list if a new name
* ldevidp list of non-duplicate names.
* OUTPUT: ldevidp list of non-duplicate names.
* meta_create_non_dup_list will take a mdname_t pointer and if the device
* is not in the list (ldevidp) will add it to the list.
* User needs to free allocated memory.
*/
void
)
{
char *lcname;
return;
/*
* Grab the name of the device and strip off slice information
*/
return;
}
else
*slice = '\0';
/* first item in list */
} else {
/* already there so just return */
return;
}
lastdevidp = tmp;
}
}
}