xref: /onnv-gate/usr/src/cmd/format/label.c (revision 13093:48f2dbca79a2)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52083Szl149053  * Common Development and Distribution License (the "License").
62083Szl149053  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*13093SRoger.Faulkner@Oracle.COM 
220Sstevel@tonic-gate /*
23*13093SRoger.Faulkner@Oracle.COM  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * This file contains the code relating to label manipulation.
280Sstevel@tonic-gate  */
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #include <string.h>
310Sstevel@tonic-gate #include <stdlib.h>
320Sstevel@tonic-gate #include <memory.h>
330Sstevel@tonic-gate #include <sys/isa_defs.h>
340Sstevel@tonic-gate #include <sys/efi_partition.h>
350Sstevel@tonic-gate #include <sys/vtoc.h>
360Sstevel@tonic-gate #include <sys/uuid.h>
370Sstevel@tonic-gate #include <errno.h>
38786Slclee #include <devid.h>
39*13093SRoger.Faulkner@Oracle.COM #include "global.h"
40*13093SRoger.Faulkner@Oracle.COM #include "label.h"
41*13093SRoger.Faulkner@Oracle.COM #include "misc.h"
42*13093SRoger.Faulkner@Oracle.COM #include "main.h"
43*13093SRoger.Faulkner@Oracle.COM #include "partition.h"
44*13093SRoger.Faulkner@Oracle.COM #include "ctlr_scsi.h"
45*13093SRoger.Faulkner@Oracle.COM #include "checkdev.h"
460Sstevel@tonic-gate 
470Sstevel@tonic-gate #if defined(_FIRMWARE_NEEDS_FDISK)
480Sstevel@tonic-gate #include <sys/dktp/fdisk.h>
490Sstevel@tonic-gate #include "menu_fdisk.h"
500Sstevel@tonic-gate #endif		/* defined(_FIRMWARE_NEEDS_FDISK) */
510Sstevel@tonic-gate 
520Sstevel@tonic-gate #ifndef	WD_NODE
530Sstevel@tonic-gate #define	WD_NODE		7
540Sstevel@tonic-gate #endif
550Sstevel@tonic-gate 
560Sstevel@tonic-gate #ifdef	__STDC__
570Sstevel@tonic-gate /*
580Sstevel@tonic-gate  * Prototypes for ANSI C compilers
590Sstevel@tonic-gate  */
600Sstevel@tonic-gate static int	do_geometry_sanity_check(void);
617563SPrasad.Singamsetty@Sun.COM static int	vtoc_to_label(struct dk_label *label, struct extvtoc *vtoc,
625084Sjohnlev 		struct dk_geom *geom, struct dk_cinfo *cinfo);
637563SPrasad.Singamsetty@Sun.COM extern int	read_extvtoc(int, struct extvtoc *);
647563SPrasad.Singamsetty@Sun.COM extern int	write_extvtoc(int, struct extvtoc *);
650Sstevel@tonic-gate static int	vtoc64_to_label(struct efi_info *, struct dk_gpt *);
660Sstevel@tonic-gate 
670Sstevel@tonic-gate #else	/* __STDC__ */
680Sstevel@tonic-gate 
690Sstevel@tonic-gate /*
700Sstevel@tonic-gate  * Prototypes for non-ANSI C compilers
710Sstevel@tonic-gate  */
720Sstevel@tonic-gate static int	do_geometry_sanity_check();
730Sstevel@tonic-gate static int	vtoc_to_label();
747563SPrasad.Singamsetty@Sun.COM extern int	read_extvtoc();
757563SPrasad.Singamsetty@Sun.COM extern int	write_extvtoc();
760Sstevel@tonic-gate static int	vtoc64_to_label();
770Sstevel@tonic-gate 
780Sstevel@tonic-gate #endif	/* __STDC__ */
790Sstevel@tonic-gate 
807563SPrasad.Singamsetty@Sun.COM #ifdef	DEBUG
817563SPrasad.Singamsetty@Sun.COM static void dump_label(struct dk_label *label);
827563SPrasad.Singamsetty@Sun.COM #endif
837563SPrasad.Singamsetty@Sun.COM 
840Sstevel@tonic-gate /*
850Sstevel@tonic-gate  * This routine checks the given label to see if it is valid.
860Sstevel@tonic-gate  */
870Sstevel@tonic-gate int
checklabel(label)880Sstevel@tonic-gate checklabel(label)
890Sstevel@tonic-gate 	register struct dk_label *label;
900Sstevel@tonic-gate {
910Sstevel@tonic-gate 
920Sstevel@tonic-gate 	/*
930Sstevel@tonic-gate 	 * Check the magic number.
940Sstevel@tonic-gate 	 */
950Sstevel@tonic-gate 	if (label->dkl_magic != DKL_MAGIC)
960Sstevel@tonic-gate 		return (0);
970Sstevel@tonic-gate 	/*
980Sstevel@tonic-gate 	 * Check the checksum.
990Sstevel@tonic-gate 	 */
1000Sstevel@tonic-gate 	if (checksum(label, CK_CHECKSUM) != 0)
1010Sstevel@tonic-gate 		return (0);
1020Sstevel@tonic-gate 	return (1);
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate /*
1060Sstevel@tonic-gate  * This routine checks or calculates the label checksum, depending on
1070Sstevel@tonic-gate  * the mode it is called in.
1080Sstevel@tonic-gate  */
1090Sstevel@tonic-gate int
checksum(label,mode)1100Sstevel@tonic-gate checksum(label, mode)
1110Sstevel@tonic-gate 	struct	dk_label *label;
1120Sstevel@tonic-gate 	int	mode;
1130Sstevel@tonic-gate {
1140Sstevel@tonic-gate 	register short *sp, sum = 0;
1150Sstevel@tonic-gate 	register short count = (sizeof (struct dk_label)) / (sizeof (short));
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 	/*
1180Sstevel@tonic-gate 	 * If we are generating a checksum, don't include the checksum
1190Sstevel@tonic-gate 	 * in the rolling xor.
1200Sstevel@tonic-gate 	 */
1210Sstevel@tonic-gate 	if (mode == CK_MAKESUM)
1220Sstevel@tonic-gate 		count -= 1;
1230Sstevel@tonic-gate 	sp = (short *)label;
1240Sstevel@tonic-gate 	/*
1250Sstevel@tonic-gate 	 * Take the xor of all the half-words in the label.
1260Sstevel@tonic-gate 	 */
1270Sstevel@tonic-gate 	while (count--) {
1280Sstevel@tonic-gate 		sum ^= *sp++;
1290Sstevel@tonic-gate 	}
1300Sstevel@tonic-gate 	/*
1310Sstevel@tonic-gate 	 * If we are checking the checksum, the total will be zero for
1320Sstevel@tonic-gate 	 * a correct checksum, so we can just return the sum.
1330Sstevel@tonic-gate 	 */
1340Sstevel@tonic-gate 	if (mode == CK_CHECKSUM)
1350Sstevel@tonic-gate 		return (sum);
1360Sstevel@tonic-gate 	/*
1370Sstevel@tonic-gate 	 * If we are generating the checksum, fill it in.
1380Sstevel@tonic-gate 	 */
1390Sstevel@tonic-gate 	else {
1400Sstevel@tonic-gate 		label->dkl_cksum = sum;
1410Sstevel@tonic-gate 		return (0);
1420Sstevel@tonic-gate 	}
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate /*
1460Sstevel@tonic-gate  * This routine is used to extract the id string from the string stored
1470Sstevel@tonic-gate  * in a disk label.  The problem is that the string in the label has
1480Sstevel@tonic-gate  * the physical characteristics of the drive appended to it.  The approach
1490Sstevel@tonic-gate  * is to find the beginning of the physical attributes portion of the string
1500Sstevel@tonic-gate  * and truncate it there.
1510Sstevel@tonic-gate  */
1520Sstevel@tonic-gate int
trim_id(id)1530Sstevel@tonic-gate trim_id(id)
1540Sstevel@tonic-gate 	char	*id;
1550Sstevel@tonic-gate {
1560Sstevel@tonic-gate 	register char *c;
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 	/*
1590Sstevel@tonic-gate 	 * Start at the end of the string.  When we match the word ' cyl',
1600Sstevel@tonic-gate 	 * we are at the beginning of the attributes.
1610Sstevel@tonic-gate 	 */
1620Sstevel@tonic-gate 	for (c = id + strlen(id); c >= id; c--) {
1630Sstevel@tonic-gate 		if (strncmp(c, " cyl", strlen(" cyl")) == 0) {
1640Sstevel@tonic-gate 			/*
1650Sstevel@tonic-gate 			 * Remove any white space.
1660Sstevel@tonic-gate 			 */
1670Sstevel@tonic-gate 			for (; (((*(c - 1) == ' ') || (*(c - 1) == '\t')) &&
1680Sstevel@tonic-gate 				(c >= id)); c--);
1690Sstevel@tonic-gate 			break;
1700Sstevel@tonic-gate 		}
1710Sstevel@tonic-gate 	}
1720Sstevel@tonic-gate 	/*
1730Sstevel@tonic-gate 	 * If we ran off the beginning of the string, something is wrong.
1740Sstevel@tonic-gate 	 */
1750Sstevel@tonic-gate 	if (c < id)
1760Sstevel@tonic-gate 		return (-1);
1770Sstevel@tonic-gate 	/*
1780Sstevel@tonic-gate 	 * Truncate the string.
1790Sstevel@tonic-gate 	 */
1800Sstevel@tonic-gate 	*c = '\0';
1810Sstevel@tonic-gate 	return (0);
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate /*
1850Sstevel@tonic-gate  * This routine is used by write_label() to do a quick sanity check on the
1860Sstevel@tonic-gate  * supplied geometry. This is not a thorough check.
1870Sstevel@tonic-gate  *
1880Sstevel@tonic-gate  * The SCSI READ_CAPACITY command is used here to get the capacity of the
1890Sstevel@tonic-gate  * disk. But, the available area to store data on a disk is usually less
1900Sstevel@tonic-gate  * than this. So, if the specified geometry evaluates to a value which falls
1910Sstevel@tonic-gate  * in this margin, then such illegal geometries can slip through the cracks.
1920Sstevel@tonic-gate  */
1930Sstevel@tonic-gate static int
do_geometry_sanity_check()1940Sstevel@tonic-gate do_geometry_sanity_check()
1950Sstevel@tonic-gate {
1960Sstevel@tonic-gate 	struct scsi_capacity_16	 capacity;
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 	if (uscsi_read_capacity(cur_file, &capacity)) {
1990Sstevel@tonic-gate 		err_print("Warning: Unable to get capacity."
2005084Sjohnlev 		    " Cannot check geometry\n");
2010Sstevel@tonic-gate 		return (0);	/* Just ignore this problem */
2020Sstevel@tonic-gate 	}
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate 	if (capacity.sc_capacity < ncyl * nhead * nsect) {
2050Sstevel@tonic-gate 		err_print("\nWarning: Current geometry overshoots "
2065084Sjohnlev 		    "actual geometry of disk\n\n");
2070Sstevel@tonic-gate 		if (check("Continue labelling disk") != 0)
2080Sstevel@tonic-gate 			return (-1);
2090Sstevel@tonic-gate 		return (0);	/* Just ignore this problem */
2100Sstevel@tonic-gate 	}
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 	return (0);
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate /*
2161060Sgz161490  * create a clear EFI partition table when format is used
2177563SPrasad.Singamsetty@Sun.COM  * to convert an SMI label to an EFI label
2180Sstevel@tonic-gate  */
2190Sstevel@tonic-gate int
SMI_vtoc_to_EFI(int fd,struct dk_gpt ** new_vtoc)2201067Sgz161490 SMI_vtoc_to_EFI(int fd, struct dk_gpt **new_vtoc)
2210Sstevel@tonic-gate {
2221060Sgz161490 	int i;
2231060Sgz161490 	struct dk_gpt	*efi;
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	if (efi_alloc_and_init(fd, EFI_NUMPAR, new_vtoc) != 0) {
2265084Sjohnlev 		err_print("SMI vtoc to EFI failed\n");
2275084Sjohnlev 		return (-1);
2280Sstevel@tonic-gate 	}
2291060Sgz161490 	efi = *new_vtoc;
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 	/*
2321060Sgz161490 	 * create a clear EFI partition table:
2331060Sgz161490 	 * s0 takes the whole disk except the primary EFI lable,
2341060Sgz161490 	 * backup EFI labels, and the reserved partition.
2351060Sgz161490 	 * s1-s6 are unassigned slices.
2360Sstevel@tonic-gate 	 */
2371060Sgz161490 	efi->efi_parts[0].p_tag = V_USR;
2381060Sgz161490 	efi->efi_parts[0].p_start = efi->efi_first_u_lba;
2391060Sgz161490 	efi->efi_parts[0].p_size = efi->efi_last_u_lba - efi->efi_first_u_lba
2404304Syl194034 	    - EFI_MIN_RESV_SIZE + 1;
2410Sstevel@tonic-gate 
2421060Sgz161490 	/*
2431060Sgz161490 	 * s1-s6 are unassigned slices
2441060Sgz161490 	 */
2451060Sgz161490 	for (i = 1; i < efi->efi_nparts - 2; i++) {
2461060Sgz161490 		efi->efi_parts[i].p_tag = V_UNASSIGNED;
2471060Sgz161490 		efi->efi_parts[i].p_start = 0;
2481060Sgz161490 		efi->efi_parts[i].p_size = 0;
2490Sstevel@tonic-gate 	}
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 	/*
2521060Sgz161490 	 * the reserved slice
2530Sstevel@tonic-gate 	 */
2541060Sgz161490 	efi->efi_parts[efi->efi_nparts - 1].p_tag = V_RESERVED;
2551060Sgz161490 	efi->efi_parts[efi->efi_nparts - 1].p_start =
2564304Syl194034 	    efi->efi_last_u_lba - EFI_MIN_RESV_SIZE + 1;
2571060Sgz161490 	efi->efi_parts[efi->efi_nparts - 1].p_size = EFI_MIN_RESV_SIZE;
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate 	return (0);
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate /*
2630Sstevel@tonic-gate  * This routine constructs and writes a label on the disk.  It writes both
2640Sstevel@tonic-gate  * the primary and backup labels.  It assumes that there is a current
2650Sstevel@tonic-gate  * partition map already defined.  It also notifies the SunOS kernel of
2660Sstevel@tonic-gate  * the label and partition information it has written on the disk.
2670Sstevel@tonic-gate  */
2680Sstevel@tonic-gate int
write_label()2690Sstevel@tonic-gate write_label()
2700Sstevel@tonic-gate {
2710Sstevel@tonic-gate 	int	error = 0, head, sec;
2720Sstevel@tonic-gate 	struct dk_label label;
2737563SPrasad.Singamsetty@Sun.COM 	struct extvtoc	vtoc;
2740Sstevel@tonic-gate 	struct dk_geom	geom;
2750Sstevel@tonic-gate 	struct dk_gpt	*vtoc64;
2760Sstevel@tonic-gate 	int		nbackups;
2779889SLarry.Liu@Sun.COM 	char		*new_label;
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
2800Sstevel@tonic-gate 	int i;
2810Sstevel@tonic-gate #endif		/* defined(_SUNOS_VTOC_8) */
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate 	/*
2845421Smishra 	 * Check to see if any partitions used for svm, vxvm or live upgrade
2855421Smishra 	 * are on the disk. If so, refuse to label the disk, but only
2865421Smishra 	 * if we are trying to shrink a partition in use.
2875421Smishra 	 */
2885421Smishra 	if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
2895421Smishra 	    (diskaddr_t)-1, 0, 1)) {
2905421Smishra 		err_print("Cannot label disk when "
2915421Smishra 		    "partitions are in use as described.\n");
2925421Smishra 		return (-1);
2935421Smishra 	}
2945421Smishra 
2955421Smishra 	/*
2960Sstevel@tonic-gate 	 * If EFI label, then write it out to disk
2970Sstevel@tonic-gate 	 */
2980Sstevel@tonic-gate 	if (cur_label == L_TYPE_EFI) {
2995084Sjohnlev 		enter_critical();
3005084Sjohnlev 		vtoc64 = cur_parts->etoc;
3015084Sjohnlev 		err_check(vtoc64);
3025084Sjohnlev 		if (efi_write(cur_file, vtoc64) != 0) {
3035084Sjohnlev 			err_print("Warning: error writing EFI.\n");
3045084Sjohnlev 			error = -1;
3055084Sjohnlev 			}
3060Sstevel@tonic-gate 
3075084Sjohnlev 		cur_disk->disk_flags |= DSK_LABEL;
3085084Sjohnlev 		exit_critical();
3095084Sjohnlev 		return (error);
3100Sstevel@tonic-gate 	}
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate 	/*
3130Sstevel@tonic-gate 	 * Fill in a label structure with the geometry information.
3140Sstevel@tonic-gate 	 */
3150Sstevel@tonic-gate 	(void) memset((char *)&label, 0, sizeof (struct dk_label));
3169889SLarry.Liu@Sun.COM 	new_label = zalloc(cur_blksz);
3179889SLarry.Liu@Sun.COM 
3180Sstevel@tonic-gate 	label.dkl_pcyl = pcyl;
3190Sstevel@tonic-gate 	label.dkl_ncyl = ncyl;
3200Sstevel@tonic-gate 	label.dkl_acyl = acyl;
3210Sstevel@tonic-gate 
3220Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3230Sstevel@tonic-gate 	label.dkl_bcyl = bcyl;
3240Sstevel@tonic-gate #endif			/* defined(_SUNOC_VTOC_16) */
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate 	label.dkl_nhead = nhead;
3270Sstevel@tonic-gate 	label.dkl_nsect = nsect;
3280Sstevel@tonic-gate 	label.dkl_apc = apc;
3290Sstevel@tonic-gate 	label.dkl_intrlv = 1;
3300Sstevel@tonic-gate 	label.dkl_rpm = cur_dtype->dtype_rpm;
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
3330Sstevel@tonic-gate 	/*
3340Sstevel@tonic-gate 	 * Also fill in the current partition information.
3350Sstevel@tonic-gate 	 */
3360Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
3370Sstevel@tonic-gate 		label.dkl_map[i] = cur_parts->pinfo_map[i];
3380Sstevel@tonic-gate 	}
3390Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate 	label.dkl_magic = DKL_MAGIC;
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate 	/*
3440Sstevel@tonic-gate 	 * Fill in the vtoc information
3450Sstevel@tonic-gate 	 */
3460Sstevel@tonic-gate 	label.dkl_vtoc = cur_parts->vtoc;
3470Sstevel@tonic-gate 
3480Sstevel@tonic-gate 	/*
3490Sstevel@tonic-gate 	 * Use the current label
3500Sstevel@tonic-gate 	 */
3510Sstevel@tonic-gate 	bcopy(cur_disk->v_volume, label.dkl_vtoc.v_volume, LEN_DKL_VVOL);
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 	/*
3540Sstevel@tonic-gate 	 * Put asciilabel in; on x86 it's in the vtoc, not the label.
3550Sstevel@tonic-gate 	 */
3560Sstevel@tonic-gate 	(void) snprintf(label.dkl_asciilabel, sizeof (label.dkl_asciilabel),
3570Sstevel@tonic-gate 	    "%s cyl %d alt %d hd %d sec %d",
3580Sstevel@tonic-gate 	    cur_dtype->dtype_asciilabel, ncyl, acyl, nhead, nsect);
3590Sstevel@tonic-gate 
3600Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3610Sstevel@tonic-gate 	/*
3629889SLarry.Liu@Sun.COM 	 * Also add in v_sectorsz, as the driver will.
3630Sstevel@tonic-gate 	 */
3649889SLarry.Liu@Sun.COM 	label.dkl_vtoc.v_sectorsz = cur_blksz;
3650Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_16) */
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate 	/*
3680Sstevel@tonic-gate 	 * Generate the correct checksum.
3690Sstevel@tonic-gate 	 */
3700Sstevel@tonic-gate 	(void) checksum(&label, CK_MAKESUM);
3710Sstevel@tonic-gate 	/*
3720Sstevel@tonic-gate 	 * Convert the label into a vtoc
3730Sstevel@tonic-gate 	 */
3740Sstevel@tonic-gate 	if (label_to_vtoc(&vtoc, &label) == -1) {
3759889SLarry.Liu@Sun.COM 		free(new_label);
3760Sstevel@tonic-gate 		return (-1);
3770Sstevel@tonic-gate 	}
3780Sstevel@tonic-gate 	/*
3790Sstevel@tonic-gate 	 * Fill in the geometry info.  This is critical that
3800Sstevel@tonic-gate 	 * we do this before writing the vtoc.
3810Sstevel@tonic-gate 	 */
3820Sstevel@tonic-gate 	bzero((caddr_t)&geom, sizeof (struct dk_geom));
3830Sstevel@tonic-gate 	geom.dkg_ncyl = ncyl;
3840Sstevel@tonic-gate 	geom.dkg_acyl = acyl;
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3870Sstevel@tonic-gate 	geom.dkg_bcyl = bcyl;
3880Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_16) */
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 	geom.dkg_nhead = nhead;
3910Sstevel@tonic-gate 	geom.dkg_nsect = nsect;
3920Sstevel@tonic-gate 	geom.dkg_intrlv = 1;
3930Sstevel@tonic-gate 	geom.dkg_apc = apc;
3940Sstevel@tonic-gate 	geom.dkg_rpm = cur_dtype->dtype_rpm;
3950Sstevel@tonic-gate 	geom.dkg_pcyl = pcyl;
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate 	/*
3980Sstevel@tonic-gate 	 * Make a quick check to see that the geometry is being
3990Sstevel@tonic-gate 	 * written now is not way off from the actual capacity
4000Sstevel@tonic-gate 	 * of the disk. This is only an appoximate check and
4010Sstevel@tonic-gate 	 * is only for SCSI disks.
4020Sstevel@tonic-gate 	 */
4030Sstevel@tonic-gate 	if (SCSI && do_geometry_sanity_check() != 0) {
4049889SLarry.Liu@Sun.COM 		free(new_label);
4050Sstevel@tonic-gate 		return (-1);
4060Sstevel@tonic-gate 	}
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate 	/*
4090Sstevel@tonic-gate 	 * Lock out interrupts so we do things in sync.
4100Sstevel@tonic-gate 	 */
4110Sstevel@tonic-gate 	enter_critical();
4120Sstevel@tonic-gate 	/*
4130Sstevel@tonic-gate 	 * Do the ioctl to tell the kernel the geometry.
4140Sstevel@tonic-gate 	 */
4150Sstevel@tonic-gate 	if (ioctl(cur_file, DKIOCSGEOM, &geom) == -1) {
4160Sstevel@tonic-gate 		err_print("Warning: error setting drive geometry.\n");
4170Sstevel@tonic-gate 		error = -1;
4180Sstevel@tonic-gate 	}
4190Sstevel@tonic-gate 	/*
4200Sstevel@tonic-gate 	 * Write the vtoc.  At the time of this writing, our
4210Sstevel@tonic-gate 	 * drivers convert the vtoc back to a label, and
4220Sstevel@tonic-gate 	 * then write both the primary and backup labels.
4230Sstevel@tonic-gate 	 * This is not a requirement, however, as we
4240Sstevel@tonic-gate 	 * always use an ioctl to read the vtoc from the
4250Sstevel@tonic-gate 	 * driver, so it can do as it likes.
4260Sstevel@tonic-gate 	 */
4277563SPrasad.Singamsetty@Sun.COM 	if (write_extvtoc(cur_file, &vtoc) != 0) {
4280Sstevel@tonic-gate 		err_print("Warning: error writing VTOC.\n");
4290Sstevel@tonic-gate 		error = -1;
4300Sstevel@tonic-gate 	}
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate 	/*
4330Sstevel@tonic-gate 	 * Calculate where the backup labels went.  They are always on
4340Sstevel@tonic-gate 	 * the last alternate cylinder, but some older drives put them
4350Sstevel@tonic-gate 	 * on head 2 instead of the last head.  They are always on the
4360Sstevel@tonic-gate 	 * first 5 odd sectors of the appropriate track.
4370Sstevel@tonic-gate 	 */
4380Sstevel@tonic-gate 	if (cur_ctype->ctype_flags & CF_BLABEL)
4390Sstevel@tonic-gate 		head  = 2;
4400Sstevel@tonic-gate 	else
4410Sstevel@tonic-gate 		head = nhead - 1;
4420Sstevel@tonic-gate 	/*
4430Sstevel@tonic-gate 	 * Read and verify the backup labels.
4440Sstevel@tonic-gate 	 */
4450Sstevel@tonic-gate 	nbackups = 0;
4460Sstevel@tonic-gate 	for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect));
4470Sstevel@tonic-gate 	    sec += 2) {
4480Sstevel@tonic-gate 		if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, (diskaddr_t)
4499889SLarry.Liu@Sun.COM 		    ((chs2bn(ncyl + acyl - 1, head, sec))
4509889SLarry.Liu@Sun.COM 		    + solaris_offset), 1, new_label, F_NORMAL, NULL)) {
4519889SLarry.Liu@Sun.COM 			err_print("Warning: error reading"
4529889SLarry.Liu@Sun.COM 			    "backup label.\n");
4530Sstevel@tonic-gate 			error = -1;
4540Sstevel@tonic-gate 		} else {
4559889SLarry.Liu@Sun.COM 			if (bcmp((char *)&label, new_label,
4565084Sjohnlev 			    sizeof (struct dk_label)) == 0) {
4579889SLarry.Liu@Sun.COM 				nbackups++;
4580Sstevel@tonic-gate 			}
4590Sstevel@tonic-gate 		}
4600Sstevel@tonic-gate 	}
4610Sstevel@tonic-gate 	if (nbackups != BAD_LISTCNT) {
4620Sstevel@tonic-gate 		err_print("Warning: %s\n", nbackups == 0 ?
4635084Sjohnlev 		    "no backup labels" : "some backup labels incorrect");
4640Sstevel@tonic-gate 	}
4650Sstevel@tonic-gate 	/*
4660Sstevel@tonic-gate 	 * Mark the current disk as labelled and notify the kernel of what
4670Sstevel@tonic-gate 	 * has happened.
4680Sstevel@tonic-gate 	 */
4690Sstevel@tonic-gate 	cur_disk->disk_flags |= DSK_LABEL;
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate 	exit_critical();
4729889SLarry.Liu@Sun.COM 	free(new_label);
4730Sstevel@tonic-gate 	return (error);
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 
4770Sstevel@tonic-gate /*
4780Sstevel@tonic-gate  * Read the label from the disk.
4797563SPrasad.Singamsetty@Sun.COM  * Do this via the read_extvtoc() library routine, then convert it to a label.
4800Sstevel@tonic-gate  * We also need a DKIOCGGEOM ioctl to get the disk's geometry.
4810Sstevel@tonic-gate  */
4820Sstevel@tonic-gate int
read_label(int fd,struct dk_label * label)4830Sstevel@tonic-gate read_label(int fd, struct dk_label *label)
4840Sstevel@tonic-gate {
4857563SPrasad.Singamsetty@Sun.COM 	struct extvtoc	vtoc;
4860Sstevel@tonic-gate 	struct dk_geom	geom;
4875084Sjohnlev 	struct dk_cinfo	dkinfo;
4880Sstevel@tonic-gate 
4897563SPrasad.Singamsetty@Sun.COM 	if (read_extvtoc(fd, &vtoc) < 0		||
4905084Sjohnlev 	    ioctl(fd, DKIOCGGEOM, &geom) == -1	||
4915084Sjohnlev 	    ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
4920Sstevel@tonic-gate 		return (-1);
4930Sstevel@tonic-gate 	}
4945084Sjohnlev 
4955084Sjohnlev 	return (vtoc_to_label(label, &vtoc, &geom, &dkinfo));
4960Sstevel@tonic-gate }
4970Sstevel@tonic-gate 
498786Slclee int
get_disk_info_from_devid(int fd,struct efi_info * label)499786Slclee get_disk_info_from_devid(int fd, struct efi_info *label)
500786Slclee {
501786Slclee 	ddi_devid_t	devid;
502786Slclee 	char		*s;
503786Slclee 	int		n;
504786Slclee 	char		*vid, *pid;
505786Slclee 	int		nvid, npid;
506786Slclee 	struct dk_minfo	minf;
507786Slclee 	struct dk_cinfo	dkinfo;
508786Slclee 
509786Slclee 	if (devid_get(fd, &devid)) {
510786Slclee 		if (option_msg && diag_msg)
511786Slclee 			err_print("devid_get failed\n");
512786Slclee 		return (-1);
513786Slclee 	}
514786Slclee 
515786Slclee 	n = devid_sizeof(devid);
516786Slclee 	s = (char *)devid;
517786Slclee 
518786Slclee 	if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
519786Slclee 		if (option_msg && diag_msg)
520786Slclee 			err_print("DKIOCINFO failed\n");
521786Slclee 		return (-1);
522786Slclee 	}
523786Slclee 
524786Slclee 	if (dkinfo.dki_ctype != DKC_DIRECT)
525786Slclee 		return (-1);
526786Slclee 
527786Slclee 	vid = s+12;
528786Slclee 	if (!(pid = strchr(vid, '=')))
529786Slclee 		return (-1);
530786Slclee 	nvid = pid - vid;
531786Slclee 	pid += 1;
532786Slclee 	npid = n - nvid - 13;
533786Slclee 
534786Slclee 	if (nvid > 9)
535786Slclee 		nvid = 9;
536786Slclee 	if (npid > 17) {
537786Slclee 		pid = pid + npid - 17;
538786Slclee 		npid = 17;
539786Slclee 	}
540786Slclee 
541786Slclee 	if (ioctl(fd, DKIOCGMEDIAINFO, &minf) == -1) {
542786Slclee 		devid_free(devid);
543786Slclee 		return (-1);
544786Slclee 	}
545786Slclee 
546786Slclee 	(void) strlcpy(label->vendor, vid, nvid);
547786Slclee 	(void) strlcpy(label->product, pid, npid);
548786Slclee 	(void) strlcpy(label->revision, "0001", 5);
549786Slclee 	label->capacity = minf.dki_capacity * minf.dki_lbsize / 512;
550786Slclee 
551786Slclee 	devid_free(devid);
552786Slclee 	return (0);
553786Slclee }
554786Slclee 
5550Sstevel@tonic-gate /*
5560Sstevel@tonic-gate  * Issue uscsi_inquiry and read_capacity commands to
5570Sstevel@tonic-gate  * retrieve the disk's Vendor, Product, Revision and
5580Sstevel@tonic-gate  * Capacity information.
5590Sstevel@tonic-gate  */
5600Sstevel@tonic-gate int
get_disk_info(int fd,struct efi_info * label)5610Sstevel@tonic-gate get_disk_info(int fd, struct efi_info *label)
5620Sstevel@tonic-gate {
5630Sstevel@tonic-gate 	struct scsi_inquiry	inquiry;
5640Sstevel@tonic-gate 	struct scsi_capacity_16	capacity;
5652083Szl149053 	struct dk_minfo		minf;
5660Sstevel@tonic-gate 
567786Slclee 	if (!get_disk_info_from_devid(fd, label))
568786Slclee 		return (0);
569786Slclee 
5700Sstevel@tonic-gate 	if (uscsi_inquiry(fd, (char *)&inquiry, sizeof (inquiry))) {
5712083Szl149053 		(void) strlcpy(label->vendor, "Unknown", 8);
5722083Szl149053 		(void) strlcpy(label->product, "Unknown", 8);
5732083Szl149053 		(void) strlcpy(label->revision, "0001", 5);
5742083Szl149053 	} else {
5752083Szl149053 		(void) strlcpy(label->vendor, inquiry.inq_vid, 9);
5762083Szl149053 		(void) strlcpy(label->product, inquiry.inq_pid, 17);
5772083Szl149053 		(void) strlcpy(label->revision, inquiry.inq_revision, 5);
5780Sstevel@tonic-gate 	}
5790Sstevel@tonic-gate 
5802083Szl149053 	if (uscsi_read_capacity(fd, &capacity)) {
5812083Szl149053 		if (ioctl(fd, DKIOCGMEDIAINFO, &minf) == -1) {
5822083Szl149053 			err_print("Fetch Capacity failed\n");
5832083Szl149053 			return (-1);
5842083Szl149053 		}
5859889SLarry.Liu@Sun.COM 		label->capacity =
5869889SLarry.Liu@Sun.COM 		    minf.dki_capacity * minf.dki_lbsize / cur_blksz;
5872083Szl149053 	} else {
5882083Szl149053 		label->capacity = capacity.sc_capacity;
5890Sstevel@tonic-gate 
5902083Szl149053 		/* Since we are counting from zero, add 1 to capacity */
5912083Szl149053 		label->capacity++;
5922083Szl149053 	}
5932083Szl149053 
5940Sstevel@tonic-gate 	return (0);
5950Sstevel@tonic-gate }
5960Sstevel@tonic-gate 
5970Sstevel@tonic-gate int
read_efi_label(int fd,struct efi_info * label)5980Sstevel@tonic-gate read_efi_label(int fd, struct efi_info *label)
5990Sstevel@tonic-gate {
6000Sstevel@tonic-gate 	struct dk_gpt	*vtoc64;
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 	/* This could fail if there is no label already */
6030Sstevel@tonic-gate 	if (efi_alloc_and_read(fd, &vtoc64) < 0) {
6040Sstevel@tonic-gate 		return (-1);
6050Sstevel@tonic-gate 	}
6060Sstevel@tonic-gate 	if (vtoc64_to_label(label, vtoc64) != 0) {
6070Sstevel@tonic-gate 		err_print("vtoc64_to_label failed\n");
6080Sstevel@tonic-gate 		return (-1);
6090Sstevel@tonic-gate 	}
6100Sstevel@tonic-gate 	efi_free(vtoc64);
6110Sstevel@tonic-gate 	if (get_disk_info(fd, label) != 0) {
6120Sstevel@tonic-gate 		return (-1);
6130Sstevel@tonic-gate 	}
6140Sstevel@tonic-gate 	return (0);
6150Sstevel@tonic-gate }
6160Sstevel@tonic-gate 
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate /*
6190Sstevel@tonic-gate  * We've read a 64-bit label which has no geometry information.  Use
6200Sstevel@tonic-gate  * some heuristics to fake up a geometry that would match the disk in
6210Sstevel@tonic-gate  * order to make the rest of format(1M) happy.
6220Sstevel@tonic-gate  */
6230Sstevel@tonic-gate static int
vtoc64_to_label(struct efi_info * label,struct dk_gpt * vtoc)6240Sstevel@tonic-gate vtoc64_to_label(struct efi_info *label, struct dk_gpt *vtoc)
6250Sstevel@tonic-gate {
6260Sstevel@tonic-gate 	int		i, nparts = 0;
6270Sstevel@tonic-gate 	struct dk_gpt	*lmap;
6280Sstevel@tonic-gate 
6290Sstevel@tonic-gate 	(void) memset((char *)label, 0, sizeof (struct efi_info));
6300Sstevel@tonic-gate 
6310Sstevel@tonic-gate 	/* XXX do a sanity check here for nparts */
6320Sstevel@tonic-gate 	nparts = vtoc->efi_nparts;
6330Sstevel@tonic-gate 	lmap = (struct dk_gpt *) calloc(1, (sizeof (struct dk_part) *
6345084Sjohnlev 	    nparts) + sizeof (struct dk_gpt));
6350Sstevel@tonic-gate 	if (lmap == NULL) {
6360Sstevel@tonic-gate 		err_print("vtoc64_to_label: unable to allocate lmap\n");
6370Sstevel@tonic-gate 		fullabort();
6380Sstevel@tonic-gate 	}
6390Sstevel@tonic-gate 	label->e_parts = lmap;
6400Sstevel@tonic-gate 
6410Sstevel@tonic-gate 	/*
6420Sstevel@tonic-gate 	 * Copy necessary portions
6430Sstevel@tonic-gate 	 * XXX Maybe we can use memcpy() ??
6440Sstevel@tonic-gate 	 */
6450Sstevel@tonic-gate 	lmap->efi_version = vtoc->efi_version;
6460Sstevel@tonic-gate 	lmap->efi_nparts = vtoc->efi_nparts;
6470Sstevel@tonic-gate 	lmap->efi_part_size = vtoc->efi_part_size;
6480Sstevel@tonic-gate 	lmap->efi_lbasize = vtoc->efi_lbasize;
6490Sstevel@tonic-gate 	lmap->efi_last_lba = vtoc->efi_last_lba;
6500Sstevel@tonic-gate 	lmap->efi_first_u_lba = vtoc->efi_first_u_lba;
6510Sstevel@tonic-gate 	lmap->efi_last_u_lba = vtoc->efi_last_u_lba;
6526590Syl194034 	lmap->efi_altern_lba = vtoc->efi_altern_lba;
6530Sstevel@tonic-gate 	lmap->efi_flags = vtoc->efi_flags;
6540Sstevel@tonic-gate 	(void) memcpy((uchar_t *)&lmap->efi_disk_uguid,
6555084Sjohnlev 	    (uchar_t *)&vtoc->efi_disk_uguid, sizeof (struct uuid));
6560Sstevel@tonic-gate 
6570Sstevel@tonic-gate 	for (i = 0; i < nparts; i++) {
6580Sstevel@tonic-gate 		lmap->efi_parts[i].p_tag = vtoc->efi_parts[i].p_tag;
6590Sstevel@tonic-gate 		lmap->efi_parts[i].p_flag = vtoc->efi_parts[i].p_flag;
6600Sstevel@tonic-gate 		lmap->efi_parts[i].p_start = vtoc->efi_parts[i].p_start;
6610Sstevel@tonic-gate 		lmap->efi_parts[i].p_size = vtoc->efi_parts[i].p_size;
6620Sstevel@tonic-gate 		(void) memcpy((uchar_t *)&lmap->efi_parts[i].p_uguid,
6630Sstevel@tonic-gate 		    (uchar_t *)&vtoc->efi_parts[i].p_uguid,
6640Sstevel@tonic-gate 		    sizeof (struct uuid));
6650Sstevel@tonic-gate 		if (vtoc->efi_parts[i].p_tag == V_RESERVED) {
6660Sstevel@tonic-gate 			bcopy(vtoc->efi_parts[i].p_name,
6670Sstevel@tonic-gate 			    lmap->efi_parts[i].p_name, LEN_DKL_VVOL);
6680Sstevel@tonic-gate 		}
6690Sstevel@tonic-gate 	}
6700Sstevel@tonic-gate 	return (0);
6710Sstevel@tonic-gate }
6720Sstevel@tonic-gate 
6730Sstevel@tonic-gate /*
6740Sstevel@tonic-gate  * Convert vtoc/geom to label.
6750Sstevel@tonic-gate  */
6760Sstevel@tonic-gate static int
vtoc_to_label(struct dk_label * label,struct extvtoc * vtoc,struct dk_geom * geom,struct dk_cinfo * cinfo)6777563SPrasad.Singamsetty@Sun.COM vtoc_to_label(struct dk_label *label, struct extvtoc *vtoc,
6787563SPrasad.Singamsetty@Sun.COM     struct dk_geom *geom, struct dk_cinfo *cinfo)
6790Sstevel@tonic-gate {
6800Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
6810Sstevel@tonic-gate 	struct dk_map32		*lmap;
6820Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
6830Sstevel@tonic-gate 	struct dkl_partition	*lmap;
6840Sstevel@tonic-gate #else
6850Sstevel@tonic-gate #error No VTOC format defined.
6860Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
6870Sstevel@tonic-gate 
6887563SPrasad.Singamsetty@Sun.COM 	struct extpartition	*vpart;
6897563SPrasad.Singamsetty@Sun.COM 	ulong_t			nblks;
6900Sstevel@tonic-gate 	int			i;
6910Sstevel@tonic-gate 
6920Sstevel@tonic-gate 	(void) memset((char *)label, 0, sizeof (struct dk_label));
6930Sstevel@tonic-gate 
6940Sstevel@tonic-gate 	/*
6950Sstevel@tonic-gate 	 * Sanity-check the vtoc
6960Sstevel@tonic-gate 	 */
6979889SLarry.Liu@Sun.COM 	if (vtoc->v_sanity != VTOC_SANE ||
6985084Sjohnlev 	    vtoc->v_nparts != V_NUMPAR) {
6990Sstevel@tonic-gate 		return (-1);
7000Sstevel@tonic-gate 	}
7010Sstevel@tonic-gate 
7020Sstevel@tonic-gate 	/*
7030Sstevel@tonic-gate 	 * Sanity check of geometry
7040Sstevel@tonic-gate 	 */
7050Sstevel@tonic-gate 	if (geom->dkg_ncyl == 0 || geom->dkg_nhead == 0 ||
7065084Sjohnlev 	    geom->dkg_nsect == 0) {
7070Sstevel@tonic-gate 		return (-1);
7080Sstevel@tonic-gate 	}
7090Sstevel@tonic-gate 
7100Sstevel@tonic-gate 	label->dkl_magic = DKL_MAGIC;
7110Sstevel@tonic-gate 
7120Sstevel@tonic-gate 	/*
7130Sstevel@tonic-gate 	 * Copy necessary portions of the geometry information
7140Sstevel@tonic-gate 	 */
7150Sstevel@tonic-gate 	label->dkl_rpm = geom->dkg_rpm;
7160Sstevel@tonic-gate 	label->dkl_pcyl = geom->dkg_pcyl;
7170Sstevel@tonic-gate 	label->dkl_apc = geom->dkg_apc;
7180Sstevel@tonic-gate 	label->dkl_intrlv = geom->dkg_intrlv;
7190Sstevel@tonic-gate 	label->dkl_ncyl = geom->dkg_ncyl;
7200Sstevel@tonic-gate 	label->dkl_acyl = geom->dkg_acyl;
7210Sstevel@tonic-gate 
7220Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
7230Sstevel@tonic-gate 	label->dkl_bcyl = geom->dkg_bcyl;
7240Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_16) */
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 	label->dkl_nhead = geom->dkg_nhead;
7270Sstevel@tonic-gate 	label->dkl_nsect = geom->dkg_nsect;
7280Sstevel@tonic-gate 
7290Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
7300Sstevel@tonic-gate 	label->dkl_obs1 = geom->dkg_obs1;
7310Sstevel@tonic-gate 	label->dkl_obs2 = geom->dkg_obs2;
7320Sstevel@tonic-gate 	label->dkl_obs3 = geom->dkg_obs3;
7330Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
7340Sstevel@tonic-gate 
7350Sstevel@tonic-gate 	label->dkl_write_reinstruct = geom->dkg_write_reinstruct;
7360Sstevel@tonic-gate 	label->dkl_read_reinstruct = geom->dkg_read_reinstruct;
7370Sstevel@tonic-gate 
7380Sstevel@tonic-gate 	/*
7390Sstevel@tonic-gate 	 * Copy vtoc structure fields into the disk label dk_vtoc
7400Sstevel@tonic-gate 	 */
7410Sstevel@tonic-gate 	label->dkl_vtoc.v_sanity = vtoc->v_sanity;
7420Sstevel@tonic-gate 	label->dkl_vtoc.v_nparts = vtoc->v_nparts;
7430Sstevel@tonic-gate 	label->dkl_vtoc.v_version = vtoc->v_version;
7440Sstevel@tonic-gate 
7450Sstevel@tonic-gate 	(void) memcpy(label->dkl_vtoc.v_volume, vtoc->v_volume,
7465084Sjohnlev 	    LEN_DKL_VVOL);
7470Sstevel@tonic-gate 	for (i = 0; i < V_NUMPAR; i++) {
7480Sstevel@tonic-gate 		label->dkl_vtoc.v_part[i].p_tag = vtoc->v_part[i].p_tag;
7490Sstevel@tonic-gate 		label->dkl_vtoc.v_part[i].p_flag = vtoc->v_part[i].p_flag;
7507563SPrasad.Singamsetty@Sun.COM 		label->dkl_vtoc.v_timestamp[i] = vtoc->timestamp[i];
7510Sstevel@tonic-gate 	}
7527563SPrasad.Singamsetty@Sun.COM 
7537563SPrasad.Singamsetty@Sun.COM 	for (i = 0; i < 10; i++)
7547563SPrasad.Singamsetty@Sun.COM 		label->dkl_vtoc.v_reserved[i] = vtoc->v_reserved[i];
7557563SPrasad.Singamsetty@Sun.COM 
7567563SPrasad.Singamsetty@Sun.COM 	label->dkl_vtoc.v_bootinfo[0] = vtoc->v_bootinfo[0];
7577563SPrasad.Singamsetty@Sun.COM 	label->dkl_vtoc.v_bootinfo[1] = vtoc->v_bootinfo[1];
7587563SPrasad.Singamsetty@Sun.COM 	label->dkl_vtoc.v_bootinfo[2] = vtoc->v_bootinfo[2];
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate 	(void) memcpy(label->dkl_asciilabel, vtoc->v_asciilabel,
7615084Sjohnlev 	    LEN_DKL_ASCII);
7620Sstevel@tonic-gate 
7630Sstevel@tonic-gate 	/*
7640Sstevel@tonic-gate 	 * Note the conversion from starting sector number
7650Sstevel@tonic-gate 	 * to starting cylinder number.
7660Sstevel@tonic-gate 	 * Return error if division results in a remainder.
7675084Sjohnlev 	 *
7685084Sjohnlev 	 * Note: don't check, if probing virtual disk in Xen
7695084Sjohnlev 	 * for that virtual disk will use fabricated # of headers
7705084Sjohnlev 	 * and sectors per track which may cause the capacity
7715084Sjohnlev 	 * not multiple of # of blocks per cylinder
7720Sstevel@tonic-gate 	 */
7730Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
7740Sstevel@tonic-gate 	lmap = label->dkl_map;
7750Sstevel@tonic-gate 
7760Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
7770Sstevel@tonic-gate 	lmap = label->dkl_vtoc.v_part;
7780Sstevel@tonic-gate #else
7790Sstevel@tonic-gate #error No VTOC format defined.
7800Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
7810Sstevel@tonic-gate 
7820Sstevel@tonic-gate 	vpart = vtoc->v_part;
7830Sstevel@tonic-gate 
7847563SPrasad.Singamsetty@Sun.COM 	nblks = label->dkl_nsect * label->dkl_nhead;
7850Sstevel@tonic-gate 
7860Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++, lmap++, vpart++) {
7875084Sjohnlev 		if (cinfo->dki_ctype != DKC_VBD) {
7885084Sjohnlev 			if ((vpart->p_start % nblks) != 0 ||
7895084Sjohnlev 			    (vpart->p_size % nblks) != 0) {
7905084Sjohnlev 				return (-1);
7915084Sjohnlev 			}
7920Sstevel@tonic-gate 		}
7930Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
7947563SPrasad.Singamsetty@Sun.COM 		lmap->dkl_cylno = (blkaddr32_t)(vpart->p_start / nblks);
7957563SPrasad.Singamsetty@Sun.COM 		lmap->dkl_nblk = (blkaddr32_t)vpart->p_size;
7960Sstevel@tonic-gate 
7970Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
7987563SPrasad.Singamsetty@Sun.COM 		lmap->p_start = (blkaddr32_t)vpart->p_start;
7997563SPrasad.Singamsetty@Sun.COM 		lmap->p_size = (blkaddr32_t)vpart->p_size;
8000Sstevel@tonic-gate #else
8010Sstevel@tonic-gate #error No VTOC format defined.
8020Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
8030Sstevel@tonic-gate 	}
8040Sstevel@tonic-gate 
8050Sstevel@tonic-gate 	/*
8060Sstevel@tonic-gate 	 * Finally, make a checksum
8070Sstevel@tonic-gate 	 */
8080Sstevel@tonic-gate 	(void) checksum(label, CK_MAKESUM);
8090Sstevel@tonic-gate 
8107563SPrasad.Singamsetty@Sun.COM #ifdef DEBUG
8117563SPrasad.Singamsetty@Sun.COM 	if (option_msg && diag_msg)
8127563SPrasad.Singamsetty@Sun.COM 		dump_label(label);
8137563SPrasad.Singamsetty@Sun.COM #endif
8140Sstevel@tonic-gate 	return (0);
8150Sstevel@tonic-gate }
8160Sstevel@tonic-gate 
8170Sstevel@tonic-gate 
8180Sstevel@tonic-gate 
8190Sstevel@tonic-gate /*
8200Sstevel@tonic-gate  * Extract a vtoc structure out of a valid label
8210Sstevel@tonic-gate  */
8220Sstevel@tonic-gate int
label_to_vtoc(struct extvtoc * vtoc,struct dk_label * label)8237563SPrasad.Singamsetty@Sun.COM label_to_vtoc(struct extvtoc *vtoc, struct dk_label *label)
8240Sstevel@tonic-gate {
8250Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
8260Sstevel@tonic-gate 	struct dk_map2		*lpart;
8270Sstevel@tonic-gate 	struct dk_map32		*lmap;
8287563SPrasad.Singamsetty@Sun.COM 	ulong_t			nblks;
8290Sstevel@tonic-gate 
8300Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
8310Sstevel@tonic-gate 	struct dkl_partition	*lpart;
8320Sstevel@tonic-gate #else
8330Sstevel@tonic-gate #error No VTOC format defined.
8340Sstevel@tonic-gate #endif				/* defined(_SUNOS_VTOC_8) */
8350Sstevel@tonic-gate 
8367563SPrasad.Singamsetty@Sun.COM 	struct extpartition	*vpart;
8370Sstevel@tonic-gate 	int			i;
8380Sstevel@tonic-gate 
8397563SPrasad.Singamsetty@Sun.COM 	(void) memset((char *)vtoc, 0, sizeof (struct extvtoc));
8400Sstevel@tonic-gate 
8410Sstevel@tonic-gate 	switch (label->dkl_vtoc.v_version) {
8420Sstevel@tonic-gate 	case 0:
8430Sstevel@tonic-gate 		/*
8440Sstevel@tonic-gate 		 * No valid vtoc information in the label.
8450Sstevel@tonic-gate 		 * Construct default p_flags and p_tags.
8460Sstevel@tonic-gate 		 */
8470Sstevel@tonic-gate 		vpart = vtoc->v_part;
8480Sstevel@tonic-gate 		for (i = 0; i < V_NUMPAR; i++, vpart++) {
8490Sstevel@tonic-gate 			vpart->p_tag = default_vtoc_map[i].p_tag;
8500Sstevel@tonic-gate 			vpart->p_flag = default_vtoc_map[i].p_flag;
8510Sstevel@tonic-gate 		}
8520Sstevel@tonic-gate 		break;
8530Sstevel@tonic-gate 
8540Sstevel@tonic-gate 	case V_VERSION:
8550Sstevel@tonic-gate 		vpart = vtoc->v_part;
8560Sstevel@tonic-gate 		lpart = label->dkl_vtoc.v_part;
8570Sstevel@tonic-gate 		for (i = 0; i < V_NUMPAR; i++, vpart++, lpart++) {
8580Sstevel@tonic-gate 			vpart->p_tag = lpart->p_tag;
8590Sstevel@tonic-gate 			vpart->p_flag = lpart->p_flag;
8600Sstevel@tonic-gate 
8610Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
8627563SPrasad.Singamsetty@Sun.COM 			vpart->p_start = (diskaddr_t)lpart->p_start;
8637563SPrasad.Singamsetty@Sun.COM 			vpart->p_size = (diskaddr_t)lpart->p_size;
8640Sstevel@tonic-gate #endif	/* defined(_SUNOS_VTOC_16) */
8657563SPrasad.Singamsetty@Sun.COM 			vtoc->timestamp[i] = label->dkl_vtoc.v_timestamp[i];
8660Sstevel@tonic-gate 		}
8670Sstevel@tonic-gate 		(void) memcpy(vtoc->v_volume, label->dkl_vtoc.v_volume,
8685084Sjohnlev 		    LEN_DKL_VVOL);
8697563SPrasad.Singamsetty@Sun.COM 
8707563SPrasad.Singamsetty@Sun.COM 		for (i = 0; i < 10; i++)
8717563SPrasad.Singamsetty@Sun.COM 			vtoc->v_reserved[i] = label->dkl_vtoc.v_reserved[i];
8727563SPrasad.Singamsetty@Sun.COM 
8737563SPrasad.Singamsetty@Sun.COM 		vtoc->v_bootinfo[0] = label->dkl_vtoc.v_bootinfo[0];
8747563SPrasad.Singamsetty@Sun.COM 		vtoc->v_bootinfo[1] = label->dkl_vtoc.v_bootinfo[1];
8757563SPrasad.Singamsetty@Sun.COM 		vtoc->v_bootinfo[2] = label->dkl_vtoc.v_bootinfo[2];
8760Sstevel@tonic-gate 		break;
8770Sstevel@tonic-gate 
8780Sstevel@tonic-gate 	default:
8790Sstevel@tonic-gate 		return (-1);
8800Sstevel@tonic-gate 	}
8810Sstevel@tonic-gate 
8820Sstevel@tonic-gate 	/*
8830Sstevel@tonic-gate 	 * XXX - this looks wrong to me....
8840Sstevel@tonic-gate 	 * why are these values hardwired, rather than returned from
8850Sstevel@tonic-gate 	 * the real disk label?
8860Sstevel@tonic-gate 	 */
8870Sstevel@tonic-gate 	vtoc->v_sanity = VTOC_SANE;
8880Sstevel@tonic-gate 	vtoc->v_version = V_VERSION;
8899889SLarry.Liu@Sun.COM 	vtoc->v_sectorsz = cur_blksz;
8900Sstevel@tonic-gate 	vtoc->v_nparts = V_NUMPAR;
8910Sstevel@tonic-gate 
8920Sstevel@tonic-gate 	(void) memcpy(vtoc->v_asciilabel, label->dkl_asciilabel,
8935084Sjohnlev 	    LEN_DKL_ASCII);
8940Sstevel@tonic-gate 
8950Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
8960Sstevel@tonic-gate 	/*
8970Sstevel@tonic-gate 	 * Convert partitioning information.
8980Sstevel@tonic-gate 	 * Note the conversion from starting cylinder number
8990Sstevel@tonic-gate 	 * to starting sector number.
9000Sstevel@tonic-gate 	 */
9010Sstevel@tonic-gate 	lmap = label->dkl_map;
9020Sstevel@tonic-gate 	vpart = vtoc->v_part;
9030Sstevel@tonic-gate 	nblks = label->dkl_nsect * label->dkl_nhead;
9040Sstevel@tonic-gate 	for (i = 0; i < V_NUMPAR; i++, vpart++, lmap++) {
9057563SPrasad.Singamsetty@Sun.COM 		vpart->p_start = (diskaddr_t)(lmap->dkl_cylno * nblks);
9067563SPrasad.Singamsetty@Sun.COM 		vpart->p_size = (diskaddr_t)lmap->dkl_nblk;
9070Sstevel@tonic-gate 	}
9080Sstevel@tonic-gate #endif			/* defined(_SUNOS_VTOC_8) */
9090Sstevel@tonic-gate 
9100Sstevel@tonic-gate 	return (0);
9110Sstevel@tonic-gate }
9120Sstevel@tonic-gate 
9130Sstevel@tonic-gate /*
9140Sstevel@tonic-gate  * Input: File descriptor
9157563SPrasad.Singamsetty@Sun.COM  * Output: 1 if disk has an EFI label, 0 otherwise.
9160Sstevel@tonic-gate  */
9170Sstevel@tonic-gate 
9180Sstevel@tonic-gate int
is_efi_type(int fd)9190Sstevel@tonic-gate is_efi_type(int fd)
9200Sstevel@tonic-gate {
9217563SPrasad.Singamsetty@Sun.COM 	struct extvtoc vtoc;
9220Sstevel@tonic-gate 
9237563SPrasad.Singamsetty@Sun.COM 	if (read_extvtoc(fd, &vtoc) == VT_ENOTSUP) {
9247563SPrasad.Singamsetty@Sun.COM 		/* assume the disk has EFI label */
9257563SPrasad.Singamsetty@Sun.COM 		return (1);
9260Sstevel@tonic-gate 	}
9270Sstevel@tonic-gate 	return (0);
9280Sstevel@tonic-gate }
9290Sstevel@tonic-gate 
9300Sstevel@tonic-gate /* make sure the user specified something reasonable */
9310Sstevel@tonic-gate void
err_check(struct dk_gpt * vtoc)9320Sstevel@tonic-gate err_check(struct dk_gpt *vtoc)
9330Sstevel@tonic-gate {
9340Sstevel@tonic-gate 	int			resv_part = -1;
9350Sstevel@tonic-gate 	int			i, j;
9360Sstevel@tonic-gate 	diskaddr_t		istart, jstart, isize, jsize, endsect;
9370Sstevel@tonic-gate 	int			overlap = 0;
9380Sstevel@tonic-gate 
9390Sstevel@tonic-gate 	/*
9400Sstevel@tonic-gate 	 * make sure no partitions overlap
9410Sstevel@tonic-gate 	 */
9420Sstevel@tonic-gate 	for (i = 0; i < vtoc->efi_nparts; i++) {
9430Sstevel@tonic-gate 		/* It can't be unassigned and have an actual size */
9440Sstevel@tonic-gate 		if ((vtoc->efi_parts[i].p_tag == V_UNASSIGNED) &&
9450Sstevel@tonic-gate 		    (vtoc->efi_parts[i].p_size != 0)) {
9460Sstevel@tonic-gate 			(void) fprintf(stderr,
9470Sstevel@tonic-gate "partition %d is \"unassigned\" but has a size of %llu\n", i,
9485084Sjohnlev 			    vtoc->efi_parts[i].p_size);
9490Sstevel@tonic-gate 		}
9500Sstevel@tonic-gate 		if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) {
9510Sstevel@tonic-gate 			continue;
9520Sstevel@tonic-gate 		}
9530Sstevel@tonic-gate 		if (vtoc->efi_parts[i].p_tag == V_RESERVED) {
9540Sstevel@tonic-gate 			if (resv_part != -1) {
9555084Sjohnlev 				(void) fprintf(stderr,
9565084Sjohnlev "found duplicate reserved partition at %d\n", i);
9570Sstevel@tonic-gate 			}
9580Sstevel@tonic-gate 			resv_part = i;
9590Sstevel@tonic-gate 			if (vtoc->efi_parts[i].p_size != EFI_MIN_RESV_SIZE)
9600Sstevel@tonic-gate 				(void) fprintf(stderr,
9610Sstevel@tonic-gate "Warning: reserved partition size must be %d sectors\n",
9625084Sjohnlev 				    EFI_MIN_RESV_SIZE);
9630Sstevel@tonic-gate 		}
9640Sstevel@tonic-gate 		if ((vtoc->efi_parts[i].p_start < vtoc->efi_first_u_lba) ||
9650Sstevel@tonic-gate 		    (vtoc->efi_parts[i].p_start > vtoc->efi_last_u_lba)) {
9660Sstevel@tonic-gate 			(void) fprintf(stderr,
9670Sstevel@tonic-gate 			    "Partition %d starts at %llu\n",
9680Sstevel@tonic-gate 			    i,
9690Sstevel@tonic-gate 			    vtoc->efi_parts[i].p_start);
9700Sstevel@tonic-gate 			(void) fprintf(stderr,
9710Sstevel@tonic-gate 			    "It must be between %llu and %llu.\n",
9720Sstevel@tonic-gate 			    vtoc->efi_first_u_lba,
9730Sstevel@tonic-gate 			    vtoc->efi_last_u_lba);
9740Sstevel@tonic-gate 		}
9750Sstevel@tonic-gate 		if ((vtoc->efi_parts[i].p_start +
9760Sstevel@tonic-gate 		    vtoc->efi_parts[i].p_size <
9770Sstevel@tonic-gate 		    vtoc->efi_first_u_lba) ||
9780Sstevel@tonic-gate 		    (vtoc->efi_parts[i].p_start +
9790Sstevel@tonic-gate 		    vtoc->efi_parts[i].p_size >
9800Sstevel@tonic-gate 		    vtoc->efi_last_u_lba + 1)) {
9810Sstevel@tonic-gate 			(void) fprintf(stderr,
9820Sstevel@tonic-gate 			    "Partition %d ends at %llu\n",
9830Sstevel@tonic-gate 			    i,
9840Sstevel@tonic-gate 			    vtoc->efi_parts[i].p_start +
9850Sstevel@tonic-gate 			    vtoc->efi_parts[i].p_size);
9860Sstevel@tonic-gate 			(void) fprintf(stderr,
9870Sstevel@tonic-gate 			    "It must be between %llu and %llu.\n",
9880Sstevel@tonic-gate 			    vtoc->efi_first_u_lba,
9890Sstevel@tonic-gate 			    vtoc->efi_last_u_lba);
9900Sstevel@tonic-gate 		}
9910Sstevel@tonic-gate 
9920Sstevel@tonic-gate 		for (j = 0; j < vtoc->efi_nparts; j++) {
9930Sstevel@tonic-gate 			isize = vtoc->efi_parts[i].p_size;
9940Sstevel@tonic-gate 			jsize = vtoc->efi_parts[j].p_size;
9950Sstevel@tonic-gate 			istart = vtoc->efi_parts[i].p_start;
9960Sstevel@tonic-gate 			jstart = vtoc->efi_parts[j].p_start;
9970Sstevel@tonic-gate 			if ((i != j) && (isize != 0) && (jsize != 0)) {
9980Sstevel@tonic-gate 				endsect = jstart + jsize -1;
9990Sstevel@tonic-gate 				if ((jstart <= istart) &&
10000Sstevel@tonic-gate 				    (istart <= endsect)) {
10010Sstevel@tonic-gate 					if (!overlap) {
10020Sstevel@tonic-gate 					(void) fprintf(stderr,
10030Sstevel@tonic-gate "label error: EFI Labels do not support overlapping partitions\n");
10040Sstevel@tonic-gate 					}
10050Sstevel@tonic-gate 					(void) fprintf(stderr,
10060Sstevel@tonic-gate "Partition %d overlaps partition %d.\n", i, j);
10070Sstevel@tonic-gate 					overlap = 1;
10080Sstevel@tonic-gate 				}
10090Sstevel@tonic-gate 			}
10100Sstevel@tonic-gate 		}
10110Sstevel@tonic-gate 	}
10120Sstevel@tonic-gate 	/* make sure there is a reserved partition */
10130Sstevel@tonic-gate 	if (resv_part == -1) {
10140Sstevel@tonic-gate 		(void) fprintf(stderr,
10155084Sjohnlev 		    "no reserved partition found\n");
10160Sstevel@tonic-gate 	}
10170Sstevel@tonic-gate }
10180Sstevel@tonic-gate 
10197563SPrasad.Singamsetty@Sun.COM #ifdef	DEBUG
10207563SPrasad.Singamsetty@Sun.COM static void
dump_label(label)10210Sstevel@tonic-gate dump_label(label)
10220Sstevel@tonic-gate 	struct dk_label	*label;
10230Sstevel@tonic-gate {
10240Sstevel@tonic-gate 	int		i;
10250Sstevel@tonic-gate 
10260Sstevel@tonic-gate 	fmt_print("%s\n", label->dkl_asciilabel);
10270Sstevel@tonic-gate 
10280Sstevel@tonic-gate 	fmt_print("version:  %d\n", label->dkl_vtoc.v_version);
10290Sstevel@tonic-gate 	fmt_print("volume:   ");
10300Sstevel@tonic-gate 	for (i = 0; i < LEN_DKL_VVOL; i++) {
10310Sstevel@tonic-gate 		if (label->dkl_vtoc.v_volume[i] == 0)
10320Sstevel@tonic-gate 			break;
10330Sstevel@tonic-gate 		fmt_print("%c", label->dkl_vtoc.v_volume[i]);
10340Sstevel@tonic-gate 	}
10350Sstevel@tonic-gate 	fmt_print("\n");
10360Sstevel@tonic-gate 	fmt_print("v_nparts: %d\n", label->dkl_vtoc.v_nparts);
10370Sstevel@tonic-gate 	fmt_print("v_sanity: %lx\n", label->dkl_vtoc.v_sanity);
10380Sstevel@tonic-gate 
10390Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
10400Sstevel@tonic-gate 	fmt_print("rpm:      %d\n", label->dkl_rpm);
10410Sstevel@tonic-gate 	fmt_print("pcyl:     %d\n", label->dkl_pcyl);
10420Sstevel@tonic-gate 	fmt_print("apc:      %d\n", label->dkl_apc);
10430Sstevel@tonic-gate 	fmt_print("obs1:     %d\n", label->dkl_obs1);
10440Sstevel@tonic-gate 	fmt_print("obs2:     %d\n", label->dkl_obs2);
10450Sstevel@tonic-gate 	fmt_print("intrlv:   %d\n", label->dkl_intrlv);
10460Sstevel@tonic-gate 	fmt_print("ncyl:     %d\n", label->dkl_ncyl);
10470Sstevel@tonic-gate 	fmt_print("acyl:     %d\n", label->dkl_acyl);
10480Sstevel@tonic-gate 	fmt_print("nhead:    %d\n", label->dkl_nhead);
10490Sstevel@tonic-gate 	fmt_print("nsect:    %d\n", label->dkl_nsect);
10500Sstevel@tonic-gate 	fmt_print("obs3:     %d\n", label->dkl_obs3);
10510Sstevel@tonic-gate 	fmt_print("obs4:     %d\n", label->dkl_obs4);
10520Sstevel@tonic-gate 
10530Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
10540Sstevel@tonic-gate 	fmt_print("rpm:      %d\n", label->dkl_rpm);
10550Sstevel@tonic-gate 	fmt_print("pcyl:     %d\n", label->dkl_pcyl);
10560Sstevel@tonic-gate 	fmt_print("apc:      %d\n", label->dkl_apc);
10570Sstevel@tonic-gate 	fmt_print("intrlv:   %d\n", label->dkl_intrlv);
10580Sstevel@tonic-gate 	fmt_print("ncyl:     %d\n", label->dkl_ncyl);
10590Sstevel@tonic-gate 	fmt_print("acyl:     %d\n", label->dkl_acyl);
10600Sstevel@tonic-gate 	fmt_print("nhead:    %d\n", label->dkl_nhead);
10610Sstevel@tonic-gate 	fmt_print("nsect:    %d\n", label->dkl_nsect);
10620Sstevel@tonic-gate 	fmt_print("bcyl:     %d\n", label->dkl_bcyl);
10630Sstevel@tonic-gate 	fmt_print("skew:     %d\n", label->dkl_skew);
10640Sstevel@tonic-gate #else
10650Sstevel@tonic-gate #error No VTOC format defined.
10660Sstevel@tonic-gate #endif				/* defined(_SUNOS_VTOC_8) */
10670Sstevel@tonic-gate 	fmt_print("magic:    %0x\n", label->dkl_magic);
10680Sstevel@tonic-gate 	fmt_print("cksum:    %0x\n", label->dkl_cksum);
10690Sstevel@tonic-gate 
10700Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
10710Sstevel@tonic-gate 
10720Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
10730Sstevel@tonic-gate 		fmt_print("%c:        cyl=%d, blocks=%d", i+'a',
10740Sstevel@tonic-gate 			label->dkl_map[i].dkl_cylno,
10750Sstevel@tonic-gate 			label->dkl_map[i].dkl_nblk);
10760Sstevel@tonic-gate 
10770Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
10787563SPrasad.Singamsetty@Sun.COM 		fmt_print("%c:        start=%u, blocks=%u", i+'a',
10790Sstevel@tonic-gate 		    label->dkl_vtoc.v_part[i].p_start,
10800Sstevel@tonic-gate 		    label->dkl_vtoc.v_part[i].p_size);
10810Sstevel@tonic-gate #else
10820Sstevel@tonic-gate #error No VTOC format defined.
10830Sstevel@tonic-gate #endif				/* defined(_SUNOS_VTOC_8) */
10840Sstevel@tonic-gate 
10850Sstevel@tonic-gate 		fmt_print(",  tag=%d,  flag=%d",
10860Sstevel@tonic-gate 			label->dkl_vtoc.v_part[i].p_tag,
10870Sstevel@tonic-gate 			label->dkl_vtoc.v_part[i].p_flag);
10880Sstevel@tonic-gate 		fmt_print("\n");
10890Sstevel@tonic-gate 	}
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate 	fmt_print("read_reinstruct:  %d\n", label->dkl_read_reinstruct);
10920Sstevel@tonic-gate 	fmt_print("write_reinstruct: %d\n", label->dkl_write_reinstruct);
10930Sstevel@tonic-gate 
10940Sstevel@tonic-gate 	fmt_print("bootinfo: ");
10950Sstevel@tonic-gate 	for (i = 0; i < 3; i++) {
10960Sstevel@tonic-gate 		fmt_print("0x%x ", label->dkl_vtoc.v_bootinfo[i]);
10970Sstevel@tonic-gate 	}
10980Sstevel@tonic-gate 	fmt_print("\n");
10990Sstevel@tonic-gate 
11000Sstevel@tonic-gate 	fmt_print("reserved: ");
11010Sstevel@tonic-gate 	for (i = 0; i < 10; i++) {
11020Sstevel@tonic-gate 		if ((i % 4) == 3)
11030Sstevel@tonic-gate 			fmt_print("\n");
11040Sstevel@tonic-gate 		fmt_print("0x%x ", label->dkl_vtoc.v_reserved[i]);
11050Sstevel@tonic-gate 	}
11060Sstevel@tonic-gate 	fmt_print("\n");
11070Sstevel@tonic-gate 
11080Sstevel@tonic-gate 	fmt_print("timestamp:\n");
11090Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
11100Sstevel@tonic-gate 		if ((i % 4) == 3)
11110Sstevel@tonic-gate 			fmt_print("\n");
11120Sstevel@tonic-gate 		fmt_print("0x%x ", label->dkl_vtoc.v_timestamp[i]);
11130Sstevel@tonic-gate 	}
11140Sstevel@tonic-gate 	fmt_print("\n");
11150Sstevel@tonic-gate 
11160Sstevel@tonic-gate 	fmt_print("pad:\n");
11170Sstevel@tonic-gate 	dump("", label->dkl_pad, LEN_DKL_PAD, HEX_ONLY);
11180Sstevel@tonic-gate 
11190Sstevel@tonic-gate 	fmt_print("\n\n");
11200Sstevel@tonic-gate }
11217563SPrasad.Singamsetty@Sun.COM #endif	/* DEBUG */
1122