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
5d25b227dSzl149053 * Common Development and Distribution License (the "License").
6d25b227dSzl149053 * 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.
24*f1bf0656SHans 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>
40*f1bf0656SHans 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 #ifdef __STDC__
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate * Prototypes for ANSI C compilers
617c478bd9Sstevel@tonic-gate */
627c478bd9Sstevel@tonic-gate static int do_geometry_sanity_check(void);
63342440ecSPrasad Singamsetty static int vtoc_to_label(struct dk_label *label, struct extvtoc *vtoc,
64843e1988Sjohnlev struct dk_geom *geom, struct dk_cinfo *cinfo);
65342440ecSPrasad Singamsetty extern int read_extvtoc(int, struct extvtoc *);
66342440ecSPrasad Singamsetty extern int write_extvtoc(int, struct extvtoc *);
677c478bd9Sstevel@tonic-gate static int vtoc64_to_label(struct efi_info *, struct dk_gpt *);
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate #else /* __STDC__ */
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate * Prototypes for non-ANSI C compilers
737c478bd9Sstevel@tonic-gate */
747c478bd9Sstevel@tonic-gate static int do_geometry_sanity_check();
757c478bd9Sstevel@tonic-gate static int vtoc_to_label();
76342440ecSPrasad Singamsetty extern int read_extvtoc();
77342440ecSPrasad Singamsetty extern int write_extvtoc();
787c478bd9Sstevel@tonic-gate static int vtoc64_to_label();
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate #endif /* __STDC__ */
817c478bd9Sstevel@tonic-gate
82342440ecSPrasad Singamsetty #ifdef DEBUG
83342440ecSPrasad Singamsetty static void dump_label(struct dk_label *label);
84342440ecSPrasad Singamsetty #endif
85342440ecSPrasad Singamsetty
867c478bd9Sstevel@tonic-gate /*
877c478bd9Sstevel@tonic-gate * This routine checks the given label to see if it is valid.
887c478bd9Sstevel@tonic-gate */
897c478bd9Sstevel@tonic-gate int
checklabel(label)907c478bd9Sstevel@tonic-gate checklabel(label)
917c478bd9Sstevel@tonic-gate register struct dk_label *label;
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate /*
957c478bd9Sstevel@tonic-gate * Check the magic number.
967c478bd9Sstevel@tonic-gate */
977c478bd9Sstevel@tonic-gate if (label->dkl_magic != DKL_MAGIC)
987c478bd9Sstevel@tonic-gate return (0);
997c478bd9Sstevel@tonic-gate /*
1007c478bd9Sstevel@tonic-gate * Check the checksum.
1017c478bd9Sstevel@tonic-gate */
1027c478bd9Sstevel@tonic-gate if (checksum(label, CK_CHECKSUM) != 0)
1037c478bd9Sstevel@tonic-gate return (0);
1047c478bd9Sstevel@tonic-gate return (1);
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate /*
1087c478bd9Sstevel@tonic-gate * This routine checks or calculates the label checksum, depending on
1097c478bd9Sstevel@tonic-gate * the mode it is called in.
1107c478bd9Sstevel@tonic-gate */
1117c478bd9Sstevel@tonic-gate int
checksum(label,mode)1127c478bd9Sstevel@tonic-gate checksum(label, mode)
1137c478bd9Sstevel@tonic-gate struct dk_label *label;
1147c478bd9Sstevel@tonic-gate int mode;
1157c478bd9Sstevel@tonic-gate {
1167c478bd9Sstevel@tonic-gate register short *sp, sum = 0;
1177c478bd9Sstevel@tonic-gate register short count = (sizeof (struct dk_label)) / (sizeof (short));
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate /*
1207c478bd9Sstevel@tonic-gate * If we are generating a checksum, don't include the checksum
1217c478bd9Sstevel@tonic-gate * in the rolling xor.
1227c478bd9Sstevel@tonic-gate */
1237c478bd9Sstevel@tonic-gate if (mode == CK_MAKESUM)
1247c478bd9Sstevel@tonic-gate count -= 1;
1257c478bd9Sstevel@tonic-gate sp = (short *)label;
1267c478bd9Sstevel@tonic-gate /*
1277c478bd9Sstevel@tonic-gate * Take the xor of all the half-words in the label.
1287c478bd9Sstevel@tonic-gate */
1297c478bd9Sstevel@tonic-gate while (count--) {
1307c478bd9Sstevel@tonic-gate sum ^= *sp++;
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate /*
1337c478bd9Sstevel@tonic-gate * If we are checking the checksum, the total will be zero for
1347c478bd9Sstevel@tonic-gate * a correct checksum, so we can just return the sum.
1357c478bd9Sstevel@tonic-gate */
1367c478bd9Sstevel@tonic-gate if (mode == CK_CHECKSUM)
1377c478bd9Sstevel@tonic-gate return (sum);
1387c478bd9Sstevel@tonic-gate /*
1397c478bd9Sstevel@tonic-gate * If we are generating the checksum, fill it in.
1407c478bd9Sstevel@tonic-gate */
1417c478bd9Sstevel@tonic-gate else {
1427c478bd9Sstevel@tonic-gate label->dkl_cksum = sum;
1437c478bd9Sstevel@tonic-gate return (0);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate /*
1487c478bd9Sstevel@tonic-gate * This routine is used to extract the id string from the string stored
1497c478bd9Sstevel@tonic-gate * in a disk label. The problem is that the string in the label has
1507c478bd9Sstevel@tonic-gate * the physical characteristics of the drive appended to it. The approach
1517c478bd9Sstevel@tonic-gate * is to find the beginning of the physical attributes portion of the string
1527c478bd9Sstevel@tonic-gate * and truncate it there.
1537c478bd9Sstevel@tonic-gate */
1547c478bd9Sstevel@tonic-gate int
trim_id(id)1557c478bd9Sstevel@tonic-gate trim_id(id)
1567c478bd9Sstevel@tonic-gate char *id;
1577c478bd9Sstevel@tonic-gate {
1587c478bd9Sstevel@tonic-gate register char *c;
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate /*
1617c478bd9Sstevel@tonic-gate * Start at the end of the string. When we match the word ' cyl',
1627c478bd9Sstevel@tonic-gate * we are at the beginning of the attributes.
1637c478bd9Sstevel@tonic-gate */
1647c478bd9Sstevel@tonic-gate for (c = id + strlen(id); c >= id; c--) {
1657c478bd9Sstevel@tonic-gate if (strncmp(c, " cyl", strlen(" cyl")) == 0) {
1667c478bd9Sstevel@tonic-gate /*
1677c478bd9Sstevel@tonic-gate * Remove any white space.
1687c478bd9Sstevel@tonic-gate */
1697c478bd9Sstevel@tonic-gate for (; (((*(c - 1) == ' ') || (*(c - 1) == '\t')) &&
1707c478bd9Sstevel@tonic-gate (c >= id)); c--);
1717c478bd9Sstevel@tonic-gate break;
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate /*
1757c478bd9Sstevel@tonic-gate * If we ran off the beginning of the string, something is wrong.
1767c478bd9Sstevel@tonic-gate */
1777c478bd9Sstevel@tonic-gate if (c < id)
1787c478bd9Sstevel@tonic-gate return (-1);
1797c478bd9Sstevel@tonic-gate /*
1807c478bd9Sstevel@tonic-gate * Truncate the string.
1817c478bd9Sstevel@tonic-gate */
1827c478bd9Sstevel@tonic-gate *c = '\0';
1837c478bd9Sstevel@tonic-gate return (0);
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate /*
1877c478bd9Sstevel@tonic-gate * This routine is used by write_label() to do a quick sanity check on the
1887c478bd9Sstevel@tonic-gate * supplied geometry. This is not a thorough check.
1897c478bd9Sstevel@tonic-gate *
1907c478bd9Sstevel@tonic-gate * The SCSI READ_CAPACITY command is used here to get the capacity of the
1917c478bd9Sstevel@tonic-gate * disk. But, the available area to store data on a disk is usually less
1927c478bd9Sstevel@tonic-gate * than this. So, if the specified geometry evaluates to a value which falls
1937c478bd9Sstevel@tonic-gate * in this margin, then such illegal geometries can slip through the cracks.
1947c478bd9Sstevel@tonic-gate */
1957c478bd9Sstevel@tonic-gate static int
do_geometry_sanity_check()1967c478bd9Sstevel@tonic-gate do_geometry_sanity_check()
1977c478bd9Sstevel@tonic-gate {
1987c478bd9Sstevel@tonic-gate struct scsi_capacity_16 capacity;
1997c478bd9Sstevel@tonic-gate
2007c478bd9Sstevel@tonic-gate if (uscsi_read_capacity(cur_file, &capacity)) {
2017c478bd9Sstevel@tonic-gate err_print("Warning: Unable to get capacity."
2027c478bd9Sstevel@tonic-gate " Cannot check geometry\n");
2037c478bd9Sstevel@tonic-gate return (0); /* Just ignore this problem */
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate if (capacity.sc_capacity < ncyl * nhead * nsect) {
2077c478bd9Sstevel@tonic-gate err_print("\nWarning: Current geometry overshoots "
2087c478bd9Sstevel@tonic-gate "actual geometry of disk\n\n");
2097c478bd9Sstevel@tonic-gate if (check("Continue labelling disk") != 0)
2107c478bd9Sstevel@tonic-gate return (-1);
2117c478bd9Sstevel@tonic-gate return (0); /* Just ignore this problem */
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate return (0);
2157c478bd9Sstevel@tonic-gate }
2167c478bd9Sstevel@tonic-gate
2177c478bd9Sstevel@tonic-gate /*
21891da5b00Sgz161490 * create a clear EFI partition table when format is used
219342440ecSPrasad Singamsetty * to convert an SMI label to an EFI label
2207c478bd9Sstevel@tonic-gate */
2217c478bd9Sstevel@tonic-gate int
SMI_vtoc_to_EFI(int fd,struct dk_gpt ** new_vtoc)2220d9ffb6aSgz161490 SMI_vtoc_to_EFI(int fd, struct dk_gpt **new_vtoc)
2237c478bd9Sstevel@tonic-gate {
22491da5b00Sgz161490 int i;
22591da5b00Sgz161490 struct dk_gpt *efi;
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate if (efi_alloc_and_init(fd, EFI_NUMPAR, new_vtoc) != 0) {
2287c478bd9Sstevel@tonic-gate err_print("SMI vtoc to EFI failed\n");
2297c478bd9Sstevel@tonic-gate return (-1);
2307c478bd9Sstevel@tonic-gate }
23191da5b00Sgz161490 efi = *new_vtoc;
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate /*
23491da5b00Sgz161490 * create a clear EFI partition table:
23591da5b00Sgz161490 * s0 takes the whole disk except the primary EFI lable,
23691da5b00Sgz161490 * backup EFI labels, and the reserved partition.
23791da5b00Sgz161490 * s1-s6 are unassigned slices.
2387c478bd9Sstevel@tonic-gate */
23991da5b00Sgz161490 efi->efi_parts[0].p_tag = V_USR;
24091da5b00Sgz161490 efi->efi_parts[0].p_start = efi->efi_first_u_lba;
24191da5b00Sgz161490 efi->efi_parts[0].p_size = efi->efi_last_u_lba - efi->efi_first_u_lba
2421cce8a3fSyl194034 - EFI_MIN_RESV_SIZE + 1;
24391da5b00Sgz161490
2447c478bd9Sstevel@tonic-gate /*
24591da5b00Sgz161490 * s1-s6 are unassigned slices
2467c478bd9Sstevel@tonic-gate */
24791da5b00Sgz161490 for (i = 1; i < efi->efi_nparts - 2; i++) {
24891da5b00Sgz161490 efi->efi_parts[i].p_tag = V_UNASSIGNED;
24991da5b00Sgz161490 efi->efi_parts[i].p_start = 0;
25091da5b00Sgz161490 efi->efi_parts[i].p_size = 0;
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate /*
25491da5b00Sgz161490 * the reserved slice
2557c478bd9Sstevel@tonic-gate */
25691da5b00Sgz161490 efi->efi_parts[efi->efi_nparts - 1].p_tag = V_RESERVED;
25791da5b00Sgz161490 efi->efi_parts[efi->efi_nparts - 1].p_start =
2581cce8a3fSyl194034 efi->efi_last_u_lba - EFI_MIN_RESV_SIZE + 1;
25991da5b00Sgz161490 efi->efi_parts[efi->efi_nparts - 1].p_size = EFI_MIN_RESV_SIZE;
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate return (0);
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate
2647c478bd9Sstevel@tonic-gate /*
2657c478bd9Sstevel@tonic-gate * This routine constructs and writes a label on the disk. It writes both
2667c478bd9Sstevel@tonic-gate * the primary and backup labels. It assumes that there is a current
2677c478bd9Sstevel@tonic-gate * partition map already defined. It also notifies the SunOS kernel of
2687c478bd9Sstevel@tonic-gate * the label and partition information it has written on the disk.
2697c478bd9Sstevel@tonic-gate */
2707c478bd9Sstevel@tonic-gate int
write_label()2717c478bd9Sstevel@tonic-gate write_label()
2727c478bd9Sstevel@tonic-gate {
2737c478bd9Sstevel@tonic-gate int error = 0, head, sec;
2747c478bd9Sstevel@tonic-gate struct dk_label label;
275342440ecSPrasad Singamsetty struct extvtoc vtoc;
2767c478bd9Sstevel@tonic-gate struct dk_geom geom;
2777c478bd9Sstevel@tonic-gate struct dk_gpt *vtoc64;
2787c478bd9Sstevel@tonic-gate int nbackups;
27965908c77Syu, larry liu - Sun Microsystems - Beijing China char *new_label;
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
2827c478bd9Sstevel@tonic-gate int i;
2837c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate /*
286c92a0838Smishra * Check to see if any partitions used for svm, vxvm or live upgrade
287c92a0838Smishra * are on the disk. If so, refuse to label the disk, but only
288c92a0838Smishra * if we are trying to shrink a partition in use.
289c92a0838Smishra */
290c92a0838Smishra if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
291c92a0838Smishra (diskaddr_t)-1, 0, 1)) {
292c92a0838Smishra err_print("Cannot label disk when "
293c92a0838Smishra "partitions are in use as described.\n");
294c92a0838Smishra return (-1);
295c92a0838Smishra }
296c92a0838Smishra
297c92a0838Smishra /*
2987c478bd9Sstevel@tonic-gate * If EFI label, then write it out to disk
2997c478bd9Sstevel@tonic-gate */
3007c478bd9Sstevel@tonic-gate if (cur_label == L_TYPE_EFI) {
3017c478bd9Sstevel@tonic-gate enter_critical();
3027c478bd9Sstevel@tonic-gate vtoc64 = cur_parts->etoc;
3037c478bd9Sstevel@tonic-gate err_check(vtoc64);
3047c478bd9Sstevel@tonic-gate if (efi_write(cur_file, vtoc64) != 0) {
3057c478bd9Sstevel@tonic-gate err_print("Warning: error writing EFI.\n");
3067c478bd9Sstevel@tonic-gate error = -1;
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate cur_disk->disk_flags |= DSK_LABEL;
3107c478bd9Sstevel@tonic-gate exit_critical();
3117c478bd9Sstevel@tonic-gate return (error);
3127c478bd9Sstevel@tonic-gate }
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate /*
3157c478bd9Sstevel@tonic-gate * Fill in a label structure with the geometry information.
3167c478bd9Sstevel@tonic-gate */
3177c478bd9Sstevel@tonic-gate (void) memset((char *)&label, 0, sizeof (struct dk_label));
31865908c77Syu, larry liu - Sun Microsystems - Beijing China new_label = zalloc(cur_blksz);
31965908c77Syu, larry liu - Sun Microsystems - Beijing China
3207c478bd9Sstevel@tonic-gate label.dkl_pcyl = pcyl;
3217c478bd9Sstevel@tonic-gate label.dkl_ncyl = ncyl;
3227c478bd9Sstevel@tonic-gate label.dkl_acyl = acyl;
3237c478bd9Sstevel@tonic-gate
3247c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3257c478bd9Sstevel@tonic-gate label.dkl_bcyl = bcyl;
3267c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOC_VTOC_16) */
3277c478bd9Sstevel@tonic-gate
3287c478bd9Sstevel@tonic-gate label.dkl_nhead = nhead;
3297c478bd9Sstevel@tonic-gate label.dkl_nsect = nsect;
3307c478bd9Sstevel@tonic-gate label.dkl_apc = apc;
3317c478bd9Sstevel@tonic-gate label.dkl_intrlv = 1;
3327c478bd9Sstevel@tonic-gate label.dkl_rpm = cur_dtype->dtype_rpm;
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
3357c478bd9Sstevel@tonic-gate /*
3367c478bd9Sstevel@tonic-gate * Also fill in the current partition information.
3377c478bd9Sstevel@tonic-gate */
3387c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) {
3397c478bd9Sstevel@tonic-gate label.dkl_map[i] = cur_parts->pinfo_map[i];
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
3427c478bd9Sstevel@tonic-gate
3437c478bd9Sstevel@tonic-gate label.dkl_magic = DKL_MAGIC;
3447c478bd9Sstevel@tonic-gate
3457c478bd9Sstevel@tonic-gate /*
3467c478bd9Sstevel@tonic-gate * Fill in the vtoc information
3477c478bd9Sstevel@tonic-gate */
3487c478bd9Sstevel@tonic-gate label.dkl_vtoc = cur_parts->vtoc;
3497c478bd9Sstevel@tonic-gate
3507c478bd9Sstevel@tonic-gate /*
3517c478bd9Sstevel@tonic-gate * Use the current label
3527c478bd9Sstevel@tonic-gate */
3537c478bd9Sstevel@tonic-gate bcopy(cur_disk->v_volume, label.dkl_vtoc.v_volume, LEN_DKL_VVOL);
3547c478bd9Sstevel@tonic-gate
3557c478bd9Sstevel@tonic-gate /*
3567c478bd9Sstevel@tonic-gate * Put asciilabel in; on x86 it's in the vtoc, not the label.
3577c478bd9Sstevel@tonic-gate */
3587c478bd9Sstevel@tonic-gate (void) snprintf(label.dkl_asciilabel, sizeof (label.dkl_asciilabel),
3597c478bd9Sstevel@tonic-gate "%s cyl %d alt %d hd %d sec %d",
3607c478bd9Sstevel@tonic-gate cur_dtype->dtype_asciilabel, ncyl, acyl, nhead, nsect);
3617c478bd9Sstevel@tonic-gate
3627c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3637c478bd9Sstevel@tonic-gate /*
36465908c77Syu, larry liu - Sun Microsystems - Beijing China * Also add in v_sectorsz, as the driver will.
3657c478bd9Sstevel@tonic-gate */
36665908c77Syu, larry liu - Sun Microsystems - Beijing China label.dkl_vtoc.v_sectorsz = cur_blksz;
3677c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */
3687c478bd9Sstevel@tonic-gate
3697c478bd9Sstevel@tonic-gate /*
3707c478bd9Sstevel@tonic-gate * Generate the correct checksum.
3717c478bd9Sstevel@tonic-gate */
3727c478bd9Sstevel@tonic-gate (void) checksum(&label, CK_MAKESUM);
3737c478bd9Sstevel@tonic-gate /*
3747c478bd9Sstevel@tonic-gate * Convert the label into a vtoc
3757c478bd9Sstevel@tonic-gate */
3767c478bd9Sstevel@tonic-gate if (label_to_vtoc(&vtoc, &label) == -1) {
37765908c77Syu, larry liu - Sun Microsystems - Beijing China free(new_label);
3787c478bd9Sstevel@tonic-gate return (-1);
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate /*
3817c478bd9Sstevel@tonic-gate * Fill in the geometry info. This is critical that
3827c478bd9Sstevel@tonic-gate * we do this before writing the vtoc.
3837c478bd9Sstevel@tonic-gate */
3847c478bd9Sstevel@tonic-gate bzero((caddr_t)&geom, sizeof (struct dk_geom));
3857c478bd9Sstevel@tonic-gate geom.dkg_ncyl = ncyl;
3867c478bd9Sstevel@tonic-gate geom.dkg_acyl = acyl;
3877c478bd9Sstevel@tonic-gate
3887c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
3897c478bd9Sstevel@tonic-gate geom.dkg_bcyl = bcyl;
3907c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */
3917c478bd9Sstevel@tonic-gate
3927c478bd9Sstevel@tonic-gate geom.dkg_nhead = nhead;
3937c478bd9Sstevel@tonic-gate geom.dkg_nsect = nsect;
3947c478bd9Sstevel@tonic-gate geom.dkg_intrlv = 1;
3957c478bd9Sstevel@tonic-gate geom.dkg_apc = apc;
3967c478bd9Sstevel@tonic-gate geom.dkg_rpm = cur_dtype->dtype_rpm;
3977c478bd9Sstevel@tonic-gate geom.dkg_pcyl = pcyl;
3987c478bd9Sstevel@tonic-gate
3997c478bd9Sstevel@tonic-gate /*
4007c478bd9Sstevel@tonic-gate * Make a quick check to see that the geometry is being
4017c478bd9Sstevel@tonic-gate * written now is not way off from the actual capacity
4027c478bd9Sstevel@tonic-gate * of the disk. This is only an appoximate check and
4037c478bd9Sstevel@tonic-gate * is only for SCSI disks.
4047c478bd9Sstevel@tonic-gate */
4057c478bd9Sstevel@tonic-gate if (SCSI && do_geometry_sanity_check() != 0) {
40665908c77Syu, larry liu - Sun Microsystems - Beijing China free(new_label);
4077c478bd9Sstevel@tonic-gate return (-1);
4087c478bd9Sstevel@tonic-gate }
4097c478bd9Sstevel@tonic-gate
4107c478bd9Sstevel@tonic-gate /*
4117c478bd9Sstevel@tonic-gate * Lock out interrupts so we do things in sync.
4127c478bd9Sstevel@tonic-gate */
4137c478bd9Sstevel@tonic-gate enter_critical();
4147c478bd9Sstevel@tonic-gate /*
4157c478bd9Sstevel@tonic-gate * Do the ioctl to tell the kernel the geometry.
4167c478bd9Sstevel@tonic-gate */
4177c478bd9Sstevel@tonic-gate if (ioctl(cur_file, DKIOCSGEOM, &geom) == -1) {
4187c478bd9Sstevel@tonic-gate err_print("Warning: error setting drive geometry.\n");
4197c478bd9Sstevel@tonic-gate error = -1;
4207c478bd9Sstevel@tonic-gate }
4217c478bd9Sstevel@tonic-gate /*
4227c478bd9Sstevel@tonic-gate * Write the vtoc. At the time of this writing, our
4237c478bd9Sstevel@tonic-gate * drivers convert the vtoc back to a label, and
4247c478bd9Sstevel@tonic-gate * then write both the primary and backup labels.
4257c478bd9Sstevel@tonic-gate * This is not a requirement, however, as we
4267c478bd9Sstevel@tonic-gate * always use an ioctl to read the vtoc from the
4277c478bd9Sstevel@tonic-gate * driver, so it can do as it likes.
4287c478bd9Sstevel@tonic-gate */
429342440ecSPrasad Singamsetty if (write_extvtoc(cur_file, &vtoc) != 0) {
4307c478bd9Sstevel@tonic-gate err_print("Warning: error writing VTOC.\n");
4317c478bd9Sstevel@tonic-gate error = -1;
4327c478bd9Sstevel@tonic-gate }
4337c478bd9Sstevel@tonic-gate
4347c478bd9Sstevel@tonic-gate /*
4357c478bd9Sstevel@tonic-gate * Calculate where the backup labels went. They are always on
4367c478bd9Sstevel@tonic-gate * the last alternate cylinder, but some older drives put them
4377c478bd9Sstevel@tonic-gate * on head 2 instead of the last head. They are always on the
4387c478bd9Sstevel@tonic-gate * first 5 odd sectors of the appropriate track.
4397c478bd9Sstevel@tonic-gate */
4407c478bd9Sstevel@tonic-gate if (cur_ctype->ctype_flags & CF_BLABEL)
4417c478bd9Sstevel@tonic-gate head = 2;
4427c478bd9Sstevel@tonic-gate else
4437c478bd9Sstevel@tonic-gate head = nhead - 1;
4447c478bd9Sstevel@tonic-gate /*
4457c478bd9Sstevel@tonic-gate * Read and verify the backup labels.
4467c478bd9Sstevel@tonic-gate */
4477c478bd9Sstevel@tonic-gate nbackups = 0;
4487c478bd9Sstevel@tonic-gate for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect));
4497c478bd9Sstevel@tonic-gate sec += 2) {
4507c478bd9Sstevel@tonic-gate if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, (diskaddr_t)
45165908c77Syu, larry liu - Sun Microsystems - Beijing China ((chs2bn(ncyl + acyl - 1, head, sec))
45265908c77Syu, larry liu - Sun Microsystems - Beijing China + solaris_offset), 1, new_label, F_NORMAL, NULL)) {
45365908c77Syu, larry liu - Sun Microsystems - Beijing China err_print("Warning: error reading"
45465908c77Syu, larry liu - Sun Microsystems - Beijing China "backup label.\n");
4557c478bd9Sstevel@tonic-gate error = -1;
4567c478bd9Sstevel@tonic-gate } else {
45765908c77Syu, larry liu - Sun Microsystems - Beijing China if (bcmp((char *)&label, new_label,
4587c478bd9Sstevel@tonic-gate sizeof (struct dk_label)) == 0) {
4597c478bd9Sstevel@tonic-gate nbackups++;
4607c478bd9Sstevel@tonic-gate }
4617c478bd9Sstevel@tonic-gate }
4627c478bd9Sstevel@tonic-gate }
4637c478bd9Sstevel@tonic-gate if (nbackups != BAD_LISTCNT) {
4647c478bd9Sstevel@tonic-gate err_print("Warning: %s\n", nbackups == 0 ?
465843e1988Sjohnlev "no backup labels" : "some backup labels incorrect");
4667c478bd9Sstevel@tonic-gate }
4677c478bd9Sstevel@tonic-gate /*
4687c478bd9Sstevel@tonic-gate * Mark the current disk as labelled and notify the kernel of what
4697c478bd9Sstevel@tonic-gate * has happened.
4707c478bd9Sstevel@tonic-gate */
4717c478bd9Sstevel@tonic-gate cur_disk->disk_flags |= DSK_LABEL;
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate exit_critical();
47465908c77Syu, larry liu - Sun Microsystems - Beijing China free(new_label);
4757c478bd9Sstevel@tonic-gate return (error);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate
4787c478bd9Sstevel@tonic-gate
4797c478bd9Sstevel@tonic-gate /*
4807c478bd9Sstevel@tonic-gate * Read the label from the disk.
481342440ecSPrasad Singamsetty * Do this via the read_extvtoc() library routine, then convert it to a label.
4827c478bd9Sstevel@tonic-gate * We also need a DKIOCGGEOM ioctl to get the disk's geometry.
4837c478bd9Sstevel@tonic-gate */
4847c478bd9Sstevel@tonic-gate int
read_label(int fd,struct dk_label * label)4857c478bd9Sstevel@tonic-gate read_label(int fd, struct dk_label *label)
4867c478bd9Sstevel@tonic-gate {
487342440ecSPrasad Singamsetty struct extvtoc vtoc;
4887c478bd9Sstevel@tonic-gate struct dk_geom geom;
489843e1988Sjohnlev struct dk_cinfo dkinfo;
4907c478bd9Sstevel@tonic-gate
491342440ecSPrasad Singamsetty if (read_extvtoc(fd, &vtoc) < 0 ||
492843e1988Sjohnlev ioctl(fd, DKIOCGGEOM, &geom) == -1 ||
493843e1988Sjohnlev ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
4947c478bd9Sstevel@tonic-gate return (-1);
4957c478bd9Sstevel@tonic-gate }
496843e1988Sjohnlev
497843e1988Sjohnlev return (vtoc_to_label(label, &vtoc, &geom, &dkinfo));
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate
5003ccda647Slclee int
get_disk_inquiry_prop(char * devpath,char ** vid,char ** pid,char ** rid)501*f1bf0656SHans Rosenfeld get_disk_inquiry_prop(char *devpath, char **vid, char **pid, char **rid)
502*f1bf0656SHans Rosenfeld {
503*f1bf0656SHans Rosenfeld char *v, *p, *r;
504*f1bf0656SHans Rosenfeld di_node_t node;
505*f1bf0656SHans Rosenfeld int ret = -1;
506*f1bf0656SHans Rosenfeld
507*f1bf0656SHans Rosenfeld node = di_init(devpath, DINFOCPYALL);
508*f1bf0656SHans Rosenfeld
509*f1bf0656SHans Rosenfeld if (node == DI_NODE_NIL)
510*f1bf0656SHans Rosenfeld goto out;
511*f1bf0656SHans Rosenfeld
512*f1bf0656SHans Rosenfeld if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
513*f1bf0656SHans Rosenfeld "inquiry-vendor-id", &v) != 1)
514*f1bf0656SHans Rosenfeld goto out;
515*f1bf0656SHans Rosenfeld
516*f1bf0656SHans Rosenfeld if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
517*f1bf0656SHans Rosenfeld "inquiry-product-id", &p) != 1)
518*f1bf0656SHans Rosenfeld goto out;
519*f1bf0656SHans Rosenfeld
520*f1bf0656SHans Rosenfeld if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
521*f1bf0656SHans Rosenfeld "inquiry-revision-id", &r) != 1)
522*f1bf0656SHans Rosenfeld goto out;
523*f1bf0656SHans Rosenfeld
524*f1bf0656SHans Rosenfeld *vid = strdup(v);
525*f1bf0656SHans Rosenfeld *pid = strdup(p);
526*f1bf0656SHans Rosenfeld *rid = strdup(r);
527*f1bf0656SHans Rosenfeld
528*f1bf0656SHans Rosenfeld if (*vid == NULL || *pid == NULL || *rid == NULL) {
529*f1bf0656SHans Rosenfeld free(*vid);
530*f1bf0656SHans Rosenfeld free(*pid);
531*f1bf0656SHans Rosenfeld free(*rid);
532*f1bf0656SHans Rosenfeld goto out;
533*f1bf0656SHans Rosenfeld }
534*f1bf0656SHans Rosenfeld
535*f1bf0656SHans Rosenfeld ret = 0;
536*f1bf0656SHans Rosenfeld
537*f1bf0656SHans Rosenfeld out:
538*f1bf0656SHans Rosenfeld di_fini(node);
539*f1bf0656SHans Rosenfeld return (ret);
540*f1bf0656SHans Rosenfeld }
541*f1bf0656SHans Rosenfeld
542*f1bf0656SHans Rosenfeld int
get_disk_inquiry_uscsi(int fd,char ** vid,char ** pid,char ** rid)543*f1bf0656SHans Rosenfeld get_disk_inquiry_uscsi(int fd, char **vid, char **pid, char **rid)
544*f1bf0656SHans Rosenfeld {
545*f1bf0656SHans Rosenfeld struct scsi_inquiry inquiry;
546*f1bf0656SHans Rosenfeld
547*f1bf0656SHans Rosenfeld if (uscsi_inquiry(fd, (char *)&inquiry, sizeof (inquiry)))
548*f1bf0656SHans Rosenfeld return (-1);
549*f1bf0656SHans Rosenfeld
550*f1bf0656SHans Rosenfeld *vid = strndup(inquiry.inq_vid, 8);
551*f1bf0656SHans Rosenfeld *pid = strndup(inquiry.inq_pid, 16);
552*f1bf0656SHans Rosenfeld *rid = strndup(inquiry.inq_revision, 4);
553*f1bf0656SHans Rosenfeld
554*f1bf0656SHans Rosenfeld if (*vid == NULL || *pid == NULL || *rid == NULL) {
555*f1bf0656SHans Rosenfeld free(*vid);
556*f1bf0656SHans Rosenfeld free(*pid);
557*f1bf0656SHans Rosenfeld free(*rid);
558*f1bf0656SHans Rosenfeld return (-1);
559*f1bf0656SHans Rosenfeld }
560*f1bf0656SHans Rosenfeld
561*f1bf0656SHans Rosenfeld return (0);
562*f1bf0656SHans Rosenfeld }
563*f1bf0656SHans Rosenfeld
564*f1bf0656SHans Rosenfeld int
get_disk_capacity(int fd,uint64_t * capacity)565*f1bf0656SHans Rosenfeld get_disk_capacity(int fd, uint64_t *capacity)
566*f1bf0656SHans Rosenfeld {
567*f1bf0656SHans Rosenfeld struct dk_minfo minf;
568*f1bf0656SHans Rosenfeld struct scsi_capacity_16 cap16;
569*f1bf0656SHans Rosenfeld
570*f1bf0656SHans Rosenfeld if (ioctl(fd, DKIOCGMEDIAINFO, &minf) == 0) {
571*f1bf0656SHans Rosenfeld *capacity = minf.dki_capacity * minf.dki_lbsize / cur_blksz;
572*f1bf0656SHans Rosenfeld return (0);
573*f1bf0656SHans Rosenfeld }
574*f1bf0656SHans Rosenfeld
575*f1bf0656SHans Rosenfeld if (uscsi_read_capacity(fd, &cap16) == 0) {
576*f1bf0656SHans Rosenfeld *capacity = cap16.sc_capacity;
577*f1bf0656SHans Rosenfeld
578*f1bf0656SHans Rosenfeld /* Since we are counting from zero, add 1 to capacity */
579*f1bf0656SHans Rosenfeld (*capacity)++;
580*f1bf0656SHans Rosenfeld
581*f1bf0656SHans Rosenfeld return (0);
582*f1bf0656SHans Rosenfeld }
583*f1bf0656SHans Rosenfeld
584*f1bf0656SHans Rosenfeld err_print("Fetch Capacity failed\n");
585*f1bf0656SHans Rosenfeld return (-1);
586*f1bf0656SHans Rosenfeld }
587*f1bf0656SHans Rosenfeld
588*f1bf0656SHans Rosenfeld int
get_disk_inquiry_devid(int fd,char ** vid,char ** pid,char ** rid)589*f1bf0656SHans Rosenfeld get_disk_inquiry_devid(int fd, char **vid, char **pid, char **rid)
5903ccda647Slclee {
5913ccda647Slclee ddi_devid_t devid;
5923ccda647Slclee char *s;
593*f1bf0656SHans Rosenfeld char *v, *p;
5943ccda647Slclee struct dk_cinfo dkinfo;
5953ccda647Slclee
5963ccda647Slclee if (devid_get(fd, &devid)) {
5973ccda647Slclee if (option_msg && diag_msg)
5983ccda647Slclee err_print("devid_get failed\n");
5993ccda647Slclee return (-1);
6003ccda647Slclee }
6013ccda647Slclee
6023ccda647Slclee s = (char *)devid;
6033ccda647Slclee
6043ccda647Slclee if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
6053ccda647Slclee if (option_msg && diag_msg)
6063ccda647Slclee err_print("DKIOCINFO failed\n");
6073ccda647Slclee return (-1);
6083ccda647Slclee }
6093ccda647Slclee
6103ccda647Slclee if (dkinfo.dki_ctype != DKC_DIRECT)
6113ccda647Slclee return (-1);
6123ccda647Slclee
613*f1bf0656SHans Rosenfeld v = s+12;
614*f1bf0656SHans Rosenfeld if (!(p = strchr(v, '=')))
6153ccda647Slclee return (-1);
616*f1bf0656SHans Rosenfeld p += 1;
6173ccda647Slclee
618*f1bf0656SHans Rosenfeld *vid = strdup(v);
619*f1bf0656SHans Rosenfeld *pid = strdup(p);
620*f1bf0656SHans Rosenfeld *rid = strdup("0001");
6213ccda647Slclee devid_free(devid);
622*f1bf0656SHans Rosenfeld
623*f1bf0656SHans Rosenfeld if (*vid == NULL || *pid == NULL || *rid == NULL) {
624*f1bf0656SHans Rosenfeld free(*vid);
625*f1bf0656SHans Rosenfeld free(*pid);
626*f1bf0656SHans Rosenfeld free(*rid);
6273ccda647Slclee return (-1);
6283ccda647Slclee }
6293ccda647Slclee
6303ccda647Slclee return (0);
6313ccda647Slclee }
6323ccda647Slclee
6337c478bd9Sstevel@tonic-gate /*
6347c478bd9Sstevel@tonic-gate * Issue uscsi_inquiry and read_capacity commands to
6357c478bd9Sstevel@tonic-gate * retrieve the disk's Vendor, Product, Revision and
6367c478bd9Sstevel@tonic-gate * Capacity information.
6377c478bd9Sstevel@tonic-gate */
6387c478bd9Sstevel@tonic-gate int
get_disk_info(int fd,struct efi_info * label,struct disk_info * disk_info)639*f1bf0656SHans Rosenfeld get_disk_info(int fd, struct efi_info *label, struct disk_info *disk_info)
6407c478bd9Sstevel@tonic-gate {
641*f1bf0656SHans Rosenfeld (void) get_disk_capacity(fd, &label->capacity);
6427c478bd9Sstevel@tonic-gate
643*f1bf0656SHans Rosenfeld if (get_disk_inquiry_prop(disk_info->devfs_name,
644*f1bf0656SHans Rosenfeld &label->vendor, &label->product, &label->revision) != 0) {
645*f1bf0656SHans Rosenfeld if (get_disk_inquiry_devid(fd, &label->vendor, &label->product,
646*f1bf0656SHans Rosenfeld &label->revision) != 0) {
647*f1bf0656SHans Rosenfeld if (get_disk_inquiry_uscsi(fd, &label->vendor,
648*f1bf0656SHans Rosenfeld &label->product, &label->revision) != 0) {
649*f1bf0656SHans Rosenfeld label->vendor = strdup("Unknown");
650*f1bf0656SHans Rosenfeld label->product = strdup("Unknown");
651*f1bf0656SHans Rosenfeld label->revision = strdup("0001");
652*f1bf0656SHans Rosenfeld if (label->vendor == NULL ||
653*f1bf0656SHans Rosenfeld label->product == NULL ||
654*f1bf0656SHans Rosenfeld label->revision == NULL) {
655*f1bf0656SHans Rosenfeld free(label->vendor);
656*f1bf0656SHans Rosenfeld free(label->product);
657*f1bf0656SHans Rosenfeld free(label->revision);
658d25b227dSzl149053 return (-1);
659d25b227dSzl149053 }
660*f1bf0656SHans Rosenfeld }
661*f1bf0656SHans Rosenfeld }
662d25b227dSzl149053 }
663d25b227dSzl149053
6647c478bd9Sstevel@tonic-gate return (0);
6657c478bd9Sstevel@tonic-gate }
6667c478bd9Sstevel@tonic-gate
6677c478bd9Sstevel@tonic-gate int
read_efi_label(int fd,struct efi_info * label,struct disk_info * disk_info)668*f1bf0656SHans Rosenfeld read_efi_label(int fd, struct efi_info *label, struct disk_info *disk_info)
6697c478bd9Sstevel@tonic-gate {
6707c478bd9Sstevel@tonic-gate struct dk_gpt *vtoc64;
6717c478bd9Sstevel@tonic-gate
6727c478bd9Sstevel@tonic-gate /* This could fail if there is no label already */
6737c478bd9Sstevel@tonic-gate if (efi_alloc_and_read(fd, &vtoc64) < 0) {
6747c478bd9Sstevel@tonic-gate return (-1);
6757c478bd9Sstevel@tonic-gate }
6767c478bd9Sstevel@tonic-gate if (vtoc64_to_label(label, vtoc64) != 0) {
6777c478bd9Sstevel@tonic-gate err_print("vtoc64_to_label failed\n");
6787c478bd9Sstevel@tonic-gate return (-1);
6797c478bd9Sstevel@tonic-gate }
6807c478bd9Sstevel@tonic-gate efi_free(vtoc64);
681*f1bf0656SHans Rosenfeld if (get_disk_info(fd, label, disk_info) != 0) {
6827c478bd9Sstevel@tonic-gate return (-1);
6837c478bd9Sstevel@tonic-gate }
6847c478bd9Sstevel@tonic-gate return (0);
6857c478bd9Sstevel@tonic-gate }
6867c478bd9Sstevel@tonic-gate
6877c478bd9Sstevel@tonic-gate
6887c478bd9Sstevel@tonic-gate /*
6897c478bd9Sstevel@tonic-gate * We've read a 64-bit label which has no geometry information. Use
6907c478bd9Sstevel@tonic-gate * some heuristics to fake up a geometry that would match the disk in
6917c478bd9Sstevel@tonic-gate * order to make the rest of format(1M) happy.
6927c478bd9Sstevel@tonic-gate */
6937c478bd9Sstevel@tonic-gate static int
vtoc64_to_label(struct efi_info * label,struct dk_gpt * vtoc)6947c478bd9Sstevel@tonic-gate vtoc64_to_label(struct efi_info *label, struct dk_gpt *vtoc)
6957c478bd9Sstevel@tonic-gate {
6967c478bd9Sstevel@tonic-gate int i, nparts = 0;
6977c478bd9Sstevel@tonic-gate struct dk_gpt *lmap;
6987c478bd9Sstevel@tonic-gate
6997c478bd9Sstevel@tonic-gate (void) memset((char *)label, 0, sizeof (struct efi_info));
7007c478bd9Sstevel@tonic-gate
7017c478bd9Sstevel@tonic-gate /* XXX do a sanity check here for nparts */
7027c478bd9Sstevel@tonic-gate nparts = vtoc->efi_nparts;
7037c478bd9Sstevel@tonic-gate lmap = (struct dk_gpt *) calloc(1, (sizeof (struct dk_part) *
7047c478bd9Sstevel@tonic-gate nparts) + sizeof (struct dk_gpt));
7057c478bd9Sstevel@tonic-gate if (lmap == NULL) {
7067c478bd9Sstevel@tonic-gate err_print("vtoc64_to_label: unable to allocate lmap\n");
7077c478bd9Sstevel@tonic-gate fullabort();
7087c478bd9Sstevel@tonic-gate }
7097c478bd9Sstevel@tonic-gate label->e_parts = lmap;
7107c478bd9Sstevel@tonic-gate
7117c478bd9Sstevel@tonic-gate /*
7127c478bd9Sstevel@tonic-gate * Copy necessary portions
7137c478bd9Sstevel@tonic-gate * XXX Maybe we can use memcpy() ??
7147c478bd9Sstevel@tonic-gate */
7157c478bd9Sstevel@tonic-gate lmap->efi_version = vtoc->efi_version;
7167c478bd9Sstevel@tonic-gate lmap->efi_nparts = vtoc->efi_nparts;
7177c478bd9Sstevel@tonic-gate lmap->efi_part_size = vtoc->efi_part_size;
7187c478bd9Sstevel@tonic-gate lmap->efi_lbasize = vtoc->efi_lbasize;
7197c478bd9Sstevel@tonic-gate lmap->efi_last_lba = vtoc->efi_last_lba;
7207c478bd9Sstevel@tonic-gate lmap->efi_first_u_lba = vtoc->efi_first_u_lba;
7217c478bd9Sstevel@tonic-gate lmap->efi_last_u_lba = vtoc->efi_last_u_lba;
722af007057Syl194034 lmap->efi_altern_lba = vtoc->efi_altern_lba;
7237c478bd9Sstevel@tonic-gate lmap->efi_flags = vtoc->efi_flags;
7247c478bd9Sstevel@tonic-gate (void) memcpy((uchar_t *)&lmap->efi_disk_uguid,
7257c478bd9Sstevel@tonic-gate (uchar_t *)&vtoc->efi_disk_uguid, sizeof (struct uuid));
7267c478bd9Sstevel@tonic-gate
7277c478bd9Sstevel@tonic-gate for (i = 0; i < nparts; i++) {
7287c478bd9Sstevel@tonic-gate lmap->efi_parts[i].p_tag = vtoc->efi_parts[i].p_tag;
7297c478bd9Sstevel@tonic-gate lmap->efi_parts[i].p_flag = vtoc->efi_parts[i].p_flag;
7307c478bd9Sstevel@tonic-gate lmap->efi_parts[i].p_start = vtoc->efi_parts[i].p_start;
7317c478bd9Sstevel@tonic-gate lmap->efi_parts[i].p_size = vtoc->efi_parts[i].p_size;
7327c478bd9Sstevel@tonic-gate (void) memcpy((uchar_t *)&lmap->efi_parts[i].p_uguid,
7337c478bd9Sstevel@tonic-gate (uchar_t *)&vtoc->efi_parts[i].p_uguid,
7347c478bd9Sstevel@tonic-gate sizeof (struct uuid));
7357c478bd9Sstevel@tonic-gate if (vtoc->efi_parts[i].p_tag == V_RESERVED) {
7367c478bd9Sstevel@tonic-gate bcopy(vtoc->efi_parts[i].p_name,
7377c478bd9Sstevel@tonic-gate lmap->efi_parts[i].p_name, LEN_DKL_VVOL);
7387c478bd9Sstevel@tonic-gate }
7397c478bd9Sstevel@tonic-gate }
7407c478bd9Sstevel@tonic-gate return (0);
7417c478bd9Sstevel@tonic-gate }
7427c478bd9Sstevel@tonic-gate
7437c478bd9Sstevel@tonic-gate /*
7447c478bd9Sstevel@tonic-gate * Convert vtoc/geom to label.
7457c478bd9Sstevel@tonic-gate */
7467c478bd9Sstevel@tonic-gate static int
vtoc_to_label(struct dk_label * label,struct extvtoc * vtoc,struct dk_geom * geom,struct dk_cinfo * cinfo)747342440ecSPrasad Singamsetty vtoc_to_label(struct dk_label *label, struct extvtoc *vtoc,
748342440ecSPrasad Singamsetty struct dk_geom *geom, struct dk_cinfo *cinfo)
7497c478bd9Sstevel@tonic-gate {
7507c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
7517c478bd9Sstevel@tonic-gate struct dk_map32 *lmap;
7527c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
7537c478bd9Sstevel@tonic-gate struct dkl_partition *lmap;
7547c478bd9Sstevel@tonic-gate #else
7557c478bd9Sstevel@tonic-gate #error No VTOC format defined.
7567c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
7577c478bd9Sstevel@tonic-gate
758342440ecSPrasad Singamsetty struct extpartition *vpart;
759342440ecSPrasad Singamsetty ulong_t nblks;
7607c478bd9Sstevel@tonic-gate int i;
7617c478bd9Sstevel@tonic-gate
7627c478bd9Sstevel@tonic-gate (void) memset((char *)label, 0, sizeof (struct dk_label));
7637c478bd9Sstevel@tonic-gate
7647c478bd9Sstevel@tonic-gate /*
7657c478bd9Sstevel@tonic-gate * Sanity-check the vtoc
7667c478bd9Sstevel@tonic-gate */
76765908c77Syu, larry liu - Sun Microsystems - Beijing China if (vtoc->v_sanity != VTOC_SANE ||
7687c478bd9Sstevel@tonic-gate vtoc->v_nparts != V_NUMPAR) {
7697c478bd9Sstevel@tonic-gate return (-1);
7707c478bd9Sstevel@tonic-gate }
7717c478bd9Sstevel@tonic-gate
7727c478bd9Sstevel@tonic-gate /*
7737c478bd9Sstevel@tonic-gate * Sanity check of geometry
7747c478bd9Sstevel@tonic-gate */
7757c478bd9Sstevel@tonic-gate if (geom->dkg_ncyl == 0 || geom->dkg_nhead == 0 ||
7767c478bd9Sstevel@tonic-gate geom->dkg_nsect == 0) {
7777c478bd9Sstevel@tonic-gate return (-1);
7787c478bd9Sstevel@tonic-gate }
7797c478bd9Sstevel@tonic-gate
7807c478bd9Sstevel@tonic-gate label->dkl_magic = DKL_MAGIC;
7817c478bd9Sstevel@tonic-gate
7827c478bd9Sstevel@tonic-gate /*
7837c478bd9Sstevel@tonic-gate * Copy necessary portions of the geometry information
7847c478bd9Sstevel@tonic-gate */
7857c478bd9Sstevel@tonic-gate label->dkl_rpm = geom->dkg_rpm;
7867c478bd9Sstevel@tonic-gate label->dkl_pcyl = geom->dkg_pcyl;
7877c478bd9Sstevel@tonic-gate label->dkl_apc = geom->dkg_apc;
7887c478bd9Sstevel@tonic-gate label->dkl_intrlv = geom->dkg_intrlv;
7897c478bd9Sstevel@tonic-gate label->dkl_ncyl = geom->dkg_ncyl;
7907c478bd9Sstevel@tonic-gate label->dkl_acyl = geom->dkg_acyl;
7917c478bd9Sstevel@tonic-gate
7927c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
7937c478bd9Sstevel@tonic-gate label->dkl_bcyl = geom->dkg_bcyl;
7947c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */
7957c478bd9Sstevel@tonic-gate
7967c478bd9Sstevel@tonic-gate label->dkl_nhead = geom->dkg_nhead;
7977c478bd9Sstevel@tonic-gate label->dkl_nsect = geom->dkg_nsect;
7987c478bd9Sstevel@tonic-gate
7997c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
8007c478bd9Sstevel@tonic-gate label->dkl_obs1 = geom->dkg_obs1;
8017c478bd9Sstevel@tonic-gate label->dkl_obs2 = geom->dkg_obs2;
8027c478bd9Sstevel@tonic-gate label->dkl_obs3 = geom->dkg_obs3;
8037c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
8047c478bd9Sstevel@tonic-gate
8057c478bd9Sstevel@tonic-gate label->dkl_write_reinstruct = geom->dkg_write_reinstruct;
8067c478bd9Sstevel@tonic-gate label->dkl_read_reinstruct = geom->dkg_read_reinstruct;
8077c478bd9Sstevel@tonic-gate
8087c478bd9Sstevel@tonic-gate /*
8097c478bd9Sstevel@tonic-gate * Copy vtoc structure fields into the disk label dk_vtoc
8107c478bd9Sstevel@tonic-gate */
8117c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_sanity = vtoc->v_sanity;
8127c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_nparts = vtoc->v_nparts;
8137c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_version = vtoc->v_version;
8147c478bd9Sstevel@tonic-gate
8157c478bd9Sstevel@tonic-gate (void) memcpy(label->dkl_vtoc.v_volume, vtoc->v_volume,
8167c478bd9Sstevel@tonic-gate LEN_DKL_VVOL);
8177c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++) {
8187c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_tag = vtoc->v_part[i].p_tag;
8197c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_flag = vtoc->v_part[i].p_flag;
820342440ecSPrasad Singamsetty label->dkl_vtoc.v_timestamp[i] = vtoc->timestamp[i];
8217c478bd9Sstevel@tonic-gate }
822342440ecSPrasad Singamsetty
823342440ecSPrasad Singamsetty for (i = 0; i < 10; i++)
824342440ecSPrasad Singamsetty label->dkl_vtoc.v_reserved[i] = vtoc->v_reserved[i];
825342440ecSPrasad Singamsetty
826342440ecSPrasad Singamsetty label->dkl_vtoc.v_bootinfo[0] = vtoc->v_bootinfo[0];
827342440ecSPrasad Singamsetty label->dkl_vtoc.v_bootinfo[1] = vtoc->v_bootinfo[1];
828342440ecSPrasad Singamsetty label->dkl_vtoc.v_bootinfo[2] = vtoc->v_bootinfo[2];
8297c478bd9Sstevel@tonic-gate
8307c478bd9Sstevel@tonic-gate (void) memcpy(label->dkl_asciilabel, vtoc->v_asciilabel,
8317c478bd9Sstevel@tonic-gate LEN_DKL_ASCII);
8327c478bd9Sstevel@tonic-gate
8337c478bd9Sstevel@tonic-gate /*
8347c478bd9Sstevel@tonic-gate * Note the conversion from starting sector number
8357c478bd9Sstevel@tonic-gate * to starting cylinder number.
8367c478bd9Sstevel@tonic-gate * Return error if division results in a remainder.
837843e1988Sjohnlev *
838843e1988Sjohnlev * Note: don't check, if probing virtual disk in Xen
839843e1988Sjohnlev * for that virtual disk will use fabricated # of headers
840843e1988Sjohnlev * and sectors per track which may cause the capacity
841843e1988Sjohnlev * not multiple of # of blocks per cylinder
8427c478bd9Sstevel@tonic-gate */
8437c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
8447c478bd9Sstevel@tonic-gate lmap = label->dkl_map;
8457c478bd9Sstevel@tonic-gate
8467c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
8477c478bd9Sstevel@tonic-gate lmap = label->dkl_vtoc.v_part;
8487c478bd9Sstevel@tonic-gate #else
8497c478bd9Sstevel@tonic-gate #error No VTOC format defined.
8507c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
8517c478bd9Sstevel@tonic-gate
8527c478bd9Sstevel@tonic-gate vpart = vtoc->v_part;
8537c478bd9Sstevel@tonic-gate
854342440ecSPrasad Singamsetty nblks = label->dkl_nsect * label->dkl_nhead;
8557c478bd9Sstevel@tonic-gate
8567c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++, lmap++, vpart++) {
857843e1988Sjohnlev if (cinfo->dki_ctype != DKC_VBD) {
8587c478bd9Sstevel@tonic-gate if ((vpart->p_start % nblks) != 0 ||
8597c478bd9Sstevel@tonic-gate (vpart->p_size % nblks) != 0) {
8607c478bd9Sstevel@tonic-gate return (-1);
8617c478bd9Sstevel@tonic-gate }
862843e1988Sjohnlev }
8637c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
864342440ecSPrasad Singamsetty lmap->dkl_cylno = (blkaddr32_t)(vpart->p_start / nblks);
865342440ecSPrasad Singamsetty lmap->dkl_nblk = (blkaddr32_t)vpart->p_size;
8667c478bd9Sstevel@tonic-gate
8677c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
868342440ecSPrasad Singamsetty lmap->p_start = (blkaddr32_t)vpart->p_start;
869342440ecSPrasad Singamsetty lmap->p_size = (blkaddr32_t)vpart->p_size;
8707c478bd9Sstevel@tonic-gate #else
8717c478bd9Sstevel@tonic-gate #error No VTOC format defined.
8727c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
8737c478bd9Sstevel@tonic-gate }
8747c478bd9Sstevel@tonic-gate
8757c478bd9Sstevel@tonic-gate /*
8767c478bd9Sstevel@tonic-gate * Finally, make a checksum
8777c478bd9Sstevel@tonic-gate */
8787c478bd9Sstevel@tonic-gate (void) checksum(label, CK_MAKESUM);
8797c478bd9Sstevel@tonic-gate
880342440ecSPrasad Singamsetty #ifdef DEBUG
881342440ecSPrasad Singamsetty if (option_msg && diag_msg)
882342440ecSPrasad Singamsetty dump_label(label);
883342440ecSPrasad Singamsetty #endif
8847c478bd9Sstevel@tonic-gate return (0);
8857c478bd9Sstevel@tonic-gate }
8867c478bd9Sstevel@tonic-gate
8877c478bd9Sstevel@tonic-gate
8887c478bd9Sstevel@tonic-gate
8897c478bd9Sstevel@tonic-gate /*
8907c478bd9Sstevel@tonic-gate * Extract a vtoc structure out of a valid label
8917c478bd9Sstevel@tonic-gate */
8927c478bd9Sstevel@tonic-gate int
label_to_vtoc(struct extvtoc * vtoc,struct dk_label * label)893342440ecSPrasad Singamsetty label_to_vtoc(struct extvtoc *vtoc, struct dk_label *label)
8947c478bd9Sstevel@tonic-gate {
8957c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
8967c478bd9Sstevel@tonic-gate struct dk_map2 *lpart;
8977c478bd9Sstevel@tonic-gate struct dk_map32 *lmap;
898342440ecSPrasad Singamsetty ulong_t nblks;
8997c478bd9Sstevel@tonic-gate
9007c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
9017c478bd9Sstevel@tonic-gate struct dkl_partition *lpart;
9027c478bd9Sstevel@tonic-gate #else
9037c478bd9Sstevel@tonic-gate #error No VTOC format defined.
9047c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
9057c478bd9Sstevel@tonic-gate
906342440ecSPrasad Singamsetty struct extpartition *vpart;
9077c478bd9Sstevel@tonic-gate int i;
9087c478bd9Sstevel@tonic-gate
909342440ecSPrasad Singamsetty (void) memset((char *)vtoc, 0, sizeof (struct extvtoc));
9107c478bd9Sstevel@tonic-gate
9117c478bd9Sstevel@tonic-gate switch (label->dkl_vtoc.v_version) {
9127c478bd9Sstevel@tonic-gate case 0:
9137c478bd9Sstevel@tonic-gate /*
9147c478bd9Sstevel@tonic-gate * No valid vtoc information in the label.
9157c478bd9Sstevel@tonic-gate * Construct default p_flags and p_tags.
9167c478bd9Sstevel@tonic-gate */
9177c478bd9Sstevel@tonic-gate vpart = vtoc->v_part;
9187c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++, vpart++) {
9197c478bd9Sstevel@tonic-gate vpart->p_tag = default_vtoc_map[i].p_tag;
9207c478bd9Sstevel@tonic-gate vpart->p_flag = default_vtoc_map[i].p_flag;
9217c478bd9Sstevel@tonic-gate }
9227c478bd9Sstevel@tonic-gate break;
9237c478bd9Sstevel@tonic-gate
9247c478bd9Sstevel@tonic-gate case V_VERSION:
9257c478bd9Sstevel@tonic-gate vpart = vtoc->v_part;
9267c478bd9Sstevel@tonic-gate lpart = label->dkl_vtoc.v_part;
9277c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++, vpart++, lpart++) {
9287c478bd9Sstevel@tonic-gate vpart->p_tag = lpart->p_tag;
9297c478bd9Sstevel@tonic-gate vpart->p_flag = lpart->p_flag;
9307c478bd9Sstevel@tonic-gate
9317c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
932342440ecSPrasad Singamsetty vpart->p_start = (diskaddr_t)lpart->p_start;
933342440ecSPrasad Singamsetty vpart->p_size = (diskaddr_t)lpart->p_size;
9347c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */
935342440ecSPrasad Singamsetty vtoc->timestamp[i] = label->dkl_vtoc.v_timestamp[i];
9367c478bd9Sstevel@tonic-gate }
9377c478bd9Sstevel@tonic-gate (void) memcpy(vtoc->v_volume, label->dkl_vtoc.v_volume,
9387c478bd9Sstevel@tonic-gate LEN_DKL_VVOL);
939342440ecSPrasad Singamsetty
940342440ecSPrasad Singamsetty for (i = 0; i < 10; i++)
941342440ecSPrasad Singamsetty vtoc->v_reserved[i] = label->dkl_vtoc.v_reserved[i];
942342440ecSPrasad Singamsetty
943342440ecSPrasad Singamsetty vtoc->v_bootinfo[0] = label->dkl_vtoc.v_bootinfo[0];
944342440ecSPrasad Singamsetty vtoc->v_bootinfo[1] = label->dkl_vtoc.v_bootinfo[1];
945342440ecSPrasad Singamsetty vtoc->v_bootinfo[2] = label->dkl_vtoc.v_bootinfo[2];
9467c478bd9Sstevel@tonic-gate break;
9477c478bd9Sstevel@tonic-gate
9487c478bd9Sstevel@tonic-gate default:
9497c478bd9Sstevel@tonic-gate return (-1);
9507c478bd9Sstevel@tonic-gate }
9517c478bd9Sstevel@tonic-gate
9527c478bd9Sstevel@tonic-gate /*
9537c478bd9Sstevel@tonic-gate * XXX - this looks wrong to me....
9547c478bd9Sstevel@tonic-gate * why are these values hardwired, rather than returned from
9557c478bd9Sstevel@tonic-gate * the real disk label?
9567c478bd9Sstevel@tonic-gate */
9577c478bd9Sstevel@tonic-gate vtoc->v_sanity = VTOC_SANE;
9587c478bd9Sstevel@tonic-gate vtoc->v_version = V_VERSION;
95965908c77Syu, larry liu - Sun Microsystems - Beijing China vtoc->v_sectorsz = cur_blksz;
9607c478bd9Sstevel@tonic-gate vtoc->v_nparts = V_NUMPAR;
9617c478bd9Sstevel@tonic-gate
9627c478bd9Sstevel@tonic-gate (void) memcpy(vtoc->v_asciilabel, label->dkl_asciilabel,
9637c478bd9Sstevel@tonic-gate LEN_DKL_ASCII);
9647c478bd9Sstevel@tonic-gate
9657c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
9667c478bd9Sstevel@tonic-gate /*
9677c478bd9Sstevel@tonic-gate * Convert partitioning information.
9687c478bd9Sstevel@tonic-gate * Note the conversion from starting cylinder number
9697c478bd9Sstevel@tonic-gate * to starting sector number.
9707c478bd9Sstevel@tonic-gate */
9717c478bd9Sstevel@tonic-gate lmap = label->dkl_map;
9727c478bd9Sstevel@tonic-gate vpart = vtoc->v_part;
9737c478bd9Sstevel@tonic-gate nblks = label->dkl_nsect * label->dkl_nhead;
9747c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++, vpart++, lmap++) {
975342440ecSPrasad Singamsetty vpart->p_start = (diskaddr_t)(lmap->dkl_cylno * nblks);
976342440ecSPrasad Singamsetty vpart->p_size = (diskaddr_t)lmap->dkl_nblk;
9777c478bd9Sstevel@tonic-gate }
9787c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
9797c478bd9Sstevel@tonic-gate
9807c478bd9Sstevel@tonic-gate return (0);
9817c478bd9Sstevel@tonic-gate }
9827c478bd9Sstevel@tonic-gate
9837c478bd9Sstevel@tonic-gate /*
9847c478bd9Sstevel@tonic-gate * Input: File descriptor
985342440ecSPrasad Singamsetty * Output: 1 if disk has an EFI label, 0 otherwise.
9867c478bd9Sstevel@tonic-gate */
9877c478bd9Sstevel@tonic-gate
9887c478bd9Sstevel@tonic-gate int
is_efi_type(int fd)9897c478bd9Sstevel@tonic-gate is_efi_type(int fd)
9907c478bd9Sstevel@tonic-gate {
991342440ecSPrasad Singamsetty struct extvtoc vtoc;
9927c478bd9Sstevel@tonic-gate
993342440ecSPrasad Singamsetty if (read_extvtoc(fd, &vtoc) == VT_ENOTSUP) {
994342440ecSPrasad Singamsetty /* assume the disk has EFI label */
9957c478bd9Sstevel@tonic-gate return (1);
9967c478bd9Sstevel@tonic-gate }
9977c478bd9Sstevel@tonic-gate return (0);
9987c478bd9Sstevel@tonic-gate }
9997c478bd9Sstevel@tonic-gate
10007c478bd9Sstevel@tonic-gate /* make sure the user specified something reasonable */
10017c478bd9Sstevel@tonic-gate void
err_check(struct dk_gpt * vtoc)10027c478bd9Sstevel@tonic-gate err_check(struct dk_gpt *vtoc)
10037c478bd9Sstevel@tonic-gate {
10047c478bd9Sstevel@tonic-gate int resv_part = -1;
10057c478bd9Sstevel@tonic-gate int i, j;
10067c478bd9Sstevel@tonic-gate diskaddr_t istart, jstart, isize, jsize, endsect;
10077c478bd9Sstevel@tonic-gate int overlap = 0;
10087c478bd9Sstevel@tonic-gate
10097c478bd9Sstevel@tonic-gate /*
10107c478bd9Sstevel@tonic-gate * make sure no partitions overlap
10117c478bd9Sstevel@tonic-gate */
10127c478bd9Sstevel@tonic-gate for (i = 0; i < vtoc->efi_nparts; i++) {
10137c478bd9Sstevel@tonic-gate /* It can't be unassigned and have an actual size */
10147c478bd9Sstevel@tonic-gate if ((vtoc->efi_parts[i].p_tag == V_UNASSIGNED) &&
10157c478bd9Sstevel@tonic-gate (vtoc->efi_parts[i].p_size != 0)) {
10167c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
10177c478bd9Sstevel@tonic-gate "partition %d is \"unassigned\" but has a size of %llu\n", i,
10187c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_size);
10197c478bd9Sstevel@tonic-gate }
10207c478bd9Sstevel@tonic-gate if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) {
10217c478bd9Sstevel@tonic-gate continue;
10227c478bd9Sstevel@tonic-gate }
10237c478bd9Sstevel@tonic-gate if (vtoc->efi_parts[i].p_tag == V_RESERVED) {
10247c478bd9Sstevel@tonic-gate if (resv_part != -1) {
10257c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
1026843e1988Sjohnlev "found duplicate reserved partition at %d\n", i);
10277c478bd9Sstevel@tonic-gate }
10287c478bd9Sstevel@tonic-gate resv_part = i;
10297c478bd9Sstevel@tonic-gate if (vtoc->efi_parts[i].p_size != EFI_MIN_RESV_SIZE)
10307c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
10317c478bd9Sstevel@tonic-gate "Warning: reserved partition size must be %d sectors\n",
10327c478bd9Sstevel@tonic-gate EFI_MIN_RESV_SIZE);
10337c478bd9Sstevel@tonic-gate }
10347c478bd9Sstevel@tonic-gate if ((vtoc->efi_parts[i].p_start < vtoc->efi_first_u_lba) ||
10357c478bd9Sstevel@tonic-gate (vtoc->efi_parts[i].p_start > vtoc->efi_last_u_lba)) {
10367c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
10377c478bd9Sstevel@tonic-gate "Partition %d starts at %llu\n",
10387c478bd9Sstevel@tonic-gate i,
10397c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_start);
10407c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
10417c478bd9Sstevel@tonic-gate "It must be between %llu and %llu.\n",
10427c478bd9Sstevel@tonic-gate vtoc->efi_first_u_lba,
10437c478bd9Sstevel@tonic-gate vtoc->efi_last_u_lba);
10447c478bd9Sstevel@tonic-gate }
10457c478bd9Sstevel@tonic-gate if ((vtoc->efi_parts[i].p_start +
10467c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_size <
10477c478bd9Sstevel@tonic-gate vtoc->efi_first_u_lba) ||
10487c478bd9Sstevel@tonic-gate (vtoc->efi_parts[i].p_start +
10497c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_size >
10507c478bd9Sstevel@tonic-gate vtoc->efi_last_u_lba + 1)) {
10517c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
10527c478bd9Sstevel@tonic-gate "Partition %d ends at %llu\n",
10537c478bd9Sstevel@tonic-gate i,
10547c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_start +
10557c478bd9Sstevel@tonic-gate vtoc->efi_parts[i].p_size);
10567c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
10577c478bd9Sstevel@tonic-gate "It must be between %llu and %llu.\n",
10587c478bd9Sstevel@tonic-gate vtoc->efi_first_u_lba,
10597c478bd9Sstevel@tonic-gate vtoc->efi_last_u_lba);
10607c478bd9Sstevel@tonic-gate }
10617c478bd9Sstevel@tonic-gate
10627c478bd9Sstevel@tonic-gate for (j = 0; j < vtoc->efi_nparts; j++) {
10637c478bd9Sstevel@tonic-gate isize = vtoc->efi_parts[i].p_size;
10647c478bd9Sstevel@tonic-gate jsize = vtoc->efi_parts[j].p_size;
10657c478bd9Sstevel@tonic-gate istart = vtoc->efi_parts[i].p_start;
10667c478bd9Sstevel@tonic-gate jstart = vtoc->efi_parts[j].p_start;
10677c478bd9Sstevel@tonic-gate if ((i != j) && (isize != 0) && (jsize != 0)) {
10687c478bd9Sstevel@tonic-gate endsect = jstart + jsize -1;
10697c478bd9Sstevel@tonic-gate if ((jstart <= istart) &&
10707c478bd9Sstevel@tonic-gate (istart <= endsect)) {
10717c478bd9Sstevel@tonic-gate if (!overlap) {
10727c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
10737c478bd9Sstevel@tonic-gate "label error: EFI Labels do not support overlapping partitions\n");
10747c478bd9Sstevel@tonic-gate }
10757c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
10767c478bd9Sstevel@tonic-gate "Partition %d overlaps partition %d.\n", i, j);
10777c478bd9Sstevel@tonic-gate overlap = 1;
10787c478bd9Sstevel@tonic-gate }
10797c478bd9Sstevel@tonic-gate }
10807c478bd9Sstevel@tonic-gate }
10817c478bd9Sstevel@tonic-gate }
10827c478bd9Sstevel@tonic-gate /* make sure there is a reserved partition */
10837c478bd9Sstevel@tonic-gate if (resv_part == -1) {
10847c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
10857c478bd9Sstevel@tonic-gate "no reserved partition found\n");
10867c478bd9Sstevel@tonic-gate }
10877c478bd9Sstevel@tonic-gate }
10887c478bd9Sstevel@tonic-gate
1089342440ecSPrasad Singamsetty #ifdef DEBUG
1090342440ecSPrasad Singamsetty static void
dump_label(label)10917c478bd9Sstevel@tonic-gate dump_label(label)
10927c478bd9Sstevel@tonic-gate struct dk_label *label;
10937c478bd9Sstevel@tonic-gate {
10947c478bd9Sstevel@tonic-gate int i;
10957c478bd9Sstevel@tonic-gate
10967c478bd9Sstevel@tonic-gate fmt_print("%s\n", label->dkl_asciilabel);
10977c478bd9Sstevel@tonic-gate
10987c478bd9Sstevel@tonic-gate fmt_print("version: %d\n", label->dkl_vtoc.v_version);
10997c478bd9Sstevel@tonic-gate fmt_print("volume: ");
11007c478bd9Sstevel@tonic-gate for (i = 0; i < LEN_DKL_VVOL; i++) {
11017c478bd9Sstevel@tonic-gate if (label->dkl_vtoc.v_volume[i] == 0)
11027c478bd9Sstevel@tonic-gate break;
11037c478bd9Sstevel@tonic-gate fmt_print("%c", label->dkl_vtoc.v_volume[i]);
11047c478bd9Sstevel@tonic-gate }
11057c478bd9Sstevel@tonic-gate fmt_print("\n");
11067c478bd9Sstevel@tonic-gate fmt_print("v_nparts: %d\n", label->dkl_vtoc.v_nparts);
11077c478bd9Sstevel@tonic-gate fmt_print("v_sanity: %lx\n", label->dkl_vtoc.v_sanity);
11087c478bd9Sstevel@tonic-gate
11097c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
11107c478bd9Sstevel@tonic-gate fmt_print("rpm: %d\n", label->dkl_rpm);
11117c478bd9Sstevel@tonic-gate fmt_print("pcyl: %d\n", label->dkl_pcyl);
11127c478bd9Sstevel@tonic-gate fmt_print("apc: %d\n", label->dkl_apc);
11137c478bd9Sstevel@tonic-gate fmt_print("obs1: %d\n", label->dkl_obs1);
11147c478bd9Sstevel@tonic-gate fmt_print("obs2: %d\n", label->dkl_obs2);
11157c478bd9Sstevel@tonic-gate fmt_print("intrlv: %d\n", label->dkl_intrlv);
11167c478bd9Sstevel@tonic-gate fmt_print("ncyl: %d\n", label->dkl_ncyl);
11177c478bd9Sstevel@tonic-gate fmt_print("acyl: %d\n", label->dkl_acyl);
11187c478bd9Sstevel@tonic-gate fmt_print("nhead: %d\n", label->dkl_nhead);
11197c478bd9Sstevel@tonic-gate fmt_print("nsect: %d\n", label->dkl_nsect);
11207c478bd9Sstevel@tonic-gate fmt_print("obs3: %d\n", label->dkl_obs3);
11217c478bd9Sstevel@tonic-gate fmt_print("obs4: %d\n", label->dkl_obs4);
11227c478bd9Sstevel@tonic-gate
11237c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
11247c478bd9Sstevel@tonic-gate fmt_print("rpm: %d\n", label->dkl_rpm);
11257c478bd9Sstevel@tonic-gate fmt_print("pcyl: %d\n", label->dkl_pcyl);
11267c478bd9Sstevel@tonic-gate fmt_print("apc: %d\n", label->dkl_apc);
11277c478bd9Sstevel@tonic-gate fmt_print("intrlv: %d\n", label->dkl_intrlv);
11287c478bd9Sstevel@tonic-gate fmt_print("ncyl: %d\n", label->dkl_ncyl);
11297c478bd9Sstevel@tonic-gate fmt_print("acyl: %d\n", label->dkl_acyl);
11307c478bd9Sstevel@tonic-gate fmt_print("nhead: %d\n", label->dkl_nhead);
11317c478bd9Sstevel@tonic-gate fmt_print("nsect: %d\n", label->dkl_nsect);
11327c478bd9Sstevel@tonic-gate fmt_print("bcyl: %d\n", label->dkl_bcyl);
11337c478bd9Sstevel@tonic-gate fmt_print("skew: %d\n", label->dkl_skew);
11347c478bd9Sstevel@tonic-gate #else
11357c478bd9Sstevel@tonic-gate #error No VTOC format defined.
11367c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
11377c478bd9Sstevel@tonic-gate fmt_print("magic: %0x\n", label->dkl_magic);
11387c478bd9Sstevel@tonic-gate fmt_print("cksum: %0x\n", label->dkl_cksum);
11397c478bd9Sstevel@tonic-gate
11407c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) {
11417c478bd9Sstevel@tonic-gate
11427c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
11437c478bd9Sstevel@tonic-gate fmt_print("%c: cyl=%d, blocks=%d", i+'a',
11447c478bd9Sstevel@tonic-gate label->dkl_map[i].dkl_cylno,
11457c478bd9Sstevel@tonic-gate label->dkl_map[i].dkl_nblk);
11467c478bd9Sstevel@tonic-gate
11477c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16)
1148342440ecSPrasad Singamsetty fmt_print("%c: start=%u, blocks=%u", i+'a',
11497c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_start,
11507c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_size);
11517c478bd9Sstevel@tonic-gate #else
11527c478bd9Sstevel@tonic-gate #error No VTOC format defined.
11537c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */
11547c478bd9Sstevel@tonic-gate
11557c478bd9Sstevel@tonic-gate fmt_print(", tag=%d, flag=%d",
11567c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_tag,
11577c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_flag);
11587c478bd9Sstevel@tonic-gate fmt_print("\n");
11597c478bd9Sstevel@tonic-gate }
11607c478bd9Sstevel@tonic-gate
11617c478bd9Sstevel@tonic-gate fmt_print("read_reinstruct: %d\n", label->dkl_read_reinstruct);
11627c478bd9Sstevel@tonic-gate fmt_print("write_reinstruct: %d\n", label->dkl_write_reinstruct);
11637c478bd9Sstevel@tonic-gate
11647c478bd9Sstevel@tonic-gate fmt_print("bootinfo: ");
11657c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) {
11667c478bd9Sstevel@tonic-gate fmt_print("0x%x ", label->dkl_vtoc.v_bootinfo[i]);
11677c478bd9Sstevel@tonic-gate }
11687c478bd9Sstevel@tonic-gate fmt_print("\n");
11697c478bd9Sstevel@tonic-gate
11707c478bd9Sstevel@tonic-gate fmt_print("reserved: ");
11717c478bd9Sstevel@tonic-gate for (i = 0; i < 10; i++) {
11727c478bd9Sstevel@tonic-gate if ((i % 4) == 3)
11737c478bd9Sstevel@tonic-gate fmt_print("\n");
11747c478bd9Sstevel@tonic-gate fmt_print("0x%x ", label->dkl_vtoc.v_reserved[i]);
11757c478bd9Sstevel@tonic-gate }
11767c478bd9Sstevel@tonic-gate fmt_print("\n");
11777c478bd9Sstevel@tonic-gate
11787c478bd9Sstevel@tonic-gate fmt_print("timestamp:\n");
11797c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) {
11807c478bd9Sstevel@tonic-gate if ((i % 4) == 3)
11817c478bd9Sstevel@tonic-gate fmt_print("\n");
11827c478bd9Sstevel@tonic-gate fmt_print("0x%x ", label->dkl_vtoc.v_timestamp[i]);
11837c478bd9Sstevel@tonic-gate }
11847c478bd9Sstevel@tonic-gate fmt_print("\n");
11857c478bd9Sstevel@tonic-gate
11867c478bd9Sstevel@tonic-gate fmt_print("pad:\n");
11877c478bd9Sstevel@tonic-gate dump("", label->dkl_pad, LEN_DKL_PAD, HEX_ONLY);
11887c478bd9Sstevel@tonic-gate
11897c478bd9Sstevel@tonic-gate fmt_print("\n\n");
11907c478bd9Sstevel@tonic-gate }
1191342440ecSPrasad Singamsetty #endif /* DEBUG */
1192