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