dsr.c revision a08731ec17cb062d80f19791149c20e0f2f43b01
/*
* 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
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Dependent on types.h, but not including it...
*/
#include <stdio.h>
#include <sys/sysmacros.h>
#include <nfs/nfs_clnt.h>
#include <kstat.h>
#include <ctype.h>
#include <dirent.h>
#include <libdevinfo.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <devid.h>
#include "dsr.h"
#include "statcommon.h"
typedef struct {
char *minor_name;
int minor_isdisk;
static char md_minor_name[MAXPATHLEN];
static char *mdsetno2name(int setno);
/* nfs info */
extern kstat_ctl_t *kc;
static int nfs_tried;
static char *get_nfs_by_minor(uint_t);
static char *cur_special(char *, char *);
/*
* Clear the snapshot so a cache miss in lookup_ks_name() will cause a fresh
* snapshot in drvinstunit2dev().
*/
void
{
if (di_dim) {
}
if (di_root) {
}
nfs_tried = 0;
}
/*
* Find information for (driver, instunit) device: return zero on failure.
*
* NOTE: Failure of drvinstunit2dev works out OK for the caller if the kstat
* name is the same as public name: the caller will just use kstat name.
*/
static int
{
int instance;
minor_match_t **mma;
char *devpath;
char *devid;
char *a, *s;
int mdsetno;
char amdsetname[MAXPATHLEN];
char *devicespath;
/* setup "no result" return values */
if (devpathp)
if (adevpathp)
if (devidp)
if (isdiskp)
*isdiskp = 0;
/* take <driver><instance><minor_name> snapshot if not established */
di_dim = di_dim_init();
return (0);
}
/*
* Determine if 'instunit' is an 'instance' or 'unit' based on the
* 'driver'. The current code only detects 'md' metadevice 'units',
* and defaults to 'instance' for everything else.
*
* For a metadevice, 'driver' is either "md" or "<setno>/md".
*/
/*
* "md" unit: Special case translation of "md" kstat names.
* For the local set the kstat name is "md<unit>", and for
* a shared set the kstat name is "<setno>/md<unit>": we map
*/
/* convert setno to setname */
} else
mdsetno = 0;
driver = "md";
instance = 0;
} else {
}
/* Try to find a minor_match that works */
break;
}
return (0);
/*
* At this point we have a devpath result. Return the information about
* the result that the caller is asking for.
*/
if (devpathp) /* devpath */
if (adevpathp) { /* abbreviated devpath */
if (mm->minor_isdisk) {
/*
* For disks we return the last component (with
* trailing "s#" or "p#" stripped off for disks).
* abbreviated devpath would be "c0t0d0".
*/
if (a == NULL) {
return (0);
}
a++;
s = strrchr(a, 's');
if (s == NULL) {
s = strrchr(a, 'p');
if (s == NULL) {
return (0);
}
}
/* don't include slice information in devpath */
*s = '\0';
} else {
/*
* remove "/dev/", and "/dsk/", from 'devpath' (like
*/
/*
* If we have an mdsetname, convert abbreviated setno
*/
if (mdsetname) {
"md/%s%s", mdsetname, a);
a = amdsetname;
} else {
if (*devpath == '/')
a = devpath + 1;
else
a = devpath;
}
}
*adevpathp = safe_strdup(a);
}
if (devidp) { /* lookup the devid */
/* take snapshots if not established */
if (di_root == DI_NODE_NIL) {
}
if (di_root) {
/* get path to /devices devinfo node */
if (devicespath) {
/* find the node in the snapshot */
/* and lookup devid property on the node */
}
}
}
if (isdiskp)
return (1); /* success */
}
/*
* The basic format of a kstat name is "<driver><instunit>,<partition>". The
* <instunit> is a base10 number, and the ",<partition>" part is optional.
*
* NOTE: In the case of non-local metadevices, the format of "<driver>" in
* a kstat name is acutally "<setno>/md".
*/
{
char *p;
int len;
char driver[MAXNAMELEN];
int instunit;
char *devpath;
int isdisk;
/*
* Extract <driver> and <instunit> from kstat name.
* Filter out illegal forms (like all digits).
*/
return (NULL);
if (p == NULL)
else
p--; /* before ",partition" */
p--; /* backwards over digits */
p++; /* start of instunit */
if ((*p == '\0') || (*p == ','))
return (NULL); /* no <instunit> */
/* hash and search for existing disklist entry */
return (entry);
}
}
/* not found, try to get dev information */
return (NULL);
}
/* and make a new disklist entry ... */
if (isdisk) {
#if defined(__i386)
#endif
}
/* add new entry to head of instunit hashed list */
return (entry);
}
/*
* The caller is responsible for freeing the returned string.
*/
static char *
mdsetno2name(int setno)
{
char *p;
/* we are looking for a link to setlink */
return (NULL);
/* doing a readlink of entry (fails for non-symlinks) */
*p = '\0';
continue;
/* and looking for a link to setlink */
continue;
/* found- name of link is the setname */
break;
}
return (mdsetname);
}
char *
{
char *cp;
char *rstr = 0;
if (cp) {
return (rstr);
}
if (host) {
if (*host) {
if (path) {
len += 2;
} else {
}
} else {
}
} else {
}
} else if (nfs_tried == 0) {
nfs_tried = 1;
do_mnttab();
goto retry;
}
}
return (rstr);
}
static char *
{
while (localnfs) {
return (localnfs->device_name);
}
}
return (0);
}
/*
* Read the cur_hostname from the mntinfo kstat
*/
static char *
{
static struct mntinfo_kstat mik;
char *rstr;
continue;
continue;
continue;
continue;
return (NULL);
return (NULL);
return (rstr);
}
return (NULL);
}
/*
* Given the hostname of the mounted server, extract the server
* mount point from the mnttab string.
*
* Common forms:
* server1,server2,server3:/path
* server1:/path,server2:/path
* or a hybrid of the two
*/
static char *
{
char *cp;
char *path;
/*
* find hostname in string
*/
return (NULL);
/*
* hostname must be followed by ',' or ':'
*/
goto again;
}
/*
* If hostname is followed by a ',' eat all characters until a ':'
*/
if (*cp == ',') {
cp++;
while (*cp != ':') {
return (NULL);
cp++;
}
}
/*
* path is terminated by either 0, or space or ','
*/
while (*cp) {
return (path);
}
cp++;
}
return (path);
}