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 ** 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 ** 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 * 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 * 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 ** 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 * 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 * 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 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 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 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 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 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 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 ** 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 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 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 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