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