xref: /onnv-gate/usr/src/lib/libdiskmgt/common/slice.c (revision 7563:84ec90ffc3f7)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52912Sartem  * Common Development and Distribution License (the "License").
62912Sartem  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*7563SPrasad.Singamsetty@Sun.COM 
220Sstevel@tonic-gate /*
23*7563SPrasad.Singamsetty@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #include <fcntl.h>
280Sstevel@tonic-gate #include <libdevinfo.h>
290Sstevel@tonic-gate #include <stdio.h>
300Sstevel@tonic-gate #include <stdlib.h>
310Sstevel@tonic-gate #include <string.h>
320Sstevel@tonic-gate #include <dirent.h>
330Sstevel@tonic-gate #include <sys/dkio.h>
340Sstevel@tonic-gate #include <sys/stat.h>
350Sstevel@tonic-gate #include <sys/sunddi.h>
360Sstevel@tonic-gate #include <sys/types.h>
370Sstevel@tonic-gate #include <sys/vtoc.h>
380Sstevel@tonic-gate #include <unistd.h>
390Sstevel@tonic-gate #include <devid.h>
400Sstevel@tonic-gate #include <dirent.h>
410Sstevel@tonic-gate #include <sys/dktp/fdisk.h>
420Sstevel@tonic-gate #include <sys/efi_partition.h>
430Sstevel@tonic-gate 
440Sstevel@tonic-gate #include "libdiskmgt.h"
450Sstevel@tonic-gate #include "disks_private.h"
460Sstevel@tonic-gate #include "partition.h"
470Sstevel@tonic-gate #ifndef VT_ENOTSUP
480Sstevel@tonic-gate #define	VT_ENOTSUP	(-5)
490Sstevel@tonic-gate #endif
500Sstevel@tonic-gate 
510Sstevel@tonic-gate #define	FMT_UNKNOWN	0
520Sstevel@tonic-gate #define	FMT_VTOC	1
530Sstevel@tonic-gate #define	FMT_EFI		2
540Sstevel@tonic-gate 
551352Seschrock typedef int (*detectorp)(char *, nvlist_t *, int *);
561352Seschrock 
571352Seschrock static detectorp detectors[] = {
581352Seschrock 	inuse_mnt,
591352Seschrock 	inuse_svm,
601352Seschrock 	inuse_active_zpool,
611352Seschrock 	inuse_lu,
621352Seschrock 	inuse_dump,
631352Seschrock 	inuse_vxvm,
641352Seschrock 	inuse_exported_zpool,
651352Seschrock 	inuse_fs,  /* fs should always be last */
661352Seschrock 	NULL
670Sstevel@tonic-gate };
680Sstevel@tonic-gate 
690Sstevel@tonic-gate static int	add_inuse(char *name, nvlist_t *attrs);
700Sstevel@tonic-gate static int	desc_ok(descriptor_t *dp);
710Sstevel@tonic-gate static void	dsk2rdsk(char *dsk, char *rdsk, int size);
720Sstevel@tonic-gate static int	get_attrs(descriptor_t *dp, int fd,  nvlist_t *attrs);
730Sstevel@tonic-gate static descriptor_t **get_fixed_assocs(descriptor_t *desc, int *errp);
740Sstevel@tonic-gate static int	get_slice_num(slice_t *devp);
750Sstevel@tonic-gate static int	match_fixed_name(disk_t *dp, char *name, int *errp);
760Sstevel@tonic-gate static int	make_fixed_descriptors(disk_t *dp);
770Sstevel@tonic-gate 
780Sstevel@tonic-gate descriptor_t **
slice_get_assoc_descriptors(descriptor_t * desc,dm_desc_type_t type,int * errp)790Sstevel@tonic-gate slice_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type,
800Sstevel@tonic-gate     int *errp)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate 	if (!desc_ok(desc)) {
830Sstevel@tonic-gate 	    *errp = ENODEV;
840Sstevel@tonic-gate 	    return (NULL);
850Sstevel@tonic-gate 	}
860Sstevel@tonic-gate 
870Sstevel@tonic-gate 	switch (type) {
880Sstevel@tonic-gate 	case DM_MEDIA:
890Sstevel@tonic-gate 	    return (media_get_assocs(desc, errp));
900Sstevel@tonic-gate 	case DM_PARTITION:
910Sstevel@tonic-gate 	    return (partition_get_assocs(desc, errp));
920Sstevel@tonic-gate 	}
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 	*errp = EINVAL;
950Sstevel@tonic-gate 	return (NULL);
960Sstevel@tonic-gate }
970Sstevel@tonic-gate 
980Sstevel@tonic-gate /*
990Sstevel@tonic-gate  * This is called by media/partition to get the slice descriptors for the given
1000Sstevel@tonic-gate  * media/partition descriptor.
1010Sstevel@tonic-gate  * For media, just get the slices, but for a partition, it must be a solaris
1020Sstevel@tonic-gate  * partition and if there are active partitions, it must be the active one.
1030Sstevel@tonic-gate  */
1040Sstevel@tonic-gate descriptor_t **
slice_get_assocs(descriptor_t * desc,int * errp)1050Sstevel@tonic-gate slice_get_assocs(descriptor_t *desc, int *errp)
1060Sstevel@tonic-gate {
1070Sstevel@tonic-gate 	/* Just check the first drive name. */
1080Sstevel@tonic-gate 	if (desc->p.disk->aliases == NULL) {
1090Sstevel@tonic-gate 	    *errp = 0;
1100Sstevel@tonic-gate 	    return (libdiskmgt_empty_desc_array(errp));
1110Sstevel@tonic-gate 	}
1120Sstevel@tonic-gate 
1132912Sartem 	return (get_fixed_assocs(desc, errp));
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate nvlist_t *
slice_get_attributes(descriptor_t * dp,int * errp)1170Sstevel@tonic-gate slice_get_attributes(descriptor_t *dp, int *errp)
1180Sstevel@tonic-gate {
1190Sstevel@tonic-gate 	nvlist_t	*attrs = NULL;
1200Sstevel@tonic-gate 	int		fd;
1210Sstevel@tonic-gate 	char		devpath[MAXPATHLEN];
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	if (!desc_ok(dp)) {
1240Sstevel@tonic-gate 	    *errp = ENODEV;
1250Sstevel@tonic-gate 	    return (NULL);
1260Sstevel@tonic-gate 	}
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate 	if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) {
1290Sstevel@tonic-gate 	    *errp = ENOMEM;
1300Sstevel@tonic-gate 	    return (NULL);
1310Sstevel@tonic-gate 	}
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate 	/* dp->name is /dev/dsk, need to convert back to /dev/rdsk */
1340Sstevel@tonic-gate 	dsk2rdsk(dp->name, devpath, sizeof (devpath));
1350Sstevel@tonic-gate 	fd = open(devpath, O_RDONLY|O_NDELAY);
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate 	if ((*errp = get_attrs(dp, fd, attrs)) != 0) {
1380Sstevel@tonic-gate 	    nvlist_free(attrs);
1390Sstevel@tonic-gate 	    attrs = NULL;
1400Sstevel@tonic-gate 	}
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 	if (fd >= 0) {
1430Sstevel@tonic-gate 	    (void) close(fd);
1440Sstevel@tonic-gate 	}
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 	return (attrs);
1470Sstevel@tonic-gate }
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate /*
1500Sstevel@tonic-gate  * Look for the slice by the slice devpath.
1510Sstevel@tonic-gate  */
1520Sstevel@tonic-gate descriptor_t *
slice_get_descriptor_by_name(char * name,int * errp)1530Sstevel@tonic-gate slice_get_descriptor_by_name(char *name, int *errp)
1540Sstevel@tonic-gate {
1550Sstevel@tonic-gate 	int		found = 0;
1560Sstevel@tonic-gate 	disk_t		*dp;
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 	for (dp = cache_get_disklist(); dp != NULL; dp = dp->next) {
1590Sstevel@tonic-gate 		found = match_fixed_name(dp, name, errp);
1600Sstevel@tonic-gate 
1612912Sartem 		if (found) {
1622912Sartem 			char	mname[MAXPATHLEN];
1630Sstevel@tonic-gate 
1642912Sartem 			if (*errp != 0) {
1652912Sartem 			    return (NULL);
1662912Sartem 			}
1670Sstevel@tonic-gate 
1682912Sartem 			mname[0] = 0;
1692912Sartem 			(void) media_read_name(dp, mname, sizeof (mname));
1700Sstevel@tonic-gate 
1712912Sartem 			return (cache_get_desc(DM_SLICE, dp, name, mname,
1722912Sartem 			    errp));
1732912Sartem 		}
1740Sstevel@tonic-gate 	}
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 	*errp = ENODEV;
1770Sstevel@tonic-gate 	return (NULL);
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate /* ARGSUSED */
1810Sstevel@tonic-gate descriptor_t **
slice_get_descriptors(int filter[],int * errp)1820Sstevel@tonic-gate slice_get_descriptors(int filter[], int *errp)
1830Sstevel@tonic-gate {
1840Sstevel@tonic-gate 	return (cache_get_descriptors(DM_SLICE, errp));
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate char *
slice_get_name(descriptor_t * desc)1880Sstevel@tonic-gate slice_get_name(descriptor_t *desc)
1890Sstevel@tonic-gate {
1900Sstevel@tonic-gate 	return (desc->name);
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate nvlist_t *
slice_get_stats(descriptor_t * dp,int stat_type,int * errp)1940Sstevel@tonic-gate slice_get_stats(descriptor_t *dp, int stat_type, int *errp)
1950Sstevel@tonic-gate {
1960Sstevel@tonic-gate 	nvlist_t	*stats;
1970Sstevel@tonic-gate 	char		*str;
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate 	if (stat_type != DM_SLICE_STAT_USE) {
2000Sstevel@tonic-gate 	    *errp = EINVAL;
2010Sstevel@tonic-gate 	    return (NULL);
2020Sstevel@tonic-gate 	}
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate 	*errp = 0;
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 	if (nvlist_alloc(&stats, NVATTRS_STAT, 0) != 0) {
2070Sstevel@tonic-gate 	    *errp = ENOMEM;
2080Sstevel@tonic-gate 	    return (NULL);
2090Sstevel@tonic-gate 	}
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 	if ((*errp = add_inuse(dp->name, stats)) != 0) {
2120Sstevel@tonic-gate 	    return (NULL);
2130Sstevel@tonic-gate 	}
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 	/* if no cluster use, check for a use of the local name */
2160Sstevel@tonic-gate 	if (nvlist_lookup_string(stats, DM_USED_BY, &str) != 0) {
2170Sstevel@tonic-gate 	    disk_t	*diskp;
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 	    diskp = dp->p.disk;
2200Sstevel@tonic-gate 	    if (diskp->aliases != NULL && diskp->aliases->cluster) {
2210Sstevel@tonic-gate 		slice_t		*sp;
2220Sstevel@tonic-gate 		int		snum = -1;
2230Sstevel@tonic-gate 		struct dk_minfo	minfo;
2240Sstevel@tonic-gate 		struct dk_cinfo	dkinfo;
2250Sstevel@tonic-gate 		char		devpath[MAXPATHLEN];
2260Sstevel@tonic-gate 		int		fd;
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate 		/* dp->name is /dev/dsk, need to convert back to /dev/rdsk */
2290Sstevel@tonic-gate 		dsk2rdsk(dp->name, devpath, sizeof (devpath));
2300Sstevel@tonic-gate 		fd = open(devpath, O_RDONLY|O_NDELAY);
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate 		if (fd >= 0 && media_read_info(fd, &minfo) &&
2330Sstevel@tonic-gate 		    ioctl(fd, DKIOCINFO, &dkinfo) >= 0) {
2340Sstevel@tonic-gate 		    snum = dkinfo.dki_partition;
2350Sstevel@tonic-gate 		}
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate 		if (fd >= 0) {
2380Sstevel@tonic-gate 		    (void) close(fd);
2390Sstevel@tonic-gate 		}
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate 		if (snum >= 0) {
2420Sstevel@tonic-gate 		    for (sp = diskp->aliases->orig_paths; sp != NULL;
2430Sstevel@tonic-gate 			sp = sp->next) {
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate 			if (sp->slice_num == snum) {
2460Sstevel@tonic-gate 			    char	localpath[MAXPATHLEN];
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate 			    slice_rdsk2dsk(sp->devpath, localpath,
2490Sstevel@tonic-gate 				sizeof (localpath));
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 			    if ((*errp = add_inuse(localpath, stats)) != 0) {
2520Sstevel@tonic-gate 				return (NULL);
2530Sstevel@tonic-gate 			    }
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate 			    break;
2560Sstevel@tonic-gate 			}
2570Sstevel@tonic-gate 		    }
2580Sstevel@tonic-gate 		}
2590Sstevel@tonic-gate 	    }
2600Sstevel@tonic-gate 	}
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate 	return (stats);
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate /*
2660Sstevel@tonic-gate  * A slice descriptor points to a disk, the name is the devpath and the
2670Sstevel@tonic-gate  * secondary name is the media name.
2680Sstevel@tonic-gate  */
2690Sstevel@tonic-gate int
slice_make_descriptors()2700Sstevel@tonic-gate slice_make_descriptors()
2710Sstevel@tonic-gate {
2720Sstevel@tonic-gate 	disk_t		*dp;
2730Sstevel@tonic-gate 
2740Sstevel@tonic-gate 	dp = cache_get_disklist();
2750Sstevel@tonic-gate 	while (dp != NULL) {
2760Sstevel@tonic-gate 	    int	error;
2770Sstevel@tonic-gate 
2782912Sartem 	    error = make_fixed_descriptors(dp);
2790Sstevel@tonic-gate 	    if (error != 0) {
2800Sstevel@tonic-gate 		return (error);
2810Sstevel@tonic-gate 	    }
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate 	    dp = dp->next;
2840Sstevel@tonic-gate 	}
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate 	return (0);
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate /* convert rdsk paths to dsk paths */
2900Sstevel@tonic-gate void
slice_rdsk2dsk(char * rdsk,char * dsk,int size)2910Sstevel@tonic-gate slice_rdsk2dsk(char *rdsk, char *dsk, int size)
2920Sstevel@tonic-gate {
2930Sstevel@tonic-gate 	char	*strp;
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 	(void) strlcpy(dsk, rdsk, size);
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 	if ((strp = strstr(dsk, "/rdsk/")) == NULL) {
2980Sstevel@tonic-gate 	    /* not rdsk, check for floppy */
2990Sstevel@tonic-gate 	    strp = strstr(dsk, "/rdiskette");
3000Sstevel@tonic-gate 	}
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate 	if (strp != NULL) {
3030Sstevel@tonic-gate 	    strp++;	/* move ptr to the r in rdsk or rdiskette */
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate 	    /* move the succeeding chars over by one */
3060Sstevel@tonic-gate 	    do {
3070Sstevel@tonic-gate 		*strp = *(strp + 1);
3080Sstevel@tonic-gate 		strp++;
3090Sstevel@tonic-gate 	    } while (*strp);
3100Sstevel@tonic-gate 	}
3110Sstevel@tonic-gate }
3120Sstevel@tonic-gate 
3130Sstevel@tonic-gate /*
3140Sstevel@tonic-gate  * Check if/how the slice is used.
3150Sstevel@tonic-gate  */
3160Sstevel@tonic-gate static int
add_inuse(char * name,nvlist_t * attrs)3170Sstevel@tonic-gate add_inuse(char *name, nvlist_t *attrs)
3180Sstevel@tonic-gate {
3190Sstevel@tonic-gate 	int	i;
3200Sstevel@tonic-gate 	int	error;
3210Sstevel@tonic-gate 
3221352Seschrock 	for (i = 0; detectors[i] != NULL; i ++) {
3231352Seschrock 	    if (detectors[i](name, attrs, &error) || error != 0) {
3240Sstevel@tonic-gate 		if (error != 0) {
3250Sstevel@tonic-gate 		    return (error);
3260Sstevel@tonic-gate 		}
3270Sstevel@tonic-gate 		break;
3280Sstevel@tonic-gate 	    }
3290Sstevel@tonic-gate 	}
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate 	return (0);
3320Sstevel@tonic-gate }
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate /* return 1 if the slice descriptor is still valid, 0 if not. */
3350Sstevel@tonic-gate static int
desc_ok(descriptor_t * dp)3360Sstevel@tonic-gate desc_ok(descriptor_t *dp)
3370Sstevel@tonic-gate {
3380Sstevel@tonic-gate 	/* First verify the media name for removable media */
3390Sstevel@tonic-gate 	if (dp->p.disk->removable) {
3400Sstevel@tonic-gate 	    char	mname[MAXPATHLEN];
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	    if (!media_read_name(dp->p.disk, mname, sizeof (mname))) {
3430Sstevel@tonic-gate 		return (0);
3440Sstevel@tonic-gate 	    }
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate 	    if (mname[0] == 0) {
3470Sstevel@tonic-gate 		return (libdiskmgt_str_eq(dp->secondary_name, NULL));
3480Sstevel@tonic-gate 	    } else {
3490Sstevel@tonic-gate 		return (libdiskmgt_str_eq(dp->secondary_name, mname));
3500Sstevel@tonic-gate 	    }
3510Sstevel@tonic-gate 	}
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 	/*
3540Sstevel@tonic-gate 	 * We could verify the slice is still there, but other code down the
3550Sstevel@tonic-gate 	 * line already does these checks (e.g. see get_attrs).
3560Sstevel@tonic-gate 	 */
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	return (1);
3590Sstevel@tonic-gate }
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate /* convert dsk paths to rdsk paths */
3620Sstevel@tonic-gate static void
dsk2rdsk(char * dsk,char * rdsk,int size)3630Sstevel@tonic-gate dsk2rdsk(char *dsk, char *rdsk, int size)
3640Sstevel@tonic-gate {
3650Sstevel@tonic-gate 	char	*slashp;
3660Sstevel@tonic-gate 	size_t	len;
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate 	(void) strlcpy(rdsk, dsk, size);
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate 	/* make sure there is enough room to add the r to dsk */
3710Sstevel@tonic-gate 	len = strlen(dsk);
3720Sstevel@tonic-gate 	if (len + 2 > size) {
3730Sstevel@tonic-gate 	    return;
3740Sstevel@tonic-gate 	}
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate 	if ((slashp = strstr(rdsk, "/dsk/")) == NULL) {
3770Sstevel@tonic-gate 	    /* not dsk, check for floppy */
3780Sstevel@tonic-gate 	    slashp = strstr(rdsk, "/diskette");
3790Sstevel@tonic-gate 	}
3800Sstevel@tonic-gate 
3810Sstevel@tonic-gate 	if (slashp != NULL) {
3820Sstevel@tonic-gate 	    char	*endp;
3830Sstevel@tonic-gate 
3840Sstevel@tonic-gate 	    endp = rdsk + len;	/* point to terminating 0 */
3850Sstevel@tonic-gate 	    /* move the succeeding chars over by one */
3860Sstevel@tonic-gate 	    do {
3870Sstevel@tonic-gate 		*(endp + 1) = *endp;
3880Sstevel@tonic-gate 		endp--;
3890Sstevel@tonic-gate 	    } while (endp != slashp);
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate 	    *(endp + 1) = 'r';
3920Sstevel@tonic-gate 	}
3930Sstevel@tonic-gate }
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate static int
get_attrs(descriptor_t * dp,int fd,nvlist_t * attrs)3960Sstevel@tonic-gate get_attrs(descriptor_t *dp, int fd,  nvlist_t *attrs)
3970Sstevel@tonic-gate {
3980Sstevel@tonic-gate 	struct dk_minfo	minfo;
3990Sstevel@tonic-gate 	int		status;
4000Sstevel@tonic-gate 	int		data_format = FMT_UNKNOWN;
4010Sstevel@tonic-gate 	int		snum = -1;
4020Sstevel@tonic-gate 	int		error;
403*7563SPrasad.Singamsetty@Sun.COM 	struct extvtoc	vtoc;
4040Sstevel@tonic-gate 	struct dk_gpt	*efip;
4050Sstevel@tonic-gate 	struct dk_cinfo	dkinfo;
4060Sstevel@tonic-gate 	disk_t		*diskp;
4070Sstevel@tonic-gate 	char		localpath[MAXPATHLEN];
4080Sstevel@tonic-gate 	int		cooked_fd;
4090Sstevel@tonic-gate 	struct stat	buf;
4100Sstevel@tonic-gate 	int		mntpnt = 0;
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate 	if (fd < 0) {
4130Sstevel@tonic-gate 	    return (ENODEV);
4140Sstevel@tonic-gate 	}
4150Sstevel@tonic-gate 
4160Sstevel@tonic-gate 	/* First make sure media is inserted and spun up. */
4170Sstevel@tonic-gate 	if (!media_read_info(fd, &minfo)) {
4180Sstevel@tonic-gate 	    return (ENODEV);
4190Sstevel@tonic-gate 	}
4200Sstevel@tonic-gate 
421*7563SPrasad.Singamsetty@Sun.COM 	if ((status = read_extvtoc(fd, &vtoc)) >= 0) {
4220Sstevel@tonic-gate 	    data_format = FMT_VTOC;
4230Sstevel@tonic-gate 	} else if (status == VT_ENOTSUP && efi_alloc_and_read(fd, &efip) >= 0) {
4240Sstevel@tonic-gate 	    data_format = FMT_EFI;
4250Sstevel@tonic-gate 	    if (nvlist_add_boolean(attrs, DM_EFI) != 0) {
4260Sstevel@tonic-gate 		efi_free(efip);
4270Sstevel@tonic-gate 		return (ENOMEM);
4280Sstevel@tonic-gate 	    }
4290Sstevel@tonic-gate 	}
4300Sstevel@tonic-gate 
4310Sstevel@tonic-gate 	if (data_format == FMT_UNKNOWN) {
4320Sstevel@tonic-gate 	    return (ENODEV);
4330Sstevel@tonic-gate 	}
4340Sstevel@tonic-gate 
4350Sstevel@tonic-gate 	if (ioctl(fd, DKIOCINFO, &dkinfo) >= 0) {
4360Sstevel@tonic-gate 	    snum = dkinfo.dki_partition;
4370Sstevel@tonic-gate 	}
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate 	/* check the slice */
4400Sstevel@tonic-gate 	if (data_format == FMT_VTOC) {
4410Sstevel@tonic-gate 	    if (snum < 0 || snum >= vtoc.v_nparts ||
4420Sstevel@tonic-gate 		vtoc.v_part[snum].p_size == 0) {
4430Sstevel@tonic-gate 		return (ENODEV);
4440Sstevel@tonic-gate 	    }
4450Sstevel@tonic-gate 	} else { /* data_format == FMT_EFI */
4460Sstevel@tonic-gate 	    if (snum < 0 || snum >= efip->efi_nparts ||
4470Sstevel@tonic-gate 		efip->efi_parts[snum].p_size == 0) {
4480Sstevel@tonic-gate 		efi_free(efip);
4490Sstevel@tonic-gate 		return (ENODEV);
4500Sstevel@tonic-gate 	    }
4510Sstevel@tonic-gate 	}
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate 	/* the slice exists */
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate 	if (nvlist_add_uint32(attrs, DM_INDEX, snum) != 0) {
4560Sstevel@tonic-gate 	    if (data_format == FMT_EFI) {
4570Sstevel@tonic-gate 		efi_free(efip);
4580Sstevel@tonic-gate 	    }
4590Sstevel@tonic-gate 	    return (ENOMEM);
4600Sstevel@tonic-gate 	}
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate 	if (data_format == FMT_VTOC) {
4630Sstevel@tonic-gate 	    if (nvlist_add_uint64(attrs, DM_START, vtoc.v_part[snum].p_start)
4640Sstevel@tonic-gate 		!= 0) {
4650Sstevel@tonic-gate 		return (ENOMEM);
4660Sstevel@tonic-gate 	    }
4670Sstevel@tonic-gate 
4680Sstevel@tonic-gate 	    if (nvlist_add_uint64(attrs, DM_SIZE, vtoc.v_part[snum].p_size)
4690Sstevel@tonic-gate 		!= 0) {
4700Sstevel@tonic-gate 		return (ENOMEM);
4710Sstevel@tonic-gate 	    }
4720Sstevel@tonic-gate 
4730Sstevel@tonic-gate 	    if (nvlist_add_uint32(attrs, DM_TAG, vtoc.v_part[snum].p_tag)
4740Sstevel@tonic-gate 		!= 0) {
4750Sstevel@tonic-gate 		return (ENOMEM);
4760Sstevel@tonic-gate 	    }
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 	    if (nvlist_add_uint32(attrs, DM_FLAG, vtoc.v_part[snum].p_flag)
4790Sstevel@tonic-gate 		!= 0) {
4800Sstevel@tonic-gate 		return (ENOMEM);
4810Sstevel@tonic-gate 	    }
4820Sstevel@tonic-gate 
4830Sstevel@tonic-gate 	} else { /* data_format == FMT_EFI */
4840Sstevel@tonic-gate 	    if (nvlist_add_uint64(attrs, DM_START,
4850Sstevel@tonic-gate 		efip->efi_parts[snum].p_start) != 0) {
4860Sstevel@tonic-gate 		efi_free(efip);
4870Sstevel@tonic-gate 		return (ENOMEM);
4880Sstevel@tonic-gate 	    }
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate 	    if (nvlist_add_uint64(attrs, DM_SIZE, efip->efi_parts[snum].p_size)
4910Sstevel@tonic-gate 		!= 0) {
4920Sstevel@tonic-gate 		efi_free(efip);
4930Sstevel@tonic-gate 		return (ENOMEM);
4940Sstevel@tonic-gate 	    }
4950Sstevel@tonic-gate 
4960Sstevel@tonic-gate 	    if (efip->efi_parts[snum].p_name[0] != 0) {
4970Sstevel@tonic-gate 		char	label[EFI_PART_NAME_LEN + 1];
4980Sstevel@tonic-gate 
4990Sstevel@tonic-gate 		(void) snprintf(label, sizeof (label), "%.*s",
5000Sstevel@tonic-gate 		    EFI_PART_NAME_LEN, efip->efi_parts[snum].p_name);
5010Sstevel@tonic-gate 		if (nvlist_add_string(attrs, DM_EFI_NAME, label) != 0) {
5020Sstevel@tonic-gate 		    efi_free(efip);
5030Sstevel@tonic-gate 		    return (ENOMEM);
5040Sstevel@tonic-gate 		}
5050Sstevel@tonic-gate 	    }
5060Sstevel@tonic-gate 	}
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate 	if (data_format == FMT_EFI) {
5090Sstevel@tonic-gate 	    efi_free(efip);
5100Sstevel@tonic-gate 	}
5110Sstevel@tonic-gate 
5120Sstevel@tonic-gate 	if (inuse_mnt(dp->name, attrs, &error)) {
5130Sstevel@tonic-gate 	    if (error != 0) {
5140Sstevel@tonic-gate 		return (error);
5150Sstevel@tonic-gate 	    }
5160Sstevel@tonic-gate 	    mntpnt = 1;
5170Sstevel@tonic-gate 	}
5180Sstevel@tonic-gate 
5190Sstevel@tonic-gate 	/*
5200Sstevel@tonic-gate 	 * Some extra attrs for cluster slices.
5210Sstevel@tonic-gate 	 *
5220Sstevel@tonic-gate 	 * get localname and possible mnt point for localpath
5230Sstevel@tonic-gate 	 */
5240Sstevel@tonic-gate 	localpath[0] = 0;
5250Sstevel@tonic-gate 	diskp = dp->p.disk;
5260Sstevel@tonic-gate 	if (diskp->aliases != NULL && diskp->aliases->cluster) {
5270Sstevel@tonic-gate 	    slice_t *sp;
5280Sstevel@tonic-gate 
5290Sstevel@tonic-gate 	    for (sp = diskp->aliases->orig_paths; sp != NULL; sp = sp->next) {
5300Sstevel@tonic-gate 		if (sp->slice_num == -1) {
5310Sstevel@tonic-gate 		    /* determine the slice number for this path */
5320Sstevel@tonic-gate 		    int			sfd;
5330Sstevel@tonic-gate 		    struct dk_cinfo	dkinfo;
5340Sstevel@tonic-gate 
5350Sstevel@tonic-gate 		    if ((sfd = open(sp->devpath, O_RDONLY|O_NDELAY)) >= 0) {
5360Sstevel@tonic-gate 			if (ioctl(sfd, DKIOCINFO, &dkinfo) >= 0) {
5370Sstevel@tonic-gate 			    sp->slice_num = dkinfo.dki_partition;
5380Sstevel@tonic-gate 			}
5390Sstevel@tonic-gate 			(void) close(sfd);
5400Sstevel@tonic-gate 		    }
5410Sstevel@tonic-gate 		}
5420Sstevel@tonic-gate 
5430Sstevel@tonic-gate 		if (sp->slice_num == snum) {
5440Sstevel@tonic-gate 		    slice_rdsk2dsk(sp->devpath, localpath, sizeof (localpath));
5450Sstevel@tonic-gate 
5460Sstevel@tonic-gate 		    if (nvlist_add_string(attrs, DM_LOCALNAME, localpath)
5470Sstevel@tonic-gate 			!= 0) {
5480Sstevel@tonic-gate 			return (ENOMEM);
5490Sstevel@tonic-gate 		    }
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate 		    if (mntpnt == 0) {
5520Sstevel@tonic-gate 			if (inuse_mnt(localpath, attrs, &error)) {
5530Sstevel@tonic-gate 			    if (error != 0) {
5540Sstevel@tonic-gate 				return (error);
5550Sstevel@tonic-gate 			    }
5560Sstevel@tonic-gate 			}
5570Sstevel@tonic-gate 		    }
5580Sstevel@tonic-gate 
5590Sstevel@tonic-gate 		    break;
5600Sstevel@tonic-gate 		}
5610Sstevel@tonic-gate 	    }
5620Sstevel@tonic-gate 	}
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate 	if (fstat(fd, &buf) != -1) {
5650Sstevel@tonic-gate 	    if (nvlist_add_uint64(attrs, DM_DEVT, buf.st_rdev) != 0) {
5660Sstevel@tonic-gate 		return (ENOMEM);
5670Sstevel@tonic-gate 	    }
5680Sstevel@tonic-gate 	}
5690Sstevel@tonic-gate 
5700Sstevel@tonic-gate 	/*
5710Sstevel@tonic-gate 	 * We need to open the cooked slice (not the raw one) to get the
5720Sstevel@tonic-gate 	 * correct devid.  Also see if we need to read the localpath for the
5730Sstevel@tonic-gate 	 * cluster disk, since the minor name is unavailable for the did pseudo
5740Sstevel@tonic-gate 	 * device.
5750Sstevel@tonic-gate 	 */
5760Sstevel@tonic-gate 	if (localpath[0] != 0) {
5770Sstevel@tonic-gate 	    cooked_fd = open(localpath, O_RDONLY|O_NDELAY);
5780Sstevel@tonic-gate 	} else {
5790Sstevel@tonic-gate 	    cooked_fd = open(dp->name, O_RDONLY|O_NDELAY);
5800Sstevel@tonic-gate 	}
5810Sstevel@tonic-gate 
5820Sstevel@tonic-gate 	if (cooked_fd >= 0) {
5830Sstevel@tonic-gate 	    int		no_mem = 0;
5840Sstevel@tonic-gate 	    ddi_devid_t	devid;
5850Sstevel@tonic-gate 
5860Sstevel@tonic-gate 	    if (devid_get(cooked_fd, &devid) == 0) {
5870Sstevel@tonic-gate 		char	*minor;
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate 		if (devid_get_minor_name(cooked_fd, &minor) == 0) {
5900Sstevel@tonic-gate 		    char	*devidstr;
5910Sstevel@tonic-gate 
5920Sstevel@tonic-gate 		    if ((devidstr = devid_str_encode(devid, minor)) != 0) {
5930Sstevel@tonic-gate 
5940Sstevel@tonic-gate 			if (nvlist_add_string(attrs, DM_DEVICEID, devidstr)
5950Sstevel@tonic-gate 			    != 0) {
5960Sstevel@tonic-gate 			    no_mem = 1;
5970Sstevel@tonic-gate 			}
5980Sstevel@tonic-gate 
5990Sstevel@tonic-gate 			devid_str_free(devidstr);
6000Sstevel@tonic-gate 		    }
6010Sstevel@tonic-gate 		    devid_str_free(minor);
6020Sstevel@tonic-gate 		}
6030Sstevel@tonic-gate 		devid_free(devid);
6040Sstevel@tonic-gate 	    }
6050Sstevel@tonic-gate 	    (void) close(cooked_fd);
6060Sstevel@tonic-gate 
6070Sstevel@tonic-gate 	    if (no_mem) {
6080Sstevel@tonic-gate 		return (ENOMEM);
6090Sstevel@tonic-gate 	    }
6100Sstevel@tonic-gate 	}
6110Sstevel@tonic-gate 
6120Sstevel@tonic-gate 	return (0);
6130Sstevel@tonic-gate }
6140Sstevel@tonic-gate 
6150Sstevel@tonic-gate static descriptor_t **
get_fixed_assocs(descriptor_t * desc,int * errp)6160Sstevel@tonic-gate get_fixed_assocs(descriptor_t *desc, int *errp)
6170Sstevel@tonic-gate {
6180Sstevel@tonic-gate 	int		fd;
6190Sstevel@tonic-gate 	int		status;
6200Sstevel@tonic-gate 	int		data_format = FMT_UNKNOWN;
6210Sstevel@tonic-gate 	int		cnt;
622*7563SPrasad.Singamsetty@Sun.COM 	struct extvtoc	vtoc;
6230Sstevel@tonic-gate 	struct dk_gpt	*efip;
6240Sstevel@tonic-gate 	int		pos;
6250Sstevel@tonic-gate 	char		*media_name = NULL;
6260Sstevel@tonic-gate 	slice_t		*devp;
6270Sstevel@tonic-gate 	descriptor_t	**slices;
6280Sstevel@tonic-gate 
6290Sstevel@tonic-gate 	if ((fd = drive_open_disk(desc->p.disk, NULL, 0)) < 0) {
6300Sstevel@tonic-gate 	    *errp = ENODEV;
6310Sstevel@tonic-gate 	    return (NULL);
6320Sstevel@tonic-gate 	}
6330Sstevel@tonic-gate 
634*7563SPrasad.Singamsetty@Sun.COM 	if ((status = read_extvtoc(fd, &vtoc)) >= 0) {
6350Sstevel@tonic-gate 	    data_format = FMT_VTOC;
6360Sstevel@tonic-gate 	} else if (status == VT_ENOTSUP && efi_alloc_and_read(fd, &efip) >= 0) {
6370Sstevel@tonic-gate 	    data_format = FMT_EFI;
6380Sstevel@tonic-gate 	} else {
6390Sstevel@tonic-gate 	    (void) close(fd);
6400Sstevel@tonic-gate 	    *errp = 0;
6410Sstevel@tonic-gate 	    return (libdiskmgt_empty_desc_array(errp));
6420Sstevel@tonic-gate 	}
6430Sstevel@tonic-gate 	(void) close(fd);
6440Sstevel@tonic-gate 
6450Sstevel@tonic-gate 	/* count the number of slices */
6460Sstevel@tonic-gate 	for (cnt = 0, devp = desc->p.disk->aliases->devpaths; devp != NULL;
6470Sstevel@tonic-gate 	    devp = devp->next, cnt++);
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate 	/* allocate the array for the descriptors */
6500Sstevel@tonic-gate 	slices = (descriptor_t **)calloc(cnt + 1, sizeof (descriptor_t *));
6510Sstevel@tonic-gate 	if (slices == NULL) {
6520Sstevel@tonic-gate 	    if (data_format == FMT_EFI) {
6530Sstevel@tonic-gate 		efi_free(efip);
6540Sstevel@tonic-gate 	    }
6550Sstevel@tonic-gate 	    *errp = ENOMEM;
6560Sstevel@tonic-gate 	    return (NULL);
6570Sstevel@tonic-gate 	}
6580Sstevel@tonic-gate 
6590Sstevel@tonic-gate 	/* get the media name from the descriptor */
6600Sstevel@tonic-gate 	if (desc->type == DM_MEDIA) {
6610Sstevel@tonic-gate 	    media_name = desc->name;
6620Sstevel@tonic-gate 	} else {
6630Sstevel@tonic-gate 	    /* must be a DM_PARTITION */
6640Sstevel@tonic-gate 	    media_name = desc->secondary_name;
6650Sstevel@tonic-gate 	}
6660Sstevel@tonic-gate 
6670Sstevel@tonic-gate 	pos = 0;
6680Sstevel@tonic-gate 	for (devp = desc->p.disk->aliases->devpaths; devp != NULL;
6690Sstevel@tonic-gate 	    devp = devp->next) {
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 	    int		slice_num;
6720Sstevel@tonic-gate 	    char	devpath[MAXPATHLEN];
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate 	    slice_num = get_slice_num(devp);
6750Sstevel@tonic-gate 	    /* can't get slicenum, so no need to keep trying the drive */
6760Sstevel@tonic-gate 	    if (slice_num == -1) {
6770Sstevel@tonic-gate 		break;
6780Sstevel@tonic-gate 	    }
6790Sstevel@tonic-gate 
6800Sstevel@tonic-gate 	    if (data_format == FMT_VTOC) {
6810Sstevel@tonic-gate 		if (slice_num >= vtoc.v_nparts ||
6820Sstevel@tonic-gate 		    vtoc.v_part[slice_num].p_size == 0) {
6830Sstevel@tonic-gate 		    continue;
6840Sstevel@tonic-gate 		}
6850Sstevel@tonic-gate 	    } else { /* data_format == FMT_EFI */
6860Sstevel@tonic-gate 		if (slice_num >= efip->efi_nparts ||
6870Sstevel@tonic-gate 		    efip->efi_parts[slice_num].p_size == 0) {
6880Sstevel@tonic-gate 		    continue;
6890Sstevel@tonic-gate 		}
6900Sstevel@tonic-gate 	    }
6910Sstevel@tonic-gate 
6920Sstevel@tonic-gate 	    slice_rdsk2dsk(devp->devpath, devpath, sizeof (devpath));
6930Sstevel@tonic-gate 	    slices[pos] = cache_get_desc(DM_SLICE, desc->p.disk, devpath,
6940Sstevel@tonic-gate 		media_name, errp);
6950Sstevel@tonic-gate 	    if (*errp != 0) {
6960Sstevel@tonic-gate 		cache_free_descriptors(slices);
6970Sstevel@tonic-gate 		if (data_format == FMT_EFI) {
6980Sstevel@tonic-gate 		    efi_free(efip);
6990Sstevel@tonic-gate 		}
7000Sstevel@tonic-gate 		return (NULL);
7010Sstevel@tonic-gate 	    }
7020Sstevel@tonic-gate 	    pos++;
7030Sstevel@tonic-gate 	}
7040Sstevel@tonic-gate 	slices[pos] = NULL;
7050Sstevel@tonic-gate 
7060Sstevel@tonic-gate 	if (data_format == FMT_EFI) {
7070Sstevel@tonic-gate 	    efi_free(efip);
7080Sstevel@tonic-gate 	}
7090Sstevel@tonic-gate 
7100Sstevel@tonic-gate 	*errp = 0;
7110Sstevel@tonic-gate 	return (slices);
7120Sstevel@tonic-gate }
7130Sstevel@tonic-gate 
7140Sstevel@tonic-gate static int
get_slice_num(slice_t * devp)7150Sstevel@tonic-gate get_slice_num(slice_t *devp)
7160Sstevel@tonic-gate {
7170Sstevel@tonic-gate 	/* check if we already determined the devpath slice number */
7180Sstevel@tonic-gate 	if (devp->slice_num == -1) {
7190Sstevel@tonic-gate 	    int		fd;
7200Sstevel@tonic-gate 
7210Sstevel@tonic-gate 	    if ((fd = open(devp->devpath, O_RDONLY|O_NDELAY)) >= 0) {
7220Sstevel@tonic-gate 		struct dk_cinfo	dkinfo;
7230Sstevel@tonic-gate 		if (ioctl(fd, DKIOCINFO, &dkinfo) >= 0) {
7240Sstevel@tonic-gate 		    devp->slice_num = dkinfo.dki_partition;
7250Sstevel@tonic-gate 		}
7260Sstevel@tonic-gate 		(void) close(fd);
7270Sstevel@tonic-gate 	    }
7280Sstevel@tonic-gate 	}
7290Sstevel@tonic-gate 
7300Sstevel@tonic-gate 	return (devp->slice_num);
7310Sstevel@tonic-gate }
7320Sstevel@tonic-gate 
7330Sstevel@tonic-gate static int
make_fixed_descriptors(disk_t * dp)7340Sstevel@tonic-gate make_fixed_descriptors(disk_t *dp)
7350Sstevel@tonic-gate {
7360Sstevel@tonic-gate 	int		error = 0;
7370Sstevel@tonic-gate 	alias_t		*ap;
7380Sstevel@tonic-gate 	slice_t		*devp;
7390Sstevel@tonic-gate 	char		mname[MAXPATHLEN];
7400Sstevel@tonic-gate 	int		data_format = FMT_UNKNOWN;
741*7563SPrasad.Singamsetty@Sun.COM 	struct extvtoc	vtoc;
7420Sstevel@tonic-gate 	struct dk_gpt	*efip;
7430Sstevel@tonic-gate 
7440Sstevel@tonic-gate 	/* Just check the first drive name. */
7450Sstevel@tonic-gate 	if ((ap = dp->aliases) == NULL) {
7460Sstevel@tonic-gate 	    return (0);
7470Sstevel@tonic-gate 	}
7480Sstevel@tonic-gate 
7490Sstevel@tonic-gate 	mname[0] = 0;
7500Sstevel@tonic-gate 	(void) media_read_name(dp, mname, sizeof (mname));
7510Sstevel@tonic-gate 
7520Sstevel@tonic-gate 	for (devp = ap->devpaths; devp != NULL; devp = devp->next) {
7530Sstevel@tonic-gate 	    int		slice_num;
7540Sstevel@tonic-gate 	    char	devpath[MAXPATHLEN];
7550Sstevel@tonic-gate 
7560Sstevel@tonic-gate 	    slice_num = get_slice_num(devp);
7570Sstevel@tonic-gate 	    /* can't get slicenum, so no need to keep trying the drive */
7580Sstevel@tonic-gate 	    if (slice_num == -1) {
7590Sstevel@tonic-gate 		break;
7600Sstevel@tonic-gate 	    }
7610Sstevel@tonic-gate 
7620Sstevel@tonic-gate 	    if (data_format == FMT_UNKNOWN) {
7630Sstevel@tonic-gate 		int	fd;
7640Sstevel@tonic-gate 		int	status;
7650Sstevel@tonic-gate 
7660Sstevel@tonic-gate 		if ((fd = drive_open_disk(dp, NULL, 0)) >= 0) {
767*7563SPrasad.Singamsetty@Sun.COM 		    if ((status = read_extvtoc(fd, &vtoc)) >= 0) {
7680Sstevel@tonic-gate 			data_format = FMT_VTOC;
7690Sstevel@tonic-gate 		    } else if (status == VT_ENOTSUP &&
7700Sstevel@tonic-gate 			efi_alloc_and_read(fd, &efip) >= 0) {
7710Sstevel@tonic-gate 			data_format = FMT_EFI;
7720Sstevel@tonic-gate 		    }
7730Sstevel@tonic-gate 		    (void) close(fd);
7740Sstevel@tonic-gate 		}
7750Sstevel@tonic-gate 	    }
7760Sstevel@tonic-gate 
7770Sstevel@tonic-gate 	    /* can't get slice data, so no need to keep trying the drive */
7780Sstevel@tonic-gate 	    if (data_format == FMT_UNKNOWN) {
7790Sstevel@tonic-gate 		break;
7800Sstevel@tonic-gate 	    }
7810Sstevel@tonic-gate 
7820Sstevel@tonic-gate 	    if (data_format == FMT_VTOC) {
7830Sstevel@tonic-gate 		if (slice_num >= vtoc.v_nparts ||
7840Sstevel@tonic-gate 		    vtoc.v_part[slice_num].p_size == 0) {
7850Sstevel@tonic-gate 		    continue;
7860Sstevel@tonic-gate 		}
7870Sstevel@tonic-gate 	    } else { /* data_format == FMT_EFI */
7880Sstevel@tonic-gate 		if (slice_num >= efip->efi_nparts ||
7890Sstevel@tonic-gate 		    efip->efi_parts[slice_num].p_size == 0) {
7900Sstevel@tonic-gate 		    continue;
7910Sstevel@tonic-gate 		}
7920Sstevel@tonic-gate 	    }
7930Sstevel@tonic-gate 
7940Sstevel@tonic-gate 	    slice_rdsk2dsk(devp->devpath, devpath, sizeof (devpath));
7950Sstevel@tonic-gate 	    cache_load_desc(DM_SLICE, dp, devpath, mname, &error);
7960Sstevel@tonic-gate 	    if (error != 0) {
7970Sstevel@tonic-gate 		break;
7980Sstevel@tonic-gate 	    }
7990Sstevel@tonic-gate 	}
8000Sstevel@tonic-gate 
8010Sstevel@tonic-gate 	if (data_format == FMT_EFI) {
8020Sstevel@tonic-gate 	    efi_free(efip);
8030Sstevel@tonic-gate 	}
8040Sstevel@tonic-gate 
8050Sstevel@tonic-gate 	return (error);
8060Sstevel@tonic-gate }
8070Sstevel@tonic-gate 
8080Sstevel@tonic-gate /*
8090Sstevel@tonic-gate  * Just look for the name on the devpaths we have cached. Return 1 if we
8100Sstevel@tonic-gate  * find the name and the size of that slice is non-zero.
8110Sstevel@tonic-gate  */
8120Sstevel@tonic-gate static int
match_fixed_name(disk_t * diskp,char * name,int * errp)8130Sstevel@tonic-gate match_fixed_name(disk_t *diskp, char *name, int *errp)
8140Sstevel@tonic-gate {
8150Sstevel@tonic-gate 	slice_t		*dp = NULL;
8160Sstevel@tonic-gate 	alias_t		*ap;
8170Sstevel@tonic-gate 	int		slice_num;
8180Sstevel@tonic-gate 	int		fd;
8190Sstevel@tonic-gate 	int		status;
8200Sstevel@tonic-gate 	int		data_format = FMT_UNKNOWN;
821*7563SPrasad.Singamsetty@Sun.COM 	struct extvtoc	vtoc;
8220Sstevel@tonic-gate 	struct dk_gpt	*efip;
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate 	ap = diskp->aliases;
8250Sstevel@tonic-gate 	while (ap != NULL) {
8260Sstevel@tonic-gate 	    slice_t	*devp;
8270Sstevel@tonic-gate 
8280Sstevel@tonic-gate 	    devp = ap->devpaths;
8290Sstevel@tonic-gate 	    while (devp != NULL) {
8300Sstevel@tonic-gate 		char	path[MAXPATHLEN];
8310Sstevel@tonic-gate 
8320Sstevel@tonic-gate 		slice_rdsk2dsk(devp->devpath, path, sizeof (path));
8330Sstevel@tonic-gate 		if (libdiskmgt_str_eq(path, name)) {
8340Sstevel@tonic-gate 		    /* found it */
8350Sstevel@tonic-gate 		    dp = devp;
8360Sstevel@tonic-gate 		    break;
8370Sstevel@tonic-gate 		}
8380Sstevel@tonic-gate 
8390Sstevel@tonic-gate 		devp = devp->next;
8400Sstevel@tonic-gate 	    }
8410Sstevel@tonic-gate 
8420Sstevel@tonic-gate 	    if (dp != NULL) {
8430Sstevel@tonic-gate 		break;
8440Sstevel@tonic-gate 	    }
8450Sstevel@tonic-gate 
8460Sstevel@tonic-gate 	    ap = ap->next;
8470Sstevel@tonic-gate 	}
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate 	if (dp == NULL) {
8500Sstevel@tonic-gate 	    *errp = 0;
8510Sstevel@tonic-gate 	    return (0);
8520Sstevel@tonic-gate 	}
8530Sstevel@tonic-gate 
8540Sstevel@tonic-gate 	/*
8550Sstevel@tonic-gate 	 * If we found a match on the name we now have to check that this
8560Sstevel@tonic-gate 	 * slice really exists (non-0 size).
8570Sstevel@tonic-gate 	 */
8580Sstevel@tonic-gate 
8590Sstevel@tonic-gate 	slice_num = get_slice_num(dp);
8600Sstevel@tonic-gate 	/* can't get slicenum, so no slice */
8610Sstevel@tonic-gate 	if (slice_num == -1) {
8620Sstevel@tonic-gate 	    *errp = ENODEV;
8630Sstevel@tonic-gate 	    return (1);
8640Sstevel@tonic-gate 	}
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate 	if ((fd = drive_open_disk(diskp, NULL, 0)) < 0) {
8670Sstevel@tonic-gate 	    *errp = ENODEV;
8680Sstevel@tonic-gate 	    return (1);
8690Sstevel@tonic-gate 	}
8700Sstevel@tonic-gate 
871*7563SPrasad.Singamsetty@Sun.COM 	if ((status = read_extvtoc(fd, &vtoc)) >= 0) {
8720Sstevel@tonic-gate 	    data_format = FMT_VTOC;
8730Sstevel@tonic-gate 	} else if (status == VT_ENOTSUP && efi_alloc_and_read(fd, &efip) >= 0) {
8740Sstevel@tonic-gate 	    data_format = FMT_EFI;
8750Sstevel@tonic-gate 	} else {
8760Sstevel@tonic-gate 	    (void) close(fd);
8770Sstevel@tonic-gate 	    *errp = ENODEV;
8780Sstevel@tonic-gate 	    return (1);
8790Sstevel@tonic-gate 	}
8800Sstevel@tonic-gate 	(void) close(fd);
8810Sstevel@tonic-gate 
8820Sstevel@tonic-gate 	if (data_format == FMT_VTOC) {
8830Sstevel@tonic-gate 	    if (slice_num < vtoc.v_nparts &&
8840Sstevel@tonic-gate 		vtoc.v_part[slice_num].p_size > 0) {
8850Sstevel@tonic-gate 		*errp = 0;
8860Sstevel@tonic-gate 		return (1);
8870Sstevel@tonic-gate 	    }
8880Sstevel@tonic-gate 	} else { /* data_format == FMT_EFI */
8890Sstevel@tonic-gate 	    if (slice_num < efip->efi_nparts &&
8900Sstevel@tonic-gate 		efip->efi_parts[slice_num].p_size > 0) {
8910Sstevel@tonic-gate 		efi_free(efip);
8920Sstevel@tonic-gate 		*errp = 0;
8930Sstevel@tonic-gate 		return (1);
8940Sstevel@tonic-gate 	    }
8950Sstevel@tonic-gate 	    efi_free(efip);
8960Sstevel@tonic-gate 	}
8970Sstevel@tonic-gate 
8980Sstevel@tonic-gate 	*errp = ENODEV;
8990Sstevel@tonic-gate 	return (1);
9000Sstevel@tonic-gate }
901