17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
518c2aff7Sartem * Common Development and Distribution License (the "License").
618c2aff7Sartem * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
222174cb7bSVirginia Wray * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <fcntl.h>
277c478bd9Sstevel@tonic-gate #include <libdevinfo.h>
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <string.h>
317c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <sys/stat.h>
347c478bd9Sstevel@tonic-gate #include <dirent.h>
357c478bd9Sstevel@tonic-gate #include <unistd.h>
367c478bd9Sstevel@tonic-gate #include <sys/dkio.h>
377c478bd9Sstevel@tonic-gate
382174cb7bSVirginia Wray #if defined(i386) || defined(__amd64)
392174cb7bSVirginia Wray #include <sys/dktp/fdisk.h>
402174cb7bSVirginia Wray #include <libfdisk.h>
412174cb7bSVirginia Wray #endif
422174cb7bSVirginia Wray
437c478bd9Sstevel@tonic-gate #include "libdiskmgt.h"
447c478bd9Sstevel@tonic-gate #include "disks_private.h"
457c478bd9Sstevel@tonic-gate #include "partition.h"
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate #ifdef sparc
487c478bd9Sstevel@tonic-gate #define les(val) ((((val)&0xFF)<<8)|(((val)>>8)&0xFF))
497c478bd9Sstevel@tonic-gate #define lel(val) (((unsigned)(les((val)&0x0000FFFF))<<16) | \
507c478bd9Sstevel@tonic-gate (les((unsigned)((val)&0xffff0000)>>16)))
517c478bd9Sstevel@tonic-gate #else
527c478bd9Sstevel@tonic-gate #define les(val) (val)
537c478bd9Sstevel@tonic-gate #define lel(val) (val)
547c478bd9Sstevel@tonic-gate #endif
557c478bd9Sstevel@tonic-gate
562174cb7bSVirginia Wray #define TOTAL_NUMPART (FD_NUMPART + MAX_EXT_PARTS)
572174cb7bSVirginia Wray
587c478bd9Sstevel@tonic-gate #define ISIZE FD_NUMPART * sizeof (struct ipart)
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate static int desc_ok(descriptor_t *dp);
617c478bd9Sstevel@tonic-gate static int get_attrs(descriptor_t *dp, struct ipart *iparts,
627c478bd9Sstevel@tonic-gate nvlist_t *attrs);
637c478bd9Sstevel@tonic-gate static int get_parts(disk_t *disk, struct ipart *iparts, char *opath,
647c478bd9Sstevel@tonic-gate int opath_len);
657c478bd9Sstevel@tonic-gate static int open_disk(disk_t *diskp, char *opath, int len);
667c478bd9Sstevel@tonic-gate static int has_slices(descriptor_t *desc, int *errp);
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate descriptor_t **
partition_get_assoc_descriptors(descriptor_t * desc,dm_desc_type_t type,int * errp)697c478bd9Sstevel@tonic-gate partition_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type,
707c478bd9Sstevel@tonic-gate int *errp)
717c478bd9Sstevel@tonic-gate {
727c478bd9Sstevel@tonic-gate if (!desc_ok(desc)) {
732174cb7bSVirginia Wray *errp = ENODEV;
742174cb7bSVirginia Wray return (NULL);
757c478bd9Sstevel@tonic-gate }
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate switch (type) {
787c478bd9Sstevel@tonic-gate case DM_MEDIA:
792174cb7bSVirginia Wray return (media_get_assocs(desc, errp));
807c478bd9Sstevel@tonic-gate case DM_SLICE:
812174cb7bSVirginia Wray if (!has_slices(desc, errp)) {
822174cb7bSVirginia Wray if (*errp != 0) {
832174cb7bSVirginia Wray return (NULL);
842174cb7bSVirginia Wray }
852174cb7bSVirginia Wray return (libdiskmgt_empty_desc_array(errp));
867c478bd9Sstevel@tonic-gate }
872174cb7bSVirginia Wray return (slice_get_assocs(desc, errp));
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate *errp = EINVAL;
917c478bd9Sstevel@tonic-gate return (NULL);
927c478bd9Sstevel@tonic-gate }
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate /*
957c478bd9Sstevel@tonic-gate * This is called by media/slice to get the associated partitions.
967c478bd9Sstevel@tonic-gate * For a media desc. we just get all the partitions, but for a slice desc.
977c478bd9Sstevel@tonic-gate * we just get the active solaris partition.
987c478bd9Sstevel@tonic-gate */
997c478bd9Sstevel@tonic-gate descriptor_t **
partition_get_assocs(descriptor_t * desc,int * errp)1007c478bd9Sstevel@tonic-gate partition_get_assocs(descriptor_t *desc, int *errp)
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate descriptor_t **partitions;
1037c478bd9Sstevel@tonic-gate int pos;
1047c478bd9Sstevel@tonic-gate int i;
1052174cb7bSVirginia Wray struct ipart iparts[TOTAL_NUMPART];
1067c478bd9Sstevel@tonic-gate char pname[MAXPATHLEN];
1077c478bd9Sstevel@tonic-gate int conv_flag = 0;
1083e1bd7a2Ssjelinek #if defined(i386) || defined(__amd64)
1093e1bd7a2Ssjelinek int len;
1103e1bd7a2Ssjelinek #endif
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate if (get_parts(desc->p.disk, iparts, pname, sizeof (pname)) != 0) {
1132174cb7bSVirginia Wray return (libdiskmgt_empty_desc_array(errp));
1147c478bd9Sstevel@tonic-gate }
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate /* allocate the array for the descriptors */
1172174cb7bSVirginia Wray partitions = (descriptor_t **)calloc(TOTAL_NUMPART + 1,
1187c478bd9Sstevel@tonic-gate sizeof (descriptor_t *));
1197c478bd9Sstevel@tonic-gate if (partitions == NULL) {
1202174cb7bSVirginia Wray *errp = ENOMEM;
1212174cb7bSVirginia Wray return (NULL);
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate
1243e1bd7a2Ssjelinek #if defined(i386) || defined(__amd64)
1252174cb7bSVirginia Wray /* convert part. name (e.g. c0d0p1) */
1262174cb7bSVirginia Wray len = strlen(pname);
1272174cb7bSVirginia Wray if (len > 1 && *(pname + (len - 2)) == 'p') {
1287c478bd9Sstevel@tonic-gate conv_flag = 1;
1297c478bd9Sstevel@tonic-gate *(pname + (len - 1)) = 0;
1302174cb7bSVirginia Wray }
1317c478bd9Sstevel@tonic-gate #endif
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate /*
1347c478bd9Sstevel@tonic-gate * If this is a slice desc. we need the first active solaris partition
1357c478bd9Sstevel@tonic-gate * and if there isn't one then we need the first solaris partition.
1367c478bd9Sstevel@tonic-gate */
1377c478bd9Sstevel@tonic-gate if (desc->type == DM_SLICE) {
1382174cb7bSVirginia Wray for (i = 0; i < TOTAL_NUMPART; i++) {
1392174cb7bSVirginia Wray if (iparts[i].bootid == ACTIVE &&
1402174cb7bSVirginia Wray (iparts[i].systid == SUNIXOS ||
1412174cb7bSVirginia Wray iparts[i].systid == SUNIXOS2)) {
1422174cb7bSVirginia Wray break;
1432174cb7bSVirginia Wray }
1447c478bd9Sstevel@tonic-gate }
1452174cb7bSVirginia Wray
1462174cb7bSVirginia Wray /*
1472174cb7bSVirginia Wray * no active solaris part.,*try to get the first solaris part.
1482174cb7bSVirginia Wray */
1492174cb7bSVirginia Wray if (i >= TOTAL_NUMPART) {
1502174cb7bSVirginia Wray for (i = 0; i < TOTAL_NUMPART; i++) {
1512174cb7bSVirginia Wray if (iparts[i].systid == SUNIXOS ||
1522174cb7bSVirginia Wray iparts[i].systid == SUNIXOS2) {
1532174cb7bSVirginia Wray break;
1542174cb7bSVirginia Wray }
1552174cb7bSVirginia Wray }
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate
1582174cb7bSVirginia Wray if (i < TOTAL_NUMPART) {
1597c478bd9Sstevel@tonic-gate /* we found a solaris partition to use */
1602174cb7bSVirginia Wray char part_name[MAXPATHLEN];
1617c478bd9Sstevel@tonic-gate
1622174cb7bSVirginia Wray if (conv_flag) {
1632174cb7bSVirginia Wray /* convert part. name (e.g. c0d0p1) */
1642174cb7bSVirginia Wray (void) snprintf(part_name, sizeof (part_name),
1652174cb7bSVirginia Wray "%s%d", pname, i+1);
1662174cb7bSVirginia Wray } else {
1672174cb7bSVirginia Wray (void) snprintf(part_name, sizeof (part_name),
1682174cb7bSVirginia Wray "%d", i+1);
1692174cb7bSVirginia Wray }
1707c478bd9Sstevel@tonic-gate
1712174cb7bSVirginia Wray /* the media name comes from the slice desc. */
1722174cb7bSVirginia Wray partitions[0] = cache_get_desc(DM_PARTITION,
1732174cb7bSVirginia Wray desc->p.disk, part_name, desc->secondary_name,
1742174cb7bSVirginia Wray errp);
1752174cb7bSVirginia Wray if (*errp != 0) {
1762174cb7bSVirginia Wray cache_free_descriptors(partitions);
1772174cb7bSVirginia Wray return (NULL);
1782174cb7bSVirginia Wray }
1792174cb7bSVirginia Wray partitions[1] = NULL;
1807c478bd9Sstevel@tonic-gate
1812174cb7bSVirginia Wray return (partitions);
1822174cb7bSVirginia Wray }
1837c478bd9Sstevel@tonic-gate
1842174cb7bSVirginia Wray return (libdiskmgt_empty_desc_array(errp));
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate /* Must be for media, so get all the parts. */
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gate pos = 0;
1902174cb7bSVirginia Wray for (i = 0; i < TOTAL_NUMPART; i++) {
1912174cb7bSVirginia Wray if (iparts[i].systid != UNUSED) {
1922174cb7bSVirginia Wray char part_name[MAXPATHLEN];
1937c478bd9Sstevel@tonic-gate
1942174cb7bSVirginia Wray /*
1952174cb7bSVirginia Wray * Process the descriptors and modify the cxdxpx
1962174cb7bSVirginia Wray * format so that it refers to the fdisk partition
1972174cb7bSVirginia Wray * number and not to the physical disk. This is
1982174cb7bSVirginia Wray * achieved by i+1, where i is the number of the
1992174cb7bSVirginia Wray * physical disk partition.
2002174cb7bSVirginia Wray */
2012174cb7bSVirginia Wray if (conv_flag) {
2022174cb7bSVirginia Wray /* convert part. name (e.g. c0d0p1) */
2032174cb7bSVirginia Wray (void) snprintf(part_name, sizeof (part_name),
2042174cb7bSVirginia Wray "%s%d", pname, i+1);
2052174cb7bSVirginia Wray } else {
2062174cb7bSVirginia Wray (void) snprintf(part_name, sizeof (part_name),
2072174cb7bSVirginia Wray "%d", i+1);
2082174cb7bSVirginia Wray }
2097c478bd9Sstevel@tonic-gate
2102174cb7bSVirginia Wray /* the media name comes from the media desc. */
2112174cb7bSVirginia Wray partitions[pos] = cache_get_desc(DM_PARTITION,
2122174cb7bSVirginia Wray desc->p.disk, part_name, desc->name, errp);
2132174cb7bSVirginia Wray if (*errp != 0) {
2142174cb7bSVirginia Wray cache_free_descriptors(partitions);
2152174cb7bSVirginia Wray return (NULL);
2162174cb7bSVirginia Wray }
2177c478bd9Sstevel@tonic-gate
2182174cb7bSVirginia Wray pos++;
2192174cb7bSVirginia Wray }
2207c478bd9Sstevel@tonic-gate }
2217c478bd9Sstevel@tonic-gate partitions[pos] = NULL;
2227c478bd9Sstevel@tonic-gate
2237c478bd9Sstevel@tonic-gate *errp = 0;
2247c478bd9Sstevel@tonic-gate return (partitions);
2257c478bd9Sstevel@tonic-gate }
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate nvlist_t *
partition_get_attributes(descriptor_t * dp,int * errp)2287c478bd9Sstevel@tonic-gate partition_get_attributes(descriptor_t *dp, int *errp)
2297c478bd9Sstevel@tonic-gate {
2307c478bd9Sstevel@tonic-gate nvlist_t *attrs = NULL;
2312174cb7bSVirginia Wray struct ipart iparts[TOTAL_NUMPART];
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate if (!desc_ok(dp)) {
2342174cb7bSVirginia Wray *errp = ENODEV;
2352174cb7bSVirginia Wray return (NULL);
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate if ((*errp = get_parts(dp->p.disk, iparts, NULL, 0)) != 0) {
2392174cb7bSVirginia Wray return (NULL);
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate
2427c478bd9Sstevel@tonic-gate if (nvlist_alloc(&attrs, NVATTRS, 0) != 0) {
2432174cb7bSVirginia Wray *errp = ENOMEM;
2442174cb7bSVirginia Wray return (NULL);
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate if ((*errp = get_attrs(dp, iparts, attrs)) != 0) {
2482174cb7bSVirginia Wray nvlist_free(attrs);
2492174cb7bSVirginia Wray attrs = NULL;
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate return (attrs);
2537c478bd9Sstevel@tonic-gate }
2547c478bd9Sstevel@tonic-gate
2557c478bd9Sstevel@tonic-gate /*
2567c478bd9Sstevel@tonic-gate * Look for the partition by the partition number (which is not too useful).
2577c478bd9Sstevel@tonic-gate */
2587c478bd9Sstevel@tonic-gate descriptor_t *
partition_get_descriptor_by_name(char * name,int * errp)2597c478bd9Sstevel@tonic-gate partition_get_descriptor_by_name(char *name, int *errp)
2607c478bd9Sstevel@tonic-gate {
2617c478bd9Sstevel@tonic-gate descriptor_t **partitions;
2627c478bd9Sstevel@tonic-gate int i;
2637c478bd9Sstevel@tonic-gate descriptor_t *partition = NULL;
2647c478bd9Sstevel@tonic-gate
2657c478bd9Sstevel@tonic-gate partitions = cache_get_descriptors(DM_PARTITION, errp);
2667c478bd9Sstevel@tonic-gate if (*errp != 0) {
2672174cb7bSVirginia Wray return (NULL);
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate
2707c478bd9Sstevel@tonic-gate for (i = 0; partitions[i]; i++) {
2712174cb7bSVirginia Wray if (libdiskmgt_str_eq(name, partitions[i]->name)) {
2722174cb7bSVirginia Wray partition = partitions[i];
2732174cb7bSVirginia Wray } else {
2742174cb7bSVirginia Wray /* clean up the unused descriptors */
2752174cb7bSVirginia Wray cache_free_descriptor(partitions[i]);
2762174cb7bSVirginia Wray }
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate free(partitions);
2797c478bd9Sstevel@tonic-gate
2807c478bd9Sstevel@tonic-gate if (partition == NULL) {
2812174cb7bSVirginia Wray *errp = ENODEV;
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate return (partition);
2857c478bd9Sstevel@tonic-gate }
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate /* ARGSUSED */
2887c478bd9Sstevel@tonic-gate descriptor_t **
partition_get_descriptors(int filter[],int * errp)2897c478bd9Sstevel@tonic-gate partition_get_descriptors(int filter[], int *errp)
2907c478bd9Sstevel@tonic-gate {
2917c478bd9Sstevel@tonic-gate return (cache_get_descriptors(DM_PARTITION, errp));
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate
2947c478bd9Sstevel@tonic-gate char *
partition_get_name(descriptor_t * desc)2957c478bd9Sstevel@tonic-gate partition_get_name(descriptor_t *desc)
2967c478bd9Sstevel@tonic-gate {
2977c478bd9Sstevel@tonic-gate return (desc->name);
2987c478bd9Sstevel@tonic-gate }
2997c478bd9Sstevel@tonic-gate
3007c478bd9Sstevel@tonic-gate /* ARGSUSED */
3017c478bd9Sstevel@tonic-gate nvlist_t *
partition_get_stats(descriptor_t * dp,int stat_type,int * errp)3027c478bd9Sstevel@tonic-gate partition_get_stats(descriptor_t *dp, int stat_type, int *errp)
3037c478bd9Sstevel@tonic-gate {
3047c478bd9Sstevel@tonic-gate /* There are no stat types defined for partitions */
3057c478bd9Sstevel@tonic-gate *errp = EINVAL;
3067c478bd9Sstevel@tonic-gate return (NULL);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate /* ARGSUSED */
3107c478bd9Sstevel@tonic-gate int
partition_has_fdisk(disk_t * dp,int fd)3117c478bd9Sstevel@tonic-gate partition_has_fdisk(disk_t *dp, int fd)
3127c478bd9Sstevel@tonic-gate {
3137c478bd9Sstevel@tonic-gate char bootsect[512 * 3]; /* 3 sectors to be safe */
3147c478bd9Sstevel@tonic-gate
3157c478bd9Sstevel@tonic-gate #ifdef sparc
3167c478bd9Sstevel@tonic-gate if (dp->drv_type == DM_DT_FIXED) {
3172174cb7bSVirginia Wray /* on sparc, only removable media can have fdisk parts. */
3182174cb7bSVirginia Wray return (0);
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate #endif
3217c478bd9Sstevel@tonic-gate
3227c478bd9Sstevel@tonic-gate /*
3237c478bd9Sstevel@tonic-gate * We assume the caller already made sure media was inserted and
3247c478bd9Sstevel@tonic-gate * spun up.
3257c478bd9Sstevel@tonic-gate */
3267c478bd9Sstevel@tonic-gate
3277c478bd9Sstevel@tonic-gate if ((ioctl(fd, DKIOCGMBOOT, bootsect) < 0) && (errno != ENOTTY)) {
3282174cb7bSVirginia Wray return (0);
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate
3317c478bd9Sstevel@tonic-gate return (1);
3327c478bd9Sstevel@tonic-gate }
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate /*
3352174cb7bSVirginia Wray * partition_make_descriptors
3362174cb7bSVirginia Wray *
3377c478bd9Sstevel@tonic-gate * A partition descriptor points to a disk, the name is the partition number
3382174cb7bSVirginia Wray * and the secondary name is the media name. The iparts parameter returned
3392174cb7bSVirginia Wray * by the get_parts function contains the structures of all of the identified
3402174cb7bSVirginia Wray * partitions found on each disk on a system. These are processed into an array
3412174cb7bSVirginia Wray * of descriptors. A descriptor contains all of the information about a
3422174cb7bSVirginia Wray * specific partition.
3432174cb7bSVirginia Wray *
3442174cb7bSVirginia Wray * Parameters: none
3452174cb7bSVirginia Wray *
3462174cb7bSVirginia Wray * Returns: 0 on success
3472174cb7bSVirginia Wray * Error value on failure
3482174cb7bSVirginia Wray *
3497c478bd9Sstevel@tonic-gate */
3502174cb7bSVirginia Wray
3517c478bd9Sstevel@tonic-gate int
partition_make_descriptors()3527c478bd9Sstevel@tonic-gate partition_make_descriptors()
3537c478bd9Sstevel@tonic-gate {
3547c478bd9Sstevel@tonic-gate int error;
3557c478bd9Sstevel@tonic-gate disk_t *dp;
3567c478bd9Sstevel@tonic-gate
3577c478bd9Sstevel@tonic-gate dp = cache_get_disklist();
3587c478bd9Sstevel@tonic-gate while (dp != NULL) {
3592174cb7bSVirginia Wray struct ipart iparts[TOTAL_NUMPART];
3602174cb7bSVirginia Wray char pname[MAXPATHLEN];
3617c478bd9Sstevel@tonic-gate
3622174cb7bSVirginia Wray if (get_parts(dp, iparts, pname, sizeof (pname)) == 0) {
3632174cb7bSVirginia Wray int i;
3642174cb7bSVirginia Wray char mname[MAXPATHLEN];
3652174cb7bSVirginia Wray int conv_flag = 0;
3663e1bd7a2Ssjelinek #if defined(i386) || defined(__amd64)
3672174cb7bSVirginia Wray /* convert part. name (e.g. c0d0p1) */
3682174cb7bSVirginia Wray int len;
3697c478bd9Sstevel@tonic-gate
3702174cb7bSVirginia Wray len = strlen(pname);
3712174cb7bSVirginia Wray if (len > 1 && *(pname + (len - 2)) == 'p') {
3722174cb7bSVirginia Wray conv_flag = 1;
3732174cb7bSVirginia Wray *(pname + (len - 1)) = 0;
3747c478bd9Sstevel@tonic-gate }
3752174cb7bSVirginia Wray #endif
3767c478bd9Sstevel@tonic-gate
3772174cb7bSVirginia Wray mname[0] = 0;
3782174cb7bSVirginia Wray (void) media_read_name(dp, mname, sizeof (mname));
3792174cb7bSVirginia Wray
3802174cb7bSVirginia Wray /*
3812174cb7bSVirginia Wray * Process the descriptors and modify the cxdxpx
3822174cb7bSVirginia Wray * format so that it refers to the fdisk partition
3832174cb7bSVirginia Wray * number and not to the physical disk. This is
3842174cb7bSVirginia Wray * achieved by i+1, where i is the number of the
3852174cb7bSVirginia Wray * physical disk partition.
3862174cb7bSVirginia Wray */
3872174cb7bSVirginia Wray for (i = 0; i < TOTAL_NUMPART; i++) {
3882174cb7bSVirginia Wray if (iparts[i].systid != UNUSED) {
3892174cb7bSVirginia Wray char part_name[MAXPATHLEN];
3902174cb7bSVirginia Wray
3912174cb7bSVirginia Wray if (conv_flag) {
3922174cb7bSVirginia Wray /*
3932174cb7bSVirginia Wray * convert partition name
3942174cb7bSVirginia Wray * (e.g. c0d0p1)
3952174cb7bSVirginia Wray */
3962174cb7bSVirginia Wray (void) snprintf(part_name,
3972174cb7bSVirginia Wray sizeof (part_name),
3982174cb7bSVirginia Wray "%s%d", pname, i+1);
3992174cb7bSVirginia Wray } else {
4002174cb7bSVirginia Wray (void) snprintf(part_name,
4012174cb7bSVirginia Wray sizeof (part_name),
4022174cb7bSVirginia Wray "%d", i+1);
4032174cb7bSVirginia Wray }
4042174cb7bSVirginia Wray
4052174cb7bSVirginia Wray cache_load_desc(DM_PARTITION, dp,
4062174cb7bSVirginia Wray part_name, mname, &error);
4072174cb7bSVirginia Wray if (error != 0) {
4082174cb7bSVirginia Wray return (error);
4092174cb7bSVirginia Wray }
4102174cb7bSVirginia Wray }
4117c478bd9Sstevel@tonic-gate }
4127c478bd9Sstevel@tonic-gate }
4132174cb7bSVirginia Wray dp = dp->next;
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate
4167c478bd9Sstevel@tonic-gate return (0);
4177c478bd9Sstevel@tonic-gate }
4187c478bd9Sstevel@tonic-gate
4197c478bd9Sstevel@tonic-gate static int
get_attrs(descriptor_t * dp,struct ipart * iparts,nvlist_t * attrs)4207c478bd9Sstevel@tonic-gate get_attrs(descriptor_t *dp, struct ipart *iparts, nvlist_t *attrs)
4217c478bd9Sstevel@tonic-gate {
4227c478bd9Sstevel@tonic-gate char *p;
4237c478bd9Sstevel@tonic-gate int part_num;
4247c478bd9Sstevel@tonic-gate
4257c478bd9Sstevel@tonic-gate /*
4267c478bd9Sstevel@tonic-gate * We already made sure the media was loaded and ready in the
4277c478bd9Sstevel@tonic-gate * get_parts call within partition_get_attributes.
4287c478bd9Sstevel@tonic-gate */
4297c478bd9Sstevel@tonic-gate
4307c478bd9Sstevel@tonic-gate p = strrchr(dp->name, 'p');
4317c478bd9Sstevel@tonic-gate if (p == NULL) {
4322174cb7bSVirginia Wray p = dp->name;
4337c478bd9Sstevel@tonic-gate } else {
4342174cb7bSVirginia Wray p++;
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate part_num = atoi(p);
4372174cb7bSVirginia Wray if (part_num > TOTAL_NUMPART ||
4382174cb7bSVirginia Wray iparts[part_num - 1].systid == UNUSED) {
4392174cb7bSVirginia Wray return (ENODEV);
4407c478bd9Sstevel@tonic-gate }
4417c478bd9Sstevel@tonic-gate
4422174cb7bSVirginia Wray /*
4432174cb7bSVirginia Wray * A partition has been found. Determine what type of
4442174cb7bSVirginia Wray * partition it is: logical, extended, or primary.
4452174cb7bSVirginia Wray * Collect the information for the partition.
4462174cb7bSVirginia Wray */
4472174cb7bSVirginia Wray #if defined(i386) || defined(__amd64)
4482174cb7bSVirginia Wray if (part_num > FD_NUMPART) {
4492174cb7bSVirginia Wray if (nvlist_add_uint32(attrs, DM_PARTITION_TYPE,
4502174cb7bSVirginia Wray DM_LOGICAL) != 0) {
4512174cb7bSVirginia Wray return (ENOMEM);
4522174cb7bSVirginia Wray }
4532174cb7bSVirginia Wray } else if (fdisk_is_dos_extended(iparts[part_num - 1].systid)) {
4542174cb7bSVirginia Wray if (nvlist_add_uint32(attrs, DM_PARTITION_TYPE,
4552174cb7bSVirginia Wray DM_EXTENDED) != 0) {
4562174cb7bSVirginia Wray return (ENOMEM);
4572174cb7bSVirginia Wray }
4582174cb7bSVirginia Wray
4592174cb7bSVirginia Wray } else {
4602174cb7bSVirginia Wray if (nvlist_add_uint32(attrs, DM_PARTITION_TYPE,
4612174cb7bSVirginia Wray DM_PRIMARY) != 0) {
4622174cb7bSVirginia Wray return (ENOMEM);
4632174cb7bSVirginia Wray }
4642174cb7bSVirginia Wray }
4652174cb7bSVirginia Wray #endif
4662174cb7bSVirginia Wray
4672174cb7bSVirginia Wray #ifdef sparc
4682174cb7bSVirginia Wray if (nvlist_add_uint32(attrs, DM_PARTITION_TYPE,
4692174cb7bSVirginia Wray DM_PRIMARY) != 0) {
4702174cb7bSVirginia Wray return (ENOMEM);
4712174cb7bSVirginia Wray }
4722174cb7bSVirginia Wray #endif
4732174cb7bSVirginia Wray
4747c478bd9Sstevel@tonic-gate
4757c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BOOTID,
4762174cb7bSVirginia Wray (unsigned int)iparts[part_num - 1].bootid) != 0) {
4772174cb7bSVirginia Wray return (ENOMEM);
4787c478bd9Sstevel@tonic-gate }
4797c478bd9Sstevel@tonic-gate
4807c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_PTYPE,
4812174cb7bSVirginia Wray (unsigned int)iparts[part_num - 1].systid) != 0) {
4822174cb7bSVirginia Wray return (ENOMEM);
4837c478bd9Sstevel@tonic-gate }
4847c478bd9Sstevel@tonic-gate
4857c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BHEAD,
4862174cb7bSVirginia Wray (unsigned int)iparts[part_num - 1].beghead) != 0) {
4872174cb7bSVirginia Wray return (ENOMEM);
4887c478bd9Sstevel@tonic-gate }
4897c478bd9Sstevel@tonic-gate
4907c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BSECT,
4912174cb7bSVirginia Wray (unsigned int)((iparts[part_num - 1].begsect) & 0x3f)) != 0) {
4922174cb7bSVirginia Wray return (ENOMEM);
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate
4957c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_BCYL, (unsigned int)
4962174cb7bSVirginia Wray ((iparts[part_num - 1].begcyl & 0xff) |
4972174cb7bSVirginia Wray ((iparts[part_num - 1].begsect & 0xc0) << 2))) != 0) {
4982174cb7bSVirginia Wray return (ENOMEM);
4997c478bd9Sstevel@tonic-gate }
5007c478bd9Sstevel@tonic-gate
5017c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_EHEAD,
5022174cb7bSVirginia Wray (unsigned int)iparts[part_num - 1].endhead) != 0) {
5032174cb7bSVirginia Wray return (ENOMEM);
5047c478bd9Sstevel@tonic-gate }
5057c478bd9Sstevel@tonic-gate
5067c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_ESECT,
5072174cb7bSVirginia Wray (unsigned int)((iparts[part_num - 1].endsect) & 0x3f)) != 0) {
5082174cb7bSVirginia Wray return (ENOMEM);
5097c478bd9Sstevel@tonic-gate }
5107c478bd9Sstevel@tonic-gate
5117c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_ECYL, (unsigned int)
5122174cb7bSVirginia Wray ((iparts[part_num - 1].endcyl & 0xff) |
5132174cb7bSVirginia Wray ((iparts[part_num - 1].endsect & 0xc0) << 2))) != 0) {
5142174cb7bSVirginia Wray return (ENOMEM);
5157c478bd9Sstevel@tonic-gate }
5167c478bd9Sstevel@tonic-gate
5177c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_RELSECT,
5182174cb7bSVirginia Wray (unsigned int)iparts[part_num - 1].relsect) != 0) {
5192174cb7bSVirginia Wray return (ENOMEM);
5207c478bd9Sstevel@tonic-gate }
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gate if (nvlist_add_uint32(attrs, DM_NSECTORS,
5232174cb7bSVirginia Wray (unsigned int)iparts[part_num - 1].numsect) != 0) {
5242174cb7bSVirginia Wray return (ENOMEM);
5257c478bd9Sstevel@tonic-gate }
5267c478bd9Sstevel@tonic-gate
5277c478bd9Sstevel@tonic-gate return (0);
5287c478bd9Sstevel@tonic-gate }
5297c478bd9Sstevel@tonic-gate
5302174cb7bSVirginia Wray /*
5312174cb7bSVirginia Wray * get_parts
5322174cb7bSVirginia Wray * Discovers the primary, extended, and logical partitions that have
5332174cb7bSVirginia Wray * been created on a disk. get_parts loops through the partitions,
5342174cb7bSVirginia Wray * collects the information on each partition and stores it in a
5352174cb7bSVirginia Wray * partition table.
5362174cb7bSVirginia Wray *
5372174cb7bSVirginia Wray * Parameters;
5382174cb7bSVirginia Wray * disk -The disk device to be evaluated for partitions
5392174cb7bSVirginia Wray * iparts -The structure that holds information about
5402174cb7bSVirginia Wray * the partitions
5412174cb7bSVirginia Wray * opath -The device path
5422174cb7bSVirginia Wray * opath_len -Buffer size used with opath
5432174cb7bSVirginia Wray * Returns:
5442174cb7bSVirginia Wray * 0 on Successful completion
5452174cb7bSVirginia Wray * Error Value on failure
5462174cb7bSVirginia Wray *
5472174cb7bSVirginia Wray */
5487c478bd9Sstevel@tonic-gate static int
get_parts(disk_t * disk,struct ipart * iparts,char * opath,int opath_len)5497c478bd9Sstevel@tonic-gate get_parts(disk_t *disk, struct ipart *iparts, char *opath, int opath_len)
5507c478bd9Sstevel@tonic-gate {
5517c478bd9Sstevel@tonic-gate int fd;
5527c478bd9Sstevel@tonic-gate struct dk_minfo minfo;
5537c478bd9Sstevel@tonic-gate struct mboot bootblk;
5547c478bd9Sstevel@tonic-gate char bootsect[512];
5557c478bd9Sstevel@tonic-gate int i;
5567c478bd9Sstevel@tonic-gate
5572174cb7bSVirginia Wray #if defined(i386) || defined(__amd64)
5582174cb7bSVirginia Wray int j, ret;
5592174cb7bSVirginia Wray ext_part_t *epp; /* extended partition structure */
5602174cb7bSVirginia Wray char *device; /* name of fixed disk drive */
5612174cb7bSVirginia Wray size_t len;
5622174cb7bSVirginia Wray logical_drive_t *log_drv; /* logical drive structure */
5632174cb7bSVirginia Wray uint64_t tmpsect;
5642174cb7bSVirginia Wray #endif
5652174cb7bSVirginia Wray
5667c478bd9Sstevel@tonic-gate /* Can't use drive_open_disk since we need the partition dev name. */
5677c478bd9Sstevel@tonic-gate if ((fd = open_disk(disk, opath, opath_len)) < 0) {
5682174cb7bSVirginia Wray return (ENODEV);
5697c478bd9Sstevel@tonic-gate }
5707c478bd9Sstevel@tonic-gate
5717c478bd9Sstevel@tonic-gate /* First make sure media is inserted and spun up. */
5727c478bd9Sstevel@tonic-gate if (!media_read_info(fd, &minfo)) {
5732174cb7bSVirginia Wray (void) close(fd);
5742174cb7bSVirginia Wray return (ENODEV);
5757c478bd9Sstevel@tonic-gate }
5767c478bd9Sstevel@tonic-gate
5777c478bd9Sstevel@tonic-gate if (!partition_has_fdisk(disk, fd)) {
5782174cb7bSVirginia Wray (void) close(fd);
5792174cb7bSVirginia Wray return (ENOTTY);
5807c478bd9Sstevel@tonic-gate }
5817c478bd9Sstevel@tonic-gate
5827c478bd9Sstevel@tonic-gate if (lseek(fd, 0, 0) == -1) {
5832174cb7bSVirginia Wray (void) close(fd);
5842174cb7bSVirginia Wray return (ENODEV);
5857c478bd9Sstevel@tonic-gate }
5867c478bd9Sstevel@tonic-gate
5877c478bd9Sstevel@tonic-gate if (read(fd, bootsect, 512) != 512) {
5882174cb7bSVirginia Wray (void) close(fd);
5892174cb7bSVirginia Wray return (ENODEV);
5907c478bd9Sstevel@tonic-gate }
5917c478bd9Sstevel@tonic-gate (void) close(fd);
5927c478bd9Sstevel@tonic-gate
5937c478bd9Sstevel@tonic-gate (void) memcpy(&bootblk, bootsect, sizeof (bootblk));
5947c478bd9Sstevel@tonic-gate
5957c478bd9Sstevel@tonic-gate if (les(bootblk.signature) != MBB_MAGIC) {
5962174cb7bSVirginia Wray return (ENOTTY);
5972174cb7bSVirginia Wray }
5982174cb7bSVirginia Wray
5992174cb7bSVirginia Wray /*
6002174cb7bSVirginia Wray * Initialize the memory space to clear unknown garbage
6012174cb7bSVirginia Wray * that might create confusing results.
6022174cb7bSVirginia Wray */
6032174cb7bSVirginia Wray for (i = 0; i < TOTAL_NUMPART; i++) {
604e4dd1ad6SVirginia Wray (void) memset(&iparts[i], 0, sizeof (struct ipart));
6052174cb7bSVirginia Wray iparts[i].systid = UNUSED;
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate (void) memcpy(iparts, bootblk.parts, ISIZE);
6097c478bd9Sstevel@tonic-gate
6102174cb7bSVirginia Wray /*
6112174cb7bSVirginia Wray * Check to see if a valid partition exists. If a valid partition
6122174cb7bSVirginia Wray * exists, check to see if it is an extended partition.
6132174cb7bSVirginia Wray * If an extended partition exists, collect the logical partition
6142174cb7bSVirginia Wray * data.
6152174cb7bSVirginia Wray */
6167c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) {
6172174cb7bSVirginia Wray if (iparts[i].systid == UNUSED)
6182174cb7bSVirginia Wray continue;
6192174cb7bSVirginia Wray
6207c478bd9Sstevel@tonic-gate iparts[i].relsect = lel(iparts[i].relsect);
6217c478bd9Sstevel@tonic-gate iparts[i].numsect = lel(iparts[i].numsect);
6222174cb7bSVirginia Wray
6232174cb7bSVirginia Wray #if defined(i386) || defined(__amd64)
6242174cb7bSVirginia Wray if (!fdisk_is_dos_extended(iparts[i].systid))
6252174cb7bSVirginia Wray continue;
6262174cb7bSVirginia Wray
627*389cd695SVirginia Wray len = strlen(disk->aliases->alias) + 1;
6282174cb7bSVirginia Wray if ((device = malloc(len)) == NULL) {
6292174cb7bSVirginia Wray if (device)
6302174cb7bSVirginia Wray free(device);
6312174cb7bSVirginia Wray continue;
6322174cb7bSVirginia Wray }
6332174cb7bSVirginia Wray
634*389cd695SVirginia Wray (void) snprintf(device, len, "%s", disk->aliases->alias);
6352174cb7bSVirginia Wray
6362174cb7bSVirginia Wray if ((ret = libfdisk_init(&epp, device, &iparts[i],
6372174cb7bSVirginia Wray FDISK_READ_DISK)) != FDISK_SUCCESS) {
6382174cb7bSVirginia Wray
6392174cb7bSVirginia Wray switch (ret) {
6402174cb7bSVirginia Wray /*
6412174cb7bSVirginia Wray * The first 2 error cases indicate that
6422174cb7bSVirginia Wray * there is no Solaris logical partition,
6432174cb7bSVirginia Wray * which is a valid condition,
6442174cb7bSVirginia Wray * so iterating through the disk continues.
6452174cb7bSVirginia Wray * Any other error cases indicate there is
6462174cb7bSVirginia Wray * a potential problem with the disk, so
6472174cb7bSVirginia Wray * don't continue iterating through the disk
6482174cb7bSVirginia Wray * and return an error.
6492174cb7bSVirginia Wray */
6502174cb7bSVirginia Wray case FDISK_EBADLOGDRIVE:
6512174cb7bSVirginia Wray case FDISK_ENOLOGDRIVE:
6522174cb7bSVirginia Wray free(device);
6536cb5747bSSharath M Srinivasan libfdisk_fini(&epp);
6542174cb7bSVirginia Wray continue;
6556cb5747bSSharath M Srinivasan case FDISK_EBADMAGIC:
6566cb5747bSSharath M Srinivasan free(device);
6576cb5747bSSharath M Srinivasan libfdisk_fini(&epp);
6586cb5747bSSharath M Srinivasan return (ENOTTY);
6592174cb7bSVirginia Wray default:
6602174cb7bSVirginia Wray free(device);
6616cb5747bSSharath M Srinivasan libfdisk_fini(&epp);
6622174cb7bSVirginia Wray return (ENODEV);
6632174cb7bSVirginia Wray }
6642174cb7bSVirginia Wray }
6652174cb7bSVirginia Wray
6662174cb7bSVirginia Wray /*
6672174cb7bSVirginia Wray * Collect logical drive information
6682174cb7bSVirginia Wray */
6692174cb7bSVirginia Wray for (log_drv = fdisk_get_ld_head(epp), j = FD_NUMPART,
6702174cb7bSVirginia Wray tmpsect = 0; (j < TOTAL_NUMPART) && (log_drv != NULL);
6712174cb7bSVirginia Wray log_drv = log_drv->next, j++) {
6722174cb7bSVirginia Wray iparts[j].bootid = log_drv->parts[0].bootid;
6732174cb7bSVirginia Wray iparts[j].beghead = log_drv->parts[0].beghead;
6742174cb7bSVirginia Wray iparts[j].begsect = log_drv->parts[0].begsect;
6752174cb7bSVirginia Wray iparts[j].begcyl = log_drv->parts[0].begcyl;
6762174cb7bSVirginia Wray iparts[j].systid = log_drv->parts[0].systid;
6772174cb7bSVirginia Wray iparts[j].endhead = log_drv->parts[0].endhead;
6782174cb7bSVirginia Wray iparts[j].endsect = log_drv->parts[0].endsect;
6792174cb7bSVirginia Wray iparts[j].endcyl = log_drv->parts[0].endcyl;
6802174cb7bSVirginia Wray iparts[j].relsect = (tmpsect +
6812174cb7bSVirginia Wray lel(log_drv->parts[0].relsect) + epp->ext_beg_sec);
6822174cb7bSVirginia Wray iparts[j].numsect = lel(log_drv->parts[0].numsect);
6832174cb7bSVirginia Wray tmpsect = lel(log_drv->parts[1].relsect);
6842174cb7bSVirginia Wray }
6852174cb7bSVirginia Wray
6862174cb7bSVirginia Wray /* free the device and the epp memory. */
6872174cb7bSVirginia Wray free(device);
6882174cb7bSVirginia Wray libfdisk_fini(&epp);
6892174cb7bSVirginia Wray #endif
6907c478bd9Sstevel@tonic-gate }
6917c478bd9Sstevel@tonic-gate
6927c478bd9Sstevel@tonic-gate return (0);
6937c478bd9Sstevel@tonic-gate }
6942174cb7bSVirginia Wray
6957c478bd9Sstevel@tonic-gate /* return 1 if the partition descriptor is still valid, 0 if not. */
6967c478bd9Sstevel@tonic-gate static int
desc_ok(descriptor_t * dp)6977c478bd9Sstevel@tonic-gate desc_ok(descriptor_t *dp)
6987c478bd9Sstevel@tonic-gate {
6997c478bd9Sstevel@tonic-gate /* First verify the media name for removable media */
7007c478bd9Sstevel@tonic-gate if (dp->p.disk->removable) {
7012174cb7bSVirginia Wray char mname[MAXPATHLEN];
7027c478bd9Sstevel@tonic-gate
7032174cb7bSVirginia Wray if (!media_read_name(dp->p.disk, mname, sizeof (mname))) {
7042174cb7bSVirginia Wray return (0);
7052174cb7bSVirginia Wray }
7067c478bd9Sstevel@tonic-gate
7072174cb7bSVirginia Wray if (mname[0] == 0) {
7082174cb7bSVirginia Wray return (libdiskmgt_str_eq(dp->secondary_name, NULL));
7092174cb7bSVirginia Wray } else {
7102174cb7bSVirginia Wray return (libdiskmgt_str_eq(dp->secondary_name, mname));
7112174cb7bSVirginia Wray }
7127c478bd9Sstevel@tonic-gate }
7137c478bd9Sstevel@tonic-gate
7147c478bd9Sstevel@tonic-gate /*
7157c478bd9Sstevel@tonic-gate * We could verify the partition is still there but this is kind of
7167c478bd9Sstevel@tonic-gate * expensive and other code down the line will do that (e.g. see
7177c478bd9Sstevel@tonic-gate * get_attrs).
7187c478bd9Sstevel@tonic-gate */
7197c478bd9Sstevel@tonic-gate
7207c478bd9Sstevel@tonic-gate return (1);
7217c478bd9Sstevel@tonic-gate }
7227c478bd9Sstevel@tonic-gate
7237c478bd9Sstevel@tonic-gate /*
7247c478bd9Sstevel@tonic-gate * Return 1 if partition has slices, 0 if not.
7257c478bd9Sstevel@tonic-gate */
7267c478bd9Sstevel@tonic-gate static int
has_slices(descriptor_t * desc,int * errp)7277c478bd9Sstevel@tonic-gate has_slices(descriptor_t *desc, int *errp)
7287c478bd9Sstevel@tonic-gate {
7297c478bd9Sstevel@tonic-gate int pnum;
7307c478bd9Sstevel@tonic-gate int i;
7317c478bd9Sstevel@tonic-gate char *p;
7322174cb7bSVirginia Wray struct ipart iparts[TOTAL_NUMPART];
7337c478bd9Sstevel@tonic-gate
7347c478bd9Sstevel@tonic-gate if (get_parts(desc->p.disk, iparts, NULL, 0) != 0) {
7352174cb7bSVirginia Wray *errp = ENODEV;
7362174cb7bSVirginia Wray return (0);
7377c478bd9Sstevel@tonic-gate }
7387c478bd9Sstevel@tonic-gate
7397c478bd9Sstevel@tonic-gate p = strrchr(desc->name, 'p');
7407c478bd9Sstevel@tonic-gate if (p == NULL) {
7412174cb7bSVirginia Wray p = desc->name;
7427c478bd9Sstevel@tonic-gate } else {
7432174cb7bSVirginia Wray p++;
7447c478bd9Sstevel@tonic-gate }
7457c478bd9Sstevel@tonic-gate pnum = atoi(p);
7467c478bd9Sstevel@tonic-gate
7477c478bd9Sstevel@tonic-gate /*
7487c478bd9Sstevel@tonic-gate * Slices are associated with the active solaris partition or if there
7497c478bd9Sstevel@tonic-gate * is no active solaris partition, then the first solaris partition.
7507c478bd9Sstevel@tonic-gate */
7517c478bd9Sstevel@tonic-gate
7527c478bd9Sstevel@tonic-gate *errp = 0;
7537c478bd9Sstevel@tonic-gate if (iparts[pnum].bootid == ACTIVE &&
7547c478bd9Sstevel@tonic-gate (iparts[pnum].systid == SUNIXOS ||
7557c478bd9Sstevel@tonic-gate iparts[pnum].systid == SUNIXOS2)) {
7567c478bd9Sstevel@tonic-gate return (1);
7577c478bd9Sstevel@tonic-gate } else {
7582174cb7bSVirginia Wray int active = 0;
7592174cb7bSVirginia Wray
7602174cb7bSVirginia Wray /* Check if there are no active solaris partitions. */
7612174cb7bSVirginia Wray for (i = 0; i < TOTAL_NUMPART; i++) {
7622174cb7bSVirginia Wray if (iparts[i].bootid == ACTIVE &&
7632174cb7bSVirginia Wray (iparts[i].systid == SUNIXOS ||
7642174cb7bSVirginia Wray iparts[i].systid == SUNIXOS2)) {
7652174cb7bSVirginia Wray active = 1;
7662174cb7bSVirginia Wray break;
7672174cb7bSVirginia Wray }
7687c478bd9Sstevel@tonic-gate }
7697c478bd9Sstevel@tonic-gate
7702174cb7bSVirginia Wray if (!active) {
7712174cb7bSVirginia Wray /* Check if this is the first solaris partition. */
7722174cb7bSVirginia Wray for (i = 0; i < TOTAL_NUMPART; i++) {
7732174cb7bSVirginia Wray if (iparts[i].systid == SUNIXOS ||
7742174cb7bSVirginia Wray iparts[i].systid == SUNIXOS2) {
7752174cb7bSVirginia Wray break;
7762174cb7bSVirginia Wray }
7772174cb7bSVirginia Wray }
7782174cb7bSVirginia Wray
7792174cb7bSVirginia Wray if (i < TOTAL_NUMPART && i == pnum) {
7802174cb7bSVirginia Wray return (1);
7812174cb7bSVirginia Wray }
7827c478bd9Sstevel@tonic-gate }
7837c478bd9Sstevel@tonic-gate }
7847c478bd9Sstevel@tonic-gate
7857c478bd9Sstevel@tonic-gate return (0);
7867c478bd9Sstevel@tonic-gate }
7877c478bd9Sstevel@tonic-gate
7887c478bd9Sstevel@tonic-gate static int
open_disk(disk_t * diskp,char * opath,int len)7897c478bd9Sstevel@tonic-gate open_disk(disk_t *diskp, char *opath, int len)
7907c478bd9Sstevel@tonic-gate {
7917c478bd9Sstevel@tonic-gate /*
79218c2aff7Sartem * Just open the first devpath.
7937c478bd9Sstevel@tonic-gate */
7947c478bd9Sstevel@tonic-gate if (diskp->aliases != NULL && diskp->aliases->devpaths != NULL) {
7957c478bd9Sstevel@tonic-gate #ifdef sparc
7962174cb7bSVirginia Wray if (opath != NULL) {
7977c478bd9Sstevel@tonic-gate (void) strlcpy(opath, diskp->aliases->devpaths->devpath, len);
7982174cb7bSVirginia Wray }
7992174cb7bSVirginia Wray return (open(diskp->aliases->devpaths->devpath, O_RDONLY|O_NDELAY));
8007c478bd9Sstevel@tonic-gate #else
8012174cb7bSVirginia Wray /* On intel we need to open partition device (e.g. c0d0p1). */
8022174cb7bSVirginia Wray char part_dev[MAXPATHLEN];
8032174cb7bSVirginia Wray char *p;
8042174cb7bSVirginia Wray
8052174cb7bSVirginia Wray (void) strlcpy(part_dev, diskp->aliases->devpaths->devpath,
8062174cb7bSVirginia Wray sizeof (part_dev));
8072174cb7bSVirginia Wray p = strrchr(part_dev, '/');
8082174cb7bSVirginia Wray if (p == NULL) {
8097c478bd9Sstevel@tonic-gate p = strrchr(part_dev, 's');
8107c478bd9Sstevel@tonic-gate if (p != NULL) {
8112174cb7bSVirginia Wray *p = 'p';
8127c478bd9Sstevel@tonic-gate }
8132174cb7bSVirginia Wray } else {
8147c478bd9Sstevel@tonic-gate char *ps;
8157c478bd9Sstevel@tonic-gate
8167c478bd9Sstevel@tonic-gate *p = 0;
8177c478bd9Sstevel@tonic-gate ps = strrchr((p + 1), 's');
8187c478bd9Sstevel@tonic-gate if (ps != NULL) {
8192174cb7bSVirginia Wray *ps = 'p';
8207c478bd9Sstevel@tonic-gate }
8217c478bd9Sstevel@tonic-gate *p = '/';
8222174cb7bSVirginia Wray }
8237c478bd9Sstevel@tonic-gate
8242174cb7bSVirginia Wray if (opath != NULL) {
8257c478bd9Sstevel@tonic-gate (void) strlcpy(opath, part_dev, len);
8262174cb7bSVirginia Wray }
8272174cb7bSVirginia Wray return (open(part_dev, O_RDONLY|O_NDELAY));
8287c478bd9Sstevel@tonic-gate #endif
8297c478bd9Sstevel@tonic-gate }
8307c478bd9Sstevel@tonic-gate
8317c478bd9Sstevel@tonic-gate return (-1);
8327c478bd9Sstevel@tonic-gate }
833