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 */ 210Sstevel@tonic-gate /* 2211091SVirginia.Wray@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #include <fcntl.h> 270Sstevel@tonic-gate #include <libdevinfo.h> 280Sstevel@tonic-gate #include <stdio.h> 290Sstevel@tonic-gate #include <stdlib.h> 300Sstevel@tonic-gate #include <string.h> 310Sstevel@tonic-gate #include <sys/sunddi.h> 320Sstevel@tonic-gate #include <sys/types.h> 330Sstevel@tonic-gate #include <sys/stat.h> 340Sstevel@tonic-gate #include <dirent.h> 350Sstevel@tonic-gate #include <unistd.h> 360Sstevel@tonic-gate #include <sys/dkio.h> 370Sstevel@tonic-gate 3811091SVirginia.Wray@Sun.COM #if defined(i386) || defined(__amd64) 3911091SVirginia.Wray@Sun.COM #include <sys/dktp/fdisk.h> 4011091SVirginia.Wray@Sun.COM #include <libfdisk.h> 4111091SVirginia.Wray@Sun.COM #endif 4211091SVirginia.Wray@Sun.COM 430Sstevel@tonic-gate #include "libdiskmgt.h" 440Sstevel@tonic-gate #include "disks_private.h" 450Sstevel@tonic-gate #include "partition.h" 460Sstevel@tonic-gate 470Sstevel@tonic-gate #ifdef sparc 480Sstevel@tonic-gate #define les(val) ((((val)&0xFF)<<8)|(((val)>>8)&0xFF)) 490Sstevel@tonic-gate #define lel(val) (((unsigned)(les((val)&0x0000FFFF))<<16) | \ 500Sstevel@tonic-gate (les((unsigned)((val)&0xffff0000)>>16))) 510Sstevel@tonic-gate #else 520Sstevel@tonic-gate #define les(val) (val) 530Sstevel@tonic-gate #define lel(val) (val) 540Sstevel@tonic-gate #endif 550Sstevel@tonic-gate 5611091SVirginia.Wray@Sun.COM #define TOTAL_NUMPART (FD_NUMPART + MAX_EXT_PARTS) 5711091SVirginia.Wray@Sun.COM 580Sstevel@tonic-gate #define ISIZE FD_NUMPART * sizeof (struct ipart) 590Sstevel@tonic-gate 600Sstevel@tonic-gate static int desc_ok(descriptor_t *dp); 610Sstevel@tonic-gate static int get_attrs(descriptor_t *dp, struct ipart *iparts, 620Sstevel@tonic-gate nvlist_t *attrs); 630Sstevel@tonic-gate static int get_parts(disk_t *disk, struct ipart *iparts, char *opath, 640Sstevel@tonic-gate int opath_len); 650Sstevel@tonic-gate static int open_disk(disk_t *diskp, char *opath, int len); 660Sstevel@tonic-gate static int has_slices(descriptor_t *desc, int *errp); 670Sstevel@tonic-gate 680Sstevel@tonic-gate descriptor_t ** 690Sstevel@tonic-gate partition_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type, 700Sstevel@tonic-gate int *errp) 710Sstevel@tonic-gate { 720Sstevel@tonic-gate if (!desc_ok(desc)) { 7311091SVirginia.Wray@Sun.COM *errp = ENODEV; 7411091SVirginia.Wray@Sun.COM return (NULL); 750Sstevel@tonic-gate } 760Sstevel@tonic-gate 770Sstevel@tonic-gate switch (type) { 780Sstevel@tonic-gate case DM_MEDIA: 7911091SVirginia.Wray@Sun.COM return (media_get_assocs(desc, errp)); 800Sstevel@tonic-gate case DM_SLICE: 8111091SVirginia.Wray@Sun.COM if (!has_slices(desc, errp)) { 8211091SVirginia.Wray@Sun.COM if (*errp != 0) { 8311091SVirginia.Wray@Sun.COM return (NULL); 8411091SVirginia.Wray@Sun.COM } 8511091SVirginia.Wray@Sun.COM return (libdiskmgt_empty_desc_array(errp)); 860Sstevel@tonic-gate } 8711091SVirginia.Wray@Sun.COM return (slice_get_assocs(desc, errp)); 880Sstevel@tonic-gate } 890Sstevel@tonic-gate 900Sstevel@tonic-gate *errp = EINVAL; 910Sstevel@tonic-gate return (NULL); 920Sstevel@tonic-gate } 930Sstevel@tonic-gate 940Sstevel@tonic-gate /* 950Sstevel@tonic-gate * This is called by media/slice to get the associated partitions. 960Sstevel@tonic-gate * For a media desc. we just get all the partitions, but for a slice desc. 970Sstevel@tonic-gate * we just get the active solaris partition. 980Sstevel@tonic-gate */ 990Sstevel@tonic-gate descriptor_t ** 1000Sstevel@tonic-gate partition_get_assocs(descriptor_t *desc, int *errp) 1010Sstevel@tonic-gate { 1020Sstevel@tonic-gate descriptor_t **partitions; 1030Sstevel@tonic-gate int pos; 1040Sstevel@tonic-gate int i; 10511091SVirginia.Wray@Sun.COM struct ipart iparts[TOTAL_NUMPART]; 1060Sstevel@tonic-gate char pname[MAXPATHLEN]; 1070Sstevel@tonic-gate int conv_flag = 0; 108767Ssjelinek #if defined(i386) || defined(__amd64) 109767Ssjelinek int len; 110767Ssjelinek #endif 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate if (get_parts(desc->p.disk, iparts, pname, sizeof (pname)) != 0) { 11311091SVirginia.Wray@Sun.COM return (libdiskmgt_empty_desc_array(errp)); 1140Sstevel@tonic-gate } 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate /* allocate the array for the descriptors */ 11711091SVirginia.Wray@Sun.COM partitions = (descriptor_t **)calloc(TOTAL_NUMPART + 1, 1180Sstevel@tonic-gate sizeof (descriptor_t *)); 1190Sstevel@tonic-gate if (partitions == NULL) { 12011091SVirginia.Wray@Sun.COM *errp = ENOMEM; 12111091SVirginia.Wray@Sun.COM return (NULL); 1220Sstevel@tonic-gate } 1230Sstevel@tonic-gate 124767Ssjelinek #if defined(i386) || defined(__amd64) 12511091SVirginia.Wray@Sun.COM /* convert part. name (e.g. c0d0p1) */ 12611091SVirginia.Wray@Sun.COM len = strlen(pname); 12711091SVirginia.Wray@Sun.COM if (len > 1 && *(pname + (len - 2)) == 'p') { 1280Sstevel@tonic-gate conv_flag = 1; 1290Sstevel@tonic-gate *(pname + (len - 1)) = 0; 13011091SVirginia.Wray@Sun.COM } 1310Sstevel@tonic-gate #endif 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate /* 1340Sstevel@tonic-gate * If this is a slice desc. we need the first active solaris partition 1350Sstevel@tonic-gate * and if there isn't one then we need the first solaris partition. 1360Sstevel@tonic-gate */ 1370Sstevel@tonic-gate if (desc->type == DM_SLICE) { 13811091SVirginia.Wray@Sun.COM for (i = 0; i < TOTAL_NUMPART; i++) { 13911091SVirginia.Wray@Sun.COM if (iparts[i].bootid == ACTIVE && 14011091SVirginia.Wray@Sun.COM (iparts[i].systid == SUNIXOS || 14111091SVirginia.Wray@Sun.COM iparts[i].systid == SUNIXOS2)) { 14211091SVirginia.Wray@Sun.COM break; 14311091SVirginia.Wray@Sun.COM } 1440Sstevel@tonic-gate } 1450Sstevel@tonic-gate 14611091SVirginia.Wray@Sun.COM /* 14711091SVirginia.Wray@Sun.COM * no active solaris part.,*try to get the first solaris part. 14811091SVirginia.Wray@Sun.COM */ 14911091SVirginia.Wray@Sun.COM if (i >= TOTAL_NUMPART) { 15011091SVirginia.Wray@Sun.COM for (i = 0; i < TOTAL_NUMPART; i++) { 15111091SVirginia.Wray@Sun.COM if (iparts[i].systid == SUNIXOS || 15211091SVirginia.Wray@Sun.COM iparts[i].systid == SUNIXOS2) { 15311091SVirginia.Wray@Sun.COM break; 15411091SVirginia.Wray@Sun.COM } 15511091SVirginia.Wray@Sun.COM } 1560Sstevel@tonic-gate } 1570Sstevel@tonic-gate 15811091SVirginia.Wray@Sun.COM if (i < TOTAL_NUMPART) { 15911091SVirginia.Wray@Sun.COM /* we found a solaris partition to use */ 16011091SVirginia.Wray@Sun.COM char part_name[MAXPATHLEN]; 16111091SVirginia.Wray@Sun.COM 16211091SVirginia.Wray@Sun.COM if (conv_flag) { 16311091SVirginia.Wray@Sun.COM /* convert part. name (e.g. c0d0p1) */ 16411091SVirginia.Wray@Sun.COM (void) snprintf(part_name, sizeof (part_name), 16511091SVirginia.Wray@Sun.COM "%s%d", pname, i+1); 16611091SVirginia.Wray@Sun.COM } else { 16711091SVirginia.Wray@Sun.COM (void) snprintf(part_name, sizeof (part_name), 16811091SVirginia.Wray@Sun.COM "%d", i+1); 16911091SVirginia.Wray@Sun.COM } 17011091SVirginia.Wray@Sun.COM 17111091SVirginia.Wray@Sun.COM /* the media name comes from the slice desc. */ 17211091SVirginia.Wray@Sun.COM partitions[0] = cache_get_desc(DM_PARTITION, 17311091SVirginia.Wray@Sun.COM desc->p.disk, part_name, desc->secondary_name, 17411091SVirginia.Wray@Sun.COM errp); 17511091SVirginia.Wray@Sun.COM if (*errp != 0) { 17611091SVirginia.Wray@Sun.COM cache_free_descriptors(partitions); 17711091SVirginia.Wray@Sun.COM return (NULL); 17811091SVirginia.Wray@Sun.COM } 17911091SVirginia.Wray@Sun.COM partitions[1] = NULL; 18011091SVirginia.Wray@Sun.COM 18111091SVirginia.Wray@Sun.COM return (partitions); 1820Sstevel@tonic-gate } 1830Sstevel@tonic-gate 18411091SVirginia.Wray@Sun.COM return (libdiskmgt_empty_desc_array(errp)); 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate /* Must be for media, so get all the parts. */ 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate pos = 0; 19011091SVirginia.Wray@Sun.COM for (i = 0; i < TOTAL_NUMPART; i++) { 19111091SVirginia.Wray@Sun.COM if (iparts[i].systid != UNUSED) { 19211091SVirginia.Wray@Sun.COM char part_name[MAXPATHLEN]; 1930Sstevel@tonic-gate 19411091SVirginia.Wray@Sun.COM /* 19511091SVirginia.Wray@Sun.COM * Process the descriptors and modify the cxdxpx 19611091SVirginia.Wray@Sun.COM * format so that it refers to the fdisk partition 19711091SVirginia.Wray@Sun.COM * number and not to the physical disk. This is 19811091SVirginia.Wray@Sun.COM * achieved by i+1, where i is the number of the 19911091SVirginia.Wray@Sun.COM * physical disk partition. 20011091SVirginia.Wray@Sun.COM */ 20111091SVirginia.Wray@Sun.COM if (conv_flag) { 20211091SVirginia.Wray@Sun.COM /* convert part. name (e.g. c0d0p1) */ 20311091SVirginia.Wray@Sun.COM (void) snprintf(part_name, sizeof (part_name), 20411091SVirginia.Wray@Sun.COM "%s%d", pname, i+1); 20511091SVirginia.Wray@Sun.COM } else { 20611091SVirginia.Wray@Sun.COM (void) snprintf(part_name, sizeof (part_name), 20711091SVirginia.Wray@Sun.COM "%d", i+1); 20811091SVirginia.Wray@Sun.COM } 20911091SVirginia.Wray@Sun.COM 21011091SVirginia.Wray@Sun.COM /* the media name comes from the media desc. */ 21111091SVirginia.Wray@Sun.COM partitions[pos] = cache_get_desc(DM_PARTITION, 21211091SVirginia.Wray@Sun.COM desc->p.disk, part_name, desc->name, errp); 21311091SVirginia.Wray@Sun.COM if (*errp != 0) { 21411091SVirginia.Wray@Sun.COM cache_free_descriptors(partitions); 21511091SVirginia.Wray@Sun.COM return (NULL); 21611091SVirginia.Wray@Sun.COM } 21711091SVirginia.Wray@Sun.COM 21811091SVirginia.Wray@Sun.COM pos++; 2190Sstevel@tonic-gate } 2200Sstevel@tonic-gate } 2210Sstevel@tonic-gate partitions[pos] = NULL; 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate *errp = 0; 2240Sstevel@tonic-gate return (partitions); 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate nvlist_t * 2280Sstevel@tonic-gate partition_get_attributes(descriptor_t *dp, int *errp) 2290Sstevel@tonic-gate { 2300Sstevel@tonic-gate nvlist_t *attrs = NULL; 23111091SVirginia.Wray@Sun.COM struct ipart iparts[TOTAL_NUMPART]; 2320Sstevel@tonic-gate 2330Sstevel@tonic-gate if (!desc_ok(dp)) { 23411091SVirginia.Wray@Sun.COM *errp = ENODEV; 23511091SVirginia.Wray@Sun.COM return (NULL); 2360Sstevel@tonic-gate } 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate if ((*errp = get_parts(dp->p.disk, iparts, NULL, 0)) != 0) { 23911091SVirginia.Wray@Sun.COM return (NULL); 2400Sstevel@tonic-gate } 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) { 24311091SVirginia.Wray@Sun.COM *errp = ENOMEM; 24411091SVirginia.Wray@Sun.COM return (NULL); 2450Sstevel@tonic-gate } 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate if ((*errp = get_attrs(dp, iparts, attrs)) != 0) { 24811091SVirginia.Wray@Sun.COM nvlist_free(attrs); 24911091SVirginia.Wray@Sun.COM attrs = NULL; 2500Sstevel@tonic-gate } 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate return (attrs); 2530Sstevel@tonic-gate } 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate /* 2560Sstevel@tonic-gate * Look for the partition by the partition number (which is not too useful). 2570Sstevel@tonic-gate */ 2580Sstevel@tonic-gate descriptor_t * 2590Sstevel@tonic-gate partition_get_descriptor_by_name(char *name, int *errp) 2600Sstevel@tonic-gate { 2610Sstevel@tonic-gate descriptor_t **partitions; 2620Sstevel@tonic-gate int i; 2630Sstevel@tonic-gate descriptor_t *partition = NULL; 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate partitions = cache_get_descriptors(DM_PARTITION, errp); 2660Sstevel@tonic-gate if (*errp != 0) { 26711091SVirginia.Wray@Sun.COM return (NULL); 2680Sstevel@tonic-gate } 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate for (i = 0; partitions[i]; i++) { 27111091SVirginia.Wray@Sun.COM if (libdiskmgt_str_eq(name, partitions[i]->name)) { 27211091SVirginia.Wray@Sun.COM partition = partitions[i]; 27311091SVirginia.Wray@Sun.COM } else { 27411091SVirginia.Wray@Sun.COM /* clean up the unused descriptors */ 27511091SVirginia.Wray@Sun.COM cache_free_descriptor(partitions[i]); 27611091SVirginia.Wray@Sun.COM } 2770Sstevel@tonic-gate } 2780Sstevel@tonic-gate free(partitions); 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate if (partition == NULL) { 28111091SVirginia.Wray@Sun.COM *errp = ENODEV; 2820Sstevel@tonic-gate } 2830Sstevel@tonic-gate 2840Sstevel@tonic-gate return (partition); 2850Sstevel@tonic-gate } 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate /* ARGSUSED */ 2880Sstevel@tonic-gate descriptor_t ** 2890Sstevel@tonic-gate partition_get_descriptors(int filter[], int *errp) 2900Sstevel@tonic-gate { 2910Sstevel@tonic-gate return (cache_get_descriptors(DM_PARTITION, errp)); 2920Sstevel@tonic-gate } 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate char * 2950Sstevel@tonic-gate partition_get_name(descriptor_t *desc) 2960Sstevel@tonic-gate { 2970Sstevel@tonic-gate return (desc->name); 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate /* ARGSUSED */ 3010Sstevel@tonic-gate nvlist_t * 3020Sstevel@tonic-gate partition_get_stats(descriptor_t *dp, int stat_type, int *errp) 3030Sstevel@tonic-gate { 3040Sstevel@tonic-gate /* There are no stat types defined for partitions */ 3050Sstevel@tonic-gate *errp = EINVAL; 3060Sstevel@tonic-gate return (NULL); 3070Sstevel@tonic-gate } 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate /* ARGSUSED */ 3100Sstevel@tonic-gate int 3110Sstevel@tonic-gate partition_has_fdisk(disk_t *dp, int fd) 3120Sstevel@tonic-gate { 3130Sstevel@tonic-gate char bootsect[512 * 3]; /* 3 sectors to be safe */ 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate #ifdef sparc 3160Sstevel@tonic-gate if (dp->drv_type == DM_DT_FIXED) { 31711091SVirginia.Wray@Sun.COM /* on sparc, only removable media can have fdisk parts. */ 31811091SVirginia.Wray@Sun.COM return (0); 3190Sstevel@tonic-gate } 3200Sstevel@tonic-gate #endif 3210Sstevel@tonic-gate 3220Sstevel@tonic-gate /* 3230Sstevel@tonic-gate * We assume the caller already made sure media was inserted and 3240Sstevel@tonic-gate * spun up. 3250Sstevel@tonic-gate */ 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate if ((ioctl(fd, DKIOCGMBOOT, bootsect) < 0) && (errno != ENOTTY)) { 32811091SVirginia.Wray@Sun.COM return (0); 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate return (1); 3320Sstevel@tonic-gate } 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate /* 33511091SVirginia.Wray@Sun.COM * partition_make_descriptors 33611091SVirginia.Wray@Sun.COM * 3370Sstevel@tonic-gate * A partition descriptor points to a disk, the name is the partition number 33811091SVirginia.Wray@Sun.COM * and the secondary name is the media name. The iparts parameter returned 33911091SVirginia.Wray@Sun.COM * by the get_parts function contains the structures of all of the identified 34011091SVirginia.Wray@Sun.COM * partitions found on each disk on a system. These are processed into an array 34111091SVirginia.Wray@Sun.COM * of descriptors. A descriptor contains all of the information about a 34211091SVirginia.Wray@Sun.COM * specific partition. 34311091SVirginia.Wray@Sun.COM * 34411091SVirginia.Wray@Sun.COM * Parameters: none 34511091SVirginia.Wray@Sun.COM * 34611091SVirginia.Wray@Sun.COM * Returns: 0 on success 34711091SVirginia.Wray@Sun.COM * Error value on failure 34811091SVirginia.Wray@Sun.COM * 3490Sstevel@tonic-gate */ 35011091SVirginia.Wray@Sun.COM 3510Sstevel@tonic-gate int 3520Sstevel@tonic-gate partition_make_descriptors() 3530Sstevel@tonic-gate { 3540Sstevel@tonic-gate int error; 3550Sstevel@tonic-gate disk_t *dp; 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate dp = cache_get_disklist(); 3580Sstevel@tonic-gate while (dp != NULL) { 35911091SVirginia.Wray@Sun.COM struct ipart iparts[TOTAL_NUMPART]; 36011091SVirginia.Wray@Sun.COM char pname[MAXPATHLEN]; 3610Sstevel@tonic-gate 36211091SVirginia.Wray@Sun.COM if (get_parts(dp, iparts, pname, sizeof (pname)) == 0) { 36311091SVirginia.Wray@Sun.COM int i; 36411091SVirginia.Wray@Sun.COM char mname[MAXPATHLEN]; 36511091SVirginia.Wray@Sun.COM int conv_flag = 0; 366767Ssjelinek #if defined(i386) || defined(__amd64) 36711091SVirginia.Wray@Sun.COM /* convert part. name (e.g. c0d0p1) */ 36811091SVirginia.Wray@Sun.COM int len; 3690Sstevel@tonic-gate 37011091SVirginia.Wray@Sun.COM len = strlen(pname); 37111091SVirginia.Wray@Sun.COM if (len > 1 && *(pname + (len - 2)) == 'p') { 37211091SVirginia.Wray@Sun.COM conv_flag = 1; 37311091SVirginia.Wray@Sun.COM *(pname + (len - 1)) = 0; 37411091SVirginia.Wray@Sun.COM } 3750Sstevel@tonic-gate #endif 3760Sstevel@tonic-gate 37711091SVirginia.Wray@Sun.COM mname[0] = 0; 37811091SVirginia.Wray@Sun.COM (void) media_read_name(dp, mname, sizeof (mname)); 3790Sstevel@tonic-gate 38011091SVirginia.Wray@Sun.COM /* 38111091SVirginia.Wray@Sun.COM * Process the descriptors and modify the cxdxpx 38211091SVirginia.Wray@Sun.COM * format so that it refers to the fdisk partition 38311091SVirginia.Wray@Sun.COM * number and not to the physical disk. This is 38411091SVirginia.Wray@Sun.COM * achieved by i+1, where i is the number of the 38511091SVirginia.Wray@Sun.COM * physical disk partition. 38611091SVirginia.Wray@Sun.COM */ 38711091SVirginia.Wray@Sun.COM for (i = 0; i < TOTAL_NUMPART; i++) { 38811091SVirginia.Wray@Sun.COM if (iparts[i].systid != UNUSED) { 38911091SVirginia.Wray@Sun.COM char part_name[MAXPATHLEN]; 3900Sstevel@tonic-gate 39111091SVirginia.Wray@Sun.COM if (conv_flag) { 39211091SVirginia.Wray@Sun.COM /* 39311091SVirginia.Wray@Sun.COM * convert partition name 39411091SVirginia.Wray@Sun.COM * (e.g. c0d0p1) 39511091SVirginia.Wray@Sun.COM */ 39611091SVirginia.Wray@Sun.COM (void) snprintf(part_name, 39711091SVirginia.Wray@Sun.COM sizeof (part_name), 39811091SVirginia.Wray@Sun.COM "%s%d", pname, i+1); 39911091SVirginia.Wray@Sun.COM } else { 40011091SVirginia.Wray@Sun.COM (void) snprintf(part_name, 40111091SVirginia.Wray@Sun.COM sizeof (part_name), 40211091SVirginia.Wray@Sun.COM "%d", i+1); 40311091SVirginia.Wray@Sun.COM } 4040Sstevel@tonic-gate 40511091SVirginia.Wray@Sun.COM cache_load_desc(DM_PARTITION, dp, 40611091SVirginia.Wray@Sun.COM part_name, mname, &error); 40711091SVirginia.Wray@Sun.COM if (error != 0) { 40811091SVirginia.Wray@Sun.COM return (error); 40911091SVirginia.Wray@Sun.COM } 41011091SVirginia.Wray@Sun.COM } 4110Sstevel@tonic-gate } 4120Sstevel@tonic-gate } 41311091SVirginia.Wray@Sun.COM dp = dp->next; 4140Sstevel@tonic-gate } 4150Sstevel@tonic-gate 4160Sstevel@tonic-gate return (0); 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate static int 4200Sstevel@tonic-gate get_attrs(descriptor_t *dp, struct ipart *iparts, nvlist_t *attrs) 4210Sstevel@tonic-gate { 4220Sstevel@tonic-gate char *p; 4230Sstevel@tonic-gate int part_num; 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate /* 4260Sstevel@tonic-gate * We already made sure the media was loaded and ready in the 4270Sstevel@tonic-gate * get_parts call within partition_get_attributes. 4280Sstevel@tonic-gate */ 4290Sstevel@tonic-gate 4300Sstevel@tonic-gate p = strrchr(dp->name, 'p'); 4310Sstevel@tonic-gate if (p == NULL) { 43211091SVirginia.Wray@Sun.COM p = dp->name; 4330Sstevel@tonic-gate } else { 43411091SVirginia.Wray@Sun.COM p++; 4350Sstevel@tonic-gate } 4360Sstevel@tonic-gate part_num = atoi(p); 43711091SVirginia.Wray@Sun.COM if (part_num > TOTAL_NUMPART || 43811091SVirginia.Wray@Sun.COM iparts[part_num - 1].systid == UNUSED) { 43911091SVirginia.Wray@Sun.COM return (ENODEV); 4400Sstevel@tonic-gate } 4410Sstevel@tonic-gate 44211091SVirginia.Wray@Sun.COM /* 44311091SVirginia.Wray@Sun.COM * A partition has been found. Determine what type of 44411091SVirginia.Wray@Sun.COM * partition it is: logical, extended, or primary. 44511091SVirginia.Wray@Sun.COM * Collect the information for the partition. 44611091SVirginia.Wray@Sun.COM */ 44711091SVirginia.Wray@Sun.COM #if defined(i386) || defined(__amd64) 44811091SVirginia.Wray@Sun.COM if (part_num > FD_NUMPART) { 44911091SVirginia.Wray@Sun.COM if (nvlist_add_uint32(attrs, DM_PARTITION_TYPE, 45011091SVirginia.Wray@Sun.COM DM_LOGICAL) != 0) { 45111091SVirginia.Wray@Sun.COM return (ENOMEM); 45211091SVirginia.Wray@Sun.COM } 45311091SVirginia.Wray@Sun.COM } else if (fdisk_is_dos_extended(iparts[part_num - 1].systid)) { 45411091SVirginia.Wray@Sun.COM if (nvlist_add_uint32(attrs, DM_PARTITION_TYPE, 45511091SVirginia.Wray@Sun.COM DM_EXTENDED) != 0) { 45611091SVirginia.Wray@Sun.COM return (ENOMEM); 45711091SVirginia.Wray@Sun.COM } 45811091SVirginia.Wray@Sun.COM 45911091SVirginia.Wray@Sun.COM } else { 46011091SVirginia.Wray@Sun.COM if (nvlist_add_uint32(attrs, DM_PARTITION_TYPE, 46111091SVirginia.Wray@Sun.COM DM_PRIMARY) != 0) { 46211091SVirginia.Wray@Sun.COM return (ENOMEM); 46311091SVirginia.Wray@Sun.COM } 46411091SVirginia.Wray@Sun.COM } 46511091SVirginia.Wray@Sun.COM #endif 46611091SVirginia.Wray@Sun.COM 46711091SVirginia.Wray@Sun.COM #ifdef sparc 46811091SVirginia.Wray@Sun.COM if (nvlist_add_uint32(attrs, DM_PARTITION_TYPE, 46911091SVirginia.Wray@Sun.COM DM_PRIMARY) != 0) { 47011091SVirginia.Wray@Sun.COM return (ENOMEM); 47111091SVirginia.Wray@Sun.COM } 47211091SVirginia.Wray@Sun.COM #endif 47311091SVirginia.Wray@Sun.COM 4740Sstevel@tonic-gate 4750Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BOOTID, 47611091SVirginia.Wray@Sun.COM (unsigned int)iparts[part_num - 1].bootid) != 0) { 47711091SVirginia.Wray@Sun.COM return (ENOMEM); 4780Sstevel@tonic-gate } 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_PTYPE, 48111091SVirginia.Wray@Sun.COM (unsigned int)iparts[part_num - 1].systid) != 0) { 48211091SVirginia.Wray@Sun.COM return (ENOMEM); 4830Sstevel@tonic-gate } 4840Sstevel@tonic-gate 4850Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BHEAD, 48611091SVirginia.Wray@Sun.COM (unsigned int)iparts[part_num - 1].beghead) != 0) { 48711091SVirginia.Wray@Sun.COM return (ENOMEM); 4880Sstevel@tonic-gate } 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BSECT, 49111091SVirginia.Wray@Sun.COM (unsigned int)((iparts[part_num - 1].begsect) & 0x3f)) != 0) { 49211091SVirginia.Wray@Sun.COM return (ENOMEM); 4930Sstevel@tonic-gate } 4940Sstevel@tonic-gate 4950Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BCYL, (unsigned int) 49611091SVirginia.Wray@Sun.COM ((iparts[part_num - 1].begcyl & 0xff) | 49711091SVirginia.Wray@Sun.COM ((iparts[part_num - 1].begsect & 0xc0) << 2))) != 0) { 49811091SVirginia.Wray@Sun.COM return (ENOMEM); 4990Sstevel@tonic-gate } 5000Sstevel@tonic-gate 5010Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_EHEAD, 50211091SVirginia.Wray@Sun.COM (unsigned int)iparts[part_num - 1].endhead) != 0) { 50311091SVirginia.Wray@Sun.COM return (ENOMEM); 5040Sstevel@tonic-gate } 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_ESECT, 50711091SVirginia.Wray@Sun.COM (unsigned int)((iparts[part_num - 1].endsect) & 0x3f)) != 0) { 50811091SVirginia.Wray@Sun.COM return (ENOMEM); 5090Sstevel@tonic-gate } 5100Sstevel@tonic-gate 5110Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_ECYL, (unsigned int) 51211091SVirginia.Wray@Sun.COM ((iparts[part_num - 1].endcyl & 0xff) | 51311091SVirginia.Wray@Sun.COM ((iparts[part_num - 1].endsect & 0xc0) << 2))) != 0) { 51411091SVirginia.Wray@Sun.COM return (ENOMEM); 5150Sstevel@tonic-gate } 5160Sstevel@tonic-gate 5170Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_RELSECT, 51811091SVirginia.Wray@Sun.COM (unsigned int)iparts[part_num - 1].relsect) != 0) { 51911091SVirginia.Wray@Sun.COM return (ENOMEM); 5200Sstevel@tonic-gate } 5210Sstevel@tonic-gate 5220Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_NSECTORS, 52311091SVirginia.Wray@Sun.COM (unsigned int)iparts[part_num - 1].numsect) != 0) { 52411091SVirginia.Wray@Sun.COM return (ENOMEM); 5250Sstevel@tonic-gate } 5260Sstevel@tonic-gate 5270Sstevel@tonic-gate return (0); 5280Sstevel@tonic-gate } 5290Sstevel@tonic-gate 53011091SVirginia.Wray@Sun.COM /* 53111091SVirginia.Wray@Sun.COM * get_parts 53211091SVirginia.Wray@Sun.COM * Discovers the primary, extended, and logical partitions that have 53311091SVirginia.Wray@Sun.COM * been created on a disk. get_parts loops through the partitions, 53411091SVirginia.Wray@Sun.COM * collects the information on each partition and stores it in a 53511091SVirginia.Wray@Sun.COM * partition table. 53611091SVirginia.Wray@Sun.COM * 53711091SVirginia.Wray@Sun.COM * Parameters; 53811091SVirginia.Wray@Sun.COM * disk -The disk device to be evaluated for partitions 53911091SVirginia.Wray@Sun.COM * iparts -The structure that holds information about 54011091SVirginia.Wray@Sun.COM * the partitions 54111091SVirginia.Wray@Sun.COM * opath -The device path 54211091SVirginia.Wray@Sun.COM * opath_len -Buffer size used with opath 54311091SVirginia.Wray@Sun.COM * Returns: 54411091SVirginia.Wray@Sun.COM * 0 on Successful completion 54511091SVirginia.Wray@Sun.COM * Error Value on failure 54611091SVirginia.Wray@Sun.COM * 54711091SVirginia.Wray@Sun.COM */ 5480Sstevel@tonic-gate static int 5490Sstevel@tonic-gate get_parts(disk_t *disk, struct ipart *iparts, char *opath, int opath_len) 5500Sstevel@tonic-gate { 5510Sstevel@tonic-gate int fd; 5520Sstevel@tonic-gate struct dk_minfo minfo; 5530Sstevel@tonic-gate struct mboot bootblk; 5540Sstevel@tonic-gate char bootsect[512]; 5550Sstevel@tonic-gate int i; 5560Sstevel@tonic-gate 55711091SVirginia.Wray@Sun.COM #if defined(i386) || defined(__amd64) 55811091SVirginia.Wray@Sun.COM int j, ret; 55911091SVirginia.Wray@Sun.COM ext_part_t *epp; /* extended partition structure */ 56011091SVirginia.Wray@Sun.COM char *device; /* name of fixed disk drive */ 56111091SVirginia.Wray@Sun.COM size_t len; 56211091SVirginia.Wray@Sun.COM logical_drive_t *log_drv; /* logical drive structure */ 56311091SVirginia.Wray@Sun.COM uint64_t tmpsect; 56411091SVirginia.Wray@Sun.COM #endif 56511091SVirginia.Wray@Sun.COM 5660Sstevel@tonic-gate /* Can't use drive_open_disk since we need the partition dev name. */ 5670Sstevel@tonic-gate if ((fd = open_disk(disk, opath, opath_len)) < 0) { 56811091SVirginia.Wray@Sun.COM return (ENODEV); 5690Sstevel@tonic-gate } 5700Sstevel@tonic-gate 5710Sstevel@tonic-gate /* First make sure media is inserted and spun up. */ 5720Sstevel@tonic-gate if (!media_read_info(fd, &minfo)) { 57311091SVirginia.Wray@Sun.COM (void) close(fd); 57411091SVirginia.Wray@Sun.COM return (ENODEV); 5750Sstevel@tonic-gate } 5760Sstevel@tonic-gate 5770Sstevel@tonic-gate if (!partition_has_fdisk(disk, fd)) { 57811091SVirginia.Wray@Sun.COM (void) close(fd); 57911091SVirginia.Wray@Sun.COM return (ENOTTY); 5800Sstevel@tonic-gate } 5810Sstevel@tonic-gate 5820Sstevel@tonic-gate if (lseek(fd, 0, 0) == -1) { 58311091SVirginia.Wray@Sun.COM (void) close(fd); 58411091SVirginia.Wray@Sun.COM return (ENODEV); 5850Sstevel@tonic-gate } 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate if (read(fd, bootsect, 512) != 512) { 58811091SVirginia.Wray@Sun.COM (void) close(fd); 58911091SVirginia.Wray@Sun.COM return (ENODEV); 5900Sstevel@tonic-gate } 5910Sstevel@tonic-gate (void) close(fd); 5920Sstevel@tonic-gate 5930Sstevel@tonic-gate (void) memcpy(&bootblk, bootsect, sizeof (bootblk)); 5940Sstevel@tonic-gate 5950Sstevel@tonic-gate if (les(bootblk.signature) != MBB_MAGIC) { 59611091SVirginia.Wray@Sun.COM return (ENOTTY); 59711091SVirginia.Wray@Sun.COM } 59811091SVirginia.Wray@Sun.COM 59911091SVirginia.Wray@Sun.COM /* 60011091SVirginia.Wray@Sun.COM * Initialize the memory space to clear unknown garbage 60111091SVirginia.Wray@Sun.COM * that might create confusing results. 60211091SVirginia.Wray@Sun.COM */ 60311091SVirginia.Wray@Sun.COM for (i = 0; i < TOTAL_NUMPART; i++) { 60411098SVirginia.Wray@Sun.COM (void) memset(&iparts[i], 0, sizeof (struct ipart)); 60511091SVirginia.Wray@Sun.COM iparts[i].systid = UNUSED; 6060Sstevel@tonic-gate } 6070Sstevel@tonic-gate 6080Sstevel@tonic-gate (void) memcpy(iparts, bootblk.parts, ISIZE); 6090Sstevel@tonic-gate 61011091SVirginia.Wray@Sun.COM /* 61111091SVirginia.Wray@Sun.COM * Check to see if a valid partition exists. If a valid partition 61211091SVirginia.Wray@Sun.COM * exists, check to see if it is an extended partition. 61311091SVirginia.Wray@Sun.COM * If an extended partition exists, collect the logical partition 61411091SVirginia.Wray@Sun.COM * data. 61511091SVirginia.Wray@Sun.COM */ 6160Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 61711091SVirginia.Wray@Sun.COM if (iparts[i].systid == UNUSED) 61811091SVirginia.Wray@Sun.COM continue; 61911091SVirginia.Wray@Sun.COM 6200Sstevel@tonic-gate iparts[i].relsect = lel(iparts[i].relsect); 6210Sstevel@tonic-gate iparts[i].numsect = lel(iparts[i].numsect); 62211091SVirginia.Wray@Sun.COM 62311091SVirginia.Wray@Sun.COM #if defined(i386) || defined(__amd64) 62411091SVirginia.Wray@Sun.COM if (!fdisk_is_dos_extended(iparts[i].systid)) 62511091SVirginia.Wray@Sun.COM continue; 62611091SVirginia.Wray@Sun.COM 627*11255SVirginia.Wray@Sun.COM len = strlen(disk->aliases->alias) + 1; 62811091SVirginia.Wray@Sun.COM if ((device = malloc(len)) == NULL) { 62911091SVirginia.Wray@Sun.COM if (device) 63011091SVirginia.Wray@Sun.COM free(device); 63111091SVirginia.Wray@Sun.COM continue; 63211091SVirginia.Wray@Sun.COM } 63311091SVirginia.Wray@Sun.COM 634*11255SVirginia.Wray@Sun.COM (void) snprintf(device, len, "%s", disk->aliases->alias); 63511091SVirginia.Wray@Sun.COM 63611091SVirginia.Wray@Sun.COM if ((ret = libfdisk_init(&epp, device, &iparts[i], 63711091SVirginia.Wray@Sun.COM FDISK_READ_DISK)) != FDISK_SUCCESS) { 63811091SVirginia.Wray@Sun.COM 63911091SVirginia.Wray@Sun.COM switch (ret) { 64011091SVirginia.Wray@Sun.COM /* 64111091SVirginia.Wray@Sun.COM * The first 2 error cases indicate that 64211091SVirginia.Wray@Sun.COM * there is no Solaris logical partition, 64311091SVirginia.Wray@Sun.COM * which is a valid condition, 64411091SVirginia.Wray@Sun.COM * so iterating through the disk continues. 64511091SVirginia.Wray@Sun.COM * Any other error cases indicate there is 64611091SVirginia.Wray@Sun.COM * a potential problem with the disk, so 64711091SVirginia.Wray@Sun.COM * don't continue iterating through the disk 64811091SVirginia.Wray@Sun.COM * and return an error. 64911091SVirginia.Wray@Sun.COM */ 65011091SVirginia.Wray@Sun.COM case FDISK_EBADLOGDRIVE: 65111091SVirginia.Wray@Sun.COM case FDISK_ENOLOGDRIVE: 65211091SVirginia.Wray@Sun.COM free(device); 65311246SSharath.Srinivasan@Sun.COM libfdisk_fini(&epp); 65411091SVirginia.Wray@Sun.COM continue; 65511246SSharath.Srinivasan@Sun.COM case FDISK_EBADMAGIC: 65611246SSharath.Srinivasan@Sun.COM free(device); 65711246SSharath.Srinivasan@Sun.COM libfdisk_fini(&epp); 65811246SSharath.Srinivasan@Sun.COM return (ENOTTY); 65911091SVirginia.Wray@Sun.COM default: 66011091SVirginia.Wray@Sun.COM free(device); 66111246SSharath.Srinivasan@Sun.COM libfdisk_fini(&epp); 66211091SVirginia.Wray@Sun.COM return (ENODEV); 66311091SVirginia.Wray@Sun.COM } 66411091SVirginia.Wray@Sun.COM } 66511091SVirginia.Wray@Sun.COM 66611091SVirginia.Wray@Sun.COM /* 66711091SVirginia.Wray@Sun.COM * Collect logical drive information 66811091SVirginia.Wray@Sun.COM */ 66911091SVirginia.Wray@Sun.COM for (log_drv = fdisk_get_ld_head(epp), j = FD_NUMPART, 67011091SVirginia.Wray@Sun.COM tmpsect = 0; (j < TOTAL_NUMPART) && (log_drv != NULL); 67111091SVirginia.Wray@Sun.COM log_drv = log_drv->next, j++) { 67211091SVirginia.Wray@Sun.COM iparts[j].bootid = log_drv->parts[0].bootid; 67311091SVirginia.Wray@Sun.COM iparts[j].beghead = log_drv->parts[0].beghead; 67411091SVirginia.Wray@Sun.COM iparts[j].begsect = log_drv->parts[0].begsect; 67511091SVirginia.Wray@Sun.COM iparts[j].begcyl = log_drv->parts[0].begcyl; 67611091SVirginia.Wray@Sun.COM iparts[j].systid = log_drv->parts[0].systid; 67711091SVirginia.Wray@Sun.COM iparts[j].endhead = log_drv->parts[0].endhead; 67811091SVirginia.Wray@Sun.COM iparts[j].endsect = log_drv->parts[0].endsect; 67911091SVirginia.Wray@Sun.COM iparts[j].endcyl = log_drv->parts[0].endcyl; 68011091SVirginia.Wray@Sun.COM iparts[j].relsect = (tmpsect + 68111091SVirginia.Wray@Sun.COM lel(log_drv->parts[0].relsect) + epp->ext_beg_sec); 68211091SVirginia.Wray@Sun.COM iparts[j].numsect = lel(log_drv->parts[0].numsect); 68311091SVirginia.Wray@Sun.COM tmpsect = lel(log_drv->parts[1].relsect); 68411091SVirginia.Wray@Sun.COM } 68511091SVirginia.Wray@Sun.COM 68611091SVirginia.Wray@Sun.COM /* free the device and the epp memory. */ 68711091SVirginia.Wray@Sun.COM free(device); 68811091SVirginia.Wray@Sun.COM libfdisk_fini(&epp); 68911091SVirginia.Wray@Sun.COM #endif 6900Sstevel@tonic-gate } 6910Sstevel@tonic-gate 6920Sstevel@tonic-gate return (0); 6930Sstevel@tonic-gate } 69411091SVirginia.Wray@Sun.COM 6950Sstevel@tonic-gate /* return 1 if the partition descriptor is still valid, 0 if not. */ 6960Sstevel@tonic-gate static int 6970Sstevel@tonic-gate desc_ok(descriptor_t *dp) 6980Sstevel@tonic-gate { 6990Sstevel@tonic-gate /* First verify the media name for removable media */ 7000Sstevel@tonic-gate if (dp->p.disk->removable) { 70111091SVirginia.Wray@Sun.COM char mname[MAXPATHLEN]; 7020Sstevel@tonic-gate 70311091SVirginia.Wray@Sun.COM if (!media_read_name(dp->p.disk, mname, sizeof (mname))) { 70411091SVirginia.Wray@Sun.COM return (0); 70511091SVirginia.Wray@Sun.COM } 7060Sstevel@tonic-gate 70711091SVirginia.Wray@Sun.COM if (mname[0] == 0) { 70811091SVirginia.Wray@Sun.COM return (libdiskmgt_str_eq(dp->secondary_name, NULL)); 70911091SVirginia.Wray@Sun.COM } else { 71011091SVirginia.Wray@Sun.COM return (libdiskmgt_str_eq(dp->secondary_name, mname)); 71111091SVirginia.Wray@Sun.COM } 7120Sstevel@tonic-gate } 7130Sstevel@tonic-gate 7140Sstevel@tonic-gate /* 7150Sstevel@tonic-gate * We could verify the partition is still there but this is kind of 7160Sstevel@tonic-gate * expensive and other code down the line will do that (e.g. see 7170Sstevel@tonic-gate * get_attrs). 7180Sstevel@tonic-gate */ 7190Sstevel@tonic-gate 7200Sstevel@tonic-gate return (1); 7210Sstevel@tonic-gate } 7220Sstevel@tonic-gate 7230Sstevel@tonic-gate /* 7240Sstevel@tonic-gate * Return 1 if partition has slices, 0 if not. 7250Sstevel@tonic-gate */ 7260Sstevel@tonic-gate static int 7270Sstevel@tonic-gate has_slices(descriptor_t *desc, int *errp) 7280Sstevel@tonic-gate { 7290Sstevel@tonic-gate int pnum; 7300Sstevel@tonic-gate int i; 7310Sstevel@tonic-gate char *p; 73211091SVirginia.Wray@Sun.COM struct ipart iparts[TOTAL_NUMPART]; 7330Sstevel@tonic-gate 7340Sstevel@tonic-gate if (get_parts(desc->p.disk, iparts, NULL, 0) != 0) { 73511091SVirginia.Wray@Sun.COM *errp = ENODEV; 73611091SVirginia.Wray@Sun.COM return (0); 7370Sstevel@tonic-gate } 7380Sstevel@tonic-gate 7390Sstevel@tonic-gate p = strrchr(desc->name, 'p'); 7400Sstevel@tonic-gate if (p == NULL) { 74111091SVirginia.Wray@Sun.COM p = desc->name; 7420Sstevel@tonic-gate } else { 74311091SVirginia.Wray@Sun.COM p++; 7440Sstevel@tonic-gate } 7450Sstevel@tonic-gate pnum = atoi(p); 7460Sstevel@tonic-gate 7470Sstevel@tonic-gate /* 7480Sstevel@tonic-gate * Slices are associated with the active solaris partition or if there 7490Sstevel@tonic-gate * is no active solaris partition, then the first solaris partition. 7500Sstevel@tonic-gate */ 7510Sstevel@tonic-gate 7520Sstevel@tonic-gate *errp = 0; 7530Sstevel@tonic-gate if (iparts[pnum].bootid == ACTIVE && 7540Sstevel@tonic-gate (iparts[pnum].systid == SUNIXOS || 7550Sstevel@tonic-gate iparts[pnum].systid == SUNIXOS2)) { 7560Sstevel@tonic-gate return (1); 7570Sstevel@tonic-gate } else { 75811091SVirginia.Wray@Sun.COM int active = 0; 7590Sstevel@tonic-gate 76011091SVirginia.Wray@Sun.COM /* Check if there are no active solaris partitions. */ 76111091SVirginia.Wray@Sun.COM for (i = 0; i < TOTAL_NUMPART; i++) { 76211091SVirginia.Wray@Sun.COM if (iparts[i].bootid == ACTIVE && 76311091SVirginia.Wray@Sun.COM (iparts[i].systid == SUNIXOS || 76411091SVirginia.Wray@Sun.COM iparts[i].systid == SUNIXOS2)) { 76511091SVirginia.Wray@Sun.COM active = 1; 76611091SVirginia.Wray@Sun.COM break; 76711091SVirginia.Wray@Sun.COM } 7680Sstevel@tonic-gate } 7690Sstevel@tonic-gate 77011091SVirginia.Wray@Sun.COM if (!active) { 77111091SVirginia.Wray@Sun.COM /* Check if this is the first solaris partition. */ 77211091SVirginia.Wray@Sun.COM for (i = 0; i < TOTAL_NUMPART; i++) { 77311091SVirginia.Wray@Sun.COM if (iparts[i].systid == SUNIXOS || 77411091SVirginia.Wray@Sun.COM iparts[i].systid == SUNIXOS2) { 77511091SVirginia.Wray@Sun.COM break; 77611091SVirginia.Wray@Sun.COM } 77711091SVirginia.Wray@Sun.COM } 77811091SVirginia.Wray@Sun.COM 77911091SVirginia.Wray@Sun.COM if (i < TOTAL_NUMPART && i == pnum) { 78011091SVirginia.Wray@Sun.COM return (1); 78111091SVirginia.Wray@Sun.COM } 7820Sstevel@tonic-gate } 7830Sstevel@tonic-gate } 7840Sstevel@tonic-gate 7850Sstevel@tonic-gate return (0); 7860Sstevel@tonic-gate } 7870Sstevel@tonic-gate 7880Sstevel@tonic-gate static int 7890Sstevel@tonic-gate open_disk(disk_t *diskp, char *opath, int len) 7900Sstevel@tonic-gate { 7910Sstevel@tonic-gate /* 7922912Sartem * Just open the first devpath. 7930Sstevel@tonic-gate */ 7940Sstevel@tonic-gate if (diskp->aliases != NULL && diskp->aliases->devpaths != NULL) { 7950Sstevel@tonic-gate #ifdef sparc 79611091SVirginia.Wray@Sun.COM if (opath != NULL) { 7970Sstevel@tonic-gate (void) strlcpy(opath, diskp->aliases->devpaths->devpath, len); 79811091SVirginia.Wray@Sun.COM } 79911091SVirginia.Wray@Sun.COM return (open(diskp->aliases->devpaths->devpath, O_RDONLY|O_NDELAY)); 8000Sstevel@tonic-gate #else 80111091SVirginia.Wray@Sun.COM /* On intel we need to open partition device (e.g. c0d0p1). */ 80211091SVirginia.Wray@Sun.COM char part_dev[MAXPATHLEN]; 80311091SVirginia.Wray@Sun.COM char *p; 8040Sstevel@tonic-gate 80511091SVirginia.Wray@Sun.COM (void) strlcpy(part_dev, diskp->aliases->devpaths->devpath, 80611091SVirginia.Wray@Sun.COM sizeof (part_dev)); 80711091SVirginia.Wray@Sun.COM p = strrchr(part_dev, '/'); 80811091SVirginia.Wray@Sun.COM if (p == NULL) { 8090Sstevel@tonic-gate p = strrchr(part_dev, 's'); 8100Sstevel@tonic-gate if (p != NULL) { 81111091SVirginia.Wray@Sun.COM *p = 'p'; 8120Sstevel@tonic-gate } 81311091SVirginia.Wray@Sun.COM } else { 8140Sstevel@tonic-gate char *ps; 8150Sstevel@tonic-gate 8160Sstevel@tonic-gate *p = 0; 8170Sstevel@tonic-gate ps = strrchr((p + 1), 's'); 8180Sstevel@tonic-gate if (ps != NULL) { 81911091SVirginia.Wray@Sun.COM *ps = 'p'; 8200Sstevel@tonic-gate } 8210Sstevel@tonic-gate *p = '/'; 82211091SVirginia.Wray@Sun.COM } 8230Sstevel@tonic-gate 82411091SVirginia.Wray@Sun.COM if (opath != NULL) { 8250Sstevel@tonic-gate (void) strlcpy(opath, part_dev, len); 82611091SVirginia.Wray@Sun.COM } 82711091SVirginia.Wray@Sun.COM return (open(part_dev, O_RDONLY|O_NDELAY)); 8280Sstevel@tonic-gate #endif 8290Sstevel@tonic-gate } 8300Sstevel@tonic-gate 8310Sstevel@tonic-gate return (-1); 8320Sstevel@tonic-gate } 833