xref: /illumos-gate/usr/src/cmd/format/label.c (revision b12aaafb)
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
5d25b227dSzl  * Common Development and Distribution License (the "License").
6d25b227dSzl  * 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  */
2123a1cceaSRoger A. Faulkner 
227c478bd9Sstevel@tonic-gate /*
2323a1cceaSRoger A. Faulkner  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
24f1bf0656SHans Rosenfeld  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate  * This file contains the code relating to label manipulation.
297c478bd9Sstevel@tonic-gate  */
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <string.h>
327c478bd9Sstevel@tonic-gate #include <stdlib.h>
337c478bd9Sstevel@tonic-gate #include <memory.h>
347c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
357c478bd9Sstevel@tonic-gate #include <sys/efi_partition.h>
367c478bd9Sstevel@tonic-gate #include <sys/vtoc.h>
377c478bd9Sstevel@tonic-gate #include <sys/uuid.h>
387c478bd9Sstevel@tonic-gate #include <errno.h>
393ccda647Slclee #include <devid.h>
40f1bf0656SHans Rosenfeld #include <libdevinfo.h>
4123a1cceaSRoger A. Faulkner #include "global.h"
4223a1cceaSRoger A. Faulkner #include "label.h"
4323a1cceaSRoger A. Faulkner #include "misc.h"
4423a1cceaSRoger A. Faulkner #include "main.h"
4523a1cceaSRoger A. Faulkner #include "partition.h"
4623a1cceaSRoger A. Faulkner #include "ctlr_scsi.h"
4723a1cceaSRoger A. Faulkner #include "checkdev.h"
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #if defined(_FIRMWARE_NEEDS_FDISK)
507c478bd9Sstevel@tonic-gate #include <sys/dktp/fdisk.h>
517c478bd9Sstevel@tonic-gate #include "menu_fdisk.h"
527c478bd9Sstevel@tonic-gate #endif		/* defined(_FIRMWARE_NEEDS_FDISK) */
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #ifndef	WD_NODE
557c478bd9Sstevel@tonic-gate #define	WD_NODE		7
567c478bd9Sstevel@tonic-gate #endif
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate static int	do_geometry_sanity_check(void);
5932a71e42SToomas Soome static int	vtoc_to_label(struct dk_label *, struct extvtoc *,
6032a71e42SToomas Soome 		struct dk_geom *, struct dk_cinfo *);
61342440ecSPrasad Singamsetty extern int	read_extvtoc(int, struct extvtoc *);
62342440ecSPrasad Singamsetty extern int	write_extvtoc(int, struct extvtoc *);
637c478bd9Sstevel@tonic-gate static int	vtoc64_to_label(struct efi_info *, struct dk_gpt *);
647c478bd9Sstevel@tonic-gate 
65342440ecSPrasad Singamsetty #ifdef	DEBUG
6632a71e42SToomas Soome static void dump_label(struct dk_label *);
67342440ecSPrasad Singamsetty #endif
68342440ecSPrasad Singamsetty 
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate  * This routine checks the given label to see if it is valid.
717c478bd9Sstevel@tonic-gate  */
727c478bd9Sstevel@tonic-gate int
checklabel(struct dk_label * label)7332a71e42SToomas Soome checklabel(struct dk_label *label)
747c478bd9Sstevel@tonic-gate {
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate 	/*
777c478bd9Sstevel@tonic-gate 	 * Check the magic number.
787c478bd9Sstevel@tonic-gate 	 */
797c478bd9Sstevel@tonic-gate 	if (label->dkl_magic != DKL_MAGIC)
807c478bd9Sstevel@tonic-gate 		return (0);
817c478bd9Sstevel@tonic-gate 	/*
827c478bd9Sstevel@tonic-gate 	 * Check the checksum.
837c478bd9Sstevel@tonic-gate 	 */
847c478bd9Sstevel@tonic-gate 	if (checksum(label, CK_CHECKSUM) != 0)
857c478bd9Sstevel@tonic-gate 		return (0);
867c478bd9Sstevel@tonic-gate 	return (1);
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate /*
907c478bd9Sstevel@tonic-gate  * This routine checks or calculates the label checksum, depending on
917c478bd9Sstevel@tonic-gate  * the mode it is called in.
927c478bd9Sstevel@tonic-gate  */
937c478bd9Sstevel@tonic-gate int
checksum(struct dk_label * label,int mode)9432a71e42SToomas Soome checksum(struct	dk_label *label, int mode)
957c478bd9Sstevel@tonic-gate {
9632a71e42SToomas Soome 	short *sp, sum = 0;
9732a71e42SToomas Soome 	short count = (sizeof (struct dk_label)) / (sizeof (short));
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 	/*
1007c478bd9Sstevel@tonic-gate 	 * If we are generating a checksum, don't include the checksum
1017c478bd9Sstevel@tonic-gate 	 * in the rolling xor.
1027c478bd9Sstevel@tonic-gate 	 */
1037c478bd9Sstevel@tonic-gate 	if (mode == CK_MAKESUM)
1047c478bd9Sstevel@tonic-gate 		count -= 1;
1057c478bd9Sstevel@tonic-gate 	sp = (short *)label;
1067c478bd9Sstevel@tonic-gate 	/*
1077c478bd9Sstevel@tonic-gate 	 * Take the xor of all the half-words in the label.
1087c478bd9Sstevel@tonic-gate 	 */
1097c478bd9Sstevel@tonic-gate 	while (count--) {
1107c478bd9Sstevel@tonic-gate 		sum ^= *sp++;
1117c478bd9Sstevel@tonic-gate 	}
1127c478bd9Sstevel@tonic-gate 	/*
1137c478bd9Sstevel@tonic-gate 	 * If we are checking the checksum, the total will be zero for
1147c478bd9Sstevel@tonic-gate 	 * a correct checksum, so we can just return the sum.
1157c478bd9Sstevel@tonic-gate 	 */
1167c478bd9Sstevel@tonic-gate 	if (mode == CK_CHECKSUM)
1177c478bd9Sstevel@tonic-gate 		return (sum);
1187c478bd9Sstevel@tonic-gate 	/*
1197c478bd9Sstevel@tonic-gate 	 * If we are generating the checksum, fill it in.
1207c478bd9Sstevel@tonic-gate 	 */
1217c478bd9Sstevel@tonic-gate 	else {
1227c478bd9Sstevel@tonic-gate 		label->dkl_cksum = sum;
1237c478bd9Sstevel@tonic-gate 		return (0);
1247c478bd9Sstevel@tonic-gate 	}
1257c478bd9Sstevel@tonic-gate }
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate /*
1287c478bd9Sstevel@tonic-gate  * This routine is used to extract the id string from the string stored
1297c478bd9Sstevel@tonic-gate  * in a disk label.  The problem is that the string in the label has
1307c478bd9Sstevel@tonic-gate  * the physical characteristics of the drive appended to it.  The approach
1317c478bd9Sstevel@tonic-gate  * is to find the beginning of the physical attributes portion of the string
1327c478bd9Sstevel@tonic-gate  * and truncate it there.
1337c478bd9Sstevel@tonic-gate  */
1347c478bd9Sstevel@tonic-gate int
trim_id(char * id)13532a71e42SToomas Soome trim_id(char *id)
1367c478bd9Sstevel@tonic-gate {
13732a71e42SToomas Soome 	char *c;
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	/*
1407c478bd9Sstevel@tonic-gate 	 * Start at the end of the string.  When we match the word ' cyl',
1417c478bd9Sstevel@tonic-gate 	 * we are at the beginning of the attributes.
1427c478bd9Sstevel@tonic-gate 	 */
1437c478bd9Sstevel@tonic-gate 	for (c = id + strlen(id); c >= id; c--) {
1447c478bd9Sstevel@tonic-gate 		if (strncmp(c, " cyl", strlen(" cyl")) == 0) {
1457c478bd9Sstevel@tonic-gate 			/*
1467c478bd9Sstevel@tonic-gate 			 * Remove any white space.
1477c478bd9Sstevel@tonic-gate 			 */
1487c478bd9Sstevel@tonic-gate 			for (; (((*(c - 1) == ' ') || (*(c - 1) == '\t')) &&
14932a71e42SToomas Soome 			    (c >= id)); c--)
15032a71e42SToomas Soome 				;
1517c478bd9Sstevel@tonic-gate 			break;
1527c478bd9Sstevel@tonic-gate 		}
1537c478bd9Sstevel@tonic-gate 	}
1547c478bd9Sstevel@tonic-gate 	/*
1557c478bd9Sstevel@tonic-gate 	 * If we ran off the beginning of the string, something is wrong.
1567c478bd9Sstevel@tonic-gate 	 */
1577c478bd9Sstevel@tonic-gate 	if (c < id)
1587c478bd9Sstevel@tonic-gate 		return (-1);
1597c478bd9Sstevel@tonic-gate 	/*
1607c478bd9Sstevel@tonic-gate 	 * Truncate the string.
1617c478bd9Sstevel@tonic-gate 	 */
1627c478bd9Sstevel@tonic-gate 	*c = '\0';
1637c478bd9Sstevel@tonic-gate 	return (0);
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate /*
1677c478bd9Sstevel@tonic-gate  * This routine is used by write_label() to do a quick sanity check on the
1687c478bd9Sstevel@tonic-gate  * supplied geometry. This is not a thorough check.
1697c478bd9Sstevel@tonic-gate  *
1707c478bd9Sstevel@tonic-gate  * The SCSI READ_CAPACITY command is used here to get the capacity of the
1717c478bd9Sstevel@tonic-gate  * disk. But, the available area to store data on a disk is usually less
1727c478bd9Sstevel@tonic-gate  * than this. So, if the specified geometry evaluates to a value which falls
1737c478bd9Sstevel@tonic-gate  * in this margin, then such illegal geometries can slip through the cracks.
1747c478bd9Sstevel@tonic-gate  */
1757c478bd9Sstevel@tonic-gate static int
do_geometry_sanity_check(void)176*b12aaafbSToomas Soome do_geometry_sanity_check(void)
1777c478bd9Sstevel@tonic-gate {
1787c478bd9Sstevel@tonic-gate 	struct scsi_capacity_16	 capacity;
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 	if (uscsi_read_capacity(cur_file, &capacity)) {
1817c478bd9Sstevel@tonic-gate 		err_print("Warning: Unable to get capacity."
182843e1988Sjohnlev 		    " Cannot check geometry\n");
1837c478bd9Sstevel@tonic-gate 		return (0);	/* Just ignore this problem */
1847c478bd9Sstevel@tonic-gate 	}
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	if (capacity.sc_capacity < ncyl * nhead * nsect) {
1877c478bd9Sstevel@tonic-gate 		err_print("\nWarning: Current geometry overshoots "
188843e1988Sjohnlev 		    "actual geometry of disk\n\n");
1897c478bd9Sstevel@tonic-gate 		if (check("Continue labelling disk") != 0)
1907c478bd9Sstevel@tonic-gate 			return (-1);
1917c478bd9Sstevel@tonic-gate 		return (0);	/* Just ignore this problem */
1927c478bd9Sstevel@tonic-gate 	}
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	return (0);
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate /*
19891da5b00Sgz  * create a clear EFI partition table when format is used
199342440ecSPrasad Singamsetty  * to convert an SMI label to an EFI label
2007c478bd9Sstevel@tonic-gate  */
2017c478bd9Sstevel@tonic-gate int
SMI_vtoc_to_EFI(int fd,struct dk_gpt ** new_vtoc)2020d9ffb6aSgz SMI_vtoc_to_EFI(int fd, struct dk_gpt **new_vtoc)
2037c478bd9Sstevel@tonic-gate {
20491da5b00Sgz 	int i;
20532a71e42SToomas Soome 	struct dk_gpt *efi;
20632a71e42SToomas Soome 	uint64_t reserved;
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	if (efi_alloc_and_init(fd, EFI_NUMPAR, new_vtoc) != 0) {
209843e1988Sjohnlev 		err_print("SMI vtoc to EFI failed\n");
210843e1988Sjohnlev 		return (-1);
2117c478bd9Sstevel@tonic-gate 	}
21291da5b00Sgz 	efi = *new_vtoc;
21332a71e42SToomas Soome 	reserved = efi_reserved_sectors(efi);
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	/*
21691da5b00Sgz 	 * create a clear EFI partition table:
21791da5b00Sgz 	 * s0 takes the whole disk except the primary EFI lable,
21891da5b00Sgz 	 * backup EFI labels, and the reserved partition.
21991da5b00Sgz 	 * s1-s6 are unassigned slices.
2207c478bd9Sstevel@tonic-gate 	 */
22191da5b00Sgz 	efi->efi_parts[0].p_tag = V_USR;
22291da5b00Sgz 	efi->efi_parts[0].p_start = efi->efi_first_u_lba;
22391da5b00Sgz 	efi->efi_parts[0].p_size = efi->efi_last_u_lba - efi->efi_first_u_lba
22432a71e42SToomas Soome 	    - reserved + 1;
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 	/*
22791da5b00Sgz 	 * s1-s6 are unassigned slices
2287c478bd9Sstevel@tonic-gate 	 */
22991da5b00Sgz 	for (i = 1; i < efi->efi_nparts - 2; i++) {
23091da5b00Sgz 		efi->efi_parts[i].p_tag = V_UNASSIGNED;
23191da5b00Sgz 		efi->efi_parts[i].p_start = 0;
23291da5b00Sgz 		efi->efi_parts[i].p_size = 0;
2337c478bd9Sstevel@tonic-gate 	}
2347c478bd9Sstevel@tonic-gate 
23591da5b00Sgz 	/*
23691da5b00Sgz 	 * the reserved slice
23791da5b00Sgz 	 */
23891da5b00Sgz 	efi->efi_parts[efi->efi_nparts - 1].p_tag = V_RESERVED;
23991da5b00Sgz 	efi->efi_parts[efi->efi_nparts - 1].p_start =
24032a71e42SToomas Soome 	    efi->efi_last_u_lba - reserved + 1;
24132a71e42SToomas Soome 	efi->efi_parts[efi->efi_nparts - 1].p_size = reserved;
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	return (0);
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate /*
2477c478bd9Sstevel@tonic-gate  * This routine constructs and writes a label on the disk.  It writes both
2487c478bd9Sstevel@tonic-gate  * the primary and backup labels.  It assumes that there is a current
2497c478bd9Sstevel@tonic-gate  * partition map already defined.  It also notifies the SunOS kernel of
2507c478bd9Sstevel@tonic-gate  * the label and partition information it has written on the disk.
2517c478bd9Sstevel@tonic-gate  */
2527c478bd9Sstevel@tonic-gate int
write_label(void)253*b12aaafbSToomas Soome write_label(void)
2547c478bd9Sstevel@tonic-gate {
2557c478bd9Sstevel@tonic-gate 	int	error = 0, head, sec;
2567c478bd9Sstevel@tonic-gate 	struct dk_label label;
257342440ecSPrasad Singamsetty 	struct extvtoc	vtoc;
2587c478bd9Sstevel@tonic-gate 	struct dk_geom	geom;
2597c478bd9Sstevel@tonic-gate 	struct dk_gpt	*vtoc64;
2607c478bd9Sstevel@tonic-gate 	int		nbackups;
26165908c77Syu, larry liu - Sun Microsystems - Beijing China 	char		*new_label;
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
2647c478bd9Sstevel@tonic-gate 	int i;
2657c478bd9Sstevel@tonic-gate #endif		/* defined(_SUNOS_VTOC_8) */
2667c478bd9Sstevel@tonic-gate 
267c92a0838Smishra 	/*
268c92a0838Smishra 	 * Check to see if any partitions used for svm, vxvm or live upgrade
269c92a0838Smishra 	 * are on the disk. If so, refuse to label the disk, but only
270c92a0838Smishra 	 * if we are trying to shrink a partition in use.
271c92a0838Smishra 	 */
272c92a0838Smishra 	if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
273c92a0838Smishra 	    (diskaddr_t)-1, 0, 1)) {
274c92a0838Smishra 		err_print("Cannot label disk when "
275c92a0838Smishra 		    "partitions are in use as described.\n");
276c92a0838Smishra 		return (-1);
277c92a0838Smishra 	}
278c92a0838Smishra 
2797c478bd9Sstevel@tonic-gate 	/*
2807c478bd9Sstevel@tonic-gate 	 * If EFI label, then write it out to disk
2817c478bd9Sstevel@tonic-gate 	 */
2827c478bd9Sstevel@tonic-gate 	if (cur_label == L_TYPE_EFI) {
283843e1988Sjohnlev 		enter_critical();
284843e1988Sjohnlev 		vtoc64 = cur_parts->etoc;
285d9172ac4SToomas Soome 		efi_err_check(vtoc64);
286843e1988Sjohnlev 		if (efi_write(cur_file, vtoc64) != 0) {
287843e1988Sjohnlev 			err_print("Warning: error writing EFI.\n");
288843e1988Sjohnlev 			error = -1;
289843e1988Sjohnlev 			}
2907c478bd9Sstevel@tonic-gate 
291843e1988Sjohnlev 		cur_disk->disk_flags |= DSK_LABEL;
292843e1988Sjohnlev 		exit_critical();
293843e1988Sjohnlev 		return (error);
2947c478bd9Sstevel@tonic-gate 	}
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	/*
2977c478bd9Sstevel@tonic-gate 	 * Fill in a label structure with the geometry information.
2987c478bd9Sstevel@tonic-gate 	 */
2997c478bd9Sstevel@tonic-gate 	(void) memset((char *)&label, 0, sizeof (struct dk_label));
30065908c77Syu, larry liu - Sun Microsystems - Beijing China 	new_label = zalloc(cur_blksz);
30165908c77Syu, larry liu - Sun Microsystems - Beijing China 
3027c478bd9Sstevel@tonic-gate 	label.dkl_pcyl = pcyl;
3037c478bd9Sstevel@tonic-gate 	label.dkl_ncyl = ncyl;
3047c478bd9Sstevel@tonic-gate 	label.dkl_acyl = acyl;
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3077c478bd9Sstevel@tonic-gate 	label.dkl_bcyl = bcyl;
3087c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOC_VTOC_16) */
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 	label.dkl_nhead = nhead;
3117c478bd9Sstevel@tonic-gate 	label.dkl_nsect = nsect;
3127c478bd9Sstevel@tonic-gate 	label.dkl_apc = apc;
3137c478bd9Sstevel@tonic-gate 	label.dkl_intrlv = 1;
3147c478bd9Sstevel@tonic-gate 	label.dkl_rpm = cur_dtype->dtype_rpm;
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
3177c478bd9Sstevel@tonic-gate 	/*
3187c478bd9Sstevel@tonic-gate 	 * Also fill in the current partition information.
3197c478bd9Sstevel@tonic-gate 	 */
3207c478bd9Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
3217c478bd9Sstevel@tonic-gate 		label.dkl_map[i] = cur_parts->pinfo_map[i];
3227c478bd9Sstevel@tonic-gate 	}
3237c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	label.dkl_magic = DKL_MAGIC;
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate 	/*
3287c478bd9Sstevel@tonic-gate 	 * Fill in the vtoc information
3297c478bd9Sstevel@tonic-gate 	 */
3307c478bd9Sstevel@tonic-gate 	label.dkl_vtoc = cur_parts->vtoc;
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 	/*
3337c478bd9Sstevel@tonic-gate 	 * Use the current label
3347c478bd9Sstevel@tonic-gate 	 */
3357c478bd9Sstevel@tonic-gate 	bcopy(cur_disk->v_volume, label.dkl_vtoc.v_volume, LEN_DKL_VVOL);
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	/*
3387c478bd9Sstevel@tonic-gate 	 * Put asciilabel in; on x86 it's in the vtoc, not the label.
3397c478bd9Sstevel@tonic-gate 	 */
3407c478bd9Sstevel@tonic-gate 	(void) snprintf(label.dkl_asciilabel, sizeof (label.dkl_asciilabel),
3417c478bd9Sstevel@tonic-gate 	    "%s cyl %d alt %d hd %d sec %d",
3427c478bd9Sstevel@tonic-gate 	    cur_dtype->dtype_asciilabel, ncyl, acyl, nhead, nsect);
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3457c478bd9Sstevel@tonic-gate 	/*
34665908c77Syu, larry liu - Sun Microsystems - Beijing China 	 * Also add in v_sectorsz, as the driver will.
3477c478bd9Sstevel@tonic-gate 	 */
34865908c77Syu, larry liu - Sun Microsystems - Beijing China 	label.dkl_vtoc.v_sectorsz = cur_blksz;
3497c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_16) */
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 	/*
3527c478bd9Sstevel@tonic-gate 	 * Generate the correct checksum.
3537c478bd9Sstevel@tonic-gate 	 */
3547c478bd9Sstevel@tonic-gate 	(void) checksum(&label, CK_MAKESUM);
3557c478bd9Sstevel@tonic-gate 	/*
3567c478bd9Sstevel@tonic-gate 	 * Convert the label into a vtoc
3577c478bd9Sstevel@tonic-gate 	 */
3587c478bd9Sstevel@tonic-gate 	if (label_to_vtoc(&vtoc, &label) == -1) {
35965908c77Syu, larry liu - Sun Microsystems - Beijing China 		free(new_label);
3607c478bd9Sstevel@tonic-gate 		return (-1);
3617c478bd9Sstevel@tonic-gate 	}
3627c478bd9Sstevel@tonic-gate 	/*
3637c478bd9Sstevel@tonic-gate 	 * Fill in the geometry info.  This is critical that
3647c478bd9Sstevel@tonic-gate 	 * we do this before writing the vtoc.
3657c478bd9Sstevel@tonic-gate 	 */
3667c478bd9Sstevel@tonic-gate 	bzero((caddr_t)&geom, sizeof (struct dk_geom));
3677c478bd9Sstevel@tonic-gate 	geom.dkg_ncyl = ncyl;
3687c478bd9Sstevel@tonic-gate 	geom.dkg_acyl = acyl;
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3717c478bd9Sstevel@tonic-gate 	geom.dkg_bcyl = bcyl;
3727c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_16) */
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate 	geom.dkg_nhead = nhead;
3757c478bd9Sstevel@tonic-gate 	geom.dkg_nsect = nsect;
3767c478bd9Sstevel@tonic-gate 	geom.dkg_intrlv = 1;
3777c478bd9Sstevel@tonic-gate 	geom.dkg_apc = apc;
3787c478bd9Sstevel@tonic-gate 	geom.dkg_rpm = cur_dtype->dtype_rpm;
3797c478bd9Sstevel@tonic-gate 	geom.dkg_pcyl = pcyl;
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 	/*
3827c478bd9Sstevel@tonic-gate 	 * Make a quick check to see that the geometry is being
3837c478bd9Sstevel@tonic-gate 	 * written now is not way off from the actual capacity
3847c478bd9Sstevel@tonic-gate 	 * of the disk. This is only an appoximate check and
3857c478bd9Sstevel@tonic-gate 	 * is only for SCSI disks.
3867c478bd9Sstevel@tonic-gate 	 */
3877c478bd9Sstevel@tonic-gate 	if (SCSI && do_geometry_sanity_check() != 0) {
38865908c77Syu, larry liu - Sun Microsystems - Beijing China 		free(new_label);
3897c478bd9Sstevel@tonic-gate 		return (-1);
3907c478bd9Sstevel@tonic-gate 	}
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 	/*
3937c478bd9Sstevel@tonic-gate 	 * Lock out interrupts so we do things in sync.
3947c478bd9Sstevel@tonic-gate 	 */
3957c478bd9Sstevel@tonic-gate 	enter_critical();
3967c478bd9Sstevel@tonic-gate 	/*
3977c478bd9Sstevel@tonic-gate 	 * Do the ioctl to tell the kernel the geometry.
3987c478bd9Sstevel@tonic-gate 	 */
3997c478bd9Sstevel@tonic-gate 	if (ioctl(cur_file, DKIOCSGEOM, &geom) == -1) {
4007c478bd9Sstevel@tonic-gate 		err_print("Warning: error setting drive geometry.\n");
4017c478bd9Sstevel@tonic-gate 		error = -1;
4027c478bd9Sstevel@tonic-gate 	}
4037c478bd9Sstevel@tonic-gate 	/*
4047c478bd9Sstevel@tonic-gate 	 * Write the vtoc.  At the time of this writing, our
4057c478bd9Sstevel@tonic-gate 	 * drivers convert the vtoc back to a label, and
4067c478bd9Sstevel@tonic-gate 	 * then write both the primary and backup labels.
4077c478bd9Sstevel@tonic-gate 	 * This is not a requirement, however, as we
4087c478bd9Sstevel@tonic-gate 	 * always use an ioctl to read the vtoc from the
4097c478bd9Sstevel@tonic-gate 	 * driver, so it can do as it likes.
4107c478bd9Sstevel@tonic-gate 	 */
411342440ecSPrasad Singamsetty 	if (write_extvtoc(cur_file, &vtoc) != 0) {
4127c478bd9Sstevel@tonic-gate 		err_print("Warning: error writing VTOC.\n");
4137c478bd9Sstevel@tonic-gate 		error = -1;
4147c478bd9Sstevel@tonic-gate 	}
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate 	/*
4177c478bd9Sstevel@tonic-gate 	 * Calculate where the backup labels went.  They are always on
4187c478bd9Sstevel@tonic-gate 	 * the last alternate cylinder, but some older drives put them
4197c478bd9Sstevel@tonic-gate 	 * on head 2 instead of the last head.  They are always on the
4207c478bd9Sstevel@tonic-gate 	 * first 5 odd sectors of the appropriate track.
4217c478bd9Sstevel@tonic-gate 	 */
4227c478bd9Sstevel@tonic-gate 	if (cur_ctype->ctype_flags & CF_BLABEL)
4237c478bd9Sstevel@tonic-gate 		head  = 2;
4247c478bd9Sstevel@tonic-gate 	else
4257c478bd9Sstevel@tonic-gate 		head = nhead - 1;
4267c478bd9Sstevel@tonic-gate 	/*
4277c478bd9Sstevel@tonic-gate 	 * Read and verify the backup labels.
4287c478bd9Sstevel@tonic-gate 	 */
4297c478bd9Sstevel@tonic-gate 	nbackups = 0;
4307c478bd9Sstevel@tonic-gate 	for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect));
4317c478bd9Sstevel@tonic-gate 	    sec += 2) {
4327c478bd9Sstevel@tonic-gate 		if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, (diskaddr_t)
43365908c77Syu, larry liu - Sun Microsystems - Beijing China 		    ((chs2bn(ncyl + acyl - 1, head, sec))
43465908c77Syu, larry liu - Sun Microsystems - Beijing China 		    + solaris_offset), 1, new_label, F_NORMAL, NULL)) {
43565908c77Syu, larry liu - Sun Microsystems - Beijing China 			err_print("Warning: error reading"
43665908c77Syu, larry liu - Sun Microsystems - Beijing China 			    "backup label.\n");
4377c478bd9Sstevel@tonic-gate 			error = -1;
4387c478bd9Sstevel@tonic-gate 		} else {
43965908c77Syu, larry liu - Sun Microsystems - Beijing China 			if (bcmp((char *)&label, new_label,
440843e1988Sjohnlev 			    sizeof (struct dk_label)) == 0) {
44165908c77Syu, larry liu - Sun Microsystems - Beijing China 				nbackups++;
4427c478bd9Sstevel@tonic-gate 			}
4437c478bd9Sstevel@tonic-gate 		}
4447c478bd9Sstevel@tonic-gate 	}
4457c478bd9Sstevel@tonic-gate 	if (nbackups != BAD_LISTCNT) {
4467c478bd9Sstevel@tonic-gate 		err_print("Warning: %s\n", nbackups == 0 ?
447843e1988Sjohnlev 		    "no backup labels" : "some backup labels incorrect");
4487c478bd9Sstevel@tonic-gate 	}
4497c478bd9Sstevel@tonic-gate 	/*
4507c478bd9Sstevel@tonic-gate 	 * Mark the current disk as labelled and notify the kernel of what
4517c478bd9Sstevel@tonic-gate 	 * has happened.
4527c478bd9Sstevel@tonic-gate 	 */
4537c478bd9Sstevel@tonic-gate 	cur_disk->disk_flags |= DSK_LABEL;
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 	exit_critical();
45665908c77Syu, larry liu - Sun Microsystems - Beijing China 	free(new_label);
4577c478bd9Sstevel@tonic-gate 	return (error);
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate /*
4627c478bd9Sstevel@tonic-gate  * Read the label from the disk.
463342440ecSPrasad Singamsetty  * Do this via the read_extvtoc() library routine, then convert it to a label.
4647c478bd9Sstevel@tonic-gate  * We also need a DKIOCGGEOM ioctl to get the disk's geometry.
4657c478bd9Sstevel@tonic-gate  */
4667c478bd9Sstevel@tonic-gate int
read_label(int fd,struct dk_label * label)4677c478bd9Sstevel@tonic-gate read_label(int fd, struct dk_label *label)
4687c478bd9Sstevel@tonic-gate {
469342440ecSPrasad Singamsetty 	struct extvtoc	vtoc;
4707c478bd9Sstevel@tonic-gate 	struct dk_geom	geom;
471843e1988Sjohnlev 	struct dk_cinfo	dkinfo;
4727c478bd9Sstevel@tonic-gate 
473342440ecSPrasad Singamsetty 	if (read_extvtoc(fd, &vtoc) < 0		||
474843e1988Sjohnlev 	    ioctl(fd, DKIOCGGEOM, &geom) == -1	||
475843e1988Sjohnlev 	    ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
4767c478bd9Sstevel@tonic-gate 		return (-1);
4777c478bd9Sstevel@tonic-gate 	}
478843e1988Sjohnlev 
479843e1988Sjohnlev 	return (vtoc_to_label(label, &vtoc, &geom, &dkinfo));
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate 
4823ccda647Slclee int
get_disk_inquiry_prop(char * devpath,char ** vid,char ** pid,char ** rid)483f1bf0656SHans Rosenfeld get_disk_inquiry_prop(char *devpath, char **vid, char **pid, char **rid)
484f1bf0656SHans Rosenfeld {
485f1bf0656SHans Rosenfeld 	char *v, *p, *r;
486f1bf0656SHans Rosenfeld 	di_node_t node;
487f1bf0656SHans Rosenfeld 	int ret = -1;
488f1bf0656SHans Rosenfeld 
489f1bf0656SHans Rosenfeld 	node = di_init(devpath, DINFOCPYALL);
490f1bf0656SHans Rosenfeld 
491f1bf0656SHans Rosenfeld 	if (node == DI_NODE_NIL)
492f1bf0656SHans Rosenfeld 		goto out;
493f1bf0656SHans Rosenfeld 
494f1bf0656SHans Rosenfeld 	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
495f1bf0656SHans Rosenfeld 	    "inquiry-vendor-id", &v) != 1)
496f1bf0656SHans Rosenfeld 		goto out;
497f1bf0656SHans Rosenfeld 
498f1bf0656SHans Rosenfeld 	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
499f1bf0656SHans Rosenfeld 	    "inquiry-product-id", &p) != 1)
500f1bf0656SHans Rosenfeld 		goto out;
501f1bf0656SHans Rosenfeld 
502f1bf0656SHans Rosenfeld 	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
503f1bf0656SHans Rosenfeld 	    "inquiry-revision-id", &r) != 1)
504f1bf0656SHans Rosenfeld 		goto out;
505f1bf0656SHans Rosenfeld 
506f1bf0656SHans Rosenfeld 	*vid = strdup(v);
507f1bf0656SHans Rosenfeld 	*pid = strdup(p);
508f1bf0656SHans Rosenfeld 	*rid = strdup(r);
509f1bf0656SHans Rosenfeld 
510f1bf0656SHans Rosenfeld 	if (*vid == NULL || *pid == NULL || *rid == NULL) {
511f1bf0656SHans Rosenfeld 		free(*vid);
512f1bf0656SHans Rosenfeld 		free(*pid);
513f1bf0656SHans Rosenfeld 		free(*rid);
514f1bf0656SHans Rosenfeld 		goto out;
515f1bf0656SHans Rosenfeld 	}
516f1bf0656SHans Rosenfeld 
517f1bf0656SHans Rosenfeld 	ret = 0;
518f1bf0656SHans Rosenfeld 
519f1bf0656SHans Rosenfeld out:
520f1bf0656SHans Rosenfeld 	di_fini(node);
521f1bf0656SHans Rosenfeld 	return (ret);
522f1bf0656SHans Rosenfeld }
523f1bf0656SHans Rosenfeld 
524f1bf0656SHans Rosenfeld int
get_disk_inquiry_uscsi(int fd,char ** vid,char ** pid,char ** rid)525f1bf0656SHans Rosenfeld get_disk_inquiry_uscsi(int fd, char **vid, char **pid, char **rid)
526f1bf0656SHans Rosenfeld {
527f1bf0656SHans Rosenfeld 	struct scsi_inquiry inquiry;
528f1bf0656SHans Rosenfeld 
529f1bf0656SHans Rosenfeld 	if (uscsi_inquiry(fd, (char *)&inquiry, sizeof (inquiry)))
530f1bf0656SHans Rosenfeld 		return (-1);
531f1bf0656SHans Rosenfeld 
532f1bf0656SHans Rosenfeld 	*vid = strndup(inquiry.inq_vid, 8);
533f1bf0656SHans Rosenfeld 	*pid = strndup(inquiry.inq_pid, 16);
534f1bf0656SHans Rosenfeld 	*rid = strndup(inquiry.inq_revision, 4);
535f1bf0656SHans Rosenfeld 
536f1bf0656SHans Rosenfeld 	if (*vid == NULL || *pid == NULL || *rid == NULL) {
537f1bf0656SHans Rosenfeld 		free(*vid);
538f1bf0656SHans Rosenfeld 		free(*pid);
539f1bf0656SHans Rosenfeld 		free(*rid);
540f1bf0656SHans Rosenfeld 		return (-1);
541f1bf0656SHans Rosenfeld 	}
542f1bf0656SHans Rosenfeld 
543f1bf0656SHans Rosenfeld 	return (0);
544f1bf0656SHans Rosenfeld }
545f1bf0656SHans Rosenfeld 
546f1bf0656SHans Rosenfeld int
get_disk_capacity(int fd,uint64_t * capacity)547f1bf0656SHans Rosenfeld get_disk_capacity(int fd, uint64_t *capacity)
548f1bf0656SHans Rosenfeld {
549f1bf0656SHans Rosenfeld 	struct dk_minfo	minf;
550f1bf0656SHans Rosenfeld 	struct scsi_capacity_16	cap16;
551f1bf0656SHans Rosenfeld 
552f1bf0656SHans Rosenfeld 	if (ioctl(fd, DKIOCGMEDIAINFO, &minf) == 0) {
553f1bf0656SHans Rosenfeld 		*capacity = minf.dki_capacity * minf.dki_lbsize / cur_blksz;
554f1bf0656SHans Rosenfeld 		return (0);
555f1bf0656SHans Rosenfeld 	}
556f1bf0656SHans Rosenfeld 
557f1bf0656SHans Rosenfeld 	if (uscsi_read_capacity(fd, &cap16) == 0) {
558f1bf0656SHans Rosenfeld 		*capacity = cap16.sc_capacity;
559f1bf0656SHans Rosenfeld 
560f1bf0656SHans Rosenfeld 		/* Since we are counting from zero, add 1 to capacity */
561f1bf0656SHans Rosenfeld 		(*capacity)++;
562f1bf0656SHans Rosenfeld 
563f1bf0656SHans Rosenfeld 		return (0);
564f1bf0656SHans Rosenfeld 	}
565f1bf0656SHans Rosenfeld 
566f1bf0656SHans Rosenfeld 	err_print("Fetch Capacity failed\n");
567f1bf0656SHans Rosenfeld 	return (-1);
568f1bf0656SHans Rosenfeld }
569f1bf0656SHans Rosenfeld 
570f1bf0656SHans Rosenfeld int
get_disk_inquiry_devid(int fd,char ** vid,char ** pid,char ** rid)571f1bf0656SHans Rosenfeld get_disk_inquiry_devid(int fd, char **vid, char **pid, char **rid)
5723ccda647Slclee {
5733ccda647Slclee 	ddi_devid_t	devid;
5743ccda647Slclee 	char		*s;
575f1bf0656SHans Rosenfeld 	char		*v, *p;
5763ccda647Slclee 	struct dk_cinfo	dkinfo;
5773ccda647Slclee 
5783ccda647Slclee 	if (devid_get(fd, &devid)) {
5793ccda647Slclee 		if (option_msg && diag_msg)
5803ccda647Slclee 			err_print("devid_get failed\n");
5813ccda647Slclee 		return (-1);
5823ccda647Slclee 	}
5833ccda647Slclee 
5843ccda647Slclee 	s = (char *)devid;
5853ccda647Slclee 
5863ccda647Slclee 	if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
5873ccda647Slclee 		if (option_msg && diag_msg)
5883ccda647Slclee 			err_print("DKIOCINFO failed\n");
5893ccda647Slclee 		return (-1);
5903ccda647Slclee 	}
5913ccda647Slclee 
5923ccda647Slclee 	if (dkinfo.dki_ctype != DKC_DIRECT)
5933ccda647Slclee 		return (-1);
5943ccda647Slclee 
595f1bf0656SHans Rosenfeld 	v = s+12;
596f1bf0656SHans Rosenfeld 	if (!(p = strchr(v, '=')))
5973ccda647Slclee 		return (-1);
598f1bf0656SHans Rosenfeld 	p += 1;
599f1bf0656SHans Rosenfeld 
600f1bf0656SHans Rosenfeld 	*vid = strdup(v);
601f1bf0656SHans Rosenfeld 	*pid = strdup(p);
602f1bf0656SHans Rosenfeld 	*rid = strdup("0001");
603f1bf0656SHans Rosenfeld 	devid_free(devid);
6043ccda647Slclee 
605f1bf0656SHans Rosenfeld 	if (*vid == NULL || *pid == NULL || *rid == NULL) {
606f1bf0656SHans Rosenfeld 		free(*vid);
607f1bf0656SHans Rosenfeld 		free(*pid);
608f1bf0656SHans Rosenfeld 		free(*rid);
6093ccda647Slclee 		return (-1);
6103ccda647Slclee 	}
6113ccda647Slclee 
6123ccda647Slclee 	return (0);
6133ccda647Slclee }
6143ccda647Slclee 
6157c478bd9Sstevel@tonic-gate /*
6167c478bd9Sstevel@tonic-gate  * Issue uscsi_inquiry and read_capacity commands to
6177c478bd9Sstevel@tonic-gate  * retrieve the disk's Vendor, Product, Revision and
6187c478bd9Sstevel@tonic-gate  * Capacity information.
6197c478bd9Sstevel@tonic-gate  */
6207c478bd9Sstevel@tonic-gate int
get_disk_info(int fd,struct efi_info * label,struct disk_info * disk_info)621f1bf0656SHans Rosenfeld get_disk_info(int fd, struct efi_info *label, struct disk_info *disk_info)
6227c478bd9Sstevel@tonic-gate {
623f1bf0656SHans Rosenfeld 	(void) get_disk_capacity(fd, &label->capacity);
624f1bf0656SHans Rosenfeld 
625f1bf0656SHans Rosenfeld 	if (get_disk_inquiry_prop(disk_info->devfs_name,
626f1bf0656SHans Rosenfeld 	    &label->vendor, &label->product, &label->revision) != 0) {
627f1bf0656SHans Rosenfeld 		if (get_disk_inquiry_devid(fd, &label->vendor, &label->product,
628f1bf0656SHans Rosenfeld 		    &label->revision) != 0) {
629f1bf0656SHans Rosenfeld 			if (get_disk_inquiry_uscsi(fd, &label->vendor,
630f1bf0656SHans Rosenfeld 			    &label->product, &label->revision) != 0) {
631f1bf0656SHans Rosenfeld 				label->vendor = strdup("Unknown");
632f1bf0656SHans Rosenfeld 				label->product = strdup("Unknown");
633f1bf0656SHans Rosenfeld 				label->revision = strdup("0001");
634f1bf0656SHans Rosenfeld 				if (label->vendor == NULL ||
635f1bf0656SHans Rosenfeld 				    label->product == NULL ||
636f1bf0656SHans Rosenfeld 				    label->revision == NULL) {
637f1bf0656SHans Rosenfeld 					free(label->vendor);
638f1bf0656SHans Rosenfeld 					free(label->product);
639f1bf0656SHans Rosenfeld 					free(label->revision);
640f1bf0656SHans Rosenfeld 					return (-1);
641f1bf0656SHans Rosenfeld 				}
642f1bf0656SHans Rosenfeld 			}
643d25b227dSzl 		}
644d25b227dSzl 	}
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 	return (0);
6477c478bd9Sstevel@tonic-gate }
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate int
read_efi_label(int fd,struct efi_info * label,struct disk_info * disk_info)650f1bf0656SHans Rosenfeld read_efi_label(int fd, struct efi_info *label, struct disk_info *disk_info)
6517c478bd9Sstevel@tonic-gate {
6527c478bd9Sstevel@tonic-gate 	struct dk_gpt	*vtoc64;
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate 	/* This could fail if there is no label already */
6557c478bd9Sstevel@tonic-gate 	if (efi_alloc_and_read(fd, &vtoc64) < 0) {
6567c478bd9Sstevel@tonic-gate 		return (-1);
6577c478bd9Sstevel@tonic-gate 	}
6587c478bd9Sstevel@tonic-gate 	if (vtoc64_to_label(label, vtoc64) != 0) {
6597c478bd9Sstevel@tonic-gate 		err_print("vtoc64_to_label failed\n");
6607c478bd9Sstevel@tonic-gate 		return (-1);
6617c478bd9Sstevel@tonic-gate 	}
6627c478bd9Sstevel@tonic-gate 	efi_free(vtoc64);
663f1bf0656SHans Rosenfeld 	if (get_disk_info(fd, label, disk_info) != 0) {
6647c478bd9Sstevel@tonic-gate 		return (-1);
6657c478bd9Sstevel@tonic-gate 	}
6667c478bd9Sstevel@tonic-gate 	return (0);
6677c478bd9Sstevel@tonic-gate }
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate /*
6717c478bd9Sstevel@tonic-gate  * We've read a 64-bit label which has no geometry information.  Use
6727c478bd9Sstevel@tonic-gate  * some heuristics to fake up a geometry that would match the disk in
673bbf21555SRichard Lowe  * order to make the rest of format(8) happy.
6747c478bd9Sstevel@tonic-gate  */
6757c478bd9Sstevel@tonic-gate static int
vtoc64_to_label(struct efi_info * label,struct dk_gpt * vtoc)6767c478bd9Sstevel@tonic-gate vtoc64_to_label(struct efi_info *label, struct dk_gpt *vtoc)
6777c478bd9Sstevel@tonic-gate {
6787c478bd9Sstevel@tonic-gate 	int		i, nparts = 0;
6797c478bd9Sstevel@tonic-gate 	struct dk_gpt	*lmap;
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	(void) memset((char *)label, 0, sizeof (struct efi_info));
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate 	/* XXX do a sanity check here for nparts */
6847c478bd9Sstevel@tonic-gate 	nparts = vtoc->efi_nparts;
6857c478bd9Sstevel@tonic-gate 	lmap = (struct dk_gpt *) calloc(1, (sizeof (struct dk_part) *
686843e1988Sjohnlev 	    nparts) + sizeof (struct dk_gpt));
6877c478bd9Sstevel@tonic-gate 	if (lmap == NULL) {
6887c478bd9Sstevel@tonic-gate 		err_print("vtoc64_to_label: unable to allocate lmap\n");
6897c478bd9Sstevel@tonic-gate 		fullabort();
6907c478bd9Sstevel@tonic-gate 	}
6917c478bd9Sstevel@tonic-gate 	label->e_parts = lmap;
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate 	/*
6947c478bd9Sstevel@tonic-gate 	 * Copy necessary portions
6957c478bd9Sstevel@tonic-gate 	 * XXX Maybe we can use memcpy() ??
6967c478bd9Sstevel@tonic-gate 	 */
6977c478bd9Sstevel@tonic-gate 	lmap->efi_version = vtoc->efi_version;
6987c478bd9Sstevel@tonic-gate 	lmap->efi_nparts = vtoc->efi_nparts;
6997c478bd9Sstevel@tonic-gate 	lmap->efi_part_size = vtoc->efi_part_size;
7007c478bd9Sstevel@tonic-gate 	lmap->efi_lbasize = vtoc->efi_lbasize;
7017c478bd9Sstevel@tonic-gate 	lmap->efi_last_lba = vtoc->efi_last_lba;
7027c478bd9Sstevel@tonic-gate 	lmap->efi_first_u_lba = vtoc->efi_first_u_lba;
7037c478bd9Sstevel@tonic-gate 	lmap->efi_last_u_lba = vtoc->efi_last_u_lba;
704af007057Syl 	lmap->efi_altern_lba = vtoc->efi_altern_lba;
7057c478bd9Sstevel@tonic-gate 	lmap->efi_flags = vtoc->efi_flags;
7067c478bd9Sstevel@tonic-gate 	(void) memcpy((uchar_t *)&lmap->efi_disk_uguid,
707843e1988Sjohnlev 	    (uchar_t *)&vtoc->efi_disk_uguid, sizeof (struct uuid));
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate 	for (i = 0; i < nparts; i++) {
7107c478bd9Sstevel@tonic-gate 		lmap->efi_parts[i].p_tag = vtoc->efi_parts[i].p_tag;
7117c478bd9Sstevel@tonic-gate 		lmap->efi_parts[i].p_flag = vtoc->efi_parts[i].p_flag;
7127c478bd9Sstevel@tonic-gate 		lmap->efi_parts[i].p_start = vtoc->efi_parts[i].p_start;
7137c478bd9Sstevel@tonic-gate 		lmap->efi_parts[i].p_size = vtoc->efi_parts[i].p_size;
7147c478bd9Sstevel@tonic-gate 		(void) memcpy((uchar_t *)&lmap->efi_parts[i].p_uguid,
7157c478bd9Sstevel@tonic-gate 		    (uchar_t *)&vtoc->efi_parts[i].p_uguid,
7167c478bd9Sstevel@tonic-gate 		    sizeof (struct uuid));
7177c478bd9Sstevel@tonic-gate 		if (vtoc->efi_parts[i].p_tag == V_RESERVED) {
7187c478bd9Sstevel@tonic-gate 			bcopy(vtoc->efi_parts[i].p_name,
7197c478bd9Sstevel@tonic-gate 			    lmap->efi_parts[i].p_name, LEN_DKL_VVOL);
7207c478bd9Sstevel@tonic-gate 		}
7217c478bd9Sstevel@tonic-gate 	}
7227c478bd9Sstevel@tonic-gate 	return (0);
7237c478bd9Sstevel@tonic-gate }
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate /*
7267c478bd9Sstevel@tonic-gate  * Convert vtoc/geom to label.
7277c478bd9Sstevel@tonic-gate  */
7287c478bd9Sstevel@tonic-gate static int
vtoc_to_label(struct dk_label * label,struct extvtoc * vtoc,struct dk_geom * geom,struct dk_cinfo * cinfo)729342440ecSPrasad Singamsetty vtoc_to_label(struct dk_label *label, struct extvtoc *vtoc,
730342440ecSPrasad Singamsetty     struct dk_geom *geom, struct dk_cinfo *cinfo)
7317c478bd9Sstevel@tonic-gate {
7327c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
7337c478bd9Sstevel@tonic-gate 	struct dk_map32		*lmap;
7347c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
7357c478bd9Sstevel@tonic-gate 	struct dkl_partition	*lmap;
7367c478bd9Sstevel@tonic-gate #else
7377c478bd9Sstevel@tonic-gate #error No VTOC format defined.
7387c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
7397c478bd9Sstevel@tonic-gate 
740342440ecSPrasad Singamsetty 	struct extpartition	*vpart;
741342440ecSPrasad Singamsetty 	ulong_t			nblks;
7427c478bd9Sstevel@tonic-gate 	int			i;
7437c478bd9Sstevel@tonic-gate 
7447c478bd9Sstevel@tonic-gate 	(void) memset((char *)label, 0, sizeof (struct dk_label));
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate 	/*
7477c478bd9Sstevel@tonic-gate 	 * Sanity-check the vtoc
7487c478bd9Sstevel@tonic-gate 	 */
74965908c77Syu, larry liu - Sun Microsystems - Beijing China 	if (vtoc->v_sanity != VTOC_SANE ||
750843e1988Sjohnlev 	    vtoc->v_nparts != V_NUMPAR) {
7517c478bd9Sstevel@tonic-gate 		return (-1);
7527c478bd9Sstevel@tonic-gate 	}
7537c478bd9Sstevel@tonic-gate 
7547c478bd9Sstevel@tonic-gate 	/*
7557c478bd9Sstevel@tonic-gate 	 * Sanity check of geometry
7567c478bd9Sstevel@tonic-gate 	 */
7577c478bd9Sstevel@tonic-gate 	if (geom->dkg_ncyl == 0 || geom->dkg_nhead == 0 ||
758843e1988Sjohnlev 	    geom->dkg_nsect == 0) {
7597c478bd9Sstevel@tonic-gate 		return (-1);
7607c478bd9Sstevel@tonic-gate 	}
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate 	label->dkl_magic = DKL_MAGIC;
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate 	/*
7657c478bd9Sstevel@tonic-gate 	 * Copy necessary portions of the geometry information
7667c478bd9Sstevel@tonic-gate 	 */
7677c478bd9Sstevel@tonic-gate 	label->dkl_rpm = geom->dkg_rpm;
7687c478bd9Sstevel@tonic-gate 	label->dkl_pcyl = geom->dkg_pcyl;
7697c478bd9Sstevel@tonic-gate 	label->dkl_apc = geom->dkg_apc;
7707c478bd9Sstevel@tonic-gate 	label->dkl_intrlv = geom->dkg_intrlv;
7717c478bd9Sstevel@tonic-gate 	label->dkl_ncyl = geom->dkg_ncyl;
7727c478bd9Sstevel@tonic-gate 	label->dkl_acyl = geom->dkg_acyl;
7737c478bd9Sstevel@tonic-gate 
7747c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
7757c478bd9Sstevel@tonic-gate 	label->dkl_bcyl = geom->dkg_bcyl;
7767c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_16) */
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate 	label->dkl_nhead = geom->dkg_nhead;
7797c478bd9Sstevel@tonic-gate 	label->dkl_nsect = geom->dkg_nsect;
7807c478bd9Sstevel@tonic-gate 
7817c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
7827c478bd9Sstevel@tonic-gate 	label->dkl_obs1 = geom->dkg_obs1;
7837c478bd9Sstevel@tonic-gate 	label->dkl_obs2 = geom->dkg_obs2;
7847c478bd9Sstevel@tonic-gate 	label->dkl_obs3 = geom->dkg_obs3;
7857c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate 	label->dkl_write_reinstruct = geom->dkg_write_reinstruct;
7887c478bd9Sstevel@tonic-gate 	label->dkl_read_reinstruct = geom->dkg_read_reinstruct;
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate 	/*
7917c478bd9Sstevel@tonic-gate 	 * Copy vtoc structure fields into the disk label dk_vtoc
7927c478bd9Sstevel@tonic-gate 	 */
7937c478bd9Sstevel@tonic-gate 	label->dkl_vtoc.v_sanity = vtoc->v_sanity;
7947c478bd9Sstevel@tonic-gate 	label->dkl_vtoc.v_nparts = vtoc->v_nparts;
7957c478bd9Sstevel@tonic-gate 	label->dkl_vtoc.v_version = vtoc->v_version;
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 	(void) memcpy(label->dkl_vtoc.v_volume, vtoc->v_volume,
798843e1988Sjohnlev 	    LEN_DKL_VVOL);
7997c478bd9Sstevel@tonic-gate 	for (i = 0; i < V_NUMPAR; i++) {
8007c478bd9Sstevel@tonic-gate 		label->dkl_vtoc.v_part[i].p_tag = vtoc->v_part[i].p_tag;
8017c478bd9Sstevel@tonic-gate 		label->dkl_vtoc.v_part[i].p_flag = vtoc->v_part[i].p_flag;
802342440ecSPrasad Singamsetty 		label->dkl_vtoc.v_timestamp[i] = vtoc->timestamp[i];
8037c478bd9Sstevel@tonic-gate 	}
804342440ecSPrasad Singamsetty 
805342440ecSPrasad Singamsetty 	for (i = 0; i < 10; i++)
806342440ecSPrasad Singamsetty 		label->dkl_vtoc.v_reserved[i] = vtoc->v_reserved[i];
807342440ecSPrasad Singamsetty 
808342440ecSPrasad Singamsetty 	label->dkl_vtoc.v_bootinfo[0] = vtoc->v_bootinfo[0];
809342440ecSPrasad Singamsetty 	label->dkl_vtoc.v_bootinfo[1] = vtoc->v_bootinfo[1];
810342440ecSPrasad Singamsetty 	label->dkl_vtoc.v_bootinfo[2] = vtoc->v_bootinfo[2];
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate 	(void) memcpy(label->dkl_asciilabel, vtoc->v_asciilabel,
813843e1988Sjohnlev 	    LEN_DKL_ASCII);
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate 	/*
8167c478bd9Sstevel@tonic-gate 	 * Note the conversion from starting sector number
8177c478bd9Sstevel@tonic-gate 	 * to starting cylinder number.
8187c478bd9Sstevel@tonic-gate 	 * Return error if division results in a remainder.
819843e1988Sjohnlev 	 *
820843e1988Sjohnlev 	 * Note: don't check, if probing virtual disk in Xen
821843e1988Sjohnlev 	 * for that virtual disk will use fabricated # of headers
822843e1988Sjohnlev 	 * and sectors per track which may cause the capacity
823843e1988Sjohnlev 	 * not multiple of # of blocks per cylinder
8247c478bd9Sstevel@tonic-gate 	 */
8257c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
8267c478bd9Sstevel@tonic-gate 	lmap = label->dkl_map;
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
8297c478bd9Sstevel@tonic-gate 	lmap = label->dkl_vtoc.v_part;
8307c478bd9Sstevel@tonic-gate #else
8317c478bd9Sstevel@tonic-gate #error No VTOC format defined.
8327c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
8337c478bd9Sstevel@tonic-gate 
8347c478bd9Sstevel@tonic-gate 	vpart = vtoc->v_part;
8357c478bd9Sstevel@tonic-gate 
836342440ecSPrasad Singamsetty 	nblks = label->dkl_nsect * label->dkl_nhead;
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++, lmap++, vpart++) {
839843e1988Sjohnlev 		if (cinfo->dki_ctype != DKC_VBD) {
840843e1988Sjohnlev 			if ((vpart->p_start % nblks) != 0 ||
841843e1988Sjohnlev 			    (vpart->p_size % nblks) != 0) {
842843e1988Sjohnlev 				return (-1);
843843e1988Sjohnlev 			}
8447c478bd9Sstevel@tonic-gate 		}
8457c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
846342440ecSPrasad Singamsetty 		lmap->dkl_cylno = (blkaddr32_t)(vpart->p_start / nblks);
847342440ecSPrasad Singamsetty 		lmap->dkl_nblk = (blkaddr32_t)vpart->p_size;
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
850342440ecSPrasad Singamsetty 		lmap->p_start = (blkaddr32_t)vpart->p_start;
851342440ecSPrasad Singamsetty 		lmap->p_size = (blkaddr32_t)vpart->p_size;
8527c478bd9Sstevel@tonic-gate #else
8537c478bd9Sstevel@tonic-gate #error No VTOC format defined.
8547c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
8557c478bd9Sstevel@tonic-gate 	}
8567c478bd9Sstevel@tonic-gate 
8577c478bd9Sstevel@tonic-gate 	/*
8587c478bd9Sstevel@tonic-gate 	 * Finally, make a checksum
8597c478bd9Sstevel@tonic-gate 	 */
8607c478bd9Sstevel@tonic-gate 	(void) checksum(label, CK_MAKESUM);
8617c478bd9Sstevel@tonic-gate 
862342440ecSPrasad Singamsetty #ifdef DEBUG
863342440ecSPrasad Singamsetty 	if (option_msg && diag_msg)
864342440ecSPrasad Singamsetty 		dump_label(label);
865342440ecSPrasad Singamsetty #endif
8667c478bd9Sstevel@tonic-gate 	return (0);
8677c478bd9Sstevel@tonic-gate }
8687c478bd9Sstevel@tonic-gate 
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate /*
8727c478bd9Sstevel@tonic-gate  * Extract a vtoc structure out of a valid label
8737c478bd9Sstevel@tonic-gate  */
8747c478bd9Sstevel@tonic-gate int
label_to_vtoc(struct extvtoc * vtoc,struct dk_label * label)875342440ecSPrasad Singamsetty label_to_vtoc(struct extvtoc *vtoc, struct dk_label *label)
8767c478bd9Sstevel@tonic-gate {
8777c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
8787c478bd9Sstevel@tonic-gate 	struct dk_map2		*lpart;
8797c478bd9Sstevel@tonic-gate 	struct dk_map32		*lmap;
880342440ecSPrasad Singamsetty 	ulong_t			nblks;
8817c478bd9Sstevel@tonic-gate 
8827c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
8837c478bd9Sstevel@tonic-gate 	struct dkl_partition	*lpart;
8847c478bd9Sstevel@tonic-gate #else
8857c478bd9Sstevel@tonic-gate #error No VTOC format defined.
8867c478bd9Sstevel@tonic-gate #endif				/* defined(_SUNOS_VTOC_8) */
8877c478bd9Sstevel@tonic-gate 
888342440ecSPrasad Singamsetty 	struct extpartition	*vpart;
8897c478bd9Sstevel@tonic-gate 	int			i;
8907c478bd9Sstevel@tonic-gate 
891342440ecSPrasad Singamsetty 	(void) memset((char *)vtoc, 0, sizeof (struct extvtoc));
8927c478bd9Sstevel@tonic-gate 
8937c478bd9Sstevel@tonic-gate 	switch (label->dkl_vtoc.v_version) {
8947c478bd9Sstevel@tonic-gate 	case 0:
8957c478bd9Sstevel@tonic-gate 		/*
8967c478bd9Sstevel@tonic-gate 		 * No valid vtoc information in the label.
8977c478bd9Sstevel@tonic-gate 		 * Construct default p_flags and p_tags.
8987c478bd9Sstevel@tonic-gate 		 */
8997c478bd9Sstevel@tonic-gate 		vpart = vtoc->v_part;
9007c478bd9Sstevel@tonic-gate 		for (i = 0; i < V_NUMPAR; i++, vpart++) {
9017c478bd9Sstevel@tonic-gate 			vpart->p_tag = default_vtoc_map[i].p_tag;
9027c478bd9Sstevel@tonic-gate 			vpart->p_flag = default_vtoc_map[i].p_flag;
9037c478bd9Sstevel@tonic-gate 		}
9047c478bd9Sstevel@tonic-gate 		break;
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate 	case V_VERSION:
9077c478bd9Sstevel@tonic-gate 		vpart = vtoc->v_part;
9087c478bd9Sstevel@tonic-gate 		lpart = label->dkl_vtoc.v_part;
9097c478bd9Sstevel@tonic-gate 		for (i = 0; i < V_NUMPAR; i++, vpart++, lpart++) {
9107c478bd9Sstevel@tonic-gate 			vpart->p_tag = lpart->p_tag;
9117c478bd9Sstevel@tonic-gate 			vpart->p_flag = lpart->p_flag;
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
914342440ecSPrasad Singamsetty 			vpart->p_start = (diskaddr_t)lpart->p_start;
915342440ecSPrasad Singamsetty 			vpart->p_size = (diskaddr_t)lpart->p_size;
9167c478bd9Sstevel@tonic-gate #endif	/* defined(_SUNOS_VTOC_16) */
917342440ecSPrasad Singamsetty 			vtoc->timestamp[i] = label->dkl_vtoc.v_timestamp[i];
9187c478bd9Sstevel@tonic-gate 		}
9197c478bd9Sstevel@tonic-gate 		(void) memcpy(vtoc->v_volume, label->dkl_vtoc.v_volume,
920843e1988Sjohnlev 		    LEN_DKL_VVOL);
921342440ecSPrasad Singamsetty 
922342440ecSPrasad Singamsetty 		for (i = 0; i < 10; i++)
923342440ecSPrasad Singamsetty 			vtoc->v_reserved[i] = label->dkl_vtoc.v_reserved[i];
924342440ecSPrasad Singamsetty 
925342440ecSPrasad Singamsetty 		vtoc->v_bootinfo[0] = label->dkl_vtoc.v_bootinfo[0];
926342440ecSPrasad Singamsetty 		vtoc->v_bootinfo[1] = label->dkl_vtoc.v_bootinfo[1];
927342440ecSPrasad Singamsetty 		vtoc->v_bootinfo[2] = label->dkl_vtoc.v_bootinfo[2];
9287c478bd9Sstevel@tonic-gate 		break;
9297c478bd9Sstevel@tonic-gate 
9307c478bd9Sstevel@tonic-gate 	default:
9317c478bd9Sstevel@tonic-gate 		return (-1);
9327c478bd9Sstevel@tonic-gate 	}
9337c478bd9Sstevel@tonic-gate 
9347c478bd9Sstevel@tonic-gate 	/*
9357c478bd9Sstevel@tonic-gate 	 * XXX - this looks wrong to me....
9367c478bd9Sstevel@tonic-gate 	 * why are these values hardwired, rather than returned from
9377c478bd9Sstevel@tonic-gate 	 * the real disk label?
9387c478bd9Sstevel@tonic-gate 	 */
9397c478bd9Sstevel@tonic-gate 	vtoc->v_sanity = VTOC_SANE;
9407c478bd9Sstevel@tonic-gate 	vtoc->v_version = V_VERSION;
94165908c77Syu, larry liu - Sun Microsystems - Beijing China 	vtoc->v_sectorsz = cur_blksz;
9427c478bd9Sstevel@tonic-gate 	vtoc->v_nparts = V_NUMPAR;
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate 	(void) memcpy(vtoc->v_asciilabel, label->dkl_asciilabel,
945843e1988Sjohnlev 	    LEN_DKL_ASCII);
9467c478bd9Sstevel@tonic-gate 
9477c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
9487c478bd9Sstevel@tonic-gate 	/*
9497c478bd9Sstevel@tonic-gate 	 * Convert partitioning information.
9507c478bd9Sstevel@tonic-gate 	 * Note the conversion from starting cylinder number
9517c478bd9Sstevel@tonic-gate 	 * to starting sector number.
9527c478bd9Sstevel@tonic-gate 	 */
9537c478bd9Sstevel@tonic-gate 	lmap = label->dkl_map;
9547c478bd9Sstevel@tonic-gate 	vpart = vtoc->v_part;
9557c478bd9Sstevel@tonic-gate 	nblks = label->dkl_nsect * label->dkl_nhead;
9567c478bd9Sstevel@tonic-gate 	for (i = 0; i < V_NUMPAR; i++, vpart++, lmap++) {
957342440ecSPrasad Singamsetty 		vpart->p_start = (diskaddr_t)(lmap->dkl_cylno * nblks);
958342440ecSPrasad Singamsetty 		vpart->p_size = (diskaddr_t)lmap->dkl_nblk;
9597c478bd9Sstevel@tonic-gate 	}
9607c478bd9Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
9617c478bd9Sstevel@tonic-gate 
9627c478bd9Sstevel@tonic-gate 	return (0);
9637c478bd9Sstevel@tonic-gate }
9647c478bd9Sstevel@tonic-gate 
9657c478bd9Sstevel@tonic-gate /*
9667c478bd9Sstevel@tonic-gate  * Input: File descriptor
967342440ecSPrasad Singamsetty  * Output: 1 if disk has an EFI label, 0 otherwise.
9687c478bd9Sstevel@tonic-gate  */
9697c478bd9Sstevel@tonic-gate 
9707c478bd9Sstevel@tonic-gate int
is_efi_type(int fd)9717c478bd9Sstevel@tonic-gate is_efi_type(int fd)
9727c478bd9Sstevel@tonic-gate {
973342440ecSPrasad Singamsetty 	struct extvtoc vtoc;
9747c478bd9Sstevel@tonic-gate 
975342440ecSPrasad Singamsetty 	if (read_extvtoc(fd, &vtoc) == VT_ENOTSUP) {
976342440ecSPrasad Singamsetty 		/* assume the disk has EFI label */
977342440ecSPrasad Singamsetty 		return (1);
9787c478bd9Sstevel@tonic-gate 	}
9797c478bd9Sstevel@tonic-gate 	return (0);
9807c478bd9Sstevel@tonic-gate }
9817c478bd9Sstevel@tonic-gate 
982342440ecSPrasad Singamsetty #ifdef	DEBUG
983342440ecSPrasad Singamsetty static void
dump_label(struct dk_label * label)98432a71e42SToomas Soome dump_label(struct dk_label *label)
9857c478bd9Sstevel@tonic-gate {
9867c478bd9Sstevel@tonic-gate 	int		i;
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 	fmt_print("%s\n", label->dkl_asciilabel);
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate 	fmt_print("version:  %d\n", label->dkl_vtoc.v_version);
9917c478bd9Sstevel@tonic-gate 	fmt_print("volume:   ");
9927c478bd9Sstevel@tonic-gate 	for (i = 0; i < LEN_DKL_VVOL; i++) {
9937c478bd9Sstevel@tonic-gate 		if (label->dkl_vtoc.v_volume[i] == 0)
9947c478bd9Sstevel@tonic-gate 			break;
9957c478bd9Sstevel@tonic-gate 		fmt_print("%c", label->dkl_vtoc.v_volume[i]);
9967c478bd9Sstevel@tonic-gate 	}
9977c478bd9Sstevel@tonic-gate 	fmt_print("\n");
9987c478bd9Sstevel@tonic-gate 	fmt_print("v_nparts: %d\n", label->dkl_vtoc.v_nparts);
9997c478bd9Sstevel@tonic-gate 	fmt_print("v_sanity: %lx\n", label->dkl_vtoc.v_sanity);
10007c478bd9Sstevel@tonic-gate 
10017c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
10027c478bd9Sstevel@tonic-gate 	fmt_print("rpm:      %d\n", label->dkl_rpm);
10037c478bd9Sstevel@tonic-gate 	fmt_print("pcyl:     %d\n", label->dkl_pcyl);
10047c478bd9Sstevel@tonic-gate 	fmt_print("apc:      %d\n", label->dkl_apc);
10057c478bd9Sstevel@tonic-gate 	fmt_print("obs1:     %d\n", label->dkl_obs1);
10067c478bd9Sstevel@tonic-gate 	fmt_print("obs2:     %d\n", label->dkl_obs2);
10077c478bd9Sstevel@tonic-gate 	fmt_print("intrlv:   %d\n", label->dkl_intrlv);
10087c478bd9Sstevel@tonic-gate 	fmt_print("ncyl:     %d\n", label->dkl_ncyl);
10097c478bd9Sstevel@tonic-gate 	fmt_print("acyl:     %d\n", label->dkl_acyl);
10107c478bd9Sstevel@tonic-gate 	fmt_print("nhead:    %d\n", label->dkl_nhead);
10117c478bd9Sstevel@tonic-gate 	fmt_print("nsect:    %d\n", label->dkl_nsect);
10127c478bd9Sstevel@tonic-gate 	fmt_print("obs3:     %d\n", label->dkl_obs3);
10137c478bd9Sstevel@tonic-gate 	fmt_print("obs4:     %d\n", label->dkl_obs4);
10147c478bd9Sstevel@tonic-gate 
10157c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
10167c478bd9Sstevel@tonic-gate 	fmt_print("rpm:      %d\n", label->dkl_rpm);
10177c478bd9Sstevel@tonic-gate 	fmt_print("pcyl:     %d\n", label->dkl_pcyl);
10187c478bd9Sstevel@tonic-gate 	fmt_print("apc:      %d\n", label->dkl_apc);
10197c478bd9Sstevel@tonic-gate 	fmt_print("intrlv:   %d\n", label->dkl_intrlv);
10207c478bd9Sstevel@tonic-gate 	fmt_print("ncyl:     %d\n", label->dkl_ncyl);
10217c478bd9Sstevel@tonic-gate 	fmt_print("acyl:     %d\n", label->dkl_acyl);
10227c478bd9Sstevel@tonic-gate 	fmt_print("nhead:    %d\n", label->dkl_nhead);
10237c478bd9Sstevel@tonic-gate 	fmt_print("nsect:    %d\n", label->dkl_nsect);
10247c478bd9Sstevel@tonic-gate 	fmt_print("bcyl:     %d\n", label->dkl_bcyl);
10257c478bd9Sstevel@tonic-gate 	fmt_print("skew:     %d\n", label->dkl_skew);
10267c478bd9Sstevel@tonic-gate #else
10277c478bd9Sstevel@tonic-gate #error No VTOC format defined.
10287c478bd9Sstevel@tonic-gate #endif				/* defined(_SUNOS_VTOC_8) */
10297c478bd9Sstevel@tonic-gate 	fmt_print("magic:    %0x\n", label->dkl_magic);
10307c478bd9Sstevel@tonic-gate 	fmt_print("cksum:    %0x\n", label->dkl_cksum);
10317c478bd9Sstevel@tonic-gate 
10327c478bd9Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
10337c478bd9Sstevel@tonic-gate 
10347c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
10357c478bd9Sstevel@tonic-gate 		fmt_print("%c:        cyl=%d, blocks=%d", i+'a',
103632a71e42SToomas Soome 		    label->dkl_map[i].dkl_cylno,
103732a71e42SToomas Soome 		    label->dkl_map[i].dkl_nblk);
10387c478bd9Sstevel@tonic-gate 
10397c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
1040342440ecSPrasad Singamsetty 		fmt_print("%c:        start=%u, blocks=%u", i+'a',
10417c478bd9Sstevel@tonic-gate 		    label->dkl_vtoc.v_part[i].p_start,
10427c478bd9Sstevel@tonic-gate 		    label->dkl_vtoc.v_part[i].p_size);
10437c478bd9Sstevel@tonic-gate #else
10447c478bd9Sstevel@tonic-gate #error No VTOC format defined.
10457c478bd9Sstevel@tonic-gate #endif				/* defined(_SUNOS_VTOC_8) */
10467c478bd9Sstevel@tonic-gate 
10477c478bd9Sstevel@tonic-gate 		fmt_print(",  tag=%d,  flag=%d",
104832a71e42SToomas Soome 		    label->dkl_vtoc.v_part[i].p_tag,
104932a71e42SToomas Soome 		    label->dkl_vtoc.v_part[i].p_flag);
10507c478bd9Sstevel@tonic-gate 		fmt_print("\n");
10517c478bd9Sstevel@tonic-gate 	}
10527c478bd9Sstevel@tonic-gate 
10537c478bd9Sstevel@tonic-gate 	fmt_print("read_reinstruct:  %d\n", label->dkl_read_reinstruct);
10547c478bd9Sstevel@tonic-gate 	fmt_print("write_reinstruct: %d\n", label->dkl_write_reinstruct);
10557c478bd9Sstevel@tonic-gate 
10567c478bd9Sstevel@tonic-gate 	fmt_print("bootinfo: ");
10577c478bd9Sstevel@tonic-gate 	for (i = 0; i < 3; i++) {
10587c478bd9Sstevel@tonic-gate 		fmt_print("0x%x ", label->dkl_vtoc.v_bootinfo[i]);
10597c478bd9Sstevel@tonic-gate 	}
10607c478bd9Sstevel@tonic-gate 	fmt_print("\n");
10617c478bd9Sstevel@tonic-gate 
10627c478bd9Sstevel@tonic-gate 	fmt_print("reserved: ");
10637c478bd9Sstevel@tonic-gate 	for (i = 0; i < 10; i++) {
10647c478bd9Sstevel@tonic-gate 		if ((i % 4) == 3)
10657c478bd9Sstevel@tonic-gate 			fmt_print("\n");
10667c478bd9Sstevel@tonic-gate 		fmt_print("0x%x ", label->dkl_vtoc.v_reserved[i]);
10677c478bd9Sstevel@tonic-gate 	}
10687c478bd9Sstevel@tonic-gate 	fmt_print("\n");
10697c478bd9Sstevel@tonic-gate 
10707c478bd9Sstevel@tonic-gate 	fmt_print("timestamp:\n");
10717c478bd9Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
10727c478bd9Sstevel@tonic-gate 		if ((i % 4) == 3)
10737c478bd9Sstevel@tonic-gate 			fmt_print("\n");
10747c478bd9Sstevel@tonic-gate 		fmt_print("0x%x ", label->dkl_vtoc.v_timestamp[i]);
10757c478bd9Sstevel@tonic-gate 	}
10767c478bd9Sstevel@tonic-gate 	fmt_print("\n");
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate 	fmt_print("pad:\n");
10797c478bd9Sstevel@tonic-gate 	dump("", label->dkl_pad, LEN_DKL_PAD, HEX_ONLY);
10807c478bd9Sstevel@tonic-gate 
10817c478bd9Sstevel@tonic-gate 	fmt_print("\n\n");
10827c478bd9Sstevel@tonic-gate }
1083342440ecSPrasad Singamsetty #endif	/* DEBUG */
1084