1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 30*7c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 31*7c478bd9Sstevel@tonic-gate #include <stdio.h> 32*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 33*7c478bd9Sstevel@tonic-gate #include <string.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 37*7c478bd9Sstevel@tonic-gate #include <dirent.h> 38*7c478bd9Sstevel@tonic-gate #include <unistd.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include "libdiskmgt.h" 42*7c478bd9Sstevel@tonic-gate #include "disks_private.h" 43*7c478bd9Sstevel@tonic-gate #include "partition.h" 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate #ifdef sparc 46*7c478bd9Sstevel@tonic-gate #define les(val) ((((val)&0xFF)<<8)|(((val)>>8)&0xFF)) 47*7c478bd9Sstevel@tonic-gate #define lel(val) (((unsigned)(les((val)&0x0000FFFF))<<16) | \ 48*7c478bd9Sstevel@tonic-gate (les((unsigned)((val)&0xffff0000)>>16))) 49*7c478bd9Sstevel@tonic-gate #else 50*7c478bd9Sstevel@tonic-gate #define les(val) (val) 51*7c478bd9Sstevel@tonic-gate #define lel(val) (val) 52*7c478bd9Sstevel@tonic-gate #endif 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate #define ISIZE FD_NUMPART * sizeof (struct ipart) 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate static int desc_ok(descriptor_t *dp); 57*7c478bd9Sstevel@tonic-gate static int get_attrs(descriptor_t *dp, struct ipart *iparts, 58*7c478bd9Sstevel@tonic-gate nvlist_t *attrs); 59*7c478bd9Sstevel@tonic-gate static int get_parts(disk_t *disk, struct ipart *iparts, char *opath, 60*7c478bd9Sstevel@tonic-gate int opath_len); 61*7c478bd9Sstevel@tonic-gate static int open_disk(disk_t *diskp, char *opath, int len); 62*7c478bd9Sstevel@tonic-gate static int has_slices(descriptor_t *desc, int *errp); 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate descriptor_t ** 65*7c478bd9Sstevel@tonic-gate partition_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type, 66*7c478bd9Sstevel@tonic-gate int *errp) 67*7c478bd9Sstevel@tonic-gate { 68*7c478bd9Sstevel@tonic-gate if (!desc_ok(desc)) { 69*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 70*7c478bd9Sstevel@tonic-gate return (NULL); 71*7c478bd9Sstevel@tonic-gate } 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate switch (type) { 74*7c478bd9Sstevel@tonic-gate case DM_MEDIA: 75*7c478bd9Sstevel@tonic-gate return (media_get_assocs(desc, errp)); 76*7c478bd9Sstevel@tonic-gate case DM_SLICE: 77*7c478bd9Sstevel@tonic-gate if (!has_slices(desc, errp)) { 78*7c478bd9Sstevel@tonic-gate if (*errp != 0) { 79*7c478bd9Sstevel@tonic-gate return (NULL); 80*7c478bd9Sstevel@tonic-gate } 81*7c478bd9Sstevel@tonic-gate return (libdiskmgt_empty_desc_array(errp)); 82*7c478bd9Sstevel@tonic-gate } 83*7c478bd9Sstevel@tonic-gate return (slice_get_assocs(desc, errp)); 84*7c478bd9Sstevel@tonic-gate } 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 87*7c478bd9Sstevel@tonic-gate return (NULL); 88*7c478bd9Sstevel@tonic-gate } 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate /* 91*7c478bd9Sstevel@tonic-gate * This is called by media/slice to get the associated partitions. 92*7c478bd9Sstevel@tonic-gate * For a media desc. we just get all the partitions, but for a slice desc. 93*7c478bd9Sstevel@tonic-gate * we just get the active solaris partition. 94*7c478bd9Sstevel@tonic-gate */ 95*7c478bd9Sstevel@tonic-gate descriptor_t ** 96*7c478bd9Sstevel@tonic-gate partition_get_assocs(descriptor_t *desc, int *errp) 97*7c478bd9Sstevel@tonic-gate { 98*7c478bd9Sstevel@tonic-gate descriptor_t **partitions; 99*7c478bd9Sstevel@tonic-gate int pos; 100*7c478bd9Sstevel@tonic-gate int i; 101*7c478bd9Sstevel@tonic-gate struct ipart iparts[FD_NUMPART]; 102*7c478bd9Sstevel@tonic-gate char pname[MAXPATHLEN]; 103*7c478bd9Sstevel@tonic-gate int conv_flag = 0; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate if (get_parts(desc->p.disk, iparts, pname, sizeof (pname)) != 0) { 106*7c478bd9Sstevel@tonic-gate return (libdiskmgt_empty_desc_array(errp)); 107*7c478bd9Sstevel@tonic-gate } 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate /* allocate the array for the descriptors */ 110*7c478bd9Sstevel@tonic-gate partitions = (descriptor_t **)calloc(FD_NUMPART + 1, 111*7c478bd9Sstevel@tonic-gate sizeof (descriptor_t *)); 112*7c478bd9Sstevel@tonic-gate if (partitions == NULL) { 113*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 114*7c478bd9Sstevel@tonic-gate return (NULL); 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate #ifdef i386 118*7c478bd9Sstevel@tonic-gate { 119*7c478bd9Sstevel@tonic-gate /* convert part. name (e.g. c0d0p0) */ 120*7c478bd9Sstevel@tonic-gate int len; 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate len = strlen(pname); 123*7c478bd9Sstevel@tonic-gate if (len > 1 && *(pname + (len - 2)) == 'p') { 124*7c478bd9Sstevel@tonic-gate conv_flag = 1; 125*7c478bd9Sstevel@tonic-gate *(pname + (len - 1)) = 0; 126*7c478bd9Sstevel@tonic-gate } 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate #endif 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* 131*7c478bd9Sstevel@tonic-gate * If this is a slice desc. we need the first active solaris partition 132*7c478bd9Sstevel@tonic-gate * and if there isn't one then we need the first solaris partition. 133*7c478bd9Sstevel@tonic-gate */ 134*7c478bd9Sstevel@tonic-gate if (desc->type == DM_SLICE) { 135*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 136*7c478bd9Sstevel@tonic-gate if (iparts[i].bootid == ACTIVE && 137*7c478bd9Sstevel@tonic-gate (iparts[i].systid == SUNIXOS || 138*7c478bd9Sstevel@tonic-gate iparts[i].systid == SUNIXOS2)) { 139*7c478bd9Sstevel@tonic-gate break; 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate /* no active solaris part., try to get the first solaris part. */ 144*7c478bd9Sstevel@tonic-gate if (i >= FD_NUMPART) { 145*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 146*7c478bd9Sstevel@tonic-gate if (iparts[i].systid == SUNIXOS || 147*7c478bd9Sstevel@tonic-gate iparts[i].systid == SUNIXOS2) { 148*7c478bd9Sstevel@tonic-gate break; 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate if (i < FD_NUMPART) { 154*7c478bd9Sstevel@tonic-gate /* we found a solaris partition to use */ 155*7c478bd9Sstevel@tonic-gate char part_name[MAXPATHLEN]; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate if (conv_flag) { 158*7c478bd9Sstevel@tonic-gate /* convert part. name (e.g. c0d0p0) */ 159*7c478bd9Sstevel@tonic-gate (void) snprintf(part_name, sizeof (part_name), "%s%d", 160*7c478bd9Sstevel@tonic-gate pname, i); 161*7c478bd9Sstevel@tonic-gate } else { 162*7c478bd9Sstevel@tonic-gate (void) snprintf(part_name, sizeof (part_name), "%d", i); 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate /* the media name comes from the slice desc. */ 166*7c478bd9Sstevel@tonic-gate partitions[0] = cache_get_desc(DM_PARTITION, desc->p.disk, 167*7c478bd9Sstevel@tonic-gate part_name, desc->secondary_name, errp); 168*7c478bd9Sstevel@tonic-gate if (*errp != 0) { 169*7c478bd9Sstevel@tonic-gate cache_free_descriptors(partitions); 170*7c478bd9Sstevel@tonic-gate return (NULL); 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate partitions[1] = NULL; 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate return (partitions); 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate return (libdiskmgt_empty_desc_array(errp)); 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate /* Must be for media, so get all the parts. */ 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate pos = 0; 184*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 185*7c478bd9Sstevel@tonic-gate if (iparts[i].systid != 0) { 186*7c478bd9Sstevel@tonic-gate char part_name[MAXPATHLEN]; 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate if (conv_flag) { 189*7c478bd9Sstevel@tonic-gate /* convert part. name (e.g. c0d0p0) */ 190*7c478bd9Sstevel@tonic-gate (void) snprintf(part_name, sizeof (part_name), "%s%d", 191*7c478bd9Sstevel@tonic-gate pname, i); 192*7c478bd9Sstevel@tonic-gate } else { 193*7c478bd9Sstevel@tonic-gate (void) snprintf(part_name, sizeof (part_name), "%d", i); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate /* the media name comes from the media desc. */ 197*7c478bd9Sstevel@tonic-gate partitions[pos] = cache_get_desc(DM_PARTITION, desc->p.disk, 198*7c478bd9Sstevel@tonic-gate part_name, desc->name, errp); 199*7c478bd9Sstevel@tonic-gate if (*errp != 0) { 200*7c478bd9Sstevel@tonic-gate cache_free_descriptors(partitions); 201*7c478bd9Sstevel@tonic-gate return (NULL); 202*7c478bd9Sstevel@tonic-gate } 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate pos++; 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate partitions[pos] = NULL; 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate *errp = 0; 210*7c478bd9Sstevel@tonic-gate return (partitions); 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate nvlist_t * 214*7c478bd9Sstevel@tonic-gate partition_get_attributes(descriptor_t *dp, int *errp) 215*7c478bd9Sstevel@tonic-gate { 216*7c478bd9Sstevel@tonic-gate nvlist_t *attrs = NULL; 217*7c478bd9Sstevel@tonic-gate struct ipart iparts[FD_NUMPART]; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate if (!desc_ok(dp)) { 220*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 221*7c478bd9Sstevel@tonic-gate return (NULL); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate if ((*errp = get_parts(dp->p.disk, iparts, NULL, 0)) != 0) { 225*7c478bd9Sstevel@tonic-gate return (NULL); 226*7c478bd9Sstevel@tonic-gate } 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) { 229*7c478bd9Sstevel@tonic-gate *errp = ENOMEM; 230*7c478bd9Sstevel@tonic-gate return (NULL); 231*7c478bd9Sstevel@tonic-gate } 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate if ((*errp = get_attrs(dp, iparts, attrs)) != 0) { 234*7c478bd9Sstevel@tonic-gate nvlist_free(attrs); 235*7c478bd9Sstevel@tonic-gate attrs = NULL; 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate return (attrs); 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate /* 242*7c478bd9Sstevel@tonic-gate * Look for the partition by the partition number (which is not too useful). 243*7c478bd9Sstevel@tonic-gate */ 244*7c478bd9Sstevel@tonic-gate descriptor_t * 245*7c478bd9Sstevel@tonic-gate partition_get_descriptor_by_name(char *name, int *errp) 246*7c478bd9Sstevel@tonic-gate { 247*7c478bd9Sstevel@tonic-gate descriptor_t **partitions; 248*7c478bd9Sstevel@tonic-gate int i; 249*7c478bd9Sstevel@tonic-gate descriptor_t *partition = NULL; 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate partitions = cache_get_descriptors(DM_PARTITION, errp); 252*7c478bd9Sstevel@tonic-gate if (*errp != 0) { 253*7c478bd9Sstevel@tonic-gate return (NULL); 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate for (i = 0; partitions[i]; i++) { 257*7c478bd9Sstevel@tonic-gate if (libdiskmgt_str_eq(name, partitions[i]->name)) { 258*7c478bd9Sstevel@tonic-gate partition = partitions[i]; 259*7c478bd9Sstevel@tonic-gate } else { 260*7c478bd9Sstevel@tonic-gate /* clean up the unused descriptors */ 261*7c478bd9Sstevel@tonic-gate cache_free_descriptor(partitions[i]); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate free(partitions); 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate if (partition == NULL) { 267*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate return (partition); 271*7c478bd9Sstevel@tonic-gate } 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 274*7c478bd9Sstevel@tonic-gate descriptor_t ** 275*7c478bd9Sstevel@tonic-gate partition_get_descriptors(int filter[], int *errp) 276*7c478bd9Sstevel@tonic-gate { 277*7c478bd9Sstevel@tonic-gate return (cache_get_descriptors(DM_PARTITION, errp)); 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate char * 281*7c478bd9Sstevel@tonic-gate partition_get_name(descriptor_t *desc) 282*7c478bd9Sstevel@tonic-gate { 283*7c478bd9Sstevel@tonic-gate return (desc->name); 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 287*7c478bd9Sstevel@tonic-gate nvlist_t * 288*7c478bd9Sstevel@tonic-gate partition_get_stats(descriptor_t *dp, int stat_type, int *errp) 289*7c478bd9Sstevel@tonic-gate { 290*7c478bd9Sstevel@tonic-gate /* There are no stat types defined for partitions */ 291*7c478bd9Sstevel@tonic-gate *errp = EINVAL; 292*7c478bd9Sstevel@tonic-gate return (NULL); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 296*7c478bd9Sstevel@tonic-gate int 297*7c478bd9Sstevel@tonic-gate partition_has_fdisk(disk_t *dp, int fd) 298*7c478bd9Sstevel@tonic-gate { 299*7c478bd9Sstevel@tonic-gate char bootsect[512 * 3]; /* 3 sectors to be safe */ 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate #ifdef sparc 302*7c478bd9Sstevel@tonic-gate if (dp->drv_type == DM_DT_FIXED) { 303*7c478bd9Sstevel@tonic-gate /* on sparc, only removable media can have fdisk parts. */ 304*7c478bd9Sstevel@tonic-gate return (0); 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate #endif 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate /* 309*7c478bd9Sstevel@tonic-gate * We assume the caller already made sure media was inserted and 310*7c478bd9Sstevel@tonic-gate * spun up. 311*7c478bd9Sstevel@tonic-gate */ 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate if ((ioctl(fd, DKIOCGMBOOT, bootsect) < 0) && (errno != ENOTTY)) { 314*7c478bd9Sstevel@tonic-gate return (0); 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate return (1); 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate /* 321*7c478bd9Sstevel@tonic-gate * A partition descriptor points to a disk, the name is the partition number 322*7c478bd9Sstevel@tonic-gate * and the secondary name is the media name. 323*7c478bd9Sstevel@tonic-gate */ 324*7c478bd9Sstevel@tonic-gate int 325*7c478bd9Sstevel@tonic-gate partition_make_descriptors() 326*7c478bd9Sstevel@tonic-gate { 327*7c478bd9Sstevel@tonic-gate int error; 328*7c478bd9Sstevel@tonic-gate disk_t *dp; 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate dp = cache_get_disklist(); 331*7c478bd9Sstevel@tonic-gate while (dp != NULL) { 332*7c478bd9Sstevel@tonic-gate struct ipart iparts[FD_NUMPART]; 333*7c478bd9Sstevel@tonic-gate char pname[MAXPATHLEN]; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate if (get_parts(dp, iparts, pname, sizeof (pname)) == 0) { 336*7c478bd9Sstevel@tonic-gate int i; 337*7c478bd9Sstevel@tonic-gate char mname[MAXPATHLEN]; 338*7c478bd9Sstevel@tonic-gate int conv_flag = 0; 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate #ifdef i386 341*7c478bd9Sstevel@tonic-gate /* convert part. name (e.g. c0d0p0) */ 342*7c478bd9Sstevel@tonic-gate int len; 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate len = strlen(pname); 345*7c478bd9Sstevel@tonic-gate if (len > 1 && *(pname + (len - 2)) == 'p') { 346*7c478bd9Sstevel@tonic-gate conv_flag = 1; 347*7c478bd9Sstevel@tonic-gate *(pname + (len - 1)) = 0; 348*7c478bd9Sstevel@tonic-gate } 349*7c478bd9Sstevel@tonic-gate #endif 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate mname[0] = 0; 352*7c478bd9Sstevel@tonic-gate (void) media_read_name(dp, mname, sizeof (mname)); 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 355*7c478bd9Sstevel@tonic-gate if (iparts[i].systid != 0) { 356*7c478bd9Sstevel@tonic-gate char part_name[MAXPATHLEN]; 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate if (conv_flag) { 359*7c478bd9Sstevel@tonic-gate /* convert part. name (e.g. c0d0p0) */ 360*7c478bd9Sstevel@tonic-gate (void) snprintf(part_name, sizeof (part_name), 361*7c478bd9Sstevel@tonic-gate "%s%d", pname, i); 362*7c478bd9Sstevel@tonic-gate } else { 363*7c478bd9Sstevel@tonic-gate (void) snprintf(part_name, sizeof (part_name), 364*7c478bd9Sstevel@tonic-gate "%d", i); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate cache_load_desc(DM_PARTITION, dp, part_name, mname, 368*7c478bd9Sstevel@tonic-gate &error); 369*7c478bd9Sstevel@tonic-gate if (error != 0) { 370*7c478bd9Sstevel@tonic-gate return (error); 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate } 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate dp = dp->next; 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate return (0); 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate static int 382*7c478bd9Sstevel@tonic-gate get_attrs(descriptor_t *dp, struct ipart *iparts, nvlist_t *attrs) 383*7c478bd9Sstevel@tonic-gate { 384*7c478bd9Sstevel@tonic-gate char *p; 385*7c478bd9Sstevel@tonic-gate int part_num; 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate /* 388*7c478bd9Sstevel@tonic-gate * We already made sure the media was loaded and ready in the 389*7c478bd9Sstevel@tonic-gate * get_parts call within partition_get_attributes. 390*7c478bd9Sstevel@tonic-gate */ 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate p = strrchr(dp->name, 'p'); 393*7c478bd9Sstevel@tonic-gate if (p == NULL) { 394*7c478bd9Sstevel@tonic-gate p = dp->name; 395*7c478bd9Sstevel@tonic-gate } else { 396*7c478bd9Sstevel@tonic-gate p++; 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate part_num = atoi(p); 399*7c478bd9Sstevel@tonic-gate if (part_num >= FD_NUMPART || iparts[part_num].systid == 0) { 400*7c478bd9Sstevel@tonic-gate return (ENODEV); 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate /* we found the partition */ 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BOOTID, 406*7c478bd9Sstevel@tonic-gate (unsigned int)iparts[part_num].bootid) != 0) { 407*7c478bd9Sstevel@tonic-gate return (ENOMEM); 408*7c478bd9Sstevel@tonic-gate } 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_PTYPE, 411*7c478bd9Sstevel@tonic-gate (unsigned int)iparts[part_num].systid) != 0) { 412*7c478bd9Sstevel@tonic-gate return (ENOMEM); 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BHEAD, 416*7c478bd9Sstevel@tonic-gate (unsigned int)iparts[part_num].beghead) != 0) { 417*7c478bd9Sstevel@tonic-gate return (ENOMEM); 418*7c478bd9Sstevel@tonic-gate } 419*7c478bd9Sstevel@tonic-gate 420*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BSECT, 421*7c478bd9Sstevel@tonic-gate (unsigned int)((iparts[part_num].begsect) & 0x3f)) != 0) { 422*7c478bd9Sstevel@tonic-gate return (ENOMEM); 423*7c478bd9Sstevel@tonic-gate } 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BCYL, (unsigned int) 426*7c478bd9Sstevel@tonic-gate ((iparts[part_num].begcyl & 0xff) | 427*7c478bd9Sstevel@tonic-gate ((iparts[part_num].begsect & 0xc0) << 2))) != 0) { 428*7c478bd9Sstevel@tonic-gate return (ENOMEM); 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_EHEAD, 432*7c478bd9Sstevel@tonic-gate (unsigned int)iparts[part_num].endhead) != 0) { 433*7c478bd9Sstevel@tonic-gate return (ENOMEM); 434*7c478bd9Sstevel@tonic-gate } 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_ESECT, 437*7c478bd9Sstevel@tonic-gate (unsigned int)((iparts[part_num].endsect) & 0x3f)) != 0) { 438*7c478bd9Sstevel@tonic-gate return (ENOMEM); 439*7c478bd9Sstevel@tonic-gate } 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_ECYL, (unsigned int) 442*7c478bd9Sstevel@tonic-gate ((iparts[part_num].endcyl & 0xff) | 443*7c478bd9Sstevel@tonic-gate ((iparts[part_num].endsect & 0xc0) << 2))) != 0) { 444*7c478bd9Sstevel@tonic-gate return (ENOMEM); 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_RELSECT, 448*7c478bd9Sstevel@tonic-gate (unsigned int)iparts[part_num].relsect) != 0) { 449*7c478bd9Sstevel@tonic-gate return (ENOMEM); 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_NSECTORS, 453*7c478bd9Sstevel@tonic-gate (unsigned int)iparts[part_num].numsect) != 0) { 454*7c478bd9Sstevel@tonic-gate return (ENOMEM); 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate return (0); 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate static int 461*7c478bd9Sstevel@tonic-gate get_parts(disk_t *disk, struct ipart *iparts, char *opath, int opath_len) 462*7c478bd9Sstevel@tonic-gate { 463*7c478bd9Sstevel@tonic-gate int fd; 464*7c478bd9Sstevel@tonic-gate struct dk_minfo minfo; 465*7c478bd9Sstevel@tonic-gate struct mboot bootblk; 466*7c478bd9Sstevel@tonic-gate char bootsect[512]; 467*7c478bd9Sstevel@tonic-gate int i; 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate /* Can't use drive_open_disk since we need the partition dev name. */ 470*7c478bd9Sstevel@tonic-gate if ((fd = open_disk(disk, opath, opath_len)) < 0) { 471*7c478bd9Sstevel@tonic-gate return (ENODEV); 472*7c478bd9Sstevel@tonic-gate } 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate /* First make sure media is inserted and spun up. */ 475*7c478bd9Sstevel@tonic-gate if (!media_read_info(fd, &minfo)) { 476*7c478bd9Sstevel@tonic-gate #ifdef i386 477*7c478bd9Sstevel@tonic-gate /* XXX Work around bug 4725434 */ 478*7c478bd9Sstevel@tonic-gate if (disk->removable) { 479*7c478bd9Sstevel@tonic-gate #endif 480*7c478bd9Sstevel@tonic-gate (void) close(fd); 481*7c478bd9Sstevel@tonic-gate return (ENODEV); 482*7c478bd9Sstevel@tonic-gate #ifdef i386 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate #endif 485*7c478bd9Sstevel@tonic-gate } 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate if (!partition_has_fdisk(disk, fd)) { 488*7c478bd9Sstevel@tonic-gate (void) close(fd); 489*7c478bd9Sstevel@tonic-gate return (ENOTTY); 490*7c478bd9Sstevel@tonic-gate } 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate if (lseek(fd, 0, 0) == -1) { 493*7c478bd9Sstevel@tonic-gate (void) close(fd); 494*7c478bd9Sstevel@tonic-gate return (ENODEV); 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate if (read(fd, bootsect, 512) != 512) { 498*7c478bd9Sstevel@tonic-gate (void) close(fd); 499*7c478bd9Sstevel@tonic-gate return (ENODEV); 500*7c478bd9Sstevel@tonic-gate } 501*7c478bd9Sstevel@tonic-gate (void) close(fd); 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate (void) memcpy(&bootblk, bootsect, sizeof (bootblk)); 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate if (les(bootblk.signature) != MBB_MAGIC) { 506*7c478bd9Sstevel@tonic-gate return (ENOTTY); 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate 509*7c478bd9Sstevel@tonic-gate (void) memcpy(iparts, bootblk.parts, ISIZE); 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 512*7c478bd9Sstevel@tonic-gate if (iparts[i].systid != 0) { 513*7c478bd9Sstevel@tonic-gate iparts[i].relsect = lel(iparts[i].relsect); 514*7c478bd9Sstevel@tonic-gate iparts[i].numsect = lel(iparts[i].numsect); 515*7c478bd9Sstevel@tonic-gate } 516*7c478bd9Sstevel@tonic-gate } 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate return (0); 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate /* return 1 if the partition descriptor is still valid, 0 if not. */ 521*7c478bd9Sstevel@tonic-gate static int 522*7c478bd9Sstevel@tonic-gate desc_ok(descriptor_t *dp) 523*7c478bd9Sstevel@tonic-gate { 524*7c478bd9Sstevel@tonic-gate /* First verify the media name for removable media */ 525*7c478bd9Sstevel@tonic-gate if (dp->p.disk->removable) { 526*7c478bd9Sstevel@tonic-gate char mname[MAXPATHLEN]; 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate if (!media_read_name(dp->p.disk, mname, sizeof (mname))) { 529*7c478bd9Sstevel@tonic-gate return (0); 530*7c478bd9Sstevel@tonic-gate } 531*7c478bd9Sstevel@tonic-gate 532*7c478bd9Sstevel@tonic-gate if (mname[0] == 0) { 533*7c478bd9Sstevel@tonic-gate return (libdiskmgt_str_eq(dp->secondary_name, NULL)); 534*7c478bd9Sstevel@tonic-gate } else { 535*7c478bd9Sstevel@tonic-gate return (libdiskmgt_str_eq(dp->secondary_name, mname)); 536*7c478bd9Sstevel@tonic-gate } 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate /* 540*7c478bd9Sstevel@tonic-gate * We could verify the partition is still there but this is kind of 541*7c478bd9Sstevel@tonic-gate * expensive and other code down the line will do that (e.g. see 542*7c478bd9Sstevel@tonic-gate * get_attrs). 543*7c478bd9Sstevel@tonic-gate */ 544*7c478bd9Sstevel@tonic-gate 545*7c478bd9Sstevel@tonic-gate return (1); 546*7c478bd9Sstevel@tonic-gate } 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate /* 549*7c478bd9Sstevel@tonic-gate * Return 1 if partition has slices, 0 if not. 550*7c478bd9Sstevel@tonic-gate */ 551*7c478bd9Sstevel@tonic-gate static int 552*7c478bd9Sstevel@tonic-gate has_slices(descriptor_t *desc, int *errp) 553*7c478bd9Sstevel@tonic-gate { 554*7c478bd9Sstevel@tonic-gate int pnum; 555*7c478bd9Sstevel@tonic-gate int i; 556*7c478bd9Sstevel@tonic-gate char *p; 557*7c478bd9Sstevel@tonic-gate struct ipart iparts[FD_NUMPART]; 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate if (get_parts(desc->p.disk, iparts, NULL, 0) != 0) { 560*7c478bd9Sstevel@tonic-gate *errp = ENODEV; 561*7c478bd9Sstevel@tonic-gate return (0); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate p = strrchr(desc->name, 'p'); 565*7c478bd9Sstevel@tonic-gate if (p == NULL) { 566*7c478bd9Sstevel@tonic-gate p = desc->name; 567*7c478bd9Sstevel@tonic-gate } else { 568*7c478bd9Sstevel@tonic-gate p++; 569*7c478bd9Sstevel@tonic-gate } 570*7c478bd9Sstevel@tonic-gate pnum = atoi(p); 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate /* 573*7c478bd9Sstevel@tonic-gate * Slices are associated with the active solaris partition or if there 574*7c478bd9Sstevel@tonic-gate * is no active solaris partition, then the first solaris partition. 575*7c478bd9Sstevel@tonic-gate */ 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate *errp = 0; 578*7c478bd9Sstevel@tonic-gate if (iparts[pnum].bootid == ACTIVE && 579*7c478bd9Sstevel@tonic-gate (iparts[pnum].systid == SUNIXOS || 580*7c478bd9Sstevel@tonic-gate iparts[pnum].systid == SUNIXOS2)) { 581*7c478bd9Sstevel@tonic-gate return (1); 582*7c478bd9Sstevel@tonic-gate } else { 583*7c478bd9Sstevel@tonic-gate int active = 0; 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate /* Check if there are no active solaris partitions. */ 586*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 587*7c478bd9Sstevel@tonic-gate if (iparts[i].bootid == ACTIVE && 588*7c478bd9Sstevel@tonic-gate (iparts[i].systid == SUNIXOS || 589*7c478bd9Sstevel@tonic-gate iparts[i].systid == SUNIXOS2)) { 590*7c478bd9Sstevel@tonic-gate active = 1; 591*7c478bd9Sstevel@tonic-gate break; 592*7c478bd9Sstevel@tonic-gate } 593*7c478bd9Sstevel@tonic-gate } 594*7c478bd9Sstevel@tonic-gate 595*7c478bd9Sstevel@tonic-gate if (!active) { 596*7c478bd9Sstevel@tonic-gate /* Check if this is the first solaris partition. */ 597*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 598*7c478bd9Sstevel@tonic-gate if (iparts[i].systid == SUNIXOS || 599*7c478bd9Sstevel@tonic-gate iparts[i].systid == SUNIXOS2) { 600*7c478bd9Sstevel@tonic-gate break; 601*7c478bd9Sstevel@tonic-gate } 602*7c478bd9Sstevel@tonic-gate } 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate if (i < FD_NUMPART && i == pnum) { 605*7c478bd9Sstevel@tonic-gate return (1); 606*7c478bd9Sstevel@tonic-gate } 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate } 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate return (0); 611*7c478bd9Sstevel@tonic-gate } 612*7c478bd9Sstevel@tonic-gate 613*7c478bd9Sstevel@tonic-gate static int 614*7c478bd9Sstevel@tonic-gate open_disk(disk_t *diskp, char *opath, int len) 615*7c478bd9Sstevel@tonic-gate { 616*7c478bd9Sstevel@tonic-gate char rmmedia_devpath[MAXPATHLEN]; 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate if (diskp->removable && media_get_volm_path(diskp, rmmedia_devpath, 619*7c478bd9Sstevel@tonic-gate sizeof (rmmedia_devpath))) { 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate int fd; 622*7c478bd9Sstevel@tonic-gate struct stat buf; 623*7c478bd9Sstevel@tonic-gate 624*7c478bd9Sstevel@tonic-gate if (rmmedia_devpath[0] == 0) { 625*7c478bd9Sstevel@tonic-gate /* removable but no media */ 626*7c478bd9Sstevel@tonic-gate return (-1); 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate 629*7c478bd9Sstevel@tonic-gate if ((fd = open(rmmedia_devpath, O_RDONLY|O_NDELAY)) < 0) { 630*7c478bd9Sstevel@tonic-gate return (-1); 631*7c478bd9Sstevel@tonic-gate } 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate if (fstat(fd, &buf) != 0) { 634*7c478bd9Sstevel@tonic-gate (void) close(fd); 635*7c478bd9Sstevel@tonic-gate return (-1); 636*7c478bd9Sstevel@tonic-gate } 637*7c478bd9Sstevel@tonic-gate 638*7c478bd9Sstevel@tonic-gate if (buf.st_mode & S_IFCHR) { 639*7c478bd9Sstevel@tonic-gate /* opened, is device, so done */ 640*7c478bd9Sstevel@tonic-gate if (opath != NULL) { 641*7c478bd9Sstevel@tonic-gate (void) strlcpy(opath, rmmedia_devpath, len); 642*7c478bd9Sstevel@tonic-gate } 643*7c478bd9Sstevel@tonic-gate return (fd); 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate } else if (buf.st_mode & S_IFDIR) { 646*7c478bd9Sstevel@tonic-gate /* disk w/ slices so handle the directory */ 647*7c478bd9Sstevel@tonic-gate DIR *dirp; 648*7c478bd9Sstevel@tonic-gate struct dirent *dentp; 649*7c478bd9Sstevel@tonic-gate int dfd; 650*7c478bd9Sstevel@tonic-gate #ifdef _LP64 651*7c478bd9Sstevel@tonic-gate struct dirent *result; 652*7c478bd9Sstevel@tonic-gate #endif 653*7c478bd9Sstevel@tonic-gate 654*7c478bd9Sstevel@tonic-gate /* each device file in the dir represents a slice */ 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate if ((dirp = fdopendir(fd)) == NULL) { 657*7c478bd9Sstevel@tonic-gate (void) close(fd); 658*7c478bd9Sstevel@tonic-gate return (-1); 659*7c478bd9Sstevel@tonic-gate } 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate if ((dentp = (struct dirent *)malloc(sizeof (struct dirent) + 662*7c478bd9Sstevel@tonic-gate _PC_NAME_MAX + 1)) == NULL) { 663*7c478bd9Sstevel@tonic-gate /* out of memory */ 664*7c478bd9Sstevel@tonic-gate (void) close(fd); 665*7c478bd9Sstevel@tonic-gate return (-1); 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate #ifdef _LP64 668*7c478bd9Sstevel@tonic-gate while (readdir_r(dirp, dentp, &result) != NULL) { 669*7c478bd9Sstevel@tonic-gate #else 670*7c478bd9Sstevel@tonic-gate while (readdir_r(dirp, dentp) != NULL) { 671*7c478bd9Sstevel@tonic-gate #endif 672*7c478bd9Sstevel@tonic-gate char slice_path[MAXPATHLEN]; 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gate if (libdiskmgt_str_eq(".", dentp->d_name) || 675*7c478bd9Sstevel@tonic-gate libdiskmgt_str_eq("..", dentp->d_name)) { 676*7c478bd9Sstevel@tonic-gate continue; 677*7c478bd9Sstevel@tonic-gate } 678*7c478bd9Sstevel@tonic-gate 679*7c478bd9Sstevel@tonic-gate (void) snprintf(slice_path, sizeof (slice_path), "%s/%s", 680*7c478bd9Sstevel@tonic-gate rmmedia_devpath, dentp->d_name); 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate if ((dfd = open(slice_path, O_RDONLY|O_NDELAY)) < 0) { 683*7c478bd9Sstevel@tonic-gate continue; 684*7c478bd9Sstevel@tonic-gate } 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate if (fstat(dfd, &buf) == 0 && (buf.st_mode & S_IFCHR)) { 687*7c478bd9Sstevel@tonic-gate /* opened, is device, so done */ 688*7c478bd9Sstevel@tonic-gate free(dentp); 689*7c478bd9Sstevel@tonic-gate (void) close(fd); 690*7c478bd9Sstevel@tonic-gate if (opath != NULL) { 691*7c478bd9Sstevel@tonic-gate (void) strlcpy(opath, slice_path, len); 692*7c478bd9Sstevel@tonic-gate } 693*7c478bd9Sstevel@tonic-gate return (dfd); 694*7c478bd9Sstevel@tonic-gate } 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate /* not a device, keep looking */ 697*7c478bd9Sstevel@tonic-gate (void) close(dfd); 698*7c478bd9Sstevel@tonic-gate } 699*7c478bd9Sstevel@tonic-gate 700*7c478bd9Sstevel@tonic-gate /* did not find a device under the rmmedia_path */ 701*7c478bd9Sstevel@tonic-gate free(dentp); 702*7c478bd9Sstevel@tonic-gate (void) close(fd); 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate /* didn't find a device under volume management control */ 706*7c478bd9Sstevel@tonic-gate return (-1); 707*7c478bd9Sstevel@tonic-gate } 708*7c478bd9Sstevel@tonic-gate 709*7c478bd9Sstevel@tonic-gate /* 710*7c478bd9Sstevel@tonic-gate * Not removable media under volume management control so just open the 711*7c478bd9Sstevel@tonic-gate * first devpath. 712*7c478bd9Sstevel@tonic-gate */ 713*7c478bd9Sstevel@tonic-gate if (diskp->aliases != NULL && diskp->aliases->devpaths != NULL) { 714*7c478bd9Sstevel@tonic-gate #ifdef sparc 715*7c478bd9Sstevel@tonic-gate if (opath != NULL) { 716*7c478bd9Sstevel@tonic-gate (void) strlcpy(opath, diskp->aliases->devpaths->devpath, len); 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate return (open(diskp->aliases->devpaths->devpath, O_RDONLY|O_NDELAY)); 719*7c478bd9Sstevel@tonic-gate #else 720*7c478bd9Sstevel@tonic-gate /* On intel we need to open partition device (e.g. c0d0p0). */ 721*7c478bd9Sstevel@tonic-gate char part_dev[MAXPATHLEN]; 722*7c478bd9Sstevel@tonic-gate char *p; 723*7c478bd9Sstevel@tonic-gate 724*7c478bd9Sstevel@tonic-gate (void) strlcpy(part_dev, diskp->aliases->devpaths->devpath, 725*7c478bd9Sstevel@tonic-gate sizeof (part_dev)); 726*7c478bd9Sstevel@tonic-gate p = strrchr(part_dev, '/'); 727*7c478bd9Sstevel@tonic-gate if (p == NULL) { 728*7c478bd9Sstevel@tonic-gate p = strrchr(part_dev, 's'); 729*7c478bd9Sstevel@tonic-gate if (p != NULL) { 730*7c478bd9Sstevel@tonic-gate *p = 'p'; 731*7c478bd9Sstevel@tonic-gate } 732*7c478bd9Sstevel@tonic-gate } else { 733*7c478bd9Sstevel@tonic-gate char *ps; 734*7c478bd9Sstevel@tonic-gate 735*7c478bd9Sstevel@tonic-gate *p = 0; 736*7c478bd9Sstevel@tonic-gate ps = strrchr((p + 1), 's'); 737*7c478bd9Sstevel@tonic-gate if (ps != NULL) { 738*7c478bd9Sstevel@tonic-gate *ps = 'p'; 739*7c478bd9Sstevel@tonic-gate } 740*7c478bd9Sstevel@tonic-gate *p = '/'; 741*7c478bd9Sstevel@tonic-gate } 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate if (opath != NULL) { 744*7c478bd9Sstevel@tonic-gate (void) strlcpy(opath, part_dev, len); 745*7c478bd9Sstevel@tonic-gate } 746*7c478bd9Sstevel@tonic-gate return (open(part_dev, O_RDONLY|O_NDELAY)); 747*7c478bd9Sstevel@tonic-gate #endif 748*7c478bd9Sstevel@tonic-gate } 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate return (-1); 751*7c478bd9Sstevel@tonic-gate } 752